组件文件:
<template>
<div class="wrap">
<div ref="multipleLineChart" :style="{ height: height, width: width }" style="overflow:hidden"></div>
</div>
</template>
<script>
export default {
name: "MultipleLineChart",
props: {
width: {
type: String,
default: "100%",
},
height: {
type: String,
default: "100%",
},
dataOption: {
type: Object,
default: {},
},
},
data() {
return {
myChart: null,
chartData: [],
leftGrid: "1%",
rightGrid: "1%",
};
},
mounted() {
var that = this;
this.$nextTick(() => {
setTimeout(function () {
that.initChart();
}, 500);
});
},
watch: {
dataOption: {
deep: true,
handler(val) {
let that = this;
setTimeout(function () {
that.initChart();
}, 500);
},
},
},
methods: {
initChart() {
if (!this.myChart) {
this.myChart = this.$echarts.init(this.$refs.multipleLineChart);
}
let that = this;
let length = this.dataOption.dataY.length;
if (length == 0) {
this.leftGrid = "1%";
this.rightGrid = "1%";
} else if (length % 2 == 0) {
this.leftGrid = 0.5 * (length-1) + "%";
this.rightGrid = 0.5 * (length-1) + "%";
} else if (length % 2 == 1) {
this.leftGrid = 0.5 * length + "%";
this.rightGrid = 0.5 * (length-1) + "%";
}
var series = [];
this.dataOption.dataY.forEach((item, index) => {
series.push({
name: this.dataOption.legend ? this.dataOption.legend[index] : "",
type: "line",
yAxisIndex: index,
smooth: this.dataOption.smooth ? true : false,
symbolSize: 6,
lineStyle: {
normal: {
width: 2,
},
},
areaStyle: {
normal: {
color: new this.$echarts.graphic.LinearGradient(
0,
0,
0,
this.dataOption.isShowAreaStyle ? 1 : 0,
[
{
offset: 0,
color: `rgba(${item.color},0.7)`,
},
{
offset: 0.95,
color: this.dataOption.needAreaBottomColor
? `rgba(${item.color},0.3)`
: "#fff",
},
],
false
),
},
},
itemStyle: {
normal: {
color: `rgb(${item.color})`,
borderColor: `rgba(${item.color},1)`,
borderWidth: 2,
},
},
data: item.yData,
});
});
let yAxis = [];
for (let i = 0; i < this.dataOption.dataY.length; i++) {
if (i == 0) {
var yAxisObj = {
type: "value",
name: this.dataOption.legend ? this.dataOption.legend[i] : "",
position: "left",
offset: 0,
nameTextStyle: {
padding: [0, 0, 0, 0],
},
axisLine: {
show: true,
lineStyle: {
color: `rgba(${this.dataOption.dataY[i].color})`,
},
},
axisLabel: {
formatter: "{value}",
},
};
} else if (i % 2 == 0) {
var yAxisObj = {
type: "value",
name: this.dataOption.legend ? this.dataOption.legend[i] : "",
position: "left",
offset: 40 * (i / 2),
nameTextStyle: {
padding: [0, 0, 0, 0],
},
axisLine: {
show: true,
lineStyle: {
color: `rgba(${this.dataOption.dataY[i].color})`,
},
},
axisLabel: {
formatter: "{value}",
},
};
} else if (i % 2 == 1) {
var yAxisObj = {
type: "value",
name: this.dataOption.legend ? this.dataOption.legend[i] : "",
position: "right",
offset: (40 * (i - 1)) / 2,
nameTextStyle: {
padding: [0, 0, 0, 0],
},
axisLine: {
show: true,
lineStyle: {
color: `rgba(${this.dataOption.dataY[i].color})`,
},
},
axisLabel: {
formatter: "{value}",
},
};
}
yAxis.push(yAxisObj);
}
const multipleTooltip = {
trigger: "axis",
confine: true,
padding: [10, 10],
extraCssText: "box-shadow: 0 0 10px rgba(0, 0, 0, 0.3);",
backgroundColor: "rgba(255,255,255,1)",
textStyle: {
color: "#5d5d5d",
},
formatter: function (params) {
var relVal = params[0].name;
for (var i = 0, l = params.length; i < l; i++) {
let circle = `<div style='display: inline-block;width: 10px;height: 20px;margin-right:4px;color: ${params[i].color}'>●</div>`;
if (String(params[i].value).indexOf(".") > -1) {
params[i].value = Number(params[i].value).toFixed(
that.dataOption.decimalpoint ? that.dataOption.decimalpoint : 2
);
}
relVal +=
"<br/>" + circle + params[i].seriesName + ":" + params[i].value;
}
return relVal;
},
};
var option = {
title: {
text: this.dataOption.title,
textStyle: {
color: this.dataOption.titleColor || "#909299",
fontSize: 14,
fontWeight: 400,
},
},
tooltip: multipleTooltip,
grid: {
left: this.leftGrid,
right: this.rightGrid,
bottom: this.dataOption.bottomGrid
? this.dataOption.bottomGrid
: "12%",
top: this.dataOption.topGrid ? this.dataOption.topGrid : "13%",
containLabel: true,
},
legend: {
show: this.dataOption.isShow,
data: this.dataOption.legend,
},
xAxis: [
{
type: "category",
data: this.dataOption.dataX,
},
],
yAxis: yAxis,
series: series,
};
this.myChart.setOption(option);
},
},
};
</script>
<style scoped>
.wrap {
height: 100%;
}
</style>
使用:
<multipleLineChart :width="'100%'" :height='"280px"' :dataOption="dataOption"></multipleLineChart>
引入:
import multipleLineChart from "@/components/charts/multipleLineChart.vue";
components: { multipleLineChart},
data() {
return {
dataOption: {
isShow: true,
legend: ["昼间", "夜间", "66"],
isShowAreaStyle: false,
smooth: true,
topGrid: "15%",
bottomGrid: "0%",
dataX: ["11", "22"],
dataY: [
{
color: "113, 104, 241",
yData: [20, 111],
},
{
color: "55, 212, 255",
yData: [20, 111],
},
{
color: "0, 154, 97",
yData: [20, 20],
},
],
},
};
},