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 2022/03/18 04:15:33 UTC
[echarts] 02/02: feat(transform): introduce aggregate and id transform
This is an automated email from the ASF dual-hosted git repository.
shenyi pushed a commit to branch aggregate-transform
in repository https://gitbox.apache.org/repos/asf/echarts.git
commit f6a7c3aee0fa7ed717a06da8e94492048eae957c
Author: pissang <bm...@gmail.com>
AuthorDate: Fri Mar 18 12:15:00 2022 +0800
feat(transform): introduce aggregate and id transform
---
src/component/transform/aggregateTransform.ts | 595 ++++++++++++++++++++++++++
src/component/transform/idTransform.ts | 95 ++++
src/component/transform/install.ts | 4 +
test/custom-shape-morphing2.html | 13 +-
test/custom-shape-morphing3.html | 13 +-
test/data-transform-aggregate.html | 26 +-
test/lib/config.js | 1 -
test/lib/ecSimpleTransform.js | 362 ----------------
test/universalTransition2.html | 10 +-
9 files changed, 718 insertions(+), 401 deletions(-)
diff --git a/src/component/transform/aggregateTransform.ts b/src/component/transform/aggregateTransform.ts
new file mode 100644
index 0000000..5bbf131
--- /dev/null
+++ b/src/component/transform/aggregateTransform.ts
@@ -0,0 +1,595 @@
+/*
+* 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.
+*/
+
+import { assert, hasOwn } from 'zrender/src/core/util';
+import {
+ DataTransformOption,
+ ExternalDataTransform,
+ ExternalDimensionDefinition,
+ ExternalSource
+} from '../../data/helper/transform';
+import { asc, quantile } from '../../util/number';
+import { DimensionLoose, DimensionName, OptionDataValue } from '../../util/types';
+
+/**
+ * @usage
+ *
+ * ```js
+ * dataset: [{
+ * source: [
+ * ['aa', 'bb', 'cc', 'tag'],
+ * [12, 0.33, 5200, 'AA'],
+ * [21, 0.65, 7100, 'AA'],
+ * [51, 0.15, 1100, 'BB'],
+ * [71, 0.75, 9100, 'BB'],
+ * ...
+ * ]
+ * }, {
+ * transform: {
+ * type: 'ecSimpleTransform:aggregate',
+ * config: {
+ * output: [
+ * // by default, use the same name with `from`.
+ * { from: 'aa', method: 'sum' },
+ * { from: 'bb', method: 'count' },
+ * { from: 'cc' }, // method by default: use the first value.
+ * { from: 'dd', method: 'Q1' },
+ * { from: 'tag' }
+ * ],
+ * groupBy: 'tag'
+ * }
+ * }
+ * // Then the result data will be:
+ * // [
+ * // ['aa', 'bb', 'cc', 'tag'],
+ * // [12, 0.33, 5200, 'AA'],
+ * // [21, 0.65, 8100, 'BB'],
+ * // ...
+ * // ]
+ * }]
+ * ```
+ */
+
+export interface AggregateTransformOption extends DataTransformOption {
+ type: 'echarts:aggregate';
+ config: {
+ // Mandatory
+ output: {
+ // Optional. The name of the result dimensions.
+ // If not provided, inherit the name from `from`.
+ name: DimensionName;
+ // Mandatory. `from` is used to reference dimension from `source`.
+ from: DimensionLoose;
+ // Optional. Aggregate method. Currently only these method supported.
+ // If not provided, use `'first'`.
+ method: AggregateMethodLoose;
+ }[];
+ // Optional
+ groupBy: DimensionLoose;
+ };
+}
+
+const METHOD_INTERNAL = {
+ 'SUM': true,
+ 'COUNT': true,
+ 'FIRST': true,
+ 'AVERAGE': true,
+ 'Q1': true,
+ 'Q2': true,
+ 'Q3': true,
+ 'MIN': true,
+ 'MAX': true
+} as const;
+const METHOD_NEEDS_COLLECT = {
+ AVERAGE: ['COUNT']
+} as const;
+const METHOD_NEEDS_GATHER_VALUES = {
+ Q1: true,
+ Q2: true,
+ Q3: true
+} as const;
+const METHOD_ALIAS = {
+ MEDIAN: 'Q2'
+} as const;
+
+type AggregateMethodLoose =
+ AggregateMethodInternal
+ | 'sum' | 'count' | 'first' | 'average' | 'Q1' | 'Q2' | 'Q3' | 'median' | 'min' | 'max';
+type AggregateMethodInternal = keyof typeof METHOD_INTERNAL;
+
+
+class ResultDimInfoInternal {
+
+ readonly method: AggregateMethodInternal;
+ readonly name: DimensionName;
+ readonly index: number;
+ readonly indexInUpstream: number;
+
+ readonly collectionInfoList = [] as {
+ method: AggregateMethodInternal;
+ indexInLine: number;
+ }[];
+
+ // FIXME: refactor
+ readonly gatheredValuesByGroup: { [groupVal: string]: number[] } = {};
+ readonly gatheredValuesNoGroup = [] as number[];
+ readonly needGatherValues: boolean = false;
+
+ __collectionResult: TravelResult<CollectionResultLine>;
+
+ private _collectionInfoMap = {} as {
+ // number is the index of `list`
+ [method in AggregateMethodInternal]: number
+ };
+
+ constructor(
+ index: number,
+ indexInUpstream: number,
+ method: AggregateMethodInternal,
+ name: DimensionName,
+ needGatherValues: boolean
+ ) {
+ this.method = method;
+ this.name = name;
+ this.index = index;
+ this.indexInUpstream = indexInUpstream;
+ this.needGatherValues = needGatherValues;
+ }
+
+ addCollectionInfo(item: ResultDimInfoInternal['collectionInfoList'][number]) {
+ this._collectionInfoMap[item.method] = this.collectionInfoList.length;
+ this.collectionInfoList.push(item);
+ }
+
+ getCollectionInfo(method: AggregateMethodInternal) {
+ return this.collectionInfoList[this._collectionInfoMap[method]];
+ }
+
+ // FIXME: temp implementation. Need refactor.
+ gatherValue(groupByDimInfo: ExternalDimensionDefinition, groupVal: OptionDataValue, value: OptionDataValue) {
+ // FIXME: convert to number compulsorily temporarily.
+ value = +value;
+ if (groupByDimInfo) {
+ if (groupVal != null) {
+ const groupValStr = groupVal + '';
+ const values = this.gatheredValuesByGroup[groupValStr]
+ || (this.gatheredValuesByGroup[groupValStr] = []);
+ values.push(value);
+ }
+ }
+ else {
+ this.gatheredValuesNoGroup.push(value);
+ }
+ }
+}
+
+type CreateInTravel<LINE> = (
+ upstream: ExternalSource,
+ dataIndex: number,
+ dimInfoList: ResultDimInfoInternal[],
+ groupByDimInfo?: ExternalDimensionDefinition,
+ groupByVal?: OptionDataValue
+) => LINE;
+type UpdateInTravel<LINE> = (
+ upstream: ExternalSource,
+ dataIndex: number,
+ targetLine: LINE,
+ dimInfoList: ResultDimInfoInternal[],
+ groupByDimInfo?: ExternalDimensionDefinition,
+ groupByVal?: OptionDataValue
+) => void;
+
+export const aggregateTransform: ExternalDataTransform<AggregateTransformOption> = {
+
+ type: 'echarts:aggregate',
+
+ transform: function (params) {
+ const upstream = params.upstream;
+ const config = params.config;
+
+ const groupByDimInfo = prepareGroupByDimInfo(config, upstream);
+ const { finalResultDimInfoList, collectionDimInfoList } = prepareDimensions(
+ config, upstream, groupByDimInfo
+ );
+
+ // Collect
+ let collectionResult: TravelResult<CollectionResultLine>;
+ if (collectionDimInfoList.length) {
+ collectionResult = travel(
+ groupByDimInfo,
+ upstream,
+ collectionDimInfoList,
+ createCollectionResultLine,
+ updateCollectionResultLine
+ );
+ }
+
+ for (let i = 0; i < collectionDimInfoList.length; i++) {
+ const dimInfo = collectionDimInfoList[i];
+ dimInfo.__collectionResult = collectionResult;
+ // FIXME: just for Q1, Q2, Q3: need asc.
+ asc(dimInfo.gatheredValuesNoGroup);
+
+ const gatheredValuesByGroup = dimInfo.gatheredValuesByGroup;
+ for (const key in gatheredValuesByGroup) {
+ if (hasOwn(gatheredValuesByGroup, key)) {
+ asc(gatheredValuesByGroup[key]);
+ }
+ }
+ }
+
+ // Calculate
+ const finalResult = travel(
+ groupByDimInfo,
+ upstream,
+ finalResultDimInfoList,
+ createFinalResultLine,
+ updateFinalResultLine
+ );
+
+ const dimensions = [];
+ for (let i = 0; i < finalResultDimInfoList.length; i++) {
+ dimensions.push(finalResultDimInfoList[i].name);
+ }
+
+ return {
+ dimensions: dimensions,
+ data: finalResult.outList
+ };
+ }
+};
+
+function prepareDimensions(
+ config: AggregateTransformOption['config'],
+ upstream: ExternalSource,
+ groupByDimInfo: ExternalDimensionDefinition
+): {
+ finalResultDimInfoList: ResultDimInfoInternal[];
+ collectionDimInfoList: ResultDimInfoInternal[];
+} {
+ const outputConfig = config.output;
+ const finalResultDimInfoList: ResultDimInfoInternal[] = [];
+ const collectionDimInfoList: ResultDimInfoInternal[] = [];
+ let gIndexInLine = 0;
+
+ for (let i = 0; i < outputConfig.length; i++) {
+ const resultDimInfoConfig = outputConfig[i];
+
+ const dimInfoInUpstream = upstream.getDimensionInfo(resultDimInfoConfig.from);
+ if (__DEV__) {
+ assert(dimInfoInUpstream, 'Can not find dimension by `from`: ' + resultDimInfoConfig.from);
+ }
+
+ const rawMethod = resultDimInfoConfig.method;
+
+ if (__DEV__) {
+ assert(
+ groupByDimInfo.index !== dimInfoInUpstream.index || rawMethod == null,
+ `Dimension ${dimInfoInUpstream.name} is the "groupBy" dimension, must not have any "method".`
+ );
+ }
+
+ const method = normalizeMethod(rawMethod);
+
+ if (__DEV__) {
+ assert(method, 'method is required');
+ }
+
+ const name = resultDimInfoConfig.name != null ? resultDimInfoConfig.name : dimInfoInUpstream.name;
+
+ const finalResultDimInfo = new ResultDimInfoInternal(
+ finalResultDimInfoList.length,
+ dimInfoInUpstream.index,
+ method,
+ name,
+ hasOwn(METHOD_NEEDS_GATHER_VALUES, method)
+ );
+ finalResultDimInfoList.push(finalResultDimInfo);
+
+ // For collection.
+ let needCollect = false;
+ if (hasOwn(METHOD_NEEDS_COLLECT, method)) {
+ needCollect = true;
+ const collectionTargetMethods = METHOD_NEEDS_COLLECT[method as keyof typeof METHOD_NEEDS_COLLECT];
+ for (let j = 0; j < collectionTargetMethods.length; j++) {
+ finalResultDimInfo.addCollectionInfo({
+ method: collectionTargetMethods[j],
+ indexInLine: gIndexInLine++
+ });
+ }
+ }
+ if (hasOwn(METHOD_NEEDS_GATHER_VALUES, method)) {
+ needCollect = true;
+ }
+ if (needCollect) {
+ collectionDimInfoList.push(finalResultDimInfo);
+ }
+ }
+
+ return { collectionDimInfoList, finalResultDimInfoList };
+}
+
+function prepareGroupByDimInfo(
+ config: AggregateTransformOption['config'],
+ upstream: ExternalSource
+): ExternalDimensionDefinition {
+ const groupByConfig = config.groupBy;
+ let groupByDimInfo;
+ if (groupByConfig != null) {
+ groupByDimInfo = upstream.getDimensionInfo(groupByConfig);
+ assert(groupByDimInfo, 'Can not find dimension by `groupBy`: ' + groupByConfig);
+ }
+ return groupByDimInfo;
+}
+
+interface TravelResult<LINE> {
+ mapByGroup: { [groupVal: string]: LINE };
+ outList: LINE[];
+}
+
+function travel<LINE>(
+ groupByDimInfo: ExternalDimensionDefinition,
+ upstream: ExternalSource,
+ resultDimInfoList: ResultDimInfoInternal[],
+ doCreate: CreateInTravel<LINE>,
+ doUpdate: UpdateInTravel<LINE>
+): TravelResult<LINE> {
+ const outList: TravelResult<LINE>['outList'] = [];
+ let mapByGroup: TravelResult<LINE>['mapByGroup'];
+
+ if (groupByDimInfo) {
+ mapByGroup = {};
+
+ for (let dataIndex = 0, len = upstream.count(); dataIndex < len; dataIndex++) {
+ const groupByVal = upstream.retrieveValue(dataIndex, groupByDimInfo.index);
+
+ // PENDING: when value is null/undefined
+ if (groupByVal == null) {
+ continue;
+ }
+
+ const groupByValStr = groupByVal + '';
+
+ if (!hasOwn(mapByGroup, groupByValStr)) {
+ const newLine = doCreate(upstream, dataIndex, resultDimInfoList, groupByDimInfo, groupByVal);
+ outList.push(newLine);
+ mapByGroup[groupByValStr] = newLine;
+ }
+ else {
+ const targetLine = mapByGroup[groupByValStr];
+ doUpdate(upstream, dataIndex, targetLine, resultDimInfoList, groupByDimInfo, groupByVal);
+ }
+ }
+ }
+ else {
+ const targetLine = doCreate(upstream, 0, resultDimInfoList);
+ outList.push(targetLine);
+ for (let dataIndex = 1, len = upstream.count(); dataIndex < len; dataIndex++) {
+ doUpdate(upstream, dataIndex, targetLine, resultDimInfoList);
+ }
+ }
+
+ return { mapByGroup, outList };
+}
+
+function normalizeMethod(method: AggregateMethodLoose): AggregateMethodInternal {
+ if (method == null) {
+ return 'FIRST';
+ }
+ let methodInternal = method.toUpperCase() as AggregateMethodInternal;
+ methodInternal = hasOwn(METHOD_ALIAS, methodInternal)
+ ? METHOD_ALIAS[methodInternal as keyof typeof METHOD_ALIAS]
+ : methodInternal;
+ assert(hasOwn(METHOD_INTERNAL, methodInternal), `Illegal method ${method}.`);
+ return methodInternal;
+}
+
+
+
+type CollectionResultLine = number[];
+
+const createCollectionResultLine: CreateInTravel<CollectionResultLine> = (
+ upstream, dataIndex, collectionDimInfoList, groupByDimInfo, groupByVal
+) => {
+ const newLine = [] as number[];
+ for (let i = 0; i < collectionDimInfoList.length; i++) {
+ const dimInfo = collectionDimInfoList[i];
+ const collectionInfoList = dimInfo.collectionInfoList;
+ for (let j = 0; j < collectionInfoList.length; j++) {
+ const collectionInfo = collectionInfoList[j];
+ // FIXME: convert to number compulsorily temporarily.
+ newLine[collectionInfo.indexInLine] = +lineCreator[collectionInfo.method](
+ upstream, dataIndex, dimInfo, groupByDimInfo, groupByVal
+ );
+ }
+ // FIXME: refactor
+ if (dimInfo.needGatherValues) {
+ const val = upstream.retrieveValue(dataIndex, dimInfo.indexInUpstream);
+ dimInfo.gatherValue(groupByDimInfo, groupByVal, val);
+ }
+ }
+ return newLine;
+};
+
+const updateCollectionResultLine: UpdateInTravel<CollectionResultLine> = (
+ upstream, dataIndex, targetLine: number[], collectionDimInfoList, groupByDimInfo, groupByVal
+) => {
+ for (let i = 0; i < collectionDimInfoList.length; i++) {
+ const dimInfo = collectionDimInfoList[i];
+ const collectionInfoList = dimInfo.collectionInfoList;
+ for (let j = 0; j < collectionInfoList.length; j++) {
+ const collectionInfo = collectionInfoList[j];
+ const indexInLine = collectionInfo.indexInLine;
+ // FIXME: convert to number compulsorily temporarily.
+ targetLine[indexInLine] = +lineUpdater[collectionInfo.method](
+ targetLine[indexInLine], upstream, dataIndex, dimInfo, groupByDimInfo, groupByVal
+ );
+ }
+ // FIXME: refactor
+ if (dimInfo.needGatherValues) {
+ const val = upstream.retrieveValue(dataIndex, dimInfo.indexInUpstream);
+ dimInfo.gatherValue(groupByDimInfo, groupByVal, val);
+ }
+ }
+};
+
+
+
+type FinalResultLine = OptionDataValue[];
+
+const createFinalResultLine: CreateInTravel<FinalResultLine> = (
+ upstream, dataIndex, finalResultDimInfoList, groupByDimInfo, groupByVal
+) => {
+ const newLine = [];
+ for (let i = 0; i < finalResultDimInfoList.length; i++) {
+ const dimInfo = finalResultDimInfoList[i];
+ const method = dimInfo.method;
+ newLine[i] = isGroupByDimension(groupByDimInfo, dimInfo)
+ ? groupByVal
+ : lineCreator[method](
+ upstream, dataIndex, dimInfo, groupByDimInfo, groupByVal
+ );
+ }
+ return newLine;
+};
+
+const updateFinalResultLine: UpdateInTravel<FinalResultLine> = (
+ upstream, dataIndex, targetLine, finalResultDimInfoList, groupByDimInfo, groupByVal
+) => {
+ for (let i = 0; i < finalResultDimInfoList.length; i++) {
+ const dimInfo = finalResultDimInfoList[i];
+ if (isGroupByDimension(groupByDimInfo, dimInfo)) {
+ continue;
+ }
+ const method = dimInfo.method;
+ targetLine[i] = lineUpdater[method](
+ targetLine[i], upstream, dataIndex, dimInfo, groupByDimInfo, groupByVal
+ );
+ }
+};
+
+function isGroupByDimension(
+ groupByDimInfo: ExternalDimensionDefinition,
+ targetDimInfo: ResultDimInfoInternal
+): boolean {
+ return groupByDimInfo && targetDimInfo.indexInUpstream === groupByDimInfo.index;
+}
+
+const lineCreator: {
+ [key in AggregateMethodInternal]: (
+ upstream: ExternalSource,
+ dataIndex: number,
+ dimInfo: ResultDimInfoInternal,
+ groupByDimInfo: ExternalDimensionDefinition,
+ groupByVal: OptionDataValue
+ ) => OptionDataValue
+} = {
+ 'SUM'(upstream, dataIndex, dimInfo) {
+ return upstream.retrieveValue(dataIndex, dimInfo.indexInUpstream);
+ },
+ 'COUNT'() {
+ return 1;
+ },
+ 'FIRST'(upstream, dataIndex, dimInfo) {
+ return upstream.retrieveValue(dataIndex, dimInfo.indexInUpstream);
+ },
+ 'MIN'(upstream, dataIndex, dimInfo) {
+ return upstream.retrieveValue(dataIndex, dimInfo.indexInUpstream);
+ },
+ 'MAX'(upstream, dataIndex, dimInfo) {
+ return upstream.retrieveValue(dataIndex, dimInfo.indexInUpstream);
+ },
+ 'AVERAGE'(upstream, dataIndex, dimInfo, groupByDimInfo, groupByVal) {
+ const collectionResult = dimInfo.__collectionResult;
+ // FIXME: refactor, bad implementation.
+ const collectLine = groupByDimInfo
+ ? collectionResult.mapByGroup[groupByVal + '']
+ : collectionResult.outList[0];
+ return (upstream.retrieveValue(dataIndex, dimInfo.indexInUpstream) as number)
+ / collectLine[dimInfo.getCollectionInfo('COUNT').indexInLine];
+ },
+ // FIXME: refactor
+ 'Q1'(upstream, dataIndex, dimInfo, groupByDimInfo, groupByVal) {
+ return lineCreatorForQ(0.25, dimInfo, groupByDimInfo, groupByVal);
+ },
+ 'Q2'(upstream, dataIndex, dimInfo, groupByDimInfo, groupByVal) {
+ return lineCreatorForQ(0.5, dimInfo, groupByDimInfo, groupByVal);
+ },
+ 'Q3'(upstream, dataIndex, dimInfo, groupByDimInfo, groupByVal) {
+ return lineCreatorForQ(0.75, dimInfo, groupByDimInfo, groupByVal);
+ }
+};
+
+const lineUpdater: {
+ [key in AggregateMethodInternal]: (
+ val: OptionDataValue,
+ upstream: ExternalSource,
+ dataIndex: number,
+ dimInfo: ResultDimInfoInternal,
+ groupByDimInfo: ExternalDimensionDefinition,
+ groupByVal: OptionDataValue
+ ) => OptionDataValue
+} = {
+ 'SUM'(val, upstream, dataIndex, dimInfo) {
+ // FIXME: handle other types
+ return (val as number) + (upstream.retrieveValue(dataIndex, dimInfo.indexInUpstream) as number);
+ },
+ 'COUNT'(val) {
+ return (val as number) + 1;
+ },
+ 'FIRST'(val) {
+ return val;
+ },
+ 'MIN'(val, upstream, dataIndex, dimInfo) {
+ return Math.min(val as number, upstream.retrieveValue(dataIndex, dimInfo.indexInUpstream) as number);
+ },
+ 'MAX'(val, upstream, dataIndex, dimInfo) {
+ return Math.max(val as number, upstream.retrieveValue(dataIndex, dimInfo.indexInUpstream) as number);
+ },
+ 'AVERAGE'(val, upstream, dataIndex, dimInfo, groupByDimInfo, groupByVal) {
+ // FIXME: refactor, bad implementation.
+ const collectLine = groupByDimInfo
+ ? dimInfo.__collectionResult.mapByGroup[groupByVal + '']
+ : dimInfo.__collectionResult.outList[0];
+ return (val as number)
+ + (upstream.retrieveValue(dataIndex, dimInfo.indexInUpstream) as number)
+ / collectLine[dimInfo.getCollectionInfo('COUNT').indexInLine];
+ },
+ 'Q1'(val, upstream, dataIndex, dimInfo) {
+ return val;
+ },
+ 'Q2'(val, upstream, dataIndex, dimInfo) {
+ return val;
+ },
+ 'Q3'(val, upstream, dataIndex, dimInfo) {
+ return val;
+ }
+};
+
+function lineCreatorForQ(
+ percent: number,
+ dimInfo: ResultDimInfoInternal,
+ groupByDimInfo: ExternalDimensionDefinition,
+ groupByVal: OptionDataValue
+) {
+ const gatheredValues = groupByDimInfo
+ ? dimInfo.gatheredValuesByGroup[groupByVal + '']
+ : dimInfo.gatheredValuesNoGroup;
+ return quantile(gatheredValues, percent);
+}
\ No newline at end of file
diff --git a/src/component/transform/idTransform.ts b/src/component/transform/idTransform.ts
new file mode 100644
index 0000000..8c01628
--- /dev/null
+++ b/src/component/transform/idTransform.ts
@@ -0,0 +1,95 @@
+/*
+* 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.
+*/
+
+import { DataTransformOption, ExternalDataTransform } from '../../data/helper/transform';
+import {
+ DimensionDefinitionLoose,
+ DimensionIndex,
+ DimensionName,
+ OptionSourceDataArrayRows
+} from '../../util/types';
+
+
+/**
+ * @usage
+ *
+ * ```js
+ * dataset: [{
+ * source: [
+ * ['aa', 'bb', 'cc', 'tag'],
+ * [12, 0.33, 5200, 'AA'],
+ * [21, 0.65, 8100, 'AA'],
+ * ...
+ * ]
+ * }, {
+ * transform: {
+ * type: 'ecSimpleTransform:id',
+ * config: {
+ * dimensionIndex: 4,
+ * dimensionName: 'ID'
+ * }
+ * }
+ * // Then the result data will be:
+ * // [
+ * // ['aa', 'bb', 'cc', 'tag', 'ID'],
+ * // [12, 0.33, 5200, 'AA', 0],
+ * // [21, 0.65, 8100, 'BB', 1],
+ * // ...
+ * // ]
+ * }]
+ * ```
+ */
+
+export interface IdTransformOption extends DataTransformOption {
+ type: 'echarts:id';
+ config: {
+ // Mandatory. Specify where to put the new id dimension.
+ dimensionIndex: DimensionIndex;
+ // Optional. If not provided, left the dimension name not defined.
+ dimensionName: DimensionName;
+ };
+}
+
+export const idTransform: ExternalDataTransform<IdTransformOption> = {
+
+ type: 'echarts:id',
+
+ transform: function (params) {
+ const upstream = params.upstream;
+ const config = params.config;
+ const dimensionIndex = config.dimensionIndex;
+ const dimensionName = config.dimensionName;
+
+ const dimsDef = upstream.cloneAllDimensionInfo() as DimensionDefinitionLoose[];
+ dimsDef[dimensionIndex] = dimensionName;
+
+ const data = upstream.cloneRawData() as OptionSourceDataArrayRows;
+
+ // TODO: support objectRows
+ for (let i = 0, len = data.length; i < len; i++) {
+ const line = data[i];
+ line[dimensionIndex] = i;
+ }
+
+ return {
+ dimensions: dimsDef,
+ data: data
+ };
+ }
+};
\ No newline at end of file
diff --git a/src/component/transform/install.ts b/src/component/transform/install.ts
index 208f6e0..01c1074 100644
--- a/src/component/transform/install.ts
+++ b/src/component/transform/install.ts
@@ -20,8 +20,12 @@
import { EChartsExtensionInstallRegisters } from '../../extension';
import {filterTransform} from './filterTransform';
import {sortTransform} from './sortTransform';
+import {aggregateTransform} from './aggregateTransform';
+import { idTransform } from './idTransform';
export function install(registers: EChartsExtensionInstallRegisters) {
registers.registerTransform(filterTransform);
registers.registerTransform(sortTransform);
+ registers.registerTransform(aggregateTransform);
+ registers.registerTransform(idTransform);
}
\ No newline at end of file
diff --git a/test/custom-shape-morphing2.html b/test/custom-shape-morphing2.html
index 8b5d2bc..91e8890 100644
--- a/test/custom-shape-morphing2.html
+++ b/test/custom-shape-morphing2.html
@@ -75,10 +75,9 @@ under the License.
<script>
require([
- 'echarts', 'ecStat', 'ecSimpleTransform', 'ecSimpleOptionPlayer'
- ], function (echarts, ecStat, ecSimpleTransform, ecSimpleOptionPlayer) {
+ 'echarts', 'ecStat', 'ecSimpleOptionPlayer'
+ ], function (echarts, ecStat, ecSimpleOptionPlayer) {
- echarts.registerTransform(ecSimpleTransform.aggregate);
echarts.registerTransform(ecStat.transform.clustering);
@@ -146,9 +145,9 @@ under the License.
id: 'mTagSum',
fromDatasetId: 'raw',
transform: {
- type: 'ecSimpleTransform:aggregate',
+ type: 'aggregate',
config: {
- resultDimensions: [
+ output: [
{ from: 'ATA', method: 'sum' },
{ from: 'STE', method: 'sum' },
{ from: 'CTZ', method: 'sum' },
@@ -183,10 +182,10 @@ under the License.
id: 'rawClusterCenters',
fromDatasetId: 'rawClusters',
transform: {
- type: 'ecSimpleTransform:aggregate',
+ type: 'aggregate',
print: true,
config: {
- resultDimensions: [
+ output: [
{ name: 'COUNT', from: 'ATA', method: 'count' },
{ from: 'CLUSTER_CENTER_ATA' },
{ from: 'CLUSTER_CENTER_STE' },
diff --git a/test/custom-shape-morphing3.html b/test/custom-shape-morphing3.html
index a5765f0..ad0f908 100644
--- a/test/custom-shape-morphing3.html
+++ b/test/custom-shape-morphing3.html
@@ -40,12 +40,9 @@ under the License.
<script>
require([
- 'echarts', 'ecStat', 'ecSimpleTransform', 'ecSimpleOptionPlayer',
+ 'echarts', 'ecStat', 'ecSimpleOptionPlayer',
'data/life-expectancy-table.json'
- ], function (echarts, ecStat, ecSimpleTransform, ecSimpleOptionPlayer, rawData) {
-
- echarts.registerTransform(ecSimpleTransform.aggregate);
- echarts.registerTransform(ecSimpleTransform.id);
+ ], function (echarts, ecStat, ecSimpleOptionPlayer, rawData) {
const COLORS = [
'#37A2DA', '#e06343', '#37a354', '#b55dba', '#b5bd48', '#8378EA', '#96BFFF'
@@ -93,7 +90,7 @@ under the License.
dimension: 'Year', gte: 1950
}
}, {
- type: 'ecSimpleTransform:id',
+ type: 'id',
config: {
dimensionIndex: ID_RAW_DATA_DIMENSIONS.indexOf('Id'),
dimensionName: 'Id'
@@ -116,9 +113,9 @@ under the License.
id: 'CountryABSumIncome',
fromDatasetId: 'CountryABData',
transform: {
- type: 'ecSimpleTransform:aggregate',
+ type: 'aggregate',
config: {
- resultDimensions: [
+ output: [
{ from: 'Income', method: 'sum' },
{ from: 'Country' }
],
diff --git a/test/data-transform-aggregate.html b/test/data-transform-aggregate.html
index f282099..97be6ed 100644
--- a/test/data-transform-aggregate.html
+++ b/test/data-transform-aggregate.html
@@ -47,10 +47,8 @@ under the License.
<script>
require([
'echarts',
- 'ecSimpleTransform',
'data/life-expectancy-table.json'
- ], function (echarts, ecSimpleTransform, _rawData) {
- echarts.registerTransform(ecSimpleTransform.aggregate);
+ ], function (echarts, _rawData) {
option = {
dataset: [{
@@ -65,9 +63,9 @@ under the License.
dimension: 'Year', gte: 1950
}
}, {
- type: 'ecSimpleTransform:aggregate',
+ type: 'aggregate',
config: {
- resultDimensions: [
+ output: [
{ from: 'Income', method: 'sum' },
{ from: 'Country' }
],
@@ -123,11 +121,9 @@ under the License.
<script>
require([
'echarts',
- 'ecSimpleTransform',
'data/life-expectancy-table.json'
- ], function (echarts, ecSimpleTransform, _rawData) {
+ ], function (echarts, _rawData) {
- echarts.registerTransform(ecSimpleTransform.aggregate);
option = {
dataset: [{
@@ -146,9 +142,9 @@ under the License.
}]
}
}, {
- type: 'ecSimpleTransform:aggregate',
+ type: 'aggregate',
config: {
- resultDimensions: [
+ output: [
{ name: 'min', from: 'Income', method: 'min' },
{ name: 'Q1', from: 'Income', method: 'Q1' },
{ name: 'Q2', from: 'Income', method: 'Q2' },
@@ -212,11 +208,9 @@ under the License.
<script>
require([
'echarts',
- 'ecSimpleTransform',
'data/life-expectancy-table.json'
- ], function (echarts, ecSimpleTransform, _rawData) {
+ ], function (echarts, _rawData) {
- echarts.registerTransform(ecSimpleTransform.aggregate);
option = {
dataset: [{
@@ -231,14 +225,12 @@ under the License.
config: {
and: [{
dimension: 'Year', gte: 1950
- // }, {
- // dimension: 'Country', eq: 'Japan'
}]
}
}, {
- type: 'ecSimpleTransform:aggregate',
+ type: 'aggregate',
config: {
- resultDimensions: [
+ output: [
{ from: 'Income', method: 'average' },
{ from: 'Country' }
],
diff --git a/test/lib/config.js b/test/lib/config.js
index 1c99b35..2b3eeb8 100644
--- a/test/lib/config.js
+++ b/test/lib/config.js
@@ -58,7 +58,6 @@
'echarts': ecDistPath,
'zrender': 'node_modules/zrender/dist/zrender',
'ecStat': 'lib/ecStat.min',
- 'ecSimpleTransform': 'lib/ecSimpleTransform',
'ecSimpleOptionPlayer': 'lib/ecSimpleOptionPlayer',
// 'ecStat': 'http://localhost:8001/echarts/echarts-stat/dist/ecStat',
'geoJson': '../geoData/geoJson',
diff --git a/test/lib/ecSimpleTransform.js b/test/lib/ecSimpleTransform.js
deleted file mode 100644
index d780fc4..0000000
--- a/test/lib/ecSimpleTransform.js
+++ /dev/null
@@ -1,362 +0,0 @@
-(function (global, factory) {
- typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
- typeof define === 'function' && define.amd ? define(['exports'], factory) :
- (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.ecSimpleTransform = {}));
-}(this, (function (exports) { 'use strict';
-
- var transform = {
- type: 'ecSimpleTransform:id',
- transform: function (params) {
- var upstream = params.upstream;
- var config = params.config;
- var dimensionIndex = config.dimensionIndex;
- var dimensionName = config.dimensionName;
- var dimsDef = upstream.cloneAllDimensionInfo();
- dimsDef[dimensionIndex] = dimensionName;
- var data = upstream.cloneRawData();
- for (var i = 0, len = data.length; i < len; i++) {
- var line = data[i];
- line[dimensionIndex] = i;
- }
- return {
- dimensions: dimsDef,
- data: data
- };
- }
- };
-
- function assert(condition, message) {
- if (!condition) {
- throw new Error(message);
- }
- }
- function hasOwn(own, prop) {
- return own.hasOwnProperty(prop);
- }
- function quantile(ascArr, p) {
- var H = (ascArr.length - 1) * p + 1;
- var h = Math.floor(H);
- var v = +ascArr[h - 1];
- var e = H - h;
- return e ? v + e * (ascArr[h] - v) : v;
- }
-
- var METHOD_INTERNAL = {
- 'SUM': true,
- 'COUNT': true,
- 'FIRST': true,
- 'AVERAGE': true,
- 'Q1': true,
- 'Q2': true,
- 'Q3': true,
- 'MIN': true,
- 'MAX': true
- };
- var METHOD_NEEDS_COLLECT = {
- AVERAGE: ['COUNT']
- };
- var METHOD_NEEDS_GATHER_VALUES = {
- Q1: true,
- Q2: true,
- Q3: true
- };
- var METHOD_ALIAS = {
- MEDIAN: 'Q2'
- };
- var ResultDimInfoInternal = (function () {
- function ResultDimInfoInternal(index, indexInUpstream, method, name, needGatherValues) {
- this.collectionInfoList = [];
- this.gatheredValuesByGroup = {};
- this.gatheredValuesNoGroup = [];
- this.needGatherValues = false;
- this._collectionInfoMap = {};
- this.method = method;
- this.name = name;
- this.index = index;
- this.indexInUpstream = indexInUpstream;
- this.needGatherValues = needGatherValues;
- }
- ResultDimInfoInternal.prototype.addCollectionInfo = function (item) {
- this._collectionInfoMap[item.method] = this.collectionInfoList.length;
- this.collectionInfoList.push(item);
- };
- ResultDimInfoInternal.prototype.getCollectionInfo = function (method) {
- return this.collectionInfoList[this._collectionInfoMap[method]];
- };
- ResultDimInfoInternal.prototype.gatherValue = function (groupByDimInfo, groupVal, value) {
- value = +value;
- if (groupByDimInfo) {
- if (groupVal != null) {
- var groupValStr = groupVal + '';
- var values = this.gatheredValuesByGroup[groupValStr]
- || (this.gatheredValuesByGroup[groupValStr] = []);
- values.push(value);
- }
- }
- else {
- this.gatheredValuesNoGroup.push(value);
- }
- };
- return ResultDimInfoInternal;
- }());
- var transform$1 = {
- type: 'ecSimpleTransform:aggregate',
- transform: function (params) {
- var upstream = params.upstream;
- var config = params.config;
- var groupByDimInfo = prepareGroupByDimInfo(config, upstream);
- var _a = prepareDimensions(config, upstream, groupByDimInfo), finalResultDimInfoList = _a.finalResultDimInfoList, collectionDimInfoList = _a.collectionDimInfoList;
- var collectionResult;
- if (collectionDimInfoList.length) {
- collectionResult = travel(groupByDimInfo, upstream, collectionDimInfoList, createCollectionResultLine, updateCollectionResultLine);
- }
- for (var i = 0; i < collectionDimInfoList.length; i++) {
- var dimInfo = collectionDimInfoList[i];
- dimInfo.__collectionResult = collectionResult;
- asc(dimInfo.gatheredValuesNoGroup);
- var gatheredValuesByGroup = dimInfo.gatheredValuesByGroup;
- for (var key in gatheredValuesByGroup) {
- if (hasOwn(gatheredValuesByGroup, key)) {
- asc(gatheredValuesByGroup[key]);
- }
- }
- }
- var finalResult = travel(groupByDimInfo, upstream, finalResultDimInfoList, createFinalResultLine, updateFinalResultLine);
- var dimensions = [];
- for (var i = 0; i < finalResultDimInfoList.length; i++) {
- dimensions.push(finalResultDimInfoList[i].name);
- }
- return {
- dimensions: dimensions,
- data: finalResult.outList
- };
- }
- };
- function prepareDimensions(config, upstream, groupByDimInfo) {
- var resultDimensionsConfig = config.resultDimensions;
- var finalResultDimInfoList = [];
- var collectionDimInfoList = [];
- var gIndexInLine = 0;
- for (var i = 0; i < resultDimensionsConfig.length; i++) {
- var resultDimInfoConfig = resultDimensionsConfig[i];
- var dimInfoInUpstream = upstream.getDimensionInfo(resultDimInfoConfig.from);
- assert(dimInfoInUpstream, 'Can not find dimension by `from`: ' + resultDimInfoConfig.from);
- var rawMethod = resultDimInfoConfig.method;
- assert(groupByDimInfo.index !== dimInfoInUpstream.index || rawMethod == null, "Dimension " + dimInfoInUpstream.name + " is the \"groupBy\" dimension, must not have any \"method\".");
- var method = normalizeMethod(rawMethod);
- assert(method, 'method is required');
- var name_1 = resultDimInfoConfig.name != null ? resultDimInfoConfig.name : dimInfoInUpstream.name;
- var finalResultDimInfo = new ResultDimInfoInternal(finalResultDimInfoList.length, dimInfoInUpstream.index, method, name_1, hasOwn(METHOD_NEEDS_GATHER_VALUES, method));
- finalResultDimInfoList.push(finalResultDimInfo);
- var needCollect = false;
- if (hasOwn(METHOD_NEEDS_COLLECT, method)) {
- needCollect = true;
- var collectionTargetMethods = METHOD_NEEDS_COLLECT[method];
- for (var j = 0; j < collectionTargetMethods.length; j++) {
- finalResultDimInfo.addCollectionInfo({
- method: collectionTargetMethods[j],
- indexInLine: gIndexInLine++
- });
- }
- }
- if (hasOwn(METHOD_NEEDS_GATHER_VALUES, method)) {
- needCollect = true;
- }
- if (needCollect) {
- collectionDimInfoList.push(finalResultDimInfo);
- }
- }
- return { collectionDimInfoList: collectionDimInfoList, finalResultDimInfoList: finalResultDimInfoList };
- }
- function prepareGroupByDimInfo(config, upstream) {
- var groupByConfig = config.groupBy;
- var groupByDimInfo;
- if (groupByConfig != null) {
- groupByDimInfo = upstream.getDimensionInfo(groupByConfig);
- assert(groupByDimInfo, 'Can not find dimension by `groupBy`: ' + groupByConfig);
- }
- return groupByDimInfo;
- }
- function travel(groupByDimInfo, upstream, resultDimInfoList, doCreate, doUpdate) {
- var outList = [];
- var mapByGroup;
- if (groupByDimInfo) {
- mapByGroup = {};
- for (var dataIndex = 0, len = upstream.count(); dataIndex < len; dataIndex++) {
- var groupByVal = upstream.retrieveValue(dataIndex, groupByDimInfo.index);
- if (groupByVal == null) {
- continue;
- }
- var groupByValStr = groupByVal + '';
- if (!hasOwn(mapByGroup, groupByValStr)) {
- var newLine = doCreate(upstream, dataIndex, resultDimInfoList, groupByDimInfo, groupByVal);
- outList.push(newLine);
- mapByGroup[groupByValStr] = newLine;
- }
- else {
- var targetLine = mapByGroup[groupByValStr];
- doUpdate(upstream, dataIndex, targetLine, resultDimInfoList, groupByDimInfo, groupByVal);
- }
- }
- }
- else {
- var targetLine = doCreate(upstream, 0, resultDimInfoList);
- outList.push(targetLine);
- for (var dataIndex = 1, len = upstream.count(); dataIndex < len; dataIndex++) {
- doUpdate(upstream, dataIndex, targetLine, resultDimInfoList);
- }
- }
- return { mapByGroup: mapByGroup, outList: outList };
- }
- function normalizeMethod(method) {
- if (method == null) {
- return 'FIRST';
- }
- var methodInternal = method.toUpperCase();
- methodInternal = hasOwn(METHOD_ALIAS, methodInternal)
- ? METHOD_ALIAS[methodInternal]
- : methodInternal;
- assert(hasOwn(METHOD_INTERNAL, methodInternal), "Illegal method " + method + ".");
- return methodInternal;
- }
- var createCollectionResultLine = function (upstream, dataIndex, collectionDimInfoList, groupByDimInfo, groupByVal) {
- var newLine = [];
- for (var i = 0; i < collectionDimInfoList.length; i++) {
- var dimInfo = collectionDimInfoList[i];
- var collectionInfoList = dimInfo.collectionInfoList;
- for (var j = 0; j < collectionInfoList.length; j++) {
- var collectionInfo = collectionInfoList[j];
- newLine[collectionInfo.indexInLine] = +lineCreator[collectionInfo.method](upstream, dataIndex, dimInfo, groupByDimInfo, groupByVal);
- }
- if (dimInfo.needGatherValues) {
- var val = upstream.retrieveValue(dataIndex, dimInfo.indexInUpstream);
- dimInfo.gatherValue(groupByDimInfo, groupByVal, val);
- }
- }
- return newLine;
- };
- var updateCollectionResultLine = function (upstream, dataIndex, targetLine, collectionDimInfoList, groupByDimInfo, groupByVal) {
- for (var i = 0; i < collectionDimInfoList.length; i++) {
- var dimInfo = collectionDimInfoList[i];
- var collectionInfoList = dimInfo.collectionInfoList;
- for (var j = 0; j < collectionInfoList.length; j++) {
- var collectionInfo = collectionInfoList[j];
- var indexInLine = collectionInfo.indexInLine;
- targetLine[indexInLine] = +lineUpdater[collectionInfo.method](targetLine[indexInLine], upstream, dataIndex, dimInfo, groupByDimInfo, groupByVal);
- }
- if (dimInfo.needGatherValues) {
- var val = upstream.retrieveValue(dataIndex, dimInfo.indexInUpstream);
- dimInfo.gatherValue(groupByDimInfo, groupByVal, val);
- }
- }
- };
- var createFinalResultLine = function (upstream, dataIndex, finalResultDimInfoList, groupByDimInfo, groupByVal) {
- var newLine = [];
- for (var i = 0; i < finalResultDimInfoList.length; i++) {
- var dimInfo = finalResultDimInfoList[i];
- var method = dimInfo.method;
- newLine[i] = isGroupByDimension(groupByDimInfo, dimInfo)
- ? groupByVal
- : lineCreator[method](upstream, dataIndex, dimInfo, groupByDimInfo, groupByVal);
- }
- return newLine;
- };
- var updateFinalResultLine = function (upstream, dataIndex, targetLine, finalResultDimInfoList, groupByDimInfo, groupByVal) {
- for (var i = 0; i < finalResultDimInfoList.length; i++) {
- var dimInfo = finalResultDimInfoList[i];
- if (isGroupByDimension(groupByDimInfo, dimInfo)) {
- continue;
- }
- var method = dimInfo.method;
- targetLine[i] = lineUpdater[method](targetLine[i], upstream, dataIndex, dimInfo, groupByDimInfo, groupByVal);
- }
- };
- function isGroupByDimension(groupByDimInfo, targetDimInfo) {
- return groupByDimInfo && targetDimInfo.indexInUpstream === groupByDimInfo.index;
- }
- function asc(list) {
- list.sort(function (a, b) {
- return a - b;
- });
- }
- var lineCreator = {
- 'SUM': function () {
- return 0;
- },
- 'COUNT': function () {
- return 1;
- },
- 'FIRST': function (upstream, dataIndex, dimInfo) {
- return upstream.retrieveValue(dataIndex, dimInfo.indexInUpstream);
- },
- 'MIN': function (upstream, dataIndex, dimInfo) {
- return upstream.retrieveValue(dataIndex, dimInfo.indexInUpstream);
- },
- 'MAX': function (upstream, dataIndex, dimInfo) {
- return upstream.retrieveValue(dataIndex, dimInfo.indexInUpstream);
- },
- 'AVERAGE': function (upstream, dataIndex, dimInfo, groupByDimInfo, groupByVal) {
- var collectLine = groupByDimInfo
- ? dimInfo.__collectionResult.mapByGroup[groupByVal + '']
- : dimInfo.__collectionResult.outList[0];
- return upstream.retrieveValue(dataIndex, dimInfo.indexInUpstream)
- / collectLine[dimInfo.getCollectionInfo('COUNT').indexInLine];
- },
- 'Q1': function (upstream, dataIndex, dimInfo, groupByDimInfo, groupByVal) {
- return lineCreatorForQ(0.25, dimInfo, groupByDimInfo, groupByVal);
- },
- 'Q2': function (upstream, dataIndex, dimInfo, groupByDimInfo, groupByVal) {
- return lineCreatorForQ(0.5, dimInfo, groupByDimInfo, groupByVal);
- },
- 'Q3': function (upstream, dataIndex, dimInfo, groupByDimInfo, groupByVal) {
- return lineCreatorForQ(0.75, dimInfo, groupByDimInfo, groupByVal);
- }
- };
- var lineUpdater = {
- 'SUM': function (val, upstream, dataIndex, dimInfo) {
- return val + upstream.retrieveValue(dataIndex, dimInfo.indexInUpstream);
- },
- 'COUNT': function (val) {
- return val + 1;
- },
- 'FIRST': function (val) {
- return val;
- },
- 'MIN': function (val, upstream, dataIndex, dimInfo) {
- return Math.min(val, upstream.retrieveValue(dataIndex, dimInfo.indexInUpstream));
- },
- 'MAX': function (val, upstream, dataIndex, dimInfo) {
- return Math.max(val, upstream.retrieveValue(dataIndex, dimInfo.indexInUpstream));
- },
- 'AVERAGE': function (val, upstream, dataIndex, dimInfo, groupByDimInfo, groupByVal) {
- var collectLine = groupByDimInfo
- ? dimInfo.__collectionResult.mapByGroup[groupByVal + '']
- : dimInfo.__collectionResult.outList[0];
- return val
- + upstream.retrieveValue(dataIndex, dimInfo.indexInUpstream)
- / collectLine[dimInfo.getCollectionInfo('COUNT').indexInLine];
- },
- 'Q1': function (val, upstream, dataIndex, dimInfo) {
- return val;
- },
- 'Q2': function (val, upstream, dataIndex, dimInfo) {
- return val;
- },
- 'Q3': function (val, upstream, dataIndex, dimInfo) {
- return val;
- }
- };
- function lineCreatorForQ(percent, dimInfo, groupByDimInfo, groupByVal) {
- var gatheredValues = groupByDimInfo
- ? dimInfo.gatheredValuesByGroup[groupByVal + '']
- : dimInfo.gatheredValuesNoGroup;
- return quantile(gatheredValues, percent);
- }
-
- exports.aggregate = transform$1;
- exports.id = transform;
-
- Object.defineProperty(exports, '__esModule', { value: true });
-
-})));
-//# sourceMappingURL=index.js.map
diff --git a/test/universalTransition2.html b/test/universalTransition2.html
index ef3a998..ff8c21e 100644
--- a/test/universalTransition2.html
+++ b/test/universalTransition2.html
@@ -165,12 +165,10 @@ under the License.
<script>
require([
- 'echarts', 'ecStat', 'ecSimpleTransform'
- ], function (echarts, ecStat, ecSimpleTransform) {
+ 'echarts', 'ecStat'
+ ], function (echarts, ecStat) {
- echarts.registerTransform(ecSimpleTransform.aggregate);
echarts.registerTransform(ecStat.transform.clustering);
- echarts.registerTransform(ecSimpleTransform.id);
const RAW_DATA = [[1425139200000,34,0.13,2,"MD","ZD","P0"],[1425225600000,28,0.71,1.5,"MB","ZD","P1"],[1425312000000,23,0.9,2.8,"MA","ZC","P2"],[1425398400000,21,0.58,6,"MB","ZC","P3"],[1425484800000,14,0.1,1.6,"MC","ZA","P4"],[1425571200000,21,0.6,7.7,"MC","ZA","P5"],[1425657600000,23,0.31,2.6,"MC","ZC","P6"],[1425744000000,34,0.74,2.4,"MD","ZE","P7"],[1425830400000,14,0.59,2.3,"MB","ZD","P8"],[1425916800000,18,0.85,5.1,"MB","ZB","P9"],[1426003200000,36,0.96,1.2,"MC","ZC [...]
const RAW_DATA_DIMENSIONS = ['DATE', 'COUNT', 'PRICE', 'WEIGHT', 'M_TAG', 'Z_TAG', 'ID'];
@@ -205,9 +203,9 @@ under the License.
id: 'raw_cluster_centers_dataset',
fromDatasetId: 'raw_clustered_dataset',
transform: {
- type: 'ecSimpleTransform:aggregate',
+ type: 'aggregate',
config: {
- resultDimensions: [
+ output: [
{ from: 'COUNT', method: 'count' },
{ from: 'CLUSTER_CENTER_COUNT', method: 'first' },
{ from: 'CLUSTER_CENTER_PRICE', method: 'first' },
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@echarts.apache.org
For additional commands, e-mail: commits-help@echarts.apache.org