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/07/13 07:13:41 UTC

[echarts] 02/02: refact(data): fix createDimensions multiple times cause default encode wrong.

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

shenyi pushed a commit to branch dataset-perf
in repository https://gitbox.apache.org/repos/asf/echarts.git

commit 83bc2d9d8a145f236b90a290eddf6519433aaed0
Author: pissang <bm...@gmail.com>
AuthorDate: Tue Jul 13 15:12:07 2021 +0800

    refact(data): fix createDimensions multiple times cause default encode  wrong.
---
 src/chart/helper/createSeriesDataFromArray.ts | 32 +++++++++++++--------------
 src/data/DataStorage.ts                       |  2 +-
 src/data/SeriesData.ts                        |  2 +-
 src/data/helper/createDimensions.ts           | 15 ++-----------
 src/data/helper/dimensionHelper.ts            | 14 +++++++++++-
 src/data/helper/sourceManager.ts              | 22 ++++++++++++------
 6 files changed, 48 insertions(+), 39 deletions(-)

diff --git a/src/chart/helper/createSeriesDataFromArray.ts b/src/chart/helper/createSeriesDataFromArray.ts
index f4b7796..02d7176 100644
--- a/src/chart/helper/createSeriesDataFromArray.ts
+++ b/src/chart/helper/createSeriesDataFromArray.ts
@@ -20,7 +20,7 @@
 import * as zrUtil from 'zrender/src/core/util';
 import SeriesData from '../../data/SeriesData';
 import createDimensions, { CreateDimensionsParams } from '../../data/helper/createDimensions';
-import {getDimensionTypeByAxis} from '../../data/helper/dimensionHelper';
+import {getDimensionTypeByAxis, omitUnusedDimensions} from '../../data/helper/dimensionHelper';
 import {getDataItemValue} from '../../util/model';
 import CoordinateSystem from '../../core/CoordinateSystem';
 import {getCoordSysInfoBySeries} from '../../model/referHelper';
@@ -122,9 +122,11 @@ function createListFromArray(
 
     const coordSysInfo = getCoordSysInfoBySeries(seriesModel);
     const coordSysDimDefs = getCoordSysDimDefs(seriesModel, coordSysInfo);
-
     const useEncodeDefaulter = opt.useEncodeDefaulter;
-    const createDimensionsConfig = {
+
+    // NOTE: don't call createDimensions on same source multiple times.
+    // It will break the encodeDefaulter which has sideeffects.
+    let dimInfoList = createDimensions(sourceOrStore, {
         coordDimensions: coordSysDimDefs,
         generateCoord: opt.generateCoord,
         encodeDefine: seriesModel.getEncode(),
@@ -132,22 +134,20 @@ function createListFromArray(
             ? useEncodeDefaulter
             : useEncodeDefaulter
             ? zrUtil.curry(makeSeriesEncodeForAxisCoordSys, coordSysDimDefs, seriesModel)
-            : null,
-        // Try to ignore unsed dimensions if sharing a high dimension datastorage
-        // 10 is an experience value.
-        ignoreUnusedDimension: isDataStorage(sourceOrStore)
-            && sourceOrStore.getDimensionCount() > 10
-    } as CreateDimensionsParams;
-    let dimInfoList = createDimensions(sourceOrStore, createDimensionsConfig);
+            : null
+    });
     let firstCategoryDimIndex = injectOrdinalMeta(dimInfoList, opt.createInvertedIndices, coordSysInfo);
 
-    if (isDataStorage(sourceOrStore)) {
+    // Try to ignore unsed dimensions if sharing a high dimension datastorage
+    // 10 is an experience value.
+    if (isDataStorage(sourceOrStore) && sourceOrStore.getDimensionCount() > 10) {
+        const omitedDimInfoList = omitUnusedDimensions(dimInfoList);
         // sourceOrStore
-        if (!sourceOrStore.syncDimensionTypes(dimInfoList)) {
-            // Fallback.
-            dimInfoList = createDimensions(sourceOrStore, zrUtil.extend(
-                createDimensionsConfig, { ignoreUnusedDimension: false }
-            ));
+        if (sourceOrStore.syncDimensionTypes(omitedDimInfoList)) {
+            dimInfoList = omitedDimInfoList;
+        }
+        else {
+            // Fallback
             firstCategoryDimIndex = injectOrdinalMeta(
                 dimInfoList, opt.createInvertedIndices, coordSysInfo
             );
diff --git a/src/data/DataStorage.ts b/src/data/DataStorage.ts
index eb4ee1a..c089e1b 100644
--- a/src/data/DataStorage.ts
+++ b/src/data/DataStorage.ts
@@ -239,7 +239,7 @@ class DataStorage {
         return this._dimensions.length;
     }
 
-    setOrdinalMeta(
+    collectOrdinalMeta(
         dimIdx: number,
         ordinalMeta: OrdinalMeta
     ) {
diff --git a/src/data/SeriesData.ts b/src/data/SeriesData.ts
index cc15ea5..f01c349 100644
--- a/src/data/SeriesData.ts
+++ b/src/data/SeriesData.ts
@@ -464,7 +464,7 @@ class SeriesData<
             const dimInfo = this._dimensionInfos[dimensions[i]];
             if (dimInfo.ordinalMeta) {
                 const dimIdx = store.getDimensionIndex(dimensions[i]);
-                store.setOrdinalMeta(dimIdx, dimInfo.ordinalMeta);
+                store.collectOrdinalMeta(dimIdx, dimInfo.ordinalMeta);
             }
         }
     }
diff --git a/src/data/helper/createDimensions.ts b/src/data/helper/createDimensions.ts
index dc5b163..57be8e9 100644
--- a/src/data/helper/createDimensions.ts
+++ b/src/data/helper/createDimensions.ts
@@ -62,13 +62,7 @@ export type CreateDimensionsParams = {
      */
     encodeDefaulter?: EncodeDefaulter,
     generateCoord?: string,
-    generateCoordCount?: number,
-    /**
-     * If ignore unused dimensions.
-     * This config will improve performance signifantly when multiple series
-     * is sharing a extra high dimension dataset.
-     */
-    ignoreUnusedDimension?: boolean
+    generateCoordCount?: number
 };
 
 /**
@@ -238,7 +232,6 @@ export default function createDimensions(
     let coordDimNameAutoIdx = 0;
     let dataDimNameAutoIdx = 0;
 
-    const pickedResult = [];
     // Set dim `name` and other `coordDim` and other props.
     for (let resultDimIdx = 0; resultDimIdx < dimCount; resultDimIdx++) {
         const resultItem = result[resultDimIdx] = result[resultDimIdx] || new DataDimensionInfo();
@@ -290,13 +283,9 @@ export default function createDimensions(
         ) {
             resultItem.type = 'ordinal';
         }
-
-        if (!resultItem.isExtraCoord || keys(resultItem.otherDims).length > 0) {
-            pickedResult.push(resultItem);
-        }
     }
 
-    return opt.ignoreUnusedDimension ? pickedResult : result;
+    return result;
 }
 
 
diff --git a/src/data/helper/dimensionHelper.ts b/src/data/helper/dimensionHelper.ts
index aae9c2e..492c488 100644
--- a/src/data/helper/dimensionHelper.ts
+++ b/src/data/helper/dimensionHelper.ts
@@ -18,12 +18,13 @@
 */
 
 
-import {each, createHashMap, assert} from 'zrender/src/core/util';
+import {each, createHashMap, assert, filter, keys} from 'zrender/src/core/util';
 import SeriesData from '../SeriesData';
 import {
     DimensionName, VISUAL_DIMENSIONS, DimensionType, DimensionUserOuput, DimensionUserOuputEncode, DimensionIndex
 } from '../../util/types';
 import { DataStorageDimensionType } from '../DataStorage';
+import DataDimensionInfo from '../DataDimensionInfo';
 
 export type DimensionSummaryEncode = {
     defaultedLabel: DimensionName[],
@@ -41,6 +42,17 @@ export type DimensionSummary = {
     encodeFirstDimNotExtra: {[coordDim: string]: DimensionName},
 };
 
+/**
+ * Omit unused dimensions.
+ * This will improve performance signifantly when multiple series
+ * is sharing a extra high dimension dataset.
+ */
+export function omitUnusedDimensions(dims: DataDimensionInfo[]) {
+    return filter(dims, (dim) => {
+        return !dim.isExtraCoord || keys(dim.otherDims).length > 0;
+    });
+}
+
 export function summarizeDimensions(data: SeriesData): DimensionSummary {
     const summary: DimensionSummary = {} as DimensionSummary;
     const encode = summary.encode = {} as DimensionSummaryEncode;
diff --git a/src/data/helper/sourceManager.ts b/src/data/helper/sourceManager.ts
index 4d0e941..b1f4f63 100644
--- a/src/data/helper/sourceManager.ts
+++ b/src/data/helper/sourceManager.ts
@@ -356,12 +356,24 @@ export class SourceManager {
 
     /**
      * Will return undefined if source don't have dimensions.
+     *
+     * Only available for series.
      */
     getDataStorage(): DataStorage | undefined {
-        return this._innerGetDataStorage(this.getSource(0));
+        if (__DEV__) {
+            assert(isSeries(this._sourceHost), 'Can only call getDataStorage on series source manager.')
+        }
+        const source = this.getSource(0);
+        const dimensionsDefine = source.dimensionsDefine;
+        const sourceReadKey = source.seriesLayoutBy
+            + '$$'
+            + source.startIndex
+            + (dimensionsDefine ? map(dimensionsDefine, def => def.name).join('$$') : '');
+
+        return this._innerGetDataStorage(source, sourceReadKey);
     }
 
-    private _innerGetDataStorage(endSource?: Source): DataStorage | undefined {
+    private _innerGetDataStorage(endSource: Source, sourceReadKey: string): DataStorage | undefined {
         // TODO Can use other sourceIndex?
         const sourceIndex = 0;
 
@@ -373,10 +385,6 @@ export class SourceManager {
         // when seriesLayoutBy or startIndex(which is affected by sourceHeader) are different.
         // So we use this two props as key. Another fact `dimensions` will be checked when initializing SeriesData.
         const sourceToInit = (endSource || source);
-        const seriesLayoutBy = sourceToInit.seriesLayoutBy;
-        const startIndex = sourceToInit.startIndex;
-        const sourceReadKey = seriesLayoutBy + '_' + startIndex;
-
         let cachedStoreMap = storeList[sourceIndex];
 
         if (!cachedStoreMap) {
@@ -388,7 +396,7 @@ export class SourceManager {
             const upSourceMgr = this._getUpstreamSourceManagers()[0];
 
             if (isSeries(this._sourceHost) && upSourceMgr) {
-                cachedStore = upSourceMgr._innerGetDataStorage(endSource);
+                cachedStore = upSourceMgr._innerGetDataStorage(endSource, sourceReadKey);
             }
             else {
                 const dimensionsDefine = source.dimensionsDefine;

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