玩转ECharts之实现“动态颜色的Label”

4,815 阅读5分钟

前言

玩转ECharts系列,主要为大家讲解我们基于ECharts如何实现企业级大屏项目中较为常用的各种奇奇怪怪的图表,接下来我们将通过几篇文章从基础图表开始为大家详细讲解实现这些图表样式的一些“小心机”。

导读

阅读完此文,你会了解基于ECharts:
1、如何实现在Label上显示数据项的值
2、如何实现动态颜色的Label
3、如何实现自定义的Label装饰
4、如何实现饼图Label标签的左右对称

背景

观察以上默认饼图我们会发现:通常默认的Label颜色是跟随数据项的,且仅显示数据项的名称。这时会带来一些问题

  1. 读者只能获取大致比例,无法获取精确的数据。
  2. 增加数据显示后数据值和名称颜色无区分,读者获取数据不够快速,不够精确。

为了解决这些问题,我们提供一些解决方案

  1. 在显示数据项目名称的同时显示具体的百分比。
  2. 为了快速区分数据项目名称和百分比,给数据项名称和百分比赋予不同颜色。
  3. 可以增加一些装饰性的元素去标注具体的名称或百分比(由于有些场景是仅显示数据项名称、有些场景是同时显示数据项名称和百分比,所以这里我们采用的是标注数据项名称)。

接下来我们来尝试一步一步实现我们的解决方案,看它到底是否有效。如图所示,采用新的方案优化了常用的饼图,为了快速获取饼图各项数值,我们分别显示了数据名称和百分比并用不同的颜色区分、增加装饰性边框来标注数据项名称增加区分度。

注意:为了突出label本文中示例图片特意相对缩小了饼图的半径,实际业务中如非必要请勿如此。

知识点

在 rich 里面,可以自定义富文本样式。利用富文本样式,可以在标签中做出非常丰富的效果。

formatter是一个字符串,可以定义label的整体结构并且支持字符串模板。rich为一个对象,定义具体的元素样式。

字符串模板

字符串模板 模板变量有:

  • {a}:系列名。
  • {b}:数据名。
  • {c}:数据值。
  • {d}:百分比。
  • {@xxx}:数据中名为'xxx'的维度的值,如{@product}表示名为'product'` 的维度的值。
  • {@[n]}:数据中维度n的值,如{@[3]}` 表示维度 3 的值,从 0 开始计数。

我们来看一个案例:

这是一个完整的echarts option配置项,其中要实现解决方案中的效果,核心代码为label部分。为了节省篇幅,下文中如未特殊说明,将仅提供核心代码。
option = {
    backgroundColor: '#000',
    title: {
        text: 'Customized Pie',
        left: 'center',
        top: 20,
        textStyle: {
            color: '#ccc'
        }
    },
    tooltip: {
        trigger: 'item',
        formatter: '{a} <br/>{b} : {c} ({d}%)'
    },
    series: [
        {
            name: '访问来源',
            type: 'pie',
            radius: '55%',
            center: ['50%', '50%'],
            color: ["#1576d2", "#d14a82", "#26c1f2", "#a166ff", "#1271cc", "#272f67", "rgba(156, 43, 182, 1)"],
            data: [
                {value: 80, name: '华为'},
                {value: 98, name: '苹果'},
                {value: 10, name: '三星'},
                {value: 80, name: '小米'},
                {value: 35, name: '其他'}
            ].sort(function (a, b) { return a.value - b.value; }),
            label: {
                // 这里定义了文本 百分比 是'value'样式的
                formatter: '{b}: {value|{d}}',
                rich: {
                    // 这个'value'样式表示文字颜色为白色
                    value: {
                       color: '#fff',
                    }
                }
            },
            labelLine: {
                lineStyle: {
                    color: 'rgba(255, 255, 255, 0.3)'
                },
                smooth: 0.2,
                length: 10,
                length2: 20
            }
        }
    ]
};

核心代码

  label: {
      // 这里定义了文本 百分比 是'value'样式的
      formatter: '{b}: {value|{d}}',
      rich: {
          // 这个'value'样式表示文字颜色为白色
          value: {
             color: '#fff',
          }
      }
  }

说明

利用formatter定义了同时显示名称和百分比、利用rich定义了百分比的显示颜色为白色。

效果

实现显示百分比

这里我们来应用formatter。实现显示百分比。

参考示例:gallery.echartsjs.com/editor.html…

核心代码

label: {
    formatter: '{b} {d}',
}

说明

只需要定义 formatter为'{b} {d}'就可以实现同时显示数据名和百分比。

效果

实现动态颜色

这里我们来应用formatter和rich。实现label的动态颜色。

参考示例:gallery.echartsjs.com/editor.html…

核心代码

label: {
    // 这样就实现了动态颜色,数据名固定为白色,百分比跟随数据项颜色
    formatter: '{name|{b}} {d}',
    rich: {
        name: {
           color: '#fff',
        }
    }
}

说明

formatter定义了名称是'name'样式的,利用rich定义了‘name’的显示颜色为白色。

效果

实现自定义装饰

这里我们来尝试一下formatter和rich的高级应用。给数据名创建一个边框和标识点。

参考示例:gallery.echartsjs.com/editor.html…

核心代码

label: {
  "formatter": '{rect|}{name|{b}}: {d}',
  "rich": {
      "name": {
         "color": '#fff',
         // 这里给name字段定义了边框颜色和边框宽度
         "borderColor": '#264884',
         "borderWidth": 1,
         "padding": [10, 15],
      },
      "rect":{
          // 这里给标识点定义了大小和颜色
         "height": 12,
         "width": 8,
         "backgroundColor": "#264884"
      }
  }
}

说明

这里我们定义了一个rect作为作为一个标识点,给了标识点一个大小和颜色。

效果

对称标签样式

从上图可见,我们实现出来的效果与预期略有差异,问题出在标签样式未对称,接下来我们来实现它。

参考示例:gallery.echartsjs.com/editor.html…

核心代码

label: {
  "formatter":function formatterFunc(params) {
    const values = params.data; // 内容
    const formatter = [`{rect|}{name|${values.name}} ${values.value}%`, `${values.value}% {name|${values.name}}{rect|}`];
    const midAngle = (values._startArc + values._endArc) / 2;
        if (midAngle <= Math.PI) {
            return formatter[0];
        } else {
            return formatter[1];
        }
  },
  "rich": {
      "name": {
         "color": '#fff',
         "borderColor": '#264884',
         "borderWidth": 1,
         "padding": [10, 15],
      },
      "rect":{
         "height": 12,
         "width": 8,
         "backgroundColor": "#264884"
      }
  }
}

说明

  1. 初始化数据的时候计算开始角度结束角度,并写入数据项的data属性。
  2. 分别定义了左右两种情况的formatter值,根据数值的左右分别取用。
  3. formatter中默认传入的params参数中获取数据,
  4. 从数据中拿到开始角度结束角度
  5. 取开始角度和中间角度的中间值判断是否<= Math.PI来区分左右,分别取用上述定义的formatter

效果

实例展示

这里有一些我们在实际应用中使用的的效果,抛砖引玉,为大家设计时提供一个思路。

往届回顾

1.  如何实现顶端装饰