Code:
// 以下代码可以直接粘贴在echarts官网的示例上
// 需求:范围随着原始折线图的颜色进行变化
// 原始图表的颜色绘制
let lineColor = ['#00a6ff', '#ff2e2e', '#00c228']
// 范围的颜色绘制
let areaColor = {
'#00a6ff': 'rgba(0, 166, 255,0.05)',
'#ff2e2e': 'rgba(255, 46, 46,0.09)',
'#00c228': 'rgba(0, 194, 40,0.06)'
// ...
}
// 范围区域 的数据
let normalValue = {
'原始数据1': {
type: '内部绘制',
minValue: 200,
maxValue: 700
},
'原始数据2': {
// type: '内部绘制',
type: '两边绘制',
// type: '一条线',
minValue: 200,
maxValue: 700
}
}
// 原始数据的图例名称
let legendName = ['原始数据1', '原始数据2']
// 获取当前折线图的y轴的最大值(用于两侧绘制) -- 在原本的绘图完成之后进行获取,然后进行重新配置和渲染
// getComponent参数:
// 参数一:轴名称 y轴 -- "yAxis" x轴 -- "xAxis"
// 参数二:存在多个y轴时,求最值的对应轴的索引oneData
// _extent的索引:0代表求最小值,1代表求最大值
// let yAxisMax = myChart.getModel().getComponent("yAxis",0).axis.scale._extent[1]
// let yAxisMaxData = Array.from({length: xData.length}, () => yAxisMax)
let yAxisMaxData = [1330,1330,1330,1330,1330,1330,1330] // y轴最大的数值数组 -- 这个是假数据
let xData = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'] // x轴数据
let legendSelect = {
} // 图例是否显示
let legendData = [] // 图例的数据
if (legendName && legendName.length) {
legendName.forEach((item,i) => {
legendSelect[item] = item.indexOf('正常范围') === -1
let obj = {
name: item,
itemStyle: {
color: ''
}
}
if(item.indexOf('正常范围') === -1) {
obj.itemStyle.color = lineColor[i]
legendData.push(obj)
}
})
}
let seriseData = [{
name: '原始数据1',
data: [820, 932, 901, 934, 1290, 1330, 1320],
type: 'line',
},
{
name: '原始数据2',
data: [80, 92, 91, 94, 190, 130, 120],
type: 'line',
}]
let newLegend = JSON.parse(JSON.stringify(legendData))
for(let i in normalValue) {
let item = normalValue[i]
legendData.forEach(j => {
if (i === j.name) {
let legendObj = {
name: `${
i}正常范围`,
itemStyle: {
color: areaColor[j.itemStyle.color]
}
}
newLegend.push(legendObj)
legendSelect[`${
i}正常范围`] = false
let minData = Array.from({
length: xData.length}, () => item.minValue)
let diffData = Array.from({
length: xData.length}, () => Math.abs(item.maxValue - item.minValue))
let maxData = Array.from({
length: xData.length}, () => item.maxValue)
if (item.type === '内部绘制') {
seriseData.push({
// 最小值进行折线图的绘制
name: `${
i}正常范围`,
data: minData,
type: 'line',
stack: `${
i}内部绘制`,
symbol: 'none',
legendHoverLink: false,
triggerLineEvent: false,
emphasis: {
disabled: true
},
lineStyle: {
color: j.itemStyle.color,
type: 'dashed'
}
},{
name: `${
i}正常范围`, // 最大值进行面积图的绘制
data: diffData,
type: 'line',
stack: `${
i}内部绘制`,
triggerLineEvent: false,
legendHoverLink: false,
emphasis: {
disabled: true
},
areaStyle: {
color: areaColor[j.itemStyle.color]
},
symbol: 'none',
lineStyle: {
color: j.itemStyle.color,
type: 'dashed'
}
})
} else if (item.type === '一条线') {
seriseData.push({
name: `${
i}正常范围`,
data: minData,
type: 'line',
symbol: 'none',
legendHoverLink: false,
triggerLineEvent: false,
emphasis: {
disabled: true
},
lineStyle: {
color: areaColor[j.itemStyle.color]
}
})
} else if(item.type === '两边绘制') {
seriseData.push({
// 最大值正常绘制折线图
name: `${
i}正常范围`,
data: maxData,
type: 'line',
stack: `${
i}两边绘制`,
triggerLineEvent: false,
legendHoverLink: false,
emphasis: {
disabled: true
},
symbol: 'none',
lineStyle: {
color: j.itemStyle.color,
type: 'dashed'
}
},
{
// y轴的最大值绘制面积图
name: `${
i}正常范围`,
data: yAxisMaxData,
type: 'line',
stack: `${
i}两边绘制`,
triggerLineEvent: false,
legendHoverLink: false,
emphasis: {
disabled: true
},
areaStyle: {
color: areaColor[j.itemStyle.color]
},
symbol: 'none',
lineStyle: {
color: j.itemStyle.color,
type: 'dashed'
},
itemStyle: {
borderColor: j.itemStyle.color
}
},
{
// 最小值正常绘制面积图
name: `${
i}正常范围`,
data: minData,
type: 'line',
triggerLineEvent: false,
legendHoverLink: false,
emphasis: {
disabled: true
},
areaStyle: {
color: areaColor[j.itemStyle.color]
},
symbol: 'none',
lineStyle: {
color: j.itemStyle.color,
type: 'dashed'
},
itemStyle: {
borderColor: j.itemStyle.color
}
})
}
}
})
}
let colorArr = []
if(newLegend && newLegend.length) {
newLegend.forEach(k => {
colorArr.push(k.itemStyle.color)
})
}
console.log('newLegend',newLegend)
option = {
color: colorArr,
xAxis: {
type: 'category',
boundaryGap: false,
data: xData
},
tooltip: {
show: true,
trigger: 'axis',
formatter: (params) => {
let areaObj = {
}
let str = `<div><div>${
params[0].name}</div>`
params.forEach(item => {
if(item.seriesName.indexOf('正常范围') === -1) {
str += `<div>${
item.marker}
<span>${
item.seriesName}:</span><span>${
item.value}</span>
</div>`
} else {
areaObj[item.seriesName] = true
}
})
newLegend.forEach(item => {
if(areaObj[item.name] && (item.name.indexOf('正常范围') != -1)) {
let itemArr = item.name.split('正常范围')
let obj = normalValue[itemArr[0]]
if(obj.type ==='一条线') {
str += `<div>
<span style="display:inline-block;margin-right:5px;border-radius:10px;width:10px;height:10px;background-color:${
item.itemStyle.color};"></span>
<span>${
item.name}:</span><span>${
obj.minValue}</span>
</div>`
str += `</div>`
}
if(obj.type ==='两边绘制') {
str += `<div>
<span style="display:inline-block;margin-right:5px;border-radius:10px;width:10px;height:10px;background-color:${
item.itemStyle.color};"></span>
<span>${
item.name}:</span>
<span>-∞ ~ ${
obj.minValue} ${
obj.maxValue} ~ +∞</span>
</div>`
str += `</div>`
}
if(obj.type ==='内部绘制') {
str += `<div>
<span style="display:inline-block;margin-right:5px;border-radius:10px;width:10px;height:10px;background-color:${
item.itemStyle.color};"></span>
<span>${
item.name}:</span><span>${
obj.minValue}~${
obj.maxValue}</span>
</div>`
str += `</div>`
}
}
})
return str
}
},
legend: {
data: newLegend,
selected: legendSelect
},
yAxis: {
type: 'value',
max: 'dataMax'
},
series: seriseData
};
Effect:
① Internal drawing:
② Draw on both sides:
③ One line: