Echarts—自定义图例布局样式和图例换行的实现

  • Post author:
  • Post category:其他




前言

之前做过各种各样需求的Echarts图表,通过查找博客和查看官网配置项api,都能实现,但是很久不用的话,再去做某些一样功能需求的图表,有些配置项还是需要反复查看,或者去搜索,所以我特意开了一个可视化专栏,去把使用过的可视化记录下来,也方便日后自己复用或者为他人提供便利!

这次就记录一下自定义图例布局样式和图例换行的实现,

我会把整个图表实现的代码都带出来,如果日后项目中用到类似的需求,也可以直接拿去!



自定义图例的饼状图

案例实现如下图;

在这里插入图片描述

在这里插入图片描述

主要实现功能代码块 legend:

 legend: {
     orient: 'vertical', //竖向展示
     left:'45%',  
     height:'60%',  //图例容器的高度,超过会换行展示
     top:'28%',
     icon:'circle',  //图标样式设置
     itemWidth:10,   //图标宽设置
     itemHeight:10,  //图标长设置
     itemGap:12,  //图标之间的距离
     data:legendData, //图例数据
     formatter: function(name) {// 图例自定义展示设置
         let total = 0
         let target
         for (let i = 0; i < dataValue.length; i++) {
             total += dataValue[i].value
             if (dataValue[i].name === name) {
                 target = dataValue[i].value
             }
         }
         var arr = [
         '{name|' + name + '}',
         '{targer|' + target + '}'
         ]
         return arr.join('  ')
     },
     textStyle: {	// 设置样式
         padding: [2, 0, 0, 0],
         rich: {
	         name: {
	             fontSize: 14,
	             width: 75
	         },
	         targer: {
	             fontSize: 14,
	             width: 38,
	             color: '#c1c1c1'
	         }
         }
     }

 },

下面我把上面饼状图实现的代码全部贴出来,如下:

<template>
    <div id="myChartOne" style="height: 240px;"></div>
 </template>
 
 <script>
 import Vue from 'vue'
 export default {
   data(){
     return{
         echartData: [],
     }
   },
   mounted(){
       this.getEchartData()
   },
   methods:{
      getEchartData(){
        Vue.axios.get('/getReportDataOne', {}).then(res => {
            if(res.status == 200){
               this.echartData = res.data
               this.initEchart(this.echartData)
            }
        })
      },
      initEchart(dataValue){
        var chartDom = document.getElementById('myChartOne');
        var myChart = this.$echarts.init(chartDom);
        var legendData = []
        dataValue.forEach(item => {
            legendData.push(item.name)
        })
        var option;
        option = {
            title:[
                {
                    text: `23043`,
                    subtext:'供应商总数(个)',
                    itemGap:6,
                    left:'22%',
                    top:'42%',
                    textAlign: 'center',
                    textStyle: {
                        color: '#000',
                        fontWeight: 'bold',
                        fontSize: 18,
                    },
                    subtextStyle:{
                        color: '#000',
                        fontWeight: 'normal',
                        fontSize: 15,
                    
                    }
                },
                {
                    text: `供应商状态(单位:个)`,
                    itemGap:6,
                    left:'45%',
                    top:'18%',
                    textStyle: {
                        color: '#000',
                        fontWeight: 'bold',
                        fontSize: 14,
                    },
                },
            ], 
            tooltip: {
                trigger: 'item',
                extraCssText: 'box-shadow: 0 0 3px rgba(0, 0, 0, 0.5);',
                backgroundColor:'rgba(255,255,255,.8)',
                confine: true ,
                textStyle:{
                    color: '#3d3d3d' ,
                    fontSize: 14 ,
                },
                formatter: function(params) {
                    const result = params.data
                    return  `
                       <div style="padding:10px 20px 10px 10px">
                         <div>
                            ${params.marker}
                            <span style="font-size:14px;font-weight:700">${params.name}供应商</span>
                         </div>
                         <ul style="margin-left:20px">
                            <li style="padding:3px 0;">${params.name}-战略型<span style="margin-left:10px;">${result.zhanlue}</span></li>
                            <li style="padding:3px 0;">${params.name}-优选型<span style="margin-left:10px;">${result.youxuan}</span></li>
                            <li style="padding:3px 0;">${params.name}-维持型<span style="margin-left:10px;">${result.weichi}</span></li>
                            <li style="padding:3px 0;">${params.name}-淘汰型<span style="margin-left:10px;">${result.taotai}</span></li>
                         </ul>
                       </div>
                    `
                }
            },
            color:['#2d5fff','#3dd070','#fe8e00','#ff5959','#bb5ce6','#37d0f6','#1ee8c9','#d9cd49','#f43ba9'],
            legend: {
                orient: 'vertical',
                left:'45%',
                height:'60%',
                top:'28%',
                icon:'circle',
                itemWidth:10,
                itemHeight:10,
                itemGap:12,
                data:legendData,
                formatter: function(name) {	// 添加
                    let total = 0
                    let target
                    for (let i = 0; i < dataValue.length; i++) {
                        total += dataValue[i].value
                        if (dataValue[i].name === name) {
                            target = dataValue[i].value
                        }
                    }
                    var arr = [
                    '{a|' + name + '}',
                    '{c|' + target + '}'
                    ]
                    return arr.join('  ')
                },
                textStyle: {	// 添加
                    padding: [2, 0, 0, 0],
                    rich: {
                    a: {
                        fontSize: 14,
                        width: 75
                    },
                    c: {
                        fontSize: 14,
                        width: 38,
                        color: '#c1c1c1'
                    }
                    }
                }

            },
            series: [
                {
                name: 'Access From',
                type: 'pie',
                center: ["23%", "50%"],//饼状图位置
                radius: ['50%', '75%'],
                avoidLabelOverlap: false,
                label: {
                    show: false,
                    position: 'center'
                },
                labelLine: {
                    show: false
                },
                data:dataValue
                }
            ]
        };

        option && myChart.setOption(option);
        myChart.on('click', (params) => {
            console.log('点击了', params);
            this.$router.push({name:'reportSupplierDetail',query:{component:'tableOne'}})
          
        });

        window.addEventListener("resize", () => {
            myChart.resize();
        });

      }
   }
 }
 </script>
 

由于后端还没有写接口,所以数据我只自己mock的,数据格式如下:

[
    { "value": 23,"zhanlue":3,"youxuan":10,"weichi":5,"taotai":5,"name": "已注册" },
    { "value": 20,"zhanlue":4,"youxuan":6,"weichi":7,"taotai":3,"name": "潜在" },
    { "value": 30,"zhanlue":4,"youxuan":15,"weichi":7,"taotai":4,"name": "整改中" },
    { "value": 50,"zhanlue":20,"youxuan":10,"weichi":10,"taotai":10,"name": "暂停合作" },
    { "value": 6,"zhanlue":2,"youxuan":2,"weichi":1,"taotai":1,"name": "黑名单" },
    { "value": 10,"zhanlue":4,"youxuan":6,"weichi":7,"taotai":3,"name": "合格" },
    { "value": 45,"zhanlue":14,"youxuan":10,"weichi":11,"taotai":10,"name": "资质到期" },
    { "value": 8,"zhanlue":4,"youxuan":1,"weichi":2,"taotai":1,"name": "冻结" },
    { "value": 50,"zhanlue":30,"youxuan":5,"weichi":5,"taotai":10,"name": "已退出" }
]

如果你没有使用mockJs,可以直接把数据放到data中的 echartData: [ ]里,非常方便,开袋即用!



图例换行

案例实现如下图:

在这里插入图片描述

这个图表展示其实跟上图是一模一样的,这里我们就不展示图表实现的全部代码啦,就把图库换行的功能实现代码 legend 展示出来;

其实很简单,就是写法都和上面一样就是加了一个换行符“\n” :

 legend: {
    left:'55%',
     top:'middle',
     icon:'circle', 
     orient:'vertical',
     itemWidth:10,
     itemHeight:10,
     data:legendData,
     //格式化图例文本
     formatter(name) {
       var num
       var a
       for (var i = 0; i < dataValue.length; i++) {
         if (dataValue[i].name == name) {
            num =  dataValue[i].value;
            a = ((dataValue[i].value/ dataValue[i].total) * 100).toFixed(2)+ '%'
         }
       }
     
       return [
         `{name|${name}}{a| ${a}}`,
         `      {num|${num}  个}`,
       ].join("\n");
     },
     textStyle:{
       fontSize: 14,
       padding: [28, 5, 0, 0],//上,右,下,左
       rich:{
         name:{
           fontSize: 14,
           // color: "#000",
            fontWeight:'bolder',
            padding: [0, 0, 0, 0]//上,右,下,左
         },
         num: {
           fontSize: 14,
           color:'#c1c1c1',
           //align:'center',
           padding: [6, 0,6,0],
         },
         a: {
           fontSize: 14,
           color:'#c1c1c1',
           padding: [0, 0,0,6],
         },

       }
     }
 },
formatter(name) {
    var num
    var a
    for (var i = 0; i < dataValue.length; i++) {
      if (dataValue[i].name == name) {
         num =  dataValue[i].value;
         a = ((dataValue[i].value/ dataValue[i].total) * 100).toFixed(2)+ '%'
      }
    }
  
    return [
      `{name|${name}}{a| ${a}}`,
      `      {num|${num}  个}`,
    ].join("\n");
  },

formatter函数最后return这里,我写的是个数组然后拼成字符串,这样写是直观,你也可以直接写成字符串,记得加上换行符就行;



版权声明:本文为qq_44182284原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。