Echarts 图表一些细节设置 lenged 双Y轴等

echarts 示例

Echarts图表效果图(Make A Pie替代)
Make A Pie 是由社区贡献者维护的用于 Apache ECharts 作品分享的第三方非官方社区。平时做Echarts图表经常需要用到,由于官方已经关闭,找到以下几个可替代的网站。(Make A Pie替代网址)

1、http://analysis.datains.cn/finance-admin/#/chartLib/all
2、makeapie 复刻站点1:http://ppchart.com/
3、Make A Pie复刻站点2:http://www.isqqw.com/ 备用地址http://echarts.isqqw.com/
4、Make A Pie复刻站点3: http://pie.antcode.net

作者:轮回千载:https://blog.csdn.net/mengdongdew/article/details/123193551?spm=1001.2014.3001.5502

echart 应用
1、vue中使用echarts-gl(3d环形图):https://blog.csdn.net/weixin_44766633/article/details/111831321
2、echarts3d饼图,环形图(包含透明效果):https://blog.csdn.net/weixin_41326021/article/details/120195920


Echarts 细节设置

1、效果图

在这里插入图片描述
(1)设置 lenged 样式:

color: ['#67E5FF', '#FFD153', '#01BAFF', '#FFBB00'],
legend: [
  {
    left: '10%',
    itemWidth: 8,
    itemHeight: 8,
    data: [
      {
        name: '进水水量',
        icon: 'circle',
        textStyle: {
          fontSize: 14,
          color: 'rgba(255,255,255,0.8)',
        },
      },
    ],
  },
  {
    left: '30%',
    itemWidth: 8,
    itemHeight: 8,
    data: [
      {
        name: '出水水量',
        icon: 'circle',
        textStyle: {
          fontSize: 14,
          color: 'rgba(255,255,255,0.8)',
        },
      },
    ],
  },
  {
    left: '50%',
    itemWidth: 8,
    itemHeight: 2,
    data: [
      {
        name: '进水浓度',
        icon: 'rect',
        textStyle: {
          fontSize: 14,
          color: 'rgba(255,255,255,0.8)',
        },
      },
    ],
  },
  {
    left: '70%',
    textStyle: {
      color: '#71F003',
      fontSize: 15,
      fontFamily: '微软雅黑',
    },
    itemWidth: 8,
    itemHeight: 2,
    data: [
      {
        name: '出水浓度',
        icon: 'rect',
        textStyle: {
          fontSize: 14,
          color: 'rgba(255,255,255,0.8)',
        },
      },
    ],
  },
],

(2)设置 Y 轴单位样式 mg/L万m³/d

nameTextStyle: {
      color: 'rgba(255,255,255,0.6)',
      padding: [0, 15, 0, 0],
},
yAxis: [
  {
    type: 'value',
    
    name: 'mg/L',
    nameTextStyle: {
      color: 'rgba(255,255,255,0.6)',
      padding: [0, 15, 0, 0],
    },
    min: 0,
    max: 4,
    interval: 1,
    axisLabel: {
      show: true, //这里的show用于设置是否显示y轴下的字体 默认为true
      textStyle: {
        //textStyle里面写y轴下的字体的样式
        color: 'rgba(255,255,255,0.6)',
        fontSize: 12,
      },
      formatter: '{value}',
    },
    splitLine: {
      show: true,
      // 背景虚线
      lineStyle: {
        color: 'rgba(255,255,255,0.2)',
      },
    },
  },
  {
    type: 'value',
    name: '万m³/d',
    nameTextStyle: {
      color: 'rgba(255,255,255,0.6)',
    },
    min: 0,
    max: 40,
    interval: 20,
    axisLabel: {
      show: true, //这里的show用于设置是否显示y轴下的字体 默认为true
      textStyle: {
        //textStyle里面写y轴下的字体的样式
        color: 'rgba(255,255,255,0.6)',
        fontSize: 12,
      },
      formatter: '{value}',
    },
    splitLine: {
      show: true,
      // 背景虚线
      lineStyle: {
        color: 'rgba(255,255,255,0.2)',
      },
    },
  },
],

2、横向柱状图

参考:https://blog.csdn.net/qq_36157085/article/details/114627259

3、echarts 中 legend 不显示问题

legend 中的data要跟series中的dataname相等 值一样才能显示;
在这里插入图片描述

4、柱状图折线图复合图

注意双Y轴,左侧Y轴和右侧Y轴,通过索引来对应

option = {
    color:['#ED7D31','#4472C4','#FFC000','#A5A5A5'],
    tooltip: {
        trigger: 'axis',
        axisPointer: {
            type: 'cross',
            crossStyle: {
                color: '#999'
            }
        }
    },
    toolbox: {
        feature: {
            dataView: {show: true, readOnly: false},
            magicType: {show: true, type: ['line', 'bar']},
            restore: {show: true},
            saveAsImage: {show: true}
        }
    },
    legend: {
        data: ['2小时快速修复', '常规施工工程', '准时百分比', '累计准时百分比']
    },
    xAxis: [
        {
            type: 'category',
            data: [ '3月', '4月', '5月', '6月', '7月'],
            axisPointer: {
                type: 'shadow'
            }
        }
    ],
    yAxis: [
        { // 对应左侧Y轴
            type: 'value',
            name: '水量',
            min: 0,
            max: 250,
            interval: 50,
            axisLabel: {
                formatter: '{value} ml'
            }
        },
        { // 对应右侧Y轴
            type: 'value',
            name: '温度',
            min: 0,
            max: 25,
            interval: 5,
            axisLabel: {
                formatter: '{value} °C'
            }
        }
    ],
    series: [
        {
            name: '2小时快速修复',
            type: 'bar',
            stack: '施工统计',
            data: [2.0, 4.9, 7.0, 23.2, 25.6, 76.7, 135.6, 162.2, 32.6, 20.0, 6.4, 3.3],
            yAxisIndex: 0, //对应左侧Y轴
        },
        {
            name: '常规施工工程',
            type: 'bar',
            stack: '施工统计',
            data: [2.6, 5.9, 9.0, 26.4, 28.7, 70.7, 175.6, 182.2, 48.7, 18.8, 6.0, 2.3],
            yAxisIndex: 0, //对应左侧Y轴
        },
        {
            name: '准时百分比',
            type: 'line',
            yAxisIndex: 1, //对应右侧Y轴
            data: [2.0, 2.2, 3.3, 4.5, 6.3]
        },
        {
            name: '累计准时百分比',
            type: 'line',
            yAxisIndex: 1,
            data: [10, 14, 13.3, 14.5,15]
        }
    ]
};

5、动态改变柱状图柱子的颜色

注意:这里的 data 属性值应该为一个对象数组形式:
例如:

data:[
  {name:'1', level:'2', value:20},
  {name:'2', level:'2', value:20},
]
series: [
  {
    name: "变化趋势",
    type: "bar",
    stack: "one",
    barWidth: 10, //柱子宽度
    data: this.data,
    zlevel: 11, // 设置层级
    itemStyle: {
      color: (params) => {
        if (params.value > 0 && params.value <= 50) {
          return "#81C124";
        } else if (params.value > 50 && params.value <= 100) {
          return "#F7C40A";
        } else if (params.value > 100 && params.value <= 150) {
          return "#F6880D";
        } else if (params.value > 150 && params.value <= 200) {
          return "#E62753";
        } else if (params.value > 200 && params.value <= 300) {
          return "#99226C";
        } else if (params.value > 300) {
          return "#751226";
        }
      },
      barBorderRadius: [1, 1, 1, 1], // 柱状图圆角
    },
  },
],

6、设置 ECharts 中图表加载动画时间

series:[
  {
    name:'销量',
    type:'bar',
    data:[5,20,36,10,10,20],
    animationDuration: 2800,
    animationEasing: 'cubicInOut',
  }
]

参考:https://blog.csdn.net/qyp_1/article/details/107686262

7、设置标准限值线

参考:https://blog.csdn.net/qq_36437172/article/details/105921501
效果:
在这里插入图片描述
代码:

series:[
  {    
    name: '',
    type: 'line',
    yAxisIndex: 0,
    showSymbol: false, //默认不显示拐点
    data: [],
    unit: '单位',
    markLine:{
      /*以下设置一行后,平均线就没有开始和结束标记了(即看不见箭头了)*/
      symbol:"none",
      data: [
        {
          name: '平均线',
          // 支持 'average', 'min', 'max'
          type: 'average',
          lineStyle:{
            normal:{
              color:"green",
              width:2,
              type:"solid",
            }
          }
        },
      ]
    }
  }
]

8、环形图中间文字设置

效果图:
在这里插入图片描述
方法一:设置 titlesubtext
参考:https://www.cnblogs.com/web520/p/6086038.html

option: {
  color: this.color,
  legend: {
    show: false,
    selectedMode: false, //取消图例上的点击事件
  },
  title: {
    show: true,
    text: "设备总数",
    subtext: "100", //副标题文本,'\n'指定换行
    x: "center", //水平安放位置,默认为'left',可选为:'center' | 'left' | 'right' | {number}(x坐标,单位px)
    y: "36%", //垂直安放位置,默认为top,可选为:'top' | 'bottom' | 'center' | {number}(y坐标,单位px)
    textAlign: null,
    itemGap: 8,
    textStyle: {
      // fontFamily: "Arial, Verdana, sans...",
      fontSize: 12,
      fontWeight: 400,
      color: "#999999",
    },
    subtextStyle: {
      // fontFamily: "Arial, Verdana, sans...",
      fontSize: 19,
      fontWeight: "bold",
      color: "#3EC3AE",
    },
  },
  series: [
    {
      name: "告警次数统计",
      type: "pie",
      radius: ["65%", "100%"], //饼图的半径,数组的第一项是内半径,第二项是外半径。支持设置成百分比,相对于容器高宽中较小的一项的一半。可以将内半径设大显示成圆环图, 设置内半径和外半径,形成环状
      center: ["50%", "50%"], //饼图的中心(圆心)坐标,数组的第一项是横坐标,第二项是纵坐标。支持设置成百分比,设置成百分比时第一项是相对于容器宽度,第二项是相对于容器高度。这里的center一旦设置, 则 graphic/legend 里的内容位置也要相应进行调整
      hoverAnimation: false, //鼠标悬浮是否有区域弹出动画,false:无 true:有
      avoidLabelOverlap: false,
      itemStyle: {
        normal: {
          label: {
            show: false,
          },
          labelLine: {
            show: true,
          },
        },
        emphasis: {
          shadowColor: "rgba(0, 0, 0, 0.1)",
          // shadowBlur: 10,
        },
      },
      data: [],
    },
  ],
},

方法二:设置 graphic

option: {
  color: this.color,
  legend: {
    show: false,
    selectedMode: false, //取消图例上的点击事件
  },
  graphic: [
    {
      type: "group",
      left: "center",
      top: "44%",
      bounding: "raw",
      children: [
        {
          type: "text",
          style: {
            text: "设备总数",
            fontSize: 12,
            fill: "#999999", //文字的颜色
            textVerticalAlign: "middle",
            textAlign: "center",
          },
        },
      ],
    },
    {
      type: "group",
      left: "center",
      top: "60%",
      bounding: "raw",
      children: [
        {
          type: "text",
          style: {
            text: "0",
            fontSize: 19,
            fill: "#3EC3AE", //文字的颜色
            textVerticalAlign: "middle",
            textAlign: "center",
          },
        },
      ],
    },
  ],
  series: [
    {
      name: "告警次数统计",
      type: "pie",
      radius: ["65%", "100%"], //饼图的半径,数组的第一项是内半径,第二项是外半径。支持设置成百分比,相对于容器高宽中较小的一项的一半。可以将内半径设大显示成圆环图, 设置内半径和外半径,形成环状
      center: ["50%", "50%"], //饼图的中心(圆心)坐标,数组的第一项是横坐标,第二项是纵坐标。支持设置成百分比,设置成百分比时第一项是相对于容器宽度,第二项是相对于容器高度。这里的center一旦设置, 则 graphic/legend 里的内容位置也要相应进行调整
      hoverAnimation: false, //鼠标悬浮是否有区域弹出动画,false:无 true:有
      avoidLabelOverlap: false,
      itemStyle: {
        normal: {
          label: {
            show: false,
          },
          labelLine: {
            show: true,
          },
        },
        emphasis: {
          shadowColor: "rgba(0, 0, 0, 0.1)",
          // shadowBlur: 10,
        },
      },
      data: [],
    },
  ],
},

9、水球图

echarts-liquidfill

10、报错:vue.esm.js:628 [Vue warn]: You may have an infinite update loop in watcher with expression “rankData”

在给 echarts 图表通过 props 传参数时,出现下面报错:
在这里插入图片描述
在带有表达式的观察程序中,可能有无限更新循环
为什么会出现这个bug呢?
分析如下:
错误的模式下:首先 yKeyData 在 created 生命周期中获取数据时也发生了变化,watch 监听到后,就执行 option 操作,结果 option 中的 data 中的数组进行倒置了 this.yKeyData.reverse(),那么 watch 监听的 yKeyData 又发生变化,陷入了无限死循环中。
在这里插入图片描述
正确的模式下:data 就是个纯数组,不可在其上添加函数操作。将倒置操作 reverse() 在传进参数之前就处理好。
在这里插入图片描述

总结:
echarts 中 option 的 data 传数组,千万不要对数组进行操作(不要在 watch 中改变所监听的数据)。否则会出 bug。
对该数组的操作在传进这个组件之前就已经处理好

11、echarts x轴文字显示不全

使用 echarts 绘制图表时,当数据量比较多时,我们会发现 x 轴文字显示不全,出现如下图的情况。
在这里插入图片描述
echarts 图表中有个 axisLabel 配置项,是坐标轴刻度标签的相关设置。interval 属性是坐标轴刻度标签的显示间隔,默认会采用标签不重叠的策略间隔显示标签。可以设置成 0 强制显示所有标签。还有一个属性:rotate: number 度角是倾斜的控制所在,在类目轴的类目标签显示不下的时候可以通过旋转防止标签之间重叠。

解决如下:

<script>
    //初始化echarts实例
    var myCharts = echarts.init(document.getElementById('main'));
 
    //指定图表的配置项和数据
    var option={
        title:{
            text:'ajax动态获取后台数据绘制echarts图表'
        },
        color:['#3398db'],      //调色盘颜色列表
        tooltip:{               //提示框组件
            trigger:'axis',     //触发类型(坐标轴触发)
            axisPointer:{
                type:'line'     //指示器类型(直线指示器)
            }
        },
        grid:{                  //直角坐标系内绘图网格
            left:'3%',          //grid组件离容器左侧的距离
            right:'4%',
            bottom:'3%',
            containLabel:true   //grid 区域是否包含坐标轴的刻度标签。
        },
        xAxis:[                                 //x轴
            {
                type:'category',                //坐标轴类型(类目轴)
                data:[],                        //类目数据
                axisTick:{                      //坐标轴刻度相关配置
                    alignWithLabel:true         //刻度线与标签对齐
                }
            }
        ],
        yAxis:[
            {
                type:'value'        //数值轴
            }
        ],
        series:[                        //系列列表
            {
                name:'直接访问',
                type:'bar',
                barWidth:'60%',
                data:[]
            }
        ]
    };
    myCharts.setOption(option);
    myCharts.showLoading();     //显示加载动画
 
    var x = [];
    var y = [];
 
    $.ajax({
        type:'get',
        url:'./data/obj.txt',
        dataType:'JSON',
        success:function(data){
            // console.log(data.data);
            data.data.map((item)=>{
                x.push(item.name);
                y.push(item.extn);
            })
            // console.log(x,y)
            myCharts.hideLoading();             //隐藏加载效果
            
            myCharts.setOption({
                xAxis:{
                    type:'category',                //坐标轴类型(类目轴)
                    data:x ,
                    axisLabel:{
                        interval:0,
                        rotate:-30
                    }
                },
                series:{
                    data:y
                }
            })
        }
    })
 
</script>

效果如下:
在这里插入图片描述
现在 x 轴的文字已经全部显示出来了

备注:参考解决方法echarts x轴文字显示不全(xAxis文字倾斜比较全面的3种做法值得推荐)

12、Echarts 初始化

  • 初始化关键一:对象值必须是重新初始化赋值,如下
    (1)可以定义一个全变变量:var myChart = null;
    (2)初始化赋值:
    myChart = echarts.init(document.getElementById("myID"));
  • 当每次数据改变,需要重新初始化时:
    mychart.dispose() 之后重新 init 就好了

13、echarts 环状图中添加图片

在这里插入图片描述
可在环形图里面、外面添加图片
线上调试地址http://echarts.zhangmuchen.top/#/detail?cid=xDoTDlajsn

代码如下:

option = {
    graphic: {
        elements: [{
            type: "image",
            z: 3, //设置图片的层级 例如:-3 0 3等
            style: {
                image: require("image/abc.png"),//你的图片地址
                width: 80,
                height: 80,
            },
            // left: "70",
            left: "center",
            top: "center",
            // position: [100, 100],
        }, ],
    },
    tooltip: {
        confine: true,
        show: false,
    },
}

14、echarts 饼图不显示0的数据

需求:当接口返回数据为0的时候,饼图会出现指示线和0数据,看上去效果并不好,产品提出,将数据为0时不显示。

这个是数据为0时的效果
在这里插入图片描述
附上源码:

var option = {
  title: {
    show: false,
    text: "",
  },
  color: [],
  tooltip: {
    trigger: "item",
    backgroundColor: "rgba(1, 12, 19, 0.9)",
    formatter: "{a} <br/>{b} :{d}%",
    textStyle: {
      fontSize: this.isFullScreen ? 20 : 12 * scale,
    },
  },
  series: [
    {
      name: this.name,
      label: {
        formatter: "{b}:{c}个/{d}%",
      },
      type: "pie",
      radius: [],
      center: ["50%", "50%"],
      data: [
        { name: "第一项", value: 1 },
        { name: "第二项", value: 0 },
        { name: "第三项", value: 0 },
        { name: "第四项", value: 5 },
        { name: "第五项", value: 3 },
      ],
    },
  ],
};

要实现数据为 0 时不显示的效果,有两种方法:
第一种是:在处理后台接口数据时,就将结果为 0 的过滤掉
第二种是:处理 option

效果如下:
在这里插入图片描述
附上代码:

var option = {
  title: {
    show: false,
    text: "",
  },
  color: [],
  tooltip: {
    trigger: "item",
    backgroundColor: "rgba(1, 12, 19, 0.9)",
    formatter: "{a} <br/>{b} :{d}%",
    textStyle: {
      fontSize: this.isFullScreen ? 20 : 12 * scale,
    },
  },
  series: [
    {
      
      label: {
        formatter: function (params, ticket, callback) {
          var total = 0;
          var percent = 0;
          newValue.forEach((value, index) => {
            total += value.value;
          });
          percent = ((params.value / total) * 100).toFixed(2);
          if (params.value == 0) {
            //取消数据为0的指示线
            params.data.labelLine.show = false;
            params.data.label.show = false;
            return null; //取消为0的数据
          } else {
            return `${params.name}${params.value}个/${percent}%`;    
          }
        },
        fontSize: 14 * scale,
      },
      type: "pie",
      radius: [],
      center: ["50%", "50%"],
      data: [
        { name: "第一项", value: 1, labelLine:{ show: true }, label: { show: true } },
        { name: "第二项", value: 0, labelLine:{ show: true }, label: { show: true } },
        { name: "第三项", value: 0, labelLine:{ show: true }, label: { show: true } },
        { name: "第四项", value: 5, labelLine:{ show: true }, label: { show: true } },
        { name: "第五项", value: 3, labelLine:{ show: true }, label: { show: true } },
      ],
    },
  ],
};

参考1:https://blog.csdn.net/li_970408/article/details/120414766
参考2:https://wenku.baidu.com/view/0cae66325c0e7cd184254b35eefdc8d376ee14b5.html
参考3:https://www.freesion.com/article/86881219213/

15、让echarts折线图X轴不从0刻度开始

效果图:
在这里插入图片描述
配置代码:
修改 xAxis.boundaryGap:true

let option = {
  tooltip: {
    trigger: "axis",
    axisPointer: {
      label: {
        backgroundColor: "#6a7985",
      },
      lineStyle: {
        color: "#C1F2FF",
      },
    },
  },
  grid: {
    top: "10%",
    left: "1%",
    right: "6%",
    bottom: "15%",
    containLabel: true,
  },
  xAxis: {
    type: "category",
    boundaryGap: true, //X轴不从0刻度开始
    data: ["2018年", "2019年", "2020年"],
    axisLabel: {
      show: true,
      interval: 0,
      margin: 12 ,
      textStyle: {
        color: "#fff",
        fontSize: 12 ,
      },
      formatter: function (value, index) {
        return value;
      },
    },
    axisLine: {
      show: true,
      lineStyle: {
        color: "rgba(255,255,255,0.6)",
        type: "solid",
      },
    },
    axisTick: {
      show: false,
    },
  },
  yAxis: {
    type: "value",
    scale: true,
    name: "数据单位:吨",
    nameTextStyle: {
      color: "rgba(255,255,255,0.6)",
      padding: [0, -20, 0, 0],
    },
    axisLabel: {
      show: true,
      interval: 0,
      textStyle: {
        color: "#fff",
        fontSize: 12 ,
      },
    },
    splitLine: {
      show: true,
      lineStyle: {
        color: "rgba(255,255,255,0.3)",
        type: "dashed",
        width: 0.8 ,
      },
    },
    axisLine: {
      show: true,
      lineStyle: {
        color: "rgba(255,255,255,0.6)",
      },
    },
    axisTick: {
      show: false,
    },
  },
  series: [
    {
      // data: [150, 230, 224, 218, 135, 147, 260],
      data: [1, 2, 3],
      type: "line",
    },
  ],
};

16、echarts 柱形图 x 轴的刻度显示在柱形中间,刻度和标签对齐

关键点:xAixs.axisTick.alignWithLabel:true

xAxis: {
  type: "category", //类名轴
  data: ["3月1日", "3月2日", "3月3日", "3月4日", "3月5日", "3月6日", "3月7日"],
  axisLine: {
    //坐标轴轴线相关设置
    lineStyle: {
      color: "#d7d7d7", //x轴线颜色设置
    },
  },
  axisLabel: {
    // 坐标轴刻度标签的相关设置
    show: true, //控制显隐
    textStyle: {
      color: "#d7d7d7", //x轴字体颜色
    },
    interval: 0,
  },
  axisTick: {
    //x轴刻度相关设置
    alignWithLabel: true,
  },
},

17、不显示 X 轴坐标轴指示器

在这里插入图片描述

xAxis: {
  type: "category",
  // 坐标轴指示器相关设置
  axisPointer: {
    type: "none", // 取消当前轴的坐标轴指示器
  },
},

18、X 轴数据多时,名称显示。解决 Echarts 柱状图X轴数据隔一个显示、文字显示不全

原始图:
在这里插入图片描述
解决 Echarts 柱状图X轴数据隔一个显示:
参考1:https://blog.csdn.net/fufu_good/article/details/106808713

解决 Echarts 柱状图X轴文字显示不全:解决x轴文字显示不全并将文字倾斜
参考2:https://blog.csdn.net/suhui1995/article/details/74231671

效果图:
在这里插入图片描述
核心代码:

axisLabel: {
	interval: 0, //设置间隔为0
	rotate: 40, //文字倾斜
	fontSize:12
},

完整代码:

<div id="concentration-container" style="width: 100%; height: 228px"> </div>
initChart() {
      var dom = document.getElementById("concentration-container");
      var myChart = echarts.init(dom, null, {
        renderer: "canvas",
        useDirtyRect: false,
      });

      var option;
      let that = this;
      let color = ["#3483EA", "#3483EA", "#D14305", "#ffffff"];

      option = {
        color: color,
        tooltip: {
          trigger: "axis",
          showDelay: 0, // 显示延迟,添加显示延迟可以避免频繁切换,单位ms
          axisPointer: {
            // 坐标轴指示器,坐标轴触发有效
            type: "shadow", // 默认为直线,可选为:'line' | 'shadow'
          },
          show: false,
          formatter: (params) => {
            let newArr = [];
            params.forEach((work) => {
              newArr.push(work);
            });

            let dataStr = `<div class="tool-tips">
                            <div class="name-con">
                              ${newArr[0].name}
                            </div>                                                  
                          </div>`;

            newArr.forEach((item, index) => {
              // 获取图标(小圆点)颜色,并且自定义样式为正方形,即要改变小圆点,只需重写marker的html片段,并修改样式即可
              dataStr += `<div>
                <div class="tool-item">         
                  <span class="len-box" style="background-color:${
                    color[item.seriesIndex]
                  };" ></span>     
                  <span>
                    <span></span>
                  </span>      
                  <span class="len-name">${item.seriesName}</span>        
                  <span class="len-percent">${item.data}</span>
                </div>
              </div>`;
            });
            return dataStr;
          },
        },
        grid: {
          top: "15%",
          left: "3%",
          right: "4%",
          bottom: "12%",
          containLabel: true,
        },
        legend: [
          {
            left: "20%",
            y: "bottom", //延Y轴居中
            // bottom:"-3%",
            itemWidth: 12,
            itemHeight: 12,
            data: [
              {
                name: "2014年",
                icon: "roundRect",
                textStyle: {
                  fontSize: 14,
                  color: "#666666",
                },
              },
            ],
          },
          {
            left: "40%",
            y: "bottom", //延Y轴居中
            // bottom: "-3%",
            itemWidth: 12,
            itemHeight: 12,
            data: [
              {
                name: "2021年",
                icon: "roundRect",
                textStyle: {
                  fontSize: 14,
                  color: "#666666",
                },
              },
            ],
          },
          {
            left: "60%",
            y: "bottom", //延Y轴居中
            // bottom: "-3%",
            itemWidth: 20,
            itemHeight: 6,
            data: [
              {
                name: "2022年",
                textStyle: {
                  fontSize: 14,
                  color: "#666666",
                },
              },
            ],
          },
        ],
        xAxis: {
          type: "category",
          data: [
            "01月",
            "02月",
            "03月",
            "04月",
            "05月",
            "06月",
            "07月",
            "08月",
            "09月",
            "10月",
            "11月",
            "12月",
          ],
          axisLine: {
            lineStyle: {
              color: "#CCCCCC",
            },
          },
          axisTick: {
            show: false, //不显示刻度
          },
          axisLabel: {
            interval: 0, //设置间隔为0
            rotate: 30, //文字倾斜
            fontSize: 12,
          },
          boundaryGap: false, // 不留白,从原点开始  ECharts折线从x轴原点(0点)开始   
        },
        yAxis: [
          {
            type: "value",
            name: "mg/L",
            nameTextStyle: {
              padding: [0, 0, 0, -30], // y轴的name属性设置位置(上右下左与原位置距离)
            },
            splitLine: { show: false },
            symbol: "none",
            axisLine: {
              show: true,
              lineStyle: {
                color: "#CCCCCC",
              },
            },
          },
        ],
        series: [
          {
            name: "2014年",
            data: [150, 155, 150, 175, 170, 162, 180, 150, 168, 188, 200, 240],
            type: "line",
            areaStyle: {
              color: "rgba(27,171,246,0.1)",
            },
            symbol: "none", //不显示拐点
            itemStyle: {
              normal: {
                lineStyle: {
                  width: 1, //折线宽度
                  color: "rgba(27,171,246,1)", //改变折线颜色
                },
              },
              emphasis: {
                lineStyle: {
                  width: 1,
                  color: "rgba(27,171,246,1)",
                },
              },
            },
          },
          {
            name: "2021年",
            data: [80, 90, 85, 95, 95, 90, 100, 85, 100, 110, 140, 160],
            type: "line",
            areaStyle: {
              color: "rgba(255,255,255,1)",
            },
            symbol: "none", //不显示拐点
            itemStyle: {
              normal: {
                lineStyle: {
                  width: 1, //折线宽度
                  color: "rgba(27,171,246,1)", //改变折线颜色
                },
              },
              emphasis: {
                lineStyle: {
                  width: 1,
                  color: "rgba(27,171,246,1)",
                },
              },
            },
            zlevel: 11,
          },
          {
            name: "2022年",
            type: "line",
            data: [150, 192, 161, 174, 182, 162],
            symbolSize: 4, //拐点大小
            animation: false,
            itemStyle: {
              normal: {
                lineStyle: {
                  width: 1, //折线宽度
                  color: "#D14305", //改变折线颜色
                },
              },
              emphasis: {
                lineStyle: {
                  width: 1,
                  color: "#D14305",
                },
              },
            },
          },
        ],
      };

      if (option && typeof option === "object") {
        myChart.setOption(option);
      }

      window.addEventListener("resize", myChart.resize);
    },

19、图例换行

参考:https://blog.csdn.net/qq_44271127/article/details/109691992

20、堆叠柱状图 文字显示

在这里插入图片描述

const option = {
    title: {
      subtext: "超标天数",
      subtextStyle: {
        color: "#999999"
      }
    },
    color: ["#2492FF", "#5DE9B0", "#FEC715"],
    tooltip: {
      trigger: "axis",
      axisPointer: {
        type: "shadow"
      }
    },
    legend: {
      show: true,
      bottom: 10,
      x: "center",
      itemWidth: 12,
      itemHeight: 12
    },
    grid: {
      top: "40",
      left: "20",
      right: "20",
      bottom: "40",
      containLabel: true
    },
    xAxis: [
      {
        type: "category",
        data: ["南澳青澳湾", "大梅沙", "小梅沙", "闸坡"],
        axisTick: { show: false },
        axisLine: {
          show: true,
          lineStyle: {
            color: "#CCCCCC"
          }
        },
        axisLabel: {
          show: true,
          // interval: 0,
          //当x轴名称太长,柱子默认隔一个显示,这里需求是让他全部显示
          fontSize: 12,
          color: "#333333",
          overflow: "break"
        }
      }
    ],
    yAxis: [
      {
        type: "value",
        axisTick: {
          show: true,
          inside: true
        },
        axisLine: {
          show: true,
          lineStyle: {
            color: "#CCCCCC"
          }
        },
        axisLabel: {
          show: true,
          color: "#999999"
        },
        splitLine: { show: false }
        // interval: 'auto',
      }
    ],
    series: [
      {
        name: "优",
        type: "bar",
        stack: "total",
        data: [60, 70, 50, 60],
        barMaxWidth: 24
      },
      {
        name: "良",
        type: "bar",
        stack: "total",
        data: [20, 15, 25, 20],
        barMaxWidth: 24
      },
      {
        name: "差",
        type: "bar",
        stack: "total",
        data: [20, 15, 25, 20],
        barMaxWidth: 24
      }
    ]
  };

处理:

//柱子上显示数值
  const seriesFormatter = (params) => {
    let value = Number.parseFloat(params.value)
    if (value === 0) {
      // 如果是0数值,不显示
      return ''
    }
    return value
  }

  /**
   * 这个位置的数据,是否在这一柱子最顶部,并且第一个不是0的数
   * @param chartData 二维数组,每行是一个系列的柱子
   * @param rowIndex chartData的行
   * @param colIndex chartData的列
   */
  const isTopLastNotZero = (chartData = [], rowIndex, colIndex) => {
    if (!chartData.length) {
      return false
    }

    // 转化 chartData
    let testArr = []
    chartData.forEach(item => {
      testArr.push(item.data)
    })

    const zip = (...arrays) => {
      // 找到最短数组的长度  
      const shortestLength = Math.min(...arrays.map(arr => arr.length));
      // 使用 map 和数组解构来组合元素  
      return Array.from({ length: shortestLength }, (_, i) => {
        return arrays.map(arr => arr[i]);
      });
    }

    let matrix = zip(...testArr)
    let viewBarData = matrix[colIndex]
    let index = viewBarData.findLastIndex(num => num != 0)
    return rowIndex === index
  }
  const getPosition = (chartData, rowIndex, colIndex) => {
    let position = ''
    if (chartData.length > 1) {
      if (isTopLastNotZero(chartData, rowIndex, colIndex)) {
        // 最顶部开始非0的柱子的标签显示在top
        position = 'top'
      } else {
        position = 'inside'
      }
    } else {
      // 只有一个系列label都显示在顶部
      position = 'top'
    }
    return position
  }

  let resultData = JSON.parse(JSON.stringify(option.series))
  resultData = resultData.map((item, rowIndex) => {
    item.data = item.data.map((work, colIndex) => {
      let position = getPosition(option.series, rowIndex, colIndex)
      return {
        value: work,
        label: {
          show: true,
          color: '#333333',
          fontSize: 12,
          formatter: seriesFormatter,
          position: position
        }
      }
    })
    return item
  })

  option.series = resultData

效果:
在这里插入图片描述

21、折线图:多X轴、双Y轴、翻转x轴

在这里插入图片描述

function getInitData() {
  //x轴日期(模拟)
  function getAll(start, end) {
    let dateList = [];
    var startTime = getDate(start);
    var endTime = getDate(end);

    while ((endTime.getTime() - startTime.getTime()) >= 0) {
      var year = startTime.getFullYear();
      var month = startTime.getMonth() + 1 < 10 ? '0' + (startTime.getMonth() + 1) : startTime.getMonth() + 1;
      var day = startTime.getDate().toString().length == 1 ? "0" + startTime.getDate() : startTime.getDate();
      // dateList.push(year + "-" + month + "-" + day);
      let obj = {
        subGroup: `${month}`,
        name: day,
        value: ""
      }
      dateList.push(obj)

      startTime.setDate(startTime.getDate() + 1);
    }
    return dateList;
  }
  function getDate(datestr) {
    var temp = datestr.split("-");
    var date = new Date(temp[0], temp[1] - 1, temp[2]);
    return date;
  }
  //日期
  var srcData = getAll('2023-10-21', '2023-11-20')
  //均值
  var meanValue = {
    subGroup: '均值',
    name: '均值',
    value: ""
  }
  srcData.push(meanValue)

  var covertData = function (src) {
    var nameList = [];
    var valueList = [];

    var subGroupLabelList = [''];
    var subGroupTickList = [0];

    var subGroupTmp = {
      name: '',
      count: 0
    };

    for (var i = 0; i < src.length; i++) {
      nameList.push(src[i].name);
      valueList.push(src[i].value);

      subGroupLabelList.push('', '');

      if (i === src.length - 1 || subGroupTmp.name !== '' && subGroupTmp.name !== src[i + 1].subGroup) {
        subGroupLabelList[i * 2 - subGroupTmp.count + 1] = src[i].subGroup;
        subGroupTmp.name = '';
        subGroupTmp.count = 0;
        subGroupTickList.push(i * 2 + 2);
      } else {
        subGroupTmp.name = src[i].subGroup;
        subGroupTmp.count++;
      }
    }

    return {
      nameList: nameList,
      valueList: valueList,
      subGroupLabelList: subGroupLabelList,
      subGroupTickList: subGroupTickList
    };
  };
  //x轴分组显示
  dstData = covertData(srcData);

  const option = {
    color: ['#0FAE59', '#666666', '#3483EB', '#0FAE59', '#666666'],
    tooltip: {
      trigger: 'axis',
      axisPointer: {
        type: 'shadow',
      },
      formatter: function (params) {
        // console.log('params12', params)
        var str = ""; //声明一个变量用来存储数据
        str += `<div style="margin-bottom: 5px; font-weight: 600">${params[0].name}</div>`;
        for (var i = 0; i < params.length; i++) {
          if (params[i].seriesType === 'bar' && params[i].value === '-') {
            continue
          } else {
            str += `
            <div style="display: flex; align-items: center;justify-content: space-between;">
              <div style="display: flex; align-items: center;"><span style="display:inline-block;margin-right:5px;margin-bottom:2px;width:10px;height:10px;border-radius:50%;background-color: ${params[i].color}"></span>${params[i].seriesName}</div>
              <div style="padding-left: 20px; font-weight: 600">${params[i].value}</div>
            </div>
            `
          }
        }
        return str;
      }
    },
    legend: {
      show: true,
      bottom: 10,
      x: 'center',
      itemWidth: 12,
      itemHeight: 8,
      data: ["总磷", "总磷-手工", '降雨量']
    },
    grid: [
      {
        bottom: '25%'
      }
    ],
    xAxis: [
      {
        //第一级
        type: 'category',
        data: [dstData.nameList],
        axisTick: {
          length: 0
        },
      },
      {
        //第二级
        type: 'category',
        data: dstData.subGroupLabelList,
        position: 'bottom',
        // boundaryGap: false,
        axisLine: {
          show: true,
          lineStyle: {
            color: '#CCCCCC',
          },
          onZero: false
        },
        axisLabel: {
          margin: 40,
          interval: 0,
          color: '#666666',
        },
        axisTick: {
          length: 60,
          interval: (index) => dstData.subGroupTickList.indexOf(index) != -1
        },
        axisPointer: {
          type: 'none'
        },
      }
    ],
    yAxis: [
      {
        name: '浓度',
        type: 'value',
        max: 5,
        axisTick: {
          show: true,
          inside: true,
        },
        axisLine: {
          show: true,
          lineStyle: {
            color: '#0FAE59',
          },
        },
        axisLabel: {
          show: true,
          color: '#0FAE59',
        },
        splitLine: { show: false },
      },
      {
        name: '降雨量',
        type: 'value',
        axisTick: {
          show: true,
          inside: true,
        },
        axisLine: {
          show: true,
          lineStyle: {
            color: '#3483EB',
          },
        },
        max: 200,
        axisLabel: {
          show: true,
          color: '#3483EB',
        },
        splitLine: { show: false },
        nameLocation: 'start',
        type: 'value',
        inverse: true
      }
    ],
    series: [
      {
        xAxisIndex: 0,
        yAxisIndex: 0,
        name: '总磷',
        type: 'line',
        showSymbol: false,
        data: [0.15, 0.23, 0.19, 0.17, 0.22, 0.25, 0.18, 0.25, 0.24, 0.15, 0.25, 0.23, 0.14, 0.1, 0.15, 0.23, 0.19, 0.17, 0.22, 0.25, 0.18, 0.25, 0.15, 0.26, 0.15, 0.23, 0.19, 0.17, 0.22, 0.25, 0.18],
        label: {
          show: true,
          color: '#0FAE59'
        },
        markLine: {
          silent: true,
          animation: false,
          data: [{ yAxis: 0.2, name: '标记线', label: { show: false } }],
          symbol: ['none', 'none'],
          position: "insideTopCenter",
          itemStyle: {
            normal: {
              lineStyle: {
                type: 'dashed',
                color: '#CCCCCC'
              },
            },
          }
        }
      },
      {
        xAxisIndex: 0,
        yAxisIndex: 0,
        name: '总磷-手工',
        type: 'line',
        symbol: 'triangle',
        data: ['-', 0.18, '-', '-', '-', '-', 0.13, '-', '-', '-', '-', '-', 0.1, '-', '-', '-', '-', '-', '-', 0.2, '-', '-', '-', '-', 0.12, '-', '-', '-', '-', '-', 0.12],
        symbolSize: 10,
        itemStyle: {
          normal: {
            label: {
              show: true,
              color: '#666666',
              position: 'bottom',
            },
            lineStyle: {
              color: "rgba(0,0,0,0)"
            }
          }
        }
      },
      {
        xAxisIndex: 0,
        yAxisIndex: 1,
        name: '降雨量',
        type: 'bar',
        data: [10, 20, 30, 25, '-', '-', '-', 18, 20, 26, 28, 10, '-', '-', '-', 12, 13, 25, '-', '-', '-', 28, 32, 23, 34, '-', '-', 15, 50, 28, 6],
        symbolSize: 8,
        label: {
          // position: 'bottom',
          // show: true,
          color: '#3483EB'
        },
        markLine: {
          silent: true,
          animation: false,
          data: [{ yAxis: 0, name: '标记线', label: { show: false } }],
          symbol: ['none', 'none'],
          position: "insideTopCenter",
          itemStyle: {
            normal: {
              lineStyle: {
                type: 'solid',
                color: '#CCCCCC'
              },
            },
          }
        }
      },
      {
        xAxisIndex: 0,
        yAxisIndex: 0,
        name: '总磷',
        type: 'bar',
        data: ['-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', 0.21],
        barMaxWidth: 10,
        label: {
          show: true,
          position: 'top',
          color: '#0FAE59'
        },
        symbolSize: 8
      },
      {
        xAxisIndex: 0,
        yAxisIndex: 0,
        name: '总磷-手工',
        type: 'bar',
        // yAxisIndex: 1,
        data: ['-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', 0.13],
        barMaxWidth: 16,
        label: {
          show: true,
          position: 'top',
          color: '#666666'
        },
        symbolSize: 8
      },
    ]
  }

  return option
}



CSS 样式

1、渐变色文字及边框

效果图:
在这里插入图片描述
代码实现:

<template>
	<div class="demo-line">
	  <div class="level-text">优~良</div>
	</div>
</template>

<style lang="scss" scoped>
.demo-line {
  width: 88px;
  height: 24px;
  border: 1px solid #28fea7;
  text-align: center;

  //背景、边框渐变
  border: 1px solid transparent;
  border-radius: 4px;
  background-clip: padding-box, border-box;
  background-origin: padding-box, border-box;
  background-image: linear-gradient(
      to right,
      rgba(6, 51, 40, 1),
      rgba(54, 70, 37, 1)
    ),
    linear-gradient(90deg, rgba(40, 254, 167, 1), rgba(247, 255, 0, 1));

  // 文字颜色渐变
  .level-text {
    -webkit-background-clip: text;
    color: transparent;
    background-image: linear-gradient(to right, #28fea7, #f7ff00);
  }
}
</style>

2、上一页、下一页切换

效果图:
请添加图片描述
代码实现:

<template>
  <div class="myt-panel-con">
    <div class="air-forecast">
      <!-- 左箭头:上一页 -->
      <div class="panel-btn left-btn" @click="prevCard"></div>
      <div ref="forecastWrap" class="forecast-wrap">
        <div
          class="forecast-item"
          v-for="(item, index) in forecastList"
          :key="index"
        >
          {{ item }}
        </div>
      </div>
      <!-- 右箭头:下一页 -->
      <div class="panel-btn right-btn" @click="nextCard"></div>
    </div> 
  </div>
</template>

<script>
export default {
  name: "ActualAirQuality", 
  components: {},
  data() {
    return {
      scrollLeft: 0,
      forecastList: ["第一", "第二", "第三", "第四", "第五", "第六", "第七", "第八"],
    };
  },
  methods: {
    // 卡片切换
    prevCard() {
      let forecastWrap = this.$refs.forecastWrap;
      let itemWidth = 120;
      if (forecastWrap.childNodes && forecastWrap.childNodes.length) {
        itemWidth = forecastWrap.childNodes[0].offsetWidth;
      }
      this.scrollLeft -= itemWidth;
      if (this.scrollLeft < 0) {
        this.scrollLeft = 0;
      }
      forecastWrap.scrollTo({ left: this.scrollLeft, behavior: "smooth" });
    },
    // 卡片切换
    nextCard() {
      let forecastWrap = this.$refs.forecastWrap;

      let itemWidth = 120;
      if (forecastWrap.childNodes && forecastWrap.childNodes.length) {
        itemWidth = forecastWrap.childNodes[0].offsetWidth;
      }
      this.scrollLeft += itemWidth;
      let maxScrollLeft = forecastWrap.scrollWidth - itemWidth * 3;
      if (this.scrollLeft > maxScrollLeft) {
        this.scrollLeft = maxScrollLeft;
      }

      forecastWrap.scrollTo({ left: this.scrollLeft, behavior: "smooth" });
    },
  },
  created() {},
  watch: {},
};
</script>

<style lang="scss" scoped>
.myt-panel-con {
  width: 743px;
  height: 400px;
  background: #001339;
  padding: 20px;
}

.air-forecast {
  display: flex;
  margin-bottom: 18px;
  height: 177px;
  width: 410px;
  .forecast-wrap {
    flex: 1;
    display: inline-flex;
    overflow-x: auto;
    &::-webkit-scrollbar {
      height: 0;
    }
  }

  .panel-btn {
    width: 20px;
    height: 169px;
    border: 1px solid transparent;
    font-size: 14px;
    cursor: pointer;
    display: flex;
    justify-content: center;
    align-items: center;
  }

  .left-btn,
  .right-btn {
    color: red;
    border: 1px solid rgba(110, 210, 255, 0.05);
    // background: #ccc;
    background: rgba(10, 34, 69, 0.8);
    font-size: 14px;
  }

  .forecast-item {
    flex-shrink: 0;
    width: 120px;
    height: 169px;
    background: linear-gradient(
      180deg,
      rgba(86, 164, 200, 0.2) 0%,
      rgba(43, 82, 100, 0.2) 100%
    );
    border: 1px solid;
    border-image: linear-gradient(to bottom, #00577e, #39cfff) 1;

    cursor: pointer;
    font-size: 16px;
    font-family: MiSans-Regular, MiSans;
    font-weight: 400;
    color: #8ad9ff;
    position: relative;
  }
}
</style>
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Windyluna

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值