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. 文件分享微信小程序的设计与开发 Java开发微信小程序 毕业设计
  2. 官方资源帖!手把手教你在TensorFlow 2.0中实现CycleGAN,推特上百赞
  3. Windows7 VMware虚拟机安装Apple Mac OSX v10.7 Lion
  4. Ruby Cucumber环境
  5. 一种网络进程间通信的方式—— 管道
  6. 遍历这些字符串,如果字符串没有包含数字的,就将字符串中的小写字母转成大写字母并打印字符串
  7. www.android ind.com,Android
  8. mysql解压版id是什么_Mysql安装(解压版)
  9. Jordan Elman Neural Networks
  10. element ui el-dialog 居中,并且内容多的时候内部可以滚动
  11. Linux下修改当前用户的最大线程数和 open files
  12. html5-5 HTML5表单元素和内嵌框架
  13. php微信转跳浏览器代码,通用微信QQ跳转浏览器打开代码
  14. EXP-00091: Exporting questionable statistics. 解决
  15. form表单提交到controller时出现404的尴尬问题(或链接不到.action、链接不到.do跳404的问题)
  16. 【 IntelliJ IDEA 】设置主题和字体
  17. 服务器图片显示小方块,高手帮忙了!!验证码跟着敲好之后 服务器打开一个小方块里面空的!在线等!!!...
  18. 巴比特 | 元宇宙每日必读:云南首个元宇宙产业园落户昆明,预计总投资 2600 万元,将探索开发NFT产品...
  19. MongoDB之副本集配置
  20. 简述电子产品的电磁兼容性设计

热门文章

  1. matlab 罗德里格 公式,旋转矩阵,四元素,欧拉角
  2. 达芬奇 17.1.1为苹果 M1 Mac 添加 H.264 10bit 硬件加速解码支持
  3. html实现价格随数量变化,一种商品价格智能分段递减定价方法与流程
  4. C语言之文件处理(fputc fgetc函数的使用)下篇
  5. POJ 2492 并查集,带权或带偏移量并查集 【例题详解】
  6. web自动化前置准备之html
  7. 探究网上的一个用MATLAB写的SIFT
  8. ESP32 LVGL8.1 ——btn 按钮 (btn 15)
  9. 三级分销系统系统设计
  10. 基于连通域标记的点云树木分离(点云聚类)