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/09 15:19:28 UTC
[echarts] branch dataset-perf updated: refact(data): separate List
to DataStorage and SeriesData
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
The following commit(s) were added to refs/heads/dataset-perf by this push:
new 85ee886 refact(data): separate List to DataStorage and SeriesData
85ee886 is described below
commit 85ee886e86e599bc5b5f8d374d3b14cd2dbe9c51
Author: pissang <bm...@gmail.com>
AuthorDate: Fri Jul 9 23:18:18 2021 +0800
refact(data): separate List to DataStorage and SeriesData
---
src/animation/universalTransition.ts | 18 +-
src/chart/bar/BarSeries.ts | 8 +-
src/chart/bar/BarView.ts | 24 +-
src/chart/bar/BaseBarSeries.ts | 6 +-
src/chart/bar/PictorialBarView.ts | 16 +-
src/chart/boxplot/BoxplotView.ts | 8 +-
src/chart/candlestick/CandlestickSeries.ts | 4 +-
src/chart/candlestick/CandlestickView.ts | 8 +-
src/chart/candlestick/candlestickLayout.ts | 10 +-
src/chart/custom/CustomSeries.ts | 6 +-
src/chart/custom/CustomView.ts | 10 +-
src/chart/effectScatter/EffectScatterSeries.ts | 8 +-
src/chart/funnel/FunnelSeries.ts | 8 +-
src/chart/funnel/FunnelView.ts | 10 +-
src/chart/funnel/funnelLayout.ts | 6 +-
src/chart/gauge/GaugeSeries.ts | 8 +-
src/chart/gauge/GaugeView.ts | 4 +-
src/chart/graph/GraphSeries.ts | 14 +-
src/chart/graph/GraphView.ts | 4 +-
src/chart/graph/circularLayoutHelper.ts | 4 +-
src/chart/heatmap/HeatmapSeries.ts | 6 +-
src/chart/helper/EffectLine.ts | 14 +-
src/chart/helper/EffectPolyline.ts | 4 +-
src/chart/helper/EffectSymbol.ts | 6 +-
src/chart/helper/LargeLineDraw.ts | 4 +-
src/chart/helper/LargeSymbolDraw.ts | 12 +-
src/chart/helper/Line.ts | 12 +-
src/chart/helper/LineDraw.ts | 10 +-
src/chart/helper/Polyline.ts | 12 +-
src/chart/helper/Symbol.ts | 12 +-
src/chart/helper/SymbolDraw.ts | 12 +-
src/chart/helper/createGraphFromNodeEdge.ts | 14 +-
...stFromArray.ts => createSeriesDataFromArray.ts} | 9 +-
...eateListSimply.ts => createSeriesDataSimply.ts} | 8 +-
src/chart/helper/labelHelper.ts | 6 +-
src/chart/helper/whiskerBoxCommon.ts | 8 +-
src/chart/line/LineSeries.ts | 6 +-
src/chart/line/LineView.ts | 20 +-
src/chart/line/helper.ts | 6 +-
src/chart/line/lineAnimationDiff.ts | 6 +-
src/chart/lines/LinesSeries.ts | 4 +-
src/chart/lines/LinesView.ts | 6 +-
src/chart/lines/linesVisual.ts | 6 +-
src/chart/map/MapSeries.ts | 15 +-
src/chart/map/mapDataStatistic.ts | 4 +-
src/chart/parallel/ParallelSeries.ts | 6 +-
src/chart/parallel/ParallelView.ts | 10 +-
src/chart/pie/PieSeries.ts | 8 +-
src/chart/pie/PieView.ts | 10 +-
src/chart/radar/RadarSeries.ts | 8 +-
src/chart/radar/RadarView.ts | 8 +-
src/chart/sankey/SankeySeries.ts | 6 +-
src/chart/sankey/SankeyView.ts | 4 +-
src/chart/scatter/ScatterSeries.ts | 8 +-
src/chart/scatter/ScatterView.ts | 4 +-
src/chart/sunburst/SunburstSeries.ts | 4 +-
src/chart/themeRiver/ThemeRiverSeries.ts | 6 +-
src/chart/themeRiver/themeRiverLayout.ts | 4 +-
src/chart/tree/TreeSeries.ts | 6 +-
src/chart/tree/TreeView.ts | 10 +-
src/chart/treemap/TreemapSeries.ts | 4 +-
src/component/helper/MapDraw.ts | 4 +-
src/component/marker/MarkAreaView.ts | 12 +-
src/component/marker/MarkLineView.ts | 18 +-
src/component/marker/MarkPointView.ts | 6 +-
src/component/marker/MarkerModel.ts | 10 +-
src/component/marker/markerHelper.ts | 8 +-
src/component/timeline/SliderTimelineModel.ts | 4 +-
src/component/timeline/TimelineModel.ts | 6 +-
src/component/visualMap/VisualMapModel.ts | 4 +-
src/coord/axisHelper.ts | 6 +-
src/coord/cartesian/Grid.ts | 4 +-
src/coord/parallel/Parallel.ts | 4 +-
src/core/Scheduler.ts | 4 +-
src/core/task.ts | 6 +-
src/data/DataDimensionInfo.ts | 5 +-
src/data/DataStorage.ts | 1141 ++++++++++
src/data/Graph.ts | 6 +-
src/data/List.ts | 2278 --------------------
src/data/SeriesData.ts | 1299 +++++++++++
src/data/Tree.ts | 12 +-
src/data/helper/completeDimensions.ts | 4 +-
src/data/helper/createDimensions.ts | 4 +-
src/data/helper/dataProvider.ts | 10 +-
src/data/helper/dataStackHelper.ts | 8 +-
src/data/helper/dimensionHelper.ts | 7 +-
src/data/helper/{linkList.ts => linkSeriesData.ts} | 50 +-
src/export/api.ts | 2 +-
src/export/api/helper.ts | 4 +-
src/label/labelStyle.ts | 4 +-
src/layout/barGrid.ts | 2 +-
src/layout/points.ts | 7 +-
src/model/Series.ts | 35 +-
src/processor/dataStack.ts | 4 +-
src/scale/Log.ts | 4 +-
src/scale/Ordinal.ts | 4 +-
src/scale/Scale.ts | 4 +-
src/util/model.ts | 6 +-
src/util/states.ts | 4 +-
src/util/types.ts | 17 +-
src/view/Chart.ts | 4 +-
src/visual/LegendVisualProvider.ts | 10 +-
src/visual/commonVisualTypes.ts | 2 +-
src/visual/helper.ts | 8 +-
src/visual/symbol.ts | 6 +-
src/visual/visualSolution.ts | 4 +-
.../spec/data/{List.test.ts => SeriesData.test.ts} | 52 +-
107 files changed, 2891 insertions(+), 2724 deletions(-)
diff --git a/src/animation/universalTransition.ts b/src/animation/universalTransition.ts
index 140afca..9dc27e2 100644
--- a/src/animation/universalTransition.ts
+++ b/src/animation/universalTransition.ts
@@ -27,7 +27,7 @@ import Path from 'zrender/src/graphic/Path';
import { EChartsExtensionInstallRegisters } from '../extension';
import { initProps } from '../util/graphic';
import DataDiffer from '../data/DataDiffer';
-import List from '../data/List';
+import SeriesData from '../data/SeriesData';
import { Dictionary, DimensionLoose, OptionDataItemObject, UniversalTransitionOption } from '../util/types';
import {
UpdateLifecycleParams,
@@ -43,22 +43,22 @@ import Displayable from 'zrender/src/graphic/Displayable';
const DATA_COUNT_THRESHOLD = 1e4;
-interface GlobalStore { oldSeries: SeriesModel[], oldData: List[] };
+interface GlobalStore { oldSeries: SeriesModel[], oldData: SeriesData[] };
const getUniversalTransitionGlobalStore = makeInner<GlobalStore, ExtensionAPI>();
interface DiffItem {
- data: List
+ data: SeriesData
dim: DimensionLoose
divide: UniversalTransitionOption['divideShape']
dataIndex: number
}
interface TransitionSeries {
- data: List
+ data: SeriesData
divide: UniversalTransitionOption['divideShape']
dim?: DimensionLoose
}
-function getGroupIdDimension(data: List) {
+function getGroupIdDimension(data: SeriesData) {
const dimensions = data.dimensions;
for (let i = 0; i < dimensions.length; i++) {
const dimInfo = data.getDimensionInfo(dimensions[i]);
@@ -452,7 +452,7 @@ interface SeriesTransitionBatch {
newSeries: TransitionSeries[]
}
-function getDivideShapeFromData(data: List) {
+function getDivideShapeFromData(data: SeriesData) {
if (data.hostModel) {
return ((data.hostModel as SeriesModel)
.getModel('universalTransition') as Model<UniversalTransitionOption>)
@@ -466,12 +466,12 @@ function findTransitionSeriesBatches(
) {
const updateBatches = createHashMap<SeriesTransitionBatch>();
- const oldDataMap = createHashMap<List>();
+ const oldDataMap = createHashMap<SeriesData>();
// Map that only store key in array seriesKey.
// Which is used to query the old data when transition from one to multiple series.
const oldDataMapForSplit = createHashMap<{
key: string,
- data: List
+ data: SeriesData
}>();
each(globalStore.oldSeries, (series, idx) => {
@@ -667,7 +667,7 @@ export function installUniversalTransition(registers: EChartsExtensionInstallReg
// Save all series of current update. Not only the updated one.
const allSeries = ecModel.getSeries();
const savedSeries: SeriesModel[] = globalStore.oldSeries = [];
- const savedData: List[] = globalStore.oldData = [];
+ const savedData: SeriesData[] = globalStore.oldData = [];
for (let i = 0; i < allSeries.length; i++) {
const data = allSeries[i].getData();
// Only save the data that can have transition.
diff --git a/src/chart/bar/BarSeries.ts b/src/chart/bar/BarSeries.ts
index 2008e91..06ede94 100644
--- a/src/chart/bar/BarSeries.ts
+++ b/src/chart/bar/BarSeries.ts
@@ -29,10 +29,10 @@ import {
SeriesEncodeOptionMixin
} from '../../util/types';
import type Cartesian2D from '../../coord/cartesian/Cartesian2D';
-import createListFromArray from '../helper/createListFromArray';
+import createListFromArray from '../helper/createSeriesDataFromArray';
import type Polar from '../../coord/polar/Polar';
import { inheritDefaultOption } from '../../util/component';
-import List from '../../data/List';
+import SeriesData from '../../data/SeriesData';
import { BrushCommonSelectorsForSeries } from '../../component/brush/selector';
export type PolarBarLabelPosition = SeriesLabelOption['position']
@@ -89,7 +89,7 @@ class BarSeriesModel extends BaseBarSeriesModel<BarSeriesOption> {
coordinateSystem: Cartesian2D | Polar;
- getInitialData(): List {
+ getInitialData(): SeriesData {
return createListFromArray(this.getSource(), this, {
useEncodeDefaulter: true,
createInvertedIndices: !!this.get('realtimeSort', true) || null
@@ -119,7 +119,7 @@ class BarSeriesModel extends BaseBarSeriesModel<BarSeriesOption> {
return progressiveThreshold;
}
- brushSelector(dataIndex: number, data: List, selectors: BrushCommonSelectorsForSeries): boolean {
+ brushSelector(dataIndex: number, data: SeriesData, selectors: BrushCommonSelectorsForSeries): boolean {
return selectors.rect(data.getItemLayout(dataIndex));
}
diff --git a/src/chart/bar/BarView.ts b/src/chart/bar/BarView.ts
index 521da0e..e6f71db 100644
--- a/src/chart/bar/BarView.ts
+++ b/src/chart/bar/BarView.ts
@@ -35,7 +35,7 @@ import {throttle} from '../../util/throttle';
import {createClipPath} from '../helper/createClipPathFromCoordSys';
import Sausage from '../../util/shape/sausage';
import ChartView from '../../view/Chart';
-import List, {DefaultDataVisual} from '../../data/List';
+import SeriesData, {DefaultDataVisual} from '../../data/SeriesData';
import GlobalModel from '../../model/Global';
import ExtensionAPI from '../../core/ExtensionAPI';
import {
@@ -88,7 +88,7 @@ type RealtimeSortConfig = {
// Return a number, based on which the ordinal sorted.
type OrderMapping = (dataIndex: number) => number;
-function getClipArea(coord: CoordSysOfBar, data: List) {
+function getClipArea(coord: CoordSysOfBar, data: SeriesData) {
const coordSysClipArea = coord.getArea && coord.getArea();
if (isCoordinateSystemType<Cartesian2D>(coord, 'cartesian2d')) {
const baseAxis = coord.getBaseAxis();
@@ -115,7 +115,7 @@ class BarView extends ChartView {
static type = 'bar' as const;
type = BarView.type;
- private _data: List;
+ private _data: SeriesData;
private _isLargeDraw: boolean;
@@ -467,7 +467,7 @@ class BarView extends ChartView {
}
private _dataSort(
- data: List<BarSeriesModel, DefaultDataVisual>,
+ data: SeriesData<BarSeriesModel, DefaultDataVisual>,
baseAxis: Axis2D,
orderMapping: OrderMapping
): OrdinalSortInfo {
@@ -498,7 +498,7 @@ class BarView extends ChartView {
}
private _isOrderChangedWithinSameData(
- data: List<BarSeriesModel, DefaultDataVisual>,
+ data: SeriesData<BarSeriesModel, DefaultDataVisual>,
orderMapping: OrderMapping,
baseAxis: Axis2D
): boolean {
@@ -543,7 +543,7 @@ class BarView extends ChartView {
}
private _updateSortWithinSameData(
- data: List<BarSeriesModel, DefaultDataVisual>,
+ data: SeriesData<BarSeriesModel, DefaultDataVisual>,
orderMapping: OrderMapping,
baseAxis: Axis2D,
api: ExtensionAPI
@@ -566,7 +566,7 @@ class BarView extends ChartView {
}
private _dispatchInitSort(
- data: List<BarSeriesModel, DefaultDataVisual>,
+ data: SeriesData<BarSeriesModel, DefaultDataVisual>,
realtimeSortCfg: RealtimeSortConfig,
api: ExtensionAPI
) {
@@ -709,7 +709,7 @@ const clip: {
interface ElementCreator {
(
- seriesModel: BarSeriesModel, data: List, newIndex: number,
+ seriesModel: BarSeriesModel, data: SeriesData, newIndex: number,
layout: RectLayout | SectorLayout, isHorizontalOrRadial: boolean,
animationModel: BarSeriesModel,
axisModel: CartesianAxisModel | AngleAxisModel | RadiusAxisModel,
@@ -875,7 +875,7 @@ const isValidLayout: Record<'cartesian2d' | 'polar', (layout: RectLayout | Secto
} as const;
interface GetLayout {
- (data: List, dataIndex: number, itemModel?: Model<BarDataItemOption>): RectLayout | SectorLayout
+ (data: SeriesData, dataIndex: number, itemModel?: Model<BarDataItemOption>): RectLayout | SectorLayout
}
const getLayout: {
[key in 'cartesian2d' | 'polar']: GetLayout
@@ -936,7 +936,7 @@ function createPolarPositionMapping(isRadial: boolean)
function updateStyle(
el: BarPossiblePath,
- data: List, dataIndex: number,
+ data: SeriesData, dataIndex: number,
itemModel: Model<BarDataItemOption>,
layout: RectLayout | SectorLayout,
seriesModel: BarSeriesModel,
@@ -1169,7 +1169,7 @@ function largePathFindDataIndex(largePath: LargePath, x: number, y: number) {
function setLargeStyle(
el: LargePath,
seriesModel: BarSeriesModel,
- data: List
+ data: SeriesData
) {
const globalStyle = data.getVisual('style');
@@ -1183,7 +1183,7 @@ function setLargeStyle(
function setLargeBackgroundStyle(
el: LargePath,
backgroundModel: Model<BarSeriesOption['backgroundStyle']>,
- data: List
+ data: SeriesData
) {
const borderColor = backgroundModel.get('borderColor') || backgroundModel.get('color');
const itemStyle = backgroundModel.getItemStyle();
diff --git a/src/chart/bar/BaseBarSeries.ts b/src/chart/bar/BaseBarSeries.ts
index 36ea14a..46eeeb4 100644
--- a/src/chart/bar/BaseBarSeries.ts
+++ b/src/chart/bar/BaseBarSeries.ts
@@ -18,7 +18,7 @@
*/
import SeriesModel from '../../model/Series';
-import createListFromArray from '../helper/createListFromArray';
+import createListFromArray from '../helper/createSeriesDataFromArray';
import {
SeriesOption,
SeriesOnCartesianOptionMixin,
@@ -28,7 +28,7 @@ import {
} from '../../util/types';
import GlobalModel from '../../model/Global';
import Cartesian2D from '../../coord/cartesian/Cartesian2D';
-import List from '../../data/List';
+import SeriesData from '../../data/SeriesData';
export interface BaseBarSeriesOption<StateOption, ExtraStateOption = DefaultExtraStateOpts>
@@ -78,7 +78,7 @@ class BaseBarSeriesModel<Opts extends BaseBarSeriesOption<unknown> = BaseBarSeri
static type = 'series.__base_bar__';
type = BaseBarSeriesModel.type;
- getInitialData(option: Opts, ecModel: GlobalModel): List {
+ getInitialData(option: Opts, ecModel: GlobalModel): SeriesData {
return createListFromArray(this.getSource(), this, {useEncodeDefaulter: true});
}
diff --git a/src/chart/bar/PictorialBarView.ts b/src/chart/bar/PictorialBarView.ts
index 565b44e..1a81fed 100644
--- a/src/chart/bar/PictorialBarView.ts
+++ b/src/chart/bar/PictorialBarView.ts
@@ -27,7 +27,7 @@ import {parsePercent, isNumeric} from '../../util/number';
import ChartView from '../../view/Chart';
import PictorialBarSeriesModel, {PictorialBarDataItemOption} from './PictorialBarSeries';
import ExtensionAPI from '../../core/ExtensionAPI';
-import List from '../../data/List';
+import SeriesData from '../../data/SeriesData';
import GlobalModel from '../../model/Global';
import Model from '../../model/Model';
import { ColorString, AnimationOptionMixin, ECElement } from '../../util/types';
@@ -131,7 +131,7 @@ class PictorialBarView extends ChartView {
static type = 'pictorialBar';
readonly type = PictorialBarView.type;
- private _data: List;
+ private _data: SeriesData;
render(
seriesModel: PictorialBarSeriesModel,
@@ -239,7 +239,7 @@ class PictorialBarView extends ChartView {
// Set or calculate default value about symbol, and calculate layout info.
function getSymbolMeta(
- data: List,
+ data: SeriesData,
dataIndex: number,
itemModel: ItemModel,
opt: CreateOpts
@@ -338,7 +338,7 @@ function convertToCoordOnAxis(axis: Axis2D, value: number) {
// Support ['100%', '100%']
function prepareSymbolSize(
- data: List,
+ data: SeriesData,
dataIndex: number,
layout: RectLayout,
symbolRepeat: PictorialBarDataItemOption['symbolRepeat'],
@@ -726,7 +726,7 @@ function createOrUpdateClip(
}
}
-function getItemModel(data: List, dataIndex: number) {
+function getItemModel(data: SeriesData, dataIndex: number) {
const itemModel = data.getItemModel(dataIndex) as ItemModel;
itemModel.getAnimationDelayParams = getAnimationDelayParams;
itemModel.isAnimationEnabled = isAnimationEnabled;
@@ -746,7 +746,7 @@ function isAnimationEnabled(this: ItemModel) {
return this.parentModel.isAnimationEnabled() && !!this.getShallow('animation');
}
-function createBar(data: List, opt: CreateOpts, symbolMeta: SymbolMeta, isUpdate?: boolean) {
+function createBar(data: SeriesData, opt: CreateOpts, symbolMeta: SymbolMeta, isUpdate?: boolean) {
// bar is the main element for each data.
const bar = new graphic.Group() as PictorialBarElement;
// bundle is used for location and clip.
@@ -798,7 +798,7 @@ function updateBar(bar: PictorialBarElement, opt: CreateOpts, symbolMeta: Symbol
}
function removeBar(
- data: List, dataIndex: number, animationModel: Model<AnimationOptionMixin>, bar: PictorialBarElement
+ data: SeriesData, dataIndex: number, animationModel: Model<AnimationOptionMixin>, bar: PictorialBarElement
) {
// Not show text when animating
const labelRect = bar.__pictorialBarRect;
@@ -825,7 +825,7 @@ function removeBar(
data.setItemGraphicEl(dataIndex, null);
}
-function getShapeStr(data: List, symbolMeta: SymbolMeta) {
+function getShapeStr(data: SeriesData, symbolMeta: SymbolMeta) {
return [
data.getItemVisual(symbolMeta.dataIndex, 'symbol') || 'none',
!!symbolMeta.symbolRepeat,
diff --git a/src/chart/boxplot/BoxplotView.ts b/src/chart/boxplot/BoxplotView.ts
index 68ac23a..748ff6e 100644
--- a/src/chart/boxplot/BoxplotView.ts
+++ b/src/chart/boxplot/BoxplotView.ts
@@ -25,7 +25,7 @@ import Path, { PathProps } from 'zrender/src/graphic/Path';
import BoxplotSeriesModel, { BoxplotDataItemOption } from './BoxplotSeries';
import GlobalModel from '../../model/Global';
import ExtensionAPI from '../../core/ExtensionAPI';
-import List from '../../data/List';
+import SeriesData from '../../data/SeriesData';
import { BoxplotItemLayout } from './boxplotLayout';
import { saveOldStyle } from '../../animation/basicTrasition';
@@ -33,7 +33,7 @@ class BoxplotView extends ChartView {
static type = 'boxplot';
type = BoxplotView.type;
- private _data: List;
+ private _data: SeriesData;
render(seriesModel: BoxplotSeriesModel, ecModel: GlobalModel, api: ExtensionAPI) {
const data = seriesModel.getData();
@@ -141,7 +141,7 @@ class BoxPath extends Path<BoxPathProps> {
function createNormalBox(
itemLayout: BoxplotItemLayout,
- data: List,
+ data: SeriesData,
dataIndex: number,
constDim: number,
isInit?: boolean
@@ -164,7 +164,7 @@ function createNormalBox(
function updateNormalBoxData(
itemLayout: BoxplotItemLayout,
el: BoxPath,
- data: List,
+ data: SeriesData,
dataIndex: number,
isInit?: boolean
) {
diff --git a/src/chart/candlestick/CandlestickSeries.ts b/src/chart/candlestick/CandlestickSeries.ts
index 68e8b8a..d71cecd 100644
--- a/src/chart/candlestick/CandlestickSeries.ts
+++ b/src/chart/candlestick/CandlestickSeries.ts
@@ -33,7 +33,7 @@ import {
SeriesEncodeOptionMixin,
DefaultEmphasisFocus
} from '../../util/types';
-import List from '../../data/List';
+import SeriesData from '../../data/SeriesData';
import Cartesian2D from '../../coord/cartesian/Cartesian2D';
import { BrushCommonSelectorsForSeries } from '../../component/brush/selector';
import { mixin } from 'zrender/src/core/util';
@@ -151,7 +151,7 @@ class CandlestickSeriesModel extends SeriesModel<CandlestickSeriesOption> {
return 'open';
}
- brushSelector(dataIndex: number, data: List, selectors: BrushCommonSelectorsForSeries): boolean {
+ brushSelector(dataIndex: number, data: SeriesData, selectors: BrushCommonSelectorsForSeries): boolean {
const itemLayout = data.getItemLayout(dataIndex);
return itemLayout && selectors.rect(itemLayout.brushRect);
}
diff --git a/src/chart/candlestick/CandlestickView.ts b/src/chart/candlestick/CandlestickView.ts
index 3a8e971..7e62360 100644
--- a/src/chart/candlestick/CandlestickView.ts
+++ b/src/chart/candlestick/CandlestickView.ts
@@ -27,7 +27,7 @@ import CandlestickSeriesModel, { CandlestickDataItemOption } from './Candlestick
import GlobalModel from '../../model/Global';
import ExtensionAPI from '../../core/ExtensionAPI';
import { StageHandlerProgressParams } from '../../util/types';
-import List from '../../data/List';
+import SeriesData from '../../data/SeriesData';
import {CandlestickItemLayout} from './candlestickLayout';
import { CoordinateSystemClipArea } from '../../coord/CoordinateSystem';
import Model from '../../model/Model';
@@ -42,7 +42,7 @@ class CandlestickView extends ChartView {
private _isLargeDraw: boolean;
- private _data: List;
+ private _data: SeriesData;
render(seriesModel: CandlestickSeriesModel, ecModel: GlobalModel, api: ExtensionAPI) {
// If there is clipPath created in large mode. Remove it.
@@ -273,7 +273,7 @@ function isNormalBoxClipped(clipArea: CoordinateSystemClipArea, itemLayout: Cand
return clipped;
}
-function setBoxCommon(el: NormalBoxPath, data: List, dataIndex: number, isSimpleBox?: boolean) {
+function setBoxCommon(el: NormalBoxPath, data: SeriesData, dataIndex: number, isSimpleBox?: boolean) {
const itemModel = data.getItemModel(dataIndex) as Model<CandlestickDataItemOption>;
el.useStyle(data.getItemVisual(dataIndex, 'style'));
@@ -359,7 +359,7 @@ function createLarge(seriesModel: CandlestickSeriesModel, group: graphic.Group,
}
}
-function setLargeStyle(sign: number, el: LargeBoxPath, seriesModel: CandlestickSeriesModel, data: List) {
+function setLargeStyle(sign: number, el: LargeBoxPath, seriesModel: CandlestickSeriesModel, data: SeriesData) {
// TODO put in visual?
const borderColor = seriesModel.get(['itemStyle', sign > 0 ? 'borderColor' : 'borderColor0'])
|| seriesModel.get(['itemStyle', sign > 0 ? 'color' : 'color0']);
diff --git a/src/chart/candlestick/candlestickLayout.ts b/src/chart/candlestick/candlestickLayout.ts
index 615c684..ae9db88 100644
--- a/src/chart/candlestick/candlestickLayout.ts
+++ b/src/chart/candlestick/candlestickLayout.ts
@@ -25,7 +25,7 @@ import {parsePercent} from '../../util/number';
import {retrieve2} from 'zrender/src/core/util';
import { StageHandler, StageHandlerProgressParams } from '../../util/types';
import CandlestickSeriesModel from './CandlestickSeries';
-import List from '../../data/List';
+import SeriesData from '../../data/SeriesData';
import { RectLike } from 'zrender/src/core/BoundingRect';
const LargeArr = typeof Float32Array !== 'undefined' ? Float32Array : Array;
@@ -78,7 +78,7 @@ const candlestickLayout: StageHandler = {
? largeProgress : normalProgress
};
- function normalProgress(params: StageHandlerProgressParams, data: List) {
+ function normalProgress(params: StageHandlerProgressParams, data: SeriesData) {
let dataIndex;
while ((dataIndex = params.next()) != null) {
@@ -162,7 +162,7 @@ const candlestickLayout: StageHandler = {
}
}
- function largeProgress(params: StageHandlerProgressParams, data: List) {
+ function largeProgress(params: StageHandlerProgressParams, data: SeriesData) {
// Structure: [sign, x, yhigh, ylow, sign, x, yhigh, ylow, ...]
const points = new LargeArr(params.count * 4);
let offset = 0;
@@ -202,7 +202,7 @@ const candlestickLayout: StageHandler = {
}
};
-function getSign(data: List, dataIndex: number, openVal: number, closeVal: number, closeDim: string) {
+function getSign(data: SeriesData, dataIndex: number, openVal: number, closeVal: number, closeDim: string) {
let sign;
if (openVal > closeVal) {
sign = -1;
@@ -221,7 +221,7 @@ function getSign(data: List, dataIndex: number, openVal: number, closeVal: numbe
return sign;
}
-function calculateCandleWidth(seriesModel: CandlestickSeriesModel, data: List) {
+function calculateCandleWidth(seriesModel: CandlestickSeriesModel, data: SeriesData) {
const baseAxis = seriesModel.getBaseAxis();
let extent;
diff --git a/src/chart/custom/CustomSeries.ts b/src/chart/custom/CustomSeries.ts
index b027f41..912ca33 100644
--- a/src/chart/custom/CustomSeries.ts
+++ b/src/chart/custom/CustomSeries.ts
@@ -44,9 +44,9 @@ import {
ZRStyleProps
} from '../../util/types';
import Element, { ElementProps } from 'zrender/src/Element';
-import List, { DefaultDataVisual } from '../../data/List';
+import SeriesData, { DefaultDataVisual } from '../../data/SeriesData';
import GlobalModel from '../../model/Global';
-import createListFromArray from '../helper/createListFromArray';
+import createListFromArray from '../helper/createSeriesDataFromArray';
import { makeInner } from '../../util/model';
import { CoordinateSystem } from '../../coord/CoordinateSystem';
import SeriesModel from '../../model/Series';
@@ -413,7 +413,7 @@ export default class CustomSeriesModel extends SeriesModel<CustomSeriesOption> {
this.currentZ = this.get('z', true);
}
- getInitialData(option: CustomSeriesOption, ecModel: GlobalModel): List {
+ getInitialData(option: CustomSeriesOption, ecModel: GlobalModel): SeriesData {
return createListFromArray(this.getSource(), this);
}
diff --git a/src/chart/custom/CustomView.ts b/src/chart/custom/CustomView.ts
index 44bc7ad..0d14ee7 100644
--- a/src/chart/custom/CustomView.ts
+++ b/src/chart/custom/CustomView.ts
@@ -51,7 +51,7 @@ import prepareGeo from '../../coord/geo/prepareCustom';
import prepareSingleAxis from '../../coord/single/prepareCustom';
import preparePolar from '../../coord/polar/prepareCustom';
import prepareCalendar from '../../coord/calendar/prepareCustom';
-import List, { DefaultDataVisual } from '../../data/List';
+import SeriesData, { DefaultDataVisual } from '../../data/SeriesData';
import GlobalModel from '../../model/Global';
import ExtensionAPI from '../../core/ExtensionAPI';
import Displayable, { DisplayableProps } from 'zrender/src/graphic/Displayable';
@@ -199,7 +199,7 @@ export default class CustomChartView extends ChartView {
static type = 'custom';
readonly type = CustomChartView.type;
- private _data: List;
+ private _data: SeriesData;
render(
customSeries: CustomSeriesModel,
@@ -822,7 +822,7 @@ function updateZForEachState(
function makeRenderItem(
customSeries: CustomSeriesModel,
- data: List<CustomSeriesModel>,
+ data: SeriesData<CustomSeriesModel>,
ecModel: GlobalModel,
api: ExtensionAPI
) {
@@ -1129,7 +1129,7 @@ function makeRenderItem(
}
}
-function wrapEncodeDef(data: List<CustomSeriesModel>): WrapEncodeDefRet {
+function wrapEncodeDef(data: SeriesData<CustomSeriesModel>): WrapEncodeDefRet {
const encodeDef = {} as WrapEncodeDefRet;
each(data.dimensions, function (dimName, dataDimIndex) {
const dimInfo = data.getDimensionInfo(dimName);
@@ -1149,7 +1149,7 @@ function createOrUpdateItem(
elOption: CustomElementOption,
seriesModel: CustomSeriesModel,
group: ViewRootGroup,
- data: List<CustomSeriesModel>
+ data: SeriesData<CustomSeriesModel>
): Element {
// [Rule]
// If `renderItem` returns `null`/`undefined`/`false`, remove the previous el if existing.
diff --git a/src/chart/effectScatter/EffectScatterSeries.ts b/src/chart/effectScatter/EffectScatterSeries.ts
index 5d16446..dbdfaf4 100644
--- a/src/chart/effectScatter/EffectScatterSeries.ts
+++ b/src/chart/effectScatter/EffectScatterSeries.ts
@@ -17,7 +17,7 @@
* under the License.
*/
-import createListFromArray from '../helper/createListFromArray';
+import createListFromArray from '../helper/createSeriesDataFromArray';
import SeriesModel from '../../model/Series';
import {
SeriesOption,
@@ -35,7 +35,7 @@ import {
CallbackDataParams
} from '../../util/types';
import GlobalModel from '../../model/Global';
-import List from '../../data/List';
+import SeriesData from '../../data/SeriesData';
import type { SymbolDrawItemModelOption } from '../helper/SymbolDraw';
import { BrushCommonSelectorsForSeries } from '../../component/brush/selector';
@@ -88,11 +88,11 @@ class EffectScatterSeriesModel extends SeriesModel<EffectScatterSeriesOption> {
hasSymbolVisual = true;
- getInitialData(option: EffectScatterSeriesOption, ecModel: GlobalModel): List {
+ getInitialData(option: EffectScatterSeriesOption, ecModel: GlobalModel): SeriesData {
return createListFromArray(this.getSource(), this, {useEncodeDefaulter: true});
}
- brushSelector(dataIndex: number, data: List, selectors: BrushCommonSelectorsForSeries): boolean {
+ brushSelector(dataIndex: number, data: SeriesData, selectors: BrushCommonSelectorsForSeries): boolean {
return selectors.point(data.getItemLayout(dataIndex));
}
diff --git a/src/chart/funnel/FunnelSeries.ts b/src/chart/funnel/FunnelSeries.ts
index 96a7739..9c1cd83 100644
--- a/src/chart/funnel/FunnelSeries.ts
+++ b/src/chart/funnel/FunnelSeries.ts
@@ -18,7 +18,7 @@
*/
import * as zrUtil from 'zrender/src/core/util';
-import createListSimply from '../helper/createListSimply';
+import createSeriesDataSimply from '../helper/createSeriesDataSimply';
import {defaultEmphasis} from '../../util/model';
import {makeSeriesEncodeForNameBased} from '../../data/helper/sourceHelper';
import LegendVisualProvider from '../../visual/LegendVisualProvider';
@@ -39,7 +39,7 @@ import {
SeriesEncodeOptionMixin
} from '../../util/types';
import GlobalModel from '../../model/Global';
-import List from '../../data/List';
+import SeriesData from '../../data/SeriesData';
type FunnelLabelOption = Omit<SeriesLabelOption, 'position'> & {
position?: LabelOption['position']
@@ -104,8 +104,8 @@ class FunnelSeriesModel extends SeriesModel<FunnelSeriesOption> {
this._defaultLabelLine(option);
}
- getInitialData(this: FunnelSeriesModel, option: FunnelSeriesOption, ecModel: GlobalModel): List {
- return createListSimply(this, {
+ getInitialData(this: FunnelSeriesModel, option: FunnelSeriesOption, ecModel: GlobalModel): SeriesData {
+ return createSeriesDataSimply(this, {
coordDimensions: ['value'],
encodeDefaulter: zrUtil.curry(makeSeriesEncodeForNameBased, this)
});
diff --git a/src/chart/funnel/FunnelView.ts b/src/chart/funnel/FunnelView.ts
index 4a58858..e379e64 100644
--- a/src/chart/funnel/FunnelView.ts
+++ b/src/chart/funnel/FunnelView.ts
@@ -23,7 +23,7 @@ import ChartView from '../../view/Chart';
import FunnelSeriesModel, {FunnelDataItemOption} from './FunnelSeries';
import GlobalModel from '../../model/Global';
import ExtensionAPI from '../../core/ExtensionAPI';
-import List from '../../data/List';
+import SeriesData from '../../data/SeriesData';
import { ColorString } from '../../util/types';
import { setLabelLineStyle, getLabelLineStatesModels } from '../../label/labelGuideHelper';
import { setLabelStyle, getLabelStatesModels } from '../../label/labelStyle';
@@ -36,7 +36,7 @@ const opacityAccessPath = ['itemStyle', 'opacity'] as const;
*/
class FunnelPiece extends graphic.Polygon {
- constructor(data: List, idx: number) {
+ constructor(data: SeriesData, idx: number) {
super();
const polygon = this;
@@ -48,7 +48,7 @@ class FunnelPiece extends graphic.Polygon {
this.updateData(data, idx, true);
}
- updateData(data: List, idx: number, firstCreate?: boolean) {
+ updateData(data: SeriesData, idx: number, firstCreate?: boolean) {
const polygon = this;
@@ -95,7 +95,7 @@ class FunnelPiece extends graphic.Polygon {
enableHoverEmphasis(this, emphasisModel.get('focus'), emphasisModel.get('blurScope'));
}
- _updateLabel(data: List, idx: number) {
+ _updateLabel(data: SeriesData, idx: number) {
const polygon = this;
const labelLine = this.getTextGuideLine();
const labelText = polygon.getTextContent();
@@ -168,7 +168,7 @@ class FunnelView extends ChartView {
static type = 'funnel' as const;
type = FunnelView.type;
- private _data: List;
+ private _data: SeriesData;
ignoreLabelLineUpdate = true;
diff --git a/src/chart/funnel/funnelLayout.ts b/src/chart/funnel/funnelLayout.ts
index 71111c3..cb11676 100644
--- a/src/chart/funnel/funnelLayout.ts
+++ b/src/chart/funnel/funnelLayout.ts
@@ -21,7 +21,7 @@ import * as layout from '../../util/layout';
import {parsePercent, linearMap} from '../../util/number';
import FunnelSeriesModel, { FunnelSeriesOption, FunnelDataItemOption } from './FunnelSeries';
import ExtensionAPI from '../../core/ExtensionAPI';
-import List from '../../data/List';
+import SeriesData from '../../data/SeriesData';
import GlobalModel from '../../model/Global';
function getViewRect(seriesModel: FunnelSeriesModel, api: ExtensionAPI) {
@@ -33,7 +33,7 @@ function getViewRect(seriesModel: FunnelSeriesModel, api: ExtensionAPI) {
);
}
-function getSortedIndices(data: List, sort: FunnelSeriesOption['sort']) {
+function getSortedIndices(data: SeriesData, sort: FunnelSeriesOption['sort']) {
const valueDim = data.mapDimension('value');
const valueArr = data.mapArray(valueDim, function (val: number) {
return val;
@@ -58,7 +58,7 @@ function getSortedIndices(data: List, sort: FunnelSeriesOption['sort']) {
return indices;
}
-function labelLayout(data: List) {
+function labelLayout(data: SeriesData) {
const seriesModel = data.hostModel;
const orient = seriesModel.get('orient');
data.each(function (idx) {
diff --git a/src/chart/gauge/GaugeSeries.ts b/src/chart/gauge/GaugeSeries.ts
index b80652f..e54f659 100644
--- a/src/chart/gauge/GaugeSeries.ts
+++ b/src/chart/gauge/GaugeSeries.ts
@@ -17,7 +17,7 @@
* under the License.
*/
-import createListSimply from '../helper/createListSimply';
+import createSeriesDataSimply from '../helper/createSeriesDataSimply';
import SeriesModel from '../../model/Series';
import {
SeriesOption,
@@ -31,7 +31,7 @@ import {
SeriesEncodeOptionMixin
} from '../../util/types';
import GlobalModel from '../../model/Global';
-import List from '../../data/List';
+import SeriesData from '../../data/SeriesData';
// [percent, color]
type GaugeColorStop = [number, ColorString];
@@ -180,8 +180,8 @@ class GaugeSeriesModel extends SeriesModel<GaugeSeriesOption> {
visualStyleAccessPath = 'itemStyle';
useColorPaletteOnData = true;
- getInitialData(option: GaugeSeriesOption, ecModel: GlobalModel): List {
- return createListSimply(this, ['value']);
+ getInitialData(option: GaugeSeriesOption, ecModel: GlobalModel): SeriesData {
+ return createSeriesDataSimply(this, ['value']);
}
static defaultOption: GaugeSeriesOption = {
diff --git a/src/chart/gauge/GaugeView.ts b/src/chart/gauge/GaugeView.ts
index a4e9005..4f10512 100644
--- a/src/chart/gauge/GaugeView.ts
+++ b/src/chart/gauge/GaugeView.ts
@@ -27,7 +27,7 @@ import GaugeSeriesModel, { GaugeDataItemOption } from './GaugeSeries';
import GlobalModel from '../../model/Global';
import ExtensionAPI from '../../core/ExtensionAPI';
import { ColorString, ECElement } from '../../util/types';
-import List from '../../data/List';
+import SeriesData from '../../data/SeriesData';
import Sausage from '../../util/shape/sausage';
import {createSymbol} from '../../util/symbol';
import ZRImage from 'zrender/src/graphic/Image';
@@ -77,7 +77,7 @@ class GaugeView extends ChartView {
static type = 'gauge' as const;
type = GaugeView.type;
- private _data: List;
+ private _data: SeriesData;
private _progressEls: graphic.Path[];
private _titleEls: graphic.Text[];
diff --git a/src/chart/graph/GraphSeries.ts b/src/chart/graph/GraphSeries.ts
index 54f9f36..42b833d 100644
--- a/src/chart/graph/GraphSeries.ts
+++ b/src/chart/graph/GraphSeries.ts
@@ -17,7 +17,7 @@
* under the License.
*/
-import List from '../../data/List';
+import SeriesData from '../../data/SeriesData';
import * as zrUtil from 'zrender/src/core/util';
import {defaultEmphasis} from '../../util/model';
import Model from '../../model/Model';
@@ -230,7 +230,7 @@ class GraphSeriesModel extends SeriesModel<GraphSeriesOption> {
static readonly dependencies = ['grid', 'polar', 'geo', 'singleAxis', 'calendar'];
- private _categoriesData: List;
+ private _categoriesData: SeriesData;
private _categoriesModels: Model<GraphCategoryItemOption>[];
/**
@@ -272,7 +272,7 @@ class GraphSeriesModel extends SeriesModel<GraphSeriesOption> {
defaultEmphasis(option, 'edgeLabel', ['show']);
}
- getInitialData(option: GraphSeriesOption, ecModel: GlobalModel): List {
+ getInitialData(option: GraphSeriesOption, ecModel: GlobalModel): SeriesData {
const edges = option.edges || option.links || [];
const nodes = option.data || option.nodes || [];
const self = this;
@@ -287,7 +287,7 @@ class GraphSeriesModel extends SeriesModel<GraphSeriesOption> {
return graph.data;
}
- function beforeLink(nodeData: List, edgeData: List) {
+ function beforeLink(nodeData: SeriesData, edgeData: SeriesData) {
// Overwrite nodeData.getItemModel to
nodeData.wrapMethod('getItemModel', function (model) {
const categoriesModels = self._categoriesModels;
@@ -335,10 +335,10 @@ class GraphSeriesModel extends SeriesModel<GraphSeriesOption> {
}
getEdgeData() {
- return this.getGraph().edgeData as List<GraphSeriesModel, LineDataVisual>;
+ return this.getGraph().edgeData as SeriesData<GraphSeriesModel, LineDataVisual>;
}
- getCategoriesData(): List {
+ getCategoriesData(): SeriesData {
return this._categoriesData;
}
@@ -380,7 +380,7 @@ class GraphSeriesModel extends SeriesModel<GraphSeriesOption> {
value: 0
}, category);
});
- const categoriesData = new List(['value'], this);
+ const categoriesData = new SeriesData(['value'], this);
categoriesData.initData(categories);
this._categoriesData = categoriesData;
diff --git a/src/chart/graph/GraphView.ts b/src/chart/graph/GraphView.ts
index 1c8d10f..08cc6ae 100644
--- a/src/chart/graph/GraphView.ts
+++ b/src/chart/graph/GraphView.ts
@@ -33,7 +33,7 @@ import GraphSeriesModel, { GraphNodeItemOption, GraphEdgeItemOption } from './Gr
import { CoordinateSystem } from '../../coord/CoordinateSystem';
import View from '../../coord/View';
import Symbol from '../helper/Symbol';
-import List from '../../data/List';
+import SeriesData from '../../data/SeriesData';
import Line from '../helper/Line';
import { getECData } from '../../util/innerStore';
@@ -109,7 +109,7 @@ class GraphView extends ChartView {
const edgeData = seriesModel.getEdgeData();
// TODO: TYPE
- lineDraw.updateData(edgeData as List);
+ lineDraw.updateData(edgeData as SeriesData);
this._updateNodeAndLinkScale();
diff --git a/src/chart/graph/circularLayoutHelper.ts b/src/chart/graph/circularLayoutHelper.ts
index a81538c..91265be 100644
--- a/src/chart/graph/circularLayoutHelper.ts
+++ b/src/chart/graph/circularLayoutHelper.ts
@@ -22,7 +22,7 @@ import * as vec2 from 'zrender/src/core/vector';
import {getSymbolSize, getNodeGlobalScale} from './graphHelper';
import GraphSeriesModel, { GraphEdgeItemOption } from './GraphSeries';
import Graph from '../../data/Graph';
-import List from '../../data/List';
+import SeriesData from '../../data/SeriesData';
import * as zrUtil from 'zrender/src/core/util';
import {getCurvenessForEdge} from '../helper/multipleGraphEdgeHelper';
@@ -105,7 +105,7 @@ interface LayoutNode {
(
seriesModel: GraphSeriesModel,
graph: Graph,
- nodeData: List,
+ nodeData: SeriesData,
r: number,
cx: number,
cy: number,
diff --git a/src/chart/heatmap/HeatmapSeries.ts b/src/chart/heatmap/HeatmapSeries.ts
index af831ef..9da21ae 100644
--- a/src/chart/heatmap/HeatmapSeries.ts
+++ b/src/chart/heatmap/HeatmapSeries.ts
@@ -18,7 +18,7 @@
*/
import SeriesModel from '../../model/Series';
-import createListFromArray from '../helper/createListFromArray';
+import createListFromArray from '../helper/createSeriesDataFromArray';
import CoordinateSystem from '../../core/CoordinateSystem';
import {
SeriesOption,
@@ -32,7 +32,7 @@ import {
SeriesOnCalendarOptionMixin
} from '../../util/types';
import GlobalModel from '../../model/Global';
-import List from '../../data/List';
+import SeriesData from '../../data/SeriesData';
import type Geo from '../../coord/geo/Geo';
import type Cartesian2D from '../../coord/cartesian/Cartesian2D';
import type Calendar from '../../coord/calendar/Calendar';
@@ -72,7 +72,7 @@ class HeatmapSeriesModel extends SeriesModel<HeatmapSeriesOption> {
// @ts-ignore
coordinateSystem: Cartesian2D | Geo | Calendar;
- getInitialData(option: HeatmapSeriesOption, ecModel: GlobalModel): List {
+ getInitialData(option: HeatmapSeriesOption, ecModel: GlobalModel): SeriesData {
return createListFromArray(this.getSource(), this, {
generateCoord: 'value'
});
diff --git a/src/chart/helper/EffectLine.ts b/src/chart/helper/EffectLine.ts
index d269faa..bc92620 100644
--- a/src/chart/helper/EffectLine.ts
+++ b/src/chart/helper/EffectLine.ts
@@ -27,7 +27,7 @@ import * as zrUtil from 'zrender/src/core/util';
import {createSymbol} from '../../util/symbol';
import * as vec2 from 'zrender/src/core/vector';
import * as curveUtil from 'zrender/src/core/curve';
-import type List from '../../data/List';
+import type SeriesData from '../../data/SeriesData';
import { LineDrawSeriesScope, LineDrawModelOption } from './LineDraw';
import Model from '../../model/Model';
import { ColorString } from '../../util/types';
@@ -49,18 +49,18 @@ class EffectLine extends graphic.Group {
private _symbolScale: number[];
- constructor(lineData: List, idx: number, seriesScope: LineDrawSeriesScope) {
+ constructor(lineData: SeriesData, idx: number, seriesScope: LineDrawSeriesScope) {
super();
this.add(this.createLine(lineData, idx, seriesScope));
this._updateEffectSymbol(lineData, idx);
}
- createLine(lineData: List, idx: number, seriesScope: LineDrawSeriesScope): graphic.Group {
+ createLine(lineData: SeriesData, idx: number, seriesScope: LineDrawSeriesScope): graphic.Group {
return new Line(lineData, idx, seriesScope);
}
- private _updateEffectSymbol(lineData: List, idx: number) {
+ private _updateEffectSymbol(lineData: SeriesData, idx: number) {
const itemModel = lineData.getItemModel<LineDrawModelOption>(idx);
const effectModel = itemModel.getModel('effect');
let size = effectModel.get('symbolSize');
@@ -107,7 +107,7 @@ class EffectLine extends graphic.Group {
}
private _updateEffectAnimation(
- lineData: List,
+ lineData: SeriesData,
effectModel: Model<LineDrawModelOption['effect']>,
idx: number
) {
@@ -189,7 +189,7 @@ class EffectLine extends graphic.Group {
];
}
- updateData(lineData: List, idx: number, seriesScope: LineDrawSeriesScope) {
+ updateData(lineData: SeriesData, idx: number, seriesScope: LineDrawSeriesScope) {
(this.childAt(0) as Line).updateData(lineData, idx, seriesScope);
this._updateEffectSymbol(lineData, idx);
}
@@ -236,7 +236,7 @@ class EffectLine extends graphic.Group {
}
- updateLayout(lineData: List, idx: number) {
+ updateLayout(lineData: SeriesData, idx: number) {
(this.childAt(0) as Line).updateLayout(lineData, idx);
const effectModel = lineData.getItemModel<LineDrawModelOption>(idx).getModel('effect');
diff --git a/src/chart/helper/EffectPolyline.ts b/src/chart/helper/EffectPolyline.ts
index 8049975..a250cb5 100644
--- a/src/chart/helper/EffectPolyline.ts
+++ b/src/chart/helper/EffectPolyline.ts
@@ -21,7 +21,7 @@ import Polyline from './Polyline';
import EffectLine, {ECSymbolOnEffectLine} from './EffectLine';
import * as vec2 from 'zrender/src/core/vector';
import { LineDrawSeriesScope } from './LineDraw';
-import List from '../../data/List';
+import SeriesData from '../../data/SeriesData';
class EffectPolyline extends EffectLine {
@@ -33,7 +33,7 @@ class EffectPolyline extends EffectLine {
private _offsets: number[];
// Override
- createLine(lineData: List, idx: number, seriesScope: LineDrawSeriesScope) {
+ createLine(lineData: SeriesData, idx: number, seriesScope: LineDrawSeriesScope) {
return new Polyline(lineData, idx, seriesScope);
};
diff --git a/src/chart/helper/EffectSymbol.ts b/src/chart/helper/EffectSymbol.ts
index c20a160..db8db9a 100644
--- a/src/chart/helper/EffectSymbol.ts
+++ b/src/chart/helper/EffectSymbol.ts
@@ -21,7 +21,7 @@ import {createSymbol, normalizeSymbolOffset, normalizeSymbolSize} from '../../ut
import {Group, Path} from '../../util/graphic';
import { enterEmphasis, leaveEmphasis, enableHoverEmphasis } from '../../util/states';
import SymbolClz from './Symbol';
-import List from '../../data/List';
+import SeriesData from '../../data/SeriesData';
import type { ZRColor, ECElement } from '../../util/types';
import type Displayable from 'zrender/src/graphic/Displayable';
import { SymbolDrawItemModelOption } from './SymbolDraw';
@@ -59,7 +59,7 @@ class EffectSymbol extends Group {
private _effectCfg: RippleEffectCfg;
- constructor(data: List, idx: number) {
+ constructor(data: SeriesData, idx: number) {
super();
const symbol = new SymbolClz(data, idx);
@@ -162,7 +162,7 @@ class EffectSymbol extends Group {
/**
* Update symbol properties
*/
- updateData(data: List, idx: number) {
+ updateData(data: SeriesData, idx: number) {
const seriesModel = data.hostModel;
(this.childAt(0) as SymbolClz).updateData(data, idx);
diff --git a/src/chart/helper/LargeLineDraw.ts b/src/chart/helper/LargeLineDraw.ts
index 50e4f8d..fca6979 100644
--- a/src/chart/helper/LargeLineDraw.ts
+++ b/src/chart/helper/LargeLineDraw.ts
@@ -24,7 +24,7 @@ import IncrementalDisplayable from 'zrender/src/graphic/IncrementalDisplayable';
import * as lineContain from 'zrender/src/contain/line';
import * as quadraticContain from 'zrender/src/contain/quadratic';
import { PathProps } from 'zrender/src/graphic/Path';
-import List from '../../data/List';
+import SeriesData from '../../data/SeriesData';
import { StageHandlerProgressParams, LineStyleOption, ColorString } from '../../util/types';
import Model from '../../model/Model';
import { getECData } from '../../util/innerStore';
@@ -49,7 +49,7 @@ interface LargeLinesCommonOption {
/**
* Data which can support large lines.
*/
-type LargeLinesData = List<Model<LargeLinesCommonOption> & {
+type LargeLinesData = SeriesData<Model<LargeLinesCommonOption> & {
seriesIndex?: number
}>;
diff --git a/src/chart/helper/LargeSymbolDraw.ts b/src/chart/helper/LargeSymbolDraw.ts
index 1840c54..3f3bcbb 100644
--- a/src/chart/helper/LargeSymbolDraw.ts
+++ b/src/chart/helper/LargeSymbolDraw.ts
@@ -24,7 +24,7 @@
import * as graphic from '../../util/graphic';
import {createSymbol} from '../../util/symbol';
import IncrementalDisplayable from 'zrender/src/graphic/IncrementalDisplayable';
-import List from '../../data/List';
+import SeriesData from '../../data/SeriesData';
import { PathProps } from 'zrender/src/graphic/Path';
import PathProxy from 'zrender/src/core/PathProxy';
import SeriesModel from '../../model/Series';
@@ -182,7 +182,7 @@ class LargeSymbolDraw {
/**
* Update symbols draw by new data
*/
- updateData(data: List, opt?: UpdateOpt) {
+ updateData(data: SeriesData, opt?: UpdateOpt) {
this.group.removeAll();
const symbolEl = new LargeSymbolPath({
rectHover: true,
@@ -198,7 +198,7 @@ class LargeSymbolDraw {
this._incremental = null;
}
- updateLayout(data: List) {
+ updateLayout(data: SeriesData) {
if (this._incremental) {
return;
}
@@ -214,7 +214,7 @@ class LargeSymbolDraw {
});
}
- incrementalPrepareUpdate(data: List) {
+ incrementalPrepareUpdate(data: SeriesData) {
this.group.removeAll();
this._clearIncremental();
@@ -233,7 +233,7 @@ class LargeSymbolDraw {
}
}
- incrementalUpdate(taskParams: StageHandlerProgressParams, data: List, opt: UpdateOpt) {
+ incrementalUpdate(taskParams: StageHandlerProgressParams, data: SeriesData, opt: UpdateOpt) {
let symbolEl;
if (this._incremental) {
symbolEl = new LargeSymbolPath();
@@ -258,7 +258,7 @@ class LargeSymbolDraw {
_setCommon(
symbolEl: LargeSymbolPath,
- data: List,
+ data: SeriesData,
isIncremental: boolean,
opt: UpdateOpt
) {
diff --git a/src/chart/helper/Line.ts b/src/chart/helper/Line.ts
index 140509d..b806d0f 100644
--- a/src/chart/helper/Line.ts
+++ b/src/chart/helper/Line.ts
@@ -25,7 +25,7 @@ import * as graphic from '../../util/graphic';
import { enableHoverEmphasis, enterEmphasis, leaveEmphasis, SPECIAL_STATES } from '../../util/states';
import {getLabelStatesModels, setLabelStyle} from '../../label/labelStyle';
import {round} from '../../util/number';
-import List from '../../data/List';
+import SeriesData from '../../data/SeriesData';
import { ZRTextAlign, ZRTextVerticalAlign, LineLabelOption, ColorString } from '../../util/types';
import SeriesModel from '../../model/Series';
import type { LineDrawSeriesScope, LineDrawModelOption } from './LineDraw';
@@ -41,7 +41,7 @@ type LineECSymbol = ECSymbol & {
__specifiedRotation: number
};
-type LineList = List<SeriesModel, LineDataVisual>;
+type LineList = SeriesData<SeriesModel, LineDataVisual>;
export interface LineLabel extends graphic.Text {
lineLabelOriginalOpacity: number
@@ -133,7 +133,7 @@ class Line extends graphic.Group {
private _fromSymbolType: string;
private _toSymbolType: string;
- constructor(lineData: List, idx: number, seriesScope?: LineDrawSeriesScope) {
+ constructor(lineData: SeriesData, idx: number, seriesScope?: LineDrawSeriesScope) {
super();
this._createLine(lineData as LineList, idx, seriesScope);
}
@@ -164,7 +164,7 @@ class Line extends graphic.Group {
}
// TODO More strict on the List type in parameters?
- updateData(lineData: List, idx: number, seriesScope: LineDrawSeriesScope) {
+ updateData(lineData: SeriesData, idx: number, seriesScope: LineDrawSeriesScope) {
const seriesModel = lineData.hostModel;
const line = this.childOfName('line') as ECLinePath;
@@ -195,7 +195,7 @@ class Line extends graphic.Group {
return this.childAt(0) as graphic.Line;
}
- _updateCommonStl(lineData: List, idx: number, seriesScope?: LineDrawSeriesScope) {
+ _updateCommonStl(lineData: SeriesData, idx: number, seriesScope?: LineDrawSeriesScope) {
const seriesModel = lineData.hostModel as SeriesModel;
const line = this.childOfName('line') as ECLinePath;
@@ -307,7 +307,7 @@ class Line extends graphic.Group {
leaveEmphasis(this);
}
- updateLayout(lineData: List, idx: number) {
+ updateLayout(lineData: SeriesData, idx: number) {
this.setLinePoints(lineData.getItemLayout(idx));
}
diff --git a/src/chart/helper/LineDraw.ts b/src/chart/helper/LineDraw.ts
index 1dde5d3..60317bc 100644
--- a/src/chart/helper/LineDraw.ts
+++ b/src/chart/helper/LineDraw.ts
@@ -19,7 +19,7 @@
import * as graphic from '../../util/graphic';
import LineGroup from './Line';
-import List from '../../data/List';
+import SeriesData from '../../data/SeriesData';
import {
StageHandlerProgressParams,
LineStyleOption,
@@ -36,13 +36,13 @@ import Model from '../../model/Model';
import { getLabelStatesModels } from '../../label/labelStyle';
interface LineLike extends graphic.Group {
- updateData(data: List, idx: number, scope?: LineDrawSeriesScope): void
- updateLayout(data: List, idx: number): void
+ updateData(data: SeriesData, idx: number, scope?: LineDrawSeriesScope): void
+ updateLayout(data: SeriesData, idx: number): void
fadeOut?(cb: () => void): void
}
interface LineLikeCtor {
- new(data: List, idx: number, scope?: LineDrawSeriesScope): LineLike
+ new(data: SeriesData, idx: number, scope?: LineDrawSeriesScope): LineLike
}
interface LineDrawStateOption {
@@ -76,7 +76,7 @@ export interface LineDrawModelOption extends LineDrawStateOption, StatesOptionMi
}
}
-type ListForLineDraw = List<Model<LineDrawModelOption & AnimationOptionMixin>>;
+type ListForLineDraw = SeriesData<Model<LineDrawModelOption & AnimationOptionMixin>>;
export interface LineDrawSeriesScope {
lineStyle?: ZRStyleProps
diff --git a/src/chart/helper/Polyline.ts b/src/chart/helper/Polyline.ts
index 29d0715..a371edc 100644
--- a/src/chart/helper/Polyline.ts
+++ b/src/chart/helper/Polyline.ts
@@ -20,15 +20,15 @@
import * as graphic from '../../util/graphic';
import { enableHoverEmphasis } from '../../util/states';
import type { LineDrawSeriesScope, LineDrawModelOption } from './LineDraw';
-import type List from '../../data/List';
+import type SeriesData from '../../data/SeriesData';
class Polyline extends graphic.Group {
- constructor(lineData: List, idx: number, seriesScope: LineDrawSeriesScope) {
+ constructor(lineData: SeriesData, idx: number, seriesScope: LineDrawSeriesScope) {
super();
this._createPolyline(lineData, idx, seriesScope);
}
- private _createPolyline(lineData: List, idx: number, seriesScope: LineDrawSeriesScope) {
+ private _createPolyline(lineData: SeriesData, idx: number, seriesScope: LineDrawSeriesScope) {
// let seriesModel = lineData.hostModel;
const points = lineData.getItemLayout(idx);
@@ -43,7 +43,7 @@ class Polyline extends graphic.Group {
this._updateCommonStl(lineData, idx, seriesScope);
};
- updateData(lineData: List, idx: number, seriesScope: LineDrawSeriesScope) {
+ updateData(lineData: SeriesData, idx: number, seriesScope: LineDrawSeriesScope) {
const seriesModel = lineData.hostModel;
const line = this.childAt(0) as graphic.Polyline;
@@ -57,7 +57,7 @@ class Polyline extends graphic.Group {
this._updateCommonStl(lineData, idx, seriesScope);
};
- _updateCommonStl(lineData: List, idx: number, seriesScope: LineDrawSeriesScope) {
+ _updateCommonStl(lineData: SeriesData, idx: number, seriesScope: LineDrawSeriesScope) {
const line = this.childAt(0) as graphic.Polyline;
const itemModel = lineData.getItemModel<LineDrawModelOption>(idx);
@@ -77,7 +77,7 @@ class Polyline extends graphic.Group {
enableHoverEmphasis(this);
};
- updateLayout(lineData: List, idx: number) {
+ updateLayout(lineData: SeriesData, idx: number) {
const polyline = this.childAt(0) as graphic.Polyline;
polyline.setShape('points', lineData.getItemLayout(idx));
};
diff --git a/src/chart/helper/Symbol.ts b/src/chart/helper/Symbol.ts
index 222776f..be2a5a4 100644
--- a/src/chart/helper/Symbol.ts
+++ b/src/chart/helper/Symbol.ts
@@ -22,7 +22,7 @@ import * as graphic from '../../util/graphic';
import {getECData} from '../../util/innerStore';
import { enterEmphasis, leaveEmphasis, enableHoverEmphasis } from '../../util/states';
import {getDefaultLabel} from './labelHelper';
-import List from '../../data/List';
+import SeriesData from '../../data/SeriesData';
import { ColorString, BlurScope, AnimationOption, ZRColor } from '../../util/types';
import SeriesModel from '../../model/Series';
import { PathProps } from 'zrender/src/graphic/Path';
@@ -55,14 +55,14 @@ class Symbol extends graphic.Group {
private _z2: number;
- constructor(data: List, idx: number, seriesScope?: SymbolDrawSeriesScope, opts?: SymbolOpts) {
+ constructor(data: SeriesData, idx: number, seriesScope?: SymbolDrawSeriesScope, opts?: SymbolOpts) {
super();
this.updateData(data, idx, seriesScope, opts);
}
_createSymbol(
symbolType: string,
- data: List,
+ data: SeriesData,
idx: number,
symbolSize: number[],
keepAspect: boolean
@@ -151,7 +151,7 @@ class Symbol extends graphic.Group {
/**
* Update symbol properties
*/
- updateData(data: List, idx: number, seriesScope?: SymbolDrawSeriesScope, opts?: SymbolOpts) {
+ updateData(data: SeriesData, idx: number, seriesScope?: SymbolDrawSeriesScope, opts?: SymbolOpts) {
this.silent = false;
const symbolType = data.getItemVisual(idx, 'symbol') || 'circle';
@@ -206,7 +206,7 @@ class Symbol extends graphic.Group {
}
_updateCommon(
- data: List,
+ data: SeriesData,
idx: number,
symbolSize: number[],
seriesScope?: SymbolDrawSeriesScope,
@@ -395,7 +395,7 @@ class Symbol extends graphic.Group {
);
}
- static getSymbolSize(data: List, idx: number) {
+ static getSymbolSize(data: SeriesData, idx: number) {
return normalizeSymbolSize(data.getItemVisual(idx, 'symbolSize'));
}
}
diff --git a/src/chart/helper/SymbolDraw.ts b/src/chart/helper/SymbolDraw.ts
index 9f53db8..28d10e7 100644
--- a/src/chart/helper/SymbolDraw.ts
+++ b/src/chart/helper/SymbolDraw.ts
@@ -20,7 +20,7 @@
import * as graphic from '../../util/graphic';
import SymbolClz from './Symbol';
import { isObject } from 'zrender/src/core/util';
-import List from '../../data/List';
+import SeriesData from '../../data/SeriesData';
import type Displayable from 'zrender/src/graphic/Displayable';
import {
StageHandlerProgressParams,
@@ -49,15 +49,15 @@ interface UpdateOpt {
}
interface SymbolLike extends graphic.Group {
- updateData(data: List, idx: number, scope?: SymbolDrawSeriesScope, opt?: UpdateOpt): void
+ updateData(data: SeriesData, idx: number, scope?: SymbolDrawSeriesScope, opt?: UpdateOpt): void
fadeOut?(cb: () => void): void
}
interface SymbolLikeCtor {
- new(data: List, idx: number, scope?: SymbolDrawSeriesScope, opt?: UpdateOpt): SymbolLike
+ new(data: SeriesData, idx: number, scope?: SymbolDrawSeriesScope, opt?: UpdateOpt): SymbolLike
}
-function symbolNeedsDraw(data: List, point: number[], idx: number, opt: UpdateOpt) {
+function symbolNeedsDraw(data: SeriesData, point: number[], idx: number, opt: UpdateOpt) {
return point && !isNaN(point[0]) && !isNaN(point[1])
&& !(opt.isIgnore && opt.isIgnore(idx))
// We do not set clipShape on group, because it will cut part of
@@ -125,7 +125,7 @@ export interface SymbolDrawSeriesScope {
fadeIn?: boolean
}
-function makeSeriesScope(data: List): SymbolDrawSeriesScope {
+function makeSeriesScope(data: SeriesData): SymbolDrawSeriesScope {
const seriesModel = data.hostModel as Model<ScatterSeriesOption>;
const emphasisModel = seriesModel.getModel('emphasis');
return {
@@ -144,7 +144,7 @@ function makeSeriesScope(data: List): SymbolDrawSeriesScope {
};
}
-export type ListForSymbolDraw = List<Model<SymbolDrawItemModelOption & AnimationOptionMixin>>;
+export type ListForSymbolDraw = SeriesData<Model<SymbolDrawItemModelOption & AnimationOptionMixin>>;
class SymbolDraw {
group = new graphic.Group();
diff --git a/src/chart/helper/createGraphFromNodeEdge.ts b/src/chart/helper/createGraphFromNodeEdge.ts
index e2a0fca..80a43a3 100644
--- a/src/chart/helper/createGraphFromNodeEdge.ts
+++ b/src/chart/helper/createGraphFromNodeEdge.ts
@@ -19,12 +19,12 @@
import * as zrUtil from 'zrender/src/core/util';
-import List from '../../data/List';
+import SeriesData from '../../data/SeriesData';
import Graph from '../../data/Graph';
-import linkList from '../../data/helper/linkList';
+import linkSeriesData from '../../data/helper/linkSeriesData';
import createDimensions from '../../data/helper/createDimensions';
import CoordinateSystem from '../../core/CoordinateSystem';
-import createListFromArray from './createListFromArray';
+import createListFromArray from './createSeriesDataFromArray';
import {
OptionSourceDataOriginal, GraphEdgeItemObject, OptionDataValue,
OptionDataItemObject
@@ -37,7 +37,7 @@ export default function createGraphFromNodeEdge(
edges: OptionSourceDataOriginal<OptionDataValue, GraphEdgeItemObject<OptionDataValue>>,
seriesModel: SeriesModel,
directed: boolean,
- beforeLink: (nodeData: List, edgeData: List) => void
+ beforeLink: (nodeData: SeriesData, edgeData: SeriesData) => void
): Graph {
// ??? TODO
// support dataset?
@@ -86,16 +86,16 @@ export default function createGraphFromNodeEdge(
const dimensionNames = createDimensions(nodes, {
coordDimensions: coordDimensions
});
- nodeData = new List(dimensionNames, seriesModel);
+ nodeData = new SeriesData(dimensionNames, seriesModel);
nodeData.initData(nodes);
}
- const edgeData = new List(['value'], seriesModel);
+ const edgeData = new SeriesData(['value'], seriesModel);
edgeData.initData(validEdges, linkNameList);
beforeLink && beforeLink(nodeData, edgeData);
- linkList({
+ linkSeriesData({
mainData: nodeData,
struct: graph,
structAttr: 'graph',
diff --git a/src/chart/helper/createListFromArray.ts b/src/chart/helper/createSeriesDataFromArray.ts
similarity index 95%
rename from src/chart/helper/createListFromArray.ts
rename to src/chart/helper/createSeriesDataFromArray.ts
index a9adc2f..4746787 100644
--- a/src/chart/helper/createListFromArray.ts
+++ b/src/chart/helper/createSeriesDataFromArray.ts
@@ -18,7 +18,7 @@
*/
import * as zrUtil from 'zrender/src/core/util';
-import List from '../../data/List';
+import SeriesData from '../../data/SeriesData';
import createDimensions from '../../data/helper/createDimensions';
import {getDimensionTypeByAxis} from '../../data/helper/dimensionHelper';
import {getDataItemValue} from '../../util/model';
@@ -31,13 +31,14 @@ import {
SOURCE_FORMAT_ORIGINAL, DimensionDefinitionLoose, DimensionDefinition, OptionSourceData, EncodeDefaulter
} from '../../util/types';
import SeriesModel from '../../model/Series';
+import DataStorage from '../../data/DataStorage';
function createListFromArray(source: Source | OptionSourceData, seriesModel: SeriesModel, opt?: {
generateCoord?: string
useEncodeDefaulter?: boolean | EncodeDefaulter
// By default: auto. If `true`, create inverted indices for all ordinal dimension on coordSys.
createInvertedIndices?: boolean
-}): List {
+}): SeriesData {
opt = opt || {};
if (!isSourceInstance(source)) {
@@ -110,12 +111,12 @@ function createListFromArray(source: Source | OptionSourceData, seriesModel: Ser
const stackCalculationInfo = enableDataStack(seriesModel, dimInfoList);
- const list = new List(dimInfoList, seriesModel);
+ const list = new SeriesData(dimInfoList, seriesModel);
list.setCalculationInfo(stackCalculationInfo);
const dimValueGetter = (firstCategoryDimIndex != null && isNeedCompleteOrdinalData(source))
- ? function (this: List, itemOpt: any, dimName: string, dataIndex: number, dimIndex: number) {
+ ? function (this: DataStorage, itemOpt: any, dimName: string, dataIndex: number, dimIndex: number) {
// Use dataIndex as ordinal value in categoryAxis
return dimIndex === firstCategoryDimIndex
? dataIndex
diff --git a/src/chart/helper/createListSimply.ts b/src/chart/helper/createSeriesDataSimply.ts
similarity index 89%
rename from src/chart/helper/createListSimply.ts
rename to src/chart/helper/createSeriesDataSimply.ts
index b38d3cd..3a8c403 100644
--- a/src/chart/helper/createListSimply.ts
+++ b/src/chart/helper/createSeriesDataSimply.ts
@@ -18,7 +18,7 @@
*/
import createDimensions, {CreateDimensionsParams} from '../../data/helper/createDimensions';
-import List from '../../data/List';
+import SeriesData from '../../data/SeriesData';
import {extend, isArray} from 'zrender/src/core/util';
import SeriesModel from '../../model/Series';
@@ -32,18 +32,18 @@ import SeriesModel from '../../model/Series';
* dimensionsCount: 5
* });
*/
-export default function createListSimply(
+export default function createSeriesDataSimply(
seriesModel: SeriesModel,
opt: CreateDimensionsParams | CreateDimensionsParams['coordDimensions'],
nameList?: string[]
-): List {
+): SeriesData {
opt = isArray(opt) && {coordDimensions: opt} || extend({}, opt);
const source = seriesModel.getSource();
const dimensionsInfo = createDimensions(source, opt as CreateDimensionsParams);
- const list = new List(dimensionsInfo, seriesModel);
+ const list = new SeriesData(dimensionsInfo, seriesModel);
list.initData(source, nameList);
return list;
diff --git a/src/chart/helper/labelHelper.ts b/src/chart/helper/labelHelper.ts
index 58a0b0d..8dc7905 100644
--- a/src/chart/helper/labelHelper.ts
+++ b/src/chart/helper/labelHelper.ts
@@ -19,7 +19,7 @@
import {retrieveRawValue} from '../../data/helper/dataProvider';
-import List from '../../data/List';
+import SeriesData from '../../data/SeriesData';
import { InterpolatableValue } from '../../util/types';
import { isArray } from 'zrender/src/core/util';
@@ -27,7 +27,7 @@ import { isArray } from 'zrender/src/core/util';
* @return label string. Not null/undefined
*/
export function getDefaultLabel(
- data: List,
+ data: SeriesData,
dataIndex: number
): string {
const labelDims = data.mapDimensionsAll('defaultedLabel');
@@ -48,7 +48,7 @@ export function getDefaultLabel(
}
export function getDefaultInterpolatedLabel(
- data: List,
+ data: SeriesData,
interpolatedValue: InterpolatableValue
): string {
const labelDims = data.mapDimensionsAll('defaultedLabel');
diff --git a/src/chart/helper/whiskerBoxCommon.ts b/src/chart/helper/whiskerBoxCommon.ts
index 679360d..0aa61a1 100644
--- a/src/chart/helper/whiskerBoxCommon.ts
+++ b/src/chart/helper/whiskerBoxCommon.ts
@@ -17,7 +17,7 @@
* under the License.
*/
-import createListSimply from '../helper/createListSimply';
+import createSeriesDataSimply from './createSeriesDataSimply';
import * as zrUtil from 'zrender/src/core/util';
import {getDimensionTypeByAxis} from '../../data/helper/dimensionHelper';
import {makeSeriesEncodeForAxisCoordSys} from '../../data/helper/sourceHelper';
@@ -25,7 +25,7 @@ import type { SeriesOption, SeriesOnCartesianOptionMixin, LayoutOrient } from '.
import type GlobalModel from '../../model/Global';
import type SeriesModel from '../../model/Series';
import type CartesianAxisModel from '../../coord/cartesian/AxisModel';
-import type List from '../../data/List';
+import type SeriesData from '../../data/SeriesData';
import type Axis2D from '../../coord/cartesian/Axis2D';
import { CoordDimensionDefinition } from '../../data/helper/createDimensions';
@@ -55,7 +55,7 @@ class WhiskerBoxCommonMixin<Opts extends CommonOption> {
/**
* @override
*/
- getInitialData(option: Opts, ecModel: GlobalModel): List {
+ getInitialData(option: Opts, ecModel: GlobalModel): SeriesData {
// When both types of xAxis and yAxis are 'value', layout is
// needed to be specified by user. Otherwise, layout can be
// judged by which axis is category.
@@ -132,7 +132,7 @@ class WhiskerBoxCommonMixin<Opts extends CommonOption> {
dimsDef: defaultValueDimensions.slice()
}];
- return createListSimply(
+ return createSeriesDataSimply(
this,
{
coordDimensions: coordDimensions,
diff --git a/src/chart/line/LineSeries.ts b/src/chart/line/LineSeries.ts
index 0b685eb..6360c89 100644
--- a/src/chart/line/LineSeries.ts
+++ b/src/chart/line/LineSeries.ts
@@ -17,7 +17,7 @@
* under the License.
*/
-import createListFromArray from '../helper/createListFromArray';
+import createListFromArray from '../helper/createSeriesDataFromArray';
import SeriesModel from '../../model/Series';
import {
SeriesOnCartesianOptionMixin,
@@ -36,7 +36,7 @@ import {
CallbackDataParams,
DefaultEmphasisFocus
} from '../../util/types';
-import List from '../../data/List';
+import SeriesData from '../../data/SeriesData';
import type Cartesian2D from '../../coord/cartesian/Cartesian2D';
import type Polar from '../../coord/polar/Polar';
import {createSymbol, ECSymbol} from '../../util/symbol';
@@ -130,7 +130,7 @@ class LineSeriesModel extends SeriesModel<LineSeriesOption> {
hasSymbolVisual = true;
- getInitialData(option: LineSeriesOption): List {
+ getInitialData(option: LineSeriesOption): SeriesData {
if (__DEV__) {
const coordSys = option.coordinateSystem;
if (coordSys !== 'polar' && coordSys !== 'cartesian2d') {
diff --git a/src/chart/line/LineView.ts b/src/chart/line/LineView.ts
index b40f589..c25bcc0 100644
--- a/src/chart/line/LineView.ts
+++ b/src/chart/line/LineView.ts
@@ -29,13 +29,13 @@ import {ECPolyline, ECPolygon} from './poly';
import ChartView from '../../view/Chart';
import {prepareDataCoordInfo, getStackedOnPoint} from './helper';
import {createGridClipPath, createPolarClipPath} from '../helper/createClipPathFromCoordSys';
-import LineSeriesModel, { LineEndLabelOption, LineSeriesOption } from './LineSeries';
+import LineSeriesModel, { LineSeriesOption } from './LineSeries';
import type GlobalModel from '../../model/Global';
import type ExtensionAPI from '../../core/ExtensionAPI';
// TODO
import Cartesian2D from '../../coord/cartesian/Cartesian2D';
import Polar from '../../coord/polar/Polar';
-import type List from '../../data/List';
+import type SeriesData from '../../data/SeriesData';
import type {
Payload,
Dictionary,
@@ -121,7 +121,7 @@ function getSmooth(smooth: number | boolean) {
function getStackedOnPoints(
coordSys: Cartesian2D | Polar,
- data: List,
+ data: SeriesData,
dataCoordInfo: ReturnType<typeof prepareDataCoordInfo>
) {
if (!dataCoordInfo.valueDim) {
@@ -187,7 +187,7 @@ function turnPointsIntoStep(
}
function getVisualGradient(
- data: List,
+ data: SeriesData,
coordSys: Cartesian2D | Polar
) {
const visualMetaList = data.getVisual('visualMeta');
@@ -290,7 +290,7 @@ function getVisualGradient(
function getIsIgnoreFunc(
seriesModel: LineSeriesModel,
- data: List,
+ data: SeriesData,
coordSys: Cartesian2D
) {
const showAllSymbol = seriesModel.get('showAllSymbol');
@@ -332,7 +332,7 @@ function getIsIgnoreFunc(
function canShowAllSymbolForCategory(
categoryAxis: Axis2D,
- data: List
+ data: SeriesData
) {
// In mose cases, line is monotonous on category axis, and the label size
// is close with each other. So we check the symbol size and some of the
@@ -544,7 +544,7 @@ class LineView extends ChartView {
_clipShapeForSymbol: CoordinateSystemClipArea;
- _data: List;
+ _data: SeriesData;
init() {
const lineGroup = new graphic.Group();
@@ -962,7 +962,7 @@ class LineView extends ChartView {
}
_initSymbolLabelAnimation(
- data: List,
+ data: SeriesData,
coordSys: Polar | Cartesian2D,
clipShape: PolarArea | Cartesian2DArea
) {
@@ -1113,7 +1113,7 @@ class LineView extends ChartView {
_endLabelOnDuring(
percent: number,
clipRect: graphic.Rect,
- data: List,
+ data: SeriesData,
animationRecord: EndLabelAnimationRecord,
valueAnimation: boolean,
endLabelModel: Model<LabelOption>,
@@ -1200,7 +1200,7 @@ class LineView extends ChartView {
*/
// FIXME Two value axis
_doUpdateAnimation(
- data: List,
+ data: SeriesData,
stackedOnPoints: ArrayLike<number>,
coordSys: Cartesian2D | Polar,
api: ExtensionAPI,
diff --git a/src/chart/line/helper.ts b/src/chart/line/helper.ts
index 200824f..e58d2e7 100644
--- a/src/chart/line/helper.ts
+++ b/src/chart/line/helper.ts
@@ -21,7 +21,7 @@ import {isDimensionStacked} from '../../data/helper/dataStackHelper';
import {map} from 'zrender/src/core/util';
import type Polar from '../../coord/polar/Polar';
import type Cartesian2D from '../../coord/cartesian/Cartesian2D';
-import List from '../../data/List';
+import SeriesData from '../../data/SeriesData';
import Axis from '../../coord/Axis';
import type { LineSeriesOption } from './LineSeries';
@@ -39,7 +39,7 @@ interface CoordInfo {
export function prepareDataCoordInfo(
coordSys: Cartesian2D | Polar,
- data: List,
+ data: SeriesData,
valueOrigin?: LineSeriesOption['areaStyle']['origin']
): CoordInfo {
const baseAxis = coordSys.getBaseAxis();
@@ -109,7 +109,7 @@ function getValueStart(valueAxis: Axis, valueOrigin: LineSeriesOption['areaStyle
export function getStackedOnPoint(
dataCoordInfo: CoordInfo,
coordSys: Cartesian2D | Polar,
- data: List,
+ data: SeriesData,
idx: number
) {
let value = NaN;
diff --git a/src/chart/line/lineAnimationDiff.ts b/src/chart/line/lineAnimationDiff.ts
index b491665..60a93a1 100644
--- a/src/chart/line/lineAnimationDiff.ts
+++ b/src/chart/line/lineAnimationDiff.ts
@@ -18,7 +18,7 @@
*/
import {prepareDataCoordInfo, getStackedOnPoint} from './helper';
-import List from '../../data/List';
+import SeriesData from '../../data/SeriesData';
import type Cartesian2D from '../../coord/cartesian/Cartesian2D';
import type Polar from '../../coord/polar/Polar';
import { LineSeriesOption } from './LineSeries';
@@ -30,7 +30,7 @@ interface DiffItem {
idx1?: number
}
-function diffData(oldData: List, newData: List) {
+function diffData(oldData: SeriesData, newData: SeriesData) {
const diffResult: DiffItem[] = [];
newData.diff(oldData)
@@ -49,7 +49,7 @@ function diffData(oldData: List, newData: List) {
}
export default function lineAnimationDiff(
- oldData: List, newData: List,
+ oldData: SeriesData, newData: SeriesData,
oldStackedOnPoints: ArrayLike<number>, newStackedOnPoints: ArrayLike<number>,
oldCoordSys: Cartesian2D | Polar, newCoordSys: Cartesian2D | Polar,
oldValueOrigin: LineSeriesOption['areaStyle']['origin'],
diff --git a/src/chart/lines/LinesSeries.ts b/src/chart/lines/LinesSeries.ts
index 98cb2dd..f6ec965 100644
--- a/src/chart/lines/LinesSeries.ts
+++ b/src/chart/lines/LinesSeries.ts
@@ -20,7 +20,7 @@
/* global Uint32Array, Float64Array, Float32Array */
import SeriesModel from '../../model/Series';
-import List from '../../data/List';
+import SeriesData from '../../data/SeriesData';
import { concatArray, mergeAll, map } from 'zrender/src/core/util';
import CoordinateSystem from '../../core/CoordinateSystem';
import {
@@ -297,7 +297,7 @@ class LinesSeriesModel extends SeriesModel<LinesSeriesOption> {
}
}
- const lineData = new List(['value'], this);
+ const lineData = new SeriesData(['value'], this);
lineData.hasItemOption = false;
lineData.initData(option.data, [], function (dataItem, dimName, dataIndex, dimIndex) {
diff --git a/src/chart/lines/LinesView.ts b/src/chart/lines/LinesView.ts
index ad1089e..6c4479d 100644
--- a/src/chart/lines/LinesView.ts
+++ b/src/chart/lines/LinesView.ts
@@ -31,7 +31,7 @@ import GlobalModel from '../../model/Global';
import ExtensionAPI from '../../core/ExtensionAPI';
import CanvasPainter from 'zrender/src/canvas/Painter';
import { StageHandlerProgressParams, StageHandlerProgressExecutor } from '../../util/types';
-import List from '../../data/List';
+import SeriesData from '../../data/SeriesData';
import type Polar from '../../coord/polar/Polar';
import type Cartesian2D from '../../coord/cartesian/Cartesian2D';
@@ -90,7 +90,7 @@ class LinesView extends ChartView {
}
}
- lineDraw.updateData(data as List);
+ lineDraw.updateData(data as SeriesData);
const clipPath = seriesModel.get('clip', true) && createClipPath(
(seriesModel.coordinateSystem as Polar | Cartesian2D), false, seriesModel
@@ -156,7 +156,7 @@ class LinesView extends ChartView {
}
}
- _updateLineDraw(data: List, seriesModel: LinesSeriesModel) {
+ _updateLineDraw(data: SeriesData, seriesModel: LinesSeriesModel) {
let lineDraw = this._lineDraw;
const hasEffect = this._showEffect(seriesModel);
const isPolyline = !!seriesModel.get('polyline');
diff --git a/src/chart/lines/linesVisual.ts b/src/chart/lines/linesVisual.ts
index 1e4c931..0e18b69 100644
--- a/src/chart/lines/linesVisual.ts
+++ b/src/chart/lines/linesVisual.ts
@@ -18,7 +18,7 @@
*/
import { StageHandler } from '../../util/types';
-import List from '../../data/List';
+import SeriesData from '../../data/SeriesData';
import LinesSeriesModel, { LinesDataItemOption } from './LinesSeries';
import Model from '../../model/Model';
import { LineDataVisual } from '../../visual/commonVisualTypes';
@@ -37,7 +37,7 @@ const linesVisual: StageHandler = {
reset(seriesModel: LinesSeriesModel) {
const symbolType = normalize(seriesModel.get('symbol'));
const symbolSize = normalize(seriesModel.get('symbolSize'));
- const data = seriesModel.getData() as List<LinesSeriesModel, LineDataVisual>;
+ const data = seriesModel.getData() as SeriesData<LinesSeriesModel, LineDataVisual>;
data.setVisual('fromSymbol', symbolType && symbolType[0]);
data.setVisual('toSymbol', symbolType && symbolType[1]);
@@ -45,7 +45,7 @@ const linesVisual: StageHandler = {
data.setVisual('toSymbolSize', symbolSize && symbolSize[1]);
function dataEach(
- data: List<LinesSeriesModel, LineDataVisual>,
+ data: SeriesData<LinesSeriesModel, LineDataVisual>,
idx: number
): void {
const itemModel = data.getItemModel(idx) as Model<LinesDataItemOption>;
diff --git a/src/chart/map/MapSeries.ts b/src/chart/map/MapSeries.ts
index f0049de..582b55c 100644
--- a/src/chart/map/MapSeries.ts
+++ b/src/chart/map/MapSeries.ts
@@ -19,7 +19,7 @@
import * as zrUtil from 'zrender/src/core/util';
-import createListSimply from '../helper/createListSimply';
+import createSeriesDataSimply from '../helper/createSeriesDataSimply';
import SeriesModel from '../../model/Series';
import geoSourceManager from '../../coord/geo/geoSourceManager';
import {makeSeriesEncodeForNameBased} from '../../data/helper/sourceHelper';
@@ -36,7 +36,7 @@ import {
} from '../../util/types';
import { Dictionary } from 'zrender/src/core/types';
import GeoModel, { GeoCommonOptionMixin, GeoItemStyleOption } from '../../coord/geo/GeoModel';
-import List from '../../data/List';
+import SeriesData from '../../data/SeriesData';
import Model from '../../model/Model';
import Geo from '../../coord/geo/Geo';
import { createTooltipMarkup } from '../../component/tooltip/tooltipMarkup';
@@ -101,7 +101,7 @@ class MapSeries extends SeriesModel<MapSeriesOption> {
// -----------------
// Injected outside
- originalData: List;
+ originalData: SeriesData;
mainSeries: MapSeries;
// Only first map series of same mapType will drawMap.
needsDrawMap: boolean = false;
@@ -109,8 +109,8 @@ class MapSeries extends SeriesModel<MapSeriesOption> {
seriesGroup: MapSeries[] = [];
- getInitialData(this: MapSeries, option: MapSeriesOption): List {
- const data = createListSimply(this, {
+ getInitialData(this: MapSeries, option: MapSeriesOption): SeriesData {
+ const data = createSeriesDataSimply(this, {
coordDimensions: ['value'],
encodeDefaulter: zrUtil.curry(makeSeriesEncodeForNameBased, this)
});
@@ -133,7 +133,10 @@ class MapSeries extends SeriesModel<MapSeriesOption> {
// Complete data with missing regions. The consequent processes (like visual
// map and render) can not be performed without a "full data". For example,
// find `dataIndex` by name.
- data.appendValues([], toAppendNames);
+ data.appendData(zrUtil.map(toAppendNames, name => ({
+ name,
+ value: NaN
+ })));
return data;
}
diff --git a/src/chart/map/mapDataStatistic.ts b/src/chart/map/mapDataStatistic.ts
index 0df4040..504f548 100644
--- a/src/chart/map/mapDataStatistic.ts
+++ b/src/chart/map/mapDataStatistic.ts
@@ -19,12 +19,12 @@
import * as zrUtil from 'zrender/src/core/util';
-import List from '../../data/List';
+import SeriesData from '../../data/SeriesData';
import MapSeries, { MapValueCalculationType } from './MapSeries';
import GlobalModel from '../../model/Global';
// FIXME 公用?
-function dataStatistics(datas: List[], statisticType: MapValueCalculationType): List {
+function dataStatistics(datas: SeriesData[], statisticType: MapValueCalculationType): SeriesData {
const dataNameMap = {} as {[mapKey: string]: number[]};
zrUtil.each(datas, function (data) {
diff --git a/src/chart/parallel/ParallelSeries.ts b/src/chart/parallel/ParallelSeries.ts
index aaca025..20140c9 100644
--- a/src/chart/parallel/ParallelSeries.ts
+++ b/src/chart/parallel/ParallelSeries.ts
@@ -20,7 +20,7 @@
import {each, bind} from 'zrender/src/core/util';
import SeriesModel from '../../model/Series';
-import createListFromArray from '../helper/createListFromArray';
+import createListFromArray from '../helper/createSeriesDataFromArray';
import {
SeriesOption,
SeriesEncodeOptionMixin,
@@ -35,7 +35,7 @@ import {
OptionEncode
} from '../../util/types';
import GlobalModel from '../../model/Global';
-import List from '../../data/List';
+import SeriesData from '../../data/SeriesData';
import { ParallelActiveState, ParallelAxisOption } from '../../coord/parallel/AxisModel';
import Parallel from '../../coord/parallel/Parallel';
import ParallelModel from '../../coord/parallel/ParallelModel';
@@ -91,7 +91,7 @@ class ParallelSeriesModel extends SeriesModel<ParallelSeriesOption> {
coordinateSystem: Parallel;
- getInitialData(this: ParallelSeriesModel, option: ParallelSeriesOption, ecModel: GlobalModel): List {
+ getInitialData(this: ParallelSeriesModel, option: ParallelSeriesOption, ecModel: GlobalModel): SeriesData {
return createListFromArray(this.getSource(), this, {
useEncodeDefaulter: bind(makeDefaultEncode, null, this)
});
diff --git a/src/chart/parallel/ParallelView.ts b/src/chart/parallel/ParallelView.ts
index c0b5714..1704b09 100644
--- a/src/chart/parallel/ParallelView.ts
+++ b/src/chart/parallel/ParallelView.ts
@@ -20,7 +20,7 @@
import * as graphic from '../../util/graphic';
import { setStatesStylesFromModel, enableHoverEmphasis } from '../../util/states';
import ChartView from '../../view/Chart';
-import List from '../../data/List';
+import SeriesData from '../../data/SeriesData';
import ParallelSeriesModel, { ParallelSeriesDataItemOption } from './ParallelSeries';
import GlobalModel from '../../model/Global';
import ExtensionAPI from '../../core/ExtensionAPI';
@@ -42,7 +42,7 @@ class ParallelView extends ChartView {
private _dataGroup = new graphic.Group();
- private _data: List;
+ private _data: SeriesData;
private _initialized = false;
@@ -160,7 +160,7 @@ function createGridClipShape(coordSys: Parallel, seriesModel: ParallelSeriesMode
return rectEl;
}
-function createLinePoints(data: List, dataIndex: number, dimensions: string[], coordSys: Parallel) {
+function createLinePoints(data: SeriesData, dataIndex: number, dimensions: string[], coordSys: Parallel) {
const points = [];
for (let i = 0; i < dimensions.length; i++) {
const dimName = dimensions[i];
@@ -172,7 +172,7 @@ function createLinePoints(data: List, dataIndex: number, dimensions: string[], c
return points;
}
-function addEl(data: List, dataGroup: graphic.Group, dataIndex: number, dimensions: string[], coordSys: Parallel) {
+function addEl(data: SeriesData, dataGroup: graphic.Group, dataIndex: number, dimensions: string[], coordSys: Parallel) {
const points = createLinePoints(data, dataIndex, dimensions, coordSys);
const line = new graphic.Polyline({
shape: {points: points},
@@ -195,7 +195,7 @@ function makeSeriesScope(seriesModel: ParallelSeriesModel): ParallelDrawSeriesSc
function updateElCommon(
el: graphic.Polyline,
- data: List,
+ data: SeriesData,
dataIndex: number,
seriesScope: ParallelDrawSeriesScope
) {
diff --git a/src/chart/pie/PieSeries.ts b/src/chart/pie/PieSeries.ts
index 0391923..85784e7 100644
--- a/src/chart/pie/PieSeries.ts
+++ b/src/chart/pie/PieSeries.ts
@@ -17,7 +17,7 @@
* under the License.
*/
-import createListSimply from '../helper/createListSimply';
+import createSeriesDataSimply from '../helper/createSeriesDataSimply';
import * as zrUtil from 'zrender/src/core/util';
import * as modelUtil from '../../util/model';
import { getPercentWithPrecision } from '../../util/number';
@@ -38,7 +38,7 @@ import {
SeriesLabelOption,
DefaultEmphasisFocus
} from '../../util/types';
-import List from '../../data/List';
+import SeriesData from '../../data/SeriesData';
interface PieItemStyleOption extends ItemStyleOption {
// can be 10
@@ -156,8 +156,8 @@ class PieSeriesModel extends SeriesModel<PieSeriesOption> {
/**
* @overwrite
*/
- getInitialData(this: PieSeriesModel): List {
- return createListSimply(this, {
+ getInitialData(this: PieSeriesModel): SeriesData {
+ return createSeriesDataSimply(this, {
coordDimensions: ['value'],
encodeDefaulter: zrUtil.curry(makeSeriesEncodeForNameBased, this)
});
diff --git a/src/chart/pie/PieView.ts b/src/chart/pie/PieView.ts
index 043654d..66c07e8 100644
--- a/src/chart/pie/PieView.ts
+++ b/src/chart/pie/PieView.ts
@@ -26,7 +26,7 @@ import ChartView from '../../view/Chart';
import GlobalModel from '../../model/Global';
import ExtensionAPI from '../../core/ExtensionAPI';
import { Payload, ColorString } from '../../util/types';
-import List from '../../data/List';
+import SeriesData from '../../data/SeriesData';
import PieSeriesModel, {PieDataItemOption} from './PieSeries';
import labelLayout from './labelLayout';
import { setLabelLineStyle, getLabelLineStatesModels } from '../../label/labelGuideHelper';
@@ -40,7 +40,7 @@ import { getBasicPieLayout } from './pieLayout';
*/
class PiePiece extends graphic.Sector {
- constructor(data: List, idx: number, startAngle: number) {
+ constructor(data: SeriesData, idx: number, startAngle: number) {
super();
this.z2 = 2;
@@ -52,7 +52,7 @@ class PiePiece extends graphic.Sector {
this.updateData(data, idx, startAngle, true);
}
- updateData(data: List, idx: number, startAngle?: number, firstCreate?: boolean): void {
+ updateData(data: SeriesData, idx: number, startAngle?: number, firstCreate?: boolean): void {
const sector = this;
const seriesModel = data.hostModel as PieSeriesModel;
@@ -158,7 +158,7 @@ class PiePiece extends graphic.Sector {
enableHoverEmphasis(this, emphasisModel.get('focus'), emphasisModel.get('blurScope'));
}
- private _updateLabel(seriesModel: PieSeriesModel, data: List, idx: number): void {
+ private _updateLabel(seriesModel: PieSeriesModel, data: SeriesData, idx: number): void {
const sector = this;
const itemModel = data.getItemModel<PieDataItemOption>(idx);
const labelLineModel = itemModel.getModel('labelLine');
@@ -223,7 +223,7 @@ class PieView extends ChartView {
ignoreLabelLineUpdate = true;
private _sectorGroup: graphic.Group;
- private _data: List;
+ private _data: SeriesData;
private _emptyCircleSector: graphic.Sector;
init(): void {
diff --git a/src/chart/radar/RadarSeries.ts b/src/chart/radar/RadarSeries.ts
index f768195..0f57ef6 100644
--- a/src/chart/radar/RadarSeries.ts
+++ b/src/chart/radar/RadarSeries.ts
@@ -18,7 +18,7 @@
*/
import SeriesModel from '../../model/Series';
-import createListSimply from '../helper/createListSimply';
+import createSeriesDataSimply from '../helper/createSeriesDataSimply';
import * as zrUtil from 'zrender/src/core/util';
import LegendVisualProvider from '../../visual/LegendVisualProvider';
import {
@@ -35,7 +35,7 @@ import {
CallbackDataParams
} from '../../util/types';
import GlobalModel from '../../model/Global';
-import List from '../../data/List';
+import SeriesData from '../../data/SeriesData';
import Radar from '../../coord/radar/Radar';
import {
createTooltipMarkup, retrieveVisualColorForTooltipMarker
@@ -90,8 +90,8 @@ class RadarSeriesModel extends SeriesModel<RadarSeriesOption> {
}
- getInitialData(option: RadarSeriesOption, ecModel: GlobalModel): List {
- return createListSimply(this, {
+ getInitialData(option: RadarSeriesOption, ecModel: GlobalModel): SeriesData {
+ return createSeriesDataSimply(this, {
generateCoord: 'indicator_',
generateCoordCount: Infinity
});
diff --git a/src/chart/radar/RadarView.ts b/src/chart/radar/RadarView.ts
index c4e28d0..3eb6da2 100644
--- a/src/chart/radar/RadarView.ts
+++ b/src/chart/radar/RadarView.ts
@@ -24,7 +24,7 @@ import * as symbolUtil from '../../util/symbol';
import ChartView from '../../view/Chart';
import RadarSeriesModel, { RadarSeriesDataItemOption } from './RadarSeries';
import ExtensionAPI from '../../core/ExtensionAPI';
-import List from '../../data/List';
+import SeriesData from '../../data/SeriesData';
import { ColorString } from '../../util/types';
import GlobalModel from '../../model/Global';
import { VectorArray } from 'zrender/src/core/vector';
@@ -40,7 +40,7 @@ class RadarView extends ChartView {
static type = 'radar';
type = RadarView.type;
- private _data: List<RadarSeriesModel>;
+ private _data: SeriesData<RadarSeriesModel>;
render(seriesModel: RadarSeriesModel, ecModel: GlobalModel, api: ExtensionAPI) {
const polar = seriesModel.coordinateSystem;
@@ -49,7 +49,7 @@ class RadarView extends ChartView {
const data = seriesModel.getData();
const oldData = this._data;
- function createSymbol(data: List<RadarSeriesModel>, idx: number) {
+ function createSymbol(data: SeriesData<RadarSeriesModel>, idx: number) {
const symbolType = data.getItemVisual(idx, 'symbol') as string || 'circle';
if (symbolType === 'none') {
return;
@@ -77,7 +77,7 @@ class RadarView extends ChartView {
oldPoints: VectorArray[],
newPoints: VectorArray[],
symbolGroup: graphic.Group,
- data: List<RadarSeriesModel>,
+ data: SeriesData<RadarSeriesModel>,
idx: number,
isInit?: boolean
) {
diff --git a/src/chart/sankey/SankeySeries.ts b/src/chart/sankey/SankeySeries.ts
index a915ef6..3261ad1 100644
--- a/src/chart/sankey/SankeySeries.ts
+++ b/src/chart/sankey/SankeySeries.ts
@@ -36,7 +36,7 @@ import {
DefaultEmphasisFocus
} from '../../util/types';
import GlobalModel from '../../model/Global';
-import List from '../../data/List';
+import SeriesData from '../../data/SeriesData';
import { LayoutRect } from '../../util/layout';
import { createTooltipMarkup } from '../../component/tooltip/tooltipMarkup';
@@ -150,7 +150,7 @@ class SankeySeriesModel extends SeriesModel<SankeySeriesOption> {
* Init a graph data structure from data in option series
*
* @param {Object} option the object used to config echarts view
- * @return {module:echarts/data/List} storage initial data
+ * @return {module:echarts/data/SeriesData} storage initial data
*/
getInitialData(option: SankeySeriesOption, ecModel: GlobalModel) {
const links = option.edges || option.links;
@@ -173,7 +173,7 @@ class SankeySeriesModel extends SeriesModel<SankeySeriesOption> {
const graph = createGraphFromNodeEdge(nodes, links, this, true, beforeLink);
return graph.data;
}
- function beforeLink(nodeData: List, edgeData: List) {
+ function beforeLink(nodeData: SeriesData, edgeData: SeriesData) {
nodeData.wrapMethod('getItemModel', function (model: Model, idx: number) {
const seriesModel = model.parentModel as SankeySeriesModel;
const layout = seriesModel.getData().getItemLayout(idx);
diff --git a/src/chart/sankey/SankeyView.ts b/src/chart/sankey/SankeyView.ts
index 480aeb5..abd589c 100644
--- a/src/chart/sankey/SankeyView.ts
+++ b/src/chart/sankey/SankeyView.ts
@@ -25,7 +25,7 @@ import SankeySeriesModel, { SankeyEdgeItemOption, SankeyNodeItemOption } from '.
import ChartView from '../../view/Chart';
import GlobalModel from '../../model/Global';
import ExtensionAPI from '../../core/ExtensionAPI';
-import List from '../../data/List';
+import SeriesData from '../../data/SeriesData';
import { RectLike } from 'zrender/src/core/BoundingRect';
import { setLabelStyle, getLabelStatesModels } from '../../label/labelStyle';
import { getECData } from '../../util/innerStore';
@@ -107,7 +107,7 @@ class SankeyView extends ChartView {
private _focusAdjacencyDisabled = false;
- private _data: List;
+ private _data: SeriesData;
render(seriesModel: SankeySeriesModel, ecModel: GlobalModel, api: ExtensionAPI) {
const sankeyView = this;
diff --git a/src/chart/scatter/ScatterSeries.ts b/src/chart/scatter/ScatterSeries.ts
index a217c5a..6248ecc 100644
--- a/src/chart/scatter/ScatterSeries.ts
+++ b/src/chart/scatter/ScatterSeries.ts
@@ -17,7 +17,7 @@
* under the License.
*/
-import createListFromArray from '../helper/createListFromArray';
+import createListFromArray from '../helper/createSeriesDataFromArray';
import SeriesModel from '../../model/Series';
import {
SeriesOption,
@@ -39,7 +39,7 @@ import {
DefaultEmphasisFocus
} from '../../util/types';
import GlobalModel from '../../model/Global';
-import List from '../../data/List';
+import SeriesData from '../../data/SeriesData';
import { BrushCommonSelectorsForSeries } from '../../component/brush/selector';
interface ScatterStateOption {
@@ -84,7 +84,7 @@ class ScatterSeriesModel extends SeriesModel<ScatterSeriesOption> {
hasSymbolVisual = true;
- getInitialData(option: ScatterSeriesOption, ecModel: GlobalModel): List {
+ getInitialData(option: ScatterSeriesOption, ecModel: GlobalModel): SeriesData {
return createListFromArray(this.getSource(), this, {
useEncodeDefaulter: true
});
@@ -109,7 +109,7 @@ class ScatterSeriesModel extends SeriesModel<ScatterSeriesOption> {
return progressiveThreshold;
}
- brushSelector(dataIndex: number, data: List, selectors: BrushCommonSelectorsForSeries): boolean {
+ brushSelector(dataIndex: number, data: SeriesData, selectors: BrushCommonSelectorsForSeries): boolean {
return selectors.point(data.getItemLayout(dataIndex));
}
diff --git a/src/chart/scatter/ScatterView.ts b/src/chart/scatter/ScatterView.ts
index 4a7fbb0..1bf6e3c 100644
--- a/src/chart/scatter/ScatterView.ts
+++ b/src/chart/scatter/ScatterView.ts
@@ -25,7 +25,7 @@ import ChartView from '../../view/Chart';
import ScatterSeriesModel from './ScatterSeries';
import GlobalModel from '../../model/Global';
import ExtensionAPI from '../../core/ExtensionAPI';
-import List from '../../data/List';
+import SeriesData from '../../data/SeriesData';
import { TaskProgressParams } from '../../core/task';
import type { StageHandlerProgressExecutor } from '../../util/types';
@@ -99,7 +99,7 @@ class ScatterView extends ChartView {
return seriesModel.get('clip', true) ? clipArea : null;
}
- _updateSymbolDraw(data: List, seriesModel: ScatterSeriesModel) {
+ _updateSymbolDraw(data: SeriesData, seriesModel: ScatterSeriesModel) {
let symbolDraw = this._symbolDraw;
const pipelineContext = seriesModel.pipelineContext;
const isLargeDraw = pipelineContext.large;
diff --git a/src/chart/sunburst/SunburstSeries.ts b/src/chart/sunburst/SunburstSeries.ts
index a1e38bf..9082acc 100644
--- a/src/chart/sunburst/SunburstSeries.ts
+++ b/src/chart/sunburst/SunburstSeries.ts
@@ -33,7 +33,7 @@ import {
DefaultEmphasisFocus
} from '../../util/types';
import GlobalModel from '../../model/Global';
-import List from '../../data/List';
+import SeriesData from '../../data/SeriesData';
import Model from '../../model/Model';
import enableAriaDecalForTree from '../helper/enableAriaDecalForTree';
@@ -164,7 +164,7 @@ class SunburstSeriesModel extends SeriesModel<SunburstSeriesOption> {
// to choose mappings approach among old shapes and new shapes.
const tree = Tree.createTree(root, this, beforeLink);
- function beforeLink(nodeData: List) {
+ function beforeLink(nodeData: SeriesData) {
nodeData.wrapMethod('getItemModel', function (model, idx) {
const node = tree.getNodeByDataIndex(idx);
const levelModel = levelModels[node.depth];
diff --git a/src/chart/themeRiver/ThemeRiverSeries.ts b/src/chart/themeRiver/ThemeRiverSeries.ts
index 6eb4f72..724526d 100644
--- a/src/chart/themeRiver/ThemeRiverSeries.ts
+++ b/src/chart/themeRiver/ThemeRiverSeries.ts
@@ -20,7 +20,7 @@
import SeriesModel from '../../model/Series';
import createDimensions from '../../data/helper/createDimensions';
import {getDimensionTypeByAxis} from '../../data/helper/dimensionHelper';
-import List from '../../data/List';
+import SeriesData from '../../data/SeriesData';
import * as zrUtil from 'zrender/src/core/util';
import {groupData, SINGLE_REFERRING} from '../../util/model';
import LegendVisualProvider from '../../visual/LegendVisualProvider';
@@ -154,7 +154,7 @@ class ThemeRiverSeriesModel extends SeriesModel<ThemeRiverSeriesOption> {
* @param option the initial option that user gived
* @param ecModel the model object for themeRiver option
*/
- getInitialData(option: ThemeRiverSeriesOption, ecModel: GlobalModel): List {
+ getInitialData(option: ThemeRiverSeriesOption, ecModel: GlobalModel): SeriesData {
const singleAxisModel = this.getReferringComponents('singleAxis', SINGLE_REFERRING).models[0];
@@ -202,7 +202,7 @@ class ThemeRiverSeriesModel extends SeriesModel<ThemeRiverSeriesOption> {
}
});
- const list = new List(dimensionsInfo, this);
+ const list = new SeriesData(dimensionsInfo, this);
list.initData(data);
return list;
diff --git a/src/chart/themeRiver/themeRiverLayout.ts b/src/chart/themeRiver/themeRiverLayout.ts
index 6de3e65..ec51217 100644
--- a/src/chart/themeRiver/themeRiverLayout.ts
+++ b/src/chart/themeRiver/themeRiverLayout.ts
@@ -23,7 +23,7 @@ import GlobalModel from '../../model/Global';
import ExtensionAPI from '../../core/ExtensionAPI';
import ThemeRiverSeriesModel, { ThemeRiverSeriesOption } from './ThemeRiverSeries';
import { RectLike } from 'zrender/src/core/BoundingRect';
-import List from '../../data/List';
+import SeriesData from '../../data/SeriesData';
export interface ThemeRiverLayoutInfo {
rect: RectLike
@@ -75,7 +75,7 @@ export default function themeRiverLayout(ecModel: GlobalModel, api: ExtensionAPI
* @param seriesModel the model object of themeRiver series
* @param height value used to compute every series height
*/
-function doThemeRiverLayout(data: List<ThemeRiverSeriesModel>, seriesModel: ThemeRiverSeriesModel, height: number) {
+function doThemeRiverLayout(data: SeriesData<ThemeRiverSeriesModel>, seriesModel: ThemeRiverSeriesModel, height: number) {
if (!data.count()) {
return;
}
diff --git a/src/chart/tree/TreeSeries.ts b/src/chart/tree/TreeSeries.ts
index 2c197e4..4f1e1b1 100644
--- a/src/chart/tree/TreeSeries.ts
+++ b/src/chart/tree/TreeSeries.ts
@@ -33,7 +33,7 @@ import {
CallbackDataParams,
DefaultEmphasisFocus
} from '../../util/types';
-import List from '../../data/List';
+import SeriesData from '../../data/SeriesData';
import View from '../../coord/View';
import { LayoutRect } from '../../util/layout';
import Model from '../../model/Model';
@@ -144,7 +144,7 @@ class TreeSeriesModel extends SeriesModel<TreeSeriesOption> {
* @param option the object used to config echarts view
* @return storage initial data
*/
- getInitialData(option: TreeSeriesOption): List {
+ getInitialData(option: TreeSeriesOption): SeriesData {
//create an virtual root
const root: TreeSeriesNodeItemOption = {
@@ -157,7 +157,7 @@ class TreeSeriesModel extends SeriesModel<TreeSeriesOption> {
const tree = Tree.createTree(root, this, beforeLink);
- function beforeLink(nodeData: List) {
+ function beforeLink(nodeData: SeriesData) {
nodeData.wrapMethod('getItemModel', function (model, idx) {
const node = tree.getNodeByDataIndex(idx);
if (!(node && node.children.length && node.isExpand)) {
diff --git a/src/chart/tree/TreeView.ts b/src/chart/tree/TreeView.ts
index bcc8be8..e86d0b2 100644
--- a/src/chart/tree/TreeView.ts
+++ b/src/chart/tree/TreeView.ts
@@ -34,7 +34,7 @@ import Path, { PathProps, PathStyleProps } from 'zrender/src/graphic/Path';
import GlobalModel from '../../model/Global';
import ExtensionAPI from '../../core/ExtensionAPI';
import { TreeNode } from '../../data/Tree';
-import List from '../../data/List';
+import SeriesData from '../../data/SeriesData';
import { setStatesStylesFromModel, setStatesFlag, setDefaultStateProxy, HOVER_STATE_BLUR } from '../../util/states';
import { ECElement } from '../../util/types';
@@ -134,7 +134,7 @@ class TreeView extends ChartView {
private _controller: RoamController;
private _controllerHost: RoamControllerHost;
- private _data: List<TreeSeriesModel>;
+ private _data: SeriesData<TreeSeriesModel>;
private _nodeScaleRatio: number;
private _min: number[];
@@ -358,7 +358,7 @@ class TreeView extends ChartView {
}
-function symbolNeedsDraw(data: List, dataIndex: number) {
+function symbolNeedsDraw(data: SeriesData, dataIndex: number) {
const layout = data.getItemLayout(dataIndex);
return layout
@@ -367,7 +367,7 @@ function symbolNeedsDraw(data: List, dataIndex: number) {
function updateNode(
- data: List,
+ data: SeriesData,
dataIndex: number,
symbolEl: TreeSymbol,
group: graphic.Group,
@@ -596,7 +596,7 @@ function drawEdge(
}
function removeNode(
- data: List,
+ data: SeriesData,
dataIndex: number,
symbolEl: TreeSymbol,
group: graphic.Group,
diff --git a/src/chart/treemap/TreemapSeries.ts b/src/chart/treemap/TreemapSeries.ts
index e84fe85..cde6a0c 100644
--- a/src/chart/treemap/TreemapSeries.ts
+++ b/src/chart/treemap/TreemapSeries.ts
@@ -40,7 +40,7 @@ import {
} from '../../util/types';
import GlobalModel from '../../model/Global';
import { LayoutRect } from '../../util/layout';
-import List from '../../data/List';
+import SeriesData from '../../data/SeriesData';
import { normalizeToArray } from '../../util/model';
import { createTooltipMarkup } from '../../component/tooltip/tooltipMarkup';
import enableAriaDecalForTree from '../helper/enableAriaDecalForTree';
@@ -367,7 +367,7 @@ class TreemapSeriesModel extends SeriesModel<TreemapSeriesOption> {
// to choose mappings approach among old shapes and new shapes.
const tree = Tree.createTree(root, this, beforeLink);
- function beforeLink(nodeData: List) {
+ function beforeLink(nodeData: SeriesData) {
nodeData.wrapMethod('getItemModel', function (model, idx) {
const node = tree.getNodeByDataIndex(idx);
const levelModel = node ? levelModels[node.depth] : null;
diff --git a/src/component/helper/MapDraw.ts b/src/component/helper/MapDraw.ts
index 31ff42d..56bf2c5 100644
--- a/src/component/helper/MapDraw.ts
+++ b/src/component/helper/MapDraw.ts
@@ -46,7 +46,7 @@ import { ViewCoordSysTransformInfoPart } from '../../coord/View';
import { GeoSVGGraphicRecord, GeoSVGResource } from '../../coord/geo/GeoSVGResource';
import Displayable from 'zrender/src/graphic/Displayable';
import Element from 'zrender/src/Element';
-import List from '../../data/List';
+import SeriesData from '../../data/SeriesData';
import { GeoJSONRegion } from '../../coord/geo/Region';
import { SVGNodeTagLower } from 'zrender/src/tool/parseSVG';
import { makeInner } from '../../util/model';
@@ -62,7 +62,7 @@ interface ViewBuildContext {
api: ExtensionAPI;
geo: Geo;
mapOrGeoModel: GeoModel | MapSeries;
- data: List;
+ data: SeriesData;
isVisualEncodedByVisualMap: boolean;
isGeo: boolean;
transformInfoRaw: ViewCoordSysTransformInfoPart;
diff --git a/src/component/marker/MarkAreaView.ts b/src/component/marker/MarkAreaView.ts
index bb20679..e4faafd 100644
--- a/src/component/marker/MarkAreaView.ts
+++ b/src/component/marker/MarkAreaView.ts
@@ -20,7 +20,7 @@
// TODO Optimize on polar
import * as colorUtil from 'zrender/src/tool/color';
-import List from '../../data/List';
+import SeriesData from '../../data/SeriesData';
import * as numberUtil from '../../util/number';
import * as graphic from '../../util/graphic';
import { enableHoverEmphasis, setStatesStylesFromModel } from '../../util/states';
@@ -47,7 +47,7 @@ interface MarkAreaDrawGroup {
}
const inner = makeInner<{
- data: List<MarkAreaModel>
+ data: SeriesData<MarkAreaModel>
}, MarkAreaDrawGroup>();
// Merge two ends option into one.
@@ -137,7 +137,7 @@ function markAreaFilter(coordSys: CoordinateSystem, item: MarkAreaMergedItemOpti
// dims can be ['x0', 'y0'], ['x1', 'y1'], ['x0', 'y1'], ['x1', 'y0']
function getSingleMarkerEndPoint(
- data: List<MarkAreaModel>,
+ data: SeriesData<MarkAreaModel>,
idx: number,
dims: typeof dimPermutations[number],
seriesModel: SeriesModel,
@@ -363,7 +363,7 @@ function createList(
) {
let coordDimsInfos: DataDimensionInfo[];
- let areaData: List<MarkAreaModel>;
+ let areaData: SeriesData<MarkAreaModel>;
const dims = ['x0', 'y0', 'x1', 'y1'];
if (coordSys) {
coordDimsInfos = map(coordSys && coordSys.dimensions, function (coordDim) {
@@ -376,7 +376,7 @@ function createList(
name: coordDim
}, info);
});
- areaData = new List(map(dims, function (dim, idx) {
+ areaData = new SeriesData(map(dims, function (dim, idx) {
return {
name: dim,
type: coordDimsInfos[idx % 2].type
@@ -388,7 +388,7 @@ function createList(
name: 'value',
type: 'float'
}];
- areaData = new List(coordDimsInfos, maModel);
+ areaData = new SeriesData(coordDimsInfos, maModel);
}
let optData = map(maModel.get('data'), curry(
diff --git a/src/component/marker/MarkLineView.ts b/src/component/marker/MarkLineView.ts
index d4ed839..23901cc 100644
--- a/src/component/marker/MarkLineView.ts
+++ b/src/component/marker/MarkLineView.ts
@@ -17,7 +17,7 @@
* under the License.
*/
-import List from '../../data/List';
+import SeriesData from '../../data/SeriesData';
import * as numberUtil from '../../util/number';
import * as markerHelper from './markerHelper';
import LineDraw from '../../chart/helper/LineDraw';
@@ -57,9 +57,9 @@ type MarkLineMergedItemOption = MarkLine2DDataItemOption[number];
const inner = makeInner<{
// from data
- from: List<MarkLineModel>
+ from: SeriesData<MarkLineModel>
// to data
- to: List<MarkLineModel>
+ to: SeriesData<MarkLineModel>
}, MarkLineModel>();
const markLineTransform = function (
@@ -196,7 +196,7 @@ function markLineFilter(
}
function updateSingleMarkerEndLayout(
- data: List<MarkLineModel>,
+ data: SeriesData<MarkLineModel>,
idx: number,
isFrom: boolean,
seriesModel: SeriesModel,
@@ -311,7 +311,7 @@ class MarkLineView extends MarkerView {
const fromData = mlData.from;
const toData = mlData.to;
- const lineData = mlData.line as List<MarkLineModel, LineDataVisual>;
+ const lineData = mlData.line as SeriesData<MarkLineModel, LineDataVisual>;
inner(mlModel).from = fromData;
inner(mlModel).to = toData;
@@ -388,7 +388,7 @@ class MarkLineView extends MarkerView {
});
function updateDataVisualAndLayout(
- data: List<MarkLineModel>,
+ data: SeriesData<MarkLineModel>,
idx: number,
isFrom: boolean
) {
@@ -452,10 +452,10 @@ function createList(coordSys: CoordinateSystem, seriesModel: SeriesModel, mlMode
}];
}
- const fromData = new List(coordDimsInfos, mlModel);
- const toData = new List(coordDimsInfos, mlModel);
+ const fromData = new SeriesData(coordDimsInfos, mlModel);
+ const toData = new SeriesData(coordDimsInfos, mlModel);
// No dimensions
- const lineData = new List([], mlModel);
+ const lineData = new SeriesData([], mlModel);
let optData = map(mlModel.get('data'), curry(
markLineTransform, seriesModel, coordSys, mlModel
diff --git a/src/component/marker/MarkPointView.ts b/src/component/marker/MarkPointView.ts
index b7cf0a2..e82fe73 100644
--- a/src/component/marker/MarkPointView.ts
+++ b/src/component/marker/MarkPointView.ts
@@ -20,7 +20,7 @@
import SymbolDraw from '../../chart/helper/SymbolDraw';
import * as numberUtil from '../../util/number';
-import List from '../../data/List';
+import SeriesData from '../../data/SeriesData';
import * as markerHelper from './markerHelper';
import MarkerView from './MarkerView';
import { CoordinateSystem } from '../../coord/CoordinateSystem';
@@ -35,7 +35,7 @@ import { getVisualFromData } from '../../visual/helper';
import { ZRColor } from '../../util/types';
function updateMarkerLayout(
- mpData: List<MarkPointModel>,
+ mpData: SeriesData<MarkPointModel>,
seriesModel: SeriesModel,
api: ExtensionAPI
) {
@@ -198,7 +198,7 @@ function createList(
}];
}
- const mpData = new List(coordDimsInfos, mpModel);
+ const mpData = new SeriesData(coordDimsInfos, mpModel);
let dataOpt = map(mpModel.get('data'), curry(
markerHelper.dataTransform, seriesModel
));
diff --git a/src/component/marker/MarkerModel.ts b/src/component/marker/MarkerModel.ts
index 341bf5b..6a68558 100644
--- a/src/component/marker/MarkerModel.ts
+++ b/src/component/marker/MarkerModel.ts
@@ -32,7 +32,7 @@ import {
} from '../../util/types';
import Model from '../../model/Model';
import GlobalModel from '../../model/Global';
-import List from '../../data/List';
+import SeriesData from '../../data/SeriesData';
import { makeInner, defaultEmphasis } from '../../util/model';
import { createTooltipMarkup } from '../tooltip/tooltipMarkup';
@@ -109,7 +109,7 @@ abstract class MarkerModel<Opts extends MarkerOption = MarkerOption> extends Com
__hostSeries: SeriesModel;
- private _data: List;
+ private _data: SeriesData;
/**
* @overrite
@@ -217,11 +217,11 @@ abstract class MarkerModel<Opts extends MarkerOption = MarkerOption> extends Com
});
}
- getData(): List<this> {
- return this._data as List<this>;
+ getData(): SeriesData<this> {
+ return this._data as SeriesData<this>;
}
- setData(data: List) {
+ setData(data: SeriesData) {
this._data = data;
}
diff --git a/src/component/marker/markerHelper.ts b/src/component/marker/markerHelper.ts
index 4ae4b75..ab4a7a9 100644
--- a/src/component/marker/markerHelper.ts
+++ b/src/component/marker/markerHelper.ts
@@ -20,7 +20,7 @@
import * as numberUtil from '../../util/number';
import {isDimensionStacked} from '../../data/helper/dataStackHelper';
import SeriesModel from '../../model/Series';
-import List from '../../data/List';
+import SeriesData from '../../data/SeriesData';
import { MarkerStatisticType, MarkerPositionOption } from './MarkerModel';
import { indexOf, curry, clone, isArray } from 'zrender/src/core/util';
import Axis from '../../coord/Axis';
@@ -68,7 +68,7 @@ function hasXAndY(item: MarkerPositionOption) {
function markerTypeCalculatorWithExtent(
markerType: MarkerStatisticType,
- data: List,
+ data: SeriesData,
otherDataDim: string,
targetDataDim: string,
otherCoordIndex: number,
@@ -171,7 +171,7 @@ export function dataTransform(
export function getAxisInfo(
item: MarkerPositionOption,
- data: List,
+ data: SeriesData,
coordSys: CoordinateSystem,
seriesModel: SeriesModel
) {
@@ -236,7 +236,7 @@ export function dimValueGetter(
}
export function numCalculate(
- data: List,
+ data: SeriesData,
valueDataDim: string,
type: MarkerStatisticType
) {
diff --git a/src/component/timeline/SliderTimelineModel.ts b/src/component/timeline/SliderTimelineModel.ts
index 618e49c..ec20bc9 100644
--- a/src/component/timeline/SliderTimelineModel.ts
+++ b/src/component/timeline/SliderTimelineModel.ts
@@ -20,7 +20,7 @@
import TimelineModel, { TimelineOption } from './TimelineModel';
import { DataFormatMixin } from '../../model/mixin/dataFormat';
import { mixin } from 'zrender/src/core/util';
-import List from '../../data/List';
+import SeriesData from '../../data/SeriesData';
import { inheritDefaultOption } from '../../util/component';
export interface SliderTimelineOption extends TimelineOption {
@@ -149,7 +149,7 @@ class SliderTimelineModel extends TimelineModel {
}
interface SliderTimelineModel extends DataFormatMixin {
- getData(): List<SliderTimelineModel>
+ getData(): SeriesData<SliderTimelineModel>
}
mixin(SliderTimelineModel, DataFormatMixin.prototype);
diff --git a/src/component/timeline/TimelineModel.ts b/src/component/timeline/TimelineModel.ts
index 619f468..ecfd963 100644
--- a/src/component/timeline/TimelineModel.ts
+++ b/src/component/timeline/TimelineModel.ts
@@ -18,7 +18,7 @@
*/
import ComponentModel from '../../model/Component';
-import List from '../../data/List';
+import SeriesData from '../../data/SeriesData';
import {
ComponentOption,
BoxLayoutOptionMixin,
@@ -171,7 +171,7 @@ class TimelineModel extends ComponentModel<TimelineOption> {
layoutMode = 'box';
- private _data: List<TimelineModel>;
+ private _data: SeriesData<TimelineModel>;
private _names: string[];
@@ -275,7 +275,7 @@ class TimelineModel extends ComponentModel<TimelineOption> {
value: 'number'
})[axisType] || 'number';
- const data = this._data = new List([{
+ const data = this._data = new SeriesData([{
name: 'value', type: dimType
}], this);
diff --git a/src/component/visualMap/VisualMapModel.ts b/src/component/visualMap/VisualMapModel.ts
index 2ef3c33..0ec6cef 100644
--- a/src/component/visualMap/VisualMapModel.ts
+++ b/src/component/visualMap/VisualMapModel.ts
@@ -38,7 +38,7 @@ import ComponentModel from '../../model/Component';
import Model from '../../model/Model';
import GlobalModel from '../../model/Global';
import SeriesModel from '../../model/Series';
-import List from '../../data/List';
+import SeriesData from '../../data/SeriesData';
const mapVisual = VisualMapping.mapVisual;
const eachVisual = VisualMapping.eachVisual;
@@ -379,7 +379,7 @@ class VisualMapModel<Opts extends VisualMapOption = VisualMapOption> extends Com
/**
* Return Concrete dimention. If return null/undefined, no dimension used.
*/
- getDataDimension(list: List) {
+ getDataDimension(list: SeriesData) {
const optDim = this.option.dimension;
const listDimensions = list.dimensions;
if (optDim == null && !listDimensions.length) {
diff --git a/src/coord/axisHelper.ts b/src/coord/axisHelper.ts
index 3bc6860..d058db3 100644
--- a/src/coord/axisHelper.ts
+++ b/src/coord/axisHelper.ts
@@ -35,7 +35,7 @@ import LogScale from '../scale/Log';
import Axis from './Axis';
import { AxisBaseOption, TimeAxisLabelFormatterOption } from './axisCommonTypes';
import type CartesianAxisModel from './cartesian/AxisModel';
-import List from '../data/List';
+import SeriesData from '../data/SeriesData';
import { getStackedDimension } from '../data/helper/dataStackHelper';
import { Dictionary, DimensionName, ScaleTick, TimeScaleTick } from '../util/types';
import { ensureScaleRawExtentInfo } from './scaleRawExtentInfo';
@@ -361,7 +361,7 @@ export function shouldShowAllLabels(axis: Axis): boolean {
&& getOptionCategoryInterval(axis.getLabelModel()) === 0;
}
-export function getDataDimensionsOnAxis(data: List, axisDim: string): DimensionName[] {
+export function getDataDimensionsOnAxis(data: SeriesData, axisDim: string): DimensionName[] {
// Remove duplicated dat dimensions caused by `getStackedDimension`.
const dataDimMap = {} as Dictionary<boolean>;
// Currently `mapDimensionsAll` will contain stack result dimension ('__\0ecstackresult').
@@ -379,7 +379,7 @@ export function getDataDimensionsOnAxis(data: List, axisDim: string): DimensionN
return zrUtil.keys(dataDimMap);
}
-export function unionAxisExtentFromData(dataExtent: number[], data: List, axisDim: string): void {
+export function unionAxisExtentFromData(dataExtent: number[], data: SeriesData, axisDim: string): void {
if (data) {
zrUtil.each(getDataDimensionsOnAxis(data, axisDim), function (dim) {
const seriesExtent = data.getApproximateExtent(dim);
diff --git a/src/coord/cartesian/Grid.ts b/src/coord/cartesian/Grid.ts
index 32c616d..6eef23e 100644
--- a/src/coord/cartesian/Grid.ts
+++ b/src/coord/cartesian/Grid.ts
@@ -44,7 +44,7 @@ import ExtensionAPI from '../../core/ExtensionAPI';
import { Dictionary } from 'zrender/src/core/types';
import {CoordinateSystemMaster} from '../CoordinateSystem';
import { ScaleDataValue } from '../../util/types';
-import List from '../../data/List';
+import SeriesData from '../../data/SeriesData';
import OrdinalScale from '../../scale/Ordinal';
import { isCartesian2DSeries, findAxisModels } from './cartesianAxisHelper';
@@ -450,7 +450,7 @@ class Grid implements CoordinateSystemMaster {
}
}, this);
- function unionExtent(data: List, axis: Axis2D): void {
+ function unionExtent(data: SeriesData, axis: Axis2D): void {
each(getDataDimensionsOnAxis(data, axis.dim), function (dim) {
axis.scale.unionExtentFromData(data, dim);
});
diff --git a/src/coord/parallel/Parallel.ts b/src/coord/parallel/Parallel.ts
index 6080b85..e22cf9a 100644
--- a/src/coord/parallel/Parallel.ts
+++ b/src/coord/parallel/Parallel.ts
@@ -37,7 +37,7 @@ import ExtensionAPI from '../../core/ExtensionAPI';
import { Dictionary, DimensionName, ScaleDataValue } from '../../util/types';
import { CoordinateSystem, CoordinateSystemMaster } from '../CoordinateSystem';
import ParallelAxisModel, { ParallelActiveState } from './AxisModel';
-import List from '../../data/List';
+import SeriesData from '../../data/SeriesData';
const each = zrUtil.each;
const mathMin = Math.min;
@@ -357,7 +357,7 @@ class Parallel implements CoordinateSystemMaster, CoordinateSystem {
* @param end the next dataIndex of the last dataIndex will be travel.
*/
eachActiveState(
- data: List,
+ data: SeriesData,
callback: (activeState: ParallelActiveState, dataIndex: number) => void,
start?: number,
end?: number
diff --git a/src/core/Scheduler.ts b/src/core/Scheduler.ts
index 2081e4a..4d67411 100644
--- a/src/core/Scheduler.ts
+++ b/src/core/Scheduler.ts
@@ -33,7 +33,7 @@ import {
import { EChartsType } from './echarts';
import SeriesModel from '../model/Series';
import ChartView from '../view/Chart';
-import List from '../data/List';
+import SeriesData from '../data/SeriesData';
export type GeneralTask = Task<TaskContext>;
export type SeriesTask = Task<SeriesTaskContext>;
@@ -76,7 +76,7 @@ type PerformStageTaskOpt = {
export interface SeriesTaskContext extends TaskContext {
model?: SeriesModel;
- data?: List;
+ data?: SeriesData;
view?: ChartView;
ecModel?: GlobalModel;
api?: ExtensionAPI;
diff --git a/src/core/task.ts b/src/core/task.ts
index 97bcaeb..08d7e23 100644
--- a/src/core/task.ts
+++ b/src/core/task.ts
@@ -21,12 +21,12 @@ import {assert, isArray} from 'zrender/src/core/util';
import SeriesModel from '../model/Series';
import { Pipeline } from './Scheduler';
import { Payload } from '../util/types';
-import List from '../data/List';
+import SeriesData from '../data/SeriesData';
export interface TaskContext {
- outputData?: List;
- data?: List;
+ outputData?: SeriesData;
+ data?: SeriesData;
payload?: Payload;
model?: SeriesModel;
};
diff --git a/src/data/DataDimensionInfo.ts b/src/data/DataDimensionInfo.ts
index 2857ef8..2b95198 100644
--- a/src/data/DataDimensionInfo.ts
+++ b/src/data/DataDimensionInfo.ts
@@ -25,7 +25,6 @@ class DataDimensionInfo {
/**
* Dimension type. The enumerable values are the key of
- * `dataCtors` of `data/List`.
* Optional.
*/
type?: DimensionType;
@@ -63,8 +62,8 @@ class DataDimensionInfo {
coordDimIndex?: number;
/**
- * This index of this dimension info in `data/List#_dimensionInfos`.
- * Mandatory after added to `data/List`.
+ * This index of this dimension info in `data/SeriesData#_dimensionInfos`.
+ * Mandatory after added to `data/SeriesData`.
*/
index?: number;
diff --git a/src/data/DataStorage.ts b/src/data/DataStorage.ts
new file mode 100644
index 0000000..2a9da9e
--- /dev/null
+++ b/src/data/DataStorage.ts
@@ -0,0 +1,1141 @@
+/*
+* 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, clone, isFunction, keys, map, reduce } from 'zrender/src/core/util';
+import {
+ Dictionary,
+ DimensionIndex,
+ DimensionName,
+ OptionDataItem,
+ OrdinalNumber,
+ ParsedValue,
+ ParsedValueNumeric
+} from '../util/types';
+import { DataProvider } from './helper/dataProvider';
+import { parseDataValue } from './helper/dataValueHelper';
+import OrdinalMeta from './OrdinalMeta';
+
+const UNDEFINED = 'undefined';
+/* global Float64Array, Int32Array, Uint32Array, Uint16Array */
+
+/**
+ * Multi dimensional data storage
+ */
+ const dataCtors = {
+ 'float': typeof Float64Array === UNDEFINED
+ ? Array : Float64Array,
+ 'int': typeof Int32Array === UNDEFINED
+ ? Array : Int32Array,
+ // Ordinal data type can be string or int
+ 'ordinal': Array,
+ 'number': Array,
+ 'time': Array
+} as const;
+
+export type DataStoreDimensionType = keyof typeof dataCtors;
+
+type DataTypedArray = Uint32Array | Int32Array | Uint16Array | Float64Array;
+type DataTypedArrayConstructor = typeof Uint32Array | typeof Int32Array | typeof Uint16Array | typeof Float64Array;
+type DataArrayLikeConstructor = typeof Array | DataTypedArrayConstructor;
+
+// Caution: MUST not use `new CtorUint32Array(arr, 0, len)`, because the Ctor of array is
+// different from the Ctor of typed array.
+const CtorUint32Array = typeof Uint32Array === UNDEFINED ? Array : Uint32Array;
+const CtorUint16Array = typeof Uint16Array === UNDEFINED ? Array : Uint16Array;
+
+type DataValueChunk = ArrayLike<ParsedValue>;
+
+// If Ctx not specified, use List as Ctx
+type EachCb0 = (idx: number) => void;
+type EachCb1 = (x: ParsedValue, idx: number) => void;
+type EachCb2 = (x: ParsedValue, y: ParsedValue, idx: number) => void;
+type EachCb = (...args: any) => void;
+type FilterCb0 = (idx: number) => boolean;
+type FilterCb1 = (x: ParsedValue, idx: number) => boolean;
+type FilterCb = (...args: any) => boolean;
+type MapArrayCb = (...args: any) => any;
+type MapCb = (...args: any) => ParsedValue | ParsedValue[];
+
+export type DimValueGetter = (
+ this: DataStorage,
+ dataItem: any,
+ /**
+ * @deprecated
+ * dimName is not used anymore
+ */
+ dimName: string,
+ dataIndex: number,
+ dimIndex: DimensionIndex
+) => ParsedValue;
+
+interface StoreDimensionInfo {
+ type?: DataStoreDimensionType; // Default to be float.
+ name?: string;
+ ordinalMeta?: OrdinalMeta;
+}
+
+let defaultDimValueGetters: {[sourceFormat: string]: DimValueGetter};
+
+function getIndicesCtor(rawCount: number): DataArrayLikeConstructor {
+ // The possible max value in this._indicies is always this._rawCount despite of filtering.
+ return rawCount > 65535 ? CtorUint32Array : CtorUint16Array;
+};
+function getInitialExtent(): [number, number] {
+ return [Infinity, -Infinity];
+};
+function cloneChunk(originalChunk: DataValueChunk): DataValueChunk {
+ const Ctor = originalChunk.constructor;
+ // Only shallow clone is enough when Array.
+ return Ctor === Array
+ ? (originalChunk as Array<ParsedValue>).slice()
+ : new (Ctor as DataTypedArrayConstructor)(originalChunk as DataTypedArray);
+}
+
+function prepareStorage(
+ storage: DataValueChunk[],
+ dimIdx: number,
+ dimType: DataStoreDimensionType,
+ end: number,
+ append?: boolean
+): void {
+ const DataCtor = dataCtors[dimType || 'float'];
+
+ if (append) {
+ const oldStore = storage[dimIdx];
+ const oldLen = oldStore && oldStore.length;
+ if (!(oldLen === end)) {
+ const newStore = new DataCtor(end);
+ // The cost of the copy is probably inconsiderable
+ // within the initial chunkSize.
+ for (let j = 0; j < oldLen; j++) {
+ newStore[j] = oldStore[j];
+ }
+ storage[dimIdx] = newStore;
+ }
+ }
+ else {
+ storage[dimIdx] = new DataCtor(end);
+ }
+};
+class DataStorage {
+ private _chunks: DataValueChunk[] = [];
+
+ private _provider: DataProvider;
+
+ // Raw extent will not be cloned, but only transfered.
+ // It will not be calculated util needed.
+ private _rawExtent: [number, number][] = [];
+
+ private _extent: [number, number][] = [];
+
+ // Indices stores the indices of data subset after filtered.
+ // This data subset will be used in chart.
+ private _indices: ArrayLike<any>;
+
+ private _count: number = 0;
+ private _rawCount: number = 0;
+
+ private _dimensions: StoreDimensionInfo[];
+ private _dimValueGetter: DimValueGetter;
+
+ defaultDimValueGetter: DimValueGetter;
+ /**
+ * Initialize from data
+ * @param data source or data or data provider.
+ */
+ initData(
+ provider: DataProvider,
+ dimensions: StoreDimensionInfo[],
+ dimValueGetter?: DimValueGetter
+ ): void {
+ if (__DEV__) {
+ assert(
+ isFunction(provider.getItem) && isFunction(provider.count),
+ 'Inavlid data provider.'
+ );
+ }
+
+ this._provider = provider;
+
+ // Clear
+ this._chunks = [];
+ this._indices = null;
+ this.getRawIndex = this._getRawIdxIdentity;
+
+ const defaultGetter = this.defaultDimValueGetter =
+ defaultDimValueGetters[provider.getSource().sourceFormat];
+ // Default dim value getter
+ this._dimValueGetter = dimValueGetter || defaultGetter;
+
+ const emptyObj = {};
+
+ // Reset raw extent.
+ this._rawExtent = [];
+ this._dimensions = dimensions;
+
+ const dimensionsIdxMap: Dictionary<number> = {};
+ let prefix = '';
+
+ // Needs to add prefix if key is used in object prototype
+ for (let i = 0; i < dimensions.length; i++) {
+ const name = dimensions[i].name;
+ if ((emptyObj as any)[name] != null) {
+ prefix = '$$';
+ }
+ }
+ for (let i = 0; i < dimensions.length; i++) {
+ const name = dimensions[i].name;
+ dimensionsIdxMap[prefix + name] = i;
+ }
+
+ // We use different functions because it may be a hotspot code.
+ this.getDimensionIndex = prefix ? function (dim) {
+ return dimensionsIdxMap[prefix + dim];
+ } : function (dim) {
+ return dimensionsIdxMap[dim];
+ };
+
+ this._initDataFromProvider(0, provider.count());
+ }
+
+ getProvider(): DataProvider {
+ return this._provider;
+ }
+
+ getDimensionIndex: (dim: DimensionName) => number;
+
+ /**
+ * Caution: Can be only called on raw data (before `this._indices` created).
+ */
+ appendData(data: ArrayLike<any>) {
+ if (__DEV__) {
+ assert(!this._indices, 'appendData can only be called on raw data.');
+ }
+
+ const provider = this._provider;
+ const start = this.count();
+ provider.appendData(data);
+ let end = provider.count();
+ if (!provider.persistent) {
+ end += start;
+ }
+ this._initDataFromProvider(start, end, true);
+
+ return [start, end];
+ }
+
+ private _initDataFromProvider(
+ start: number,
+ end: number,
+ append?: boolean
+ ): void {
+ if (start >= end) {
+ return;
+ }
+
+ const provider = this._provider;
+ const chunks = this._chunks;
+ const dimensions = this._dimensions;
+ const dimLen = dimensions.length;
+ const rawExtent = this._rawExtent;
+ const dimNames = map(dimensions, dim => dim.name);
+
+ for (let i = 0; i < dimLen; i++) {
+ const dim = dimensions[i];
+ if (!rawExtent[i]) {
+ rawExtent[i] = getInitialExtent();
+ }
+ prepareStorage(chunks, i, dim.type, end, append);
+ }
+
+ if (provider.fillStorage) {
+ provider.fillStorage(start, end, chunks, rawExtent);
+ }
+ else {
+ let dataItem = [] as OptionDataItem;
+ for (let idx = start; idx < end; idx++) {
+ // NOTICE: Try not to write things into dataItem
+ dataItem = provider.getItem(idx, dataItem);
+ // Each data item is value
+ // [1, 2]
+ // 2
+ // Bar chart, line chart which uses category axis
+ // only gives the 'y' value. 'x' value is the indices of category
+ // Use a tempValue to normalize the value to be a (x, y) value
+
+ // Store the data by dimensions
+ for (let dimIdx = 0; dimIdx < dimLen; dimIdx++) {
+ const dimStorage = chunks[dimIdx];
+ // PENDING NULL is empty or zero
+ const val = this._dimValueGetter(
+ dataItem, dimNames[dimIdx], idx, dimIdx
+ ) as ParsedValueNumeric;
+ (dimStorage as ParsedValue[])[idx] = val;
+
+ const dimRawExtent = rawExtent[dimIdx];
+ val < dimRawExtent[0] && (dimRawExtent[0] = val);
+ val > dimRawExtent[1] && (dimRawExtent[1] = val);
+ }
+ }
+ }
+
+ if (!provider.persistent && provider.clean) {
+ // Clean unused data if data source is typed array.
+ provider.clean();
+ }
+
+ this._rawCount = this._count = end;
+ // Reset data extent
+ this._extent = [];
+ }
+
+ count(): number {
+ return this._count;
+ }
+
+ /**
+ * Get value. Return NaN if idx is out of range.
+ */
+ get(dim: number, idx: number): ParsedValue {
+ if (!(idx >= 0 && idx < this._count)) {
+ return NaN;
+ }
+ const dimStore = this._chunks[dim];
+ return dimStore ? dimStore[this.getRawIndex(idx)] : NaN;
+ }
+
+ /**
+ * @param dim concrete dim
+ */
+ getByRawIndex(dim: number, rawIdx: number): ParsedValue {
+ if (!(rawIdx >= 0 && rawIdx < this._rawCount)) {
+ return NaN;
+ }
+ const dimStore = this._chunks[dim];
+ return dimStore ? dimStore[rawIdx] : NaN;
+ }
+
+ /**
+ * Get sum of data in one dimension
+ */
+ getSum(dim: DimensionIndex): number {
+ const dimData = this._chunks[dim];
+ let sum = 0;
+ if (dimData) {
+ for (let i = 0, len = this.count(); i < len; i++) {
+ const value = this.get(dim, i) as number;
+ if (!isNaN(value)) {
+ sum += value;
+ }
+ }
+ }
+ return sum;
+ }
+
+ /**
+ * Get median of data in one dimension
+ */
+ getMedian(dim: DimensionIndex): number {
+ const dimDataArray: ParsedValue[] = [];
+ // map all data of one dimension
+ this.each([dim], function (val) {
+ if (!isNaN(val as number)) {
+ dimDataArray.push(val);
+ }
+ });
+
+ // TODO
+ // Use quick select?
+ const sortedDimDataArray = dimDataArray.sort(function (a: number, b: number) {
+ return a - b;
+ }) as number[];
+ const len = this.count();
+ // calculate median
+ return len === 0
+ ? 0
+ : len % 2 === 1
+ ? sortedDimDataArray[(len - 1) / 2]
+ : (sortedDimDataArray[len / 2] + sortedDimDataArray[len / 2 - 1]) / 2;
+ }
+
+ /**
+ * Retreive the index with given raw data index
+ */
+ indexOfRawIndex(rawIndex: number): number {
+ if (rawIndex >= this._rawCount || rawIndex < 0) {
+ return -1;
+ }
+
+ if (!this._indices) {
+ return rawIndex;
+ }
+
+ // Indices are ascending
+ const indices = this._indices;
+
+ // If rawIndex === dataIndex
+ const rawDataIndex = indices[rawIndex];
+ if (rawDataIndex != null && rawDataIndex < this._count && rawDataIndex === rawIndex) {
+ return rawIndex;
+ }
+
+ let left = 0;
+ let right = this._count - 1;
+ while (left <= right) {
+ const mid = (left + right) / 2 | 0;
+ if (indices[mid] < rawIndex) {
+ left = mid + 1;
+ }
+ else if (indices[mid] > rawIndex) {
+ right = mid - 1;
+ }
+ else {
+ return mid;
+ }
+ }
+ return -1;
+ }
+
+
+ /**
+ * Retreive the index of nearest value
+ * @param dim
+ * @param value
+ * @param [maxDistance=Infinity]
+ * @return If and only if multiple indices has
+ * the same value, they are put to the result.
+ */
+ indicesOfNearest(
+ dim: DimensionIndex, value: number, maxDistance?: number
+ ): number[] {
+ const chunks = this._chunks;
+ const dimData = chunks[dim];
+ const nearestIndices: number[] = [];
+
+ if (!dimData) {
+ return nearestIndices;
+ }
+
+ if (maxDistance == null) {
+ maxDistance = Infinity;
+ }
+
+ let minDist = Infinity;
+ let minDiff = -1;
+ let nearestIndicesLen = 0;
+
+ // Check the test case of `test/ut/spec/data/SeriesData.js`.
+ for (let i = 0, len = this.count(); i < len; i++) {
+ const dataIndex = this.getRawIndex(i);
+ const diff = value - (dimData[dataIndex] as number);
+ const dist = Math.abs(diff);
+ if (dist <= maxDistance) {
+ // When the `value` is at the middle of `this.get(dim, i)` and `this.get(dim, i+1)`,
+ // we'd better not push both of them to `nearestIndices`, otherwise it is easy to
+ // get more than one item in `nearestIndices` (more specifically, in `tooltip`).
+ // So we chose the one that `diff >= 0` in this csae.
+ // But if `this.get(dim, i)` and `this.get(dim, j)` get the same value, both of them
+ // should be push to `nearestIndices`.
+ if (dist < minDist
+ || (dist === minDist && diff >= 0 && minDiff < 0)
+ ) {
+ minDist = dist;
+ minDiff = diff;
+ nearestIndicesLen = 0;
+ }
+ if (diff === minDiff) {
+ nearestIndices[nearestIndicesLen++] = i;
+ }
+ }
+ }
+ nearestIndices.length = nearestIndicesLen;
+
+ return nearestIndices;
+ }
+
+ getIndices(): ArrayLike<number> {
+ let newIndices;
+
+ const indices = this._indices;
+ if (indices) {
+ const Ctor = indices.constructor as DataArrayLikeConstructor;
+ const thisCount = this._count;
+ // `new Array(a, b, c)` is different from `new Uint32Array(a, b, c)`.
+ if (Ctor === Array) {
+ newIndices = new Ctor(thisCount);
+ for (let i = 0; i < thisCount; i++) {
+ newIndices[i] = indices[i];
+ }
+ }
+ else {
+ newIndices = new (Ctor as DataTypedArrayConstructor)(
+ (indices as DataTypedArray).buffer, 0, thisCount
+ );
+ }
+ }
+ else {
+ const Ctor = getIndicesCtor(this._rawCount);
+ newIndices = new Ctor(this.count());
+ for (let i = 0; i < newIndices.length; i++) {
+ newIndices[i] = i;
+ }
+ }
+
+ return newIndices;
+ }
+
+ /**
+ * Data filter
+ */
+ filterSelf(
+ dims: DimensionIndex[],
+ cb: FilterCb
+ ) {
+ if (!this._count) {
+ return;
+ }
+
+ const count = this.count();
+ const Ctor = getIndicesCtor(this._rawCount);
+ const newIndices = new Ctor(count);
+ const value = [];
+ const dimSize = dims.length;
+
+ let offset = 0;
+ const dim0 = dims[0];
+ const chunks = this._chunks;
+
+ for (let i = 0; i < count; i++) {
+ let keep;
+ const rawIdx = this.getRawIndex(i);
+ // Simple optimization
+ if (dimSize === 0) {
+ keep = (cb as FilterCb0)(i);
+ }
+ else if (dimSize === 1) {
+ const val = chunks[dim0][rawIdx];
+ keep = (cb as FilterCb1)(val, i);
+ }
+ else {
+ let k = 0;
+ for (; k < dimSize; k++) {
+ value[k] = chunks[dims[k]][rawIdx];
+ }
+ value[k] = i;
+ keep = (cb as FilterCb).apply(null, value);
+ }
+ if (keep) {
+ newIndices[offset++] = rawIdx;
+ }
+ }
+
+ // Set indices after filtered.
+ if (offset < count) {
+ this._indices = newIndices;
+ }
+ this._count = offset;
+ // Reset data extent
+ this._extent = [];
+
+ this._updateGetRawIdx();
+ }
+
+ /**
+ * Select data in range. (For optimization of filter)
+ * (Manually inline code, support 5 million data filtering in data zoom.)
+ */
+ selectRange(range: {[dimIdx: number]: [number, number]}) {
+
+ const len = this._count;
+
+ if (!len) {
+ return;
+ }
+
+ const dims = keys(range);
+ const dimSize = dims.length;
+ if (!dimSize) {
+ return;
+ }
+
+ const originalCount = this.count();
+ const Ctor = getIndicesCtor(this._rawCount);
+ const newIndices = new Ctor(originalCount);
+
+ let offset = 0;
+ const dim0 = dims[0];
+
+ const min = range[dim0][0];
+ const max = range[dim0][1];
+ const storeArr = this._chunks;
+
+ let quickFinished = false;
+ if (!this._indices) {
+ // Extreme optimization for common case. About 2x faster in chrome.
+ let idx = 0;
+ if (dimSize === 1) {
+ const dimStorage = storeArr[dims[0]];
+ for (let i = 0; i < len; i++) {
+ const val = dimStorage[i];
+ // NaN will not be filtered. Consider the case, in line chart, empty
+ // value indicates the line should be broken. But for the case like
+ // scatter plot, a data item with empty value will not be rendered,
+ // but the axis extent may be effected if some other dim of the data
+ // item has value. Fortunately it is not a significant negative effect.
+ if (
+ (val >= min && val <= max) || isNaN(val as any)
+ ) {
+ newIndices[offset++] = idx;
+ }
+ idx++;
+ }
+ quickFinished = true;
+ }
+ else if (dimSize === 2) {
+ const dimStorage = storeArr[dims[0]];
+ const dimStorage2 = storeArr[dims[1]];
+ const min2 = range[dims[1]][0];
+ const max2 = range[dims[1]][1];
+ for (let i = 0; i < len; i++) {
+ const val = dimStorage[i];
+ const val2 = dimStorage2[i];
+ // Do not filter NaN, see comment above.
+ if ((
+ (val >= min && val <= max) || isNaN(val as any)
+ )
+ && (
+ (val2 >= min2 && val2 <= max2) || isNaN(val2 as any)
+ )
+ ) {
+ newIndices[offset++] = idx;
+ }
+ idx++;
+ }
+ quickFinished = true;
+ }
+ }
+ if (!quickFinished) {
+ if (dimSize === 1) {
+ for (let i = 0; i < originalCount; i++) {
+ const rawIndex = this.getRawIndex(i);
+ const val = storeArr[dims[0]][rawIndex];
+ // Do not filter NaN, see comment above.
+ if (
+ (val >= min && val <= max) || isNaN(val as any)
+ ) {
+ newIndices[offset++] = rawIndex;
+ }
+ }
+ }
+ else {
+ for (let i = 0; i < originalCount; i++) {
+ let keep = true;
+ const rawIndex = this.getRawIndex(i);
+ for (let k = 0; k < dimSize; k++) {
+ const dimk = dims[k];
+ const val = storeArr[dimk][rawIndex];
+ // Do not filter NaN, see comment above.
+ if (val < range[dimk][0] || val > range[dimk][1]) {
+ keep = false;
+ }
+ }
+ if (keep) {
+ newIndices[offset++] = this.getRawIndex(i);
+ }
+ }
+ }
+ }
+
+ // Set indices after filtered.
+ if (offset < originalCount) {
+ this._indices = newIndices;
+ }
+ this._count = offset;
+ // Reset data extent
+ this._extent = [];
+
+ this._updateGetRawIdx();
+ }
+
+ /**
+ * Data mapping to a plain array
+ */
+ /* eslint-enable */
+ mapArray(dims: DimensionIndex[], cb: MapArrayCb): any[] {
+ const result: any[] = [];
+ this.each(dims, function () {
+ result.push(cb && (cb as MapArrayCb).apply(null, arguments));
+ });
+ return result;
+ }
+
+ /**
+ * Data mapping to a new List with given dimensions
+ */
+ map(dims: DimensionIndex[], cb: MapCb): DataStorage {
+ // TODO only clone picked chunks.
+ const target = this.clone(dims);
+ const targetChunks = target._chunks;
+
+ // Following properties are all immutable.
+ // So we can reference to the same value
+ target._indices = this._indices;
+ target.getRawIndex = this.getRawIndex;
+
+ const tmpRetValue = [];
+ const dimSize = dims.length;
+ const dataCount = this.count();
+ const values = [];
+ const rawExtent = target._rawExtent;
+
+ for (let dataIndex = 0; dataIndex < dataCount; dataIndex++) {
+ const rawIndex = this.getRawIndex(dataIndex);
+
+ for (let k = 0; k < dimSize; k++) {
+ values[k] = targetChunks[dims[k]][rawIndex];
+ }
+ values[dimSize] = dataIndex;
+
+ let retValue = cb && cb.apply(null, values);
+ if (retValue != null) {
+ // a number or string (in oridinal dimension)?
+ if (typeof retValue !== 'object') {
+ tmpRetValue[0] = retValue;
+ retValue = tmpRetValue;
+ }
+
+ for (let i = 0; i < retValue.length; i++) {
+ const dim = dims[i];
+ const val = retValue[i];
+ const rawExtentOnDim = rawExtent[dim];
+
+ const dimStore = targetChunks[dim];
+ if (dimStore) {
+ (dimStore as ParsedValue[])[rawIndex] = val;
+ }
+
+ if (val < rawExtentOnDim[0]) {
+ rawExtentOnDim[0] = val as number;
+ }
+ if (val > rawExtentOnDim[1]) {
+ rawExtentOnDim[1] = val as number;
+ }
+ }
+ }
+ }
+
+ return target;
+ }
+
+ /**
+ * Large data down sampling using largest-triangle-three-buckets
+ * @param {string} valueDimension
+ * @param {number} targetCount
+ */
+ lttbDownSample(
+ valueDimension: DimensionIndex,
+ rate: number
+ ) {
+ const target = this.clone([valueDimension]);
+ const targetStorage = target._chunks;
+ const dimStore = targetStorage[valueDimension];
+ const len = this.count();
+ const newIndices = new (getIndicesCtor(this._rawCount))(len);
+
+ let sampledIndex = 0;
+
+ const frameSize = Math.floor(1 / rate);
+
+ let currentRawIndex = this.getRawIndex(0);
+ let maxArea;
+ let area;
+ let nextRawIndex;
+
+ // First frame use the first data.
+ newIndices[sampledIndex++] = currentRawIndex;
+ for (let i = 1; i < len - 1; i += frameSize) {
+ const nextFrameStart = Math.min(i + frameSize, len - 1);
+ const nextFrameEnd = Math.min(i + frameSize * 2, len);
+
+ const avgX = (nextFrameEnd + nextFrameStart) / 2;
+ let avgY = 0;
+
+ for (let idx = nextFrameStart; idx < nextFrameEnd; idx++) {
+ const rawIndex = this.getRawIndex(idx);
+ const y = dimStore[rawIndex] as number;
+ if (isNaN(y)) {
+ continue;
+ }
+ avgY += y as number;
+ }
+ avgY /= (nextFrameEnd - nextFrameStart);
+
+ const frameStart = i;
+ const frameEnd = Math.min(i + frameSize, len);
+
+ const pointAX = i - 1;
+ const pointAY = dimStore[currentRawIndex] as number;
+
+ maxArea = -1;
+
+ nextRawIndex = frameStart;
+ // Find a point from current frame that construct a triangel with largest area with previous selected point
+ // And the average of next frame.
+ for (let idx = frameStart; idx < frameEnd; idx++) {
+ const rawIndex = this.getRawIndex(idx);
+ const y = dimStore[rawIndex] as number;
+ if (isNaN(y)) {
+ continue;
+ }
+ // Calculate triangle area over three buckets
+ area = Math.abs((pointAX - avgX) * (y - pointAY)
+ - (pointAX - idx) * (avgY - pointAY)
+ );
+ if (area > maxArea) {
+ maxArea = area;
+ nextRawIndex = rawIndex; // Next a is this b
+ }
+ }
+
+ newIndices[sampledIndex++] = nextRawIndex;
+
+ currentRawIndex = nextRawIndex; // This a is the next a (chosen b)
+ }
+
+ // First frame use the last data.
+ newIndices[sampledIndex++] = this.getRawIndex(len - 1);
+ target._count = sampledIndex;
+ target._indices = newIndices;
+
+ target.getRawIndex = this._getRawIdx;
+ return target;
+ }
+
+
+ /**
+ * Large data down sampling on given dimension
+ * @param sampleIndex Sample index for name and id
+ */
+ downSample(
+ dimension: DimensionIndex,
+ rate: number,
+ sampleValue: (frameValues: ArrayLike<ParsedValue>) => ParsedValueNumeric,
+ sampleIndex: (frameValues: ArrayLike<ParsedValue>, value: ParsedValueNumeric) => number
+ ): DataStorage {
+ const target = this.clone([dimension]);
+ const targetStorage = target._chunks;
+
+ const frameValues = [];
+ let frameSize = Math.floor(1 / rate);
+
+ const dimStore = targetStorage[dimension];
+ const len = this.count();
+ const rawExtentOnDim = target._rawExtent[dimension];
+
+ const newIndices = new (getIndicesCtor(this._rawCount))(len);
+
+ let offset = 0;
+ for (let i = 0; i < len; i += frameSize) {
+ // Last frame
+ if (frameSize > len - i) {
+ frameSize = len - i;
+ frameValues.length = frameSize;
+ }
+ for (let k = 0; k < frameSize; k++) {
+ const dataIdx = this.getRawIndex(i + k);
+ frameValues[k] = dimStore[dataIdx];
+ }
+ const value = sampleValue(frameValues);
+ const sampleFrameIdx = this.getRawIndex(
+ Math.min(i + sampleIndex(frameValues, value) || 0, len - 1)
+ );
+ // Only write value on the filtered data
+ (dimStore as number[])[sampleFrameIdx] = value;
+
+ if (value < rawExtentOnDim[0]) {
+ rawExtentOnDim[0] = value;
+ }
+ if (value > rawExtentOnDim[1]) {
+ rawExtentOnDim[1] = value;
+ }
+
+ newIndices[offset++] = sampleFrameIdx;
+ }
+
+ target._count = offset;
+
+ this._updateGetRawIdx();
+
+ return target;
+ }
+
+ /**
+ * Data iteration
+ * @param ctx default this
+ * @example
+ * list.each('x', function (x, idx) {});
+ * list.each(['x', 'y'], function (x, y, idx) {});
+ * list.each(function (idx) {})
+ */
+ each(dims: DimensionIndex[], cb: EachCb): void {
+ if (!this._count) {
+ return;
+ }
+ const dimSize = dims.length;
+ const chunks = this._chunks;
+
+ for (let i = 0, len = this.count(); i < len; i++) {
+ const rawIdx = this.getRawIndex(i);
+ // Simple optimization
+ switch (dimSize) {
+ case 0:
+ (cb as EachCb0)(i);
+ break;
+ case 1:
+ (cb as EachCb1)(chunks[dims[0]][rawIdx], i);
+ break;
+ case 2:
+ (cb as EachCb2)(
+ chunks[dims[0]][rawIdx], chunks[dims[1]][rawIdx], i
+ );
+ break;
+ default:
+ let k = 0;
+ const value = [];
+ for (; k < dimSize; k++) {
+ value[k] = chunks[dims[k]][rawIdx];
+ }
+ // Index
+ value[k] = i;
+ (cb as EachCb).apply(null, value);
+ }
+ }
+ }
+
+ /**
+ * Get extent of data in one dimension
+ */
+ getDataExtent(dim: DimensionIndex): [number, number] {
+ // Make sure use concrete dim as cache name.
+ const dimData = this._chunks[dim];
+ const initialExtent = getInitialExtent();
+
+ if (!dimData) {
+ return initialExtent;
+ }
+
+ // Make more strict checkings to ensure hitting cache.
+ const currEnd = this.count();
+
+ // Consider the most cases when using data zoom, `getDataExtent`
+ // happened before filtering. We cache raw extent, which is not
+ // necessary to be cleared and recalculated when restore data.
+ const useRaw = !this._indices;
+ let dimExtent: [number, number];
+
+ if (useRaw) {
+ return this._rawExtent[dim].slice() as [number, number];
+ }
+ dimExtent = this._extent[dim];
+ if (dimExtent) {
+ return dimExtent.slice() as [number, number];
+ }
+ dimExtent = initialExtent;
+
+ let min = dimExtent[0];
+ let max = dimExtent[1];
+
+ for (let i = 0; i < currEnd; i++) {
+ const rawIdx = this.getRawIndex(i);
+ const value = dimData[rawIdx] as ParsedValueNumeric;
+ value < min && (min = value);
+ value > max && (max = value);
+ }
+
+ dimExtent = [min, max];
+
+ this._extent[dim] = dimExtent;
+
+ return dimExtent;
+ }
+
+ /**
+ * Get raw data index.
+ * Do not initialize.
+ * Default `getRawIndex`. And it can be changed.
+ */
+ getRawIndex: (idx: number) => number;
+
+ /**
+ * Get raw data item
+ */
+ getRawDataItem(idx: number): OptionDataItem {
+ const rawIdx = this.getRawIndex(idx);
+ if (!this._provider.persistent) {
+ const val = [];
+ const chunks = this._chunks;
+ for (let i = 0; i < chunks.length; i++) {
+ val.push(chunks[i][rawIdx]);
+ }
+ return val;
+ }
+ else {
+ return this._provider.getItem(this.getRawIndex(idx));
+ }
+ }
+
+ /**
+ *
+ * @param clonedDims Determine which dims to clone. Will share the data if not specified.
+ */
+ clone(clonedDims?: number[]): DataStorage {
+ const target = new DataStorage();
+ const chunks = this._chunks;
+ const clonedDimsMap = clonedDims && reduce(clonedDims, (obj, dimIdx) => {
+ obj[dimIdx] = true;
+ return obj;
+ }, {} as Record<string, boolean>);
+
+ if (clonedDimsMap) {
+ for (let i = 0; i < chunks.length; i++) {
+ // Not clone if dim is not picked.
+ target._chunks[i] = (clonedDimsMap && !clonedDimsMap[i])
+ ? chunks[i] : cloneChunk(chunks[i]);
+ }
+ }
+ else {
+ target._chunks = chunks;
+ }
+ this._copyCommonProps(target);
+ return target;
+ }
+
+ /**
+ * Get category data.
+ */
+ getCategory(dimIdx: number, idx: number) {
+ const rawIdx = this.getRawIndex(idx);
+ const chunk = this._chunks[dimIdx];
+
+ let val;
+ if (chunk) {
+ const dimInfo = this._dimensions[dimIdx];
+ const ordinalMeta = dimInfo.ordinalMeta;
+ val = chunk[rawIdx];
+ if (ordinalMeta) {
+ val = ordinalMeta.categories[val as OrdinalNumber];
+ }
+ }
+ return val;
+ }
+
+ private _copyCommonProps(target: DataStorage) {
+ target._count = this._count;
+ target._rawCount = this._rawCount;
+ target._extent = clone(this._extent);
+ target._rawExtent = clone(this._rawExtent);
+ target._indices = this._cloneIndices();
+ target._provider = this._provider;
+ target.getDimensionIndex = this.getDimensionIndex;
+ target._updateGetRawIdx();
+ }
+
+ private _cloneIndices() {
+ if (this._indices) {
+ const Ctor = this._indices.constructor as DataArrayLikeConstructor;
+ let indices;
+ if (Ctor === Array) {
+ const thisCount = this._indices.length;
+ indices = new Ctor(thisCount);
+ for (let i = 0; i < thisCount; i++) {
+ indices[i] = this._indices[i];
+ }
+ }
+ else {
+ indices = new (Ctor as DataTypedArrayConstructor)(this._indices);
+ }
+ return indices;
+ }
+ return null;
+ }
+
+ private _getRawIdxIdentity(idx: number) {
+ return idx;
+ }
+ private _getRawIdx(idx: number) {
+ if (idx < this._count && idx >= 0) {
+ return this._indices[idx];
+ }
+ return -1;
+ }
+
+ private _updateGetRawIdx() {
+ this.getRawIndex = this._indices ? this._getRawIdx : this._getRawIdxIdentity;
+ }
+
+ private static internalField = (function () {
+
+ function getDimValueSimply(
+ this: DataStorage, dataItem: any, dimName: string, dataIndex: number, dimIndex: number
+ ): ParsedValue {
+ return parseDataValue(dataItem[dimIndex], this._dimensions[dimIndex]);
+ }
+
+ defaultDimValueGetters = {
+
+ arrayRows: getDimValueSimply,
+
+ objectRows(
+ this: DataStorage, dataItem: any, dimName: string, dataIndex: number, dimIndex: number
+ ): ParsedValue {
+ return parseDataValue(dataItem[dimIndex], this._dimensions[dataIndex]);
+ },
+
+ keyedColumns: getDimValueSimply,
+
+ original(
+ this: DataStorage, dataItem: any, dimName: string, dataIndex: number, dimIndex: number
+ ): ParsedValue {
+ // Performance sensitive, do not use modelUtil.getDataItemValue.
+ // If dataItem is an plain object with no value field, the let `value`
+ // will be assigned with the object, but it will be tread correctly
+ // in the `convertValue`.
+ const value = dataItem && (dataItem.value == null ? dataItem : dataItem.value);
+
+ return parseDataValue(
+ (value instanceof Array)
+ ? value[dimIndex]
+ // If value is a single number or something else not array.
+ : value,
+ this._dimensions[dimIndex]
+ );
+ },
+
+ typedArray: function (
+ this: DataStorage, dataItem: any, dimName: string, dataIndex: number, dimIndex: number
+ ): ParsedValue {
+ return dataItem[dimIndex];
+ }
+
+ };
+
+ })();
+}
+
+export default DataStorage;
\ No newline at end of file
diff --git a/src/data/Graph.ts b/src/data/Graph.ts
index 75ec38f..0ab5f21 100644
--- a/src/data/Graph.ts
+++ b/src/data/Graph.ts
@@ -19,7 +19,7 @@
import * as zrUtil from 'zrender/src/core/util';
import { Dictionary } from 'zrender/src/core/types';
-import List from './List';
+import SeriesData from './SeriesData';
import Model from '../model/Model';
import Element from 'zrender/src/Element';
import { DimensionLoose, ParsedValue } from '../util/types';
@@ -36,9 +36,9 @@ class Graph {
readonly edges: GraphEdge[] = [];
- data: List;
+ data: SeriesData;
- edgeData: List;
+ edgeData: SeriesData;
/**
* Whether directed graph.
diff --git a/src/data/List.ts b/src/data/List.ts
deleted file mode 100644
index 0ad2792..0000000
--- a/src/data/List.ts
+++ /dev/null
@@ -1,2278 +0,0 @@
-/*
-* 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.
-*/
-
-/* global Float64Array, Int32Array, Uint32Array, Uint16Array */
-
-/**
- * List for data storage
- */
-
-import * as zrUtil from 'zrender/src/core/util';
-import {PathStyleProps} from 'zrender/src/graphic/Path';
-import Model from '../model/Model';
-import DataDiffer from './DataDiffer';
-import {DefaultDataProvider, DataProvider} from './helper/dataProvider';
-import {summarizeDimensions, DimensionSummary} from './helper/dimensionHelper';
-import DataDimensionInfo from './DataDimensionInfo';
-import {ArrayLike, Dictionary, FunctionPropertyNames} from 'zrender/src/core/types';
-import Element from 'zrender/src/Element';
-import {
- DimensionIndex, DimensionName, DimensionLoose, OptionDataItem,
- ParsedValue, ParsedValueNumeric, OrdinalNumber, DimensionUserOuput,
- ModelOption, SeriesDataType, OptionSourceData, SOURCE_FORMAT_TYPED_ARRAY, SOURCE_FORMAT_ORIGINAL,
- DecalObject
-} from '../util/types';
-import {isDataItemOption, convertOptionIdName} from '../util/model';
-import { getECData } from '../util/innerStore';
-import type Graph from './Graph';
-import type Tree from './Tree';
-import type { VisualMeta } from '../component/visualMap/VisualMapModel';
-import { parseDataValue } from './helper/dataValueHelper';
-import {isSourceInstance, Source} from './Source';
-import OrdinalMeta from './OrdinalMeta';
-import { LineStyleProps } from '../model/mixin/lineStyle';
-
-const mathFloor = Math.floor;
-const isObject = zrUtil.isObject;
-const map = zrUtil.map;
-
-const UNDEFINED = 'undefined';
-const INDEX_NOT_FOUND = -1;
-
-// Use prefix to avoid index to be the same as otherIdList[idx],
-// which will cause weird udpate animation.
-const ID_PREFIX = 'e\0\0';
-
-const dataCtors = {
- 'float': typeof Float64Array === UNDEFINED
- ? Array : Float64Array,
- 'int': typeof Int32Array === UNDEFINED
- ? Array : Int32Array,
- // Ordinal data type can be string or int
- 'ordinal': Array,
- 'number': Array,
- 'time': Array
-};
-
-export type ListDimensionType = keyof typeof dataCtors;
-
-// Caution: MUST not use `new CtorUint32Array(arr, 0, len)`, because the Ctor of array is
-// different from the Ctor of typed array.
-const CtorUint32Array = typeof Uint32Array === UNDEFINED ? Array : Uint32Array;
-const CtorInt32Array = typeof Int32Array === UNDEFINED ? Array : Int32Array;
-const CtorUint16Array = typeof Uint16Array === UNDEFINED ? Array : Uint16Array;
-
-type DataTypedArray = Uint32Array | Int32Array | Uint16Array | Float64Array;
-type DataTypedArrayConstructor = typeof Uint32Array | typeof Int32Array | typeof Uint16Array | typeof Float64Array;
-type DataArrayLikeConstructor = typeof Array | DataTypedArrayConstructor;
-
-
-type DimValueGetter = (
- this: List,
- dataItem: any,
- dimName: DimensionName,
- dataIndex: number,
- dimIndex: DimensionIndex
-) => ParsedValue;
-
-type DataValueChunk = ArrayLike<ParsedValue>;
-type DataStorage = {[dimName: string]: DataValueChunk};
-type NameRepeatCount = {[name: string]: number};
-
-
-type ItrParamDims = DimensionLoose | Array<DimensionLoose>;
-// If Ctx not specified, use List as Ctx
-type CtxOrList<Ctx> = unknown extends Ctx ? List : Ctx;
-type EachCb0<Ctx> = (this: CtxOrList<Ctx>, idx: number) => void;
-type EachCb1<Ctx> = (this: CtxOrList<Ctx>, x: ParsedValue, idx: number) => void;
-type EachCb2<Ctx> = (this: CtxOrList<Ctx>, x: ParsedValue, y: ParsedValue, idx: number) => void;
-type EachCb<Ctx> = (this: CtxOrList<Ctx>, ...args: any) => void;
-type FilterCb0<Ctx> = (this: CtxOrList<Ctx>, idx: number) => boolean;
-type FilterCb1<Ctx> = (this: CtxOrList<Ctx>, x: ParsedValue, idx: number) => boolean;
-type FilterCb2<Ctx> = (this: CtxOrList<Ctx>, x: ParsedValue, y: ParsedValue, idx: number) => boolean;
-type FilterCb<Ctx> = (this: CtxOrList<Ctx>, ...args: any) => boolean;
-type MapArrayCb0<Ctx> = (this: CtxOrList<Ctx>, idx: number) => any;
-type MapArrayCb1<Ctx> = (this: CtxOrList<Ctx>, x: ParsedValue, idx: number) => any;
-type MapArrayCb2<Ctx> = (this: CtxOrList<Ctx>, x: ParsedValue, y: ParsedValue, idx: number) => any;
-type MapArrayCb<Ctx> = (this: CtxOrList<Ctx>, ...args: any) => any;
-type MapCb1<Ctx> = (this: CtxOrList<Ctx>, x: ParsedValue, idx: number) => ParsedValue | ParsedValue[];
-type MapCb2<Ctx> = (this: CtxOrList<Ctx>, x: ParsedValue, y: ParsedValue, idx: number) =>
- ParsedValue | ParsedValue[];
-type MapCb<Ctx> = (this: CtxOrList<Ctx>, ...args: any) => ParsedValue | ParsedValue[];
-
-
-const TRANSFERABLE_PROPERTIES = [
- 'hasItemOption', '_nameList', '_idList', '_invertedIndicesMap',
- '_rawData', '_dimValueGetter',
- '_count', '_rawCount', '_nameDimIdx', '_idDimIdx', '_nameRepeatCount'
-];
-const CLONE_PROPERTIES = [
- '_extent', '_approximateExtent', '_rawExtent'
-];
-
-export interface DefaultDataVisual {
- style: PathStyleProps
- // Draw type determined which prop should be set with encoded color.
- // It's only available on the global visual. Use getVisual('drawType') to access it.
- // It will be set in visual/style.ts module in the first priority.
- drawType: 'fill' | 'stroke'
-
- symbol?: string
- symbolSize?: number | number[]
- symbolRotate?: number
- symbolKeepAspect?: boolean
- symbolOffset?: string | number | (string | number)[]
-
- liftZ?: number
- // For legend.
- legendIcon?: string
- legendLineStyle?: LineStyleProps
-
- // visualMap will inject visualMeta data
- visualMeta?: VisualMeta[]
-
- // If color is encoded from palette
- colorFromPalette?: boolean
-
- decal?: DecalObject
-}
-
-export interface DataCalculationInfo<SERIES_MODEL> {
- stackedDimension: string;
- stackedByDimension: string;
- isStackedByIndex: boolean;
- stackedOverDimension: string;
- stackResultDimension: string;
- stackedOnSeries?: SERIES_MODEL;
-}
-
-// -----------------------------
-// Internal method declarations:
-// -----------------------------
-let defaultDimValueGetters: {[sourceFormat: string]: DimValueGetter};
-let prepareInvertedIndex: (list: List) => void;
-let getIndicesCtor: (list: List) => DataArrayLikeConstructor;
-let prepareStorage: (
- storage: DataStorage, dimInfo: DataDimensionInfo, end: number, append?: boolean
-) => void;
-let getRawIndexWithoutIndices: (this: List, idx: number) => number;
-let getRawIndexWithIndices: (this: List, idx: number) => number;
-let getId: (list: List, rawIndex: number) => string;
-let getIdNameFromStore: (list: List, dimIdx: number, ordinalMeta: OrdinalMeta, rawIndex: number) => string;
-let makeIdFromName: (list: List, idx: number) => void;
-let normalizeDimensions: (dimensions: ItrParamDims) => Array<DimensionLoose>;
-let validateDimensions: (list: List, dims: DimensionName[]) => void;
-let cloneListForMapAndSample: (original: List, excludeDimensions: DimensionName[]) => List;
-let getInitialExtent: () => [number, number];
-let setItemDataAndSeriesIndex: (this: Element, child: Element) => void;
-let transferProperties: (target: List, source: List) => void;
-
-
-class List<
- HostModel extends Model = Model,
- Visual extends DefaultDataVisual = DefaultDataVisual
-> {
-
- readonly type = 'list';
-
- readonly dimensions: string[];
-
- // Infomation of each data dimension, like data type.
- private _dimensionInfos: {[dimName: string]: DataDimensionInfo};
-
- readonly hostModel: HostModel;
-
- /**
- * @readonly
- */
- dataType: SeriesDataType;
-
- /**
- * @readonly
- * Host graph if List is used to store graph nodes / edges.
- */
- graph?: Graph;
-
- /**
- * @readonly
- * Host tree if List is used to store tree ndoes.
- */
- tree?: Tree;
-
- // Indices stores the indices of data subset after filtered.
- // This data subset will be used in chart.
- private _indices: ArrayLike<any>;
-
- private _count: number = 0;
- private _rawCount: number = 0;
- private _storage: DataStorage = {};
- // We have an extra array store here. It's faster to be acessed than KV structured `_storage`.
- // We profile the code `storage[dim]` and it seems to be KeyedLoadIC_Megamorphic instead of fast property access.
- // Not sure why this happens. But using an extra array seems leads to faster `initData`
- // See https://github.com/apache/incubator-echarts/pull/13314 for more explanation.
- private _storageArr: DataValueChunk[] = [];
- private _nameList: string[] = [];
- private _idList: string[] = [];
-
- // Models of data option is stored sparse for optimizing memory cost
- // Never used yet (not used yet).
- // private _optionModels: Model[] = [];
-
- // Global visual properties after visual coding
- private _visual: Dictionary<any> = {};
-
- // Globel layout properties.
- private _layout: Dictionary<any> = {};
-
- // Item visual properties after visual coding
- private _itemVisuals: Dictionary<any>[] = [];
-
- // Item layout properties after layout
- private _itemLayouts: any[] = [];
-
- // Graphic elemnents
- private _graphicEls: Element[] = [];
-
- private _rawData: DataProvider;
-
- // Raw extent will not be cloned, but only transfered.
- // It will not be calculated util needed.
- private _rawExtent: {[dimName: string]: [number, number]} = {};
-
- private _extent: {[dimName: string]: [number, number]} = {};
-
- // key: dim, value: extent
- private _approximateExtent: {[dimName: string]: [number, number]} = {};
-
- private _dimensionsSummary: DimensionSummary;
-
- private _invertedIndicesMap: {[dimName: string]: ArrayLike<number>};
-
- private _calculationInfo: DataCalculationInfo<HostModel> = {} as DataCalculationInfo<HostModel>;
-
- // User output info of this data.
- // DO NOT use it in other places!
- // When preparing user params for user callbacks, we have
- // to clone these inner data structures to prevent users
- // from modifying them to effect built-in logic. And for
- // performance consideration we make this `userOutput` to
- // avoid clone them too many times.
- readonly userOutput: DimensionUserOuput;
-
- // Having detected that there is data item is non primitive type
- // (in type `OptionDataItemObject`).
- // Like `data: [ { value: xx, itemStyle: {...} }, ...]`
- // At present it only happen in `SOURCE_FORMAT_ORIGINAL`.
- hasItemOption: boolean = true;
-
- // @readonly
- defaultDimValueGetter: DimValueGetter;
- private _dimValueGetter: DimValueGetter;
- private _dimValueGetterArrayRows: DimValueGetter;
-
- // id or name is used on dynamic data, mapping old and new items.
- // When generating id from name, avoid repeat.
- private _nameRepeatCount: NameRepeatCount;
- private _nameDimIdx: number;
- private _nameOrdinalMeta: OrdinalMeta;
- private _idDimIdx: number;
- private _idOrdinalMeta: OrdinalMeta;
- private _dontMakeIdFromName: boolean;
-
- private __wrappedMethods: string[];
-
- // Methods that create a new list based on this list should be listed here.
- // Notice that those method should `RETURN` the new list.
- TRANSFERABLE_METHODS = ['cloneShallow', 'downSample', 'lttbDownSample', 'map'] as const;
- // Methods that change indices of this list should be listed here.
- CHANGABLE_METHODS = ['filterSelf', 'selectRange'] as const;
- DOWNSAMPLE_METHODS = ['downSample', 'lttbDownSample'] as const;
-
- /**
- * @param dimensions
- * For example, ['someDimName', {name: 'someDimName', type: 'someDimType'}, ...].
- * Dimensions should be concrete names like x, y, z, lng, lat, angle, radius
- */
- constructor(dimensions: Array<string | object | DataDimensionInfo>, hostModel: HostModel) {
- dimensions = dimensions || ['x', 'y'];
-
- const dimensionInfos: Dictionary<DataDimensionInfo> = {};
- const dimensionNames = [];
- const invertedIndicesMap: Dictionary<number[]> = {};
-
- for (let i = 0; i < dimensions.length; i++) {
- // Use the original dimensions[i], where other flag props may exists.
- const dimInfoInput = dimensions[i];
-
- const dimensionInfo: DataDimensionInfo =
- zrUtil.isString(dimInfoInput)
- ? new DataDimensionInfo({name: dimInfoInput})
- : !(dimInfoInput instanceof DataDimensionInfo)
- ? new DataDimensionInfo(dimInfoInput)
- : dimInfoInput;
-
- const dimensionName = dimensionInfo.name;
- dimensionInfo.type = dimensionInfo.type || 'float';
- if (!dimensionInfo.coordDim) {
- dimensionInfo.coordDim = dimensionName;
- dimensionInfo.coordDimIndex = 0;
- }
-
- const otherDims = dimensionInfo.otherDims = dimensionInfo.otherDims || {};
- dimensionNames.push(dimensionName);
- dimensionInfos[dimensionName] = dimensionInfo;
-
- dimensionInfo.index = i;
-
- if (dimensionInfo.createInvertedIndices) {
- invertedIndicesMap[dimensionName] = [];
- }
- if (otherDims.itemName === 0) {
- this._nameDimIdx = i;
- this._nameOrdinalMeta = dimensionInfo.ordinalMeta;
- }
- if (otherDims.itemId === 0) {
- this._idDimIdx = i;
- this._idOrdinalMeta = dimensionInfo.ordinalMeta;
- }
- }
-
- this.dimensions = dimensionNames;
- this._dimensionInfos = dimensionInfos;
- this.hostModel = hostModel;
-
- // Cache summary info for fast visit. See "dimensionHelper".
- this._dimensionsSummary = summarizeDimensions(this);
-
- this._invertedIndicesMap = invertedIndicesMap;
-
- this.userOutput = this._dimensionsSummary.userOutput;
- }
-
- /**
- * The meanings of the input parameter `dim`:
- *
- * + If dim is a number (e.g., `1`), it means the index of the dimension.
- * For example, `getDimension(0)` will return 'x' or 'lng' or 'radius'.
- * + If dim is a number-like string (e.g., `"1"`):
- * + If there is the same concrete dim name defined in `this.dimensions`, it means that concrete name.
- * + If not, it will be converted to a number, which means the index of the dimension.
- * (why? because of the backward compatbility. We have been tolerating number-like string in
- * dimension setting, although now it seems that it is not a good idea.)
- * For example, `visualMap[i].dimension: "1"` is the same meaning as `visualMap[i].dimension: 1`,
- * if no dimension name is defined as `"1"`.
- * + If dim is a not-number-like string, it means the concrete dim name.
- * For example, it can be be default name `"x"`, `"y"`, `"z"`, `"lng"`, `"lat"`, `"angle"`, `"radius"`,
- * or customized in `dimensions` property of option like `"age"`.
- *
- * Get dimension name
- * @param dim See above.
- * @return Concrete dim name.
- */
- getDimension(dim: DimensionLoose): DimensionName {
- if (typeof dim === 'number'
- // If being a number-like string but not being defined a dimension name.
- || (!isNaN(dim as any) && !this._dimensionInfos.hasOwnProperty(dim))
- ) {
- dim = this.dimensions[dim as DimensionIndex];
- }
- return dim as DimensionName;
- }
-
- /**
- * Get type and calculation info of particular dimension
- * @param dim
- * Dimension can be concrete names like x, y, z, lng, lat, angle, radius
- * Or a ordinal number. For example getDimensionInfo(0) will return 'x' or 'lng' or 'radius'
- */
- getDimensionInfo(dim: DimensionLoose): DataDimensionInfo {
- // Do not clone, because there may be categories in dimInfo.
- return this._dimensionInfos[this.getDimension(dim)];
- }
-
- /**
- * concrete dimension name list on coord.
- */
- getDimensionsOnCoord(): DimensionName[] {
- return this._dimensionsSummary.dataDimsOnCoord.slice();
- }
-
- /**
- * @param coordDim
- * @param idx A coordDim may map to more than one data dim.
- * If not specified, return the first dim not extra.
- * @return concrete data dim. If not found, return null/undefined
- */
- mapDimension(coordDim: DimensionName): DimensionName;
- mapDimension(coordDim: DimensionName, idx: number): DimensionName;
- mapDimension(coordDim: DimensionName, idx?: number): DimensionName {
- const dimensionsSummary = this._dimensionsSummary;
-
- if (idx == null) {
- return dimensionsSummary.encodeFirstDimNotExtra[coordDim] as any;
- }
-
- const dims = dimensionsSummary.encode[coordDim];
- return dims ? dims[idx as number] as any : null;
- }
-
- mapDimensionsAll(coordDim: DimensionName): DimensionName[] {
- const dimensionsSummary = this._dimensionsSummary;
- const dims = dimensionsSummary.encode[coordDim];
- return (dims || []).slice();
- }
-
- /**
- * Initialize from data
- * @param data source or data or data provider.
- * @param nameList The name of a datum is used on data diff and
- * default label/tooltip.
- * A name can be specified in encode.itemName,
- * or dataItem.name (only for series option data),
- * or provided in nameList from outside.
- */
- initData(
- data: Source | OptionSourceData | DataProvider,
- nameList?: string[],
- dimValueGetter?: DimValueGetter
- ): void {
-
- const notProvider = isSourceInstance(data) || zrUtil.isArrayLike(data);
- const provider: DataProvider = notProvider
- ? new DefaultDataProvider(data as Source | OptionSourceData, this.dimensions.length)
- : data as DataProvider;
-
- if (__DEV__) {
- zrUtil.assert(
- notProvider || (
- zrUtil.isFunction(provider.getItem)
- && zrUtil.isFunction(provider.count)
- ),
- 'Inavlid data provider.'
- );
- }
-
- this._rawData = provider;
- const sourceFormat = provider.getSource().sourceFormat;
-
- // Clear
- this._storage = {};
- this._indices = null;
- this._dontMakeIdFromName =
- this._idDimIdx != null
- || sourceFormat === SOURCE_FORMAT_TYPED_ARRAY // Cosndier performance.
- || !!provider.fillStorage;
-
- this._nameList = (nameList || []).slice();
- this._idList = [];
-
- this._nameRepeatCount = {};
-
- if (!dimValueGetter) {
- this.hasItemOption = false;
- }
-
- this.defaultDimValueGetter = defaultDimValueGetters[sourceFormat];
- // Default dim value getter
- this._dimValueGetter = dimValueGetter = dimValueGetter
- || this.defaultDimValueGetter;
- this._dimValueGetterArrayRows = defaultDimValueGetters.arrayRows;
-
- // Reset raw extent.
- this._rawExtent = {};
-
- this._initDataFromProvider(0, provider.count());
-
- // If data has no item option.
- if (provider.pure) {
- this.hasItemOption = false;
- }
- }
-
- getProvider(): DataProvider {
- return this._rawData;
- }
-
- /**
- * Caution: Can be only called on raw data (before `this._indices` created).
- */
- appendData(data: ArrayLike<any>): void {
- if (__DEV__) {
- zrUtil.assert(!this._indices, 'appendData can only be called on raw data.');
- }
-
- const rawData = this._rawData;
- const start = this.count();
- rawData.appendData(data);
- let end = rawData.count();
- if (!rawData.persistent) {
- end += start;
- }
- this._initDataFromProvider(start, end, true);
- }
-
- /**
- * Caution: Can be only called on raw data (before `this._indices` created).
- * This method does not modify `rawData` (`dataProvider`), but only
- * add values to storage.
- *
- * The final count will be increased by `Math.max(values.length, names.length)`.
- *
- * @param values That is the SourceType: 'arrayRows', like
- * [
- * [12, 33, 44],
- * [NaN, 43, 1],
- * ['-', 'asdf', 0]
- * ]
- * Each item is exaclty cooresponding to a dimension.
- */
- appendValues(values: any[][], names?: string[]): void {
- const storage = this._storage;
- const dimensions = this.dimensions;
- const dimLen = dimensions.length;
- const rawExtent = this._rawExtent;
-
- const start = this.count();
- const end = start + Math.max(values.length, names ? names.length : 0);
-
- for (let i = 0; i < dimLen; i++) {
- const dim = dimensions[i];
- if (!rawExtent[dim]) {
- rawExtent[dim] = getInitialExtent();
- }
- prepareStorage(storage, this._dimensionInfos[dim], end, true);
- }
-
- const rawExtentArr = map(dimensions, (dim) => {
- return rawExtent[dim];
- });
-
- const storageArr = this._storageArr = map(dimensions, (dim) => {
- return storage[dim];
- });
-
- const emptyDataItem: number[] = [];
- for (let idx = start; idx < end; idx++) {
- const sourceIdx = idx - start;
- // Store the data by dimensions
- for (let dimIdx = 0; dimIdx < dimLen; dimIdx++) {
- const dim = dimensions[dimIdx];
- const val = this._dimValueGetterArrayRows(
- values[sourceIdx] || emptyDataItem, dim, sourceIdx, dimIdx
- ) as ParsedValueNumeric;
- storageArr[dimIdx][idx] = val;
-
- const dimRawExtent = rawExtentArr[dimIdx];
- val < dimRawExtent[0] && (dimRawExtent[0] = val);
- val > dimRawExtent[1] && (dimRawExtent[1] = val);
- }
-
- if (names) {
- this._nameList[idx] = names[sourceIdx];
- if (!this._dontMakeIdFromName) {
- makeIdFromName(this, idx);
- }
- }
- }
-
- this._rawCount = this._count = end;
-
- // Reset data extent
- this._extent = {};
-
- prepareInvertedIndex(this);
- }
-
- private _initDataFromProvider(start: number, end: number, append?: boolean): void {
- if (start >= end) {
- return;
- }
-
- const rawData = this._rawData;
- const storage = this._storage;
- const dimensions = this.dimensions;
- const dimLen = dimensions.length;
- const dimensionInfoMap = this._dimensionInfos;
- const nameList = this._nameList;
- const idList = this._idList;
- const rawExtent = this._rawExtent;
- const sourceFormat = rawData.getSource().sourceFormat;
- const isFormatOriginal = sourceFormat === SOURCE_FORMAT_ORIGINAL;
-
- for (let i = 0; i < dimLen; i++) {
- const dim = dimensions[i];
- if (!rawExtent[dim]) {
- rawExtent[dim] = getInitialExtent();
- }
- prepareStorage(storage, dimensionInfoMap[dim], end, append);
- }
-
- const storageArr = this._storageArr = map(dimensions, (dim) => {
- return storage[dim];
- });
-
- const rawExtentArr = map(dimensions, (dim) => {
- return rawExtent[dim];
- });
-
- if (rawData.fillStorage) {
- rawData.fillStorage(start, end, storageArr, rawExtentArr);
- }
- else {
- let dataItem = [] as OptionDataItem;
- for (let idx = start; idx < end; idx++) {
- // NOTICE: Try not to write things into dataItem
- dataItem = rawData.getItem(idx, dataItem);
- // Each data item is value
- // [1, 2]
- // 2
- // Bar chart, line chart which uses category axis
- // only gives the 'y' value. 'x' value is the indices of category
- // Use a tempValue to normalize the value to be a (x, y) value
-
- // Store the data by dimensions
- for (let dimIdx = 0; dimIdx < dimLen; dimIdx++) {
- const dim = dimensions[dimIdx];
- const dimStorage = storageArr[dimIdx];
- // PENDING NULL is empty or zero
- const val = this._dimValueGetter(dataItem, dim, idx, dimIdx) as ParsedValueNumeric;
- dimStorage[idx] = val;
-
- const dimRawExtent = rawExtentArr[dimIdx];
- val < dimRawExtent[0] && (dimRawExtent[0] = val);
- val > dimRawExtent[1] && (dimRawExtent[1] = val);
- }
-
- // If dataItem is {name: ...} or {id: ...}, it has highest priority.
- // This kind of ids and names are always stored `_nameList` and `_idList`.
- if (isFormatOriginal && !rawData.pure && dataItem) {
- const itemName = (dataItem as any).name;
- if (nameList[idx] == null && itemName != null) {
- nameList[idx] = convertOptionIdName(itemName, null);
- }
- const itemId = (dataItem as any).id;
- if (idList[idx] == null && itemId != null) {
- idList[idx] = convertOptionIdName(itemId, null);
- }
- }
-
- if (!this._dontMakeIdFromName) {
- makeIdFromName(this, idx);
- }
- }
- }
-
- if (!rawData.persistent && rawData.clean) {
- // Clean unused data if data source is typed array.
- rawData.clean();
- }
-
- this._rawCount = this._count = end;
-
- // Reset data extent
- this._extent = {};
-
- prepareInvertedIndex(this);
- }
-
- count(): number {
- return this._count;
- }
-
- getIndices(): ArrayLike<number> {
- let newIndices;
-
- const indices = this._indices;
- if (indices) {
- const Ctor = indices.constructor as DataArrayLikeConstructor;
- const thisCount = this._count;
- // `new Array(a, b, c)` is different from `new Uint32Array(a, b, c)`.
- if (Ctor === Array) {
- newIndices = new Ctor(thisCount);
- for (let i = 0; i < thisCount; i++) {
- newIndices[i] = indices[i];
- }
- }
- else {
- newIndices = new (Ctor as DataTypedArrayConstructor)(
- (indices as DataTypedArray).buffer, 0, thisCount
- );
- }
- }
- else {
- const Ctor = getIndicesCtor(this);
- newIndices = new Ctor(this.count());
- for (let i = 0; i < newIndices.length; i++) {
- newIndices[i] = i;
- }
- }
-
- return newIndices;
- }
-
- // Get data by index of dimension.
- // Because in v8 access array by number variable is faster than access object by string variable
- // Not sure why but the optimization just works.
- getByDimIdx(dimIdx: number, idx: number): ParsedValue {
- if (!(idx >= 0 && idx < this._count)) {
- return NaN;
- }
- const dimStore = this._storageArr[dimIdx];
- return dimStore ? dimStore[this.getRawIndex(idx)] : NaN;
- }
-
- /**
- * Get value. Return NaN if idx is out of range.
- * @param dim Dim must be concrete name.
- */
- get(dim: DimensionName, idx: number): ParsedValue {
- if (!(idx >= 0 && idx < this._count)) {
- return NaN;
- }
- const dimStore = this._storage[dim];
- return dimStore ? dimStore[this.getRawIndex(idx)] : NaN;
- }
-
- /**
- * @param dim concrete dim
- */
- getByRawIndex(dim: DimensionName, rawIdx: number): ParsedValue {
- if (!(rawIdx >= 0 && rawIdx < this._rawCount)) {
- return NaN;
- }
- const dimStore = this._storage[dim];
- return dimStore ? dimStore[rawIdx] : NaN;
- }
-
- /**
- * Get value for multi dimensions.
- * @param dimensions If ignored, using all dimensions.
- */
- getValues(idx: number): ParsedValue[];
- getValues(dimensions: readonly DimensionName[], idx: number): ParsedValue[];
- getValues(dimensions: readonly DimensionName[] | number, idx?: number): ParsedValue[] {
- const values = [];
-
- if (!zrUtil.isArray(dimensions)) {
- // stack = idx;
- idx = dimensions as number;
- dimensions = this.dimensions;
- }
-
- for (let i = 0, len = dimensions.length; i < len; i++) {
- values.push(this.get(dimensions[i], idx /*, stack */));
- }
-
- return values;
- }
-
- /**
- * If value is NaN. Inlcuding '-'
- * Only check the coord dimensions.
- */
- hasValue(idx: number): boolean {
- const dataDimsOnCoord = this._dimensionsSummary.dataDimsOnCoord;
- for (let i = 0, len = dataDimsOnCoord.length; i < len; i++) {
- // Ordinal type originally can be string or number.
- // But when an ordinal type is used on coord, it can
- // not be string but only number. So we can also use isNaN.
- if (isNaN(this.get(dataDimsOnCoord[i], idx) as any)) {
- return false;
- }
- }
- return true;
- }
-
- /**
- * Get extent of data in one dimension
- */
- getDataExtent(dim: DimensionLoose): [number, number] {
- // Make sure use concrete dim as cache name.
- dim = this.getDimension(dim);
- const dimData = this._storage[dim];
- const initialExtent = getInitialExtent();
-
- // stack = !!((stack || false) && this.getCalculationInfo(dim));
-
- if (!dimData) {
- return initialExtent;
- }
-
- // Make more strict checkings to ensure hitting cache.
- const currEnd = this.count();
- // let cacheName = [dim, !!stack].join('_');
- // let cacheName = dim;
-
- // Consider the most cases when using data zoom, `getDataExtent`
- // happened before filtering. We cache raw extent, which is not
- // necessary to be cleared and recalculated when restore data.
- const useRaw = !this._indices; // && !stack;
- let dimExtent: [number, number];
-
- if (useRaw) {
- return this._rawExtent[dim].slice() as [number, number];
- }
- dimExtent = this._extent[dim];
- if (dimExtent) {
- return dimExtent.slice() as [number, number];
- }
- dimExtent = initialExtent;
-
- let min = dimExtent[0];
- let max = dimExtent[1];
-
- for (let i = 0; i < currEnd; i++) {
- const rawIdx = this.getRawIndex(i);
- const value = dimData[rawIdx] as ParsedValueNumeric;
- value < min && (min = value);
- value > max && (max = value);
- }
-
- dimExtent = [min, max];
-
- this._extent[dim] = dimExtent;
-
- return dimExtent;
- }
-
- /**
- * PENDING: In fact currently this function is only used to short-circuit
- * the calling of `scale.unionExtentFromData` when data have been filtered by modules
- * like "dataZoom". `scale.unionExtentFromData` is used to calculate data extent for series on
- * an axis, but if a "axis related data filter module" is used, the extent of the axis have
- * been fixed and no need to calling `scale.unionExtentFromData` actually.
- * But if we add "custom data filter" in future, which is not "axis related", this method may
- * be still needed.
- *
- * Optimize for the scenario that data is filtered by a given extent.
- * Consider that if data amount is more than hundreds of thousand,
- * extent calculation will cost more than 10ms and the cache will
- * be erased because of the filtering.
- */
- getApproximateExtent(dim: DimensionLoose): [number, number] {
- dim = this.getDimension(dim);
- return this._approximateExtent[dim] || this.getDataExtent(dim);
- }
-
- /**
- * Calculate extent on a filtered data might be time consuming.
- * Approximate extent is only used for: calculte extent of filtered data outside.
- */
- setApproximateExtent(extent: [number, number], dim: DimensionLoose): void {
- dim = this.getDimension(dim);
- this._approximateExtent[dim] = extent.slice() as [number, number];
- }
-
- getCalculationInfo<CALC_INFO_KEY extends keyof DataCalculationInfo<HostModel>>(
- key: CALC_INFO_KEY
- ): DataCalculationInfo<HostModel>[CALC_INFO_KEY] {
- return this._calculationInfo[key];
- }
-
- /**
- * @param key or k-v object
- */
- setCalculationInfo(
- key: DataCalculationInfo<HostModel>
- ): void;
- setCalculationInfo<CALC_INFO_KEY extends keyof DataCalculationInfo<HostModel>>(
- key: CALC_INFO_KEY,
- value: DataCalculationInfo<HostModel>[CALC_INFO_KEY]
- ): void;
- setCalculationInfo(
- key: (keyof DataCalculationInfo<HostModel>) | DataCalculationInfo<HostModel>,
- value?: DataCalculationInfo<HostModel>[keyof DataCalculationInfo<HostModel>]
- ): void {
- isObject(key)
- ? zrUtil.extend(this._calculationInfo, key as object)
- : ((this._calculationInfo as any)[key] = value);
- }
-
- /**
- * Get sum of data in one dimension
- */
- getSum(dim: DimensionName): number {
- const dimData = this._storage[dim];
- let sum = 0;
- if (dimData) {
- for (let i = 0, len = this.count(); i < len; i++) {
- const value = this.get(dim, i) as number;
- if (!isNaN(value)) {
- sum += value;
- }
- }
- }
- return sum;
- }
-
- /**
- * Get median of data in one dimension
- */
- getMedian(dim: DimensionLoose): number {
- const dimDataArray: ParsedValue[] = [];
- // map all data of one dimension
- this.each(dim, function (val) {
- if (!isNaN(val as number)) {
- dimDataArray.push(val);
- }
- });
-
- // TODO
- // Use quick select?
- const sortedDimDataArray = dimDataArray.sort(function (a: number, b: number) {
- return a - b;
- }) as number[];
- const len = this.count();
- // calculate median
- return len === 0
- ? 0
- : len % 2 === 1
- ? sortedDimDataArray[(len - 1) / 2]
- : (sortedDimDataArray[len / 2] + sortedDimDataArray[len / 2 - 1]) / 2;
- }
-
- // /**
- // * Retreive the index with given value
- // * @param {string} dim Concrete dimension.
- // * @param {number} value
- // * @return {number}
- // */
- // Currently incorrect: should return dataIndex but not rawIndex.
- // Do not fix it until this method is to be used somewhere.
- // FIXME Precision of float value
- // indexOf(dim, value) {
- // let storage = this._storage;
- // let dimData = storage[dim];
- // let chunkSize = this._chunkSize;
- // if (dimData) {
- // for (let i = 0, len = this.count(); i < len; i++) {
- // let chunkIndex = mathFloor(i / chunkSize);
- // let chunkOffset = i % chunkSize;
- // if (dimData[chunkIndex][chunkOffset] === value) {
- // return i;
- // }
- // }
- // }
- // return -1;
- // }
-
- /**
- * Only support the dimension which inverted index created.
- * Do not support other cases until required.
- * @param dim concrete dim
- * @param value ordinal index
- * @return rawIndex
- */
- rawIndexOf(dim: DimensionName, value: OrdinalNumber): number {
- const invertedIndices = dim && this._invertedIndicesMap[dim];
- if (__DEV__) {
- if (!invertedIndices) {
- throw new Error('Do not supported yet');
- }
- }
- const rawIndex = invertedIndices[value];
- if (rawIndex == null || isNaN(rawIndex)) {
- return INDEX_NOT_FOUND;
- }
- return rawIndex;
- }
-
- /**
- * Retreive the index with given name
- */
- indexOfName(name: string): number {
- for (let i = 0, len = this.count(); i < len; i++) {
- if (this.getName(i) === name) {
- return i;
- }
- }
-
- return -1;
- }
-
- /**
- * Retreive the index with given raw data index
- */
- indexOfRawIndex(rawIndex: number): number {
- if (rawIndex >= this._rawCount || rawIndex < 0) {
- return -1;
- }
-
- if (!this._indices) {
- return rawIndex;
- }
-
- // Indices are ascending
- const indices = this._indices;
-
- // If rawIndex === dataIndex
- const rawDataIndex = indices[rawIndex];
- if (rawDataIndex != null && rawDataIndex < this._count && rawDataIndex === rawIndex) {
- return rawIndex;
- }
-
- let left = 0;
- let right = this._count - 1;
- while (left <= right) {
- const mid = (left + right) / 2 | 0;
- if (indices[mid] < rawIndex) {
- left = mid + 1;
- }
- else if (indices[mid] > rawIndex) {
- right = mid - 1;
- }
- else {
- return mid;
- }
- }
- return -1;
- }
-
- /**
- * Retreive the index of nearest value
- * @param dim
- * @param value
- * @param [maxDistance=Infinity]
- * @return If and only if multiple indices has
- * the same value, they are put to the result.
- */
- indicesOfNearest(
- dim: DimensionName, value: number, maxDistance?: number
- ): number[] {
- const storage = this._storage;
- const dimData = storage[dim];
- const nearestIndices: number[] = [];
-
- if (!dimData) {
- return nearestIndices;
- }
-
- if (maxDistance == null) {
- maxDistance = Infinity;
- }
-
- let minDist = Infinity;
- let minDiff = -1;
- let nearestIndicesLen = 0;
-
-
- // Check the test case of `test/ut/spec/data/List.js`.
- for (let i = 0, len = this.count(); i < len; i++) {
- const dataIndex = this.getRawIndex(i);
- const diff = value - (dimData[dataIndex] as number);
- const dist = Math.abs(diff);
- if (dist <= maxDistance) {
- // When the `value` is at the middle of `this.get(dim, i)` and `this.get(dim, i+1)`,
- // we'd better not push both of them to `nearestIndices`, otherwise it is easy to
- // get more than one item in `nearestIndices` (more specifically, in `tooltip`).
- // So we chose the one that `diff >= 0` in this csae.
- // But if `this.get(dim, i)` and `this.get(dim, j)` get the same value, both of them
- // should be push to `nearestIndices`.
- if (dist < minDist
- || (dist === minDist && diff >= 0 && minDiff < 0)
- ) {
- minDist = dist;
- minDiff = diff;
- nearestIndicesLen = 0;
- }
- if (diff === minDiff) {
- nearestIndices[nearestIndicesLen++] = i;
- }
- }
- }
- nearestIndices.length = nearestIndicesLen;
-
- return nearestIndices;
- }
-
- /**
- * Get raw data index.
- * Do not initialize.
- * Default `getRawIndex`. And it can be changed.
- */
- getRawIndex: (idx: number) => number = getRawIndexWithoutIndices;
-
- /**
- * Get raw data item
- */
- getRawDataItem(idx: number): OptionDataItem {
- if (!this._rawData.persistent) {
- const val = [];
- for (let i = 0; i < this.dimensions.length; i++) {
- const dim = this.dimensions[i];
- val.push(this.get(dim, idx));
- }
- return val;
- }
- else {
- return this._rawData.getItem(this.getRawIndex(idx));
- }
- }
-
- /**
- * @return Never be null/undefined. `number` will be converted to string. Becuase:
- * In most cases, name is used in display, where returning a string is more convenient.
- * In other cases, name is used in query (see `indexOfName`), where we can keep the
- * rule that name `2` equals to name `'2'`.
- */
- getName(idx: number): string {
- const rawIndex = this.getRawIndex(idx);
- let name = this._nameList[rawIndex];
- if (name == null && this._nameDimIdx != null) {
- name = getIdNameFromStore(this, this._nameDimIdx, this._nameOrdinalMeta, rawIndex);
- }
- if (name == null) {
- name = '';
- }
- return name;
- }
-
- /**
- * @return Never null/undefined. `number` will be converted to string. Becuase:
- * In all cases having encountered at present, id is used in making diff comparison, which
- * are usually based on hash map. We can keep the rule that the internal id are always string
- * (treat `2` is the same as `'2'`) to make the related logic simple.
- */
- getId(idx: number): string {
- return getId(this, this.getRawIndex(idx));
- }
-
- /**
- * Data iteration
- * @param ctx default this
- * @example
- * list.each('x', function (x, idx) {});
- * list.each(['x', 'y'], function (x, y, idx) {});
- * list.each(function (idx) {})
- */
- each<Ctx>(cb: EachCb0<Ctx>, ctx?: Ctx, ctxCompat?: Ctx): void;
- each<Ctx>(dims: DimensionLoose, cb: EachCb1<Ctx>, ctx?: Ctx, ctxCompat?: Ctx): void;
- each<Ctx>(dims: [DimensionLoose], cb: EachCb1<Ctx>, ctx?: Ctx, ctxCompat?: Ctx): void;
- each<Ctx>(dims: [DimensionLoose, DimensionLoose], cb: EachCb2<Ctx>, ctx?: Ctx, ctxCompat?: Ctx): void;
- each<Ctx>(dims: ItrParamDims, cb: EachCb<Ctx>, ctx?: Ctx, ctxCompat?: Ctx): void;
- each<Ctx>(
- dims: ItrParamDims | EachCb<Ctx>,
- cb: EachCb<Ctx> | Ctx,
- ctx?: Ctx,
- ctxCompat?: Ctx
- ): void {
- 'use strict';
-
- if (!this._count) {
- return;
- }
-
- if (typeof dims === 'function') {
- ctxCompat = ctx;
- ctx = cb as Ctx;
- cb = dims;
- dims = [];
- }
-
- // ctxCompat just for compat echarts3
- const fCtx = (ctx || ctxCompat || this) as CtxOrList<Ctx>;
-
- const dimNames = map(normalizeDimensions(dims), this.getDimension, this);
-
- if (__DEV__) {
- validateDimensions(this, dimNames);
- }
-
- const dimSize = dimNames.length;
- const dimIndices = map(dimNames, (dimName) => {
- return this._dimensionInfos[dimName].index;
- });
- const storageArr = this._storageArr;
-
- for (let i = 0, len = this.count(); i < len; i++) {
- const rawIdx = this.getRawIndex(i);
- // Simple optimization
- switch (dimSize) {
- case 0:
- (cb as EachCb0<Ctx>).call(fCtx, i);
- break;
- case 1:
- (cb as EachCb1<Ctx>).call(fCtx, storageArr[dimIndices[0]][rawIdx], i);
- break;
- case 2:
- (cb as EachCb2<Ctx>).call(
- fCtx, storageArr[dimIndices[0]][rawIdx], storageArr[dimIndices[1]][rawIdx], i
- );
- break;
- default:
- let k = 0;
- const value = [];
- for (; k < dimSize; k++) {
- value[k] = storageArr[dimIndices[k]][rawIdx];
- }
- // Index
- value[k] = i;
- (cb as EachCb<Ctx>).apply(fCtx, value);
- }
- }
- }
-
- /**
- * Data filter
- */
- filterSelf<Ctx>(cb: FilterCb0<Ctx>, ctx?: Ctx, ctxCompat?: Ctx): this;
- filterSelf<Ctx>(dims: DimensionLoose, cb: FilterCb1<Ctx>, ctx?: Ctx, ctxCompat?: Ctx): this;
- filterSelf<Ctx>(dims: [DimensionLoose], cb: FilterCb1<Ctx>, ctx?: Ctx, ctxCompat?: Ctx): this;
- filterSelf<Ctx>(dims: [DimensionLoose, DimensionLoose], cb: FilterCb2<Ctx>, ctx?: Ctx, ctxCompat?: Ctx): this;
- filterSelf<Ctx>(dims: ItrParamDims, cb: FilterCb<Ctx>, ctx?: Ctx, ctxCompat?: Ctx): this;
- filterSelf<Ctx>(
- dims: ItrParamDims | FilterCb<Ctx>,
- cb: FilterCb<Ctx> | Ctx,
- ctx?: Ctx,
- ctxCompat?: Ctx
- ): List {
- 'use strict';
-
- if (!this._count) {
- return;
- }
-
- if (typeof dims === 'function') {
- ctxCompat = ctx;
- ctx = cb as Ctx;
- cb = dims;
- dims = [];
- }
-
- // ctxCompat just for compat echarts3
- const fCtx = (ctx || ctxCompat || this) as CtxOrList<Ctx>;
-
- const dimNames = map(
- normalizeDimensions(dims), this.getDimension, this
- );
-
- if (__DEV__) {
- validateDimensions(this, dimNames);
- }
-
-
- const count = this.count();
- const Ctor = getIndicesCtor(this);
- const newIndices = new Ctor(count);
- const value = [];
- const dimSize = dimNames.length;
-
- let offset = 0;
- const dimIndices = map(dimNames, (dimName) => {
- return this._dimensionInfos[dimName].index;
- });
- const dim0 = dimIndices[0];
- const storageArr = this._storageArr;
-
- for (let i = 0; i < count; i++) {
- let keep;
- const rawIdx = this.getRawIndex(i);
- // Simple optimization
- if (dimSize === 0) {
- keep = (cb as FilterCb0<Ctx>).call(fCtx, i);
- }
- else if (dimSize === 1) {
- const val = storageArr[dim0][rawIdx];
- keep = (cb as FilterCb1<Ctx>).call(fCtx, val, i);
- }
- else {
- let k = 0;
- for (; k < dimSize; k++) {
- value[k] = storageArr[dimIndices[k]][rawIdx];
- }
- value[k] = i;
- keep = (cb as FilterCb<Ctx>).apply(fCtx, value);
- }
- if (keep) {
- newIndices[offset++] = rawIdx;
- }
- }
-
- // Set indices after filtered.
- if (offset < count) {
- this._indices = newIndices;
- }
- this._count = offset;
- // Reset data extent
- this._extent = {};
-
- this.getRawIndex = this._indices ? getRawIndexWithIndices : getRawIndexWithoutIndices;
-
- return this;
- }
-
- /**
- * Select data in range. (For optimization of filter)
- * (Manually inline code, support 5 million data filtering in data zoom.)
- */
- selectRange(range: {[dimName: string]: [number, number]}): List {
- 'use strict';
-
- const len = this._count;
-
- if (!len) {
- return;
- }
-
- const dimensions = [];
- for (const dim in range) {
- if (range.hasOwnProperty(dim)) {
- dimensions.push(dim);
- }
- }
-
- if (__DEV__) {
- validateDimensions(this, dimensions);
- }
-
- const dimSize = dimensions.length;
- if (!dimSize) {
- return;
- }
-
- const originalCount = this.count();
- const Ctor = getIndicesCtor(this);
- const newIndices = new Ctor(originalCount);
-
- let offset = 0;
- const dim0 = dimensions[0];
- const dimIndices = map(dimensions, (dimName) => {
- return this._dimensionInfos[dimName].index;
- });
-
- const min = range[dim0][0];
- const max = range[dim0][1];
- const storageArr = this._storageArr;
-
- let quickFinished = false;
- if (!this._indices) {
- // Extreme optimization for common case. About 2x faster in chrome.
- let idx = 0;
- if (dimSize === 1) {
- const dimStorage = storageArr[dimIndices[0]];
- for (let i = 0; i < len; i++) {
- const val = dimStorage[i];
- // NaN will not be filtered. Consider the case, in line chart, empty
- // value indicates the line should be broken. But for the case like
- // scatter plot, a data item with empty value will not be rendered,
- // but the axis extent may be effected if some other dim of the data
- // item has value. Fortunately it is not a significant negative effect.
- if (
- (val >= min && val <= max) || isNaN(val as any)
- ) {
- newIndices[offset++] = idx;
- }
- idx++;
- }
- quickFinished = true;
- }
- else if (dimSize === 2) {
- const dimStorage = storageArr[dimIndices[0]];
- const dimStorage2 = storageArr[dimIndices[1]];
- const min2 = range[dimensions[1]][0];
- const max2 = range[dimensions[1]][1];
- for (let i = 0; i < len; i++) {
- const val = dimStorage[i];
- const val2 = dimStorage2[i];
- // Do not filter NaN, see comment above.
- if ((
- (val >= min && val <= max) || isNaN(val as any)
- )
- && (
- (val2 >= min2 && val2 <= max2) || isNaN(val2 as any)
- )
- ) {
- newIndices[offset++] = idx;
- }
- idx++;
- }
- quickFinished = true;
- }
- }
- if (!quickFinished) {
- if (dimSize === 1) {
- for (let i = 0; i < originalCount; i++) {
- const rawIndex = this.getRawIndex(i);
- const val = storageArr[dimIndices[0]][rawIndex];
- // Do not filter NaN, see comment above.
- if (
- (val >= min && val <= max) || isNaN(val as any)
- ) {
- newIndices[offset++] = rawIndex;
- }
- }
- }
- else {
- for (let i = 0; i < originalCount; i++) {
- let keep = true;
- const rawIndex = this.getRawIndex(i);
- for (let k = 0; k < dimSize; k++) {
- const dimk = dimensions[k];
- const val = storageArr[dimIndices[k]][rawIndex];
- // Do not filter NaN, see comment above.
- if (val < range[dimk][0] || val > range[dimk][1]) {
- keep = false;
- }
- }
- if (keep) {
- newIndices[offset++] = this.getRawIndex(i);
- }
- }
- }
- }
-
- // Set indices after filtered.
- if (offset < originalCount) {
- this._indices = newIndices;
- }
- this._count = offset;
- // Reset data extent
- this._extent = {};
-
- this.getRawIndex = this._indices ? getRawIndexWithIndices : getRawIndexWithoutIndices;
-
- return this;
- }
-
- /**
- * Data mapping to a plain array
- */
- mapArray<Ctx, Cb extends MapArrayCb0<Ctx>>(cb: Cb, ctx?: Ctx, ctxCompat?: Ctx): ReturnType<Cb>[];
- /* eslint-disable */
- mapArray<Ctx, Cb extends MapArrayCb1<Ctx>>(dims: DimensionLoose, cb: Cb, ctx?: Ctx, ctxCompat?: Ctx): ReturnType<Cb>[];
- mapArray<Ctx, Cb extends MapArrayCb1<Ctx>>(dims: [DimensionLoose], cb: Cb, ctx?: Ctx, ctxCompat?: Ctx): ReturnType<Cb>[];
- mapArray<Ctx, Cb extends MapArrayCb2<Ctx>>(dims: [DimensionLoose, DimensionLoose], cb: Cb, ctx?: Ctx, ctxCompat?: Ctx): ReturnType<Cb>[];
- mapArray<Ctx, Cb extends MapArrayCb<Ctx>>(dims: ItrParamDims, cb: Cb, ctx?: Ctx, ctxCompat?: Ctx): ReturnType<Cb>[];
- /* eslint-enable */
- mapArray<Ctx>(
- dims: ItrParamDims | MapArrayCb<Ctx>,
- cb: MapArrayCb<Ctx> | Ctx,
- ctx?: Ctx,
- ctxCompat?: Ctx
- ): any[] {
- 'use strict';
-
- if (typeof dims === 'function') {
- ctxCompat = ctx;
- ctx = cb as Ctx;
- cb = dims;
- dims = [];
- }
-
- // ctxCompat just for compat echarts3
- ctx = (ctx || ctxCompat || this) as Ctx;
-
- const result: any[] = [];
- this.each(dims, function () {
- result.push(cb && (cb as MapArrayCb<Ctx>).apply(this, arguments));
- }, ctx);
- return result;
- }
-
- /**
- * Data mapping to a new List with given dimensions
- */
- map<Ctx>(dims: DimensionLoose, cb: MapCb1<Ctx>, ctx?: Ctx, ctxCompat?: Ctx): List<HostModel>;
- map<Ctx>(dims: [DimensionLoose], cb: MapCb1<Ctx>, ctx?: Ctx, ctxCompat?: Ctx): List<HostModel>;
- map<Ctx>(dims: [DimensionLoose, DimensionLoose], cb: MapCb2<Ctx>, ctx?: Ctx, ctxCompat?: Ctx): List<HostModel>;
- map<Ctx>(
- dims: ItrParamDims,
- cb: MapCb<Ctx>,
- ctx?: Ctx,
- ctxCompat?: Ctx
- ): List {
- 'use strict';
-
- // ctxCompat just for compat echarts3
- const fCtx = (ctx || ctxCompat || this) as CtxOrList<Ctx>;
-
- const dimNames = map(
- normalizeDimensions(dims), this.getDimension, this
- );
-
- if (__DEV__) {
- validateDimensions(this, dimNames);
- }
-
- const list = cloneListForMapAndSample(this, dimNames);
- const storage = list._storage;
-
- // Following properties are all immutable.
- // So we can reference to the same value
- list._indices = this._indices;
- list.getRawIndex = list._indices ? getRawIndexWithIndices : getRawIndexWithoutIndices;
-
- const tmpRetValue = [];
- const dimSize = dimNames.length;
- const dataCount = this.count();
- const values = [];
- const rawExtent = list._rawExtent;
-
- for (let dataIndex = 0; dataIndex < dataCount; dataIndex++) {
- for (let dimIndex = 0; dimIndex < dimSize; dimIndex++) {
- values[dimIndex] = this.get(dimNames[dimIndex], dataIndex);
- }
- values[dimSize] = dataIndex;
-
- let retValue = cb && cb.apply(fCtx, values);
- if (retValue != null) {
- // a number or string (in oridinal dimension)?
- if (typeof retValue !== 'object') {
- tmpRetValue[0] = retValue;
- retValue = tmpRetValue;
- }
-
- const rawIndex = this.getRawIndex(dataIndex);
-
- for (let i = 0; i < retValue.length; i++) {
- const dim = dimNames[i];
- const val = retValue[i];
- const rawExtentOnDim = rawExtent[dim];
-
- const dimStore = storage[dim];
- if (dimStore) {
- dimStore[rawIndex] = val;
- }
-
- if (val < rawExtentOnDim[0]) {
- rawExtentOnDim[0] = val as number;
- }
- if (val > rawExtentOnDim[1]) {
- rawExtentOnDim[1] = val as number;
- }
- }
- }
- }
-
- return list;
- }
-
- /**
- * Large data down sampling on given dimension
- * @param sampleIndex Sample index for name and id
- */
- downSample(
- dimension: DimensionName,
- rate: number,
- sampleValue: (frameValues: ArrayLike<ParsedValue>) => ParsedValueNumeric,
- sampleIndex: (frameValues: ArrayLike<ParsedValue>, value: ParsedValueNumeric) => number
- ): List<HostModel> {
- const list = cloneListForMapAndSample(this, [dimension]);
- const targetStorage = list._storage;
-
- const frameValues = [];
- let frameSize = mathFloor(1 / rate);
-
- const dimStore = targetStorage[dimension];
- const len = this.count();
- const rawExtentOnDim = list._rawExtent[dimension];
-
- const newIndices = new (getIndicesCtor(this))(len);
-
- let offset = 0;
- for (let i = 0; i < len; i += frameSize) {
- // Last frame
- if (frameSize > len - i) {
- frameSize = len - i;
- frameValues.length = frameSize;
- }
- for (let k = 0; k < frameSize; k++) {
- const dataIdx = this.getRawIndex(i + k);
- frameValues[k] = dimStore[dataIdx];
- }
- const value = sampleValue(frameValues);
- const sampleFrameIdx = this.getRawIndex(
- Math.min(i + sampleIndex(frameValues, value) || 0, len - 1)
- );
- // Only write value on the filtered data
- dimStore[sampleFrameIdx] = value;
-
- if (value < rawExtentOnDim[0]) {
- rawExtentOnDim[0] = value;
- }
- if (value > rawExtentOnDim[1]) {
- rawExtentOnDim[1] = value;
- }
-
- newIndices[offset++] = sampleFrameIdx;
- }
-
- list._count = offset;
- list._indices = newIndices;
-
- list.getRawIndex = getRawIndexWithIndices;
-
- return list as List<HostModel>;
- }
-
- /**
- * Large data down sampling using largest-triangle-three-buckets
- * @param {string} valueDimension
- * @param {number} targetCount
- */
- lttbDownSample(
- valueDimension: DimensionName,
- rate: number
- ) {
- const list = cloneListForMapAndSample(this, []);
- const targetStorage = list._storage;
- const dimStore = targetStorage[valueDimension];
- const len = this.count();
- const newIndices = new (getIndicesCtor(this))(len);
-
- let sampledIndex = 0;
-
- const frameSize = mathFloor(1 / rate);
-
- let currentRawIndex = this.getRawIndex(0);
- let maxArea;
- let area;
- let nextRawIndex;
-
- // First frame use the first data.
- newIndices[sampledIndex++] = currentRawIndex;
- for (let i = 1; i < len - 1; i += frameSize) {
- const nextFrameStart = Math.min(i + frameSize, len - 1);
- const nextFrameEnd = Math.min(i + frameSize * 2, len);
-
- const avgX = (nextFrameEnd + nextFrameStart) / 2;
- let avgY = 0;
-
- for (let idx = nextFrameStart; idx < nextFrameEnd; idx++) {
- const rawIndex = this.getRawIndex(idx);
- const y = dimStore[rawIndex] as number;
- if (isNaN(y)) {
- continue;
- }
- avgY += y as number;
- }
- avgY /= (nextFrameEnd - nextFrameStart);
-
- const frameStart = i;
- const frameEnd = Math.min(i + frameSize, len);
-
- const pointAX = i - 1;
- const pointAY = dimStore[currentRawIndex] as number;
-
- maxArea = -1;
-
- nextRawIndex = frameStart;
- // Find a point from current frame that construct a triangel with largest area with previous selected point
- // And the average of next frame.
- for (let idx = frameStart; idx < frameEnd; idx++) {
- const rawIndex = this.getRawIndex(idx);
- const y = dimStore[rawIndex] as number;
- if (isNaN(y)) {
- continue;
- }
- // Calculate triangle area over three buckets
- area = Math.abs((pointAX - avgX) * (y - pointAY)
- - (pointAX - idx) * (avgY - pointAY)
- );
- if (area > maxArea) {
- maxArea = area;
- nextRawIndex = rawIndex; // Next a is this b
- }
- }
-
- newIndices[sampledIndex++] = nextRawIndex;
-
- currentRawIndex = nextRawIndex; // This a is the next a (chosen b)
- }
-
- // First frame use the last data.
- newIndices[sampledIndex++] = this.getRawIndex(len - 1);
- list._count = sampledIndex;
- list._indices = newIndices;
-
- list.getRawIndex = getRawIndexWithIndices;
- return list;
- }
-
-
- /**
- * Get model of one data item.
- */
- // TODO: Type of data item
- getItemModel<ItemOpts extends unknown = unknown>(idx: number): Model<ItemOpts
- // Extract item option with value key. FIXME will cause incompatitable issue
- // Extract<HostModel['option']['data'][number], { value?: any }>
- > {
- const hostModel = this.hostModel;
- const dataItem = this.getRawDataItem(idx) as ModelOption;
- return new Model(dataItem, hostModel, hostModel && hostModel.ecModel);
- }
-
- /**
- * Create a data differ
- */
- diff(otherList: List): DataDiffer {
- const thisList = this;
-
- return new DataDiffer(
- otherList ? otherList.getIndices() : [],
- this.getIndices(),
- function (idx: number) {
- return getId(otherList, idx);
- },
- function (idx: number) {
- return getId(thisList, idx);
- }
- );
- }
-
- /**
- * Get visual property.
- */
- getVisual<K extends keyof Visual>(key: K): Visual[K] {
- const visual = this._visual as Visual;
- return visual && visual[key];
- }
-
- /**
- * Set visual property
- *
- * @example
- * setVisual('color', color);
- * setVisual({
- * 'color': color
- * });
- */
- setVisual<K extends keyof Visual>(key: K, val: Visual[K]): void;
- setVisual(kvObj: Partial<Visual>): void;
- setVisual(kvObj: string | Partial<Visual>, val?: any): void {
- this._visual = this._visual || {};
- if (isObject(kvObj)) {
- zrUtil.extend(this._visual, kvObj);
- }
- else {
- this._visual[kvObj as string] = val;
- }
- }
-
- /**
- * Get visual property of single data item
- */
- // eslint-disable-next-line
- getItemVisual<K extends keyof Visual>(idx: number, key: K): Visual[K] {
- const itemVisual = this._itemVisuals[idx] as Visual;
- const val = itemVisual && itemVisual[key];
- if (val == null) {
- // Use global visual property
- return this.getVisual(key);
- }
- return val;
- }
-
- /**
- * If exists visual property of single data item
- */
- hasItemVisual() {
- return this._itemVisuals.length > 0;
- }
-
- /**
- * Make sure itemVisual property is unique
- */
- // TODO: use key to save visual to reduce memory.
- ensureUniqueItemVisual<K extends keyof Visual>(idx: number, key: K): Visual[K] {
- const itemVisuals = this._itemVisuals;
- let itemVisual = itemVisuals[idx] as Visual;
- if (!itemVisual) {
- itemVisual = itemVisuals[idx] = {} as Visual;
- }
- let val = itemVisual[key];
- if (val == null) {
- val = this.getVisual(key);
-
- // TODO Performance?
- if (zrUtil.isArray(val)) {
- val = val.slice() as unknown as Visual[K];
- }
- else if (isObject(val)) {
- val = zrUtil.extend({}, val);
- }
-
- itemVisual[key] = val;
- }
- return val;
- }
- /**
- * Set visual property of single data item
- *
- * @param {number} idx
- * @param {string|Object} key
- * @param {*} [value]
- *
- * @example
- * setItemVisual(0, 'color', color);
- * setItemVisual(0, {
- * 'color': color
- * });
- */
- // eslint-disable-next-line
- setItemVisual<K extends keyof Visual>(idx: number, key: K, value: Visual[K]): void;
- setItemVisual(idx: number, kvObject: Partial<Visual>): void;
- // eslint-disable-next-line
- setItemVisual<K extends keyof Visual>(idx: number, key: K | Partial<Visual>, value?: Visual[K]): void {
- const itemVisual = this._itemVisuals[idx] || {};
- this._itemVisuals[idx] = itemVisual;
-
- if (isObject(key)) {
- zrUtil.extend(itemVisual, key);
- }
- else {
- itemVisual[key as string] = value;
- }
- }
-
- /**
- * Clear itemVisuals and list visual.
- */
- clearAllVisual(): void {
- this._visual = {};
- this._itemVisuals = [];
- }
-
- /**
- * Set layout property.
- */
- setLayout(key: string, val: any): void;
- setLayout(kvObj: Dictionary<any>): void;
- setLayout(key: string | Dictionary<any>, val?: any): void {
- if (isObject(key)) {
- for (const name in key) {
- if (key.hasOwnProperty(name)) {
- this.setLayout(name, key[name]);
- }
- }
- return;
- }
- this._layout[key] = val;
- }
-
- /**
- * Get layout property.
- */
- getLayout(key: string): any {
- return this._layout[key];
- }
-
- /**
- * Get layout of single data item
- */
- getItemLayout(idx: number): any {
- return this._itemLayouts[idx];
- }
-
- /**
- * Set layout of single data item
- */
- setItemLayout<M = false>(
- idx: number,
- layout: (M extends true ? Dictionary<any> : any),
- merge?: M
- ): void {
- this._itemLayouts[idx] = merge
- ? zrUtil.extend(this._itemLayouts[idx] || {}, layout)
- : layout;
- }
-
- /**
- * Clear all layout of single data item
- */
- clearItemLayouts(): void {
- this._itemLayouts.length = 0;
- }
-
- /**
- * Set graphic element relative to data. It can be set as null
- */
- setItemGraphicEl(idx: number, el: Element): void {
- const hostModel = this.hostModel;
-
- if (el) {
- const ecData = getECData(el);
- // Add data index and series index for indexing the data by element
- // Useful in tooltip
- ecData.dataIndex = idx;
- ecData.dataType = this.dataType;
- ecData.seriesIndex = hostModel && (hostModel as any).seriesIndex;
-
- // TODO: not store dataIndex on children.
- if (el.type === 'group') {
- el.traverse(setItemDataAndSeriesIndex, el);
- }
- }
-
- this._graphicEls[idx] = el;
- }
-
- getItemGraphicEl(idx: number): Element {
- return this._graphicEls[idx];
- }
-
- eachItemGraphicEl<Ctx = unknown>(
- cb: (this: Ctx, el: Element, idx: number) => void,
- context?: Ctx
- ): void {
- zrUtil.each(this._graphicEls, function (el, idx) {
- if (el) {
- cb && cb.call(context, el, idx);
- }
- });
- }
-
- /**
- * Shallow clone a new list except visual and layout properties, and graph elements.
- * New list only change the indices.
- */
- cloneShallow(list?: List<HostModel>): List<HostModel> {
- if (!list) {
- const dimensionInfoList = map(this.dimensions, this.getDimensionInfo, this);
- list = new List(dimensionInfoList, this.hostModel);
- }
-
- // FIXME
- list._storage = this._storage;
- list._storageArr = this._storageArr;
-
- transferProperties(list, this);
-
- // Clone will not change the data extent and indices
- if (this._indices) {
- const Ctor = this._indices.constructor as DataArrayLikeConstructor;
- if (Ctor === Array) {
- const thisCount = this._indices.length;
- list._indices = new Ctor(thisCount);
- for (let i = 0; i < thisCount; i++) {
- list._indices[i] = this._indices[i];
- }
- }
- else {
- list._indices = new (Ctor as DataTypedArrayConstructor)(this._indices);
- }
- }
- else {
- list._indices = null;
- }
- list.getRawIndex = list._indices ? getRawIndexWithIndices : getRawIndexWithoutIndices;
-
- return list;
- }
-
- /**
- * Wrap some method to add more feature
- */
- wrapMethod(
- methodName: FunctionPropertyNames<List>,
- injectFunction: (...args: any) => any
- ): void {
- const originalMethod = this[methodName];
- if (typeof originalMethod !== 'function') {
- return;
- }
- this.__wrappedMethods = this.__wrappedMethods || [];
- this.__wrappedMethods.push(methodName);
- this[methodName] = function () {
- const res = (originalMethod as any).apply(this, arguments);
- return injectFunction.apply(this, [res].concat(zrUtil.slice(arguments)));
- };
- }
-
-
- // ----------------------------------------------------------
- // A work around for internal method visiting private member.
- // ----------------------------------------------------------
- private static internalField = (function () {
-
- defaultDimValueGetters = {
-
- arrayRows: getDimValueSimply,
-
- objectRows: function (
- this: List, dataItem: Dictionary<any>, dimName: string, dataIndex: number, dimIndex: number
- ): ParsedValue {
- return parseDataValue(dataItem[dimName], this._dimensionInfos[dimName]);
- },
-
- keyedColumns: getDimValueSimply,
-
- original: function (
- this: List, dataItem: any, dimName: string, dataIndex: number, dimIndex: number
- ): ParsedValue {
- // Performance sensitive, do not use modelUtil.getDataItemValue.
- // If dataItem is an plain object with no value field, the let `value`
- // will be assigned with the object, but it will be tread correctly
- // in the `convertValue`.
- const value = dataItem && (dataItem.value == null ? dataItem : dataItem.value);
-
- // If any dataItem is like { value: 10 }
- if (!this._rawData.pure && isDataItemOption(dataItem)) {
- this.hasItemOption = true;
- }
- return parseDataValue(
- (value instanceof Array)
- ? value[dimIndex]
- // If value is a single number or something else not array.
- : value,
- this._dimensionInfos[dimName]
- );
- },
-
- typedArray: function (
- this: List, dataItem: any, dimName: string, dataIndex: number, dimIndex: number
- ): ParsedValue {
- return dataItem[dimIndex];
- }
-
- };
-
- function getDimValueSimply(
- this: List, dataItem: any, dimName: string, dataIndex: number, dimIndex: number
- ): ParsedValue {
- return parseDataValue(dataItem[dimIndex], this._dimensionInfos[dimName]);
- }
-
- prepareInvertedIndex = function (list: List): void {
- const invertedIndicesMap = list._invertedIndicesMap;
- zrUtil.each(invertedIndicesMap, function (invertedIndices, dim) {
- const dimInfo = list._dimensionInfos[dim];
-
- // Currently, only dimensions that has ordinalMeta can create inverted indices.
- const ordinalMeta = dimInfo.ordinalMeta;
- if (ordinalMeta) {
- invertedIndices = invertedIndicesMap[dim] = new CtorInt32Array(
- ordinalMeta.categories.length
- );
- // The default value of TypedArray is 0. To avoid miss
- // mapping to 0, we should set it as INDEX_NOT_FOUND.
- for (let i = 0; i < invertedIndices.length; i++) {
- invertedIndices[i] = INDEX_NOT_FOUND;
- }
- for (let i = 0; i < list._count; i++) {
- // Only support the case that all values are distinct.
- invertedIndices[list.get(dim, i) as number] = i;
- }
- }
- });
- };
-
- getIdNameFromStore = function (
- list: List, dimIdx: number, ordinalMeta: OrdinalMeta, rawIndex: number
- ): string {
- let val;
- const chunk = list._storageArr[dimIdx];
- if (chunk) {
- val = chunk[rawIndex];
- if (ordinalMeta && ordinalMeta.categories.length) {
- val = ordinalMeta.categories[val as OrdinalNumber];
- }
- }
- return convertOptionIdName(val, null);
- };
-
- getIndicesCtor = function (list: List): DataArrayLikeConstructor {
- // The possible max value in this._indicies is always this._rawCount despite of filtering.
- return list._rawCount > 65535 ? CtorUint32Array : CtorUint16Array;
- };
-
- prepareStorage = function (
- storage: DataStorage,
- dimInfo: DataDimensionInfo,
- end: number,
- append?: boolean
- ): void {
- const DataCtor = dataCtors[dimInfo.type];
- const dim = dimInfo.name;
-
- if (append) {
- const oldStore = storage[dim];
- const oldLen = oldStore && oldStore.length;
- if (!(oldLen === end)) {
- const newStore = new DataCtor(end);
- // The cost of the copy is probably inconsiderable
- // within the initial chunkSize.
- for (let j = 0; j < oldLen; j++) {
- newStore[j] = oldStore[j];
- }
- storage[dim] = newStore;
- }
- }
- else {
- storage[dim] = new DataCtor(end);
- }
- };
-
- getRawIndexWithoutIndices = function (this: List, idx: number): number {
- return idx;
- };
-
- getRawIndexWithIndices = function (this: List, idx: number): number {
- if (idx < this._count && idx >= 0) {
- return this._indices[idx];
- }
- return -1;
- };
-
- /**
- * @see the comment of `List['getId']`.
- */
- getId = function (list: List, rawIndex: number): string {
- let id = list._idList[rawIndex];
- if (id == null && list._idDimIdx != null) {
- id = getIdNameFromStore(list, list._idDimIdx, list._idOrdinalMeta, rawIndex);
- }
- if (id == null) {
- id = ID_PREFIX + rawIndex;
- }
- return id;
- };
-
- normalizeDimensions = function (
- dimensions: ItrParamDims
- ): Array<DimensionLoose> {
- if (!zrUtil.isArray(dimensions)) {
- dimensions = dimensions != null ? [dimensions] : [];
- }
- return dimensions;
- };
-
- validateDimensions = function (list: List, dims: DimensionName[]): void {
- for (let i = 0; i < dims.length; i++) {
- // stroage may be empty when no data, so use
- // dimensionInfos to check.
- if (!list._dimensionInfos[dims[i]]) {
- console.error('Unkown dimension ' + dims[i]);
- }
- }
- };
-
- // Data in excludeDimensions is copied, otherwise transfered.
- cloneListForMapAndSample = function (
- original: List, excludeDimensions: DimensionName[]
- ): List {
- const allDimensions = original.dimensions;
- const list = new List(
- map(allDimensions, original.getDimensionInfo, original),
- original.hostModel
- );
- // FIXME If needs stackedOn, value may already been stacked
- transferProperties(list, original);
-
- const storage = list._storage = {} as DataStorage;
- const originalStorage = original._storage;
- const storageArr: DataValueChunk[] = list._storageArr = [];
-
- // Init storage
- for (let i = 0; i < allDimensions.length; i++) {
- const dim = allDimensions[i];
- if (originalStorage[dim]) {
- // Notice that we do not reset invertedIndicesMap here, becuase
- // there is no scenario of mapping or sampling ordinal dimension.
- if (zrUtil.indexOf(excludeDimensions, dim) >= 0) {
- storage[dim] = cloneChunk(originalStorage[dim]);
- list._rawExtent[dim] = getInitialExtent();
- list._extent[dim] = null;
- }
- else {
- // Direct reference for other dimensions
- storage[dim] = originalStorage[dim];
- }
- storageArr.push(storage[dim]);
- }
- }
- return list;
- };
-
- function cloneChunk(originalChunk: DataValueChunk): DataValueChunk {
- const Ctor = originalChunk.constructor;
- // Only shallow clone is enough when Array.
- return Ctor === Array
- ? (originalChunk as Array<ParsedValue>).slice()
- : new (Ctor as DataTypedArrayConstructor)(originalChunk as DataTypedArray);
- }
-
- getInitialExtent = function (): [number, number] {
- return [Infinity, -Infinity];
- };
-
- setItemDataAndSeriesIndex = function (this: Element, child: Element): void {
- const childECData = getECData(child);
- const thisECData = getECData(this);
- childECData.seriesIndex = thisECData.seriesIndex;
- childECData.dataIndex = thisECData.dataIndex;
- childECData.dataType = thisECData.dataType;
- };
-
- transferProperties = function (target: List, source: List): void {
- zrUtil.each(
- TRANSFERABLE_PROPERTIES.concat(source.__wrappedMethods || []),
- function (propName) {
- if (source.hasOwnProperty(propName)) {
- (target as any)[propName] = (source as any)[propName];
- }
- }
- );
-
- target.__wrappedMethods = source.__wrappedMethods;
-
- zrUtil.each(CLONE_PROPERTIES, function (propName) {
- (target as any)[propName] = zrUtil.clone((source as any)[propName]);
- });
-
- target._calculationInfo = zrUtil.extend({}, source._calculationInfo);
- };
-
- makeIdFromName = function (list: List, idx: number): void {
- const nameList = list._nameList;
- const idList = list._idList;
- const nameDimIdx = list._nameDimIdx;
- const idDimIdx = list._idDimIdx;
-
- let name = nameList[idx];
- let id = idList[idx];
-
- if (name == null && nameDimIdx != null) {
- nameList[idx] = name = getIdNameFromStore(list, nameDimIdx, list._nameOrdinalMeta, idx);
- }
- if (id == null && idDimIdx != null) {
- idList[idx] = id = getIdNameFromStore(list, idDimIdx, list._idOrdinalMeta, idx);
- }
- if (id == null && name != null) {
- const nameRepeatCount = list._nameRepeatCount;
- const nmCnt = nameRepeatCount[name] = (nameRepeatCount[name] || 0) + 1;
- id = name;
- if (nmCnt > 1) {
- id += '__ec__' + nmCnt;
- }
- idList[idx] = id;
- }
- };
-
- })();
-
-}
-
-interface List {
- getLinkedData(dataType?: SeriesDataType): List;
- getLinkedDataAll(): { data: List, type?: SeriesDataType }[];
-}
-
-export default List;
diff --git a/src/data/SeriesData.ts b/src/data/SeriesData.ts
new file mode 100644
index 0000000..553a225
--- /dev/null
+++ b/src/data/SeriesData.ts
@@ -0,0 +1,1299 @@
+/*
+* 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.
+*/
+
+/* global Float64Array, Int32Array, Uint32Array, Uint16Array */
+
+/**
+ * List for data storage
+ */
+
+import * as zrUtil from 'zrender/src/core/util';
+import {PathStyleProps} from 'zrender/src/graphic/Path';
+import Model from '../model/Model';
+import DataDiffer from './DataDiffer';
+import {DefaultDataProvider} from './helper/dataProvider';
+import {summarizeDimensions, DimensionSummary} from './helper/dimensionHelper';
+import DataDimensionInfo from './DataDimensionInfo';
+import {ArrayLike, Dictionary, FunctionPropertyNames} from 'zrender/src/core/types';
+import Element from 'zrender/src/Element';
+import {
+ DimensionIndex, DimensionName, DimensionLoose, OptionDataItem,
+ ParsedValue, ParsedValueNumeric, DimensionUserOuput,
+ ModelOption, SeriesDataType, OptionSourceData, SOURCE_FORMAT_TYPED_ARRAY, SOURCE_FORMAT_ORIGINAL,
+ DecalObject,
+ OrdinalNumber
+} from '../util/types';
+import {convertOptionIdName, isDataItemOption} from '../util/model';
+import { getECData } from '../util/innerStore';
+import type Graph from './Graph';
+import type Tree from './Tree';
+import type { VisualMeta } from '../component/visualMap/VisualMapModel';
+import {isSourceInstance, Source} from './Source';
+import { LineStyleProps } from '../model/mixin/lineStyle';
+import DataStorage, { DimValueGetter } from './DataStorage';
+
+const isObject = zrUtil.isObject;
+const map = zrUtil.map;
+
+const CtorInt32Array = typeof Int32Array === 'undefined' ? Array : Int32Array;
+
+// Use prefix to avoid index to be the same as otherIdList[idx],
+// which will cause weird udpate animation.
+const ID_PREFIX = 'e\0\0';
+
+const INDEX_NOT_FOUND = -1;
+
+type NameRepeatCount = {[name: string]: number};
+type ItrParamDims = DimensionLoose | Array<DimensionLoose>;
+// If Ctx not specified, use List as Ctx
+type CtxOrList<Ctx> = unknown extends Ctx ? SeriesData : Ctx;
+type EachCb0<Ctx> = (this: CtxOrList<Ctx>, idx: number) => void;
+type EachCb1<Ctx> = (this: CtxOrList<Ctx>, x: ParsedValue, idx: number) => void;
+type EachCb2<Ctx> = (this: CtxOrList<Ctx>, x: ParsedValue, y: ParsedValue, idx: number) => void;
+type EachCb<Ctx> = (this: CtxOrList<Ctx>, ...args: any) => void;
+type FilterCb0<Ctx> = (this: CtxOrList<Ctx>, idx: number) => boolean;
+type FilterCb1<Ctx> = (this: CtxOrList<Ctx>, x: ParsedValue, idx: number) => boolean;
+type FilterCb2<Ctx> = (this: CtxOrList<Ctx>, x: ParsedValue, y: ParsedValue, idx: number) => boolean;
+type FilterCb<Ctx> = (this: CtxOrList<Ctx>, ...args: any) => boolean;
+type MapArrayCb0<Ctx> = (this: CtxOrList<Ctx>, idx: number) => any;
+type MapArrayCb1<Ctx> = (this: CtxOrList<Ctx>, x: ParsedValue, idx: number) => any;
+type MapArrayCb2<Ctx> = (this: CtxOrList<Ctx>, x: ParsedValue, y: ParsedValue, idx: number) => any;
+type MapArrayCb<Ctx> = (this: CtxOrList<Ctx>, ...args: any) => any;
+type MapCb1<Ctx> = (this: CtxOrList<Ctx>, x: ParsedValue, idx: number) => ParsedValue | ParsedValue[];
+type MapCb2<Ctx> = (this: CtxOrList<Ctx>, x: ParsedValue, y: ParsedValue, idx: number) =>
+ ParsedValue | ParsedValue[];
+type MapCb<Ctx> = (this: CtxOrList<Ctx>, ...args: any) => ParsedValue | ParsedValue[];
+
+const TRANSFERABLE_PROPERTIES = [
+ 'hasItemOption', '_nameList', '_idList', '_invertedIndicesMap',
+ '_rawData', '_dimValueGetter', '_store',
+ '_nameDimIdx', '_idDimIdx', '_nameRepeatCount'
+];
+const CLONE_PROPERTIES = [
+ '_approximateExtent'
+];
+
+export interface DefaultDataVisual {
+ style: PathStyleProps
+ // Draw type determined which prop should be set with encoded color.
+ // It's only available on the global visual. Use getVisual('drawType') to access it.
+ // It will be set in visual/style.ts module in the first priority.
+ drawType: 'fill' | 'stroke'
+
+ symbol?: string
+ symbolSize?: number | number[]
+ symbolRotate?: number
+ symbolKeepAspect?: boolean
+ symbolOffset?: string | number | (string | number)[]
+
+ liftZ?: number
+ // For legend.
+ legendIcon?: string
+ legendLineStyle?: LineStyleProps
+
+ // visualMap will inject visualMeta data
+ visualMeta?: VisualMeta[]
+
+ // If color is encoded from palette
+ colorFromPalette?: boolean
+
+ decal?: DecalObject
+}
+
+export interface DataCalculationInfo<SERIES_MODEL> {
+ stackedDimension: string;
+ stackedByDimension: string;
+ isStackedByIndex: boolean;
+ stackedOverDimension: string;
+ stackResultDimension: string;
+ stackedOnSeries?: SERIES_MODEL;
+}
+
+// -----------------------------
+// Internal method declarations:
+// -----------------------------
+let prepareInvertedIndex: (list: SeriesData) => void;
+let getId: (list: SeriesData, rawIndex: number) => string;
+let getIdNameFromStore: (list: SeriesData, dimIdx: number, dataIdx: number) => string;
+let normalizeDimensions: (dimensions: ItrParamDims) => Array<DimensionLoose>;
+let validateDimensions: (list: SeriesData, dims: DimensionIndex[]) => void;
+let setItemDataAndSeriesIndex: (this: Element, child: Element) => void;
+let transferProperties: (target: SeriesData, source: SeriesData) => void;
+let cloneListForMapAndSample: (original: SeriesData) => SeriesData;
+
+class SeriesData<
+ HostModel extends Model = Model,
+ Visual extends DefaultDataVisual = DefaultDataVisual
+> {
+
+ readonly type = 'list';
+
+ readonly dimensions: string[];
+
+ // Infomation of each data dimension, like data type.
+ private _dimensionInfos: {[dimName: string]: DataDimensionInfo};
+
+ readonly hostModel: HostModel;
+
+ /**
+ * @readonly
+ */
+ dataType: SeriesDataType;
+
+ /**
+ * @readonly
+ * Host graph if List is used to store graph nodes / edges.
+ */
+ graph?: Graph;
+
+ /**
+ * @readonly
+ * Host tree if List is used to store tree ndoes.
+ */
+ tree?: Tree;
+
+ private _store: DataStorage;
+
+ private _nameList: string[] = [];
+ private _idList: string[] = [];
+
+ // Models of data option is stored sparse for optimizing memory cost
+ // Never used yet (not used yet).
+ // private _optionModels: Model[] = [];
+
+ // Global visual properties after visual coding
+ private _visual: Dictionary<any> = {};
+
+ // Globel layout properties.
+ private _layout: Dictionary<any> = {};
+
+ // Item visual properties after visual coding
+ private _itemVisuals: Dictionary<any>[] = [];
+
+ // Item layout properties after layout
+ private _itemLayouts: any[] = [];
+
+ // Graphic elemnents
+ private _graphicEls: Element[] = [];
+
+ // key: dim, value: extent
+ private _approximateExtent: {[dimName: string]: [number, number]} = {};
+
+ private _dimensionsSummary: DimensionSummary;
+
+ private _invertedIndicesMap: {[dimName: string]: ArrayLike<number>};
+
+ private _calculationInfo: DataCalculationInfo<HostModel> = {} as DataCalculationInfo<HostModel>;
+
+ // User output info of this data.
+ // DO NOT use it in other places!
+ // When preparing user params for user callbacks, we have
+ // to clone these inner data structures to prevent users
+ // from modifying them to effect built-in logic. And for
+ // performance consideration we make this `userOutput` to
+ // avoid clone them too many times.
+ readonly userOutput: DimensionUserOuput;
+
+ // Having detected that there is data item is non primitive type
+ // (in type `OptionDataItemObject`).
+ // Like `data: [ { value: xx, itemStyle: {...} }, ...]`
+ // At present it only happen in `SOURCE_FORMAT_ORIGINAL`.
+ hasItemOption: boolean = false;
+
+ // id or name is used on dynamic data, mapping old and new items.
+ // When generating id from name, avoid repeat.
+ private _nameRepeatCount: NameRepeatCount;
+ private _nameDimIdx: number;
+ private _idDimIdx: number;
+
+ private __wrappedMethods: string[];
+
+ // Methods that create a new list based on this list should be listed here.
+ // Notice that those method should `RETURN` the new list.
+ TRANSFERABLE_METHODS = ['cloneShallow', 'downSample', 'lttbDownSample', 'map'] as const;
+ // Methods that change indices of this list should be listed here.
+ CHANGABLE_METHODS = ['filterSelf', 'selectRange'] as const;
+ DOWNSAMPLE_METHODS = ['downSample', 'lttbDownSample'] as const;
+
+ /**
+ * @param dimensions
+ * For example, ['someDimName', {name: 'someDimName', type: 'someDimType'}, ...].
+ * Dimensions should be concrete names like x, y, z, lng, lat, angle, radius
+ */
+ constructor(dimensions: Array<string | object | DataDimensionInfo>, hostModel: HostModel) {
+ dimensions = dimensions || ['x', 'y'];
+
+ const dimensionInfos: Dictionary<DataDimensionInfo> = {};
+ const dimensionNames = [];
+ const invertedIndicesMap: Dictionary<number[]> = {};
+
+ for (let i = 0; i < dimensions.length; i++) {
+ // Use the original dimensions[i], where other flag props may exists.
+ const dimInfoInput = dimensions[i];
+
+ const dimensionInfo: DataDimensionInfo =
+ zrUtil.isString(dimInfoInput)
+ ? new DataDimensionInfo({name: dimInfoInput})
+ : !(dimInfoInput instanceof DataDimensionInfo)
+ ? new DataDimensionInfo(dimInfoInput)
+ : dimInfoInput;
+
+ const dimensionName = dimensionInfo.name;
+ dimensionInfo.type = dimensionInfo.type || 'float';
+ if (!dimensionInfo.coordDim) {
+ dimensionInfo.coordDim = dimensionName;
+ dimensionInfo.coordDimIndex = 0;
+ }
+
+ const otherDims = dimensionInfo.otherDims = dimensionInfo.otherDims || {};
+ dimensionNames.push(dimensionName);
+ dimensionInfos[dimensionName] = dimensionInfo;
+
+ dimensionInfo.index = i;
+
+ if (dimensionInfo.createInvertedIndices) {
+ invertedIndicesMap[dimensionName] = [];
+ }
+ if (otherDims.itemName === 0) {
+ this._nameDimIdx = i;
+ }
+ if (otherDims.itemId === 0) {
+ this._idDimIdx = i;
+ }
+ }
+
+ this.dimensions = dimensionNames;
+ this._dimensionInfos = dimensionInfos;
+ this.hostModel = hostModel;
+
+ // Cache summary info for fast visit. See "dimensionHelper".
+ this._dimensionsSummary = summarizeDimensions(this);
+
+ this._invertedIndicesMap = invertedIndicesMap;
+
+ this.userOutput = this._dimensionsSummary.userOutput;
+ }
+
+ /**
+ * The meanings of the input parameter `dim`:
+ *
+ * + If dim is a number (e.g., `1`), it means the index of the dimension.
+ * For example, `getDimension(0)` will return 'x' or 'lng' or 'radius'.
+ * + If dim is a number-like string (e.g., `"1"`):
+ * + If there is the same concrete dim name defined in `this.dimensions`, it means that concrete name.
+ * + If not, it will be converted to a number, which means the index of the dimension.
+ * (why? because of the backward compatbility. We have been tolerating number-like string in
+ * dimension setting, although now it seems that it is not a good idea.)
+ * For example, `visualMap[i].dimension: "1"` is the same meaning as `visualMap[i].dimension: 1`,
+ * if no dimension name is defined as `"1"`.
+ * + If dim is a not-number-like string, it means the concrete dim name.
+ * For example, it can be be default name `"x"`, `"y"`, `"z"`, `"lng"`, `"lat"`, `"angle"`, `"radius"`,
+ * or customized in `dimensions` property of option like `"age"`.
+ *
+ * Get dimension name
+ * @param dim See above.
+ * @return Concrete dim name.
+ */
+ getDimension(dim: DimensionLoose): DimensionName {
+ if (typeof dim === 'number'
+ // If being a number-like string but not being defined a dimension name.
+ || (!isNaN(dim as any) && !this._dimensionInfos.hasOwnProperty(dim))
+ ) {
+ dim = this.dimensions[dim as DimensionIndex];
+ }
+ return dim as DimensionName;
+ }
+
+ getDimensionIndex(dim: DimensionLoose): DimensionIndex {
+ if (typeof dim === 'number') {
+ return dim;
+ }
+ const idx = this._store.getDimensionIndex(dim);
+ if (idx == null) {
+ // If being a number-like string but not being defined a dimension name.
+ return +dim;
+ }
+ return idx;
+ }
+
+ /**
+ * Get type and calculation info of particular dimension
+ * @param dim
+ * Dimension can be concrete names like x, y, z, lng, lat, angle, radius
+ * Or a ordinal number. For example getDimensionInfo(0) will return 'x' or 'lng' or 'radius'
+ */
+ getDimensionInfo(dim: DimensionLoose): DataDimensionInfo {
+ // Do not clone, because there may be categories in dimInfo.
+ return this._dimensionInfos[this.getDimension(dim)];
+ }
+
+ /**
+ * concrete dimension name list on coord.
+ */
+ getDimensionsOnCoord(): DimensionName[] {
+ return this._dimensionsSummary.dataDimsOnCoord.slice();
+ }
+
+ /**
+ * @param coordDim
+ * @param idx A coordDim may map to more than one data dim.
+ * If not specified, return the first dim not extra.
+ * @return concrete data dim. If not found, return null/undefined
+ */
+ mapDimension(coordDim: DimensionName): DimensionName;
+ mapDimension(coordDim: DimensionName, idx: number): DimensionName;
+ mapDimension(coordDim: DimensionName, idx?: number): DimensionName {
+ const dimensionsSummary = this._dimensionsSummary;
+
+ if (idx == null) {
+ return dimensionsSummary.encodeFirstDimNotExtra[coordDim] as any;
+ }
+
+ const dims = dimensionsSummary.encode[coordDim];
+ return dims ? dims[idx as number] as any : null;
+ }
+
+ mapDimensionsAll(coordDim: DimensionName): DimensionName[] {
+ const dimensionsSummary = this._dimensionsSummary;
+ const dims = dimensionsSummary.encode[coordDim];
+ return (dims || []).slice();
+ }
+
+ getStore() {
+ return this._store;
+ }
+
+ /**
+ * Initialize from data
+ * @param data source or data or data storage.
+ * @param nameList The name of a datum is used on data diff and
+ * default label/tooltip.
+ * A name can be specified in encode.itemName,
+ * or dataItem.name (only for series option data),
+ * or provided in nameList from outside.
+ */
+ initData(
+ data: Source | OptionSourceData | DataStorage,
+ nameList?: string[],
+ dimValueGetter?: DimValueGetter
+ ): void {
+ const isRaw = isSourceInstance(data) || zrUtil.isArrayLike(data);
+ let store: DataStorage;
+ if (isRaw) {
+ const provider = new DefaultDataProvider(data as Source | OptionSourceData, this.dimensions.length);
+ const dimensionInfos = map(this.dimensions, dimName => this._dimensionInfos[dimName]);
+ store = new DataStorage();
+ store.initData(provider, dimensionInfos, dimValueGetter);
+ }
+ else {
+ store = data as DataStorage;
+ }
+
+ this._store = store;
+
+ // Reset
+ this._nameList = (nameList || []).slice();
+ this._idList = [];
+ this._nameRepeatCount = {};
+
+ this._doInit(0, store.count());
+ }
+
+ /**
+ * Caution: Can be only called on raw data (before `this._indices` created).
+ */
+ appendData(data: ArrayLike<any>): void {
+ const range = this._store.appendData(data);
+ this._doInit(range[0], range[1]);
+ }
+
+ private _doInit(start: number, end: number): void {
+ if (start >= end) {
+ return;
+ }
+
+ const store = this._store;
+ const provider = store.getProvider();
+
+ const nameList = this._nameList;
+ const idList = this._idList;
+ const sourceFormat = provider.getSource().sourceFormat;
+ const isFormatOriginal = sourceFormat === SOURCE_FORMAT_ORIGINAL;
+
+ const dontMakeIdFromName = this._idDimIdx != null
+ || sourceFormat === SOURCE_FORMAT_TYPED_ARRAY // Consider performance.
+ || !!provider.fillStorage;
+
+ // Each data item is value
+ // [1, 2]
+ // 2
+ // Bar chart, line chart which uses category axis
+ // only gives the 'y' value. 'x' value is the indices of category
+ // Use a tempValue to normalize the value to be a (x, y) value
+ // If dataItem is {name: ...} or {id: ...}, it has highest priority.
+ // This kind of ids and names are always stored `_nameList` and `_idList`.
+ if (isFormatOriginal && !provider.pure) {
+ const sharedDataItem = [] as OptionDataItem;
+ for (let idx = start; idx < end; idx++) {
+ // NOTICE: Try not to write things into dataItem
+ const dataItem = provider.getItem(idx, sharedDataItem);
+ if (!this.hasItemOption && isDataItemOption(dataItem)) {
+ this.hasItemOption = true;
+ }
+ if (dataItem) {
+ const itemName = (dataItem as any).name;
+ if (nameList[idx] == null && itemName != null) {
+ nameList[idx] = convertOptionIdName(itemName, null);
+ }
+ const itemId = (dataItem as any).id;
+ if (idList[idx] == null && itemId != null) {
+ idList[idx] = convertOptionIdName(itemId, null);
+ }
+ }
+ }
+ }
+
+ if (!dontMakeIdFromName) {
+ const nameDimIdx = this._nameDimIdx;
+ const idDimIdx = this._idDimIdx;
+
+ for (let idx = start; idx < end; idx++) {
+ let name = nameList[idx];
+ let id = idList[idx];
+
+ if (name == null && nameDimIdx != null) {
+ nameList[idx] = name = getIdNameFromStore(this, nameDimIdx, idx);
+ }
+ if (id == null && idDimIdx != null) {
+ idList[idx] = id = getIdNameFromStore(this, idDimIdx, idx);
+ }
+ if (id == null && name != null) {
+ const nameRepeatCount = this._nameRepeatCount;
+ const nmCnt = nameRepeatCount[name] = (nameRepeatCount[name] || 0) + 1;
+ id = name;
+ if (nmCnt > 1) {
+ id += '__ec__' + nmCnt;
+ }
+ idList[idx] = id;
+ }
+ }
+ }
+
+ prepareInvertedIndex(this);
+ }
+ /**
+ * PENDING: In fact currently this function is only used to short-circuit
+ * the calling of `scale.unionExtentFromData` when data have been filtered by modules
+ * like "dataZoom". `scale.unionExtentFromData` is used to calculate data extent for series on
+ * an axis, but if a "axis related data filter module" is used, the extent of the axis have
+ * been fixed and no need to calling `scale.unionExtentFromData` actually.
+ * But if we add "custom data filter" in future, which is not "axis related", this method may
+ * be still needed.
+ *
+ * Optimize for the scenario that data is filtered by a given extent.
+ * Consider that if data amount is more than hundreds of thousand,
+ * extent calculation will cost more than 10ms and the cache will
+ * be erased because of the filtering.
+ */
+ getApproximateExtent(dim: DimensionLoose): [number, number] {
+ return this._approximateExtent[dim] || this._store.getDataExtent(this.getDimensionIndex(dim));
+ }
+
+ /**
+ * Calculate extent on a filtered data might be time consuming.
+ * Approximate extent is only used for: calculte extent of filtered data outside.
+ */
+ setApproximateExtent(extent: [number, number], dim: DimensionLoose): void {
+ dim = this.getDimension(dim);
+ this._approximateExtent[dim] = extent.slice() as [number, number];
+ }
+
+ getCalculationInfo<CALC_INFO_KEY extends keyof DataCalculationInfo<HostModel>>(
+ key: CALC_INFO_KEY
+ ): DataCalculationInfo<HostModel>[CALC_INFO_KEY] {
+ return this._calculationInfo[key];
+ }
+
+ /**
+ * @param key or k-v object
+ */
+ setCalculationInfo(
+ key: DataCalculationInfo<HostModel>
+ ): void;
+ setCalculationInfo<CALC_INFO_KEY extends keyof DataCalculationInfo<HostModel>>(
+ key: CALC_INFO_KEY,
+ value: DataCalculationInfo<HostModel>[CALC_INFO_KEY]
+ ): void;
+ setCalculationInfo(
+ key: (keyof DataCalculationInfo<HostModel>) | DataCalculationInfo<HostModel>,
+ value?: DataCalculationInfo<HostModel>[keyof DataCalculationInfo<HostModel>]
+ ): void {
+ isObject(key)
+ ? zrUtil.extend(this._calculationInfo, key as object)
+ : ((this._calculationInfo as any)[key] = value);
+ }
+
+ /**
+ * @return Never be null/undefined. `number` will be converted to string. Becuase:
+ * In most cases, name is used in display, where returning a string is more convenient.
+ * In other cases, name is used in query (see `indexOfName`), where we can keep the
+ * rule that name `2` equals to name `'2'`.
+ */
+ getName(idx: number): string {
+ const rawIndex = this.getRawIndex(idx);
+ let name = this._nameList[rawIndex];
+ if (name == null && this._nameDimIdx != null) {
+ name = getIdNameFromStore(this, this._nameDimIdx, rawIndex);
+ }
+ if (name == null) {
+ name = '';
+ }
+ return name;
+ }
+
+ /**
+ * @return Never null/undefined. `number` will be converted to string. Becuase:
+ * In all cases having encountered at present, id is used in making diff comparison, which
+ * are usually based on hash map. We can keep the rule that the internal id are always string
+ * (treat `2` is the same as `'2'`) to make the related logic simple.
+ */
+ getId(idx: number): string {
+ return getId(this, this.getRawIndex(idx));
+ }
+
+ count() {
+ return this._store.count();
+ }
+ /**
+ * Get value. Return NaN if idx is out of range.
+ * @param dim Dim must be concrete name.
+ */
+ get(dim: DimensionName, idx: number): ParsedValue {
+ const store = this._store;
+ return store.get(store.getDimensionIndex(dim), idx);
+ }
+
+ getByRawIndex(dim: DimensionName, rawIdx: number): ParsedValue {
+ const store = this._store;
+ return store.getByRawIndex(store.getDimensionIndex(dim), rawIdx);
+ }
+
+ getIndices() {
+ return this._store.getIndices();
+ }
+
+ getDataExtent(dim: DimensionLoose): [number, number] {
+ return this._store.getDataExtent(this.getDimensionIndex(dim));
+ }
+
+ getSum(dim: DimensionLoose): number {
+ return this._store.getSum(this.getDimensionIndex(dim));
+ }
+
+ getMedian(dim: DimensionLoose): number {
+ return this._store.getMedian(this.getDimensionIndex(dim));
+ }
+ /**
+ * Get value for multi dimensions.
+ * @param dimensions If ignored, using all dimensions.
+ */
+ getValues(idx: number): ParsedValue[];
+ getValues(dimensions: readonly DimensionName[], idx: number): ParsedValue[];
+ getValues(dimensions: readonly DimensionName[] | number, idx?: number): ParsedValue[] {
+ const values = [];
+ if (!zrUtil.isArray(dimensions)) {
+ // stack = idx;
+ idx = dimensions as number;
+ dimensions = this.dimensions;
+ }
+
+ for (let i = 0, len = dimensions.length; i < len; i++) {
+ values.push(this.get(dimensions[i], idx));
+ }
+
+ return values;
+ }
+
+ /**
+ * If value is NaN. Inlcuding '-'
+ * Only check the coord dimensions.
+ */
+ hasValue(idx: number): boolean {
+ const dataDimsOnCoord = this._dimensionsSummary.dataDimsOnCoord;
+ for (let i = 0, len = dataDimsOnCoord.length; i < len; i++) {
+ // Ordinal type originally can be string or number.
+ // But when an ordinal type is used on coord, it can
+ // not be string but only number. So we can also use isNaN.
+ if (isNaN(this.get(dataDimsOnCoord[i], idx) as any)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Retreive the index with given name
+ */
+ indexOfName(name: string): number {
+ for (let i = 0, len = this._store.count(); i < len; i++) {
+ if (this.getName(i) === name) {
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ getRawIndex(idx: number) {
+ return this._store.getRawIndex(idx);
+ }
+
+ indexOfRawIndex(rawIndex: number) {
+ return this._store.indexOfRawIndex(rawIndex);
+ }
+
+ /**
+ * Only support the dimension which inverted index created.
+ * Do not support other cases until required.
+ * @param dim concrete dim
+ * @param value ordinal index
+ * @return rawIndex
+ */
+ rawIndexOf(dim: DimensionName, value: OrdinalNumber): number {
+ const invertedIndices = dim && this._invertedIndicesMap[dim];
+ if (__DEV__) {
+ if (!invertedIndices) {
+ throw new Error('Do not supported yet');
+ }
+ }
+ const rawIndex = invertedIndices[value];
+ if (rawIndex == null || isNaN(rawIndex)) {
+ return INDEX_NOT_FOUND;
+ }
+ return rawIndex;
+ }
+
+ /**
+ * Retreive the index of nearest value
+ * @param dim
+ * @param value
+ * @param [maxDistance=Infinity]
+ * @return If and only if multiple indices has
+ * the same value, they are put to the result.
+ */
+ indicesOfNearest(dim: DimensionLoose, value: number, maxDistance?: number): number[] {
+ return this._store.indicesOfNearest(
+ this.getDimensionIndex(dim),
+ value, maxDistance
+ );
+ }
+ /**
+ * Data iteration
+ * @param ctx default this
+ * @example
+ * list.each('x', function (x, idx) {});
+ * list.each(['x', 'y'], function (x, y, idx) {});
+ * list.each(function (idx) {})
+ */
+ each<Ctx>(cb: EachCb0<Ctx>, ctx?: Ctx, ctxCompat?: Ctx): void;
+ each<Ctx>(dims: DimensionLoose, cb: EachCb1<Ctx>, ctx?: Ctx): void;
+ each<Ctx>(dims: [DimensionLoose], cb: EachCb1<Ctx>, ctx?: Ctx): void;
+ each<Ctx>(dims: [DimensionLoose, DimensionLoose], cb: EachCb2<Ctx>, ctx?: Ctx): void;
+ each<Ctx>(dims: ItrParamDims, cb: EachCb<Ctx>, ctx?: Ctx): void;
+ each<Ctx>(
+ dims: ItrParamDims | EachCb<Ctx>,
+ cb: EachCb<Ctx> | Ctx,
+ ctx?: Ctx
+ ): void {
+ 'use strict';
+
+ if (typeof dims === 'function') {
+ ctx = cb as Ctx;
+ cb = dims;
+ dims = [];
+ }
+
+ // ctxCompat just for compat echarts3
+ const fCtx = (ctx || this) as CtxOrList<Ctx>;
+
+ const dimIndices = map(normalizeDimensions(dims), this.getDimensionIndex, this);
+
+ if (__DEV__) {
+ validateDimensions(this, dimIndices);
+ }
+
+ this._store.each(dimIndices, (fCtx
+ ? zrUtil.bind(cb as any, fCtx as any)
+ : cb) as any
+ );
+ }
+ /**
+ * Data filter
+ */
+ filterSelf<Ctx>(cb: FilterCb0<Ctx>, ctx?: Ctx, ctxCompat?: Ctx): this;
+ filterSelf<Ctx>(dims: DimensionLoose, cb: FilterCb1<Ctx>, ctx?: Ctx): this;
+ filterSelf<Ctx>(dims: [DimensionLoose], cb: FilterCb1<Ctx>, ctx?: Ctx): this;
+ filterSelf<Ctx>(dims: [DimensionLoose, DimensionLoose], cb: FilterCb2<Ctx>, ctx?: Ctx): this;
+ filterSelf<Ctx>(dims: ItrParamDims, cb: FilterCb<Ctx>, ctx?: Ctx): this;
+ filterSelf<Ctx>(
+ dims: ItrParamDims | FilterCb<Ctx>,
+ cb: FilterCb<Ctx> | Ctx,
+ ctx?: Ctx
+ ): SeriesData {
+ 'use strict';
+
+ if (typeof dims === 'function') {
+ ctx = cb as Ctx;
+ cb = dims;
+ dims = [];
+ }
+
+ // ctxCompat just for compat echarts3
+ const fCtx = (ctx || this) as CtxOrList<Ctx>;
+
+ const dimIndices = map(normalizeDimensions(dims), this.getDimensionIndex, this);
+
+ if (__DEV__) {
+ validateDimensions(this, dimIndices);
+ }
+
+ this._store.filterSelf(dimIndices, (fCtx
+ ? zrUtil.bind(cb as any, fCtx as any)
+ : cb) as any
+ );
+
+ return this;
+ }
+
+ /**
+ * Select data in range. (For optimization of filter)
+ * (Manually inline code, support 5 million data filtering in data zoom.)
+ */
+ selectRange(range: Record<string, [number, number]>): SeriesData {
+ 'use strict';
+
+ const innerRange: Record<number, [number, number]> = {};
+ const dims = zrUtil.keys(range);
+ const dimIndices: number[] = [];
+ zrUtil.each(dims, (dim) => {
+ const dimIdx = this.getDimensionIndex(dim);
+ innerRange[dimIdx] = range[dim];
+ dimIndices.push(dimIdx);
+ });
+
+ if (__DEV__) {
+ validateDimensions(this, dimIndices);
+ }
+
+ this._store.selectRange(innerRange);
+ return this;
+ }
+
+ /**
+ * Data mapping to a plain array
+ */
+ mapArray<Ctx, Cb extends MapArrayCb0<Ctx>>(cb: Cb, ctx?: Ctx, ctxCompat?: Ctx): ReturnType<Cb>[];
+ /* eslint-disable */
+ mapArray<Ctx, Cb extends MapArrayCb1<Ctx>>(dims: DimensionLoose, cb: Cb, ctx?: Ctx, ctxCompat?: Ctx): ReturnType<Cb>[];
+ mapArray<Ctx, Cb extends MapArrayCb1<Ctx>>(dims: [DimensionLoose], cb: Cb, ctx?: Ctx, ctxCompat?: Ctx): ReturnType<Cb>[];
+ mapArray<Ctx, Cb extends MapArrayCb2<Ctx>>(dims: [DimensionLoose, DimensionLoose], cb: Cb, ctx?: Ctx, ctxCompat?: Ctx): ReturnType<Cb>[];
+ mapArray<Ctx, Cb extends MapArrayCb<Ctx>>(dims: ItrParamDims, cb: Cb, ctx?: Ctx, ctxCompat?: Ctx): ReturnType<Cb>[];
+ /* eslint-enable */
+ mapArray<Ctx>(
+ dims: ItrParamDims | MapArrayCb<Ctx>,
+ cb: MapArrayCb<Ctx> | Ctx,
+ ctx?: Ctx
+ ): unknown[] {
+ 'use strict';
+
+ if (typeof dims === 'function') {
+ ctx = cb as Ctx;
+ cb = dims;
+ dims = [];
+ }
+
+ // ctxCompat just for compat echarts3
+ ctx = (ctx || this) as Ctx;
+
+ const result: unknown[] = [];
+ this.each(dims, function () {
+ result.push(cb && (cb as MapArrayCb<Ctx>).apply(this, arguments));
+ }, ctx);
+ return result;
+ }
+
+ /**
+ * Data mapping to a new List with given dimensions
+ */
+ map<Ctx>(dims: DimensionLoose, cb: MapCb1<Ctx>, ctx?: Ctx, ctxCompat?: Ctx): SeriesData<HostModel>;
+ map<Ctx>(dims: [DimensionLoose], cb: MapCb1<Ctx>, ctx?: Ctx, ctxCompat?: Ctx): SeriesData<HostModel>;
+ /* eslint-disable-next-line */
+ map<Ctx>(dims: [DimensionLoose, DimensionLoose], cb: MapCb2<Ctx>, ctx?: Ctx, ctxCompat?: Ctx): SeriesData<HostModel>;
+ map<Ctx>(
+ dims: ItrParamDims,
+ cb: MapCb<Ctx>,
+ ctx?: Ctx,
+ ctxCompat?: Ctx
+ ): SeriesData {
+ 'use strict';
+
+ // ctxCompat just for compat echarts3
+ const fCtx = (ctx || ctxCompat || this) as CtxOrList<Ctx>;
+
+ const dimIndices = map(
+ normalizeDimensions(dims), this.getDimensionIndex, this
+ );
+
+ if (__DEV__) {
+ validateDimensions(this, dimIndices);
+ }
+
+ const list = cloneListForMapAndSample(this);
+ list._store = this._store.map(dimIndices, (fCtx
+ ? zrUtil.bind(cb as any, fCtx as any)
+ : cb) as any
+ );
+ return list;
+ }
+
+ /**
+ * Large data down sampling on given dimension
+ * @param sampleIndex Sample index for name and id
+ */
+ downSample(
+ dimension: DimensionLoose,
+ rate: number,
+ sampleValue: (frameValues: ArrayLike<ParsedValue>) => ParsedValueNumeric,
+ sampleIndex: (frameValues: ArrayLike<ParsedValue>, value: ParsedValueNumeric) => number
+ ): SeriesData<HostModel> {
+ const list = cloneListForMapAndSample(this);
+ list._store = this._store.downSample(
+ this.getDimensionIndex(dimension),
+ rate,
+ sampleValue,
+ sampleIndex
+ );
+ return list as SeriesData<HostModel>;
+ }
+
+ /**
+ * Large data down sampling using largest-triangle-three-buckets
+ * @param {string} valueDimension
+ * @param {number} targetCount
+ */
+ lttbDownSample(
+ valueDimension: DimensionLoose,
+ rate: number
+ ) {
+ const list = cloneListForMapAndSample(this);
+ list._store = this._store.lttbDownSample(
+ this.getDimensionIndex(valueDimension),
+ rate
+ );
+ return list;
+ }
+
+ getRawDataItem(idx: number) {
+ return this._store.getRawDataItem(idx);
+ }
+ /**
+ * Get model of one data item.
+ */
+ // TODO: Type of data item
+ getItemModel<ItemOpts extends unknown = unknown>(idx: number): Model<ItemOpts
+ // Extract item option with value key. FIXME will cause incompatitable issue
+ // Extract<HostModel['option']['data'][number], { value?: any }>
+ > {
+ const hostModel = this.hostModel;
+ const dataItem = this.getRawDataItem(idx) as ModelOption;
+ return new Model(dataItem, hostModel, hostModel && hostModel.ecModel);
+ }
+
+ /**
+ * Create a data differ
+ */
+ diff(otherList: SeriesData): DataDiffer {
+ const thisList = this;
+
+ return new DataDiffer(
+ otherList ? otherList.getStore().getIndices() : [],
+ this.getStore().getIndices(),
+ function (idx: number) {
+ return getId(otherList, idx);
+ },
+ function (idx: number) {
+ return getId(thisList, idx);
+ }
+ );
+ }
+
+ /**
+ * Get visual property.
+ */
+ getVisual<K extends keyof Visual>(key: K): Visual[K] {
+ const visual = this._visual as Visual;
+ return visual && visual[key];
+ }
+
+ /**
+ * Set visual property
+ *
+ * @example
+ * setVisual('color', color);
+ * setVisual({
+ * 'color': color
+ * });
+ */
+ setVisual<K extends keyof Visual>(key: K, val: Visual[K]): void;
+ setVisual(kvObj: Partial<Visual>): void;
+ setVisual(kvObj: string | Partial<Visual>, val?: any): void {
+ this._visual = this._visual || {};
+ if (isObject(kvObj)) {
+ zrUtil.extend(this._visual, kvObj);
+ }
+ else {
+ this._visual[kvObj as string] = val;
+ }
+ }
+
+ /**
+ * Get visual property of single data item
+ */
+ // eslint-disable-next-line
+ getItemVisual<K extends keyof Visual>(idx: number, key: K): Visual[K] {
+ const itemVisual = this._itemVisuals[idx] as Visual;
+ const val = itemVisual && itemVisual[key];
+ if (val == null) {
+ // Use global visual property
+ return this.getVisual(key);
+ }
+ return val;
+ }
+
+ /**
+ * If exists visual property of single data item
+ */
+ hasItemVisual() {
+ return this._itemVisuals.length > 0;
+ }
+
+ /**
+ * Make sure itemVisual property is unique
+ */
+ // TODO: use key to save visual to reduce memory.
+ ensureUniqueItemVisual<K extends keyof Visual>(idx: number, key: K): Visual[K] {
+ const itemVisuals = this._itemVisuals;
+ let itemVisual = itemVisuals[idx] as Visual;
+ if (!itemVisual) {
+ itemVisual = itemVisuals[idx] = {} as Visual;
+ }
+ let val = itemVisual[key];
+ if (val == null) {
+ val = this.getVisual(key);
+
+ // TODO Performance?
+ if (zrUtil.isArray(val)) {
+ val = val.slice() as unknown as Visual[K];
+ }
+ else if (isObject(val)) {
+ val = zrUtil.extend({}, val);
+ }
+
+ itemVisual[key] = val;
+ }
+ return val;
+ }
+ /**
+ * Set visual property of single data item
+ *
+ * @param {number} idx
+ * @param {string|Object} key
+ * @param {*} [value]
+ *
+ * @example
+ * setItemVisual(0, 'color', color);
+ * setItemVisual(0, {
+ * 'color': color
+ * });
+ */
+ // eslint-disable-next-line
+ setItemVisual<K extends keyof Visual>(idx: number, key: K, value: Visual[K]): void;
+ setItemVisual(idx: number, kvObject: Partial<Visual>): void;
+ // eslint-disable-next-line
+ setItemVisual<K extends keyof Visual>(idx: number, key: K | Partial<Visual>, value?: Visual[K]): void {
+ const itemVisual = this._itemVisuals[idx] || {};
+ this._itemVisuals[idx] = itemVisual;
+
+ if (isObject(key)) {
+ zrUtil.extend(itemVisual, key);
+ }
+ else {
+ itemVisual[key as string] = value;
+ }
+ }
+
+ /**
+ * Clear itemVisuals and list visual.
+ */
+ clearAllVisual(): void {
+ this._visual = {};
+ this._itemVisuals = [];
+ }
+
+ /**
+ * Set layout property.
+ */
+ setLayout(key: string, val: any): void;
+ setLayout(kvObj: Dictionary<any>): void;
+ setLayout(key: string | Dictionary<any>, val?: any): void {
+ if (isObject(key)) {
+ for (const name in key) {
+ if (key.hasOwnProperty(name)) {
+ this.setLayout(name, key[name]);
+ }
+ }
+ return;
+ }
+ this._layout[key] = val;
+ }
+
+ /**
+ * Get layout property.
+ */
+ getLayout(key: string): any {
+ return this._layout[key];
+ }
+
+ /**
+ * Get layout of single data item
+ */
+ getItemLayout(idx: number): any {
+ return this._itemLayouts[idx];
+ }
+
+ /**
+ * Set layout of single data item
+ */
+ setItemLayout<M = false>(
+ idx: number,
+ layout: (M extends true ? Dictionary<any> : any),
+ merge?: M
+ ): void {
+ this._itemLayouts[idx] = merge
+ ? zrUtil.extend(this._itemLayouts[idx] || {}, layout)
+ : layout;
+ }
+
+ /**
+ * Clear all layout of single data item
+ */
+ clearItemLayouts(): void {
+ this._itemLayouts.length = 0;
+ }
+
+ /**
+ * Set graphic element relative to data. It can be set as null
+ */
+ setItemGraphicEl(idx: number, el: Element): void {
+ const hostModel = this.hostModel;
+
+ if (el) {
+ const ecData = getECData(el);
+ // Add data index and series index for indexing the data by element
+ // Useful in tooltip
+ ecData.dataIndex = idx;
+ ecData.dataType = this.dataType;
+ ecData.seriesIndex = hostModel && (hostModel as any).seriesIndex;
+
+ // TODO: not store dataIndex on children.
+ if (el.type === 'group') {
+ el.traverse(setItemDataAndSeriesIndex, el);
+ }
+ }
+
+ this._graphicEls[idx] = el;
+ }
+
+ getItemGraphicEl(idx: number): Element {
+ return this._graphicEls[idx];
+ }
+
+ eachItemGraphicEl<Ctx = unknown>(
+ cb: (this: Ctx, el: Element, idx: number) => void,
+ context?: Ctx
+ ): void {
+ zrUtil.each(this._graphicEls, function (el, idx) {
+ if (el) {
+ cb && cb.call(context, el, idx);
+ }
+ });
+ }
+
+ /**
+ * Shallow clone a new list except visual and layout properties, and graph elements.
+ * New list only change the indices.
+ */
+ cloneShallow(list?: SeriesData<HostModel>): SeriesData<HostModel> {
+ if (!list) {
+ const dimensionInfoList = map(this.dimensions, this.getDimensionInfo, this);
+ list = new SeriesData(dimensionInfoList, this.hostModel);
+ }
+
+ transferProperties(list, this);
+
+ return list;
+ }
+
+ /**
+ * Wrap some method to add more feature
+ */
+ wrapMethod(
+ methodName: FunctionPropertyNames<SeriesData>,
+ injectFunction: (...args: any) => any
+ ): void {
+ const originalMethod = this[methodName];
+ if (typeof originalMethod !== 'function') {
+ return;
+ }
+ this.__wrappedMethods = this.__wrappedMethods || [];
+ this.__wrappedMethods.push(methodName);
+ this[methodName] = function () {
+ const res = (originalMethod as any).apply(this, arguments);
+ return injectFunction.apply(this, [res].concat(zrUtil.slice(arguments)));
+ };
+ }
+
+
+ // ----------------------------------------------------------
+ // A work around for internal method visiting private member.
+ // ----------------------------------------------------------
+ private static internalField = (function () {
+
+ prepareInvertedIndex = function (list: SeriesData): void {
+ const invertedIndicesMap = list._invertedIndicesMap;
+ zrUtil.each(invertedIndicesMap, function (invertedIndices, dim) {
+ const dimInfo = list._dimensionInfos[dim];
+ // Currently, only dimensions that has ordinalMeta can create inverted indices.
+ const ordinalMeta = dimInfo.ordinalMeta;
+ const store = list._store;
+ const dimIdx = store.getDimensionIndex(dim);
+ if (ordinalMeta) {
+ invertedIndices = invertedIndicesMap[dim] = new CtorInt32Array(
+ ordinalMeta.categories.length
+ );
+ // The default value of TypedArray is 0. To avoid miss
+ // mapping to 0, we should set it as INDEX_NOT_FOUND.
+ for (let i = 0; i < invertedIndices.length; i++) {
+ invertedIndices[i] = INDEX_NOT_FOUND;
+ }
+ for (let i = 0; i < store.count(); i++) {
+ // Only support the case that all values are distinct.
+ invertedIndices[store.get(dimIdx, i) as number] = i;
+ }
+ }
+ });
+ };
+
+ getIdNameFromStore = function (
+ list: SeriesData, dimIdx: number, idx: number
+ ): string {
+ return convertOptionIdName(list.getStore().getCategory(dimIdx, idx), null);
+ };
+
+ /**
+ * @see the comment of `List['getId']`.
+ */
+ getId = function (list: SeriesData, rawIndex: number): string {
+ let id = list._idList[rawIndex];
+ if (id == null && list._idDimIdx != null) {
+ id = getIdNameFromStore(list, list._idDimIdx, rawIndex);
+ }
+ if (id == null) {
+ id = ID_PREFIX + rawIndex;
+ }
+ return id;
+ };
+
+ normalizeDimensions = function (
+ dimensions: ItrParamDims
+ ): Array<DimensionLoose> {
+ if (!zrUtil.isArray(dimensions)) {
+ dimensions = dimensions != null ? [dimensions] : [];
+ }
+ return dimensions;
+ };
+
+ validateDimensions = function (list: SeriesData, dims: DimensionIndex[]): void {
+ for (let i = 0; i < dims.length; i++) {
+ // stroage may be empty when no data, so use
+ // dimensionInfos to check.
+ if (!list.dimensions[dims[i]]) {
+ console.error('Unkown dimension ' + dims[i]);
+ }
+ }
+ };
+
+ // Data in excludeDimensions is copied, otherwise transfered.
+ cloneListForMapAndSample = function (original: SeriesData): SeriesData {
+ const allDimensions = original.dimensions;
+ const list = new SeriesData(
+ map(allDimensions, original.getDimensionInfo, original),
+ original.hostModel
+ );
+ // FIXME If needs stackedOn, value may already been stacked
+ transferProperties(list, original);
+ return list;
+ };
+
+ setItemDataAndSeriesIndex = function (this: Element, child: Element): void {
+ const childECData = getECData(child);
+ const thisECData = getECData(this);
+ childECData.seriesIndex = thisECData.seriesIndex;
+ childECData.dataIndex = thisECData.dataIndex;
+ childECData.dataType = thisECData.dataType;
+ };
+
+ transferProperties = function (target: SeriesData, source: SeriesData): void {
+ zrUtil.each(
+ TRANSFERABLE_PROPERTIES.concat(source.__wrappedMethods || []),
+ function (propName) {
+ if (source.hasOwnProperty(propName)) {
+ (target as any)[propName] = (source as any)[propName];
+ }
+ }
+ );
+
+ target.__wrappedMethods = source.__wrappedMethods;
+
+ zrUtil.each(CLONE_PROPERTIES, function (propName) {
+ (target as any)[propName] = zrUtil.clone((source as any)[propName]);
+ });
+
+ target._calculationInfo = zrUtil.extend({}, source._calculationInfo);
+ };
+
+ })();
+
+}
+
+interface SeriesData {
+ getLinkedData(dataType?: SeriesDataType): SeriesData;
+ getLinkedDataAll(): { data: SeriesData, type?: SeriesDataType }[];
+}
+
+export default SeriesData;
diff --git a/src/data/Tree.ts b/src/data/Tree.ts
index 684fcb8..207e451 100644
--- a/src/data/Tree.ts
+++ b/src/data/Tree.ts
@@ -23,8 +23,8 @@
import * as zrUtil from 'zrender/src/core/util';
import Model from '../model/Model';
-import linkList from './helper/linkList';
-import List from './List';
+import linkSeriesData from './helper/linkSeriesData';
+import SeriesData from './SeriesData';
import createDimensions from './helper/createDimensions';
import {
DimensionLoose, ParsedValue, OptionDataValue,
@@ -307,7 +307,7 @@ class Tree<HostModel extends Model = Model, LevelOption = any> {
root: TreeNode;
- data: List;
+ data: SeriesData;
hostModel: HostModel;
@@ -399,7 +399,7 @@ class Tree<HostModel extends Model = Model, LevelOption = any> {
static createTree<T extends TreeNodeOption, HostModel extends Model, LevelOption>(
dataRoot: T,
hostModel: HostModel,
- beforeLink?: (data: List) => void
+ beforeLink?: (data: SeriesData) => void
) {
const tree = new Tree(hostModel);
@@ -436,12 +436,12 @@ class Tree<HostModel extends Model = Model, LevelOption = any> {
dimensionsCount: dimMax
});
- const list = new List(dimensionsInfo, hostModel);
+ const list = new SeriesData(dimensionsInfo, hostModel);
list.initData(listData);
beforeLink && beforeLink(list);
- linkList({
+ linkSeriesData({
mainData: list,
struct: tree,
structAttr: 'tree'
diff --git a/src/data/helper/completeDimensions.ts b/src/data/helper/completeDimensions.ts
index f95122b..b0afd04 100644
--- a/src/data/helper/completeDimensions.ts
+++ b/src/data/helper/completeDimensions.ts
@@ -31,7 +31,7 @@ import {
EncodeDefaulter, OptionEncodeValue, OptionEncode, DimensionName, DimensionIndex, DataVisualDimensions
} from '../../util/types';
import DataDimensionInfo from '../DataDimensionInfo';
-import List from '../List';
+import SeriesData from '../SeriesData';
import { CoordDimensionDefinition, CoordDimensionDefinitionLoose } from './createDimensions';
@@ -76,7 +76,7 @@ import { CoordDimensionDefinition, CoordDimensionDefinitionLoose } from './creat
*/
function completeDimensions(
sysDims: CoordDimensionDefinitionLoose[],
- source: Source | List | OptionSourceData,
+ source: Source | SeriesData | OptionSourceData,
opt: {
dimsDef?: DimensionDefinitionLoose[];
encodeDef?: HashMap<OptionEncodeValue, DimensionName> | OptionEncode;
diff --git a/src/data/helper/createDimensions.ts b/src/data/helper/createDimensions.ts
index 102104c..82a625a 100644
--- a/src/data/helper/createDimensions.ts
+++ b/src/data/helper/createDimensions.ts
@@ -26,7 +26,7 @@ import {
DimensionDefinitionLoose, OptionEncode, OptionEncodeValue,
EncodeDefaulter, OptionSourceData, DimensionName, DimensionDefinition, DataVisualDimensions, DimensionIndex
} from '../../util/types';
-import List from '../List';
+import SeriesData from '../SeriesData';
import DataDimensionInfo from '../DataDimensionInfo';
import { HashMap } from 'zrender/src/core/util';
import OrdinalMeta from '../OrdinalMeta';
@@ -60,7 +60,7 @@ export type CreateDimensionsParams = {
*/
export default function createDimensions(
// TODO: TYPE completeDimensions type
- source: Source | List | OptionSourceData,
+ source: Source | SeriesData | OptionSourceData,
opt?: CreateDimensionsParams
): DataDimensionInfo[] {
opt = opt || {};
diff --git a/src/data/helper/dataProvider.ts b/src/data/helper/dataProvider.ts
index 94a60fb..5dc74c0 100644
--- a/src/data/helper/dataProvider.ts
+++ b/src/data/helper/dataProvider.ts
@@ -36,7 +36,7 @@ import {
DimensionName, DimensionIndex, OptionSourceData,
DimensionIndexLoose, OptionDataItem, OptionDataValue, SourceFormat, SeriesLayoutBy, ParsedValue
} from '../../util/types';
-import List from '../List';
+import SeriesData from '../SeriesData';
export interface DataProvider {
/**
@@ -469,7 +469,7 @@ function getMethodMapKey(sourceFormat: SourceFormat, seriesLayoutBy: SeriesLayou
// value may be 0.91000000001, which have brings trouble to display.
// TODO: consider how to treat null/undefined/NaN when display?
export function retrieveRawValue(
- data: List, dataIndex: number, dim?: DimensionName | DimensionIndexLoose
+ data: SeriesData, dataIndex: number, dim?: DimensionName | DimensionIndexLoose
// If dimIndex is null/undefined, return OptionDataItem.
// Otherwise, return OptionDataValue.
): OptionDataValue | OptionDataItem {
@@ -484,7 +484,7 @@ export function retrieveRawValue(
return;
}
- const sourceFormat = data.getProvider().getSource().sourceFormat;
+ const sourceFormat = data.getStore().getProvider().getSource().sourceFormat;
let dimName;
let dimIndex;
@@ -510,12 +510,12 @@ export function retrieveRawValue(
* @param dataIndex
* @param attr like 'selected'
*/
-export function retrieveRawAttr(data: List, dataIndex: number, attr: string): any {
+export function retrieveRawAttr(data: SeriesData, dataIndex: number, attr: string): any {
if (!data) {
return;
}
- const sourceFormat = data.getProvider().getSource().sourceFormat;
+ const sourceFormat = data.getStore().getProvider().getSource().sourceFormat;
if (sourceFormat !== SOURCE_FORMAT_ORIGINAL
&& sourceFormat !== SOURCE_FORMAT_OBJECT_ROWS
diff --git a/src/data/helper/dataStackHelper.ts b/src/data/helper/dataStackHelper.ts
index cef669c..0343014 100644
--- a/src/data/helper/dataStackHelper.ts
+++ b/src/data/helper/dataStackHelper.ts
@@ -20,7 +20,7 @@
import {each, isString} from 'zrender/src/core/util';
import DataDimensionInfo from '../DataDimensionInfo';
import SeriesModel from '../../model/Series';
-import List, { DataCalculationInfo } from '../List';
+import SeriesData, { DataCalculationInfo } from '../SeriesData';
import type { SeriesOption, SeriesStackOptionMixin, DimensionName } from '../../util/types';
@@ -30,7 +30,7 @@ import type { SeriesOption, SeriesStackOptionMixin, DimensionName } from '../../
* we just support that stacked by index.
*
* @param seriesModel
- * @param dimensionInfoList The same as the input of <module:echarts/data/List>.
+ * @param dimensionInfoList The same as the input of <module:echarts/data/SeriesData>.
* The input dimensionInfoList will be modified.
* @param opt
* @param opt.stackedCoordDimension Specify a coord dimension if needed.
@@ -154,7 +154,7 @@ export function enableDataStack(
};
}
-export function isDimensionStacked(data: List, stackedDim: string /*, stackedByDim*/): boolean {
+export function isDimensionStacked(data: SeriesData, stackedDim: string /*, stackedByDim*/): boolean {
// Each single series only maps to one pair of axis. So we do not need to
// check stackByDim, whatever stacked by a dimension or stacked by index.
return !!stackedDim && stackedDim === data.getCalculationInfo('stackedDimension');
@@ -165,7 +165,7 @@ export function isDimensionStacked(data: List, stackedDim: string /*, stackedByD
// );
}
-export function getStackedDimension(data: List, targetDim: string): DimensionName {
+export function getStackedDimension(data: SeriesData, targetDim: string): DimensionName {
return isDimensionStacked(data, targetDim)
? data.getCalculationInfo('stackResultDimension')
: targetDim;
diff --git a/src/data/helper/dimensionHelper.ts b/src/data/helper/dimensionHelper.ts
index b38062d..425271f 100644
--- a/src/data/helper/dimensionHelper.ts
+++ b/src/data/helper/dimensionHelper.ts
@@ -19,10 +19,11 @@
import {each, createHashMap, assert} from 'zrender/src/core/util';
-import List, { ListDimensionType } from '../List';
+import SeriesData from '../SeriesData';
import {
DimensionName, VISUAL_DIMENSIONS, DimensionType, DimensionUserOuput, DimensionUserOuputEncode, DimensionIndex
} from '../../util/types';
+import { DataStoreDimensionType } from '../DataStorage';
export type DimensionSummaryEncode = {
defaultedLabel: DimensionName[],
@@ -40,7 +41,7 @@ export type DimensionSummary = {
encodeFirstDimNotExtra: {[coordDim: string]: DimensionName},
};
-export function summarizeDimensions(data: List): DimensionSummary {
+export function summarizeDimensions(data: SeriesData): DimensionSummary {
const summary: DimensionSummary = {} as DimensionSummary;
const encode = summary.encode = {} as DimensionSummaryEncode;
const notExtraCoordDimMap = createHashMap<1, DimensionName>();
@@ -140,7 +141,7 @@ function getOrCreateEncodeArr(
}
// FIXME:TS should be type `AxisType`
-export function getDimensionTypeByAxis(axisType: string): ListDimensionType {
+export function getDimensionTypeByAxis(axisType: string): DataStoreDimensionType {
return axisType === 'category'
? 'ordinal'
: axisType === 'time'
diff --git a/src/data/helper/linkList.ts b/src/data/helper/linkSeriesData.ts
similarity index 75%
rename from src/data/helper/linkList.ts
rename to src/data/helper/linkSeriesData.ts
index a7cecc4..2b767cf 100644
--- a/src/data/helper/linkList.ts
+++ b/src/data/helper/linkSeriesData.ts
@@ -23,37 +23,37 @@
*/
import { curry, each, assert, extend, map, keys } from 'zrender/src/core/util';
-import List from '../List';
+import SeriesData from '../SeriesData';
import { makeInner } from '../../util/model';
import { SeriesDataType } from '../../util/types';
// That is: { dataType: data },
// like: { node: nodeList, edge: edgeList }.
// Should contain mainData.
-type Datas = { [key in SeriesDataType]?: List };
+type Datas = { [key in SeriesDataType]?: SeriesData };
type StructReferDataAttr = 'data' | 'edgeData';
type StructAttr = 'tree' | 'graph';
const inner = makeInner<{
datas: Datas;
- mainData: List;
-}, List>();
+ mainData: SeriesData;
+}, SeriesData>();
// Caution:
-// In most case, either list or its shallow clones (see list.cloneShallow)
+// In most case, either seriesData or its shallow clones (see seriesData.cloneShallow)
// is active in echarts process. So considering heap memory consumption,
-// we do not clone tree or graph, but share them among list and its shallow clones.
-// But in some rare case, we have to keep old list (like do animation in chart). So
-// please take care that both the old list and the new list share the same tree/graph.
+// we do not clone tree or graph, but share them among seriesData and its shallow clones.
+// But in some rare case, we have to keep old seriesData (like do animation in chart). So
+// please take care that both the old seriesData and the new seriesData share the same tree/graph.
-type LinkListOpt = {
- mainData: List;
+type LinkSeriesDataOpt = {
+ mainData: SeriesData;
// For example, instance of Graph or Tree.
struct: {
update: () => void;
} & {
- [key in StructReferDataAttr]?: List
+ [key in StructReferDataAttr]?: SeriesData
};
// Will designate: `mainData[structAttr] = struct;`
structAttr: StructAttr;
@@ -63,7 +63,7 @@ type LinkListOpt = {
datasAttr?: { [key in SeriesDataType]?: StructReferDataAttr };
};
-function linkList(opt: LinkListOpt): void {
+function linkSeriesData(opt: LinkSeriesDataOpt): void {
const mainData = opt.mainData;
let datas = opt.datas;
@@ -76,7 +76,7 @@ function linkList(opt: LinkListOpt): void {
linkAll(mainData, datas, opt);
// Porxy data original methods.
- each(datas, function (data: List) {
+ each(datas, function (data: SeriesData) {
each(mainData.TRANSFERABLE_METHODS, function (methodName) {
data.wrapMethod(methodName, curry(transferInjection, opt));
});
@@ -95,7 +95,7 @@ function linkList(opt: LinkListOpt): void {
assert(datas[mainData.dataType] === mainData);
}
-function transferInjection(this: List, opt: LinkListOpt, res: List): unknown {
+function transferInjection(this: SeriesData, opt: LinkSeriesDataOpt, res: SeriesData): unknown {
if (isMainData(this)) {
// Transfer datas to new main data.
const datas = extend({}, inner(this).datas);
@@ -109,17 +109,17 @@ function transferInjection(this: List, opt: LinkListOpt, res: List): unknown {
return res;
}
-function changeInjection(opt: LinkListOpt, res: unknown): unknown {
+function changeInjection(opt: LinkSeriesDataOpt, res: unknown): unknown {
opt.struct && opt.struct.update();
return res;
}
-function cloneShallowInjection(opt: LinkListOpt, res: List): List {
+function cloneShallowInjection(opt: LinkSeriesDataOpt, res: SeriesData): SeriesData {
// cloneShallow, which brings about some fragilities, may be inappropriate
// to be exposed as an API. So for implementation simplicity we can make
// the restriction that cloneShallow of not-mainData should not be invoked
// outside, but only be invoked here.
- each(inner(res).datas, function (data: List, dataType) {
+ each(inner(res).datas, function (data: SeriesData, dataType) {
data !== res && linkSingle(data.cloneShallow(), dataType, res, opt);
});
return res;
@@ -131,7 +131,7 @@ function cloneShallowInjection(opt: LinkListOpt, res: List): List {
* @public
* @param [dataType] If not specified, return mainData.
*/
-function getLinkedData(this: List, dataType?: SeriesDataType): List {
+function getLinkedData(this: SeriesData, dataType?: SeriesDataType): SeriesData {
const mainData = inner(this).mainData;
return (dataType == null || mainData == null)
? mainData
@@ -141,8 +141,8 @@ function getLinkedData(this: List, dataType?: SeriesDataType): List {
/**
* Get list of all linked data
*/
-function getLinkedDataAll(this: List): {
- data: List,
+function getLinkedDataAll(this: SeriesData): {
+ data: SeriesData,
type?: SeriesDataType
}[] {
const mainData = inner(this).mainData;
@@ -156,18 +156,18 @@ function getLinkedDataAll(this: List): {
});
}
-function isMainData(data: List): boolean {
+function isMainData(data: SeriesData): boolean {
return inner(data).mainData === data;
}
-function linkAll(mainData: List, datas: Datas, opt: LinkListOpt): void {
+function linkAll(mainData: SeriesData, datas: Datas, opt: LinkSeriesDataOpt): void {
inner(mainData).datas = {};
- each(datas, function (data: List, dataType) {
+ each(datas, function (data: SeriesData, dataType) {
linkSingle(data, dataType, mainData, opt);
});
}
-function linkSingle(data: List, dataType: SeriesDataType, mainData: List, opt: LinkListOpt): void {
+function linkSingle(data: SeriesData, dataType: SeriesDataType, mainData: SeriesData, opt: LinkSeriesDataOpt): void {
inner(mainData).datas[dataType] = data;
inner(data).mainData = mainData;
@@ -183,4 +183,4 @@ function linkSingle(data: List, dataType: SeriesDataType, mainData: List, opt: L
data.getLinkedDataAll = getLinkedDataAll;
}
-export default linkList;
+export default linkSeriesData;
diff --git a/src/export/api.ts b/src/export/api.ts
index 1d84814..9279b3c 100644
--- a/src/export/api.ts
+++ b/src/export/api.ts
@@ -53,7 +53,7 @@ export * as util from './api/util';
export {default as env} from 'zrender/src/core/env';
//////////////// Export for Exension Usage ////////////////
-export {default as List} from '../data/List';
+export {default as SeriesData} from '../data/SeriesData';
export {default as Model} from '../model/Model';
export {default as Axis} from '../coord/Axis';
diff --git a/src/export/api/helper.ts b/src/export/api/helper.ts
index 07d6cef..614d210 100644
--- a/src/export/api/helper.ts
+++ b/src/export/api/helper.ts
@@ -22,7 +22,7 @@
*/
import * as zrUtil from 'zrender/src/core/util';
-import createListFromArray from '../../chart/helper/createListFromArray';
+import createSeriesDataFromArray from '../../chart/helper/createSeriesDataFromArray';
// import createGraphFromNodeEdge from './chart/helper/createGraphFromNodeEdge';
import * as axisHelper from '../../coord/axisHelper';
import {AxisModelCommonMixin} from '../../coord/axisModelCommonMixin';
@@ -43,7 +43,7 @@ import { DisplayState, TextCommonOption } from '../../util/types';
* Create a muti dimension List structure from seriesModel.
*/
export function createList(seriesModel: SeriesModel) {
- return createListFromArray(seriesModel.getSource(), seriesModel);
+ return createSeriesDataFromArray(seriesModel.getSource(), seriesModel);
}
// export function createGraph(seriesModel) {
diff --git a/src/label/labelStyle.ts b/src/label/labelStyle.ts
index def6b19..606aa94 100644
--- a/src/label/labelStyle.ts
+++ b/src/label/labelStyle.ts
@@ -38,7 +38,7 @@ import { isFunction, retrieve2, extend, keys, trim } from 'zrender/src/core/util
import { SPECIAL_STATES, DISPLAY_STATES } from '../util/states';
import { deprecateReplaceLog } from '../util/log';
import { makeInner, interpolateRawValues } from '../util/model';
-import List from '../data/List';
+import SeriesData from '../data/SeriesData';
import { initProps, updateProps } from '../util/graphic';
import { getECData } from '../util/innerStore';
@@ -688,7 +688,7 @@ export function setLabelValueAnimation(
export function animateLabelValue(
textEl: ZRText,
dataIndex: number,
- data: List,
+ data: SeriesData,
animatableModel: Model<AnimationOptionMixin>,
labelFetcher: SetLabelStyleOpt<number>['labelFetcher']
) {
diff --git a/src/layout/barGrid.ts b/src/layout/barGrid.ts
index edf6400..b389d7a 100644
--- a/src/layout/barGrid.ts
+++ b/src/layout/barGrid.ts
@@ -472,7 +472,7 @@ export function layout(seriesType: string, ecModel: GlobalModel) {
const valueDim = data.mapDimension(valueAxis.dim);
const baseDim = data.mapDimension(baseAxis.dim);
- const stacked = isDimensionStacked(data, valueDim /*, baseDim*/);
+ const stacked = isDimensionStacked(data, valueDim);
const isValueAxisH = valueAxis.isHorizontal();
const valueAxisStart = getValueAxisStart(baseAxis, valueAxis, stacked);
diff --git a/src/layout/points.ts b/src/layout/points.ts
index 8946852..2d138be 100644
--- a/src/layout/points.ts
+++ b/src/layout/points.ts
@@ -69,18 +69,19 @@ export default function pointsLayout(seriesType: string, forceStoreInTypedArray?
const tmpIn: ParsedValueNumeric[] = [];
const tmpOut: number[] = [];
+ const store = data.getStore();
for (let i = params.start, offset = 0; i < params.end; i++) {
let point;
if (dimLen === 1) {
- const x = data.getByDimIdx(dimIdx0, i) as ParsedValueNumeric;
+ const x = store.get(dimIdx0, i) as ParsedValueNumeric;
// NOTE: Make sure the second parameter is null to use default strategy.
point = coordSys.dataToPoint(x, null, tmpOut);
}
else {
- tmpIn[0] = data.getByDimIdx(dimIdx0, i) as ParsedValueNumeric;
- tmpIn[1] = data.getByDimIdx(dimIdx1, i) as ParsedValueNumeric;
+ tmpIn[0] = store.get(dimIdx0, i) as ParsedValueNumeric;
+ tmpIn[1] = store.get(dimIdx1, i) as ParsedValueNumeric;
// Let coordinate system to handle the NaN data.
point = coordSys.dataToPoint(tmpIn, null, tmpOut);
}
diff --git a/src/model/Series.ts b/src/model/Series.ts
index 9ee54c8..a47d819 100644
--- a/src/model/Series.ts
+++ b/src/model/Series.ts
@@ -40,7 +40,7 @@ import { CoordinateSystem } from '../coord/CoordinateSystem';
import { ExtendableConstructor, mountExtend, Constructor } from '../util/clazz';
import { PipelineContext, SeriesTaskContext, GeneralTask, OverallTask, SeriesTask } from '../core/Scheduler';
import LegendVisualProvider from '../visual/LegendVisualProvider';
-import List from '../data/List';
+import SeriesData from '../data/SeriesData';
import Axis from '../coord/Axis';
import type { BrushCommonSelectorsForSeries, BrushSelectableArea } from '../component/brush/selector';
import makeStyleMapper from './mixin/makeStyleMapper';
@@ -52,12 +52,12 @@ import {Group} from '../util/graphic';
import {LegendIconParams} from '../component/legend/LegendModel';
const inner = modelUtil.makeInner<{
- data: List
- dataBeforeProcessed: List
+ data: SeriesData
+ dataBeforeProcessed: SeriesData
sourceManager: SourceManager
}, SeriesModel>();
-function getSelectionKey(data: List, dataIndex: number): string {
+function getSelectionKey(data: SeriesData, dataIndex: number): string {
return data.getName(dataIndex) || data.getId(dataIndex);
}
@@ -105,7 +105,7 @@ interface SeriesModel {
*/
brushSelector(
dataIndex: number,
- data: List,
+ data: SeriesData,
selectors: BrushCommonSelectorsForSeries,
area: BrushSelectableArea
): boolean;
@@ -220,7 +220,7 @@ class SeriesModel<Opt extends SeriesOption = SeriesOption> extends ComponentMode
// dataBeforeProcessed by cloneShallow), cloneShallow will
// cause data.graph.data !== data when using
// module:echarts/data/Graph or module:echarts/data/Tree.
- // See module:echarts/data/helper/linkList
+ // See module:echarts/data/helper/linkSeriesData
// Theoretically, it is unreasonable to call `seriesModel.getData()` in the model
// init or merge stage, because the data can be restored. So we do not `restoreData`
@@ -314,7 +314,7 @@ class SeriesModel<Opt extends SeriesOption = SeriesOption> extends ComponentMode
* Init a data structure from data related option in series
* Must be overriden.
*/
- getInitialData(option: Opt, ecModel: GlobalModel): List {
+ getInitialData(option: Opt, ecModel: GlobalModel): SeriesData {
return;
}
@@ -335,23 +335,23 @@ class SeriesModel<Opt extends SeriesOption = SeriesOption> extends ComponentMode
* data in the stream procedure. So we fetch data from upstream
* each time `task.perform` called.
*/
- getData(dataType?: SeriesDataType): List<this> {
+ getData(dataType?: SeriesDataType): SeriesData<this> {
const task = getCurrentTask(this);
if (task) {
const data = task.context.data;
- return (dataType == null ? data : data.getLinkedData(dataType)) as List<this>;
+ return (dataType == null ? data : data.getLinkedData(dataType)) as SeriesData<this>;
}
else {
// When series is not alive (that may happen when click toolbox
// restore or setOption with not merge mode), series data may
// be still need to judge animation or something when graphic
// elements want to know whether fade out.
- return inner(this).data as List<this>;
+ return inner(this).data as SeriesData<this>;
}
}
getAllData(): ({
- data: List,
+ data: SeriesData,
type?: SeriesDataType
})[] {
const mainData = this.getData();
@@ -360,7 +360,7 @@ class SeriesModel<Opt extends SeriesOption = SeriesOption> extends ComponentMode
: [{ data: mainData }];
}
- setData(data: List): void {
+ setData(data: SeriesData): void {
const task = getCurrentTask(this);
if (task) {
const context = task.context;
@@ -392,7 +392,7 @@ class SeriesModel<Opt extends SeriesOption = SeriesOption> extends ComponentMode
/**
* Get data before processed
*/
- getRawData(): List {
+ getRawData(): SeriesData {
return inner(this).dataBeforeProcessed;
}
@@ -541,7 +541,6 @@ class SeriesModel<Opt extends SeriesOption = SeriesOption> extends ComponentMode
return true;
}
- // NOTE: don't support define universalTransition in global option yet.
const universalTransitionOpt = this.option.universalTransition;
// Quick reject
if (!universalTransitionOpt) {
@@ -556,7 +555,7 @@ class SeriesModel<Opt extends SeriesOption = SeriesOption> extends ComponentMode
return universalTransitionOpt && universalTransitionOpt.enabled;
}
- private _innerSelect(data: List, innerDataIndices: number[]) {
+ private _innerSelect(data: SeriesData, innerDataIndices: number[]) {
const selectedMode = this.option.selectedMode;
const len = innerDataIndices.length;
if (!selectedMode || !len) {
@@ -585,7 +584,7 @@ class SeriesModel<Opt extends SeriesOption = SeriesOption> extends ComponentMode
}
}
- private _initSelectedMapFromData(data: List) {
+ private _initSelectedMapFromData(data: SeriesData) {
// Ignore select info in data if selectedMap exists.
// NOTE It's only for legacy usage. edge data is not supported.
if (this.option.selectedMap) {
@@ -676,13 +675,13 @@ function dataTaskProgress(param: StageHandlerProgressParams, context: SeriesTask
}
// TODO refactor
-function wrapData(data: List, seriesModel: SeriesModel): void {
+function wrapData(data: SeriesData, seriesModel: SeriesModel): void {
zrUtil.each([...data.CHANGABLE_METHODS, ...data.DOWNSAMPLE_METHODS], function (methodName) {
data.wrapMethod(methodName as any, zrUtil.curry(onDataChange, seriesModel));
});
}
-function onDataChange(this: List, seriesModel: SeriesModel, newList: List): List {
+function onDataChange(this: SeriesData, seriesModel: SeriesModel, newList: SeriesData): SeriesData {
const task = getCurrentTask(seriesModel);
if (task) {
// Consider case: filter, selectRange
diff --git a/src/processor/dataStack.ts b/src/processor/dataStack.ts
index e9559cb..88cdc68 100644
--- a/src/processor/dataStack.ts
+++ b/src/processor/dataStack.ts
@@ -21,7 +21,7 @@ import {createHashMap, each} from 'zrender/src/core/util';
import GlobalModel from '../model/Global';
import SeriesModel from '../model/Series';
import { SeriesOption, SeriesStackOptionMixin, DimensionName } from '../util/types';
-import List from '../data/List';
+import SeriesData from '../data/SeriesData';
import { addSafe } from '../util/number';
interface StackInfo {
@@ -30,7 +30,7 @@ interface StackInfo {
stackedByDimension: DimensionName
stackResultDimension: DimensionName
stackedOverDimension: DimensionName
- data: List
+ data: SeriesData
seriesModel: SeriesModel<SeriesOption & SeriesStackOptionMixin>
}
// (1) [Caution]: the logic is correct based on the premises:
diff --git a/src/scale/Log.ts b/src/scale/Log.ts
index 11a1c84..f8c3258 100644
--- a/src/scale/Log.ts
+++ b/src/scale/Log.ts
@@ -24,7 +24,7 @@ import * as scaleHelper from './helper';
// Use some method of IntervalScale
import IntervalScale from './Interval';
-import List from '../data/List';
+import SeriesData from '../data/SeriesData';
import { DimensionName, ScaleTick } from '../util/types';
const scaleProto = Scale.prototype;
@@ -118,7 +118,7 @@ class LogScale extends Scale {
scaleProto.unionExtent.call(this, extent);
}
- unionExtentFromData(data: List, dim: DimensionName): void {
+ unionExtentFromData(data: SeriesData, dim: DimensionName): void {
// TODO
// filter value that <= 0
this.unionExtent(data.getApproximateExtent(dim));
diff --git a/src/scale/Ordinal.ts b/src/scale/Ordinal.ts
index 76f515a..7f23c2d 100644
--- a/src/scale/Ordinal.ts
+++ b/src/scale/Ordinal.ts
@@ -26,7 +26,7 @@
import Scale from './Scale';
import OrdinalMeta from '../data/OrdinalMeta';
-import List from '../data/List';
+import SeriesData from '../data/SeriesData';
import * as scaleHelper from './helper';
import {
OrdinalRawValue,
@@ -263,7 +263,7 @@ class OrdinalScale extends Scale<OrdinalScaleSetting> {
return this._extent[1] - this._extent[0] + 1;
}
- unionExtentFromData(data: List, dim: DimensionLoose) {
+ unionExtentFromData(data: SeriesData, dim: DimensionLoose) {
this.unionExtent(data.getApproximateExtent(dim));
}
diff --git a/src/scale/Scale.ts b/src/scale/Scale.ts
index 701013c..afae3f4 100644
--- a/src/scale/Scale.ts
+++ b/src/scale/Scale.ts
@@ -20,7 +20,7 @@
import * as clazzUtil from '../util/clazz';
import { Dictionary } from 'zrender/src/core/types';
-import List from '../data/List';
+import SeriesData from '../data/SeriesData';
import {
DimensionName,
ScaleDataValue,
@@ -91,7 +91,7 @@ abstract class Scale<SETTING extends Dictionary<unknown> = Dictionary<unknown>>
/**
* Set extent from data
*/
- unionExtentFromData(data: List, dim: DimensionName | DimensionLoose): void {
+ unionExtentFromData(data: SeriesData, dim: DimensionName | DimensionLoose): void {
this.unionExtent(data.getApproximateExtent(dim));
}
diff --git a/src/util/model.ts b/src/util/model.ts
index b640ec6..a16377e 100644
--- a/src/util/model.ts
+++ b/src/util/model.ts
@@ -32,7 +32,7 @@ import {
import env from 'zrender/src/core/env';
import GlobalModel from '../model/Global';
import ComponentModel, {ComponentModelConstructor} from '../model/Component';
-import List from '../data/List';
+import SeriesData from '../data/SeriesData';
import {
ComponentOption,
ComponentMainType,
@@ -686,7 +686,7 @@ export function compressBatches(
* each of which can be Array or primary type.
* @return dataIndex If not found, return undefined/null.
*/
-export function queryDataIndex(data: List, payload: Payload & {
+export function queryDataIndex(data: SeriesData, payload: Payload & {
dataIndexInside?: number | number[]
dataIndex?: number | number[]
name?: string | string[]
@@ -1032,7 +1032,7 @@ export function groupData<T, R extends string | number>(
* Other cases do not supported.
*/
export function interpolateRawValues(
- data: List,
+ data: SeriesData,
precision: number | 'auto',
sourceValue: InterpolatableValue,
targetValue: InterpolatableValue,
diff --git a/src/util/states.ts b/src/util/states.ts
index aa78811..ac5e01c 100644
--- a/src/util/states.ts
+++ b/src/util/states.ts
@@ -41,7 +41,7 @@ import {
import { extend, indexOf, isArrayLike, isObject, keys, isArray, each } from 'zrender/src/core/util';
import { getECData } from './innerStore';
import * as colorTool from 'zrender/src/tool/color';
-import List from '../data/List';
+import SeriesData from '../data/SeriesData';
import SeriesModel from '../model/Series';
import { CoordinateSystemMaster, CoordinateSystem } from '../coord/CoordinateSystem';
import { queryDataIndex, makeInner } from './model';
@@ -422,7 +422,7 @@ export function blurSeries(
const ecModel = api.getModel();
blurScope = blurScope || 'coordinateSystem';
- function leaveBlurOfIndices(data: List, dataIndices: ArrayLike<number>) {
+ function leaveBlurOfIndices(data: SeriesData, dataIndices: ArrayLike<number>) {
for (let i = 0; i < dataIndices.length; i++) {
const itemEl = data.getItemGraphicEl(dataIndices[i]);
itemEl && leaveBlur(itemEl);
diff --git a/src/util/types.ts b/src/util/types.ts
index 225d6cb..3e4dd22 100644
--- a/src/util/types.ts
+++ b/src/util/types.ts
@@ -33,7 +33,7 @@ import ExtensionAPI from '../core/ExtensionAPI';
import SeriesModel from '../model/Series';
import { createHashMap, HashMap } from 'zrender/src/core/util';
import { TaskPlanCallbackReturn, TaskProgressParams } from '../core/task';
-import List, {ListDimensionType} from '../data/List';
+import SeriesData from '../data/SeriesData';
import { Dictionary, ElementEventName, ImageLike, TextAlign, TextVerticalAlign } from 'zrender/src/core/types';
import { PatternObject } from 'zrender/src/graphic/Pattern';
import { TooltipMarker } from './format';
@@ -47,6 +47,7 @@ import { ImageStyleProps } from 'zrender/src/graphic/Image';
import ZRText, { TextStyleProps } from 'zrender/src/graphic/Text';
import { Source } from '../data/Source';
import Model from '../model/Model';
+import { DataStoreDimensionType } from '../data/DataStorage';
@@ -128,7 +129,7 @@ export interface ECElement extends Element {
}
export interface DataHost {
- getData(dataType?: SeriesDataType): List;
+ getData(dataType?: SeriesDataType): SeriesData;
}
export interface DataModel extends Model<unknown>, DataHost, DataFormatMixin {}
@@ -300,8 +301,8 @@ export interface StageHandlerInternal extends StageHandler {
export type StageHandlerProgressParams = TaskProgressParams;
export interface StageHandlerProgressExecutor {
- dataEach?: (data: List, idx: number) => void;
- progress?: (params: StageHandlerProgressParams, data: List) => void;
+ dataEach?: (data: SeriesData, idx: number) => void;
+ progress?: (params: StageHandlerProgressParams, data: SeriesData) => void;
}
export type StageHandlerPlanReturn = TaskPlanCallbackReturn;
export interface StageHandlerPlan {
@@ -355,11 +356,11 @@ export type OrdinalSortInfo = {
/**
* `OptionDataValue` is the primitive value in `series.data` or `dataset.source`.
* `OptionDataValue` are parsed (see `src/data/helper/dataValueHelper.parseDataValue`)
- * into `ParsedValue` and stored into `data/List` storage.
+ * into `ParsedValue` and stored into `data/SeriesData` storage.
* Note:
* (1) The term "parse" does not mean `src/scale/Scale['parse']`.
* (2) If a category dimension is not mapped to any axis, its raw value will NOT be
- * parsed to `OrdinalNumber` but keep the original `OrdinalRawValue` in `src/data/List` storage.
+ * parsed to `OrdinalNumber` but keep the original `OrdinalRawValue` in `src/data/SeriesData` storage.
*/
export type ParsedValue = ParsedValueNumeric | OrdinalRawValue;
export type ParsedValueNumeric = number | OrdinalNumber;
@@ -414,7 +415,7 @@ export type DimensionIndex = number;
export type DimensionIndexLoose = DimensionIndex | string;
export type DimensionName = string;
export type DimensionLoose = DimensionName | DimensionIndexLoose;
-export type DimensionType = ListDimensionType;
+export type DimensionType = DataStoreDimensionType;
export const VISUAL_DIMENSIONS = createHashMap<number, keyof DataVisualDimensions>([
'tooltip', 'label', 'itemName', 'itemId', 'itemGroupId', 'seriesName'
@@ -436,7 +437,7 @@ export interface DataVisualDimensions {
}
export type DimensionDefinition = {
- type?: ListDimensionType,
+ type?: DataStoreDimensionType,
name?: DimensionName,
displayName?: string
};
diff --git a/src/view/Chart.ts b/src/view/Chart.ts
index eb9db4a..8f32838 100644
--- a/src/view/Chart.ts
+++ b/src/view/Chart.ts
@@ -34,7 +34,7 @@ import {
StageHandlerPlanReturn, DisplayState, StageHandlerProgressParams, ECElementEvent
} from '../util/types';
import { SeriesTaskContext, SeriesTask } from '../core/Scheduler';
-import List from '../data/List';
+import SeriesData from '../data/SeriesData';
const inner = modelUtil.makeInner<{
updateMethod: keyof ChartView
@@ -206,7 +206,7 @@ function elSetState(el: Element, state: DisplayState, highlightDigit: number) {
}
}
-function toggleHighlight(data: List, payload: Payload, state: DisplayState) {
+function toggleHighlight(data: SeriesData, payload: Payload, state: DisplayState) {
const dataIndex = modelUtil.queryDataIndex(data, payload);
const highlightDigit = (payload && payload.highlightKey != null)
diff --git a/src/visual/LegendVisualProvider.ts b/src/visual/LegendVisualProvider.ts
index c62297e..c4ff79a 100644
--- a/src/visual/LegendVisualProvider.ts
+++ b/src/visual/LegendVisualProvider.ts
@@ -1,4 +1,4 @@
-import List from '../data/List';
+import SeriesData from '../data/SeriesData';
/*
* Licensed to the Apache Software Foundation (ASF) under one
@@ -26,14 +26,14 @@ import List from '../data/List';
*/
class LegendVisualProvider {
- private _getDataWithEncodedVisual: () => List;
- private _getRawData: () => List;
+ private _getDataWithEncodedVisual: () => SeriesData;
+ private _getRawData: () => SeriesData;
constructor(
// Function to get data after filtered. It stores all the encoding info
- getDataWithEncodedVisual: () => List,
+ getDataWithEncodedVisual: () => SeriesData,
// Function to get raw data before filtered.
- getRawData: () => List
+ getRawData: () => SeriesData
) {
this._getDataWithEncodedVisual = getDataWithEncodedVisual;
this._getRawData = getRawData;
diff --git a/src/visual/commonVisualTypes.ts b/src/visual/commonVisualTypes.ts
index e279a4c..7b81214 100644
--- a/src/visual/commonVisualTypes.ts
+++ b/src/visual/commonVisualTypes.ts
@@ -17,7 +17,7 @@
* under the License.
*/
-import { DefaultDataVisual } from '../data/List';
+import { DefaultDataVisual } from '../data/SeriesData';
export interface LineDataVisual extends DefaultDataVisual {
fromSymbol: string
diff --git a/src/visual/helper.ts b/src/visual/helper.ts
index e419a9a..5c60f6f 100644
--- a/src/visual/helper.ts
+++ b/src/visual/helper.ts
@@ -24,10 +24,10 @@
* In the List module storage:
* 'style', 'symbol', 'symbolSize'...
*/
-import List from '../data/List';
+import SeriesData from '../data/SeriesData';
-export function getItemVisualFromData(data: List, dataIndex: number, key: string) {
+export function getItemVisualFromData(data: SeriesData, dataIndex: number, key: string) {
switch (key) {
case 'color':
const style = data.getItemVisual(dataIndex, 'style');
@@ -45,7 +45,7 @@ export function getItemVisualFromData(data: List, dataIndex: number, key: string
}
}
-export function getVisualFromData(data: List, key: string) {
+export function getVisualFromData(data: SeriesData, key: string) {
switch (key) {
case 'color':
const style = data.getVisual('style');
@@ -63,7 +63,7 @@ export function getVisualFromData(data: List, key: string) {
}
}
-export function setItemVisualFromData(data: List, dataIndex: number, key: string, value: any) {
+export function setItemVisualFromData(data: SeriesData, dataIndex: number, key: string, value: any) {
switch (key) {
case 'color':
// Make sure not sharing style object.
diff --git a/src/visual/symbol.ts b/src/visual/symbol.ts
index 1e17689..019d536 100644
--- a/src/visual/symbol.ts
+++ b/src/visual/symbol.ts
@@ -28,7 +28,7 @@ import {
SymbolRotateCallback,
SymbolOffsetCallback
} from '../util/types';
-import List from '../data/List';
+import SeriesData from '../data/SeriesData';
import SeriesModel from '../model/Series';
import GlobalModel from '../model/Global';
@@ -91,7 +91,7 @@ const seriesSymbolTask: StageHandler = {
return;
}
- function dataEach(data: List, idx: number) {
+ function dataEach(data: SeriesData, idx: number) {
const rawValue = seriesModel.getRawValue(idx);
const params = seriesModel.getDataParams(idx);
hasSymbolTypeCallback && data.setItemVisual(
@@ -133,7 +133,7 @@ const dataSymbolTask: StageHandler = {
const data = seriesModel.getData();
- function dataEach(data: List, idx: number) {
+ function dataEach(data: SeriesData, idx: number) {
const itemModel = data.getItemModel<SymbolOptionMixin>(idx);
const itemSymbolType = itemModel.getShallow('symbol', true);
const itemSymbolSize = itemModel.getShallow('symbolSize', true);
diff --git a/src/visual/visualSolution.ts b/src/visual/visualSolution.ts
index accd72d..2f014a8 100644
--- a/src/visual/visualSolution.ts
+++ b/src/visual/visualSolution.ts
@@ -30,7 +30,7 @@ import {
DimensionLoose,
StageHandlerProgressExecutor
} from '../util/types';
-import List from '../data/List';
+import SeriesData from '../data/SeriesData';
import { getItemVisualFromData, setItemVisualFromData } from './helper';
const each = zrUtil.each;
@@ -135,7 +135,7 @@ export function replaceVisualOption<T extends string>(
export function applyVisual<VisualState extends string, Scope>(
stateList: readonly VisualState[],
visualMappings: VisualMappingCollection<VisualState>,
- data: List,
+ data: SeriesData,
getValueState: (this: Scope, valueOrIndex: ParsedValue | number) => VisualState,
scope?: Scope,
dimension?: DimensionLoose
diff --git a/test/ut/spec/data/List.test.ts b/test/ut/spec/data/SeriesData.test.ts
similarity index 92%
rename from test/ut/spec/data/List.test.ts
rename to test/ut/spec/data/SeriesData.test.ts
index c136afc..6442cf3 100644
--- a/test/ut/spec/data/List.test.ts
+++ b/test/ut/spec/data/SeriesData.test.ts
@@ -20,7 +20,7 @@
/* global Float32Array */
-import List from '../../../../src/data/List';
+import SeriesData from '../../../../src/data/SeriesData';
import Model from '../../../../src/model/Model';
import { createSourceFromSeriesDataOption, Source, createSource } from '../../../../src/data/Source';
import { OptionDataItemObject, OptionDataValue, SOURCE_FORMAT_ARRAY_ROWS } from '../../../../src/util/types';
@@ -37,7 +37,7 @@ describe('List', function () {
describe('Data Manipulation', function () {
it('initData 1d', function () {
- const list = new List(['x', 'y'], new Model());
+ const list = new SeriesData(['x', 'y'], new Model());
list.initData([10, 20, 30]);
expect(list.get('x', 0)).toEqual(10);
expect(list.get('x', 1)).toEqual(20);
@@ -46,21 +46,21 @@ describe('List', function () {
});
it('initData 2d', function () {
- const list = new List(['x', 'y'], new Model());
+ const list = new SeriesData(['x', 'y'], new Model());
list.initData([[10, 15], [20, 25], [30, 35]]);
expect(list.get('x', 1)).toEqual(20);
expect(list.get('y', 1)).toEqual(25);
});
it('initData 2d yx', function () {
- const list = new List(['y', 'x'], new Model());
+ const list = new SeriesData(['y', 'x'], new Model());
list.initData([[10, 15], [20, 25], [30, 35]]);
expect(list.get('x', 1)).toEqual(25);
expect(list.get('y', 1)).toEqual(20);
});
it('Data with option 1d', function () {
- const list = new List(['x', 'y'], new Model());
+ const list = new SeriesData(['x', 'y'], new Model());
list.initData([
1,
{
@@ -73,17 +73,17 @@ describe('List', function () {
});
it('Empty data', function () {
- const list = new List(['x', 'y'], new Model());
+ const list = new SeriesData(['x', 'y'], new Model());
list.initData([1, '-']);
expect(list.get('y', 1)).toBeNaN();
});
it('getRawValue', function () {
- const list1 = new List(['x', 'y'], new Model());
+ const list1 = new SeriesData(['x', 'y'], new Model());
// here construct a new list2 because if we only use one list
// to call initData() twice, list._chunkCount will be accumulated
// to 1 instead of 0.
- const list2 = new List(['x', 'y'], new Model());
+ const list2 = new SeriesData(['x', 'y'], new Model());
list1.initData([1, 2, 3]);
expect(list1.getItemModel(1).option).toEqual(2);
@@ -93,22 +93,22 @@ describe('List', function () {
});
it('indexOfRawIndex', function () {
- const list = new List(['x'], new Model());
+ const list = new SeriesData(['x'], new Model());
list.initData([]);
expect(list.indexOfRawIndex(1)).toEqual(-1);
- const list1 = new List(['x'], new Model());
+ const list1 = new SeriesData(['x'], new Model());
list1.initData([0]);
expect(list1.indexOfRawIndex(0)).toEqual(0);
expect(list1.indexOfRawIndex(1)).toEqual(-1);
- const list2 = new List(['x'], new Model());
+ const list2 = new SeriesData(['x'], new Model());
list2.initData([0, 1, 2, 3]);
expect(list2.indexOfRawIndex(1)).toEqual(1);
expect(list2.indexOfRawIndex(2)).toEqual(2);
expect(list2.indexOfRawIndex(5)).toEqual(-1);
- const list3 = new List(['x'], new Model());
+ const list3 = new SeriesData(['x'], new Model());
list3.initData([0, 1, 2, 3, 4]);
expect(list3.indexOfRawIndex(2)).toEqual(2);
expect(list3.indexOfRawIndex(3)).toEqual(3);
@@ -121,14 +121,14 @@ describe('List', function () {
});
it('getDataExtent', function () {
- const list = new List(['x', 'y'], new Model());
+ const list = new SeriesData(['x', 'y'], new Model());
list.initData([1, 2, 3]);
expect(list.getDataExtent('x')).toEqual([1, 3]);
expect(list.getDataExtent('y')).toEqual([1, 3]);
});
it('Data types', function () {
- const list = new List([{
+ const list = new SeriesData([{
name: 'x',
type: 'int'
}, {
@@ -141,7 +141,7 @@ describe('List', function () {
});
it('map', function () {
- const list = new List(['x', 'y'], new Model());
+ const list = new SeriesData(['x', 'y'], new Model());
list.initData([[10, 15], [20, 25], [30, 35]]);
expect(list.map(['x', 'y'], function (x: number, y: number) {
return [x + 2, y + 2];
@@ -151,7 +151,7 @@ describe('List', function () {
});
it('mapArray', function () {
- const list = new List(['x', 'y'], new Model());
+ const list = new SeriesData(['x', 'y'], new Model());
list.initData([[10, 15], [20, 25], [30, 35]]);
expect(list.mapArray(['x', 'y'], function (x, y) {
return [x, y];
@@ -159,7 +159,7 @@ describe('List', function () {
});
it('filterSelf', function () {
- const list = new List(['x', 'y'], new Model());
+ const list = new SeriesData(['x', 'y'], new Model());
list.initData([[10, 15], [20, 25], [30, 35]]);
expect(list.filterSelf(['x', 'y'], function (x, y) {
return x < 30 && x > 10;
@@ -169,7 +169,7 @@ describe('List', function () {
});
it('dataProvider', function () {
- const list = new List(['x', 'y'], new Model());
+ const list = new SeriesData(['x', 'y'], new Model());
const typedArray = new Float32Array([10, 10, 20, 20]);
const source = createSourceFromSeriesDataOption(typedArray);
list.initData({
@@ -193,7 +193,7 @@ describe('List', function () {
describe('Data read', function () {
it('indicesOfNearest', function () {
- const list = new List(['value'], new Model());
+ const list = new SeriesData(['value'], new Model());
// ---- index: 0 1 2 3 4 5 6 7
list.initData([10, 20, 30, 35, 40, 40, 35, 50]);
@@ -213,7 +213,7 @@ describe('List', function () {
describe('id_and_name', function () {
- function makeOneByOneChecker(list: List) {
+ function makeOneByOneChecker(list: SeriesData) {
let getIdDataIndex = 0;
let getNameDataIndex = 0;
@@ -237,7 +237,7 @@ describe('List', function () {
describe('only_name_declared', function () {
- function doChecks(list: List) {
+ function doChecks(list: SeriesData) {
const oneByOne = makeOneByOneChecker(list);
oneByOne.idEqualsTo('a');
@@ -260,7 +260,7 @@ describe('List', function () {
}
it('sourceFormatOriginal', function () {
- const list = new List(['x', 'y'], new Model());
+ const list = new SeriesData(['x', 'y'], new Model());
list.initData([
{ value: 10, name: 'a' },
{ value: 20, name: 'b' },
@@ -276,7 +276,7 @@ describe('List', function () {
});
it('sourceFormatArrayRows', function () {
- const list = new List(
+ const list = new SeriesData(
[
'x',
{ name: 'q', type: 'ordinal', otherDims: { itemName: 0 } }
@@ -314,7 +314,7 @@ describe('List', function () {
describe('id_name_declared_sourceFormat_original', function () {
it('sourceFormatOriginal', function () {
- const list = new List(['x'], new Model());
+ const list = new SeriesData(['x'], new Model());
const oneByOne = makeOneByOneChecker(list);
list.initData([
@@ -407,7 +407,7 @@ describe('List', function () {
describe('id_name_declared_sourceFormat_arrayRows', function () {
- function makeChecker(list: List) {
+ function makeChecker(list: SeriesData) {
const oneByOne = makeOneByOneChecker(list);
return {
checkAfterInitData() {
@@ -491,7 +491,7 @@ describe('List', function () {
});
function testArrayRowsInSource(dimensionsInfo: DataDimensionInfo[]): void {
- const list = new List(dimensionsInfo, new Model());
+ const list = new SeriesData(dimensionsInfo, new Model());
const checker = makeChecker(list);
const source = createSource(
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@echarts.apache.org
For additional commands, e-mail: commits-help@echarts.apache.org