2021SC@SDUSC

Component源码解读---接上篇

plain

legend.plain为平面的legend图例组件,主要包含LegendAction、LegendModel和LegendView文件。

import LegendModel from './LegendModel';
import LegendView from './LegendView';
import legendFilter from './legendFilter';
import { installLegendAction } from './legendAction';
export function install(registers) {registers.registerComponentModel(LegendModel);registers.registerComponentView(LegendView);registers.registerProcessor(registers.PRIORITY.PROCESSOR.SERIES_FILTER, legendFilter);registers.registerSubTypeDefaulter('legend', function () {return 'plain';});installLegendAction(registers);
}

LegendAction文件中注册了legend的对外API: legendToggleSelect、legendAllSelect、legendInverseSelect、legendSelect和legendUnSelect。

registers.registerAction('legendToggleSelect', 'legendselectchanged', curry(legendSelectActionHandler, 'toggleSelected'));
registers.registerAction('legendAllSelect', 'legendselectall', curry(legendSelectActionHandler, 'allSelect'));
registers.registerAction('legendInverseSelect', 'legendinverseselect', curry(legendSelectActionHandler, 'inverseSelect'));
registers.registerAction('legendSelect', 'legendselected', curry(legendSelectActionHandler, 'select'));
registers.registerAction('legendUnSelect', 'legendunselected', curry(legendSelectActionHandler, 'unSelect'));

LegendFilter文件中当legend的isSelected返回true,则显示与legend name相同series的数据,即实现数据过滤。

export default function legendFilter(ecModel) {var legendModels = ecModel.findComponents({mainType: 'legend'});if (legendModels && legendModels.length) {ecModel.filterSeries(function (series) {// If in any legend component the status is not selected.// Because in legend series is assumed selected when it is not in the legend data.for (var i = 0; i < legendModels.length; i++) {if (!legendModels[i].isSelected(series.name)) { //isSelected返回false,则与legend name相同的series数据不显示return false;}}return true;});}
}

LegendModel通过extendComponentModel方法扩展自Component Model,重写defaultOption属性,重写了init方法,定义了select、unSelect、toggleSelected以及isSelected等方法。

LegendView 通过extendComponentView方法扩展自Component View,重写了init以及render方法对legend进行渲染.

//重写initLegendView.prototype.init = function () {this.group.add(this._contentGroup = new Group());this.group.add(this._selectorGroup = new Group());this._isFirstRender = true;};
//重写render
LegendView.prototype.render = function (legendModel, ecModel, api) {var isFirstRender = this._isFirstRender;this._isFirstRender = false;this.resetInner();if (!legendModel.get('show', true)) {return;}var itemAlign = legendModel.get('align');var orient = legendModel.get('orient');if (!itemAlign || itemAlign === 'auto') {itemAlign = legendModel.get('left') === 'right' && orient === 'vertical' ? 'right' : 'left';} // selector has been normalized to an array in modelvar selector = legendModel.get('selector', true);var selectorPosition = legendModel.get('selectorPosition', true);if (selector && (!selectorPosition || selectorPosition === 'auto')) {selectorPosition = orient === 'horizontal' ? 'end' : 'start';}this.renderInner(itemAlign, legendModel, ecModel, api, selector, orient, selectorPosition); // Perform layout.
//见下面代码LegendView.prototype.renderInnervar positionInfo = legendModel.getBoxLayoutParams();var viewportSize = {width: api.getWidth(),height: api.getHeight()};var padding = legendModel.get('padding');var maxSize = layoutUtil.getLayoutRect(positionInfo, viewportSize, padding);var mainRect = this.layoutInner(legendModel, itemAlign, maxSize, isFirstRender, selector, selectorPosition); // Place mainGroup, based on the calculated `mainRect`.var layoutRect = layoutUtil.getLayoutRect(zrUtil.defaults({width: mainRect.width,height: mainRect.height}, positionInfo), viewportSize, padding);this.group.x = layoutRect.x - mainRect.x;this.group.y = layoutRect.y - mainRect.y;this.group.markRedraw(); // Render background after group is layout.this.group.add(this._backgroundEl = makeBackground(mainRect, legendModel));};// renderInner中调用了createItem方法创建Legend item
// 并绑定了click、mouseover、mouseout等事件
LegendView.prototype.renderInner = function (itemAlign, legendModel, ecModel, api, selector, orient, selectorPosition) {var contentGroup = this.getContentGroup();var legendDrawnMap = zrUtil.createHashMap();var selectMode = legendModel.get('selectedMode');var excludeSeriesId = [];ecModel.eachRawSeries(function (seriesModel) {!seriesModel.get('legendHoverLink') && excludeSeriesId.push(seriesModel.id);});each(legendModel.getData(), function (legendItemModel, dataIndex) {var name = legendItemModel.get('name'); // Use empty string or \n as a newline stringif (!this.newlineDisabled && (name === '' || name === '\n')) {var g = new Group(); // @ts-ignoreg.newline = true;contentGroup.add(g);return;} // Representitive series.var seriesModel = ecModel.getSeriesByName(name)[0];if (legendDrawnMap.get(name)) {// Have been drawedreturn;} // Legend to control series.if (seriesModel) {var data = seriesModel.getData();var lineVisualStyle = data.getVisual('legendLineStyle') || {};var legendIcon = data.getVisual('legendIcon');/*** `data.getVisual('style')` may be the color from the register* in series. For example, for line series,*/var style = data.getVisual('style');var itemGroup = this._createItem(seriesModel, name, dataIndex, legendItemModel, legendModel, itemAlign, lineVisualStyle, style, legendIcon, selectMode);//创建ItemitemGroup.on('click', curry(dispatchSelectAction, name, null, api, excludeSeriesId)).on('mouseover', curry(dispatchHighlightAction, seriesModel.name, null, api, excludeSeriesId)).on('mouseout', curry(dispatchDownplayAction, seriesModel.name, null, api, excludeSeriesId));//绑定了click、mouseover、mouseout等事件legendDrawnMap.set(name, true);} else {// Legend to control data. In pie and funnel.ecModel.eachRawSeries(function (seriesModel) {// In case multiple series has same data nameif (legendDrawnMap.get(name)) {return;}if (seriesModel.legendVisualProvider) {var provider = seriesModel.legendVisualProvider;if (!provider.containName(name)) {return;}var idx = provider.indexOfName(name);var style = provider.getItemVisual(idx, 'style');var legendIcon = provider.getItemVisual(idx, 'legendIcon');var colorArr = parse(style.fill); // Color may be set to transparent in visualMap when data is out of range.// Do not show nothing.if (colorArr && colorArr[3] === 0) {colorArr[3] = 0.2; // TODO color is set to 0, 0, 0, 0. Should show correct RGBAstyle.fill = stringify(colorArr, 'rgba');}var itemGroup = this._createItem(seriesModel, name, dataIndex, legendItemModel, legendModel, itemAlign, {}, style, legendIcon, selectMode); // FIXME: consider different series has items with the same name.itemGroup.on('click', curry(dispatchSelectAction, null, name, api, excludeSeriesId)) // Should not specify the series name, consider legend controls// more than one pie series..on('mouseover', curry(dispatchHighlightAction, null, name, api, excludeSeriesId)).on('mouseout', curry(dispatchDownplayAction, null, name, api, excludeSeriesId));legendDrawnMap.set(name, true);}}, this);}if (process.env.NODE_ENV !== 'production') {if (!legendDrawnMap.get(name)) {console.warn(name + ' series not exists. Legend data should be same with series name or data name.');}}}, this);if (selector) {this._createSelector(selector, legendModel, api, orient, selectorPosition);}};//创建Item
LegendView.prototype._createItem = function (seriesModel, name, dataIndex, legendItemModel, legendModel, itemAlign, lineVisualStyle, itemVisualStyle, legendIcon, selectMode) {var drawType = seriesModel.visualDrawType;var itemWidth = legendModel.get('itemWidth');var itemHeight = legendModel.get('itemHeight');var isSelected = legendModel.isSelected(name);var iconRotate = legendItemModel.get('symbolRotate');var symbolKeepAspect = legendItemModel.get('symbolKeepAspect');var legendIconType = legendItemModel.get('icon');legendIcon = legendIconType || legendIcon || 'roundRect';var style = getLegendStyle(legendIcon, legendItemModel, lineVisualStyle, itemVisualStyle, drawType, isSelected);var itemGroup = new Group();var textStyleModel = legendItemModel.getModel('textStyle');if (typeof seriesModel.getLegendIcon === 'function' && (!legendIconType || legendIconType === 'inherit')) {// Series has specific way to define legend iconitemGroup.add(seriesModel.getLegendIcon({itemWidth: itemWidth,itemHeight: itemHeight,icon: legendIcon,iconRotate: iconRotate,itemStyle: style.itemStyle,lineStyle: style.lineStyle,symbolKeepAspect: symbolKeepAspect}));} else {// Use default legend icon policy for most seriesvar rotate = legendIconType === 'inherit' && seriesModel.getData().getVisual('symbol') ? iconRotate === 'inherit' ? seriesModel.getData().getVisual('symbolRotate') : iconRotate : 0; // No rotation for no iconitemGroup.add(getDefaultLegendIcon({itemWidth: itemWidth,itemHeight: itemHeight,icon: legendIcon,iconRotate: rotate,itemStyle: style.itemStyle,lineStyle: style.lineStyle,symbolKeepAspect: symbolKeepAspect}));}var textX = itemAlign === 'left' ? itemWidth + 5 : -5;var textAlign = itemAlign;var formatter = legendModel.get('formatter');var content = name;if (typeof formatter === 'string' && formatter) {content = formatter.replace('{name}', name != null ? name : '');} else if (typeof formatter === 'function') {content = formatter(name);}var inactiveColor = legendItemModel.get('inactiveColor');itemGroup.add(new graphic.Text({style: createTextStyle(textStyleModel, {text: content,x: textX,y: itemHeight / 2,fill: isSelected ? textStyleModel.getTextColor() : inactiveColor,align: textAlign,verticalAlign: 'middle'})})); // Add a invisible rect to increase the area of mouse hovervar hitRect = new graphic.Rect({shape: itemGroup.getBoundingRect(),invisible: true});var tooltipModel = legendItemModel.getModel('tooltip');if (tooltipModel.get('show')) {graphic.setTooltipConfig({el: hitRect,componentModel: legendModel,itemName: name,itemTooltipOption: tooltipModel.option});}itemGroup.add(hitRect);itemGroup.eachChild(function (child) {child.silent = true;});hitRect.silent = !selectMode;this.getContentGroup().add(itemGroup);enableHoverEmphasis(itemGroup); // @ts-ignoreitemGroup.__legendDataIndex = dataIndex;return itemGroup;};

ECharts 源码解读 五相关推荐

  1. ECharts 源码解读 二

    2021SC@SDUSC 源码结构和打包 源码使用webpack打包,查看文件webpack.config.js可知,将echarts源码编译成三个版本,分别为常用版本,精简版本,完整版本,分别对应w ...

  2. rocketmq的broker源码解读五(刷盘)

    5)刷盘 在2.1.1.3)小节中,提到了启动刷盘线程,这里进行详述:commitLog默认异步刷盘,用的是FlushRealTimeService实例,同步刷盘用的是GroupCommitServi ...

  3. Echarts 源码解读 十

    2021SC@SDUSC 直角坐标轴 Axis 包括xAxis, yAxis CartesianAxisView CartesianAxisView扩展自AxisView,重写了render,定义了s ...

  4. faster rcnn源码解读(五)之layer(网络里的input-data)

    转载自:faster rcnn源码解读(五)之layer(网络里的input-data) - 野孩子的专栏 - 博客频道 - CSDN.NET http://blog.csdn.net/u010668 ...

  5. SnapKit 源码解读(五):Models

    Models 里面的所有文件,都是用来对约束建模使用的. Typealiases Typealiases 为跨平台能力定义了一套公用的类. #if os(iOS) || os(tvOS)import ...

  6. Vue源码解读(五):render和VNode

    Vue 2.0 相比 Vue 1.0 最大的升级就是利用了虚拟DOM. 在 Vue 1.0 中视图的更新是纯响应式的.在进行响应式初始化的时候,一个响应式数据 key 会创建一个对应的 dep,这个 ...

  7. Alamofire源码解读系列(五)之结果封装(Result)

    本篇讲解Result的封装 前言 有时候,我们会根据现实中的事物来对程序中的某个业务关系进行抽象,这句话很难理解.在Alamofire中,使用Response来描述请求后的结果.我们都知道Alamof ...

  8. Bert系列(二)——源码解读之模型主体

    本篇文章主要是解读模型主体代码modeling.py.在阅读这篇文章之前希望读者们对bert的相关理论有一定的了解,尤其是transformer的结构原理,网上的资料很多,本文内容对原理部分就不做过多 ...

  9. Bert系列(三)——源码解读之Pre-train

    https://www.jianshu.com/p/22e462f01d8c pre-train是迁移学习的基础,虽然Google已经发布了各种预训练好的模型,而且因为资源消耗巨大,自己再预训练也不现 ...

最新文章

  1. 利用OpenCV求取图像的重心
  2. 最近的生活 - 18年03月20日
  3. 图像阈值处理cv2.threshold()函数(python)
  4. 区块链去中心化的生命之源:“DPOS(委托权益证明)共识机制”
  5. OpenCV reshape函数需要注意的细节
  6. 白银TD盈亏计算实例介绍
  7. mysql三张表关联查询成绩表_mysql三张表关联查询
  8. 《Adobe Illustrator CC经典教程》—第0课0.2节使用Adobe Creative Cloud进行同步设置
  9. 常用Win32 API函数
  10. 备战2019年数据库系统工程师从什么时候开始合适?
  11. 综合布线干线子系统设计原则
  12. 7个顶级静态代码分析工具
  13. 频率相噪中相关公式、名词注释详解
  14. Java学习-设计模式-单例模式
  15. 制作本地视频网站 苹果cms 超详细
  16. 关键词抽取工具-THUtag 个人使用心得
  17. 闹钟(Alarm Clock)
  18. 华为服务器批量系统软件,华为云ECS批量管理工具
  19. java 文件移动_java 文件移动
  20. Android自定义View2--触摸事件传递机制

热门文章

  1. 武田将在美国血液学会第60届年会上呈报各类血液肿瘤治疗需求数据
  2. java开发页面超链接样式_Web报表中如何设置超链接的样式
  3. Image Animation是什么
  4. 分页插件 limit使用失败
  5. 新年伊始,我们共赴数据盛宴,与未来对话!​(文末有彩蛋)
  6. 大学生医用计算机题库,2020年大学生计算机二级考试练习试题(一)包含答案...
  7. 实用的PDF阅读器官方版
  8. comsol显示电场计算结果_comsol电场示例.pdf
  9. videoInput库+opencv+usb采集卡+监控相机
  10. 局域网测速工具lan_speed