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]
