百度前端技术部 echarts 团队
浏览器端数据可视化图表组件库
15000
{0|图表 / 组件 / 交互行为 / API}
{0|}
- {1|变化多、需扩展、需易维护}
- {2|架构、演变}
{0| 所有数据、组件、布局、行为、...
由用户声明的 option 描述
}
Note: 在基本设定(声明式,数据驱动,单向流)下才有后面的讨论。
{0|}
下面在这几方面介绍架构的设计和进化
Note: 下面的介绍,按『需求』->『解决』(按需抽象)的逻辑
{1|~800*500}
Note: coord 有公用的 interface(如 dataToPoint)。coord 有单独的阶段。
{0|~800*400}
Note: 过渡动画指的是:option 不放在 view 里管理,从而 view 能重用,从而能在非 merge 模式有过渡动画。 引入Model后这些feature的实现会清晰。
option cascade
option management: timeline
option management: responsive (media query)
回顾: echarts2 ARCH
Note: 下面从『组件依赖』这个例子来介绍引入『工作流程』的意义。
【组件间的依赖】
{2|依赖声明和拓扑} {3|}
Note: dependency: ec2#echarts.js: dataZoom.syncOption。
【组件间的交互】
【组件间的交互】
echarts2:事件通讯
{0|消除了组件的『实例间的依赖』}
问题 1:需主动监听其他组件的事件。
{0|~1100*220}
{1|}
{2|组件之间仍然要互相知晓(类型的依赖)}
Note:
onlegendselected 中,tooltip 要主动监听,并更新自己的 selectedMap,从而才能遍历 series 时候避开没有选中的。各个 component 都要主动监听,则扩展性问题。
问题 2:
// 因为交互行为导致的后续过程(如清除、刷新等)可能有所不同, // echarts main 只得主动监听一些组件事件,从而形成了 switch case。 switch (eventType) { case ecConfig.EVENT.LEGEND_SELECTED : this._onlegendSelected(param); break; case ecConfig.EVENT.DATA_ZOOM : ... this._ondataZoom(param); break; case ecConfig.EVENT.DATA_RANGE : fromMyself && this._ondataRange(param); break; case ecConfig.EVENT.MAGIC_TYPE_CHANGED : ... this._onmagicTypeChanged(param); break; case ecConfig.EVENT.DATA_VIEW_CHANGED : fromMyself && this._ondataViewChanged(param); break; case ecConfig.EVENT.TOOLTIP_HOVER : fromMyself && this._tooltipHover(param); break; case ecConfig.EVENT.RESTORE : case ecConfig.EVENT.REFRESH : case ecConfig.EVENT.TOOLTIP_IN_GRID : case ecConfig.EVENT.TOOLTIP_OUT_GRID : ...
{1|纯粹的『事件模式』并不足以指导后续行为}
Note:
一些后续行为,如 clearEffect 之类,是公用的,不适于写在每个组件的事件响应函数中。
{0|}
{2|}
Note: 无非都是(1)改变状态(2)更新数据(3)刷新视图 和具体事件无关(刷新的类型稍微有点变化,比如tooltip不需要全局刷新)。 所以可以进一步解耦抽象:阶段。
{0|}
echarts3 workflow
Note:
从视觉编码这例子来看工作流程。
数据 => 视觉元素
{0|标记:点、线、面}
{1|视觉通道}
Note: 不同组件都能干涉 visual(visaulMap 组件,brush 组件,原生组件) (legend 对颜色的干涉 ec2 中存在 legend)
{0|尽量解耦?} {1|尽量抽象?}