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

ovilia pushed a commit to branch feat-custom
in repository https://gitbox.apache.org/repos/asf/echarts.git

commit 197bacd2d84a94e03dbfd27e6c620da0dc8247af
Author: Ovilia <[email protected]>
AuthorDate: Mon Aug 5 17:33:09 2024 +0800

    feat(custom): custom series can be registered
---
 src/chart/custom/CustomSeriesManager.ts | 17 ++++++
 src/chart/custom/CustomView.ts          |  6 ++-
 src/core/echarts.ts                     |  6 +++
 src/model/Global.ts                     | 17 +++++-
 test/custom-register.html               | 92 +++++++++++++++++++++++++++++++++
 5 files changed, 135 insertions(+), 3 deletions(-)

diff --git a/src/chart/custom/CustomSeriesManager.ts 
b/src/chart/custom/CustomSeriesManager.ts
new file mode 100644
index 000000000..e4b1d6085
--- /dev/null
+++ b/src/chart/custom/CustomSeriesManager.ts
@@ -0,0 +1,17 @@
+import { CustomSeriesRenderItem } from './CustomSeries';
+
+const customRenderers: {[type: string]: CustomSeriesRenderItem} = {};
+
+class CustomSeriesManager {
+
+    static register = function (type: string, creator: 
CustomSeriesRenderItem): void {
+        customRenderers[type] = creator;
+    };
+
+    static get = function (type: string): CustomSeriesRenderItem {
+        return customRenderers[type];
+    }
+
+}
+
+export default CustomSeriesManager;
diff --git a/src/chart/custom/CustomView.ts b/src/chart/custom/CustomView.ts
index ee4e244cf..0122deef7 100644
--- a/src/chart/custom/CustomView.ts
+++ b/src/chart/custom/CustomView.ts
@@ -591,7 +591,11 @@ function makeRenderItem(
     ecModel: GlobalModel,
     api: ExtensionAPI
 ) {
-    const renderItem = customSeries.get('renderItem');
+    const type = customSeries.get('type').split('.');
+    const customRenderer = type.length > 1
+        ? ecModel.getCustomRenderer(type[1])
+        : null;
+    const renderItem = customRenderer || customSeries.get('renderItem');
     const coordSys = customSeries.coordinateSystem;
     let prepareResult = {} as ReturnType<PrepareCustomInfo>;
 
diff --git a/src/core/echarts.ts b/src/core/echarts.ts
index 4ecb2c653..5b742da0e 100644
--- a/src/core/echarts.ts
+++ b/src/core/echarts.ts
@@ -51,6 +51,7 @@ import ComponentModel from '../model/Component';
 import SeriesModel from '../model/Series';
 import ComponentView, {ComponentViewConstructor} from '../view/Component';
 import ChartView, {ChartViewConstructor} from '../view/Chart';
+import {CustomSeriesRenderItem} from '../chart/custom/CustomSeries';
 import * as graphic from '../util/graphic';
 import {getECData} from '../util/innerStore';
 import {
@@ -132,6 +133,7 @@ import lifecycle, {
 import { platformApi, setPlatformAPI } from 'zrender/src/core/platform';
 import { getImpl } from './impl';
 import type geoSourceManager from '../coord/geo/geoSourceManager';
+import CustomSeriesManager from '../chart/custom/CustomSeriesManager';
 
 declare let global: any;
 
@@ -2893,6 +2895,10 @@ export function getCoordinateSystemDimensions(type: 
string): DimensionDefinition
     }
 }
 
+export function registerCustomSeries(seriesType: string, renderItem: 
CustomSeriesRenderItem) {
+    CustomSeriesManager.register(seriesType, renderItem);
+}
+
 export {registerLocale} from './locale';
 
 /**
diff --git a/src/model/Global.ts b/src/model/Global.ts
index b845d7263..e59b8bc6f 100644
--- a/src/model/Global.ts
+++ b/src/model/Global.ts
@@ -62,6 +62,7 @@ import { concatInternalOptions } from 
'./internalComponentCreator';
 import { LocaleOption } from '../core/locale';
 import {PaletteMixin} from './mixin/palette';
 import { error, warn } from '../util/log';
+import CustomSeriesManager from '../chart/custom/CustomSeriesManager';
 
 export interface GlobalModelSetOptionOpts {
     replaceMerge: ComponentMainType | ComponentMainType[];
@@ -161,6 +162,8 @@ class GlobalModel extends Model<ECUnitOption> {
 
     private _optionManager: OptionManager;
 
+    private _customSeriesManager: CustomSeriesManager;
+
     private _componentsMap: HashMap<ComponentModel[], ComponentMainType>;
 
     /**
@@ -410,14 +413,20 @@ class GlobalModel extends Model<ECUnitOption> {
                 }
                 else {
                     const isSeriesType = mainType === 'series';
+
+                    let subType = resultItem.keyInfo.subType;
+                    if (subType && subType.startsWith('custom.')) {
+                        subType = 'custom';
+                    }
+
                     const ComponentModelClass = (ComponentModel as 
ComponentModelConstructor).getClass(
-                        mainType, resultItem.keyInfo.subType,
+                        mainType,
+                        subType,
                         !isSeriesType // Give a more detailed warn later if 
series don't exists
                     );
 
                     if (!ComponentModelClass) {
                         if (__DEV__) {
-                            const subType = resultItem.keyInfo.subType;
                             const seriesImportName = 
BUILTIN_CHARTS_MAP[subType as keyof typeof BUILTIN_CHARTS_MAP];
                             if (!componetsMissingLogPrinted[subType]) {
                                 componetsMissingLogPrinted[subType] = true;
@@ -578,6 +587,10 @@ echarts.use([${seriesImportName}]);`);
         }
     }
 
+    getCustomRenderer(type: string) {
+        return CustomSeriesManager.get(type);
+    }
+
     /**
      * @return Never be null/undefined.
      */
diff --git a/test/custom-register.html b/test/custom-register.html
new file mode 100644
index 000000000..89f6da5ea
--- /dev/null
+++ b/test/custom-register.html
@@ -0,0 +1,92 @@
+<!DOCTYPE html>
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+
+<html>
+    <head>
+        <meta charset="utf-8">
+        <meta name="viewport" content="width=device-width, initial-scale=1" />
+        <script src="lib/simpleRequire.js"></script>
+        <script src="lib/config.js"></script>
+        <script src="lib/jquery.min.js"></script>
+        <script src="lib/facePrint.js"></script>
+        <script src="lib/testHelper.js"></script>
+        <!-- <script src="ut/lib/canteen.js"></script> -->
+        <link rel="stylesheet" href="lib/reset.css" />
+    </head>
+    <body>
+        <style>
+        </style>
+
+
+
+        <div id="main0"></div>
+
+
+
+
+
+
+        <script>
+        require([
+            'echarts',
+            // 'map/js/china',
+            // './data/nutrients.json'
+        ], function (echarts) {
+            const renderItem = (params, api) => {
+                return {
+                    type: 'circle',
+                    shape: {
+                        cx: api.coord([api.value(0), api.value(1)])[0],
+                        cy: api.coord([api.value(0), api.value(1)])[1],
+                        r: api.value(2)
+                    },
+                    style: {
+                        fill: api.visual('color')
+                    }
+                }
+            };
+            echarts.registerCustomSeries('bubble', renderItem);
+
+            const option = {
+                xAxis: {},
+                yAxis: {},
+                series: {
+                    type: 'custom.bubble',
+                    data: [[11, 22, 20], [33, 44, 40]]
+                }
+            };
+
+            const chart = testHelper.create(echarts, 'main0', {
+                title: [
+                    'Custom Series: bubble',
+                ],
+                option: option
+                // height: 300,
+                // buttons: [{text: 'btn-txt', onclick: function () {}}],
+                // recordCanvas: true,
+            });
+        });
+        </script>
+
+
+    </body>
+</html>
+


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to