echarts -- 自定义统计图 -- 双Y坐标系的“重叠色块”+“折线图”混合图

218 阅读3分钟

这篇文章正在修改中...

前言

分享一些自定义的 echarts 统计图实现案例,一般我这里写的都是网上比较少有的案例,主要是为了方便自己后续项目中进行参考和使用

echarts 官方测试网站

echarts.apache.org/examples/en…

参考资料

echarts.zhangmuchen.top/#/detail?ci…

image.png

echarts.apache.org/examples/en…

image.png

期望展示的效果草图

image.png

  • 我这里加上了双y坐标的效果
$.get(ROOT_PATH + '/data/asset/data/aqi-beijing.json', function (data) {
  myChart.setOption(
    (option = {
      title: {
        text: 'Beijing AQI',
        left: '1%'
      },
      tooltip: {
        trigger: 'axis'
      },
      grid: {
        left: '5%',
        right: '15%',
        bottom: '10%'
      },
      xAxis: {
        data: data.map(function (item) {
          return item[0];
        })
      },
      yAxis: [
        {
            type: 'value',
            name: 'y轴1',
            axisLine: {
                show: true,  // 确保轴线显示
                lineStyle: {
                    color: '#333'  // 轴线颜色
                }
            },
            position: 'left',
        },
        {
            type: 'value',
            name: 'y轴2',
            position: 'right',
            offset: 0,
            axisLine: {
              show: true,
                lineStyle: {
                    color: '#675bba'
                }
            },
            axisLabel: {
                formatter: '{value} %'
            }
        }
        ],
      toolbox: {
        right: 10,
        feature: {
          dataZoom: {
            yAxisIndex: 'none'
          },
          restore: {},
          saveAsImage: {}
        }
      },
      dataZoom: [
        {
          startValue: '2014-06-01'
        },
        {
          type: 'inside'
        }
      ],
      visualMap: {
        top: 50,
        right: 10,
        pieces: [
          {
            gt: 0,
            lte: 50,
            color: '#93CE07'
          },
          {
            gt: 50,
            lte: 100,
            color: '#FBDB0F'
          },
          {
            gt: 100,
            lte: 150,
            color: '#FC7D02'
          },
          {
            gt: 150,
            lte: 200,
            color: '#FD0100'
          },
          {
            gt: 200,
            lte: 300,
            color: '#AA069F'
          },
          {
            gt: 300,
            color: '#AC3B2A'
          }
        ],
        outOfRange: {
          color: '#999'
        }
      },
      series: {
        name: 'Beijing AQI',
        type: 'line',
        data: data.map(function (item) {
          return item[1];
        }),
        markLine: {
          silent: true,
          lineStyle: {
            color: '#333'
          },
          data: [
            {
              yAxis: 50
            },
            {
              yAxis: 100
            },
            {
              yAxis: 150
            },
            {
              yAxis: 200
            },
            {
              yAxis: 300
            }
          ]
        }
      }
    })
  );
});

源码在此!!!

$.get(ROOT_PATH + '/data/asset/data/aqi-beijing.json', function (data) {
    console.log('----- x = ', data.map(function (item) {
          return item[0];
        }))
  console.log('----- y = ', data.map(function (item) {
          return item[1];
        }))
  // 为了实现目标效果,此方案需要一条隐藏的折线,用于包含所有其余图像(即这条这些只需要两个点,这两个点的y轴坐标的范围要能够包含所有其他图像数据中的最大值和最小值)
  const rangePoints = [[0,60],[0,-80]]
        
  myChart.setOption(
    (option = {
      title: {
        text: 'Beijing AQI',
        left: '1%'
      },
      tooltip: {
        trigger: 'axis'
      },
      grid: {
        left: '5%',
        right: '15%',
        bottom: '10%'
      },
      xAxis: {
          show: true,
          name: '0 [X]',
          type: 'value',
          min: 0,  // 设置 x 轴最小值为 0
          splitLine: {
              show: true,  // 显示刻度线
              lineStyle: {
                  type: 'solid'  // 线条样式,可以设置为 'solid', 'dashed', 'dotted' 等
              }
          },
          position: 'bottom',
          axisLine: {
            show: false,
          },
          axisLabel: {
              show: false,  // 是否显示轴标签
              inside: false,
              margin: 0
          },
          minorTick: {
            show: true
          },
          minorSplitLine: {
            show: true
          }
      },
      yAxis: [
        {
            show: false,
            type: 'value',
            name: 'y轴1',
            axisLine: {
                show: true,  // 确保轴线显示
                onZero: true,  // 保证 y 轴在 x 轴0点处穿过
                lineStyle: {
                    color: '#333'  // 轴线颜色
                }
            },
            position: 'left',
            axisLabel: {
              show: false
            },
        },
        {
            type: 'value',
            name: 'y轴2',
            position: 'right',
            offset: 0,
            axisLine: {
              show: true,
              onZero: true,  // 保证 y 轴在 x 轴0点处穿过
              lineStyle: {
                  color: '#675bba'
              }
            },
            axisLabel: {
                show: false
            }
        },
        {
            type: 'value',
            name: 'y轴3',
            position: 'left',
            offset: 0,
            axisLine: {
              show: true,
              onZero: true,  // 保证 y 轴在 x 轴0点处穿过
              lineStyle: {
                  color: '#675bba'
              }
            },
            axisLabel: {
                show: false
            }
        }
      ],
      series: [
        // 波浪折线图绘制
        {
          name: '波浪折线图',
          type: 'line',
          colorBy: 'data',
          itemStyle: {
            color: '#0033b1'
          },
          showSymbol: false,
          clip: true,
          smooth: true,
          data: [[0,10],[10,-15],[20,23],[30,-30],[40,39],[50,-20],[60,36]],
        },
        // ---------- 用折线实现自定义绘制 x坐标轴 ------------
        // 由于 x坐标轴的 label 无法紧挨着x坐标轴的下方,只支持在整个图像的顶部或底部,而且x坐标轴也只会在所有图层的底部,会被其他图形覆盖掉
        // 但是我们期望的是,x坐标轴应该在所有图层的最顶,即无论如何都应该能看到x坐标轴
        // 所有通过一条覆盖在x坐标轴上的折线这种方案来自定义实现x坐标轴
        {
          type: 'line',
          showSymbol: true,
          clip: true,
          data: [[0,0],[10,0],[20,0],[30,0],[40,0],[50,0],[60,0]],
          colorBy: 'data',
          label: {
            show: true,
            formatter: function (params) {
              return params.data[0]
            },
            backgroundColor: '#ffffff00',
            offset: [0,32],
          },
          lineStyle: {
            color: '#000000',
            width: 1,
          },
          // symbol: 'path://M0,0 0,10'
          symbol: 'rect',
          symbolSize: 3,
          itemStyle: {
            color: '#000',
          },
        },
        // ---------------- 绘制颜色区块的实现方式 -----------------
        // 不同颜色的区块绘制
        {
          name: '不同颜色的区块',
          type: 'line',
          colorBy: 'data',
          // data: data.map(function (item) {
          //   return item[1];
          // }),
          itemStyle: {
            color: '#aaaaaa00' // 隐藏折线,把折线颜色改为透明
          },
          tooltip: {
            show: false,
          },
          // data: [60, 60, 60],
          data: rangePoints, // 为了能够完整显示所有区块,data中的最小值和最大值必须包含下面的 markline和markArea
          // ---------- 通过 markArea 和 markline 组合实现虚线边框的区块图像 -----------
          markArea: {
            data: [
              // 区块图像1
              [{
      					yAxis: 50,
      					itemStyle: {
      						color: "#ffa69350"
      					}
      				}, 
      				{
      					yAxis: -50
      				}],
      				// 区块图像2
              [{
      					yAxis: 36,
      					itemStyle: {
      						color: "#8fff9e50"
      					}
      				}, 
      				{
      					yAxis: -10
      				}],
            ]
          },
          markLine: {
            silent: true,
            symbol: 'none', // 线终点标记的图形(默认为箭头,这里不要显示)
            data: [
              // 区块图像1 -- 上下边框虚线
              {
                yAxis: 50,
                symbol: 'none', // 线起点标记的图形(不要显示)
                label: {
                  formatter: function (params) {
                    return params.value > 0 ? `+${params.value}` : params.value
                  }
                },
                lineStyle: {
                  color: '#ff5733',
                },
              },
              {
                yAxis: -50,
                symbol: 'none',
                lineStyle: {
                  color: '#ff5733',
                },
              },
              // 区块图像2 -- 上下边框虚线
              {
                yAxis: 36,
                symbol: 'none', // 线起点标记的图形(不要显示)
                label: {
                  formatter: function (params) {
                    return params.value > 0 ? `+${params.value}` : params.value
                  }
                },
                lineStyle: {
                  color: '#00ac16',
                },
              },
              {
                yAxis: -10,
                symbol: 'none',
                lineStyle: {
                  color: '#00ac16',
                },
              },
            ]
          }
        }
      ]
    })
  );
});

  • 目前效果:

line-aqi.png