Demo 可以查看项目下的http://localhost:8080/demo/bar/barchart.html 这个示例。
设计思路 自定义也是继承自series,然后将数据模型(model)和作图功能(view)完全开放给用户。因此需要用户自己实现作图逻辑,有不低的使用门槛。
文件位置 自定义功能是大约在2020.03.09开始使用的,实际上程序在2018年2月份就已经由WJW添加上去了。
程序位于src/chart/custom目录下。
代码逻辑 CustomModel 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 32 33 34 35 36 import SeriesModel from '../../model/Series' ;import { each } from '../../util' ;export const TYPE = 'custom' ;export default class CustomModel extends SeriesModel { static type = TYPE ; type = TYPE ; static defaultOption = { zlevel : 0 , z : 1 , view : { }, model : { } } constructor ( ) { super (...arguments ); let modelFunc = this .get ('model' ); each (modelFunc, (func, name ) => { this [name] = func; }); } }
CustomView 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 import ChartView from '../../view/Chart' ;import { TYPE } from './CustomModel' ;import { each } from '../../util' ;export default class CustomView extends ChartView { static type = TYPE ; type = TYPE ; constructor (model ) { super (...arguments ); let viewFunc = model.get ('view' ); each (viewFunc, (func, name ) => { this [name] = func; }); } }
流程详解 自定义类型使用方法和常规 series 一致,绘图逻辑需写在 view 对象里面的 render 方法中,如:
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 32 33 34 35 36 37 38 39 40 41 series: [{ type: 'custom' , zlevel: 10 , $dataIndex : 1 , view: { render: function (model, globalModel, global ) { let data = model.getData () let axisModel = globalModel.getComponent ('axis' ) let xScale = axisModel[0 ].getScale () let yScale = axisModel[1 ].getScale () let bandWidth = xScale.bandwidth () let attr = [], attr2 = [] data.forEach (d => { attr2.push ({ shape : { cx : xScale (d[0 ]) + bandWidth / 2 , cy : yScale (d[1 ]), r : 10 }, style : { fill : 'red' , stroke : 'green' , lineWidth : 5 } }) }) this.setShapeGroup ('circle' , D3Charts.graphic.Circle, attr2) this.setShape ('text' , D3Charts.graphic.Text, { style : { x : 200 , y : 100 , text : '随便写点字' } }) } } }]
完整例子可前往:http://datav.iwencai.com/platform/chartconfig.html#chartId=282
render 方法提供三个参数,model, globalModel, global
model: custom 模块的 model 信息,获取 model 配置信息等
globalModel: 保存着全局的 model 信息,比如在这里获取 axis, grid 等组件的 model 等
global: 用于获取全局信息的一些方法,比如获取视图宽高、DOM 等
如上面的例子中,在柱状图中添加自定义的 circle 形状,有如下步骤
获取数据 首先需要确定绘图数据,获取数据
1 let data = model.getData()
要想正确获取数据,前提是配置正确的 $dataIndex,这将用于确定 data 数据源中的数据索引
【核心】获取柱子坐标 这一步是非常关键的,要想用好自定义,必须掌握获取各种坐标数据的API。
1 2 3 4 let axisModel = globalModel.getComponent ('axis' ) let xScale = axisModel[0] .getScale () let yScale = axisModel[1] .getScale () let bandWidth = xScale.bandwidth ()
通过坐标轴的 scale 获取柱子处的坐标
在 globalModel 上获取到 axis 组件,根据配置情况分别获取到 x、y 轴,在其之上调用 getScale 则获取到了相应的坐标轴, 由于是 band 类型的 scale,要想获得柱子中间的 x 值,则需要加上柱子的一半宽度,柱子宽度通过 scale.bandwidth() 获得。
处理数据 1 2 3 4 5 6 7 8 9 10 11 12 13 14 data.forEach (d => { attr2.push ({ shape : { cx : xScale (d[0 ]) + bandWidth / 2 , cy : yScale (d[1 ]), r : 10 }, style : { fill : 'red' , stroke : 'green' , lineWidth : 5 } }) })
结合 scale 和数据,生成需要绘图的数据和配置,不同的 shape 对应不同的配置,可通过 https://ecomfe.github.io/zrender-doc/public/api.html 查看各 shape 的配置方法
绘制图形 主要有 setShape 和 setShapeGroup 两个方法进行绘制
setShape(name, Shape, shapeAttr, animateOption, callback): 设置单个 shape
setShapeGroup(name, Shape, shapeAttrArray, animateOption, callback): 设置一组 shape
其中参数
name: 形状的名字
Shape: 要绘制的形状构造器,如 Line、Circle 等
shapeAttr(Array): 形状的配置
animateOption: 动画相关的配置
callback: 绘制完成的回调
给绘制的图形设置动画(可选) 设置 setShape(Group) 的 animateOption 参数,即可以决定是否开启动画和动画相关配置,完整配置参数如下:
1 2 3 4 5 6 { animation: Boolean animateFrom: Object duration: Number easing: String }
给绘制的图形绑定事件(可选) 在 setShape(Group) 的事件回调 callback 中,参数即为绘制好的图形,可直接通过 .on 方法对其进行事件绑定,更多方法见:https://ecomfe.github.io/zrender-doc/public/api.html#oneventname-eventhandler-context 如:
1 2 3 4 5 6 7 8 9 10 11 this.setShapeGroup( 'circle' , D3Charts.graphic.Circle, attr2, {}, function (circle ) { circle .on ('click' , () => { console.log('我被点击了!' ) }) } )