如果你们设计稿大概像这样,那么下面的方法都可参考
实现思路-- 找到数据中第一个轴的最小最大值,然后看分割线几根,相除,第二个类似操作就行
核心代码 诸位品鉴
js
let y1Min = null;
let y1Max = null;
let y2Min = null;
let y2Max = null;
y1Min = _getMinValue(props.datas.seriesData[key].data);
y1Max = _getMaxValue(props.datas.seriesData[key].data);
yData[0] = {
name: seriesData.length > 0 ? props.datas.seriesData[key].unit : "",
type: "value",
min: y1Min,
max: y1Max,
// minInterval: 1,
splitNumber: 5,
interval: (y1Max - y1Min) / 5,
};
y2Min = _getMinValue(props.datas.seriesData[key].data);
y2Max = _getMaxValue(props.datas.seriesData[key].data);
yData[1] = {
name: seriesData.length > 0 ? props.datas.seriesData[key].unit : "",
type: "value",
min: y2Min,
max: y2Max,
// minInterval: 1,
splitNumber: 5,
interval: (y2Max - y2Min) / 5,
};
function _getMaxValue(arr) {
const max = Math.max(...arr);
// 这样处理是为了不让最大值刚好到坐标轴最顶部
return Math.ceil(max / 10) * 10;
}
function _getMinValue(arr) {
const min = Math.min(...arr);
// 这样处理是为了不让最大值刚好到坐标轴最底部
return Math.floor(min / 10) * 10;
}
开始使用
父页面
js
<AToUnitCharts :datas="chartDetialList.VoltageAmmeterData" />
async function getVoltageAmmeterData() {
let data = await XXXX();
// 后端返回类似这样
// {
// batterystackvoltage: 15,
// batterystackcurrent: 11,
// time: "2024-04-25 12:00:00",
// },
// {
// batterystackvoltage: 20,
// batterystackcurrent: 21,
// time: "2024-04-25 12:01:00",
// },
let keys = [
{
label: "batterystackvoltage",
name: "总电压",
colors: [167, 79, 214], // 这里是 rgba 的前三位,因为需求是线条是 100% 面积是10%
unit: "电压(V)",
legend: true, // 这里是是否显示图例
yIdex: 0, // 这里控制是坐标轴的左面还是右面
},
{
label: "batterystackcurrent",
name: "总电流",
colors: [123, 159, 210], // 这里是 rgba 的前三位,因为需求是线条是 100% 面积是10%
unit: "电流(A)",
legend: true, // 这里是是否显示图例
yIdex: 1,
},
];
chartDetialList.VoltageAmmeterData = tickesTwoChartData(
data.data,
keys,
"time"
);
}
// 这个是封装上面接收到的字段,然后丢到子组件里让子组件去玩。
//主要玩的就是数据驱动视图,不然子组件每个图表都是不一样的逻辑也太扯淡了
// data,返回的主数据 keys: label: 字段名称,name 名称 xkeys x轴的对应字段
const tickesTwoChartData = (data, keys, xkeys) => {
let xData = [];
let seriesData = {};
keys.forEach((x) => {
seriesData[x.label] = {
name: x.name,
data: [],
unit: x.unit,
colors: x.colors,
legend: x.legend || null,
//
yIdex: x.yIdex,
};
});
data.forEach((item) => {
xData.push(item[xkeys]);
keys.forEach((x) => {
seriesData[x.label].data.push(item[x.label]);
});
});
return {
xData,
seriesData,
};
};
封装一个根据数据驱动的echarts 面积图
js
<template>
<div class="w-100% h-100%" ref="myChart"></div>
</template>
<script setup lang="ts">
import * as echarts from "echarts";
import dayjs from "dayjs";
const props = defineProps({
// 传入的参数
datas: {
type: Object,
default: () => {},
},
});
watch(
() => props.datas,
(newVal) => {
initChart();
},
{ deep: true }
);
function _getMaxValue(arr) {
const max = Math.max(...arr);
// 这样处理是为了不让最大值刚好到坐标轴最顶部
return Math.ceil(max / 10) * 10;
}
function _getMinValue(arr) {
const min = Math.min(...arr);
// 这样处理是为了不让最大值刚好到坐标轴最底部
return Math.floor(min / 10) * 10;
}
const myChart = ref(null);
function initChart() {
let legendData = [];
let seriesData = [];
let yData = [];
let y1Min = null;
let y1Max = null;
let y2Min = null;
let y2Max = null;
for (const key in props.datas.seriesData) {
if (props.datas.seriesData[key].legend) {
legendData.push({
name: props.datas.seriesData[key].name,
icon: "rect",
itemStyle: {
color: `rgba(${props.datas.seriesData[key].colors.join(",")},1)`,
},
});
}
seriesData.push({
name: props.datas.seriesData[key].name,
type: "line",
yAxisIndex: props.datas.seriesData[key].yIdex,
areaStyle: {
color: {
type: "linear",
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [
{
offset: 0,
color: `rgba(${props.datas.seriesData[key].colors.join(
","
)},0.1)`,
},
{
offset: 1,
color: `rgba(${props.datas.seriesData[key].colors.join(",")},0)`,
},
],
},
},
lineStyle: {
color: `rgba(${props.datas.seriesData[key].colors.join(",")},1)`,
},
itemStyle: {
color: `rgba(${props.datas.seriesData[key].colors.join(",")},1)`,
},
smooth: true,
unit: props.datas.seriesData[key].unit,
data: props.datas.seriesData[key].data,
});
if (seriesData.length > 0) {
if (props.datas.seriesData[key].yIdex == 0) {
y1Min = _getMinValue(props.datas.seriesData[key].data);
y1Max = _getMaxValue(props.datas.seriesData[key].data);
yData[0] = {
name: seriesData.length > 0 ? props.datas.seriesData[key].unit : "",
type: "value",
min: y1Min,
max: y1Max,
// minInterval: 1,
splitNumber: 5,
interval: (y1Max - y1Min) / 5,
};
// console.log(y1Min, "--------------", y1Max);
}
if (props.datas.seriesData[key].yIdex == 1) {
y2Min = _getMinValue(props.datas.seriesData[key].data);
y2Max = _getMaxValue(props.datas.seriesData[key].data);
yData[1] = {
name: seriesData.length > 0 ? props.datas.seriesData[key].unit : "",
type: "value",
min: y2Min,
max: y2Max,
// minInterval: 1,
splitNumber: 5,
interval: (y2Max - y2Min) / 5,
};
// console.log(y2Min, "--------------", y2Max);
}
}
}
let chartDom = myChart.value;
let myCharts = echarts.init(chartDom);
let option = {
grid: {
left: "3%",
right: "3%",
bottom: "15%",
top: "10%",
containLabel: true,
},
tooltip: {
trigger: "axis",
axisPointer: {
label: {
backgroundColor: "#6a7985",
},
},
},
legend: {
show: legendData.length > 0,
data: legendData,
top: 0,
itemHeight: 3,
itemWidth: 15,
left: "center",
width: "100%",
},
xAxis: {
type: "category",
boundaryGap: false,
axisLine: {
lineStyle: {
color: "#86909C",
},
},
axisLabel: {
// 这里需求是时间。我格式化过了,不需要的小伙子小姐姐可以不用
formatter: function (value, index) {
return dayjs(value).format("HH:mm");
},
},
data: props.datas?.xData,
},
yAxis:
yData.length > 0
? yData
: {
name: seriesData.length > 0 ? seriesData[0].unit : "",
type: "value",
},
series: seriesData,
};
option && myCharts.setOption(option);
const observer = new ResizeObserver(() => {
myCharts.resize();
});
observer.observe(chartDom);
}
onMounted(() => {
initChart();
});
</script>
完活! 有用 好用AI肯定干不出来这样的