echarts图例过多,折线过多颜色不知道怎么分配怎么办??优化如下

优化一:很简单,echarts自身支持legend图例分页,加了分页就优化了图例过多情况。

legend['type']: 'scroll', // 添加这一行代码即可实现图例分页功能

option = {
    title: {
        text: '折线图堆叠'
    },
    tooltip: {
        trigger: 'axis'
    },
    legend: {
        type: 'scroll', // 添加这一行代码即可实现图例分页功能
        orient: 'horizontal', // 'vertical'
        x: 'right', // 'center' | 'left' | {number},
        y: 'bottom', // 'center' | 'bottom' | {number}
        // backgroundColor: '#fff',
        // borderColor: 'rgba(178,34,34,0.8)',
        // borderWidth: 4,
        padding: 10, // [5, 10, 15, 20]
        itemGap: 20,
        textStyle: { color: 'black' },
        data: ['邮件营销', '联盟广告', '视频广告', '直接访问', '搜索引擎']
    },
    grid: {
        left: '3%',
        right: '4%',
        bottom: '3%',
        containLabel: true
    },
    toolbox: {
        feature: {
            saveAsImage: {}
        }
    },
    xAxis: {
        type: 'category',
        boundaryGap: false,
        data: ['周一', '周二', '周三', '周四', '周五', '周六', '周日']
    },
    yAxis: {
        type: 'value'
    },
    series: [
        {
            name: '邮件营销',
            type: 'line',
            stack: '总量',
            data: [120, 132, 101, 134, 90, 230, 210]
        },
        {
            name: '联盟广告',
            type: 'line',
            stack: '总量',
            data: [220, 182, 191, 234, 290, 330, 310]
        },
        {
            name: '视频广告',
            type: 'line',
            stack: '总量',
            data: [150, 232, 201, 154, 190, 330, 410]
        },
        {
            name: '直接访问',
            type: 'line',
            stack: '总量',
            data: [320, 332, 301, 334, 390, 330, 320]
        },
        {
            name: '搜索引擎',
            type: 'line',
            stack: '总量',
            data: [820, 932, 901, 934, 1290, 1330, 1320]
        }
    ]
};

优化二:不仅仅优化图例,顺便配置一下显示情况,显示过多数据会显得杂乱无章,我们可以只配置部分图例,配置部分选中的

var data = genData(50);

option = {
    title: {
        text: '同名数量统计',
        subtext: '纯属虚构',
        left: 'center'
    },
    tooltip: {
        trigger: 'item',
        formatter: '{a} <br/>{b} : {c} ({d}%)'
    },
    legend: {
        type: 'scroll', // 图例优化
        orient: 'vertical',
        right: 10,
        top: 20,
        bottom: 20,
        data: data.legendData,

        selected: data.selected // 只配置部分图例,配置部分选中的
    },
    series: [
        {
            name: '姓名',
            type: 'pie',
            radius: '55%',
            center: ['40%', '50%'],
            data: data.seriesData,
            emphasis: {
                itemStyle: {
                    shadowBlur: 10,
                    shadowOffsetX: 0,
                    shadowColor: 'rgba(0, 0, 0, 0.5)'
                }
            }
        }
    ]
};




function genData(count) {
    var nameList = [
        '赵', '钱', '孙', '李', '周', '吴', '郑', '王', '冯', '陈', '褚', '卫', '蒋', '沈', '韩', '杨', '朱', '秦', '尤', '许', '何', '吕', '施', '张', '孔', '曹', '严', '华', '金', '魏', '陶', '姜', '戚', '谢', '邹', '喻', '柏', '水', '窦', '章', '云', '苏', '潘', '葛', '奚', '范', '彭', '郎', '鲁', '韦', '昌', '马', '苗', '凤', '花', '方', '俞', '任', '袁', '柳', '酆', '鲍', '史', '唐', '费', '廉', '岑', '薛', '雷', '贺', '倪', '汤', '滕', '殷', '罗', '毕', '郝', '邬', '安', '常', '乐', '于', '时', '傅', '皮', '卞', '齐', '康', '伍', '余', '元', '卜', '顾', '孟', '平', '黄', '和', '穆', '萧', '尹', '姚', '邵', '湛', '汪', '祁', '毛', '禹', '狄', '米', '贝', '明', '臧', '计', '伏', '成', '戴', '谈', '宋', '茅', '庞', '熊', '纪', '舒', '屈', '项', '祝', '董', '梁', '杜', '阮', '蓝', '闵', '席', '季', '麻', '强', '贾', '路', '娄', '危'
    ];
    var legendData = [];
    var seriesData = [];
    var selected = {};  // 只配置部分图例,配置部分选中的
    for (var i = 0; i < count; i++) {
        name = Math.random() > 0.65
            ? makeWord(4, 1) + '·' + makeWord(3, 0)
            : makeWord(2, 1);
        legendData.push(name);
        seriesData.push({
            name: name,
            value: Math.round(Math.random() * 100000)
        });
        selected[name] = i < 6;  // 只配置部分图例,配置部分选中的
    }

    return {
        legendData: legendData,
        seriesData: seriesData,
        selected: selected  // 只配置部分图例,配置部分选中的
    };

    function makeWord(max, min) {
        var nameLen = Math.ceil(Math.random() * max + min);
        var name = [];
        for (var i = 0; i < nameLen; i++) {
            name.push(nameList[Math.round(Math.random() * nameList.length - 1)]);
        }
        return name.join('');
    }
}

好看的配色

colors: [
    {
      c100: '#60acfc',
      c40: '#9fcdfdd9'
    },
    {
      c100: '#32d3eb',
      c40: '#84e4f3db'
    },
    {
      c100: '#9d94ea',
      c40: '#d4cffd'
    },
    {
      c100: '#40cec7',
      c40: '#8ce1ddde'
    },
    {
      c100: '#8087e6',
      c40: '#c4c8fb'
    },
    {
      c100: '#39b3ea',
      c40: '#7dc6f2d6'
    },
    {
      c100: '#5bc49f',
      c40: '#9cdbc5d6'
    },
    {
      c100: '#7885f1',
      c40: '#b8bffb'
    },
    {
      c100: '#76a1ef',
      c40: '#c5d8fb'
    },
    {
      c100: '#27a1ea',
      c40: '#7dc6f2d1'
    },
    {
      c100: '#35c5ea',
      c40: '#85dcf2d9'
    },
    {
      c100: '#f788aa',
      c40: '#f7adc4e0'
    },
    {
      c100: '#fb9a8a',
      c40: '#fca8a6c9'
    },
    {
      c100: '#d870af',
      c40: '#dc91bfd1'
    },
    {
      c100: '#4ebecd',
      c40: '#94d8e1c9'
    }
  ]

设置只有前n项展示,后面的让用户自己点击

var selected = {};  // 只配置部分图例,配置部分选中的
const selected = {}
            lengedData.forEach((_, i) => {
              selected[_] = i < 10;
            }) 
            // 设置只有前n项展示,后面的让用户自己点击
            const arrC = [0, 1, 2, 3, 4, 5]
            arrC.forEach(_ => {
              myOptions[_].legend.data = lengedData
              myOptions[_].legend.selected = selected // 设置只有前n项展示,后面的让用户自己点击
              myOptions[_].xAxis.data = xAxisData
            })

修改完成之后,legend.data,legend.selected会像下面这个样子

data: 
0: "图例名01"
1: "图例名02"
2: "图例名03"
3: "图例名04"
4: "图例名05"
5: "图例名06"
6: "图例名07"
7: "图例名08"
8: "图例名09"
9: "图例名10"
10: "图例名11"
11: "图例名12"
12: "图例名13"
13: "图例名14"
14: "图例名15"
15: "图例名16"
selected:
图例名1: true
图例名2: true
图例名3: true
图例名4: true
图例名5: true
图例名6: true
图例名7: true
图例名8: true
图例名09: true
图例名10: true
图例名11: false
图例名12: false
图例名13: false
图例名14: false
图例名15: false
图例名16: false

优化三:ECharts实现可缩放x轴,使用鼠标滚轮可以放大缩小

$(document).ready(function () {
  var myChart = echarts.init(document.getElementById("container-one-content"));
  // 123456热线
  var option = {
    xAxis: {
      type: "category",
      boundaryGap: false,
      data: ["17/1", "17/2", "17/3", "17/4", "17/5", "17/6", "17/7", "17/8", "17/9", "17/10", "17/11", "17/12", "17/13", "17/14"],
      axisLine: {
        lineStyle: {
          color: "#03A9F4"
        }
      }
    },
    yAxis: [
      {
        name: "单位/件",
        type: "value",
        axisLine: {
          lineStyle: {
            color: "#03A9F4"
          }
        },
        splitLine: {
          //网格线
          show: false
        }
      },
      {
        type: "value",
        min: 0,
        max: 1000,
        axisLine: {
          lineStyle: {
            color: "#03A9F4"
          }
        },
        splitLine: {
          //网格线
          show: false
        },
        axisLabel: {
          show: true,
          formatter: function (value, index) {
            return value / 25;
          },
          show: true,
          color: "#03A9F4",
          fontSize: 13
        }
      }
    ],
    series: [
      {
        data: [820, 932, 901, 2234, 1290, 1330, 1320, 1100, 2590, 1870, 2400, 1500, 1133, 888],
        type: "line",
        areaStyle: {
          color: "green"
        },
        lineStyle: {
          color: "#4CAF50"
        }
      }
    ],
    // 需要添加的代码:使用鼠标滚轮可以放大缩小
    dataZoom: [
      {
        id: 'dataZoomX',
        type: 'inside',
        xAxisIndex: [0],
        filterMode: 'none',
        start: 0,
        end: 50
      }
    ]
    // 需要添加的代码:使用鼠标滚轮可以放大缩小
  };
  // 使用刚指定的配置项和数据显示图表。
  myChart.setOption(option);

优化4:添加小图标指示,当鼠标放在图例时候,会清晰看到所指示的那一条线

let symbolStyle = { // 不同的圆点形状
                  0: 'heart',
                  1: 'rectangle',
                  2: 'triangle',
                  3: 'diamond',
                  4: 'emptyCircle',
                  5: 'emptyRectangle',
                  6: 'emptyTriangle',
                  7: 'emptyDiamond'
                }
                series.push({
                  name: _.station_code,
                  type: 'line',
                  symbol: symbolStyle[i], // 用来配合tooltip.trigger='item'
                  symbolSize: 1, // 设定折线点的大小
                  // smooth: true, // 折点是圆弧状的
                  // showSymbol: true,
                  // symbol: "circle", //折点设定为实心点
                  // symbolSize: 20,
                  stack: _.stacke,
                  data: _.data,
                  itemStyle: { color: {}},
                  areaStyle: { color: {}},
                  lineStyle: {}
                })

优化5:Echarts 折线图区域鼠标事件高亮,这个还没启用,但是可以作为参考,原博主写的样式

原博地址:https://blog.csdn.net/qq_36330228/article/details/106629199

下面是一些DEMO可以看一下代码

<template>
  <div>
    <!-- 案例1 -->
    <div id="myChart" ref="mapBox" style="width: 100%; height: 400px"></div>
    <!-- 案例1 -->
    <div id="myChart0" ref="mapBox0" style="width: 100%; height: 400px" />
    <div id="myChart1" ref="mapBox1" style="width: 100%; height: 400px" />
    <div id="myChart2" ref="mapBox2" style="width: 100%; height: 400px" />
    <div id="myChart3" ref="mapBox3" style="width: 100%; height: 400px" />
    <div id="myChart4" ref="mapBox4" style="width: 100%; height: 400px" />
    <div id="myChart5" ref="mapBox5" style="width: 100%; height: 400px" />
  </div>
</template>

<script>
import echarts from 'echarts'
// 設置圖表基礎配置項和數據
// 案例myOption
const myOption = {
  title: {
    text: '折线图',
    link: 'http://localhost:8000/',
    subtext: '折线图信息一覽表'
  },
  // title: {
  //     text: '折线图堆叠'
  // },
  tooltip: {
    trigger: 'axis'
  },
  legend: {
    orient: 'horizontal', // 'vertical'
    x: 'right', // 'center' | 'left' | {number},
    y: 'bottom', // 'center' | 'bottom' | {number}
    // backgroundColor: '#fff',
    // borderColor: 'rgba(178,34,34,0.8)',
    // borderWidth: 4,
    padding: 10, // [5, 10, 15, 20]
    itemGap: 20,
    // textStyle: { color: 'red' },
    data: ['邮件营销', '联盟广告', '视频广告', '直接访问', '搜索引擎']
  },
  grid: {
    left: '3%',
    right: '4%',
    bottom: 40,
    containLabel: true
  },
  toolbox: {
    feature: {
      saveAsImage: {}
    }
  },
  xAxis: {
    type: 'category',
    boundaryGap: false,
    data: ['周一', '周二', '周三', '周四', '周五', '周六', '周日']
  },
  yAxis: {
    type: 'value'
  },
  series: [
    {
      name: '邮件营销',
      type: 'line',
      // stack: '总量', // 总量就會相加
      data: [120, 132, 101, 134, 90, 230, 210]
    },
    {
      name: '联盟广告',
      type: 'line',
      // stack: '总量',
      data: [220, 182, 191, 234, 290, 330, 310]
    },
    {
      name: '视频广告',
      type: 'line',
      // stack: '总量',
      data: [150, 232, 201, 154, 190, 330, 410]
    },
    {
      name: '直接访问',
      type: 'line',
      // stack: '总量',
      data: [320, 332, 301, 334, 390, 330, 320]
    },
    {
      name: '搜索引擎',
      type: 'line',
      // stack: '总量',
      data: [820, 932, 901, 221, 434, 70, 1320]
    }
  ]
}
// 案例myOption
// 案例myOption0 需要注意的是 visualMap 和 series 存在一定的样式冲突, 不能同时使用
const myOption0 = {
  visualMap: {
    // 视觉映射  渐变过渡等效果
    show: false,
    type: 'continuous',
    seriesIndex: 0,
    min: 0, // 控制最小的数据显示色
    max: 60, // 控制最大的数据显示色
    // color:["#4C8400","#80BB0D","#B4DA20","#B6DA8C"], // 折线渐变色 , 由大到小排序  ECharts2的用法,ECharts3用inRange,如下
    inRange: {
      color: ['#4C8400', '#80BB0D', '#B4DA20', '#B6DA8C'],
      symbolSize: [30, 100] // 折线点的过渡大小, 从小到大
    }
  },
  tooltip: {
    // 鼠标移入效果
    trigger: 'axis',
    formatter: function(cur) {
      // formatter有  字符串模板 和 回调函数格式 两种
      // 详情: https://www.echartsjs.com/zh/option.html#series-line.tooltip.formatter

      // 通过参数 cur 基本就可以获取想要的数据了,当然也可以自定义数据
      console.log(cur)

      // 最后把要展示的数据记得用return 出来
      return
    }
  },
  xAxis: {
    // x轴样式与数据
    data: ['a', 'b', 'c', 'd', 'e'],
    axisLine: {
      lineStyle: {
        color: '#D8E3EA'
      }
    },
    axisLabel: {
      interval: 55, // X轴显示文字 间隔,数据太多,每格55个 显示一次 , 有时候太多显示不全,可以为0,强制全部显示,
      fontSize: 12,
      color: '#fff'
    },
    splitLine: { show: false }
  },
  yAxis: {
    // y轴样式与数据
    splitLine: {
      show: true,
      lineStyle: {
        color: '#A5C1D8'
      }
    },
    axisLine: {
      lineStyle: {
        color: '#D8E3EA'
      }
    },
    axisLabel: {
      interval: 55,
      fontSize: 14,
      color: '#fff'
    }
  },
  series: {
    type: 'line',
    showSymbol: false,
    data: [1, 2, 3, 4, 5, 6, 7, 8],
    symbol: 'circle', // 折线点的图形
    symbolSize: 10, // 图形大小
    itemStyle: {
      // 图形点和折线的颜色, 可以是单一的,也可以是渐变的
      // color:"#f00"  //单一
      color: {
        // 渐变  属性值 同CSS
        type: 'linear',
        x: 0,
        y: 0,
        x2: 0,
        y2: 1,
        colorStops: [
          {
            offset: 0,
            color: 'red' // 0% 处的颜色
          },
          {
            offset: 1,
            color: 'blue' // 100% 处的颜色
          }
        ]
      }
    },
    lineStyle: {
      // 单独配置折线图线条的显示效果, 配置基本和 itemStyle差不多
      color: '#f0f', // 颜色
      width: 5 // 线宽
    },
    areaStyle: {
      // 折线下面区域块的样式
      color: '#fff'
    }
  }
}
// 案例myOption0
// 案例myOption1,这个可以实现点击更换成单个展示信息的
let color = ''
const dataJson = {
  IsClickFlg: false
}
const myOption1 = {
  tooltip: {
    trigger: 'axis',
    axisPointer: {
      type: 'cross',
      label: {
        backgroundColor: '#6a7985'
      }
    }
  },
  legend: {
    data: [
      '电话销售',
      '纸质传媒',
      '邮件营销',
      '联盟广告',
      '视频广告',
      '直接访问',
      '搜索引擎'
    ]
  },
  grid: {
    left: '3%',
    right: '4%',
    bottom: '3%',
    containLabel: true
  },
  xAxis: [
    {
      type: 'category',
      boundaryGap: false,
      data: ['周一', '周二', '周三', '周四', '周五', '周六', '周日']
    }
  ],
  yAxis: [
    {
      type: 'value'
    }
  ],
  series: [
    {
      name: '电话销售',
      type: 'line',
      symbolSize: 2,
      stack: '总量',
      areaStyle: {},
      data: [10, 22, 11, 24, 10, 23, 21]
    },
    {
      name: '纸质传媒',
      type: 'line',
      symbolSize: 2,
      stack: '总量',
      areaStyle: {},
      data: [12, 13, 10, 13, 90, 23, 21]
    },
    {
      name: '邮件营销',
      type: 'line',
      stack: '总量',
      symbolSize: 2,
      areaStyle: {},
      data: [120, 132, 101, 134, 90, 230, 210]
    },
    {
      name: '联盟广告',
      type: 'line',
      stack: '总量',
      symbolSize: 2,
      areaStyle: {},
      data: [220, 182, 191, 234, 290, 330, 310]
    },
    {
      name: '视频广告',
      type: 'line',
      stack: '总量',
      symbolSize: 2,
      areaStyle: {},
      data: [150, 232, 201, 154, 190, 330, 410]
    },
    {
      name: '直接访问',
      type: 'line',
      stack: '总量',
      symbolSize: 2,
      areaStyle: {},
      data: [320, 332, 301, 334, 390, 330, 320]
    },
    {
      name: '搜索引擎',
      type: 'line',
      stack: '总量',
      symbolSize: 2,
      label: {
        normal: {
          show: true,
          position: 'top'
        }
      },
      areaStyle: {},
      data: [220, 332, 401, 234, 590, 630, 320]
    }
  ]
}
// 案例myOption1
// 区域图表myOption2  还不错哦但是只支持一个线哦多了不好用
const myOption2 = {
  xAxis: {
    type: 'category',
    boundaryGap: false,
    data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
  },
  yAxis: {
    type: 'value'
  },
  series: [
    {
      data: [820, 932, 901, 934, 1290, 1330, 1320],
      type: 'line',
      areaStyle: {}
    }
  ]
}
// 区域图表myOption2  还不错哦但是只支持一个线哦多了不好用

export default {
  data() {
    return {}
  },
  methods: {
    // 設置圖表自定縮放1
    resizeTheChart() {
      // console.log('縮放執行中~~~');
      if (this.$refs && this.$refs.mapBox) {
        const myChartNode = document.getElementById('myChart')
        if (myChartNode) {
          myChartNode.style.height = myChartNode.offsetWidth * 0.5 + 'px'
        }
        this.myChart.resize()
      }
    }
    // 設置圖表自定縮放2
  },
  mounted() {
    // 初始化echarts實例
    this.myChart = echarts.init(this.$refs.mapBox) // 案例myOption
    this.myChart.setOption(myOption) // 案例myOption

    this.myChart0 = echarts.init(this.$refs.mapBox0)
    this.myChart0.setOption(myOption0) // 案例myOption0
    this.myChart1 = echarts.init(this.$refs.mapBox1)
    this.myChart1.setOption(myOption1) // 案例myOption1
    // 案例myOption1
    this.myChart1.getZr().on('click', params => {
      // 触发了点击事件
      dataJson.IsClickFlg = true
      // 记录区域高亮前的颜色
      color = params.color
      console.log(this.myChart1)
      myOption1.tooltip.trigger = 'item'
      myOption1.series.symbolSize = 5
      // this.myChart1.clear()
      this.myChart1.setOption(myOption1)
      // 下面这个不晓得为何不生效
      // this.myChart1.setOption({
      //   tooltip: {
      //     trigger: 'item'
      //   },
      //   series: {
      //     name: params.seriesName,
      //     symbolSize: 5,
      //     lineStyle: {
      //       width: 5
      //     },
      //     areaStyle: {
      //       color: 'red'
      //     },
      //     tooltip: {
      //       textStyle: {
      //         color: 'white',
      //         fontSize: 14
      //       }
      //     }
      //   }
      // })
      // 这个不晓得为何不生效
    })

    this.myChart1.getZr().on('mouseout', params => {
      // 加上判断是否点击过的标志作用,避免鼠标监控事件一直触发,导致区域颜色会改变,可以去掉这句代码试下
      if (dataJson.IsClickFlg) {
        myOption1.tooltip.trigger = 'axis'
        myOption1.series.symbolSize = 2
        // this.myChart1.clear()
        this.myChart1.setOption(myOption1)
        // this.myChart1.setOption({
        //   tooltip: {
        //     trigger: 'axis'
        //   },
        //   series: {
        //     name: params.seriesName,
        //     symbolSize: 2,
        //     lineStyle: {
        //       width: 2
        //     },
        //     areaStyle: {
        //       color: color
        //     }
        //   }
        // })
        // 区域颜色还原,点击标志还原
        dataJson.IsClickFlg = false
      }
    })
    // 案例myOption1
    // 案例myOption2
    this.myChart2 = echarts.init(this.$refs.mapBox2)
    this.myChart2.setOption(myOption2) // 案例0
    this.myChart2.getZr().on('click', params => {
      const pointInPixel = [params.offsetX, params.offsetY] // 鼠标点击位置
      if (this.myChart2.containPixel('grid', pointInPixel)) { // 过滤绘制图形的网格外的点击事件
        const xIndex = this.myChart2.convertFromPixel({ seriesIndex: 0 }, [
          params.offsetX,
          params.offsetY
        ])[0] // 获取点击位置对应的x轴数据的索引值
        const a = this.myChart2.getOption().series[0].data[xIndex] // 获取到对应的这个折现最近的折点y轴对应值
        // 事件处理代码书写位置
        console.log('第几个节点', xIndex)
        console.log('y轴对应值', a)
      }
    })
    // 案例myOption2
    this.myChart3 = echarts.init(this.$refs.mapBox3)
    this.myChart4 = echarts.init(this.$refs.mapBox4)
    this.myChart5 = echarts.init(this.$refs.mapBox5)
    window.addEventListener('resize', this.resizeTheChart)
  },
  destroyed() {
    window.removeEventListener('resize', this.resizeTheChart)
  }
}
</script>
<style lang='less'>
</style>

参考博文:
https://blog.csdn.net/lightpass/article/details/81457410
https://blog.csdn.net/qq_36330228/article/details/106629199
https://blog.csdn.net/qq_41619796/article/details/88661894
https://blog.csdn.net/yl640007010/article/details/79731604

posted @ 2020-10-13 01:07  糖~豆豆  阅读(2784)  评论(0编辑  收藏  举报
Live2D