You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@echarts.apache.org by su...@apache.org on 2019/09/22 19:31:44 UTC

[incubator-echarts] 01/01: feat: provide `echarts.registerShape` and `echarts.getShapeClass` for custom shape in `custom series` and `graphic component`.

This is an automated email from the ASF dual-hosted git repository.

sushuang pushed a commit to branch fix/custom-graphic
in repository https://gitbox.apache.org/repos/asf/incubator-echarts.git

commit 8813853c61fe4ff99a5a56e0bb6d5a6e66acf19f
Author: SHUANG SU <su...@gmail.com>
AuthorDate: Mon Sep 23 03:16:52 2019 +0800

    feat: provide `echarts.registerShape` and `echarts.getShapeClass` for custom shape in `custom series` and `graphic component`.
---
 src/chart/custom.js      | 10 +++++++-
 src/component/graphic.js | 18 +++++++++++++-
 src/export.js            |  1 +
 src/util/graphic.js      | 61 ++++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 88 insertions(+), 2 deletions(-)

diff --git a/src/chart/custom.js b/src/chart/custom.js
index 7c31bb7..784e59c 100644
--- a/src/chart/custom.js
+++ b/src/chart/custom.js
@@ -231,6 +231,8 @@ function createEl(elOption) {
     var graphicType = elOption.type;
     var el;
 
+    // Those graphic elements are not shapes. They should not be
+    // overwritten by users, so do them first.
     if (graphicType === 'path') {
         var shape = elOption.shape;
         // Using pathRect brings convenience to users sacle svg path.
@@ -255,8 +257,14 @@ function createEl(elOption) {
         el = new graphicUtil.Text({});
         el.__customText = elOption.style.text;
     }
+    else if (graphicType === 'group') {
+        el = new graphicUtil.Group();
+    }
+    else if (graphicType === 'compoundPath') {
+        throw new Error('"compoundPath" is not supported yet.');
+    }
     else {
-        var Clz = graphicUtil[graphicType.charAt(0).toUpperCase() + graphicType.slice(1)];
+        var Clz = graphicUtil.getShapeClass(graphicType);
 
         if (__DEV__) {
             zrUtil.assert(Clz, 'graphic type "' + graphicType + '" can not be found.');
diff --git a/src/component/graphic.js b/src/component/graphic.js
index 92674a7..e689db1 100644
--- a/src/component/graphic.js
+++ b/src/component/graphic.js
@@ -26,6 +26,18 @@ import * as graphicUtil from '../util/graphic';
 import * as layoutUtil from '../util/layout';
 import {parsePercent} from '../util/number';
 
+var _nonShapeGraphicElements = {
+
+    // Reserved but not supported in graphic component.
+    path: null,
+    compoundPath: null,
+
+    // Supported in graphic component.
+    group: graphicUtil.Group,
+    image: graphicUtil.Image,
+    text: graphicUtil.Text
+};
+
 // -------------
 // Preprocessor
 // -------------
@@ -440,7 +452,11 @@ function createEl(id, targetElParent, elOption, elMap) {
         zrUtil.assert(graphicType, 'graphic type MUST be set');
     }
 
-    var Clz = graphicUtil[graphicType.charAt(0).toUpperCase() + graphicType.slice(1)];
+    var Clz = _nonShapeGraphicElements.hasOwnProperty(graphicType)
+        // Those graphic elements are not shapes. They should not be
+        // overwritten by users, so do them first.
+        ? _nonShapeGraphicElements[graphicType]
+        : graphicUtil.getShapeClass(graphicType);
 
     if (__DEV__) {
         zrUtil.assert(Clz, 'graphic type can not be found');
diff --git a/src/export.js b/src/export.js
index dded75c..6ddd62e 100644
--- a/src/export.js
+++ b/src/export.js
@@ -71,6 +71,7 @@ zrUtil.each(
         'setHoverStyle', 'setLabelStyle', 'setTextStyle', 'setText',
         'getFont', 'updateProps', 'initProps', 'getTransform',
         'clipPointsByRect', 'clipRectByRect',
+        'registerShape', 'getShapeClass',
         'Group',
         'Image',
         'Text',
diff --git a/src/util/graphic.js b/src/util/graphic.js
index 38b2b85..0ca633d 100644
--- a/src/util/graphic.js
+++ b/src/util/graphic.js
@@ -65,6 +65,8 @@ var NORMAL = 'normal';
 var _highlightNextDigit = 1;
 var _highlightKeyMap = {};
 
+var _customShapeMap = {};
+
 
 /**
  * Extend shape with parameters
@@ -81,6 +83,53 @@ export function extendPath(pathData, opts) {
 }
 
 /**
+ * Register a user defined shape.
+ * The shape class can be fetched by `getShapeClass`
+ * This method will not overwrite the built-in shapes.
+ * The shape can be used in `custom series` and
+ * `graphic component` by declaring `{type: name}`.
+ *
+ * @param {string} name
+ * @param {Object} ShapeClass Can be generated by `extendShape`.
+ */
+export function registerShape(name, ShapeClass) {
+    _customShapeMap[name] = ShapeClass;
+}
+
+/**
+ * Find shape class registered by `registerShape`. Usually used in
+ * fetching user defined shape.
+ *
+ * [Caution]:
+ * (1) This method **MUST NOT be used inside echarts !!!**, unless it is prepared
+ * to use user registered shapes.
+ * Because the built-in shape (see `getBuiltInShape`) will be registered by
+ * `registerShape` by default. That enables users to get both built-in
+ * shapes as well as the shapes belonging to themsleves. But users can overwrite
+ * the built-in shapes by using names like 'circle', 'rect' via calling
+ * `registerShape`. So the echarts inner featrues should not fetch shapes from here
+ * in case that it is overwritten by users, except that some features, like
+ * `custom series`, `graphic component`, do it deliberately.
+ *
+ * (2) In the features like `custom series`, `graphic component`, the user input
+ * `{tpye: 'xxx'}` does not only specify shapes but also specify other graphic
+ * elements like `'group'`, `'text'`, `'image'` or event `'path'`. Those names
+ * are reserved names, that is, if some user register a shape named `'image'`,
+ * the shape will not be used. If we intending to add some more reserved names
+ * in feature, that might bring break changes (disable some existing user shape
+ * names). But that case probably rearly happen. So we dont make more mechanism
+ * to resolve this issue here.
+ *
+ * @param {string} name
+ * @return {Object} The shape class. If not found, return nothing.
+ */
+export function getShapeClass(name) {
+    if (_customShapeMap.hasOwnProperty(name)) {
+        return _customShapeMap[name];
+    }
+}
+
+/**
  * Create a path element from path data string
  * @param {string} pathData
  * @param {Object} opts
@@ -1377,6 +1426,18 @@ function nearZero(val) {
     return val <= (1e-6) && val >= -(1e-6);
 }
 
+// Register built-in shapes. These shapes might be overwirtten
+// by users, although we do not recommend that.
+registerShape('circle', Circle);
+registerShape('sector', Sector);
+registerShape('ring', Ring);
+registerShape('polygon', Polygon);
+registerShape('polyline', Polyline);
+registerShape('rect', Rect);
+registerShape('line', Line);
+registerShape('bezierCurve', BezierCurve);
+registerShape('arc', Arc);
+
 export {
     Group,
     ZImage as Image,


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@echarts.apache.org
For additional commands, e-mail: commits-help@echarts.apache.org