|
@@ -0,0 +1,172 @@
|
|
|
+<script setup>
|
|
|
+import { ref, onMounted, onUnmounted, computed } from 'vue';
|
|
|
+import * as echarts from 'echarts';
|
|
|
+import { getEchartData } from "@/api/business/comparison";
|
|
|
+import { getEchartLineOption } from "./echartConfig";
|
|
|
+
|
|
|
+let echart = null;
|
|
|
+let lastClickTime = new Date();
|
|
|
+
|
|
|
+const props = defineProps({
|
|
|
+ category: {
|
|
|
+ type: Array,
|
|
|
+ default: () => []
|
|
|
+ }
|
|
|
+})
|
|
|
+
|
|
|
+const echartRefDom = ref(null);
|
|
|
+
|
|
|
+const activeIndex = ref(0);
|
|
|
+
|
|
|
+const activeItem = computed(() => props.category[activeIndex.value]);
|
|
|
+
|
|
|
+const formatData = async () => {
|
|
|
+
|
|
|
+ echart.showLoading();
|
|
|
+
|
|
|
+ const data = await getEchartData({ category: activeItem.value.value });
|
|
|
+
|
|
|
+ const xAxisData = [];
|
|
|
+ const realOneList = [];
|
|
|
+ const realTwoList = [];
|
|
|
+ const realThreeList = [];
|
|
|
+ const hsForecastOneList = [];
|
|
|
+ const hsForecastTwoList = [];
|
|
|
+ const hsForecastThreeList = [];
|
|
|
+ const yyForecastOneList = [];
|
|
|
+ const yyForecastTwoList = [];
|
|
|
+ const yyForecastThreeList = [];
|
|
|
+
|
|
|
+ data.map(item => {
|
|
|
+ const {
|
|
|
+ remark,
|
|
|
+ realOne, realTwo, realThree,
|
|
|
+ hsForecastOne, hsForecastTwo, hsForecastThree,
|
|
|
+ yyForecastOne, yyForecastTwo, yyForecastThree
|
|
|
+ } = item;
|
|
|
+ xAxisData.push(remark);
|
|
|
+ realOneList.push(realOne);
|
|
|
+ realTwoList.push(realTwo);
|
|
|
+ realThreeList.push(realThree);
|
|
|
+ hsForecastOneList.push(hsForecastOne);
|
|
|
+ hsForecastTwoList.push(hsForecastTwo);
|
|
|
+ hsForecastThreeList.push(hsForecastThree);
|
|
|
+ yyForecastOneList.push(yyForecastOne);
|
|
|
+ yyForecastTwoList.push(yyForecastTwo);
|
|
|
+ yyForecastThreeList.push(yyForecastThree);
|
|
|
+ })
|
|
|
+
|
|
|
+ const echartData = [
|
|
|
+ { name: 'Real_1', val: realOneList },
|
|
|
+ { name: 'Real_2', val: realTwoList },
|
|
|
+ { name: 'Real_3', val: realThreeList },
|
|
|
+ { name: 'TFTpre_1', val: hsForecastOneList },
|
|
|
+ { name: 'TFTpre_2', val: hsForecastTwoList },
|
|
|
+ { name: 'TFTpre_3', val: hsForecastThreeList },
|
|
|
+ { name: 'LSTMpre_1', val: yyForecastOneList },
|
|
|
+ { name: 'LSTMpre_2', val: yyForecastTwoList },
|
|
|
+ { name: 'LSTMpre_3', val: yyForecastThreeList }
|
|
|
+ ]
|
|
|
+
|
|
|
+ const option = getEchartLineOption({ xAxisData, echartData })
|
|
|
+
|
|
|
+ console.log("option", option);
|
|
|
+
|
|
|
+ echart.setOption(option);
|
|
|
+
|
|
|
+ echart.hideLoading();
|
|
|
+}
|
|
|
+
|
|
|
+const changeActive = (i) => {
|
|
|
+ activeIndex.value = i;
|
|
|
+ formatData();
|
|
|
+}
|
|
|
+
|
|
|
+const legendselectchanged = () => {
|
|
|
+ echart.on('legendselectchanged', function (params) {
|
|
|
+
|
|
|
+ let currentTime = new Date().getTime();
|
|
|
+ let timeDiff = currentTime - lastClickTime;
|
|
|
+
|
|
|
+ const legendData = echart.getOption().series;
|
|
|
+
|
|
|
+ if (timeDiff < 300) {
|
|
|
+ for (var i = 0; i < legendData.length; i++) {
|
|
|
+ if (params.name == legendData[i].name) {
|
|
|
+ echart.dispatchAction({
|
|
|
+ type: 'legendSelect',
|
|
|
+ name: legendData[i].name
|
|
|
+ });
|
|
|
+ } else {
|
|
|
+ echart.dispatchAction({
|
|
|
+ type: 'legendUnSelect',
|
|
|
+ name: legendData[i].name
|
|
|
+ });
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ lastClickTime = currentTime;
|
|
|
+ });
|
|
|
+}
|
|
|
+
|
|
|
+const windowResize = () => echart.resize();
|
|
|
+
|
|
|
+onMounted(async () => {
|
|
|
+
|
|
|
+ echart = echarts.init(echartRefDom.value);
|
|
|
+
|
|
|
+ window.addEventListener('resize', windowResize);
|
|
|
+
|
|
|
+ formatData();
|
|
|
+
|
|
|
+ legendselectchanged();
|
|
|
+})
|
|
|
+
|
|
|
+onUnmounted(() => {
|
|
|
+ window.addEventListener('resize', windowResize);
|
|
|
+})
|
|
|
+
|
|
|
+</script>
|
|
|
+
|
|
|
+<template>
|
|
|
+ <div class="echart-container">
|
|
|
+ <h4 class="title">{{ activeItem.label }} 预测趋势图</h4>
|
|
|
+ <div ref="echartRefDom" class="echart-inner"></div>
|
|
|
+ <ul class="legend-inner space-x-[40px]">
|
|
|
+ <li v-for="item, index in category" :key="index" :class="['legend-item', { active: activeIndex == index }]"
|
|
|
+ @click="changeActive(index)">{{ item.label }}</li>
|
|
|
+ </ul>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<style lang="scss" scoped>
|
|
|
+.echart-container {
|
|
|
+
|
|
|
+ .title {
|
|
|
+ padding: 10px 0 20px 0;
|
|
|
+ text-align: center;
|
|
|
+ font-weight: bold;
|
|
|
+ }
|
|
|
+
|
|
|
+ .echart-inner {
|
|
|
+ height: 280px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .legend-inner {
|
|
|
+ display: flex;
|
|
|
+ justify-content: center;
|
|
|
+ align-items: center;
|
|
|
+ padding-top: 30px;
|
|
|
+ font-size: 14px;
|
|
|
+ color: #999;
|
|
|
+
|
|
|
+ .legend-item {
|
|
|
+ cursor: pointer;
|
|
|
+ }
|
|
|
+
|
|
|
+ .active {
|
|
|
+ color: #409eff;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+</style>
|