Browse Source

feat:说明

master
waibao2 1 month ago
parent
commit
c6828bfd21
  1. 17
      README.md
  2. 369
      src/components/ChartsTimeLine/index.vue
  3. 11
      src/components/ZhengBian/index.vue

17
README.md

@ -37,3 +37,20 @@ yarn dev
1. ESelectSingle: 普通下拉框选择器 1. ESelectSingle: 普通下拉框选择器
2. ETree: 页面左侧树结构 2. ETree: 页面左侧树结构
3. SingleStation: 级联下拉框选择器 3. SingleStation: 级联下拉框选择器
# 公共组件趋势图说明
1. ChartsBar
* seriesData:只有一个对象的时候使用
2. ChartsBarLine
* seriesData:是数组的时候使用
2. ChartsTimeBar
* 时间轴的趋势图(缩放echarts使用)
* legendData: 图例数据
* xAxisData: x轴数据
* seriesData: 图表数据
* textTitle: 图表标题
* unit: 单位
* echartType: 图表类型
* timeType: 时间类型
* grid: 图表网格配置

369
src/components/ChartsTimeLine/index.vue

@ -1,369 +0,0 @@
<template>
<!-- <div > -->
<div ref="ChartsTimeBarRef" style="height:100%;width: 100%;" class="chart-container"></div>
<!-- </div> -->
</template>
<script setup>
import * as echarts from "echarts";
import dayjs from 'dayjs'
import { onMounted, nextTick, ref, onUnmounted } from "vue";
const props = defineProps({
legendData: {
type: Array,
default: () => []
},
xAxisData: {
type: Array,
default: () => []
},
seriesData: {
type: Array,
default: () => []
},
textTitle: {
type: String,
default: ''
},
unit: {
type: String,
default: 'mm'
},
grid: {
type: Object,
default: () => {
return {
left: "5%",
right: "5%",
bottom: "16%",
top: "16%",
containLabel: true,
}
}
}
})
const ChartsTimeBarRef = ref(null);
let echartsBar = null;
let resizeObserver = null;
// props
watch([() => props.legendData, () => props.xAxisData, () => props.seriesData], () => {
if (echartsBar) {
updateChart();
}
}, { deep: true });
onMounted(() => {
console.log(props.xAxisData, '======xAxisData')
initEcharts();
window.addEventListener('resize', handleResize);
//
if (ChartsTimeBarRef.value) {
resizeObserver = new ResizeObserver(handleResize);
resizeObserver.observe(ChartsTimeBarRef.value);
}
});
onUnmounted(() => {
window.removeEventListener('resize', handleResize);
if (resizeObserver && ChartsTimeBarRef.value) {
resizeObserver.unobserve(ChartsTimeBarRef.value);
}
if (echartsBar) {
echartsBar.dispose();
}
});
const echartsLoading = ref(true);
const initEcharts = () => {
nextTick(() => {
if (ChartsTimeBarRef.value) {
echartsBar = echarts.init(ChartsTimeBarRef.value, "macarons");
let option = getChartOption();
echartsBar.setOption(option);
//
const resizeChart = () => {
if (echartsBar && ChartsTimeBarRef.value) {
echartsBar.resize({
width: ChartsTimeBarRef.value.clientWidth,
height: ChartsTimeBarRef.value.clientHeight
});
}
};
//
resizeChart();
}
});
};
const updateChart = () => {
nextTick(() => {
if (echartsBar) {
let option = getChartOption();
echartsBar.setOption(option, true); // 使notMerge:true
resizeChart();
}
});
};
const resizeChart = () => {
if (echartsBar && ChartsTimeBarRef.value) {
echartsBar.resize({
width: ChartsTimeBarRef.value.clientWidth,
height: ChartsTimeBarRef.value.clientHeight
});
}
};
const handleResize = () => {
if (echartsBar && ChartsTimeBarRef.value) {
//
clearTimeout(window.resizeTimer);
window.resizeTimer = setTimeout(() => {
echartsBar.resize({
width: ChartsTimeBarRef.value.clientWidth,
height: ChartsTimeBarRef.value.clientHeight,
animation: {
duration: 300
}
});
}, 100);
}
};
const getChartOption = () => {
let allData = [];
props.seriesData.forEach(series => {
if (series.data) {
series.data.forEach(item => {
// [time, value] {tm: time, value: value}
const value = Array.isArray(item) ? item[1] : (item.value !== undefined ? item.value : item);
if (value !== undefined && value !== null && !isNaN(value)) {
allData.push(Number(value));
}
});
}
});
// y
let yAxisMin = 0;
let yAxisMax = 100;
if (allData.length > 0) {
const minVal = Math.min(...allData);
const maxVal = Math.max(...allData);
// 使
const range = maxVal - minVal;
const margin = range > 0 ? range * 0.1 : 1;
yAxisMin = Math.floor((minVal - margin) * 100) / 100; //
yAxisMax = Math.ceil((maxVal + margin) * 100) / 100; //
//
if (minVal >= 0 && yAxisMin < 0) {
yAxisMin = 0;
}
}
const series = props.seriesData.map((item, index) => {
const colors = [
["#fccb05", "#f5804d"],
["#8bd46e", "#09bcb7"],
["#248ff7", "#6851f1"]
];
const color = colors[index % colors.length];
return {
name: props.legendData[index],
type: "line",
barWidth: item.data.length > 100 ? '15%' : "20",
showSymbol: false,
itemStyle: {
normal: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{ offset: 0, color: color[0] },
{ offset: 1, color: color[1] }
]),
barBorderRadius: 12,
},
},
data: item.data.map(val => val[1]),
};
});
let option = {
// backgroundColor: "#323a5e",
title: {
text: props.textTitle,
textStyle: {
align: "center",
color: "#000",
fontSize: 20,
},
top: "3%",
left: "50%",
},
tooltip: {
trigger: "axis",
axisPointer: {
//
type: "shadow", // 线'line' | 'shadow'
},
},
grid: props.grid,
legend: {
data: props.legendData,
right: 10,
top: 12,
textStyle: {
color: "#000",
},
itemWidth: 12,
itemHeight: 10,
// itemGap: 35
},
xAxis: {
type: "category",
data: props.xAxisData,
axisLine: {
lineStyle: {
color: "#ccc",
},
},
axisLabel: {
textStyle: {
fontFamily: "Microsoft YaHei",
},
showMinLabel: true, //
showMaxLabel: true, //
formatter: function (value) {
let date = dayjs(value)
let yearMonthDay = date.format('YYYY-MM-DD')
let hourMinute = date.format('HH:mm')
let result = `{a|${hourMinute}}\n{b|${yearMonthDay}}`;
if (props.timeType == 'day') {
result = `{b|${yearMonthDay}}`;
}
return result
},
rich: {
a: {
fontSize: 12,
color: '#000',
padding: [0, 0, 5, 0] //
},
b: {
fontSize: 12,
color: '#000'
}
}
},
},
yAxis: {
type: "value",
min: yAxisMin,
max: yAxisMax,
name: 'mm',
nameLocation: 'middle',
nameTextStyle: {//y
color: '#464b50'
},
nameGap: 50,
axisLine: {
show: true,
lineStyle: {
color: "#ccc",
},
},
splitLine: {
show: true,
lineStyle: {
color: "#ccc",
},
},
axisLabel: {
textStyle: {
color: "#000000",
},
// formatter
formatter: function (value) {
return value.toFixed(2);
}
},
},
dataZoom: [
{
show: true,
// height: 15,
xAxisIndex: [0],
bottom: "8%",
start: 0,
end: 100,
handleIcon:
"path://M306.1,413c0,2.2-1.8,4-4,4h-59.8c-2.2,0-4-1.8-4-4V200.8c0-2.2,1.8-4,4-4h59.8c2.2,0,4,1.8,4,4V413z",
handleSize: "110%",
handleStyle: {
color: "#d3dee5",
},
textStyle: {
color: "#000",
},
borderColor: "#90979c",
},
{
type: "inside",
show: true,
// height: 15,
start: 1,
end: 35,
},
// {
// type: 'inside'
// },
// {
// type: 'slider'
// }
],
series: series,
};
return option
// var app = {
// currentIndex: -1,
// };
// setInterval(function () {
// var dataLen = option.series[0].data.length;
// //
// myChart.dispatchAction({
// type: "downplay",
// seriesIndex: 0,
// dataIndex: app.currentIndex,
// });
// app.currentIndex = (app.currentIndex + 1) % dataLen;
// //console.log(app.currentIndex);
// //
// myChart.dispatchAction({
// type: "highlight",
// seriesIndex: 0,
// dataIndex: app.currentIndex,
// });
// // tooltip
// myChart.dispatchAction({
// type: "showTip",
// seriesIndex: 0,
// dataIndex: app.currentIndex,
// });
// }, 1000);
}
</script>
<style scoped>
.chart-container {
width: 100%;
height: 100%;
min-height: 300px;
position: relative;
}
</style>

11
src/components/ZhengBian/index.vue

@ -22,6 +22,12 @@
<el-button type="primary" icon="Search" @click="handleQuery">查询</el-button> <el-button type="primary" icon="Search" @click="handleQuery">查询</el-button>
<el-switch class="ml20" v-model="staticType" @change='changeStaticType' size="large" inline-prompt style="--el-switch-on-color: #13ce66; --el-switch-off-color: #1890FF" active-text="逐日显示" active-value="1" inactive-value="0" inactive-text="逐时显示" /> <el-switch class="ml20" v-model="staticType" @change='changeStaticType' size="large" inline-prompt style="--el-switch-on-color: #13ce66; --el-switch-off-color: #1890FF" active-text="逐日显示" active-value="1" inactive-value="0" inactive-text="逐时显示" />
</el-form-item> </el-form-item>
<el-form-item v-if="staticType==1">
<div style="font-size: 12px;color:#ccc">
逐日天表统计的是当日早八点到次日早八点
</div>
</el-form-item>
<br /> <br />
<el-form-item label="对比站点"> <el-form-item label="对比站点">
<el-select-v2 collapse-tags multiple filterable clearable v-model="compareStation" @change="changeCompareStnmIds" :options="stationOptions" :props="defaultProps" placeholder="请选择对比测站名称" style="width: 360px" /> <el-select-v2 collapse-tags multiple filterable clearable v-model="compareStation" @change="changeCompareStnmIds" :options="stationOptions" :props="defaultProps" placeholder="请选择对比测站名称" style="width: 360px" />
@ -91,6 +97,11 @@
<div class="el-upload__text"> <div class="el-upload__text">
将文件拖到此处<em>点击上传</em> 将文件拖到此处<em>点击上传</em>
</div> </div>
<template #tip>
<div class="el-upload__tip ">
模板就是预处理数据表格导出的文件
</div>
</template>
</el-upload> </el-upload>
</div> </div>
</el-form> </el-form>

Loading…
Cancel
Save