echarts实现双坐标系图形叠加展示

先看效果图

在这里插入图片描述

实现步骤
安装echarts, 实例化echarts
html代码
 <div id="main" ref="chart" style="width: 100%;height: 400px"></div>
vue 的data和mounted
data() {
	chart: null
},
 mounted() {
 	 this.chart = echarts.init(this.$refs.chart)
 }

进行各项配置
1. legend 自定义文字和图例样式及颜色
 let legend = { 
     textStyle: { // 配置文字样式
         color: 'rgba(54, 65, 65)'
     },
     data: [
         // 配置icon样式 'circle', 'rect', 'roundRect', 'triangle', 'diamond', 'pin', 'arrow', 'none'
         { icon: 'roundRect', name: '衣服' },
         { icon: 'roundRect', name: '裤子' },
         { icon: 'roundRect', name: '裙子' },
         // 自定义配置icon(这里我是引用的本地图片,缺点:点击legend时无法动态置灰,需要自己设置事件置灰)
         { icon: `image://${require('@/assets/imgs/line.png')}`, name: '鞋子' },
     ]
 }
# 案例中鞋子的icon还可以通过itemHeight来实现(注意:需要设置left top等属性 防止文字重叠),(缺点:屏幕缩小legend可能会重叠 导致适配问题)
let legend = Object.keys(colorMap).map((key, index) => {
  let obj = {
    itemStyle: { color: colorMap[key] },
    textStyle: {
      color: 'rgba(54, 65, 65)',
    },
    top: 5,
    itemWidth: 14,
    itemHeight: 8,
    data: [{ name: key, icon: 'roundRect' }]
  }
  if (key === 'Power to Grid') obj.left = '30%'
  else if (key === 'PV') obj.left = '41%'
  else if (key === 'Load') obj.left = '46%'
  else if (key === 'Battery') obj.left = '52%'
  else {
    obj.left = '59%'
    obj.itemHeight = 2
  }
  return obj
})

# 图例还可以通过svg来实现(解决了点击时不自动置灰和适配问题)!!!推荐使用svg自定义
 let legend = { 
     textStyle: { // 配置文字样式
         color: 'rgba(54, 65, 65)'
     },
     data: [
         // 配置icon样式 'circle', 'rect', 'roundRect', 'triangle', 'diamond', 'pin', 'arrow', 'none'
         { icon: 'roundRect', name: '衣服' },
         { icon: 'roundRect', name: '裤子' },
         { icon: 'roundRect', name: '裙子' },
         // 自定义配置icon(这里我是引用的本地图片,缺点:点击legend时无法动态置灰,需要自己设置事件置灰)
         { icon: `path://M448 64h128v860.3H448z`, name: '鞋子' }, // 实线
         # 如果想绘制虚线
         // obj.icon = 'path://M448 64h128v230.3H448zM448 396.9h128v230.3H448zM448 729.7h128V960H448z'
         # path说明:
          // M 从448 64坐标点开始
	      // h 向x轴右移128(相当于坐标变成了(576, 64))
	      // v 向y轴下移230.3(相当于坐标变成了(576, 294.3))
	      // H 绝对定位到448的点(相当于坐标变成了(448, 294.3))
	      // z 当前点与出始点相连,闭合了(相当于坐标变成了(448, 64))
     ]
 }

推荐使用svg自定义icon !!!

2. 自定义tooltip
// 颜色映射
let colorMap = {
    ['衣服']: '#0094D6',
    ['裤子']: '#1DA445',
    ['裙子']: '#EF9236',
    ['鞋子']: '#EACC46',
}

let tooltip = {
    show: true,
    confine: true,
    trigger: "axis",
    axisPointer: {
        type: "line"
    },
    formatter: (res) => {
        // 头部显示时间段
        var strHtml = '<div class="dateInfo">' + res[0].axisValue + "</div>";
        res.forEach(function (item) {
            // 根据seriesName显示不同icon颜色和样式
            strHtml =
                strHtml +
                `<div class="toolTipRow">
                    <span class="icon ${item.seriesName}" style="background-color: ${colorMap[item.seriesName]}"></span>
                    ${item.seriesName}
                </div>`;
        })
        strHtml = `<div class="toolTipContent">${strHtml}</div>`;
        return strHtml;
    }
}

// 需要配置css
#main {
    ::v-deep.toolTipContent {
        background-color: #fff;
        margin: -6px;
        border-radius: 5px;
        padding: 10px;

        .toolTipRow {
            padding: 0px 5px 0px 24px;
            position: relative;
            font-size: 12px;
        }

        .icon {
            position: absolute;
            display: inline-block;
            width: 14px;
            height: 8px;
            top: 50%;
            left: 0px;
            transform: translateY(-50%)
        }

        .icon.鞋子 {
            // 这样不太规范,尽量用英文哦
            height: 2px;
        }
    }
}
配置x和y坐标轴
 let xAxis = {
     type: 'category',
      axisLine: { // 轴线相关
          lineStyle: {
              color: 'rgb(235, 235, 235)'
          }
      },
      axisTick: { // 刻度线相关
          show: false
      },
      axisLabel: { // x轴文本
          color: 'rgb(54, 65, 65)'
      },
      data: [
          '00:00', '02:00', '04:00', '06:00', '08:00', '10:00', '12:00',
          '14:00', '16:00', '18:00', '20:00', '22:00', '24:00'
      ]
  },
 let  yAxis = [ // 显示两个坐标轴用数组形式哦
      {
          name: 'name1',
          type: 'value',
          // nameGap: 8,
          splitLine: { // 网格分割线
              lineStyle: {
                  type: 'dashed',
                  width: 0.8,
                  color: 'rgba(235, 235, 235, 1)'
              }
          },
          axisLabel: {
              color: 'rgba(54, 65, 65, 0.55)'
          },
          nameTextStyle: {
              color: 'rgba(54, 65, 65, 0.55)',

          }
      },
      {
          name: 'name2', // 自定义y轴名称
          type: 'value',
          splitLine: {
              lineStyle: {
                  type: 'dashed',
                  width: 0.8,
                  color: 'rgba(235, 235, 235, 1)'
              }
          },
          axisLabel: {
              color: 'rgba(54, 65, 65, 0.55)'
          }
      }
  ],
配置series
let series =  [
     {
         name: '衣服',
         type: 'line',
         smooth: true,
         lineStyle: {
             width: 0
         },
         showSymbol: false,
         seriesLayoutBy: 'row',
         areaStyle: {
             opacity: 0.6,
             color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
                 {
                     offset: 0,
                     color: 'rgb(0, 148, 214)'
                 },
                 {
                     offset: 1,
                     color: 'rgb(0, 148, 214)'
                 }
             ])
         },
         emphasis: { focus: 'series' },
         data: [18, 46, 26, 62, 18, 236, 107, 88, 9, 100, 101, 240]
     },
     {
         name: '裤子',
         type: 'line',
         smooth: true,
         lineStyle: {
             width: 0
         },
         showSymbol: false,
         seriesLayoutBy: 'row',
         areaStyle: {
             opacity: 0.6,
             color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
                 {
                     offset: 0,
                     color: 'rgb(29, 164, 69)'
                 },
                 {
                     offset: 1,
                     color: 'rgb(29, 164, 69)'
                 }
             ])
         },
         emphasis: { focus: 'series' },
         data: [32, 43, 56, 88, 210, 37, 69, 54, 100, 40, 99, 330, 250, 524, 302]
     },
     {
         name: '裙子',
         type: 'line',
         smooth: true,
         lineStyle: {
             width: 0
         },
         showSymbol: false,
         seriesLayoutBy: 'row',
         areaStyle: {
             opacity: 0.6,
             color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
                 {
                     offset: 0,
                     color: 'rgb(234, 204, 70)'
                 },
                 {
                     offset: 1,
                     color: 'rgb(234, 204, 70)'
                 }
             ])
         },
         emphasis: { focus: 'series' },
         data: [100, 40, 32, 43, 56, 88, 210, 99, 330, 250, 524, 302, 37, 69, 54]
     },
     {
         name: '鞋子',
         type: 'line',
         smooth: true,
         yAxisIndex: 1, // 显示另一条y轴数据
         showSymbol: false,
         emphasis: { focus: 'series' },
         lineStyle: {
             color: 'rgb(234, 204, 70)'
         },
         data: [80, 85, 80, 90, 84, 94, 84, 90, 100, 80, 85, 80, 90, 84, 94, 84, 90, 100]
     }
 ]
series代码优化改进
 // 模拟数据
  let mockData = [
       [18, 46, 26, 62, 18, 236, 107, 88, 9, 100, 101, 240],
       [32, 43, 56, 88, 210, 37, 69, 54, 100, 40, 99, 330, 250, 524, 302],
       [100, 40, 32, 43, 56, 88, 210, 99, 330, 250, 524, 302, 37, 69, 54],
       [80, 85, 80, 90, 84, 94, 84, 90, 100, 80, 85, 80, 90, 84, 94, 84, 90, 100],
   ]

   // 由于配置项基本相同,只是名称不同和颜色,因此用循环,减少代码量啦
   let series = Object.keys(colorMap).map((key, index) => {
       let obj = {
           name: key,
           type: 'line',
           smooth: true,
           lineStyle: {
               width: 0
           },
           showSymbol: false,
           seriesLayoutBy: 'row',
           areaStyle: {
               opacity: 0.6,
               color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
                   {
                       offset: 0,
                       color: colorMap[key] // 根据名称配置颜色
                   },
                   {
                       offset: 1,
                       color: colorMap[key]
                   }
               ])
           },
           emphasis: { focus: 'series' },
           data: mockData[index] // 真实业务逻辑中 根据接口设置data
       }
       // 鞋子 是折线以及样式不同,需要单独设置下
       if (key === '鞋子') {
           obj['yAxisIndex'] = 1
           obj['areaStyle'] = null
           obj['lineStyle']['width'] = 1
           obj['lineStyle']['color'] = colorMap[key]
       }
       return obj
   })
调用setOption 完成!
 mounted() {
       let option = {
            legend: legend,
            tooltip: tooltip,
            xAxis: xAxis,
            yAxis: yAxis,
            grid: { top: '16%' }, // 距离图例的位置
            series: series
        };
        this.chart.setOption(option);
    },
看在我这么写的这么详细的份上,关注我一下吧……(o^^o)
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值