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