Echarts Area Chart 2.0 (Range Drawing)

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:
Insert image description here

② Draw on both sides:
Insert image description here

③ One line:

Insert image description here

Guess you like

Origin blog.csdn.net/Y1914960928/article/details/132422423