From f16acb06ab278cdcb1d39a29680634010638326d Mon Sep 17 00:00:00 2001 From: riku <risaku@163.com> Date: 星期三, 08 五月 2024 17:35:48 +0800 Subject: [PATCH] 1. 完成表格模块的功能迁移; 2. 完成表格、折线图、地图标记三者点击联动 --- src/components/SliderBar.vue | 13 src/utils/map/animation.js | 389 +++++++++++++++++ src/views/historymode/HistoryMode.vue | 43 + src/utils/map/dialog.js | 16 src/assets/border.css | 1 src/components/monitor/DataSummary.vue | 91 ++++ src/components/monitor/FactorCheckbox.vue | 66 ++ src/components.d.ts | 9 src/components/CardButton.vue | 13 src/views/historymode/component/DataSheet.vue | 77 +++ src/utils/map/marks.js | 11 src/components/map/MapToolbox.vue | 2 src/components/core/CoreMenu.vue | 2 src/components/monitor/DataTable.vue | 161 ++++++- src/utils/map/sector.js | 38 src/utils/map/3dLayer.js | 165 +++--- src/model/FrameAnimation.js | 143 ++++++ src/views/historymode/component/TrendAnalysis.vue | 14 src/components/monitor/LineChart.vue | 46 + 19 files changed, 1,128 insertions(+), 172 deletions(-) diff --git a/src/assets/border.css b/src/assets/border.css index 30416bf..a45a338 100644 --- a/src/assets/border.css +++ b/src/assets/border.css @@ -565,6 +565,7 @@ /* 鎸夐挳 */ .ff-toggle-btn { position: relative; + } .ff-toggle-btn .ff-border-top { diff --git a/src/components.d.ts b/src/components.d.ts index 2930d6a..a01e48b 100644 --- a/src/components.d.ts +++ b/src/components.d.ts @@ -12,6 +12,8 @@ CardButton: typeof import('./components/CardButton.vue')['default'] CoreHeader: typeof import('./components/core/CoreHeader.vue')['default'] CoreMenu: typeof import('./components/core/CoreMenu.vue')['default'] + DataStatistic: typeof import('./components/monitor/DataStatistic.vue')['default'] + DataSummary: typeof import('./components/monitor/DataSummary.vue')['default'] DataTable: typeof import('./components/monitor/DataTable.vue')['default'] ElButton: typeof import('element-plus/es')['ElButton'] ElCheckbox: typeof import('element-plus/es')['ElCheckbox'] @@ -26,11 +28,15 @@ ElFormItem: typeof import('element-plus/es')['ElFormItem'] ElIcon: typeof import('element-plus/es')['ElIcon'] ElOption: typeof import('element-plus/es')['ElOption'] + ElPagination: typeof import('element-plus/es')['ElPagination'] ElRadio: typeof import('element-plus/es')['ElRadio'] ElRadioGroup: typeof import('element-plus/es')['ElRadioGroup'] ElRow: typeof import('element-plus/es')['ElRow'] ElSelect: typeof import('element-plus/es')['ElSelect'] ElSlider: typeof import('element-plus/es')['ElSlider'] + ElTable: typeof import('element-plus/es')['ElTable'] + ElTableColumn: typeof import('element-plus/es')['ElTableColumn'] + ElText: typeof import('element-plus/es')['ElText'] FactorCheckbox: typeof import('./components/monitor/FactorCheckbox.vue')['default'] FactorLegend: typeof import('./components/monitor/FactorLegend.vue')['default'] FactorRadio: typeof import('./components/monitor/FactorRadio.vue')['default'] @@ -45,4 +51,7 @@ SearchBar: typeof import('./components/search/SearchBar.vue')['default'] SliderBar: typeof import('./components/SliderBar.vue')['default'] } + export interface ComponentCustomProperties { + vLoading: typeof import('element-plus/es')['ElLoadingDirective'] + } } diff --git a/src/components/CardButton.vue b/src/components/CardButton.vue index e0cb7b3..6536cb9 100644 --- a/src/components/CardButton.vue +++ b/src/components/CardButton.vue @@ -1,9 +1,14 @@ <template> - <BaseCard type="btn" size="medium" direction="right" @click="handleClick"> + <BaseCard + type="btn" + size="medium" + :direction="direction" + @click="handleClick" + > <template #content> <div class="card-btn"> <img :src="src" class="ff-img m-b-8" /> - <span v-for="(item, index) in name" :key="index"> {{ item }}</span> + <span v-for="item in name" :key="item"> {{ item }}</span> </div> </template> </BaseCard> @@ -18,13 +23,13 @@ name: String, direction: { type: String, - default: 'left' + default: 'right' } }, emits: ['click'], data() { return { - src: this.direction ? shrinkLeft : shrinkRight + src: this.direction == 'right' ? shrinkRight : shrinkLeft }; }, computed: {}, diff --git a/src/components/SliderBar.vue b/src/components/SliderBar.vue index 7a1f519..6acf1bd 100644 --- a/src/components/SliderBar.vue +++ b/src/components/SliderBar.vue @@ -13,17 +13,22 @@ </el-select> </el-form-item> <div class="slider-wrap m-l-16"> - <el-slider v-model="progress" :marks="marks" @input="handleInput" /> + <el-slider :model-value="progress" :marks="marks" @input="handleInput" /> </div> </el-row> </template> <script> export default { - emits: ['input', 'sizeChange'], + props: { + progress: { + type: Number, + default: 0 + } + }, + emits: ['update:progress', 'sizeChange'], data() { return { pageSize: 200, - progress: 0, marks: { 0: { style: { @@ -43,7 +48,7 @@ methods: { handleInput(e) { // console.log(e); - this.$emit('input', e); + this.$emit('update:progress', e); }, handleSizeChange(e) { this.$emit('sizeChange', e); diff --git a/src/components/core/CoreMenu.vue b/src/components/core/CoreMenu.vue index 920f38f..a88e8cc 100644 --- a/src/components/core/CoreMenu.vue +++ b/src/components/core/CoreMenu.vue @@ -1,6 +1,6 @@ <template> <div class="map-mode-change p-events-auto"> - <template v-for="(item, index) in menu" :key="index"> + <template v-for="(item, index) in menu" :key="item.path"> <a :class="btnClz(item.selected)" @click="navTo(index)"> <div>{{ item.name }}</div> </a> diff --git a/src/components/map/MapToolbox.vue b/src/components/map/MapToolbox.vue index cabd44c..270e612 100644 --- a/src/components/map/MapToolbox.vue +++ b/src/components/map/MapToolbox.vue @@ -14,7 +14,7 @@ <el-dropdown-menu> <el-dropdown-item v-for="(item, index) in toolItem" - :key="index" + :key="item.label" :command="index" > <el-button diff --git a/src/components/monitor/DataSummary.vue b/src/components/monitor/DataSummary.vue new file mode 100644 index 0000000..4d4b9e2 --- /dev/null +++ b/src/components/monitor/DataSummary.vue @@ -0,0 +1,91 @@ +<template> + <el-row justify="end"> + <el-col span="4"> + <CardButton + name="鏁版嵁缁熻" + direction="left" + @click="() => (show = !show)" + ></CardButton> + </el-col> + <el-col span="20"> + <BaseCard v-show="show" direction="rigtht" borderless="r"> + <template #content> + <!-- <el-row> + <el-text style="color: white">鏁版嵁缁熻</el-text> + </el-row> --> + <el-table + :data="showSummary" + v-loading="loading" + table-layout="auto" + size="small" + :show-overflow-tooltip="true" + border + row-class-name="t-row" + cell-class-name="t-cell" + header-row-class-name="t-header-row" + header-cell-class-name="t-header-cell" + > + <el-table-column prop="factor" label="鍥犲瓙" width="66" /> + <el-table-column prop="avg" label="鍧囧��" width="66" /> + <el-table-column prop="min" label="鏈�灏忓��" width="66" /> + <el-table-column prop="max" label="鏈�澶у��" width="66" /> + </el-table> + </template> + </BaseCard> + </el-col> + </el-row> +</template> +<script> +import { FactorDatas } from '@/model/FactorDatas'; +import { factorName } from '@/constant/factor-name'; + +export default { + props: { + loading: Boolean, + factorDatas: FactorDatas, + selectFactorType: Array + }, + data() { + return { + show: true + }; + }, + computed: { + summary() { + const list = []; + for (const key in this.factorDatas.factor) { + if (Object.hasOwnProperty.call(this.factorDatas.factor, key)) { + const f = this.factorDatas.factor[key]; + let min, + max, + total = 0, + count = 0; + f.datas.forEach((v) => { + if (!min || v.factorData < min) { + min = v.factorData; + } + if (!max || v.factorData > max) { + max = v.factorData; + } + total += v.factorData; + count++; + }); + list.push({ + factorId: f.factorId, + factor: factorName[f.factorName], + min, + max, + avg: count == 0 ? 0 : Math.round((total / count) * 100) / 100 + }); + } + } + return list; + }, + showSummary() { + return this.summary.filter((v) => { + return this.selectFactorType.includes(v.factorId); + }); + } + } +}; +</script> diff --git a/src/components/monitor/DataTable.vue b/src/components/monitor/DataTable.vue index eff8fda..71de11d 100644 --- a/src/components/monitor/DataTable.vue +++ b/src/components/monitor/DataTable.vue @@ -1,61 +1,109 @@ <template> - <BaseCard> + <BaseCard size="medium" direction="right"> <template #content> <el-table - :data="tableData" + ref="tableRef" + :data="showData" v-loading="loading" - table-layout="fixed" - :row-class-name="tableRowClassName" - :height="tableHeight" + table-layout="auto" + height="calc(94vh - var(--bevel-length-2))" + size="small" + :show-overflow-tooltip="true" border + row-class-name="t-row" + cell-class-name="t-cell" + header-row-class-name="t-header-row" + header-cell-class-name="t-header-cell" + :show-summary="false" + :highlight-current-row="true" + @row-click="handleRowClick" > - <el-table-column prop="TIME" label="鏃堕棿" /> <el-table-column - v-for="(item, index) in tableColumn" - :key="index" - :prop="item.name" - :label="item.label" - /> + :fixed="true" + prop="TIME" + label="鏃堕棿" + :formatter="timeFormatter" + align="center" + width="66" + > + </el-table-column> + <template v-for="item in tableColumn" :key="item.name"> + <el-table-column + v-if="selectFactorType.includes(item.value)" + :prop="item.name" + :label="item.label" + align="center" + width="64" + /> + </template> </el-table> <el-pagination - v-if="pagination" ref="paginationRef" class="el-pagination" + small v-model:current-page="currentPage" v-model:page-size="pageSize" - :page-sizes="[10, 20, 50, 100]" - :background="true" - layout="total, sizes, prev, pager, next, jumper" - :total="total" + :page-sizes="[200, 500]" + :hide-on-single-page="false" + layout="prev, pager, next" + :total="tableData.length" /> </template> - <template #footer> </template> + <template #footer> + <el-row justify="end"> + <el-text size="small" type="warning" + >鍏� {{ tableData.length }} 鏉★紝{{ pageSize }}鏉�/椤�</el-text + > + </el-row> + </template> </BaseCard> </template> <script> +import moment from 'moment'; import { FactorDatas } from '@/model/FactorDatas'; import { checkboxOptions } from '@/constant/checkbox-options'; import { TYPE0 } from '@/constant/device-type'; export default { props: { + loading: Boolean, factorDatas: FactorDatas, deviceType: { type: String, // type0: 杞﹁浇鎴栨棤浜烘満; type1:鏃犱汉鑸� default: TYPE0 - } + }, + selectFactorType: { + type: Array, + default: () => ['1', '2', '3'] + }, + // 褰撳墠閫変腑楂樹寒鐨勬暟鎹偣绱㈠紩 + locateIndex: Number }, data() { return { tableHeight: '500', total: 0, currentPage: 1, - pageSize: 20, - loading: false + pageSize: 200, + rowHeight: undefined }; + }, + emits: ['tableClick'], + watch: { + locateIndex(nV, oV) { + if (nV == oV) return; + this.$refs.tableRef.setCurrentRow(this.tableData[nV]); + // 璁$畻鍒嗛〉 + this.currentPage = parseInt(nV / this.pageSize) + 1; + // 璁$畻瀵瑰簲鍒嗛〉涓殑绱㈠紩 + const index = nV % this.pageSize; + + const h = this.getRowHeight(); + this.$refs.tableRef.setScrollTop(h * index - 350); + } }, computed: { tableData() { @@ -65,18 +113,87 @@ const f = this.factorDatas.factor[key]; f.datas.forEach((v, i) => { if (list.length <= i) { - list.push({ [f.factorName]: v }); + list.push({ + index: i, + [f.factorName]: v.factorData + }); } else { - list[i][f.factorName] = v; + list[i][f.factorName] = v.factorData; } }); } } return list; }, + showData() { + const sIndex = (this.currentPage - 1) * this.pageSize; + const eIndex = sIndex + this.pageSize; + return this.tableData.slice(sIndex, eIndex); + }, tableColumn() { return checkboxOptions(this.deviceType); + } + }, + methods: { + // 鑾峰彇琛ㄦ牸绗竴琛岄珮搴� + getRowHeight() { + if (!this.rowHeight) { + const rowList = document.getElementsByClassName('t-row'); + if (rowList.length != 0) { + const row = rowList[0]; + this.rowHeight = row.getBoundingClientRect().height; + } else { + this.rowHeight = 0; + } + } + return this.rowHeight; + }, + timeFormatter(row, col, cellValue, index) { + return moment(cellValue).format('HH:mm:ss'); + }, + handleRowClick(row, col, event) { + this.$emit('tableClick', row.index); + // console.log(row); + // console.log(col); + // console.log(event.target.getBoundingClientRect().height); } } }; </script> +<style> +.el-table { + --el-table-bg-color: transparent; + --el-table-row-hover-bg-color: #23dad0a2; + --el-table-current-row-bg-color: #7dff5d96; + --el-table-text-color: var(--font-color); +} + +.t-row { + cursor: pointer; + background-color: transparent !important; +} + +.t-cell { + /* background: red !important; */ + /* height: 40px; + border: 1px solid black; */ +} + +.t-header-row { +} + +.t-header-cell { + background-color: var(--bg-color-2) !important; + text-align: center !important; + color: white !important; +} +.el-pagination { + --el-pagination-bg-color: transparent; + --el-pagination-button-bg-color: transparent; + --el-pagination-button-color: transparent; + --el-pagination-button-disabled-color: white; + --el-pagination-button-disabled-bg-color: transparent; + --el-pagination-text-color: white; + --el-pagination-button-color: white; +} +</style> diff --git a/src/components/monitor/FactorCheckbox.vue b/src/components/monitor/FactorCheckbox.vue index 43c1b93..7e236e3 100644 --- a/src/components/monitor/FactorCheckbox.vue +++ b/src/components/monitor/FactorCheckbox.vue @@ -1,17 +1,20 @@ <template> - <BaseCard direction="top-left" borderless="t"> + <BaseCard :direction="direction" :borderless="borderlessDirection"> <template #content> <el-checkbox-group - v-model="checkbox" + :model-value="modelValue" size="default" - @change="handleChange" + :min="1" + @update:model-value="handleChange" > - <el-checkbox - v-for="(item, i) in options" - :key="i" - :value="item.value" - >{{ item.label }}</el-checkbox - > + <div :class="vertical ? 'vertical-class' : ''"> + <el-checkbox + v-for="item in options" + :key="item.label" + :value="item.value" + >{{ item.label }}</el-checkbox + > + </div> </el-checkbox-group> </template> </BaseCard> @@ -24,13 +27,41 @@ export default { props: { + // 澶嶉�夋鍊� + modelValue: Array, deviceType: { type: String, // type0: 杞﹁浇鎴栨棤浜烘満; type1:鏃犱汉鑸� default: TYPE0 + }, + /** + * + * 鏍峰紡鏈濆悜 + * top-left | left + */ + direction: { + type: String, + default: 'top-left' + }, + /** + * 鏃犺竟妗嗙殑鏂瑰悜 + * t | r + */ + borderlessDirection: { + type: String, + default: 't' + }, + /** + * 鍐呭鏄惁鍨傜洿鎺掑竷 + */ + vertical: Boolean, + // 榛樿閫変腑鐨勪釜鏁帮紙浠庣涓�涓�夐」寮�濮嬶級 + defaultNum: { + type: Number, + default: 1 } }, - emits: ['change'], + emits: ['update:modelValue'], data() { return { checkbox: [checkboxOptions(TYPE0)[0].value] @@ -44,13 +75,19 @@ watch: { deviceType(nV, oV) { if (nV != oV) { - this.checkbox = this.options[0].value; + const res = []; + const array = checkboxOptions(nV); + for (let i = 0; i < this.defaultNum; i++) { + const e = array[i]; + res.push(e.value); + } + this.$emit('update:modelValue', res); } } }, methods: { handleChange(value) { - this.$emit('change', value); + this.$emit('update:modelValue', value); } } }; @@ -61,4 +98,9 @@ margin-right: 6px; /* height: initial; */ } + +.vertical-class { + display: flex; + flex-direction: column; +} </style> diff --git a/src/components/monitor/LineChart.vue b/src/components/monitor/LineChart.vue index 612cb61..2a0b846 100644 --- a/src/components/monitor/LineChart.vue +++ b/src/components/monitor/LineChart.vue @@ -6,7 +6,7 @@ <template #footer> <!-- 鍗曢〉鏁版嵁閲�--> <SliderBar - @input="(e) => (progress = e)" + v-model:progress="progress" @size-change="(e) => (pageSize = e)" ></SliderBar> </template> @@ -21,6 +21,7 @@ export default { props: { + loading: Boolean, factorDatas: { type: FactorDatas // default: () => new FactorDatas() @@ -28,7 +29,9 @@ selectFactorType: { type: Array, default: () => ['1'] - } + }, + // 褰撳墠閫変腑楂樹寒鐨勬暟鎹偣绱㈠紩 + locateIndex: Number }, data() { return { @@ -39,6 +42,7 @@ progress: 0 }; }, + emits: ['chartClick'], watch: { factorDatas: { handler() { @@ -56,6 +60,35 @@ this.changeChartRange(); }, pageSize() { + this.changeChartRange(); + }, + locateIndex(nV, oV) { + if (nV == oV) return; + // 1. 瀹氫綅鐐瑰簲璇ュ睍绀哄湪瓒嬪娍鍥句腑闂达紝鍥犳瀹氫綅鐧惧垎姣斿線鍓嶅亸绉诲綋鍓峗size鐨勪竴鍗� + let i = nV - parseInt(this.pageSize / 2); + // 2. 纭繚绱㈠紩涓嶄細瓒呭嚭鑼冨洿 + i = i < 0 ? 0 : i; + // 3. 鑾峰彇绱㈠紩瀵瑰簲鐨勮繘搴︾櫨鍒嗘瘮 + this.progress = (i / (this.allXAxis.length - this.pageSize)) * 100; + + for (const iterator of this.allSeries) { + // if (iterator.name == factorName || (iterator.name == 'TVOC' || factorName == 'VOC')) { + iterator.markLine = { + symbol: 'none', + data: [ + { + name: '閫変腑', + xAxis: this.allXAxis[nV], + label: { + color: 'white' + }, + lineStyle: { + color: 'yellow' + } + } + ] + }; + } this.changeChartRange(); } }, @@ -103,16 +136,18 @@ } // this.option.dataZoom[0].start = startPer; // this.option.dataZoom[0].end = endPer; - this.lineChart.setOption(this.option); + this.lineChart.setOption(this.option, { notMerge: true }); }, getShowXAxis(sIndex, eIndex) { return this.allXAxis.slice(sIndex, eIndex); }, getShowSeries(sIndex, eIndex) { - const res = this.allSeries.filter((s) => { + this.allSeries.forEach((s) => { if (sIndex && eIndex) { s.data = s.allData.slice(sIndex, eIndex); } + }); + const res = this.allSeries.filter((s) => { return this.selectFactorType.includes(s.key); }); return res; @@ -137,6 +172,9 @@ }, mounted() { this.lineChart = echarts.init(this.$refs.lineChart); + this.lineChart.on('click', (e) => { + this.$emit('chartClick', e.dataIndex); + }); } }; </script> diff --git a/src/model/FrameAnimation.js b/src/model/FrameAnimation.js new file mode 100644 index 0000000..ad4dd8c --- /dev/null +++ b/src/model/FrameAnimation.js @@ -0,0 +1,143 @@ +import moment from 'moment'; + +/** + * 甯у姩鐢绘帶鍒跺伐鍏� + * + */ +function FrameAnimation() { + // 鍔ㄧ敾甯ф暟 + this.fps = 12; + // 甯ч棿闅�(ms) + this.timeout = 1000 / this.fps; + this.speed = 1; + this.animationTask = []; + // 鍗曟鎻掑叆鏈�澶氫换鍔℃暟 + this.maxTasks = 10; + this.onNextTask; + + this.isPause = false; + this.isRunning = false; + // 鏄惁寮�鍚姩鎬佺粯鍒堕�熷害 + this.dynamicSpeed = false; + // 姣忎釜浠诲姟鑰楁椂锛堢锛� + this.taskPeriod = 4; + // 鏁版嵁鏈�鏂版椂闂� + this.lastestTime; +} + +FrameAnimation.prototype = { + start: function () { + if (this.intervalFlag != undefined) { + this.isPause = false; + } else { + this.isRunning = true; + this._doTask(); + } + }, + /** + * 鍔ㄦ�佸姩鐢婚�熷害 + * 褰撻〉闈㈠け鍘荤劍鐐规椂锛屽惊鐜换鍔s浼氭殏鍋滐紝姝ゆ椂鍚庣画鐨勮建杩瑰姩鐢诲氨浼氳寤跺悗锛� + * 鍚屾椂锛岀敱浜庢祻瑙堝櫒鎬ц兘闂锛屽綋杩愯鏃堕棿閫愭笎鍙橀暱鏃讹紝杞ㄨ抗鍔ㄧ敾涓庡疄闄呮椂闂寸殑宸�间篃浼氶�愭笎鎷夊ぇ锛� + * 鍥犳闇�瑕佸姩鎬佽皟鏁村姩鐢昏繍琛屽�嶉�燂紝涓庡疄闄呮椂闂翠繚鎸佺浉杩� + */ + dynamicAdjustment: function (time) { + if (this.dynamicSpeed && this.lastestTime) { + // 浠ヤ袱涓潗鏍囩偣锛堜竴娆ask锛変负鏈�灏忓崟浣嶏紝鏍规嵁褰撳墠缁樺埗鏁版嵁鏃堕棿鍜屾渶鏂版暟鎹椂闂寸殑宸�硷紝璋冩暣缁樺埗閫熷害 + var t1 = moment(time); + var t2 = moment(this.lastestTime); + var sec = Math.abs(t1.diff(t2, 'seconds')); // 鑾峰彇鏃堕棿宸� + + // 褰撴椂闂村樊瓒呰繃鍗曚换鍔¤�楁椂鏃讹紝闇�瑕侀�傚綋鍔犲揩鍔ㄧ敾閫熷害 + if (sec > this.taskPeriod) { + this.speed = Math.round(sec / this.taskPeriod); + if (this.speed > 16) { + // this.speed = 16 + } + } else { + this.speed = 1; + } + } + }, + changeSpeed: function (speed) { + if (typeof speed === 'number') { + this.speed = speed; + } + }, + pause: function () { + this.isPause = true; + }, + stop: function () { + if (this.intervalFlag != undefined) { + clearInterval(this.intervalFlag); + this.intervalFlag = undefined; + this.animationTask = []; + } + + // 褰撳墠浠诲姟鍒楄〃缁撴潫鍚庯紝棣栧厛鍒ゆ柇鏄惁鏈変笅涓�娈典换鍔� + if (this.onNextTask) { + this.onNextTask(); + return; + } + + if (typeof this.onStopCallback === 'function') { + this.onStopCallback(); + } + + this.isRunning = false; + this.isPause = false; + this.lastestTime = undefined; + }, + setOnStopCallback: function (callback) { + this.onStopCallback = callback; + }, + addTask: function (count, data, callback) { + var task = { + data: data, + count: count, + task: callback + }; + this.animationTask.push(task); + // console.log('FrameAnimation: addTask ' + count); + }, + // 浠诲姟閲囧彇鍒嗘鎵ц鏂瑰紡锛屽嵆褰撳綋鍓嶄换鍔″垪琛ㄦ墽琛屽畬鎴愬悗锛岀户缁紑濮嬪鐞嗕笅涓�娈典换鍔� + addOnNextTasks: function (callback) { + this.onNextTask = callback; + }, + runStatus: function () { + return this.isRunning; + }, + _doTask: function () { + if (this.animationTask.length > 0) { + var t = this.animationTask[0]; + + // 鍔ㄦ�佽皟鏁撮�熷害 + this.dynamicAdjustment(t.data.times[t.data.times.length - 1]); + + var index = 0; + this.intervalFlag = setInterval(() => { + if (this.isPause) { + return; + } + if (index >= t.count) { + this._endTask(this.intervalFlag); + return; + } + t.task(t.data, index, t.count); + + index += this.speed; + // console.log("_doTask:" + index); + }, this.timeout); + } + }, + _endTask: function (intervalFlag) { + clearInterval(intervalFlag); + this.animationTask.splice(0, 1); + if (this.animationTask.length > 0) { + this._doTask(); + } else { + this.stop(); + } + } +}; + +export { FrameAnimation }; diff --git a/src/utils/map/3dLayer.js b/src/utils/map/3dLayer.js index 251ce09..9ba66bd 100644 --- a/src/utils/map/3dLayer.js +++ b/src/utils/map/3dLayer.js @@ -87,89 +87,88 @@ return scale; } -/** - * 缁樺浘 - */ -function drawMesh(fDatas, factor, center, merge) { - const lnglats_GD = fDatas.lnglats_GD; - const coors = fDatas.coors_GD; - const heights = factor.heights; - const colors = factor.colors; - const bColor = factor.bottomColor; - if (center) { - map.setZoomAndCenter(16, center); - } - - // eslint-disable-next-line no-undef - var cylinder = new AMap.Object3D.Mesh(); - cylinder.backOrFront = 'both'; - cylinder.transparent = true; - - var geometry = cylinder.geometry; - - const scale = _getScale(_minH, _maxH); - for (let i = 0; i < coors.length; i++) { - var r = lnglats_GD[i]; - var lastP = lnglats_GD[i - 1]; - var p = coors[i]; - var h = (heights[i] - _minH) * scale + _minHeight; - if (heights[i] == -1) { - h = -1; - } - - geometry.vertices.push(p.x, p.y, 0); //搴曢儴椤剁偣 - geometry.vertices.push(p.x, p.y, 0 - h); //椤堕儴椤剁偣 - - if (i > 0) { - // eslint-disable-next-line no-undef - var distance = AMap.GeometryUtil.distance(r, lastP); - //涓や釜鏁版嵁鐐规渶灏忛棿闅旀椂闂翠负4s锛屽亣璁捐溅閫熸寜鐓�120km/h璁$畻锛�4s琛岄┒鏈�澶ц窛绂讳綔涓�132绫筹紝 - //璁惧畾瓒呰繃1鍒嗛挓鐨勬暟鎹粯鍒剁壒娈婄殑杩炵嚎 - if (distance <= 500 && h != -1) { - var bottomIndex = i * 2; - var topIndex = bottomIndex + 1; - var lastBottomIndex = bottomIndex - 2; - var lastTopIndex = bottomIndex - 1; - geometry.faces.push(bottomIndex, topIndex, lastTopIndex); - geometry.faces.push(bottomIndex, lastBottomIndex, lastTopIndex); - } - } - - // var bColor = bColor - var tColor = colors[i]; - geometry.vertexColors.push.apply(geometry.vertexColors, bColor); //搴曢儴椤剁偣棰滆壊 - geometry.vertexColors.push.apply(geometry.vertexColors, tColor); //椤堕儴椤剁偣棰滆壊 - } - - // 7.鏍规嵁鍚堝苟閫夐」閲嶇疆鎴栨柊澧炲綋鍓嶇紦瀛樻暟鎹� - if (merge != true) { - _factorDatas = fDatas; - _factor = factor; - if (_cylinder != undefined) { - object3Dlayer.remove(_cylinder); - } - } else { - // _factorDatas.lnglats.push.apply( - // _factorDatas.lnglats, - // lnglats_GD - // ); - // _factorDatas.coors.push.apply(_factorDatas.coors, coors); - // _factorDatas.heights.push.apply(_factorDatas.heights, heights); - // _factorDatas.colors.push.apply(_factorDatas.colors, colors); - // _factorDatas.bottomColor = bColor; - } - object3Dlayer.add(cylinder); - /**************test ****************/ - // object3Dlayer.on('mouseover', function (e) { - // console.log( - // `榧犳爣绉诲叆瑕嗙洊鐗�! [${e.lnglat.getlng()}, ${e.lnglat.getLat()}]` - // ); - // }); - /**************test ****************/ - _cylinder = cylinder; -} - export default { + /** + * 缁樺浘 + */ + drawMesh(fDatas, factor, center, merge) { + const lnglats_GD = fDatas.lnglats_GD; + const coors = fDatas.coors_GD; + const heights = factor.heights; + const colors = factor.colors; + const bColor = factor.bottomColor; + if (center) { + map.setZoomAndCenter(16, center); + } + + // eslint-disable-next-line no-undef + var cylinder = new AMap.Object3D.Mesh(); + cylinder.backOrFront = 'both'; + cylinder.transparent = true; + + var geometry = cylinder.geometry; + + const scale = _getScale(_minH, _maxH); + for (let i = 0; i < coors.length; i++) { + var r = lnglats_GD[i]; + var lastP = lnglats_GD[i - 1]; + var p = coors[i]; + var h = (heights[i] - _minH) * scale + _minHeight; + if (heights[i] == -1) { + h = -1; + } + + geometry.vertices.push(p.x, p.y, 0); //搴曢儴椤剁偣 + geometry.vertices.push(p.x, p.y, 0 - h); //椤堕儴椤剁偣 + + if (i > 0) { + // eslint-disable-next-line no-undef + var distance = AMap.GeometryUtil.distance(r, lastP); + //涓や釜鏁版嵁鐐规渶灏忛棿闅旀椂闂翠负4s锛屽亣璁捐溅閫熸寜鐓�120km/h璁$畻锛�4s琛岄┒鏈�澶ц窛绂讳綔涓�132绫筹紝 + //璁惧畾瓒呰繃1鍒嗛挓鐨勬暟鎹粯鍒剁壒娈婄殑杩炵嚎 + if (distance <= 500 && h != -1) { + var bottomIndex = i * 2; + var topIndex = bottomIndex + 1; + var lastBottomIndex = bottomIndex - 2; + var lastTopIndex = bottomIndex - 1; + geometry.faces.push(bottomIndex, topIndex, lastTopIndex); + geometry.faces.push(bottomIndex, lastBottomIndex, lastTopIndex); + } + } + + // var bColor = bColor + var tColor = colors[i]; + geometry.vertexColors.push.apply(geometry.vertexColors, bColor); //搴曢儴椤剁偣棰滆壊 + geometry.vertexColors.push.apply(geometry.vertexColors, tColor); //椤堕儴椤剁偣棰滆壊 + } + + // 7.鏍规嵁鍚堝苟閫夐」閲嶇疆鎴栨柊澧炲綋鍓嶇紦瀛樻暟鎹� + if (merge != true) { + _factorDatas = fDatas; + _factor = factor; + if (_cylinder != undefined) { + object3Dlayer.remove(_cylinder); + } + } else { + // _factorDatas.lnglats.push.apply( + // _factorDatas.lnglats, + // lnglats_GD + // ); + // _factorDatas.coors.push.apply(_factorDatas.coors, coors); + // _factorDatas.heights.push.apply(_factorDatas.heights, heights); + // _factorDatas.colors.push.apply(_factorDatas.colors, colors); + // _factorDatas.bottomColor = bColor; + } + object3Dlayer.add(cylinder); + /**************test ****************/ + // object3Dlayer.on('mouseover', function (e) { + // console.log( + // `榧犳爣绉诲叆瑕嗙洊鐗�! [${e.lnglat.getlng()}, ${e.lnglat.getLat()}]` + // ); + // }); + /**************test ****************/ + _cylinder = cylinder; + }, /** * 缁樺埗3D璧拌璺嚎鍥� * @param fDatas 瀹屾暣鐩戞祴鏁版嵁 @@ -213,7 +212,7 @@ } // 5.缁樺埗3D鍥惧舰 - drawMesh(fDatas, factor, center, merge); + this.drawMesh(fDatas, factor, center, merge); // 缂╂斁鍦板浘鍒板悎閫傜殑瑙嗛噹绾у埆 // map.setFitView() diff --git a/src/utils/map/animation.js b/src/utils/map/animation.js new file mode 100644 index 0000000..551b3bb --- /dev/null +++ b/src/utils/map/animation.js @@ -0,0 +1,389 @@ +import { FrameAnimation } from '@/model/FrameAnimation'; +import calculate from '@/utils/map/calculate'; +import Layer from '@/utils/map/3dLayer'; +import sector from '@/utils/map/sector'; +import map from '@/utils/map/index_old'; + +function MapAnimation() { + // 闈炶繛缁潗鏍囩偣鏈�澶ц窛绂�(绫�) + this.maxD = 500; + // 褰撳墠缁樺埗鐨勭洃娴嬪洜瀛愮被鍨� + this.factorType = 0; + this.factorDatas; + // 杞藉叿绫诲瀷 + this.vehicleType = 0; // 0: 杞﹁締锛�1锛氭棤浜烘満锛�2锛氭棤浜鸿埞 + // 甯у姩鐢绘帶鍒跺伐鍏� + this.frameAnimation = new FrameAnimation(); + // 鍔ㄧ敾甯ф暟 + this._fps = this.frameAnimation.fps; + // 缁樺埗鍥惧舰缂撳瓨 + this.moveViews = {}; +} + +MapAnimation.prototype = { + setFactorType: function (factorType) { + this.factorType = factorType; + }, + + /** + * 璁剧疆杞藉叿绫诲瀷锛屽搴旀樉绀轰笉鍚岀殑鍥炬爣 + */ + setVehicleType: function (t) { + this.vehicleType = t; + this.moveViews = {}; + }, + + /** + * 杞﹁締绉诲姩鍔ㄧ敾 + * @param {*} factorDatas + * @param {*} factorType + */ + moveAnimation: function (factorDatas, factorType, startIndex) { + // MapUtil.drawLine(factorDatas.lnglats_GD) + + // 璁剧疆褰撳墠鏁版嵁鐨勬渶鏂版椂闂� + this.frameAnimation.lastestTime = + factorDatas.times[factorDatas.times.length - 1]; + + // 褰撴暟鎹紦瀛樹笉涓虹┖鏃讹紝璇存槑涓婁竴娆$殑缁樺埗杩樻湭缁撴潫锛屾墍浠ュ彧鏇存柊鏁版嵁婧愬嵆鍙� + if (this.factorDatas != undefined) { + this.factorType = factorType; + this.factorDatas = factorDatas; + return; + } + + this.factorType = factorType; + this.factorDatas = factorDatas; + + this.startIndex = startIndex == undefined ? 0 : startIndex; + // 涓�娆℃�ф渶澶氳绠梉this.frameAnimation.maxTasks]涓潗鏍囩偣鐨勭粯鍒惰建杩癸紝缁樺埗瀹屾垚鍚庡啀娆¤绠楋紝鎻愬崌鍓嶇缃戦〉鍝嶅簲閫熷害 + this.endIndex = this.startIndex + this.frameAnimation.maxTasks; + if (this.endIndex >= factorDatas.length()) { + this.endIndex = factorDatas.length() - 1; + } + + // console.log(new Date()); + this.nextAnimation(this.startIndex, factorDatas, this.endIndex); + // console.log(new Date()); + }, + + nextAnimation: function (start, factorDatas, endIndex) { + if (factorDatas == undefined) { + return; + } + var that = this; + + // 鏁版嵁鏍煎紡杞崲 + for (let i = start; i < factorDatas.length(); i++) { + // 缁堢偣 + if (i == endIndex || i == factorDatas.length() - 1) { + break; + } + // 鍔ㄧ敾杞ㄨ抗 + var animationData = factorDatas.getByIndex(0, i + 1); + + // 璺緞鐐� + var sPos = factorDatas.lnglats_GD[i]; + var ePos = factorDatas.lnglats_GD[i + 1]; + // 缁堢偣鐩稿璧风偣鐨勮搴� + var angle = this._getAngle(sPos, ePos); + // 璺緞鎬婚暱搴� + // eslint-disable-next-line no-undef + var distance = AMap.GeometryUtil.distance(sPos, ePos); + + // 鏃堕棿宸� + var d1 = new Date(factorDatas.times[i]); + var d2 = new Date(factorDatas.times[i + 1]); + var duration = (d2 - d1) / 1000; + // 鎬诲抚鏁� + var count = duration * this._fps; + // 鍗曞抚璺濈 + var d = distance / count; + // 姣忎釜fps瀵瑰簲鐨勫疄闄呮椂闀�(榛樿1绉�) + var t = 1; + // 涓ょ偣闂翠笉杩炵画鏃� + if (distance > this.maxD) { + count = 4 * this._fps; + d = distance / count; + t = duration / (count / this._fps); + } + + // 鐩戞祴鏁版嵁 + // var fData1 = factorDatas.getByIndex(i, i + 1) + var fData2 = factorDatas.getByIndex(i + 1, i + 2); + + // 璁$畻鍔ㄧ敾杞ㄨ抗 + for (let i = 0; i < count - 1; i++) { + // path + var length = d * (i + 1); + if (isNaN(angle)) { + animationData.lnglats_GD.push(sPos); + } else { + var point = this._getLatLon(sPos, length, angle); + animationData.lnglats_GD.push(point); + } + // time + var time = d1.format('yyyy-MM-dd hh:mm:ss'); + if ((i + 1) % this._fps == 0) { + var t1 = d1.getTime(); + d1.setTime(t1 + t * 1000); + time = d1.format('yyyy-MM-dd hh:mm:ss'); + } + animationData.times.push(time); + } + // factor + for (const key in animationData.factor) { + var factor = animationData.factor[key]; + factor.insertFrame(fData2.factor[key], count, distance <= this.maxD); + } + + animationData.refreshHeight(); + var coor_GD = calculate.lngLatToGeodeticCoord(animationData.lnglats_GD); + animationData.coors_GD = coor_GD; + + this.frameAnimation.addTask( + count, + animationData, + function (data, index, count) { + var length = data.length(); + var start = length - count + 1; + // 1.鑾峰彇鏁版嵁 + var d = data.getByIndex(0, start + index + 1); + var f = d.factor[that.factorType + 1 + '']; + // 2.缁樺埗鍥惧舰 + if (length > count || index > 0) { + // 3d鍥惧舰 + // var lnglat = d.lnglats_GD[d.lnglats_GD.length - 1]; + Layer.drawMesh(d, f); + // MapUtil.drawLine(lnglat) + + // 椋庡悜椋庨�� + sector.drawSector(d, start + index); + // if (d.factor['17'] != undefined && d.factor['16'] != undefined) { + // var windDir = d.factor['17'].datas; + // windDir = windDir[windDir.length - 1].factorData; + // var windSpeed = d.factor['16'].datas; + // windSpeed = windSpeed[windSpeed.length - 1].factorData; + // MapUtil.drawSector4(lnglat, windDir, windSpeed); + // } + } + + var pos = d.lnglats_GD[d.lnglats_GD.length - 1]; + var time = d.times[d.times.length - 1].slice(10); + // 缁樺埗杞﹁締鍥炬爣鍜屾椂闂存枃鏈� + var status = 0; + // 鍋滄 + if (index + 1 == count) { + status = 1; + } + // 琛岄┒涓� + else { + status = 2; + } + that._setPosition(pos, time, status); + // console.log("animation"); + } + ); + } + + // 褰揺ndIndex宸茬粡鏄渶鍚庝竴涓潗鏍囩偣鏃讹紝璺緞缁樺埗缁撴潫锛屽惁鍒欏紑濮嬩笅涓�娈佃矾寰勭粯鍒� + if (that.endIndex < that.factorDatas.length() - 1) { + that.startIndex = that.endIndex; + that.endIndex = that.startIndex + that.frameAnimation.maxTasks; + if (that.endIndex >= that.factorDatas.length) { + that.endIndex = that.factorDatas.length - 1; + } + var cb = function () { + that.nextAnimation(that.startIndex, that.factorDatas, that.endIndex); + }; + that.frameAnimation.addOnNextTasks(cb); + } + // 褰撳叏閮ㄦ暟鎹粯鍒跺畬鎴愭椂锛屾竻绌烘暟鎹� + else { + that.factorDatas = undefined; + that.frameAnimation.addOnNextTasks(undefined); + } + + this.start(); + }, + + /*******************************鍔ㄧ敾浠诲姟閫昏緫 -start ******************************/ + start: function () { + sector.clearSector(); + this.frameAnimation.start(); + }, + changeSpeed: function (speed) { + this.frameAnimation.changeSpeed(speed); + }, + pause: function () { + this.frameAnimation.pause(); + }, + stop: function () { + this.factorDatas = undefined; + this.frameAnimation.addOnNextTasks(undefined); + this.frameAnimation.stop(); + }, + setOnStopCallback: function (callback) { + this.frameAnimation.setOnStopCallback( + function () { + this._clearMap(); + callback(); + }.bind(this) + ); + }, + runStatus: function () { + return this.frameAnimation.runStatus(); + }, + /** + * 璁剧疆鏄惁寮�鍚姩鎬佺粯鍒堕�熷害 + */ + setDynamicSpeed: function (b, sec) { + if (b) { + this.frameAnimation.dynamicSpeed = true; + this.frameAnimation.taskPeriod = sec; + } else { + this.frameAnimation.dynamicSpeed = false; + this.frameAnimation.taskPeriod = sec; + } + }, + /*******************************鍔ㄧ敾浠诲姟閫昏緫 -end ******************************/ + + _clearMap: function () { + var list = []; + for (const key in this.moveViews) { + list.push(this.moveViews[key]); + } + map.remove(list); + this.moveViews = {}; + sector.clearSector(); + }, + _setPosition: function (pos, time, status) { + // eslint-disable-next-line no-undef + var lnglat = new AMap.LngLat(...pos); + if (this.moveViews['text'] == undefined) { + var url; + switch (this.vehicleType) { + case 0: + url = './asset/mipmap/car_driving.png'; + break; + case 1: + url = './asset/mipmap/car_driving.png'; + break; + case 2: + url = './asset/mipmap/boat_driving.png'; + break; + default: + url = './asset/mipmap/car_driving.png'; + break; + } + // var url = "./asset/mipmap/car_offline.png"; + // switch (status) { + // case 0: + // url = "./asset/mipmap/car_offline.png"; + // break; + // case 1: + // url = "./asset/mipmap/car_stop.png"; + // break; + // case 2: + // url = "./asset/mipmap/car_driving.png"; + // break; + // default: + // url = "./asset/mipmap/car_stop.png"; + // break; + // } + + var icon = new AMap.Icon({ + size: new AMap.Size(60, 30), + imageSize: new AMap.Size(54, 21), + image: url + // imageOffset: new AMap.Pixel(-16, -16) // 鐩稿浜庡熀鐐圭殑鍋忕Щ浣嶇疆 + }); + + var car = new AMap.Marker({ + icon: icon, + position: lnglat, // 鍩虹偣浣嶇疆 + offset: new AMap.Pixel(-20, -15) // 鐩稿浜庡熀鐐圭殑鍋忕Щ浣嶇疆 + }); + + MapUtil._map.add(car); + this.moveViews['car'] = car; + + // 鏃堕棿 + var text = new AMap.Text({ + text: time, + position: lnglat, + offset: new AMap.Pixel(5, 20), + style: { + 'font-size': '13px', + 'text-align': 'center', + color: 'black', + 'background-color': 'white', + // 'text-shadow': 'black 2px 2px 2px', + 'border-radius': '2px', + border: '0px', + padding: '0 4px' + } + }); + MapUtil._map.add(text); + this.moveViews['text'] = text; + } else { + MapUtil.setCenter(lnglat); + this.moveViews['car'].setPosition(lnglat); + this.moveViews['text'].setPosition(lnglat); + this.moveViews['text'].setText(time); + } + }, + _setStatus: function (status) {}, + + /** + * 鏍规嵁鍧愭爣鐐广�佽窛绂诲拰瑙掑害锛屽緱鍒板彟涓�涓潗鏍囩偣 + * @param {*} pos + * @param {*} distance 绫� + * @param {*} angle + */ + _getLatLon: function (pos, distance, angle) { + var Ea = 6378137; // 璧ら亾鍗婂緞 + var Eb = 6356725; // 鏋佸崐寰� + var dx = distance * Math.sin((angle * Math.PI) / 180); + var dy = distance * Math.cos((angle * Math.PI) / 180); + var ec = Eb + ((Ea - Eb) * (90.0 - pos[1])) / 90.0; + var ed = ec * Math.cos((pos[1] * Math.PI) / 180); + var lng = ((dx / ed + (pos[0] * Math.PI) / 180.0) * 180.0) / Math.PI; + var lat = ((dy / ec + (pos[1] * Math.PI) / 180.0) * 180.0) / Math.PI; + return [lng, lat]; + }, + + /** + * 鏍规嵁涓や釜鍧愭爣鐐硅幏寰楃浉瀵硅搴� + * @param {*} sPos + * @param {*} ePos + */ + _getAngle: function (sPos, ePos) { + var lng_a = sPos[0]; + var lat_a = sPos[1]; + var lng_b = ePos[0]; + var lat_b = ePos[1]; + + var a = ((90 - lat_b) * Math.PI) / 180; + var b = ((90 - lat_a) * Math.PI) / 180; + var AOC_BOC = ((lng_b - lng_a) * Math.PI) / 180; + var cosc = + Math.cos(a) * Math.cos(b) + Math.sin(a) * Math.sin(b) * Math.cos(AOC_BOC); + var sinc = Math.sqrt(1 - cosc * cosc); + var sinA = (Math.sin(a) * Math.sin(AOC_BOC)) / sinc; + var A = (Math.asin(sinA) * 180) / Math.PI; + var res = 0; + if (lng_b > lng_a && lat_b > lat_a) res = A; + else if (lng_b > lng_a && lat_b < lat_a) res = 180 - A; + else if (lng_b < lng_a && lat_b < lat_a) res = 180 - A; + else if (lng_b < lng_a && lat_b > lat_a) res = 360 + A; + else if (lng_b > lng_a && lat_b == lat_a) res = 90; + else if (lng_b < lng_a && lat_b == lat_a) res = 270; + else if (lng_b == lng_a && lat_b > lat_a) res = 0; + else if (lng_b == lng_a && lat_b < lat_a) res = 180; + + return res; + } +}; + +export { MapAnimation }; diff --git a/src/utils/map/dialog.js b/src/utils/map/dialog.js index 54292bd..443f87b 100644 --- a/src/utils/map/dialog.js +++ b/src/utils/map/dialog.js @@ -1,6 +1,7 @@ -import { factorName } from '../../constant/factor-name'; -import { factorUnit } from '../../constant/factor-unit'; -import { windDir } from '../../constant/wind-dir'; +import { factorName } from '@/constant/factor-name'; +import { factorUnit } from '@/constant/factor-unit'; +import { windDir } from '@/constant/wind-dir'; +import { map } from './index_old'; export const DialogUtil = { show: true, @@ -152,7 +153,8 @@ // 瀹氫箟椤堕儴鏍囬 var top = document.createElement('div'); // top.className = "info-top"; - top.className = 'ff-content ff-content-top-left ff-content-small-borderless-t info-top'; + top.className = + 'ff-content ff-content-top-left ff-content-small-borderless-t info-top'; var top_b = document.createElement('div'); top_b.className = 'ff-border-bottom'; var top_t = document.createElement('div'); @@ -246,13 +248,13 @@ return info; }, - openNewWindow(factorDatas, i, map, position, onClose) { + openNewWindow(factorDatas, i, onClose) { if (!this.show) return; const window = this.createInfoWindow(factorDatas, i, onClose); - window.open(map, position); + window.open(map, factorDatas.lnglats_GD[i]); }, - openNewWindow2(factorData, map, position, onClose) { + openNewWindow2(factorData, position, onClose) { if (!this.show) return; const window = this.createInfoWindow2(factorData, onClose); window.open(map, position); diff --git a/src/utils/map/marks.js b/src/utils/map/marks.js index 94144d2..0d3c21d 100644 --- a/src/utils/map/marks.js +++ b/src/utils/map/marks.js @@ -52,17 +52,8 @@ }); massMarks.on('click', (event) => { const i = event.data.id; - // 1. 缁樺埗鎵囧舰鍖哄煙 - sector.drawSector(fDatas, i); - - // 2. 缁樺埗瀵硅瘽妗� - DialogUtil.openNewWindow(fDatas, i, map, lnglats[i], () => { - // 绉婚櫎鎵囧舰鍖哄煙 - // clearSector3(); - }); - // 3. 鑷畾涔夌偣鍑讳簨浠� - onClick(); + onClick(i); }); // eslint-disable-next-line no-undef var marker = new AMap.Marker({ diff --git a/src/utils/map/sector.js b/src/utils/map/sector.js index 846eff2..f2aa490 100644 --- a/src/utils/map/sector.js +++ b/src/utils/map/sector.js @@ -1,25 +1,25 @@ import { map, object3Dlayer } from './index_old'; import calculate from './calculate'; +import imgLocation from '@/assets/mipmap/location.png'; var _defaultDeg = 30, _sector = undefined, _sectorViews = {}; -function clearSector() { - var list = []; - for (const key in _sectorViews) { - list.push(_sectorViews[key]); - } - if (list.length > 0) { - map.remove(list); - _sectorViews = {}; - } - if (_sector) { - object3Dlayer.remove(_sector); - } -} - export default { + clearSector() { + var list = []; + for (const key in _sectorViews) { + list.push(_sectorViews[key]); + } + if (list.length > 0) { + map.remove(list); + _sectorViews = {}; + } + if (_sector) { + object3Dlayer.remove(_sector); + } + }, drawSector(fDatas, i) { const lnglat = fDatas.lnglats_GD[i]; let windDir = fDatas.factor[17].datas[i].factorData; @@ -31,7 +31,7 @@ return; } if (_sector != undefined) { - clearSector(); + this.clearSector(); } // eslint-disable-next-line no-undef @@ -126,7 +126,7 @@ styles: [ { icon: { - img: './asset/mipmap/location.png', + img: imgLocation, size: [16, 16], //鍙鍖哄煙鐨勫ぇ灏� ancher: [8, 16], //閿氱偣 fitZoom: 18, //鏈�鍚堥�傜殑绾у埆 @@ -152,7 +152,7 @@ styles: [ { icon: { - img: './asset/mipmap/location.png', + img: imgLocation, size: [16, 16], //鍙鍖哄煙鐨勫ぇ灏� ancher: [8, 16], //閿氱偣 fitZoom: 18, //鏈�鍚堥�傜殑绾у埆 @@ -182,7 +182,7 @@ styles: [ { icon: { - img: './asset/mipmap/location.png', + img: imgLocation, size: [16, 16], //鍙鍖哄煙鐨勫ぇ灏� ancher: [8, 16], //閿氱偣 fitZoom: 18, //鏈�鍚堥�傜殑绾у埆 @@ -207,7 +207,7 @@ styles: [ { icon: { - img: './asset/mipmap/location.png', + img: imgLocation, size: [16, 16], //鍙鍖哄煙鐨勫ぇ灏� ancher: [8, 16], //閿氱偣 fitZoom: 18, //鏈�鍚堥�傜殑绾у埆 diff --git a/src/views/historymode/HistoryMode.vue b/src/views/historymode/HistoryMode.vue index fc56796..817a150 100644 --- a/src/views/historymode/HistoryMode.vue +++ b/src/views/historymode/HistoryMode.vue @@ -20,23 +20,36 @@ </el-row> <TrendAnalysis class="trend-analysis" + :locate-index="locateIndex" + @chart-click="handelIndexChange" :factor-datas="factorDatas" + :device-type="deviceType" ></TrendAnalysis> + <DataSheet + class="data-sheet" + :locate-index="locateIndex" + @table-click="handelIndexChange" + :factor-datas="factorDatas" + :device-type="deviceType" + ></DataSheet> </div> </template> <script> import Layer from '@/utils/map/3dLayer'; import marks from '@/utils/map/marks'; +import sector from '@/utils/map/sector'; +import { DialogUtil } from '@/utils/map/dialog'; import monitorDataApi from '@/api/monitorDataApi'; import { useFetchData } from '@/composables/fetchData'; import moment from 'moment'; import { TYPE0 } from '@/constant/device-type'; import { FactorDatas } from '@/model/FactorDatas'; import TrendAnalysis from './component/TrendAnalysis.vue'; +import DataSheet from './component/DataSheet.vue'; export default { - components: { TrendAnalysis }, + components: { TrendAnalysis, DataSheet }, setup() { const { loading, fetchData } = useFetchData(10000); return { loading, fetchData }; @@ -55,7 +68,9 @@ setCenter: true, // 缁樺埗妯″紡锛�0锛氳嚜鍔ㄦā寮忥紝鑷姩璁$畻褰撳墠鏁版嵁鐨勮寖鍥达紝缁樺埗鍚堥�傜殑姣斾緥锛�1锛氭墜鍔ㄦā寮忥紝鏍规嵁椤甸潰璁剧疆鐨勭粯鍥捐寖鍥磋繘琛岀粯鍒� drawMode: 0, - searchTime: [] + searchTime: [], + // 褰撳墠閫変腑楂樹寒鐨勬暟鎹偣绱㈠紩 + locateIndex: undefined }; }, watch: { @@ -66,6 +81,11 @@ } }, methods: { + // 鐩戝惉鎶樼嚎鍥惧拰琛ㄦ牸鐨勭偣鍑讳簨浠� + handelIndexChange(index) { + this.locateIndex = index; + this.drawSector(index); + }, draw() { // todo 鍒锋柊鍥句緥 const factor = this.factorDatas.factor[this.factorType]; @@ -85,13 +105,24 @@ // } }, drawMassMarks(e) { - marks.drawMassMarks(this.factorDatas, e, () => { + marks.drawMassMarks(this.factorDatas, e, (index) => { // 鏌ヨ鑼冨洿鍐呯殑鐩戞祴绔欑偣 // SceneUtil.searchByCoordinate(lnglat[0], lnglat[1], distance); // 3. 瓒嬪娍鍥捐烦杞畾浣� // const progress = FChart.locate(lineChart.chart, lineChart.option, i, _factor.factorName); // 4. 琛ㄦ牸鏁版嵁璺宠浆瀹氫綅 // Table.locate(i); + this.drawSector(index); + this.locateIndex = index; + }); + }, + drawSector(index) { + // 1. 缁樺埗鎵囧舰鍖哄煙 + sector.drawSector(this.factorDatas, index); + // 2. 缁樺埗瀵硅瘽妗� + DialogUtil.openNewWindow(this.factorDatas, index, () => { + // 绉婚櫎鎵囧舰鍖哄煙 + // clearSector3(); }); }, onFetchData(type, data) { @@ -155,4 +186,10 @@ left: 0; bottom: 2px; } + +.data-sheet { + position: absolute; + right: 0; + top: 0; +} </style> diff --git a/src/views/historymode/component/DataSheet.vue b/src/views/historymode/component/DataSheet.vue index e69de29..9d2cfbe 100644 --- a/src/views/historymode/component/DataSheet.vue +++ b/src/views/historymode/component/DataSheet.vue @@ -0,0 +1,77 @@ +<template> + <el-row class="wrap"> + <el-col span="2" class="flex-col"> + <el-row justify="end"> + <CardButton + name="璧拌埅鏁版嵁璇︽儏" + direction="left" + @click="() => (show = !show)" + ></CardButton> + </el-row> + <el-row class="flex-col"> + <DataSummary + v-show="show" + :loading="loading" + :factor-datas="factorDatas" + :select-factor-type="selectFactorType" + ></DataSummary> + </el-row> + </el-col> + <el-col v-show="show" span="10"> + <el-row align="bottom"> + <DataTable + :loading="loading" + :select-factor-type="selectFactorType" + :factor-datas="factorDatas" + :device-type="deviceType" + :locate-index="locateIndex" + @table-click="handleTableClick" + ></DataTable> + <FactorCheckbox + direction="left" + vertical + borderless-direction="r" + v-model="selectFactorType" + :device-type="deviceType" + ></FactorCheckbox> + </el-row> + </el-col> + </el-row> +</template> +<script> +import { TYPE0 } from '@/constant/device-type'; +import { FactorDatas } from '@/model/FactorDatas'; + +export default { + props: { + loading: Boolean, + factorDatas: FactorDatas, + deviceType: { + type: String, + // type0: 杞﹁浇鎴栨棤浜烘満; type1:鏃犱汉鑸� + default: TYPE0 + }, + // 褰撳墠閫変腑楂樹寒鐨勬暟鎹偣绱㈠紩 + locateIndex: Number + }, + data() { + return { + selectFactorType: ['1', '2', '3'], + show: false + }; + }, + emits: ['tableClick'], + methods: { + handleTableClick(index) { + this.$emit('tableClick', index); + } + } +}; +</script> +<style scoped> +.flex-col { + display: flex; + flex-direction: column; + justify-content: space-between; +} +</style> diff --git a/src/views/historymode/component/TrendAnalysis.vue b/src/views/historymode/component/TrendAnalysis.vue index 7960195..06be06b 100644 --- a/src/views/historymode/component/TrendAnalysis.vue +++ b/src/views/historymode/component/TrendAnalysis.vue @@ -3,10 +3,12 @@ <Transition name=""> <el-col v-show="show" span="10"> <FactorCheckbox + v-model="selectFactorType" :device-type="deviceType" - @change="(e) => (selectFactorType = e)" ></FactorCheckbox> <LineChart + :locate-index="locateIndex" + @chart-click="handleChartClick" :factor-datas="factorDatas" :select-factor-type="selectFactorType" ></LineChart> @@ -32,13 +34,21 @@ deviceType: { type: String }, - factorDatas: FactorDatas + factorDatas: FactorDatas, + // 褰撳墠閫変腑楂樹寒鐨勬暟鎹偣绱㈠紩 + locateIndex: Number }, data() { return { selectFactorType: ['1'], show: true }; + }, + emits: ['chartClick'], + methods: { + handleChartClick(index) { + this.$emit('chartClick', index); + } } }; </script> -- Gitblit v1.9.3