图表微调开发者模式

2021-6-29 About 13 min

# 图表微调开发者模式


随着我们的客户不断增多,数据看板、大屏投放的业务场景,图表主题偏好也随之不断增多,虽然目前我支持到的图表微调项多达数百项,而且还在根据用户的反馈不断的增加。 但是,始终会遇到一些微调需求是不太适合通过界面控制来交互,又或者是迭代速度不够快,影响用户的项目交付。因此,我们从 1.1 开始引入 echarts 图相关的高级开发者模式。把主动权最大化交给用户!

# 高级开发者模式是什么?

开发者模式受众是有前端 js 开发经验的专业开发人员, 并且需要对原生 echarts 配置项有所了解

工作原理

允许用户在微调时插入一段 js 代码,该代码运行在echarts.setOption(option)之前,通过 JavaScript 代码、工具包和我们公开的相关 api 接口, 调整图配置option 对象的相关属性,从而做出任意 echarts 支持的渲染效果,如:目前还不支持的渐变色、graphics 水印、toolbox等其他所有 echarts 支持,而且我们的微调界面涵盖不全的配置项。

# 怎么做?

  1. 确认图表是否为 echarts 图(目前除交叉表、明细表、进度条、KPI 指标卡之外都属于 ehcarts 图)
  2. 在图表微调栏最下方可以看到开发者模式栏,点击代码按钮弹窗显示微调配置脚本编辑栏,如下所示:
  3. 支持操作的变量介绍,该插入代码段用户可以使用任意原始,或自定义、或支持的第三方库对option进行操作
变量 介绍
option 最终会传递给 echarts.setOption 接口的配置对象
$$option 开放给用户进行合并的对象,改对象最终会与目标对象 option 进行深度合并
_ Lodash (opens new window) 工具函数库
moment moment v2.22 (opens new window) 时间处理工具库
numbro numbro v1 (opens new window) 数字格式化工具库
ChartUtils iBI图表数据处理工具库, ChartUtils.linearGradient2Css(color); 把echarts的线性渐变色对象解析为css background样式
自定义 你也可以自己在ext.js 定义自己的工具方法

关于数组的深度合并

我们知道两个数组合并普通方案都是完全覆盖,后者覆盖替换前者,ehcarts中的大量配置在数组中都以对象的形式记录,微调的时候往往又只需要修改数组项中的其中几个属性, 因为我们支持的深度合并方案允许用户在数组对应的Index位置传递对象,然后进行对象比对,合并到数组中响应对象

// 覆盖合并
merge(
	[{ a: true }],
	[{ b: true }, 'ah yup']
) // => [{ b: true }, 'ah yup']

// 深度数组合并解释
merge(
	[{ a: true }],
	[{ b: true }, 'ah yup']
) // => [{ a: true, b: true }, 'ah yup']
1
2
3
4
5
6
7
8
9
10
11

调试小技巧

打开编辑器默认模板可以供参照,修改变更之后,点击确认按钮生效,取消测不做任何修改;Reset重置为初始模板状态, 在适当的时候用console.log()控制台打印结果

  • 控制台打印观察option对象具体的结构
  • 通过在代码中增加debugger,Chrome F12打开控制台调试

# 一些例子简单介绍

# 修改图例颜色为渐变色

下面的代码把系列数组中第一个系列的样式进行了跳转,包含barWidth,color等等

DETAILS
$$option = {
  series: [{
            type: 'bar',
            barWidth: '30%',
            itemStyle: {
                normal: {
                    barBorderRadius: 30,
                    color: new echarts.graphic.LinearGradient(
                        0, 0, 0, 1, [{
                                offset: 0,
                                color: '#00feff'
                            },
                            {
                                offset: 0.5,
                                color: '#027eff'
                            },
                            {
                                offset: 1,
                                color: '#0286ff'
                            }
                        ]
                    )
                }
            },
            
        }
    ]
}

// 渐变色需要取消tooltip的fomatter函数
delete option.tooltip.formatter;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31

# 增加graphics元素

前面介绍数组合并为深度合并,但是我们现在需要往graphic中新增元素,因为不能用之前的合并方案,而且需要直接往opiton.graphic中插入新的绘图元素

let graphics = [
        {
            type: 'image',
            id: 'logo',
            right: 20,
            top: 20,
            z: -10,
            bounding: 'raw',
            origin: [75, 75],
            style: {
                image: 'http://echarts.baidu.com/images/favicon.png',
                width: 150,
                height: 150,
                opacity: 0.4
            }
        }
    ];

option.graphic = option.graphic || [];
// pushAll 非标准js语法,为系统扩展数组之后的方法
option.graphic.pushAll(graphics);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

# 自定义tooltip

该案例演示了通过es6语法、外部lodash函数库,结合echarts回调给出来的参数处理tooltip

$$option = {
  tooltip: {
    formatter(params) {
      let name = params[0].name;
      let s = `<div style="text-align: left">${name}`;
      _.chain(params)
          .each(p => {
              let {seriesName, value, marker} = p;
              s += `<br/>${marker}`;
              s += `${seriesName}: ${value}`
          })
          .value();
      return s;
    }
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

# 漏斗图中间数值,右边类目

ECharts原生配置不支持双标签,实现思路需要复制一个series用于标签配置

const s = option.series[0];
// 相同配置
Object.assign(s, {
     maxSize: '50%',
    //  left: '20%',
});

// 复制一份之后不通用配置
const s2 = _.cloneDeep(s);

Object.assign(s.label, {
    formatter: '{b}',
    padding: [5, 10],
    backgroundColor: 'lightGrey',
    // align: 'right',
    position: 'right',
});

Object.assign(s2, {
    label: {
        position: 'inside',
        color: 'white',
        formatter(params) {
            let {seriesName, name, value, data} = params;
            const { percent } = data;
            return `${data.value}\n(${percent}%)`;
        }
    }
});

option.series.push(s2);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31

# 更多案例,陆续更新中...

Last update: February 17, 2025 15:53