You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@echarts.apache.org by sh...@apache.org on 2021/03/31 06:08:41 UTC

[echarts] 02/02: fix(debug): enhance error log when component is missing

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

shenyi pushed a commit to branch enhance-missing-components-log
in repository https://gitbox.apache.org/repos/asf/echarts.git

commit 4933a8ea7a91eb1753ed24cc2dcd2ae5a6252a58
Author: pissang <bm...@gmail.com>
AuthorDate: Wed Mar 31 14:06:08 2021 +0800

    fix(debug): enhance error log when component is missing
---
 src/model/Global.ts   | 85 ++++++++++++++++++++++++++++++++++++++++++++++++++-
 src/util/component.ts |  4 +--
 2 files changed, 86 insertions(+), 3 deletions(-)

diff --git a/src/model/Global.ts b/src/model/Global.ts
index 8e77709..3cfbc24 100644
--- a/src/model/Global.ts
+++ b/src/model/Global.ts
@@ -61,6 +61,7 @@ import Scheduler from '../core/Scheduler';
 import { concatInternalOptions } from './internalComponentCreator';
 import { LocaleOption } from '../core/locale';
 import {PaletteMixin} from './mixin/palette';
+import { error } from '../util/log';
 
 export interface GlobalModelSetOptionOpts {
     replaceMerge: ComponentMainType | ComponentMainType[];
@@ -79,6 +80,57 @@ let initBase: (ecModel: GlobalModel, baseOption: ECUnitOption) => void;
 const OPTION_INNER_KEY = '\0_ec_inner';
 const OPTION_INNER_VALUE = 1;
 
+const BUITIN_COMPONENTS_MAP = {
+    grid: 'GridComponent',
+    polar: 'PolarComponent',
+    geo: 'GeoComponent',
+    singleAxis: 'SingleAxisComponent',
+    parallel: 'ParallelComponent',
+    calendar: 'CalendarComponent',
+    graphic: 'GraphicComponent',
+    toolbox: 'ToolboxComponent',
+    tooltip: 'TooltipComponent',
+    axisPointer: 'AxisPointerComponent',
+    brush: 'BrushComponent',
+    title: 'TitleComponent',
+    timeline: 'TimelineComponent',
+    markPoint: 'MarkPointComponent',
+    markLine: 'MarkLineComponent',
+    markArea: 'MarkAreaComponent',
+    legend: 'LegendComponent',
+    dataZoom: 'DataZoomComponent',
+    visualMap: 'VisualMapComponent'
+    // aria: 'AriaComponent',
+    // dataset: 'DatasetComponent'
+} as const;
+
+const BUILTIN_CHARTS_MAP = {
+    line: 'LineChart',
+    bar: 'BarChart',
+    pie: 'PieChart',
+    scatter: 'ScatterChart',
+    radar: 'RadarChart',
+    map: 'MapChart',
+    tree: 'TreeChart',
+    treemap: 'TreemapChart',
+    graph: 'GraphChart',
+    gauge: 'GaugeChart',
+    funnel: 'FunnelChart',
+    parallel: 'ParallelChart',
+    sankey: 'SankeyChart',
+    boxplot: 'BoxplotChart',
+    candlestick: 'CandlestickChart',
+    effectScatter: 'EffectScatterChart',
+    lines: 'LinesChart',
+    heatmap: 'HeatmapChart',
+    pictorialBar: 'PictorialBarChart',
+    themeRiver: 'ThemeRiverChart',
+    sunburst: 'SunburstChart',
+    custom: 'CustomChart'
+} as const;
+
+const componetsMissingLogPrinted: Record<string, boolean> = {};
+
 class GlobalModel extends Model<ECUnitOption> {
     // @readonly
     option: ECUnitOption;
@@ -250,6 +302,16 @@ class GlobalModel extends Model<ECUnitOption> {
             }
 
             if (!ComponentModel.hasClass(mainType)) {
+                if (__DEV__) {
+                    const namedComponents = BUITIN_COMPONENTS_MAP[mainType as keyof typeof BUITIN_COMPONENTS_MAP];
+                    if (namedComponents && !componetsMissingLogPrinted[namedComponents]) {
+                        error(`Component ${mainType} is used but not imported.
+import { ${namedComponents} } from 'echarts/components';
+echarts.use([${namedComponents}]);`);
+                        componetsMissingLogPrinted[namedComponents] = true;
+                    }
+                }
+
                 // globalSettingTask.dirty();
                 option[mainType] = option[mainType] == null
                     ? clone(componentOption)
@@ -328,10 +390,31 @@ class GlobalModel extends Model<ECUnitOption> {
                     // or it has been removed in previous `replaceMerge` and left a "hole" in this component index.
                 }
                 else {
+                    const isSeriesType = mainType === 'series';
                     const ComponentModelClass = (ComponentModel as ComponentModelConstructor).getClass(
-                        mainType, resultItem.keyInfo.subType, true
+                        mainType, resultItem.keyInfo.subType,
+                        isSeriesType // Give a more detailed warn if series don't exists
                     );
 
+                    if (!ComponentModelClass) {
+                        if (__DEV__) {
+                            const subType = resultItem.keyInfo.subType;
+                            const namedSeries = BUILTIN_CHARTS_MAP[subType as keyof typeof BUILTIN_CHARTS_MAP];
+                            if (!componetsMissingLogPrinted[subType]) {
+                                componetsMissingLogPrinted[subType] = true;
+                                if (namedSeries) {
+                                    error(`Series ${subType} is used but not imported.
+import { ${namedSeries} } from 'echarts/charts';
+echarts.use([${namedSeries}]);`);
+                                }
+                                else {
+                                    error(`Unkown series ${subType}`);
+                                }
+                            }
+                        }
+                        return;
+                    }
+
                     if (componentModel && componentModel.constructor === ComponentModelClass) {
                         componentModel.name = resultItem.keyInfo.name;
                         // componentModel.settingTask && componentModel.settingTask.dirty();
diff --git a/src/util/component.ts b/src/util/component.ts
index 5433337..de55be6 100644
--- a/src/util/component.ts
+++ b/src/util/component.ts
@@ -102,7 +102,7 @@ type DepGraph = {[cmptMainType: string]: DepGraphItem};
  * Topological travel on Activity Network (Activity On Vertices).
  * Dependencies is defined in Model.prototype.dependencies, like ['xAxis', 'yAxis'].
  * If 'xAxis' or 'yAxis' is absent in componentTypeList, just ignore it in topology.
- * If there is circle dependencey, Error will be thrown.
+ * If there is circular dependencey, Error will be thrown.
  */
 export function enableTopologicalTravel<T>(
     entity: TopologicalTravelable<T>,
@@ -152,7 +152,7 @@ export function enableTopologicalTravel<T>(
         zrUtil.each(targetNameSet, function () {
             let errMsg = '';
             if (__DEV__) {
-                errMsg = makePrintable('Circle dependency may exists: ', targetNameSet, targetNameList, fullNameList);
+                errMsg = makePrintable('Circular dependency may exists: ', targetNameSet, targetNameList, fullNameList);
             }
             throw new Error(errMsg);
         });

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