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 2020/04/01 06:28:43 UTC
[incubator-echarts] branch next updated: refact: use 'style' in
visual instead of separate color, opacity. bug fixes on state management.
This is an automated email from the ASF dual-hosted git repository.
shenyi pushed a commit to branch next
in repository https://gitbox.apache.org/repos/asf/incubator-echarts.git
The following commit(s) were added to refs/heads/next by this push:
new 51c675d refact: use 'style' in visual instead of separate color, opacity. bug fixes on state management.
51c675d is described below
commit 51c675d11a8ba94d3f47ed170ed5e3b8c1ee5d2e
Author: pissang <bm...@gmail.com>
AuthorDate: Wed Apr 1 14:28:01 2020 +0800
refact: use 'style' in visual instead of separate color, opacity. bug fixes on state management.
---
src/chart/bar/BarView.ts | 41 ++---
src/chart/bar/PictorialBarSeries.ts | 4 +
src/chart/bar/PictorialBarView.ts | 50 +++---
src/chart/bar/barItemStyle.ts | 60 -------
src/chart/boxplot/BoxplotSeries.ts | 2 +
src/chart/boxplot/BoxplotView.ts | 13 +-
src/chart/boxplot/boxplotVisual.ts | 29 +---
src/chart/candlestick/CandlestickView.ts | 20 +--
src/chart/candlestick/candlestickVisual.ts | 18 +-
src/chart/effectScatter.ts | 2 -
src/chart/effectScatter/EffectScatterSeries.ts | 1 +
src/chart/funnel.ts | 2 -
src/chart/funnel/FunnelSeries.ts | 2 +
src/chart/funnel/FunnelView.ts | 23 +--
src/chart/gauge/GaugeView.ts | 1 +
src/chart/graph.ts | 2 -
src/chart/graph/GraphSeries.ts | 7 +-
src/chart/graph/GraphView.ts | 4 +-
src/chart/graph/categoryVisual.ts | 37 ++--
src/chart/graph/edgeVisual.ts | 43 +++--
src/chart/heatmap/HeatmapView.ts | 13 +-
src/chart/helper/EffectLine.ts | 7 +-
src/chart/helper/EffectSymbol.ts | 4 +-
src/chart/helper/LargeLineDraw.ts | 6 +-
src/chart/helper/LargeSymbolDraw.ts | 16 +-
src/chart/helper/Line.ts | 66 ++++---
src/chart/helper/LineDraw.ts | 2 +-
src/chart/helper/Polyline.ts | 14 +-
src/chart/helper/Symbol.ts | 74 +++-----
src/chart/helper/SymbolDraw.ts | 5 +-
src/chart/line.ts | 3 +-
src/chart/line/LineSeries.ts | 3 +
src/chart/line/LineView.ts | 6 +-
src/chart/lines/LinesSeries.ts | 3 +-
src/chart/lines/linesVisual.ts | 14 +-
src/chart/map.ts | 2 -
src/chart/map/MapView.ts | 3 +-
src/chart/parallel/ParallelSeries.ts | 3 +-
src/chart/parallel/ParallelView.ts | 25 +--
src/chart/parallel/parallelVisual.ts | 23 +--
src/chart/pictorialBar.ts | 2 -
src/chart/pie.ts | 2 -
src/chart/pie/PieSeries.ts | 2 +
src/chart/pie/PieView.ts | 27 ++-
src/chart/radar.ts | 4 -
src/chart/radar/RadarSeries.ts | 4 +
src/chart/radar/RadarView.ts | 21 ++-
src/chart/scatter.ts | 3 -
src/chart/scatter/ScatterSeries.ts | 2 +
src/chart/sunburst.ts | 2 -
src/chart/sunburst/SunburstPiece.ts | 148 ++++++++--------
src/chart/sunburst/SunburstSeries.ts | 12 +-
src/chart/sunburst/SunburstView.ts | 6 +-
src/chart/sunburst/sunburstLayout.ts | 4 +-
.../sunburstVisual.ts} | 35 ++--
src/chart/themeRiver.ts | 2 -
src/chart/themeRiver/ThemeRiverSeries.ts | 2 +
src/chart/themeRiver/ThemeRiverView.ts | 11 +-
src/chart/tree.ts | 4 +-
src/chart/tree/TreeSeries.ts | 5 +
src/chart/tree/TreeView.ts | 3 +
src/chart/{map/mapVisual.ts => tree/treeVisual.ts} | 28 ++-
src/chart/treemap/TreemapView.ts | 5 +-
src/chart/treemap/treemapVisual.ts | 6 +-
src/component/axis/AngleAxisView.ts | 1 -
src/component/axis/AxisBuilder.ts | 1 +
src/component/axis/CartesianAxisView.ts | 2 +
src/component/axis/axisSplitHelper.ts | 1 +
src/component/brush/brushAction.ts | 2 +-
src/component/helper/MapDraw.ts | 14 +-
src/component/legend/LegendView.ts | 40 ++---
src/component/marker/MarkAreaView.ts | 34 ++--
src/component/marker/MarkLineView.ts | 35 ++--
src/component/marker/MarkPointView.ts | 11 +-
src/component/toolbox/ToolboxView.ts | 2 +-
src/component/visualMap/visualEncoding.ts | 3 +-
src/data/Graph.ts | 20 +--
src/data/List.ts | 189 ++++++++++++---------
src/data/Tree.ts | 7 +-
src/echarts.ts | 70 +++++---
src/model/Model.ts | 4 +-
src/model/Series.ts | 40 ++++-
src/model/mixin/areaStyle.ts | 5 +-
src/model/mixin/dataFormat.ts | 7 +-
src/model/mixin/itemStyle.ts | 6 +-
src/model/mixin/lineStyle.ts | 6 +-
src/model/mixin/makeStyleMapper.ts | 11 +-
src/util/graphic.ts | 121 ++++++++-----
src/util/symbol.ts | 39 +++--
src/util/types.ts | 2 +-
src/view/Chart.ts | 10 --
src/visual/LegendVisualProvider.ts | 2 +-
src/{chart/tree.ts => visual/commonVisualTypes.ts} | 16 +-
src/visual/dataColor.ts | 95 -----------
src/visual/helper.ts | 87 ++++++++++
src/visual/seriesColor.ts | 75 --------
src/visual/style.ts | 165 ++++++++++++++++++
src/visual/symbol.ts | 178 +++++++++++--------
src/visual/visualSolution.ts | 9 +-
99 files changed, 1185 insertions(+), 1118 deletions(-)
diff --git a/src/chart/bar/BarView.ts b/src/chart/bar/BarView.ts
index 53c9817..f7e4719 100644
--- a/src/chart/bar/BarView.ts
+++ b/src/chart/bar/BarView.ts
@@ -19,8 +19,7 @@
import {__DEV__} from '../../config';
import * as zrUtil from 'zrender/src/core/util';
-import {Rect, Sector, getECData, updateProps, initProps, enableHoverEmphasis, setLabelStyle} from '../../util/graphic';
-import {getBarItemStyle} from './barItemStyle';
+import {Rect, Sector, getECData, updateProps, initProps, enableHoverEmphasis, setLabelStyle, clearStates} from '../../util/graphic';
import Path, { PathProps } from 'zrender/src/graphic/Path';
import Group from 'zrender/src/graphic/Group';
import {throttle} from '../../util/throttle';
@@ -30,7 +29,7 @@ import ChartView from '../../view/Chart';
import List from '../../data/List';
import GlobalModel from '../../model/Global';
import ExtensionAPI from '../../ExtensionAPI';
-import { StageHandlerProgressParams, ZRElementEvent } from '../../util/types';
+import { StageHandlerProgressParams, ZRElementEvent, ColorString } from '../../util/types';
import BarSeriesModel, { BarSeriesOption, BarDataItemOption } from './BarSeries';
import type Axis2D from '../../coord/cartesian/Axis2D';
import type Cartesian2D from '../../coord/cartesian/Cartesian2D';
@@ -171,7 +170,7 @@ class BarView extends ChartView {
const bgEl = createBackgroundEl(
coord, isHorizontalOrRadial, layout
);
- bgEl.useStyle(getBarItemStyle(backgroundModel));
+ bgEl.useStyle(backgroundModel.getItemStyle());
bgEls[dataIndex] = bgEl;
}
@@ -207,7 +206,7 @@ class BarView extends ChartView {
if (drawBackground) {
const bgEl = oldBgEls[oldIndex];
- bgEl.useStyle(getBarItemStyle(backgroundModel));
+ bgEl.useStyle(backgroundModel.getItemStyle());
bgEls[newIndex] = bgEl;
const shape = createBackgroundShape(isHorizontalOrRadial, layout, coord);
@@ -231,6 +230,7 @@ class BarView extends ChartView {
}
if (el) {
+ clearStates(el);
updateProps(el as Path, {
shape: layout
}, animationModel, newIndex);
@@ -394,6 +394,7 @@ const elementCreator: {
shape: zrUtil.extend({}, layout),
z2: 1
});
+ // rect.autoBatch = true;
rect.name = 'item';
@@ -528,24 +529,16 @@ function updateStyle(
isHorizontal: boolean,
isPolar: boolean
) {
- const color = data.getItemVisual(dataIndex, 'color');
- const opacity = data.getItemVisual(dataIndex, 'opacity');
- const stroke = data.getVisual('borderColor');
- const itemStyleModel = itemModel.getModel('itemStyle');
- const hoverStyle = getBarItemStyle(itemModel.getModel(['emphasis', 'itemStyle']));
+ const style = data.getItemVisual(dataIndex, 'style');
+ const hoverStyle = itemModel.getModel(['emphasis', 'itemStyle']).getItemStyle();
if (!isPolar) {
- (el as Rect).setShape('r', itemStyleModel.get('barBorderRadius') || 0);
+ (el as Rect).setShape('r', itemModel.get(['itemStyle', 'barBorderRadius']) || 0);
}
- el.useStyle(zrUtil.defaults(
- {
- stroke: isZeroOnPolar(layout as SectorLayout) ? 'none' : stroke,
- fill: isZeroOnPolar(layout as SectorLayout) ? 'none' : color,
- opacity: opacity
- },
- getBarItemStyle(itemStyleModel)
- ));
+ el.useStyle(style);
+
+ el.ignore = isZeroOnPolar(layout as SectorLayout);
const cursorStyle = itemModel.getShallow('cursor');
cursorStyle && (el as Path).attr('cursor', cursorStyle);
@@ -563,7 +556,7 @@ function updateStyle(
labelFetcher: seriesModel,
labelDataIndex: dataIndex,
defaultText: getDefaultLabel(seriesModel.getData(), dataIndex),
- autoColor: color,
+ autoColor: style.fill as ColorString,
defaultOutsidePosition: labelPositionOutside
}
);
@@ -727,12 +720,12 @@ function setLargeStyle(
seriesModel: BarSeriesModel,
data: List
) {
- const borderColor = data.getVisual('borderColor') || data.getVisual('color');
- const itemStyle = seriesModel.getModel('itemStyle').getItemStyle(['color', 'borderColor']);
+ const globalStyle = data.getVisual('style');
- el.useStyle(itemStyle);
+ el.useStyle(zrUtil.extend({}, globalStyle));
+ // Use stroke instead of fill.
el.style.fill = null;
- el.style.stroke = borderColor;
+ el.style.stroke = globalStyle.fill;
el.style.lineWidth = data.getLayout('barWidth');
}
diff --git a/src/chart/bar/PictorialBarSeries.ts b/src/chart/bar/PictorialBarSeries.ts
index d6ff9e0..07abcc7 100644
--- a/src/chart/bar/PictorialBarSeries.ts
+++ b/src/chart/bar/PictorialBarSeries.ts
@@ -124,6 +124,10 @@ class PictorialBarSeriesModel extends BaseBarSeriesModel<PictorialBarSeriesOptio
coordinateSystem: Cartesian2D;
+
+ hasSymbolVisual = true;
+ defaultSymbol = 'roundRect';
+
static defaultOption: PictorialBarSeriesOption = inheritDefaultOption(BaseBarSeriesModel.defaultOption, {
symbol: 'circle', // Customized bar shape
diff --git a/src/chart/bar/PictorialBarView.ts b/src/chart/bar/PictorialBarView.ts
index 743ab47..518630c 100644
--- a/src/chart/bar/PictorialBarView.ts
+++ b/src/chart/bar/PictorialBarView.ts
@@ -33,7 +33,7 @@ import type Displayable from 'zrender/src/graphic/Displayable';
import type Axis2D from '../../coord/cartesian/Axis2D';
import type Element from 'zrender/src/Element';
import { getDefaultLabel } from '../helper/labelHelper';
-import { PathProps } from 'zrender/src/graphic/Path';
+import { PathProps, PathStyleProps } from 'zrender/src/graphic/Path';
const BAR_BORDER_WIDTH_QUERY = ['itemStyle', 'borderWidth'] as const;
@@ -90,7 +90,7 @@ interface SymbolMeta {
valueLineWidth: number
opacity: number
- color: ColorString
+ style: PathStyleProps
z2: number
itemModel: ItemModel
@@ -190,6 +190,7 @@ class PictorialBarView extends ChartView {
}
if (bar) {
+ bar.clearStates();
updateBar(bar, opt, symbolMeta);
}
else {
@@ -253,7 +254,7 @@ function getSymbolMeta(
layout: layout,
itemModel: itemModel,
symbolType: data.getItemVisual(dataIndex, 'symbol') || 'circle',
- color: data.getItemVisual(dataIndex, 'color'),
+ style: data.getItemVisual(dataIndex, 'style'),
symbolClip: symbolClip,
symbolRepeat: symbolRepeat,
symbolRepeatDirection: itemModel.get('symbolRepeatDirection'),
@@ -354,15 +355,19 @@ function prepareSymbolSize(
const categoryDim = opt.categoryDim;
const categorySize = Math.abs(layout[categoryDim.wh]);
- let symbolSize = data.getItemVisual(dataIndex, 'symbolSize');
+ const symbolSize = data.getItemVisual(dataIndex, 'symbolSize');
+ let parsedSymbolSize: number[];
if (zrUtil.isArray(symbolSize)) {
- symbolSize = symbolSize.slice();
+ parsedSymbolSize = symbolSize.slice();
}
else {
if (symbolSize == null) {
- symbolSize = '100%';
+ // will parse to number below
+ parsedSymbolSize = ['100%', '100%'] as unknown as number[];
+ }
+ else {
+ parsedSymbolSize = [symbolSize, symbolSize];
}
- symbolSize = [symbolSize, symbolSize];
}
// Note: percentage symbolSize (like '100%') do not consider lineWidth, because it is
@@ -370,21 +375,21 @@ function prepareSymbolSize(
// So the actual size will bigger than layout size if lineWidth is bigger than zero,
// which can be tolerated in pictorial chart.
- symbolSize[categoryDim.index] = parsePercent(
- symbolSize[categoryDim.index],
+ parsedSymbolSize[categoryDim.index] = parsePercent(
+ parsedSymbolSize[categoryDim.index],
categorySize
);
- symbolSize[valueDim.index] = parsePercent(
- symbolSize[valueDim.index],
+ parsedSymbolSize[valueDim.index] = parsePercent(
+ parsedSymbolSize[valueDim.index],
symbolRepeat ? categorySize : Math.abs(boundingLength)
);
- outputSymbolMeta.symbolSize = symbolSize;
+ outputSymbolMeta.symbolSize = parsedSymbolSize;
// If x or y is less than zero, show reversed shape.
const symbolScale = outputSymbolMeta.symbolScale = [
- symbolSize[0] / symbolPatternSize,
- symbolSize[1] / symbolPatternSize
+ parsedSymbolSize[0] / symbolPatternSize,
+ parsedSymbolSize[1] / symbolPatternSize
];
// Follow convention, 'right' and 'top' is the normal scale.
symbolScale[valueDim.index] *= (opt.isHorizontal ? -1 : 1) * pxSign;
@@ -523,8 +528,7 @@ function createPath(symbolMeta: SymbolMeta) {
-symbolPatternSize / 2,
-symbolPatternSize / 2,
symbolPatternSize,
- symbolPatternSize,
- symbolMeta.color
+ symbolPatternSize
);
(path as Displayable).attr({
culling: true
@@ -921,25 +925,15 @@ function updateCommon(
opt: CreateOpts,
symbolMeta: SymbolMeta
) {
- const color = symbolMeta.color;
const dataIndex = symbolMeta.dataIndex;
const itemModel = symbolMeta.itemModel;
// Color must be excluded.
// Because symbol provide setColor individually to set fill and stroke
- const normalStyle = itemModel.getModel('itemStyle').getItemStyle(['color']);
const hoverStyle = itemModel.getModel(['emphasis', 'itemStyle']).getItemStyle();
const cursorStyle = itemModel.getShallow('cursor');
eachPath(bar, function (path) {
- // PENDING setColor should be before setStyle!!!
- path.setColor(color);
- path.setStyle(zrUtil.defaults(
- {
- fill: color,
- opacity: symbolMeta.opacity
- },
- normalStyle
- ));
+ path.useStyle(symbolMeta.style);
graphic.enableHoverEmphasis(path, hoverStyle);
cursorStyle && (path.cursor = cursorStyle);
@@ -959,7 +953,7 @@ function updateCommon(
labelFetcher: opt.seriesModel,
labelDataIndex: dataIndex,
defaultText: getDefaultLabel(opt.seriesModel.getData(), dataIndex),
- autoColor: color,
+ autoColor: symbolMeta.style.fill as ColorString,
defaultOutsidePosition: barPositionOutside
}
);
diff --git a/src/chart/bar/barItemStyle.ts b/src/chart/bar/barItemStyle.ts
deleted file mode 100644
index bf00770..0000000
--- a/src/chart/bar/barItemStyle.ts
+++ /dev/null
@@ -1,60 +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.
-*/
-
-import makeStyleMapper from '../../model/mixin/makeStyleMapper';
-import Model from '../../model/Model';
-import { PathStyleProps } from 'zrender/src/graphic/Path';
-
-const mapStyle = makeStyleMapper(
- [
- ['fill', 'color'],
- ['stroke', 'borderColor'],
- ['lineWidth', 'borderWidth'],
- // Compatitable with 2
- ['stroke', 'barBorderColor'],
- ['lineWidth', 'barBorderWidth'],
- ['opacity'],
- ['shadowBlur'],
- ['shadowOffsetX'],
- ['shadowOffsetY'],
- ['shadowColor']
- ]
-);
-
-type BarItemStyleKeys = 'fill'
- | 'stroke'
- | 'lineWidth'
- | 'stroke'
- | 'lineWidth'
- | 'opacity'
- | 'shadowBlur'
- | 'shadowOffsetX'
- | 'shadowOffsetY'
- | 'shadowColor';
-type ItemStyleProps = Pick<PathStyleProps, BarItemStyleKeys>;
-
-export function getBarItemStyle(model: Model, excludes?: BarItemStyleKeys[]): ItemStyleProps {
- const style = mapStyle(model, excludes);
- if (model.getBorderLineDash) {
- const lineDash = model.getBorderLineDash();
- lineDash && (style.lineDash = lineDash);
- }
- return style;
-}
-
diff --git a/src/chart/boxplot/BoxplotSeries.ts b/src/chart/boxplot/BoxplotSeries.ts
index 7de4b72..d65e505 100644
--- a/src/chart/boxplot/BoxplotSeries.ts
+++ b/src/chart/boxplot/BoxplotSeries.ts
@@ -97,6 +97,8 @@ class BoxplotSeriesModel extends SeriesModel<BoxplotSeriesOption> {
dimensions: string[];
+ visualColorBrushType = 'stroke' as const;
+
static defaultOption: BoxplotSeriesOption = {
zlevel: 0,
z: 2,
diff --git a/src/chart/boxplot/BoxplotView.ts b/src/chart/boxplot/BoxplotView.ts
index e4b4473..21df40f 100644
--- a/src/chart/boxplot/BoxplotView.ts
+++ b/src/chart/boxplot/BoxplotView.ts
@@ -20,7 +20,7 @@
import * as zrUtil from 'zrender/src/core/util';
import ChartView from '../../view/Chart';
import * as graphic from '../../util/graphic';
-import Path, { PathProps, PathStyleProps } from 'zrender/src/graphic/Path';
+import Path, { PathProps } from 'zrender/src/graphic/Path';
import BoxplotSeriesModel, { BoxplotDataItemOption } from './BoxplotSeries';
import GlobalModel from '../../model/Global';
import ExtensionAPI from '../../ExtensionAPI';
@@ -179,14 +179,9 @@ function updateNormalBoxData(
);
const itemModel = data.getItemModel<BoxplotDataItemOption>(dataIndex);
- const normalItemStyleModel = itemModel.getModel('itemStyle');
- const borderColor = data.getItemVisual(dataIndex, 'color');
-
- // Exclude borderColor.
- const itemStyle = normalItemStyleModel.getItemStyle(['borderColor']) as PathStyleProps;
- itemStyle.stroke = borderColor;
- itemStyle.strokeNoScale = true;
- el.useStyle(itemStyle);
+
+ el.useStyle(data.getItemVisual(dataIndex, 'style'));
+ el.style.strokeNoScale = true;
el.z2 = 100;
diff --git a/src/chart/boxplot/boxplotVisual.ts b/src/chart/boxplot/boxplotVisual.ts
index c2ebc87..4deee98 100644
--- a/src/chart/boxplot/boxplotVisual.ts
+++ b/src/chart/boxplot/boxplotVisual.ts
@@ -19,36 +19,11 @@
import GlobalModel from '../../model/Global';
import ExtensionAPI from '../../ExtensionAPI';
-import BoxplotSeriesModel, { BoxplotDataItemOption } from './BoxplotSeries';
-
-const borderColorQuery = ['itemStyle', 'borderColor'] as const;
+import BoxplotSeriesModel from './BoxplotSeries';
export default function (ecModel: GlobalModel, api: ExtensionAPI) {
-
- const globalColors = ecModel.get('color');
-
ecModel.eachRawSeriesByType('boxplot', function (seriesModel: BoxplotSeriesModel) {
-
- const defaulColor = globalColors[seriesModel.seriesIndex % globalColors.length];
- const data = seriesModel.getData();
-
- data.setVisual({
- legendSymbol: 'roundRect',
- // Use name 'color' but not 'borderColor' for legend usage and
- // visual coding from other component like dataRange.
- color: seriesModel.get(borderColorQuery) || defaulColor
- });
-
- // Only visible series has each data be visual encoded
- if (!ecModel.isSeriesFiltered(seriesModel)) {
- data.each(function (idx) {
- const itemModel = data.getItemModel<BoxplotDataItemOption>(idx);
- data.setItemVisual(
- idx,
- {color: itemModel.get(borderColorQuery, true)}
- );
- });
- }
+ seriesModel.getData().setVisual('legendSymbol', 'roundRect');
});
}
\ No newline at end of file
diff --git a/src/chart/candlestick/CandlestickView.ts b/src/chart/candlestick/CandlestickView.ts
index 3130a34..6b9909d 100644
--- a/src/chart/candlestick/CandlestickView.ts
+++ b/src/chart/candlestick/CandlestickView.ts
@@ -132,6 +132,7 @@ class CandlestickView extends ChartView {
el = createNormalBox(itemLayout, newIdx);
}
else {
+ graphic.clearStates(el);
graphic.updateProps(el, {
shape: {
points: itemLayout.ends
@@ -274,18 +275,9 @@ function isNormalBoxClipped(clipArea: CoordinateSystemClipArea, itemLayout: Cand
function setBoxCommon(el: NormalBoxPath, data: List, dataIndex: number, isSimpleBox?: boolean) {
const itemModel = data.getItemModel(dataIndex) as Model<CandlestickDataItemOption>;
- const normalItemStyleModel = itemModel.getModel('itemStyle');
- const color = data.getItemVisual(dataIndex, 'color');
- const borderColor = data.getItemVisual(dataIndex, 'borderColor') || color;
- // Color must be excluded.
- // Because symbol provide setColor individually to set fill and stroke
- const itemStyle = normalItemStyleModel.getItemStyle(SKIP_PROPS);
-
- el.useStyle(itemStyle);
+ el.useStyle(data.getItemVisual(dataIndex, 'style'));
el.style.strokeNoScale = true;
- el.style.fill = color;
- el.style.stroke = borderColor;
el.__simpleBox = isSimpleBox;
@@ -369,9 +361,9 @@ function createLarge(seriesModel: CandlestickSeriesModel, group: graphic.Group,
}
function setLargeStyle(sign: number, el: LargeBoxPath, seriesModel: CandlestickSeriesModel, data: List) {
- const suffix = sign > 0 ? 'P' : 'N';
- const borderColor = data.getVisual('borderColor' + suffix)
- || data.getVisual('color' + suffix);
+ // TODO put in visual?
+ const borderColor = seriesModel.get(['itemStyle', sign > 0 ? 'borderColor' : 'borderColor0'])
+ || seriesModel.get(['itemStyle', sign > 0 ? 'color' : 'color0']);
// Color must be excluded.
// Because symbol provide setColor individually to set fill and stroke
@@ -380,8 +372,6 @@ function setLargeStyle(sign: number, el: LargeBoxPath, seriesModel: CandlestickS
el.useStyle(itemStyle);
el.style.fill = null;
el.style.stroke = borderColor;
- // No different
- // el.style.lineWidth = .5;
}
diff --git a/src/chart/candlestick/candlestickVisual.ts b/src/chart/candlestick/candlestickVisual.ts
index d55d2e6..7e7ed5c 100644
--- a/src/chart/candlestick/candlestickVisual.ts
+++ b/src/chart/candlestick/candlestickVisual.ts
@@ -52,13 +52,7 @@ const candlestickVisual: StageHandler = {
const data = seriesModel.getData();
- data.setVisual({
- legendSymbol: 'roundRect',
- colorP: getColor(1, seriesModel),
- colorN: getColor(-1, seriesModel),
- borderColorP: getBorderColor(1, seriesModel),
- borderColorN: getBorderColor(-1, seriesModel)
- });
+ data.setVisual('legendSymbol', 'roundRect');
// Only visible series has each data be visual encoded
if (ecModel.isSeriesFiltered(seriesModel)) {
@@ -73,13 +67,9 @@ const candlestickVisual: StageHandler = {
const itemModel = data.getItemModel(dataIndex);
const sign = data.getItemLayout(dataIndex).sign;
- data.setItemVisual(
- dataIndex,
- {
- color: getColor(sign, itemModel),
- borderColor: getBorderColor(sign, itemModel)
- }
- );
+ const style = itemModel.getItemStyle(['color', 'borderColor']);
+ style.fill = getColor(sign, itemModel);
+ style.stroke = getBorderColor(sign, itemModel) || style.fill;
}
}
};
diff --git a/src/chart/effectScatter.ts b/src/chart/effectScatter.ts
index 31391f1..06e7dda 100644
--- a/src/chart/effectScatter.ts
+++ b/src/chart/effectScatter.ts
@@ -22,8 +22,6 @@ import * as echarts from '../echarts';
import './effectScatter/EffectScatterSeries';
import './effectScatter/EffectScatterView';
-import visualSymbol from '../visual/symbol';
import layoutPoints from '../layout/points';
-echarts.registerVisual(visualSymbol('effectScatter', 'circle'));
echarts.registerLayout(layoutPoints('effectScatter'));
\ No newline at end of file
diff --git a/src/chart/effectScatter/EffectScatterSeries.ts b/src/chart/effectScatter/EffectScatterSeries.ts
index 99feb09..e4887c7 100644
--- a/src/chart/effectScatter/EffectScatterSeries.ts
+++ b/src/chart/effectScatter/EffectScatterSeries.ts
@@ -81,6 +81,7 @@ class EffectScatterSeriesModel extends SeriesModel<EffectScatterSeriesOption> {
static readonly dependencies = ['grid', 'polar'];
+ hasSymbolVisual = true;
getInitialData(option: EffectScatterSeriesOption, ecModel: GlobalModel): List {
return createListFromArray(this.getSource(), this, {useEncodeDefaulter: true});
diff --git a/src/chart/funnel.ts b/src/chart/funnel.ts
index 154b40b..98c5594 100644
--- a/src/chart/funnel.ts
+++ b/src/chart/funnel.ts
@@ -22,10 +22,8 @@ import * as echarts from '../echarts';
import './funnel/FunnelSeries';
import './funnel/FunnelView';
-import dataColor from '../visual/dataColor';
import funnelLayout from './funnel/funnelLayout';
import dataFilter from '../processor/dataFilter';
-echarts.registerVisual(dataColor('funnel'));
echarts.registerLayout(funnelLayout);
echarts.registerProcessor(dataFilter('funnel'));
\ No newline at end of file
diff --git a/src/chart/funnel/FunnelSeries.ts b/src/chart/funnel/FunnelSeries.ts
index a00c36e..1140507 100644
--- a/src/chart/funnel/FunnelSeries.ts
+++ b/src/chart/funnel/FunnelSeries.ts
@@ -96,6 +96,8 @@ class FunnelSeriesModel extends SeriesModel<FunnelSeriesOption> {
static type = 'series.funnel' as const;
type = FunnelSeriesModel.type;
+ useColorPaletteOnData: true;
+
init(option: FunnelSeriesOption) {
super.init.apply(this, arguments as any);
diff --git a/src/chart/funnel/FunnelView.ts b/src/chart/funnel/FunnelView.ts
index 123b190..b5ae8d6 100644
--- a/src/chart/funnel/FunnelView.ts
+++ b/src/chart/funnel/FunnelView.ts
@@ -24,7 +24,7 @@ import FunnelSeriesModel, {FunnelDataItemOption} from './FunnelSeries';
import GlobalModel from '../../model/Global';
import ExtensionAPI from '../../ExtensionAPI';
import List from '../../data/List';
-import { DisplayState } from '../../util/types';
+import { DisplayState, ColorString } from '../../util/types';
import Displayable from 'zrender/src/graphic/Displayable';
const opacityAccessPath = ['itemStyle', 'opacity'] as const;
@@ -51,7 +51,7 @@ class FunnelPiece extends graphic.Group {
this.updateData(data, idx, true);
}
- highDownOnUpdate(fromState: DisplayState, toState: DisplayState) {
+ onStateChange(fromState: DisplayState, toState: DisplayState) {
const labelLine = this.childAt(1) as graphic.Polyline;
const text = this.childAt(2) as graphic.Text;
@@ -102,18 +102,9 @@ class FunnelPiece extends graphic.Group {
}
// Update common style
- const itemStyleModel = itemModel.getModel('itemStyle');
- const visualColor = data.getItemVisual(idx, 'color');
-
- polygon.setStyle(
- zrUtil.defaults(
- {
- lineJoin: 'round',
- fill: visualColor
- },
- itemStyleModel.getItemStyle(['opacity'])
- )
- );
+ polygon.useStyle(data.getItemVisual(idx, 'style'));
+ polygon.style.lineJoin = 'round';
+
const polygonEmphasisState = polygon.ensureState('emphasis');
polygonEmphasisState.style = itemModel.getModel(['emphasis', 'itemStyle']).getItemStyle();
@@ -137,7 +128,8 @@ class FunnelPiece extends graphic.Group {
const labelHoverModel = itemModel.getModel(['emphasis', 'label']);
const labelLineModel = itemModel.getModel('labelLine');
const labelLineHoverModel = itemModel.getModel(['emphasis', 'labelLine']);
- const visualColor = data.getItemVisual(idx, 'color');
+
+ const visualColor = data.getItemVisual(idx, 'style').stroke as ColorString;
graphic.setLabelStyle(
labelText, labelModel, labelHoverModel,
@@ -221,6 +213,7 @@ class FunnelView extends ChartView {
})
.update(function (newIdx, oldIdx) {
const piece = oldData.getItemGraphicEl(oldIdx) as FunnelPiece;
+ graphic.clearStates(piece);
piece.updateData(data, newIdx);
diff --git a/src/chart/gauge/GaugeView.ts b/src/chart/gauge/GaugeView.ts
index fe590bd..77e3c8c 100644
--- a/src/chart/gauge/GaugeView.ts
+++ b/src/chart/gauge/GaugeView.ts
@@ -347,6 +347,7 @@ class GaugeView extends ChartView {
})
.update(function (newIdx, oldIdx) {
const pointer = oldData.getItemGraphicEl(oldIdx) as PointerPath;
+ graphic.clearStates(pointer);
graphic.updateProps(pointer, {
shape: {
diff --git a/src/chart/graph.ts b/src/chart/graph.ts
index 6dcb736..9ed32c8 100644
--- a/src/chart/graph.ts
+++ b/src/chart/graph.ts
@@ -24,7 +24,6 @@ import './graph/GraphView';
import './graph/graphAction';
import categoryFilter from './graph/categoryFilter';
-import visualSymbol from '../visual/symbol';
import categoryVisual from './graph/categoryVisual';
import edgeVisual from './graph/edgeVisual';
import simpleLayout from './graph/simpleLayout';
@@ -35,7 +34,6 @@ import View from '../coord/View';
echarts.registerProcessor(categoryFilter);
-echarts.registerVisual(visualSymbol('graph', 'circle', null));
echarts.registerVisual(categoryVisual);
echarts.registerVisual(edgeVisual);
diff --git a/src/chart/graph/GraphSeries.ts b/src/chart/graph/GraphSeries.ts
index bac92d4..10fd53a 100644
--- a/src/chart/graph/GraphSeries.ts
+++ b/src/chart/graph/GraphSeries.ts
@@ -47,6 +47,7 @@ import Graph from '../../data/Graph';
import GlobalModel from '../../model/Global';
import { VectorArray } from 'zrender/src/core/vector';
import { ForceLayoutInstance } from './forceLayout';
+import { LineDataVisual } from '../../visual/commonVisualTypes';
type GraphDataValue = OptionDataValue | OptionDataValue[];
@@ -224,6 +225,8 @@ class GraphSeriesModel extends SeriesModel<GraphSeriesOption> {
forceLayout?: ForceLayoutInstance;
+ hasSymbolVisual = true;
+
init(option: GraphSeriesOption) {
super.init.apply(this, arguments as any);
@@ -310,8 +313,8 @@ class GraphSeriesModel extends SeriesModel<GraphSeriesOption> {
return this.getData().graph;
}
- getEdgeData(): List {
- return this.getGraph().edgeData;
+ getEdgeData() {
+ return this.getGraph().edgeData as List<GraphSeriesModel, LineDataVisual>;
}
getCategoriesData(): List {
diff --git a/src/chart/graph/GraphView.ts b/src/chart/graph/GraphView.ts
index c73f0b1..7d604a3 100644
--- a/src/chart/graph/GraphView.ts
+++ b/src/chart/graph/GraphView.ts
@@ -38,6 +38,7 @@ import Symbol from '../helper/Symbol';
import Model from '../../model/Model';
import { Payload } from '../../util/types';
import { LineLabel } from '../helper/Line';
+import List from '../../data/List';
const FOCUS_ADJACENCY = '__focusNodeAdjacency';
const UNFOCUS_ADJACENCY = '__unfocusNodeAdjacency';
@@ -172,7 +173,8 @@ class GraphView extends ChartView {
symbolDraw.updateData(data);
const edgeData = seriesModel.getEdgeData();
- lineDraw.updateData(edgeData);
+ // TODO: TYPE
+ lineDraw.updateData(edgeData as List);
this._updateNodeAndLinkScale();
diff --git a/src/chart/graph/categoryVisual.ts b/src/chart/graph/categoryVisual.ts
index 1775d44..593d493 100644
--- a/src/chart/graph/categoryVisual.ts
+++ b/src/chart/graph/categoryVisual.ts
@@ -20,6 +20,7 @@
import GlobalModel from '../../model/Global';
import GraphSeriesModel, { GraphNodeItemOption } from './GraphSeries';
import { Dictionary, ColorString } from '../../util/types';
+import { extend } from 'zrender/src/core/util';
export default function (ecModel: GlobalModel) {
@@ -36,14 +37,12 @@ export default function (ecModel: GlobalModel) {
categoryNameIdxMap['ec-' + name] = idx;
const itemModel = categoriesData.getItemModel<GraphNodeItemOption>(idx);
- const color = itemModel.get(['itemStyle', 'color'])
- || seriesModel.getColorFromPalette(name, paletteScope);
- categoriesData.setItemVisual(idx, 'color', color);
-
- const opacity = itemModel.get(['itemStyle', 'opacity']);
- if (opacity != null) {
- categoriesData.setItemVisual(idx, 'opacity', opacity);
+ const style = itemModel.getItemStyle();
+ if (!style.fill) {
+ // Get color from palette.
+ style.fill = seriesModel.getColorFromPalette(name, paletteScope);
}
+ categoriesData.setItemVisual(idx, 'style', style);
const symbolVisualList = ['symbol', 'symbolSize', 'symbolKeepAspect'] as const;
@@ -59,21 +58,23 @@ export default function (ecModel: GlobalModel) {
if (categoriesData.count()) {
data.each(function (idx) {
const model = data.getItemModel<GraphNodeItemOption>(idx);
- let category = model.getShallow('category');
- if (category != null) {
- if (typeof category === 'string') {
- category = categoryNameIdxMap['ec-' + category];
+ let categoryIdx = model.getShallow('category');
+ if (categoryIdx != null) {
+ if (typeof categoryIdx === 'string') {
+ categoryIdx = categoryNameIdxMap['ec-' + categoryIdx];
}
- const visualList = ['color', 'opacity', 'symbol', 'symbolSize', 'symbolKeepAspect'] as const;
+ const categoryStyle = categoriesData.getItemVisual(categoryIdx, 'style');
+ const style = data.ensureUniqueItemVisual(idx, 'style');
+ extend(style, categoryStyle);
+
+ const visualList = ['symbol', 'symbolSize', 'symbolKeepAspect'] as const;
for (let i = 0; i < visualList.length; i++) {
- if (data.getItemVisual(idx, visualList[i], true) == null) {
- data.setItemVisual(
- idx, visualList[i],
- categoriesData.getItemVisual(category, visualList[i])
- );
- }
+ data.setItemVisual(
+ idx, visualList[i],
+ categoriesData.getItemVisual(categoryIdx, visualList[i])
+ );
}
}
});
diff --git a/src/chart/graph/edgeVisual.ts b/src/chart/graph/edgeVisual.ts
index 85b88ba..7c74786 100644
--- a/src/chart/graph/edgeVisual.ts
+++ b/src/chart/graph/edgeVisual.ts
@@ -19,7 +19,11 @@
import GlobalModel from '../../model/Global';
import GraphSeriesModel, { GraphEdgeItemOption } from './GraphSeries';
+import { DefaultDataVisual } from '../../data/List';
+import { extend } from 'zrender/src/core/util';
+function normalize(a: string | string[]): string[];
+function normalize(a: number | number[]): number[];
function normalize(a: string | number | (string | number)[]): (string | number)[] {
if (!(a instanceof Array)) {
a = [a, a];
@@ -27,6 +31,13 @@ function normalize(a: string | number | (string | number)[]): (string | number)[
return a;
}
+interface EdgeLineDataVisual extends DefaultDataVisual {
+ fromSymbol: string
+ toSymbol: string
+ fromSymbolSize: number
+ toSymbolSize: number
+}
+
export default function (ecModel: GlobalModel) {
ecModel.eachSeriesByType('graph', function (seriesModel: GraphSeriesModel) {
const graph = seriesModel.getGraph();
@@ -34,15 +45,15 @@ export default function (ecModel: GlobalModel) {
const symbolType = normalize(seriesModel.get('edgeSymbol'));
const symbolSize = normalize(seriesModel.get('edgeSymbolSize'));
- const colorQuery = ['lineStyle', 'color'] as const;
- const opacityQuery = ['lineStyle', 'opacity'] as const;
+ // const colorQuery = ['lineStyle', 'color'] as const;
+ // const opacityQuery = ['lineStyle', 'opacity'] as const;
edgeData.setVisual('fromSymbol', symbolType && symbolType[0]);
edgeData.setVisual('toSymbol', symbolType && symbolType[1]);
edgeData.setVisual('fromSymbolSize', symbolSize && symbolSize[0]);
edgeData.setVisual('toSymbolSize', symbolSize && symbolSize[1]);
- edgeData.setVisual('color', seriesModel.get(colorQuery));
- edgeData.setVisual('opacity', seriesModel.get(opacityQuery));
+
+ edgeData.setVisual('style', seriesModel.getModel('itemStyle').getItemStyle());
edgeData.each(function (idx) {
const itemModel = edgeData.getItemModel<GraphEdgeItemOption>(idx);
@@ -50,24 +61,28 @@ export default function (ecModel: GlobalModel) {
const symbolType = normalize(itemModel.getShallow('symbol', true));
const symbolSize = normalize(itemModel.getShallow('symbolSize', true));
// Edge visual must after node visual
- let color = itemModel.get(colorQuery);
- const opacity = itemModel.get(opacityQuery);
- switch (color) {
- case 'source':
- color = edge.node1.getVisual('color');
+ const style = itemModel.getModel('lineStyle').getLineStyle();
+
+ const existsStyle = edgeData.ensureUniqueItemVisual(idx, 'style');
+ extend(existsStyle, style);
+
+ switch (existsStyle.stroke) {
+ case 'source': {
+ const nodeStyle = edge.node1.getVisual('style');
+ existsStyle.stroke = nodeStyle && nodeStyle.fill;
break;
- case 'target':
- color = edge.node2.getVisual('color');
+ }
+ case 'target': {
+ const nodeStyle = edge.node2.getVisual('style');
+ existsStyle.stroke = nodeStyle && nodeStyle.fill;
break;
+ }
}
symbolType[0] && edge.setVisual('fromSymbol', symbolType[0]);
symbolType[1] && edge.setVisual('toSymbol', symbolType[1]);
symbolSize[0] && edge.setVisual('fromSymbolSize', symbolSize[0]);
symbolSize[1] && edge.setVisual('toSymbolSize', symbolSize[1]);
-
- edge.setVisual('color', color);
- edge.setVisual('opacity', opacity);
});
});
}
\ No newline at end of file
diff --git a/src/chart/heatmap/HeatmapView.ts b/src/chart/heatmap/HeatmapView.ts
index ed96906..d4585d3 100644
--- a/src/chart/heatmap/HeatmapView.ts
+++ b/src/chart/heatmap/HeatmapView.ts
@@ -184,7 +184,6 @@ class HeatmapView extends ChartView {
const group = this.group;
const data = seriesModel.getData();
- let style = seriesModel.getModel('itemStyle').getItemStyle(['color']);
let hoverStl = seriesModel.getModel(['emphasis', 'itemStyle']).getItemStyle();
let labelModel = seriesModel.getModel('label');
let hoverLabelModel = seriesModel.getModel(['emphasis', 'label']);
@@ -221,10 +220,7 @@ class HeatmapView extends ChartView {
width: Math.ceil(width),
height: Math.ceil(height)
},
- style: {
- fill: data.getItemVisual(idx, 'color'),
- opacity: data.getItemVisual(idx, 'opacity')
- }
+ style: data.getItemVisual(idx, 'style')
});
}
else {
@@ -236,10 +232,7 @@ class HeatmapView extends ChartView {
rect = new graphic.Rect({
z2: 1,
shape: coordSys.dataToRect([data.get(dataDims[0], idx)]).contentShape,
- style: {
- fill: data.getItemVisual(idx, 'color'),
- opacity: data.getItemVisual(idx, 'opacity')
- }
+ style: data.getItemVisual(idx, 'style')
});
}
@@ -247,7 +240,6 @@ class HeatmapView extends ChartView {
// Optimization for large datset
if (data.hasItemOption) {
- style = itemModel.getModel('itemStyle').getItemStyle(['color']);
hoverStl = itemModel.getModel(['emphasis', 'itemStyle']).getItemStyle();
labelModel = itemModel.getModel('label');
hoverLabelModel = itemModel.getModel(['emphasis', 'label']);
@@ -268,7 +260,6 @@ class HeatmapView extends ChartView {
}
);
- rect.setStyle(style);
graphic.enableHoverEmphasis(rect, data.hasItemOption ? hoverStl : zrUtil.extend({}, hoverStl));
rect.incremental = incremental;
diff --git a/src/chart/helper/EffectLine.ts b/src/chart/helper/EffectLine.ts
index bf20ab9..66503f0 100644
--- a/src/chart/helper/EffectLine.ts
+++ b/src/chart/helper/EffectLine.ts
@@ -30,6 +30,7 @@ import * as curveUtil from 'zrender/src/core/curve';
import type List from '../../data/List';
import { LineDrawSeriesScope, LineDrawModelOption } from './LineDraw';
import Model from '../../model/Model';
+import { ColorString } from '../../util/types';
export type ECSymbolOnEffectLine = ReturnType<typeof createSymbol> & {
__t: number
@@ -67,7 +68,9 @@ class EffectLine extends graphic.Group {
if (!zrUtil.isArray(size)) {
size = [size, size];
}
- const color = effectModel.get('color') || lineData.getItemVisual(idx, 'color');
+
+ const lineStyle = lineData.getItemVisual(idx, 'style');
+ const color = effectModel.get('color') || (lineStyle && lineStyle.stroke);
let symbol = this.childAt(1) as ECSymbolOnEffectLine;
if (this._symbolType !== symbolType) {
@@ -89,7 +92,7 @@ class EffectLine extends graphic.Group {
}
// Shadow color is same with color in default
- symbol.setStyle('shadowColor', color);
+ symbol.setStyle('shadowColor', color as ColorString);
symbol.setStyle(effectModel.getItemStyle(['color']));
symbol.scaleX = size[0];
diff --git a/src/chart/helper/EffectSymbol.ts b/src/chart/helper/EffectSymbol.ts
index f6fb57c..c43a928 100644
--- a/src/chart/helper/EffectSymbol.ts
+++ b/src/chart/helper/EffectSymbol.ts
@@ -173,7 +173,9 @@ class EffectSymbol extends Group {
const itemModel = data.getItemModel<SymbolDrawItemModelOption>(idx);
const symbolType = data.getItemVisual(idx, 'symbol');
const symbolSize = normalizeSymbolSize(data.getItemVisual(idx, 'symbolSize'));
- const color = data.getItemVisual(idx, 'color');
+
+ const symbolStyle = data.getItemVisual(idx, 'style');
+ const color = symbolStyle && symbolStyle.fill;
rippleGroup.setScale(symbolSize);
diff --git a/src/chart/helper/LargeLineDraw.ts b/src/chart/helper/LargeLineDraw.ts
index 761a21f..6aabbb1 100644
--- a/src/chart/helper/LargeLineDraw.ts
+++ b/src/chart/helper/LargeLineDraw.ts
@@ -261,9 +261,9 @@ class LargeLineDraw {
);
lineEl.style.strokeNoScale = true;
- const visualColor = data.getVisual('color');
- if (visualColor) {
- lineEl.setStyle('stroke', visualColor);
+ const style = data.getVisual('style');
+ if (style && style.stroke) {
+ lineEl.setStyle('stroke', style.stroke);
}
lineEl.setStyle('fill', null);
diff --git a/src/chart/helper/LargeSymbolDraw.ts b/src/chart/helper/LargeSymbolDraw.ts
index ef30a1f..458788f 100644
--- a/src/chart/helper/LargeSymbolDraw.ts
+++ b/src/chart/helper/LargeSymbolDraw.ts
@@ -264,20 +264,9 @@ class LargeSymbolDraw {
const hostModel = data.hostModel;
opt = opt || {};
- // TODO
- // if (data.hasItemVisual.symbolSize) {
- // // TODO typed array?
- // symbolEl.setShape('sizes', data.mapArray(
- // function (idx) {
- // let size = data.getItemVisual(idx, 'symbolSize');
- // return (size instanceof Array) ? size : [size, size];
- // }
- // ));
- // }
- // else {
+
const size = data.getVisual('symbolSize');
symbolEl.setShape('size', (size instanceof Array) ? size : [size, size]);
- // }
symbolEl.softClipShape = opt.clipShape || null;
// Create symbolProxy to build path for each data
@@ -295,7 +284,8 @@ class LargeSymbolDraw {
)
);
- const visualColor = data.getVisual('color');
+ const globalStyle = data.getVisual('style');
+ const visualColor = globalStyle && globalStyle.fill;
if (visualColor) {
symbolEl.setColor(visualColor);
}
diff --git a/src/chart/helper/Line.ts b/src/chart/helper/Line.ts
index 1835716..47823aa 100644
--- a/src/chart/helper/Line.ts
+++ b/src/chart/helper/Line.ts
@@ -24,15 +24,19 @@ import ECLinePath from './LinePath';
import * as graphic from '../../util/graphic';
import {round} from '../../util/number';
import List from '../../data/List';
-import { ZRTextAlign, ZRTextVerticalAlign, LineLabelOption } from '../../util/types';
+import { ZRTextAlign, ZRTextVerticalAlign, LineLabelOption, ColorString } from '../../util/types';
import SeriesModel from '../../model/Series';
import type { LineDrawSeriesScope, LineDrawModelOption } from './LineDraw';
+
import { TextStyleProps } from 'zrender/src/graphic/Text';
+import { LineDataVisual } from '../../visual/commonVisualTypes';
const SYMBOL_CATEGORIES = ['fromSymbol', 'toSymbol'] as const;
type ECSymbol = ReturnType<typeof createSymbol>;
+type LineList = List<SeriesModel, LineDataVisual>;
+
export interface LineLabel extends graphic.Text {
lineLabelOriginalOpacity: number
}
@@ -44,28 +48,29 @@ interface InnerLineLabel extends LineLabel {
__labelDistance: number[]
}
-function makeSymbolTypeKey(symbolCategory: string) {
+function makeSymbolTypeKey(symbolCategory: 'fromSymbol' | 'toSymbol') {
return '_' + symbolCategory + 'Type' as '_fromSymbolType' | '_toSymbolType';
}
/**
* @inner
*/
-function createSymbol(name: string, lineData: List, idx: number) {
- const color = lineData.getItemVisual(idx, 'color');
+function createSymbol(name: 'fromSymbol' | 'toSymbol', lineData: LineList, idx: number) {
const symbolType = lineData.getItemVisual(idx, name);
- let symbolSize = lineData.getItemVisual(idx, name + 'Size');
+ const symbolSize = lineData.getItemVisual(
+ idx,
+ name + 'Size' as 'fromSymbolSize' | 'toSymbolSize'
+ );
if (!symbolType || symbolType === 'none') {
return;
}
- if (!zrUtil.isArray(symbolSize)) {
- symbolSize = [symbolSize, symbolSize];
- }
+ const symbolSizeArr = zrUtil.isArray(symbolSize)
+ ? symbolSize : [symbolSize, symbolSize];
const symbolPath = symbolUtil.createSymbol(
- symbolType, -symbolSize[0] / 2, -symbolSize[1] / 2,
- symbolSize[0], symbolSize[1], color
+ symbolType, -symbolSizeArr[0] / 2, -symbolSizeArr[1] / 2,
+ symbolSizeArr[0], symbolSizeArr[1]
);
symbolPath.name = name;
@@ -105,7 +110,6 @@ function setLinePoints(targetShape: ECLinePath['shape'], points: number[][]) {
}
}
-
class Line extends graphic.Group {
private _fromSymbolType: string;
@@ -113,10 +117,10 @@ class Line extends graphic.Group {
constructor(lineData: List, idx: number, seriesScope?: LineDrawSeriesScope) {
super();
- this._createLine(lineData, idx, seriesScope);
+ this._createLine(lineData as LineList, idx, seriesScope);
}
- _createLine(lineData: List, idx: number, seriesScope?: LineDrawSeriesScope) {
+ _createLine(lineData: LineList, idx: number, seriesScope?: LineDrawSeriesScope) {
const seriesModel = lineData.hostModel;
const linePoints = lineData.getItemLayout(idx);
const line = createLine(linePoints);
@@ -150,6 +154,7 @@ class Line extends graphic.Group {
this._updateCommonStl(lineData, idx, seriesScope);
}
+ // TODO More strict on the List type in parameters?
updateData(lineData: List, idx: number, seriesScope: LineDrawSeriesScope) {
const seriesModel = lineData.hostModel;
@@ -163,12 +168,12 @@ class Line extends graphic.Group {
graphic.updateProps(line, target, seriesModel, idx);
zrUtil.each(SYMBOL_CATEGORIES, function (symbolCategory) {
- const symbolType = lineData.getItemVisual(idx, symbolCategory);
+ const symbolType = (lineData as LineList).getItemVisual(idx, symbolCategory);
const key = makeSymbolTypeKey(symbolCategory);
// Symbol changed
if (this[key] !== symbolType) {
this.remove(this.childOfName(symbolCategory));
- const symbol = createSymbol(symbolCategory, lineData, idx);
+ const symbol = createSymbol(symbolCategory, lineData as LineList, idx);
this.add(symbol);
}
this[key] = symbolType;
@@ -182,7 +187,6 @@ class Line extends graphic.Group {
const line = this.childOfName('line') as ECLinePath;
- let lineStyle = seriesScope && seriesScope.lineStyle;
let hoverLineStyle = seriesScope && seriesScope.hoverLineStyle;
let labelModel = seriesScope && seriesScope.labelModel;
let hoverLabelModel = seriesScope && seriesScope.hoverLabelModel;
@@ -191,29 +195,18 @@ class Line extends graphic.Group {
if (!seriesScope || lineData.hasItemOption) {
const itemModel = lineData.getItemModel<LineDrawModelOption>(idx);
- lineStyle = itemModel.getModel('lineStyle').getLineStyle();
hoverLineStyle = itemModel.getModel(['emphasis', 'lineStyle']).getLineStyle();
labelModel = itemModel.getModel('label');
hoverLabelModel = itemModel.getModel(['emphasis', 'label']);
}
- const visualColor = lineData.getItemVisual(idx, 'color');
- const visualOpacity = zrUtil.retrieve3(
- lineData.getItemVisual(idx, 'opacity'),
- lineStyle.opacity,
- 1
- );
-
- line.useStyle(zrUtil.defaults(
- {
- strokeNoScale: true,
- fill: 'none',
- stroke: visualColor,
- opacity: visualOpacity
- },
- lineStyle
- ));
+ const lineStyle = lineData.getItemVisual(idx, 'style');
+ const visualColor = lineStyle.stroke;
+
+ line.useStyle(lineStyle);
+ line.style.strokeNoScale = true;
+
const lineEmphasisState = line.ensureState('emphasis');
lineEmphasisState.style = hoverLineStyle;
@@ -222,9 +215,8 @@ class Line extends graphic.Group {
const symbol = this.childOfName(symbolCategory) as ECSymbol;
if (symbol) {
symbol.setColor(visualColor);
- symbol.setStyle({
- opacity: visualOpacity
- });
+ symbol.style.opacity = lineStyle.opacity;
+ symbol.markRedraw();
}
}, this);
@@ -237,7 +229,7 @@ class Line extends graphic.Group {
// FIXME: the logic below probably should be merged to `graphic.setLabelStyle`.
if (showLabel || hoverShowLabel) {
- defaultLabelColor = visualColor || '#000';
+ defaultLabelColor = visualColor as ColorString || '#000';
baseText = seriesModel.getFormattedLabel(idx, 'normal', lineData.dataType);
if (baseText == null) {
diff --git a/src/chart/helper/LineDraw.ts b/src/chart/helper/LineDraw.ts
index 18e6857..0acf339 100644
--- a/src/chart/helper/LineDraw.ts
+++ b/src/chart/helper/LineDraw.ts
@@ -77,7 +77,6 @@ export interface LineDrawModelOption {
type ListForLineDraw = List<Model<LineDrawModelOption & AnimationOptionMixin>>;
export interface LineDrawSeriesScope {
- lineStyle?: ZRStyleProps
hoverLineStyle?: ZRStyleProps
labelModel?: Model<LineLabelOption>
@@ -205,6 +204,7 @@ class LineDraw {
itemEl = new this._LineCtor(newLineData, newIdx, seriesScope);
}
else {
+ graphic.clearStates(itemEl);
itemEl.updateData(newLineData, newIdx, seriesScope);
}
diff --git a/src/chart/helper/Polyline.ts b/src/chart/helper/Polyline.ts
index 49df307..0e8df66 100644
--- a/src/chart/helper/Polyline.ts
+++ b/src/chart/helper/Polyline.ts
@@ -18,7 +18,6 @@
*/
import * as graphic from '../../util/graphic';
-import * as zrUtil from 'zrender/src/core/util';
import type { LineDrawSeriesScope, LineDrawModelOption } from './LineDraw';
import type List from '../../data/List';
@@ -61,23 +60,14 @@ class Polyline extends graphic.Group {
const line = this.childAt(0) as graphic.Polyline;
const itemModel = lineData.getItemModel<LineDrawModelOption>(idx);
- const visualColor = lineData.getItemVisual(idx, 'color');
- let lineStyle = seriesScope && seriesScope.lineStyle;
let hoverLineStyle = seriesScope && seriesScope.hoverLineStyle;
if (!seriesScope || lineData.hasItemOption) {
- lineStyle = itemModel.getModel('lineStyle').getLineStyle();
hoverLineStyle = itemModel.getModel(['emphasis', 'lineStyle']).getLineStyle();
}
- line.useStyle(zrUtil.defaults(
- {
- strokeNoScale: true,
- fill: 'none',
- stroke: visualColor
- },
- lineStyle
- ));
+ line.useStyle(lineData.getItemVisual(idx, 'style'));
+ line.style.strokeNoScale = true;
const lineEmphasisState = line.ensureState('emphasis');
lineEmphasisState.style = hoverLineStyle;
diff --git a/src/chart/helper/Symbol.ts b/src/chart/helper/Symbol.ts
index a4c46df..33eab5d 100644
--- a/src/chart/helper/Symbol.ts
+++ b/src/chart/helper/Symbol.ts
@@ -17,25 +17,24 @@
* under the License.
*/
-import * as zrUtil from 'zrender/src/core/util';
import {createSymbol} from '../../util/symbol';
import * as graphic from '../../util/graphic';
import {parsePercent} from '../../util/number';
import {getDefaultLabel} from './labelHelper';
import List from '../../data/List';
-import { DisplayState } from '../../util/types';
+import { DisplayState, ColorString } from '../../util/types';
import SeriesModel from '../../model/Series';
import { PathProps } from 'zrender/src/graphic/Path';
import { SymbolDrawSeriesScope, SymbolDrawItemModelOption } from './SymbolDraw';
+import { extend } from 'zrender/src/core/util';
// Update common properties
-const normalStyleAccessPath = ['itemStyle'] as const;
const emphasisStyleAccessPath = ['emphasis', 'itemStyle'] as const;
const normalLabelAccessPath = ['label'] as const;
const emphasisLabelAccessPath = ['emphasis', 'label'] as const;
type ECSymbol = ReturnType<typeof createSymbol> & {
- highDownOnUpdate(fromState: DisplayState, toState: DisplayState): void
+ onStateChange(fromState: DisplayState, toState: DisplayState): void
};
class Symbol extends graphic.Group {
@@ -67,8 +66,6 @@ class Symbol extends graphic.Group {
// Remove paths created before
this.removeAll();
- const color = data.getItemVisual(idx, 'color');
-
// let symbolPath = createSymbol(
// symbolType, -0.5, -0.5, 1, 1, color
// );
@@ -76,7 +73,7 @@ class Symbol extends graphic.Group {
// and macOS Sierra, a circle stroke become a rect, no matter what
// the scale is set. So we set width/height as 2. See #4150.
const symbolPath = createSymbol(
- symbolType, -1, -1, 2, 2, color, keepAspect
+ symbolType, -1, -1, 2, 2, null, keepAspect
);
symbolPath.attr({
@@ -170,7 +167,7 @@ class Symbol extends graphic.Group {
if (isInit) {
const keepAspect = data.getItemVisual(idx, 'symbolKeepAspect');
- this._createSymbol(symbolType, data, idx, symbolSize, keepAspect);
+ this._createSymbol(symbolType as string, data, idx, symbolSize, keepAspect);
}
else {
const symbolPath = this.childAt(0) as ECSymbol;
@@ -185,11 +182,13 @@ class Symbol extends graphic.Group {
if (isInit) {
const symbolPath = this.childAt(0) as ECSymbol;
- const fadeIn = seriesScope && seriesScope.fadeIn;
+ // Always fadeIn. Because it has fadeOut animation when symbol is removed..
+ // const fadeIn = seriesScope && seriesScope.fadeIn;
+ const fadeIn = true;
const target: PathProps = {
- scaleX: symbolPath.scaleX,
- scaleY: symbolPath.scaleY
+ scaleX: this._scaleX,
+ scaleY: this._scaleY
};
fadeIn && (target.style = {
opacity: symbolPath.style.opacity
@@ -212,25 +211,7 @@ class Symbol extends graphic.Group {
) {
const symbolPath = this.childAt(0) as ECSymbol;
const seriesModel = data.hostModel as SeriesModel;
- const color = data.getItemVisual(idx, 'color');
-
- // Reset style
- if (symbolPath.type !== 'image') {
- symbolPath.useStyle({
- strokeNoScale: true
- });
- }
- else {
- symbolPath.setStyle({
- opacity: null,
- shadowBlur: null,
- shadowOffsetX: null,
- shadowOffsetY: null,
- shadowColor: null
- });
- }
- let itemStyle = seriesScope && seriesScope.itemStyle;
let hoverItemStyle = seriesScope && seriesScope.hoverItemStyle;
let symbolRotate = seriesScope && seriesScope.symbolRotate;
let symbolOffset = seriesScope && seriesScope.symbolOffset;
@@ -243,9 +224,6 @@ class Symbol extends graphic.Group {
const itemModel = (seriesScope && seriesScope.itemModel)
? seriesScope.itemModel : data.getItemModel<SymbolDrawItemModelOption>(idx);
- // Color must be excluded.
- // Because symbol provide setColor individually to set fill and stroke
- itemStyle = itemModel.getModel(normalStyleAccessPath).getItemStyle(['color']);
hoverItemStyle = itemModel.getModel(emphasisStyleAccessPath).getItemStyle();
symbolRotate = itemModel.getShallow('symbolRotate');
@@ -256,11 +234,6 @@ class Symbol extends graphic.Group {
hoverAnimation = itemModel.getShallow('hoverAnimation');
cursorStyle = itemModel.getShallow('cursor');
}
- else {
- hoverItemStyle = zrUtil.extend({}, hoverItemStyle);
- }
-
- const elStyle = symbolPath.style;
symbolPath.attr('rotation', (symbolRotate || 0) * Math.PI / 180 || 0);
@@ -272,14 +245,19 @@ class Symbol extends graphic.Group {
cursorStyle && symbolPath.attr('cursor', cursorStyle);
// PENDING setColor before setStyle!!!
- symbolPath.setColor(color, seriesScope && seriesScope.symbolInnerColor);
-
- symbolPath.setStyle(itemStyle);
-
- const opacity = data.getItemVisual(idx, 'opacity');
- if (opacity != null) {
- elStyle.opacity = opacity;
+ const symbolStyle = data.getItemVisual(idx, 'style');
+ const visualColor = symbolStyle.fill;
+ if (symbolPath.__isEmptyBrush) {
+ // fill and stroke will be swapped if it's empty.
+ // So we cloned a new style to avoid it affecting the original style in visual storage.
+ // TODO Better implementation. No empty logic!
+ symbolPath.useStyle(extend({}, symbolStyle));
+ }
+ else {
+ symbolPath.useStyle(symbolStyle);
}
+ symbolPath.setColor(visualColor, seriesScope && seriesScope.symbolInnerColor);
+ symbolPath.style.strokeNoScale = true;
const liftZ = data.getItemVisual(idx, 'liftZ');
const z2Origin = this._z2;
@@ -302,7 +280,7 @@ class Symbol extends graphic.Group {
labelFetcher: seriesModel,
labelDataIndex: idx,
defaultText: getLabelDefaultText,
- autoColor: color
+ autoColor: visualColor as ColorString
}
);
@@ -313,9 +291,9 @@ class Symbol extends graphic.Group {
this._scaleX = symbolSize[0] / 2;
this._scaleY = symbolSize[1] / 2;
- symbolPath.highDownOnUpdate = (
+ symbolPath.onStateChange = (
hoverAnimation && seriesModel.isAnimationEnabled()
- ) ? highDownOnUpdate : null;
+ ) ? onStateChange : null;
graphic.enableHoverEmphasis(symbolPath, hoverItemStyle);
}
@@ -352,7 +330,7 @@ class Symbol extends graphic.Group {
}
}
-function highDownOnUpdate(this: ECSymbol, fromState: DisplayState, toState: DisplayState) {
+function onStateChange(this: ECSymbol, fromState: DisplayState, toState: DisplayState) {
// Do not support this hover animation util some scenario required.
// Animation can only be supported in hover layer when using `el.incremetal`.
if (this.incremental || this.useHoverLayer) {
diff --git a/src/chart/helper/SymbolDraw.ts b/src/chart/helper/SymbolDraw.ts
index 7eea47e..938a4d8 100644
--- a/src/chart/helper/SymbolDraw.ts
+++ b/src/chart/helper/SymbolDraw.ts
@@ -94,7 +94,6 @@ export interface SymbolDrawItemModelOption extends SymbolOptionMixin<object> {
}
export interface SymbolDrawSeriesScope {
- itemStyle?: ZRStyleProps
hoverItemStyle?: ZRStyleProps
symbolRotate?: number
symbolOffset?: number[]
@@ -111,7 +110,6 @@ export interface SymbolDrawSeriesScope {
function makeSeriesScope(data: List): SymbolDrawSeriesScope {
const seriesModel = data.hostModel;
return {
- itemStyle: seriesModel.getModel('itemStyle').getItemStyle(['color']),
hoverItemStyle: seriesModel.getModel(['emphasis', 'itemStyle']).getItemStyle(),
symbolRotate: seriesModel.get('symbolRotate'),
symbolOffset: seriesModel.get('symbolOffset'),
@@ -168,6 +166,7 @@ class SymbolDraw {
})
.update(function (newIdx, oldIdx) {
let symbolEl = oldData.getItemGraphicEl(oldIdx) as SymbolLike;
+
const point = data.getItemLayout(newIdx) as number[];
if (!symbolNeedsDraw(data, point, newIdx, opt)) {
group.remove(symbolEl);
@@ -178,6 +177,8 @@ class SymbolDraw {
symbolEl.setPosition(point);
}
else {
+ graphic.clearStates(symbolEl);
+
symbolEl.updateData(data, newIdx, seriesScope);
graphic.updateProps(symbolEl, {
x: point[0],
diff --git a/src/chart/line.ts b/src/chart/line.ts
index c0c1e6d..541b481 100644
--- a/src/chart/line.ts
+++ b/src/chart/line.ts
@@ -21,14 +21,13 @@ import * as echarts from '../echarts';
import './line/LineSeries';
import './line/LineView';
-import visualSymbol from '../visual/symbol';
+
import layoutPoints from '../layout/points';
import dataSample from '../processor/dataSample';
// In case developer forget to include grid component
import '../component/gridSimple';
-echarts.registerVisual(visualSymbol('line', 'circle', 'line'));
echarts.registerLayout(layoutPoints('line'));
// Down sample after filter
diff --git a/src/chart/line/LineSeries.ts b/src/chart/line/LineSeries.ts
index c53aa8c..1fcb748 100644
--- a/src/chart/line/LineSeries.ts
+++ b/src/chart/line/LineSeries.ts
@@ -103,6 +103,9 @@ class LineSeriesModel extends SeriesModel<LineSeriesOption> {
coordinateSystem: Cartesian2D | Polar;
+ hasSymbolVisual = true;
+ legendSymbol = 'line';
+
getInitialData(option: LineSeriesOption): List {
if (__DEV__) {
const coordSys = option.coordinateSystem;
diff --git a/src/chart/line/LineView.ts b/src/chart/line/LineView.ts
index c829293..80a2f3f 100644
--- a/src/chart/line/LineView.ts
+++ b/src/chart/line/LineView.ts
@@ -37,7 +37,6 @@ import type ExtensionAPI from '../../ExtensionAPI';
import Cartesian2D from '../../coord/cartesian/Cartesian2D';
import Polar from '../../coord/polar/Polar';
import type List from '../../data/List';
-import type { VisualMeta } from '../../component/visualMap/VisualMapModel';
import type { Payload, Dictionary, ColorString } from '../../util/types';
import type OrdinalScale from '../../scale/Ordinal';
import type Axis2D from '../../coord/cartesian/Axis2D';
@@ -135,7 +134,7 @@ function getVisualGradient(
data: List,
coordSys: Cartesian2D | Polar
) {
- const visualMetaList = data.getVisual('visualMeta') as VisualMeta[];
+ const visualMetaList = data.getVisual('visualMeta');
if (!visualMetaList || !visualMetaList.length || !data.count()) {
// When data.count() is 0, gradient range can not be calculated.
return;
@@ -513,7 +512,8 @@ class LineView extends ChartView {
}
}
- const visualColor = getVisualGradient(data, coordSys) || data.getVisual('color');
+ const visualColor = getVisualGradient(data, coordSys)
+ || data.getVisual('style')[data.getVisual('brushType')];
polyline.useStyle(zrUtil.defaults(
// Use color in lineStyle first
diff --git a/src/chart/lines/LinesSeries.ts b/src/chart/lines/LinesSeries.ts
index 7618169..41d514a 100644
--- a/src/chart/lines/LinesSeries.ts
+++ b/src/chart/lines/LinesSeries.ts
@@ -149,7 +149,8 @@ class LinesSeriesModel extends SeriesModel<LinesSeriesOption> {
static readonly dependencies = ['grid', 'polar', 'geo', 'calendar'];
- visualColorAccessPath = ['lineStyle', 'color'];
+ visualStyleAccessPath = 'lineStyle';
+ visualColorBrushType = 'stroke' as const;
private _flatCoords: ArrayLike<number>;
private _flatCoordsOffset: ArrayLike<number>;
diff --git a/src/chart/lines/linesVisual.ts b/src/chart/lines/linesVisual.ts
index 0f37f93..1e4c931 100644
--- a/src/chart/lines/linesVisual.ts
+++ b/src/chart/lines/linesVisual.ts
@@ -21,6 +21,7 @@ import { StageHandler } from '../../util/types';
import List from '../../data/List';
import LinesSeriesModel, { LinesDataItemOption } from './LinesSeries';
import Model from '../../model/Model';
+import { LineDataVisual } from '../../visual/commonVisualTypes';
function normalize(a: string | string[]): string[];
function normalize(a: number | number[]): number[];
@@ -31,33 +32,30 @@ function normalize(a: string | number | (string | number)[]): (string | number)[
return a;
}
-const opacityQuery = ['lineStyle', 'opacity'] as const;
-
const linesVisual: StageHandler = {
seriesType: 'lines',
reset(seriesModel: LinesSeriesModel) {
const symbolType = normalize(seriesModel.get('symbol'));
const symbolSize = normalize(seriesModel.get('symbolSize'));
- const data = seriesModel.getData();
+ const data = seriesModel.getData() as List<LinesSeriesModel, LineDataVisual>;
data.setVisual('fromSymbol', symbolType && symbolType[0]);
data.setVisual('toSymbol', symbolType && symbolType[1]);
data.setVisual('fromSymbolSize', symbolSize && symbolSize[0]);
data.setVisual('toSymbolSize', symbolSize && symbolSize[1]);
- data.setVisual('opacity', seriesModel.get(opacityQuery));
- function dataEach(data: List<LinesSeriesModel>, idx: number): void {
+ function dataEach(
+ data: List<LinesSeriesModel, LineDataVisual>,
+ idx: number
+ ): void {
const itemModel = data.getItemModel(idx) as Model<LinesDataItemOption>;
const symbolType = normalize(itemModel.getShallow('symbol', true));
const symbolSize = normalize(itemModel.getShallow('symbolSize', true));
- const opacity = itemModel.get(opacityQuery);
symbolType[0] && data.setItemVisual(idx, 'fromSymbol', symbolType[0]);
symbolType[1] && data.setItemVisual(idx, 'toSymbol', symbolType[1]);
symbolSize[0] && data.setItemVisual(idx, 'fromSymbolSize', symbolSize[0]);
symbolSize[1] && data.setItemVisual(idx, 'toSymbolSize', symbolSize[1]);
-
- data.setItemVisual(idx, 'opacity', opacity);
}
return {
diff --git a/src/chart/map.ts b/src/chart/map.ts
index 6e22e8b..b53e5d5 100644
--- a/src/chart/map.ts
+++ b/src/chart/map.ts
@@ -25,13 +25,11 @@ import '../action/geoRoam';
import '../coord/geo/geoCreator';
import mapSymbolLayout from './map/mapSymbolLayout';
-import mapVisual from './map/mapVisual';
import mapDataStatistic from './map/mapDataStatistic';
import backwardCompat from './map/backwardCompat';
import createDataSelectAction from '../action/createDataSelectAction';
echarts.registerLayout(mapSymbolLayout);
-echarts.registerVisual(mapVisual);
echarts.registerProcessor(echarts.PRIORITY.PROCESSOR.STATISTIC, mapDataStatistic);
echarts.registerPreprocessor(backwardCompat);
diff --git a/src/chart/map/MapView.ts b/src/chart/map/MapView.ts
index 87ded60..6e0bd06 100644
--- a/src/chart/map/MapView.ts
+++ b/src/chart/map/MapView.ts
@@ -142,7 +142,8 @@ class MapView extends ChartView {
// And each series also need a symbol with legend color
//
// Layout and visual are put one the different data
- fill: mapModel.getData().getVisual('color')
+ // TODO
+ fill: mapModel.getData().getVisual('style').fill
},
shape: {
cx: point[0] + offset * 9,
diff --git a/src/chart/parallel/ParallelSeries.ts b/src/chart/parallel/ParallelSeries.ts
index 879d22f..6b9dbfc 100644
--- a/src/chart/parallel/ParallelSeries.ts
+++ b/src/chart/parallel/ParallelSeries.ts
@@ -85,7 +85,8 @@ class ParallelSeriesModel extends SeriesModel<ParallelSeriesOption> {
static dependencies = ['parallel'];
- visualColorAccessPath = ['lineStyle', 'color'];
+ visualStyleAccessPath = 'lineStyle';
+ visualColorBrushType = 'stroke' as const;
coordinateSystem: Parallel;
diff --git a/src/chart/parallel/ParallelView.ts b/src/chart/parallel/ParallelView.ts
index d5e2873..9569dd3 100644
--- a/src/chart/parallel/ParallelView.ts
+++ b/src/chart/parallel/ParallelView.ts
@@ -20,19 +20,17 @@
import * as graphic from '../../util/graphic';
import ChartView from '../../view/Chart';
import List from '../../data/List';
-import ParallelSeriesModel, { ParallelSeriesDataItemOption } from './ParallelSeries';
+import ParallelSeriesModel from './ParallelSeries';
import GlobalModel from '../../model/Global';
import ExtensionAPI from '../../ExtensionAPI';
import { StageHandlerProgressParams, ParsedValue, Payload } from '../../util/types';
import Parallel from '../../coord/parallel/Parallel';
import { OptionAxisType } from '../../coord/axisCommonTypes';
-import { PathStyleProps } from 'zrender/src/graphic/Path';
const DEFAULT_SMOOTH = 0.3;
interface ParallelDrawSeriesScope {
smooth: number
- lineStyle: PathStyleProps
}
class ParallelView extends ChartView {
static type = 'parallel';
@@ -79,6 +77,8 @@ class ParallelView extends ChartView {
function update(newDataIndex: number, oldDataIndex: number) {
const line = oldData.getItemGraphicEl(oldDataIndex) as graphic.Polyline;
+ graphic.clearStates(line);
+
const points = createLinePoints(data, newDataIndex, dimensions, coordSys);
data.setItemGraphicEl(newDataIndex, line);
const animationModel = (payload && payload.animation === false) ? null : seriesModel;
@@ -189,7 +189,6 @@ function makeSeriesScope(seriesModel: ParallelSeriesModel): ParallelDrawSeriesSc
smooth === true && (smooth = DEFAULT_SMOOTH);
return {
- lineStyle: seriesModel.getModel('lineStyle').getLineStyle(),
smooth: smooth != null ? +smooth : DEFAULT_SMOOTH
};
}
@@ -200,23 +199,7 @@ function updateElCommon(
dataIndex: number,
seriesScope: ParallelDrawSeriesScope
) {
- let lineStyle = seriesScope.lineStyle;
-
- if (data.hasItemOption) {
- const lineStyleModel = data.getItemModel<ParallelSeriesDataItemOption>(dataIndex)
- .getModel('lineStyle');
- lineStyle = lineStyleModel.getLineStyle();
- }
-
- el.useStyle(lineStyle);
-
- const elStyle = el.style;
- elStyle.fill = null;
- // lineStyle.color have been set to itemVisual in module:echarts/visual/seriesColor.
- elStyle.stroke = data.getItemVisual(dataIndex, 'color');
- // lineStyle.opacity have been set to itemVisual in parallelVisual.
- elStyle.opacity = data.getItemVisual(dataIndex, 'opacity');
-
+ el.useStyle(data.getItemVisual(dataIndex, 'style'));
seriesScope.smooth && (el.shape.smooth = seriesScope.smooth);
}
diff --git a/src/chart/parallel/parallelVisual.ts b/src/chart/parallel/parallelVisual.ts
index 4aa88a6..e50b82e 100644
--- a/src/chart/parallel/parallelVisual.ts
+++ b/src/chart/parallel/parallelVisual.ts
@@ -30,28 +30,14 @@ const parallelVisual: StageHandler = {
reset: function (seriesModel: ParallelSeriesModel, ecModel) {
- // let itemStyleModel = seriesModel.getModel('itemStyle');
- const lineStyleModel = seriesModel.getModel('lineStyle');
- const globalColors = ecModel.get('color');
-
- const color = lineStyleModel.get('color')
- // || itemStyleModel.get('color')
- || globalColors[seriesModel.seriesIndex % globalColors.length];
- const inactiveOpacity = seriesModel.get('inactiveOpacity');
- const activeOpacity = seriesModel.get('activeOpacity');
- const lineStyle = seriesModel.getModel('lineStyle').getLineStyle();
-
const coordSys = seriesModel.coordinateSystem;
- const data = seriesModel.getData();
const opacityMap = {
- normal: lineStyle.opacity,
- active: activeOpacity,
- inactive: inactiveOpacity
+ normal: seriesModel.get(['lineStyle', 'opacity']),
+ active: seriesModel.get('activeOpacity'),
+ inactive: seriesModel.get('inactiveOpacity')
};
- data.setVisual('color', color);
-
return {
progress(params, data) {
coordSys.eachActiveState(data, function (activeState, dataIndex) {
@@ -62,7 +48,8 @@ const parallelVisual: StageHandler = {
);
itemOpacity != null && (opacity = itemOpacity);
}
- data.setItemVisual(dataIndex, 'opacity', opacity);
+ const existsStyle = data.ensureUniqueItemVisual(dataIndex, 'style');
+ existsStyle.opacity = opacity;
}, params.start, params.end);
}
};
diff --git a/src/chart/pictorialBar.ts b/src/chart/pictorialBar.ts
index 975e4d9..65e494c 100644
--- a/src/chart/pictorialBar.ts
+++ b/src/chart/pictorialBar.ts
@@ -25,7 +25,6 @@ import './bar/PictorialBarSeries';
import './bar/PictorialBarView';
import { layout } from '../layout/barGrid';
-import visualSymbol from '../visual/symbol';
// In case developer forget to include grid component
import '../component/gridSimple';
@@ -33,4 +32,3 @@ import '../component/gridSimple';
echarts.registerLayout(zrUtil.curry(
layout, 'pictorialBar'
));
-echarts.registerVisual(visualSymbol('pictorialBar', 'roundRect'));
diff --git a/src/chart/pie.ts b/src/chart/pie.ts
index 4f8630b..b568a99 100644
--- a/src/chart/pie.ts
+++ b/src/chart/pie.ts
@@ -24,7 +24,6 @@ import './pie/PieSeries';
import './pie/PieView';
import createDataSelectAction from '../action/createDataSelectAction';
-import dataColor from '../visual/dataColor';
import pieLayout from './pie/pieLayout';
import dataFilter from '../processor/dataFilter';
@@ -44,6 +43,5 @@ createDataSelectAction('pie', [{
// type PieLayoutParameters = Parameters<typeof pieLayout>;
-echarts.registerVisual(dataColor('pie'));
echarts.registerLayout(zrUtil.curry(pieLayout, 'pie'));
echarts.registerProcessor(dataFilter('pie'));
\ No newline at end of file
diff --git a/src/chart/pie/PieSeries.ts b/src/chart/pie/PieSeries.ts
index bae1cdd..f1bc70d 100644
--- a/src/chart/pie/PieSeries.ts
+++ b/src/chart/pie/PieSeries.ts
@@ -112,6 +112,8 @@ class PieSeriesModel extends SeriesModel<PieSeriesOption> {
static type = 'series.pie' as const;
+ useColorPaletteOnData = true;
+
/**
* @overwrite
*/
diff --git a/src/chart/pie/PieView.ts b/src/chart/pie/PieView.ts
index 3e02c4f..020e624 100644
--- a/src/chart/pie/PieView.ts
+++ b/src/chart/pie/PieView.ts
@@ -24,7 +24,7 @@ import * as graphic from '../../util/graphic';
import ChartView from '../../view/Chart';
import GlobalModel from '../../model/Global';
import ExtensionAPI from '../../ExtensionAPI';
-import { Payload, DisplayState, ECElement } from '../../util/types';
+import { Payload, DisplayState, ECElement, ColorString } from '../../util/types';
import List from '../../data/List';
import PieSeriesModel, {PieDataItemOption} from './PieSeries';
import { Dictionary } from 'zrender/src/core/types';
@@ -157,18 +157,7 @@ class PiePiece extends graphic.Group {
}
}
- // Update common style
- const visualColor = data.getItemVisual(idx, 'color');
-
- sector.useStyle(
- zrUtil.defaults(
- {
- lineJoin: 'bevel',
- fill: visualColor
- },
- itemModel.getModel('itemStyle').getItemStyle()
- )
- );
+ sector.useStyle(data.getItemVisual(idx, 'style'));
const sectorEmphasisState = sector.ensureState('emphasis');
sectorEmphasisState.style = itemModel.getModel(['emphasis', 'itemStyle']).getItemStyle();
@@ -188,7 +177,7 @@ class PiePiece extends graphic.Group {
const withAnimation = !firstCreate && animationTypeUpdate === 'transition';
this._updateLabel(data, idx, withAnimation);
- (this as ECElement).highDownOnUpdate = (itemModel.get('hoverAnimation') && seriesModel.isAnimationEnabled())
+ (this as ECElement).onStateChange = (itemModel.get('hoverAnimation') && seriesModel.isAnimationEnabled())
? function (fromState: DisplayState, toState: DisplayState): void {
if (toState === 'emphasis') {
@@ -246,7 +235,9 @@ class PiePiece extends graphic.Group {
const labelHoverModel = itemModel.getModel(['emphasis', 'label']);
const labelLineModel = itemModel.getModel('labelLine');
const labelLineHoverModel = itemModel.getModel(['emphasis', 'labelLine']);
- const visualColor = data.getItemVisual(idx, 'color');
+
+ const style = data.getItemVisual(idx, 'style');
+ const visualColor = style && style.fill as ColorString;
graphic.setLabelStyle(
labelText,
@@ -260,7 +251,7 @@ class PiePiece extends graphic.Group {
{
align: labelLayout.textAlign,
verticalAlign: labelLayout.verticalAlign,
- opacity: data.getItemVisual(idx, 'opacity')
+ opacity: style && style.opacity
}
);
@@ -313,7 +304,7 @@ class PiePiece extends graphic.Group {
// Default use item visual color
labelLine.setStyle({
stroke: visualColor,
- opacity: data.getItemVisual(idx, 'opacity')
+ opacity: style && style.opacity
});
labelLine.setStyle(labelLineModel.getModel('lineStyle').getLineStyle());
@@ -382,6 +373,8 @@ class PieView extends ChartView {
.update(function (newIdx, oldIdx) {
const piePiece = oldData.getItemGraphicEl(oldIdx) as PiePiece;
+ graphic.clearStates(piePiece);
+
if (!isFirstRender && animationTypeUpdate !== 'transition') {
piePiece.eachChild(function (child) {
child.stopAnimation(true);
diff --git a/src/chart/radar.ts b/src/chart/radar.ts
index 0ed87f7..282537f 100644
--- a/src/chart/radar.ts
+++ b/src/chart/radar.ts
@@ -24,14 +24,10 @@ import '../component/radar';
import './radar/RadarSeries';
import './radar/RadarView';
-import dataColor from '../visual/dataColor';
-import visualSymbol from '../visual/symbol';
import radarLayout from './radar/radarLayout';
import dataFilter from '../processor/dataFilter';
import backwardCompat from './radar/backwardCompat';
-echarts.registerVisual(dataColor('radar'));
-echarts.registerVisual(visualSymbol('radar', 'circle'));
echarts.registerLayout(radarLayout);
echarts.registerProcessor(dataFilter('radar'));
echarts.registerPreprocessor(backwardCompat);
\ No newline at end of file
diff --git a/src/chart/radar/RadarSeries.ts b/src/chart/radar/RadarSeries.ts
index 0403b8d..05c8dd1 100644
--- a/src/chart/radar/RadarSeries.ts
+++ b/src/chart/radar/RadarSeries.ts
@@ -82,6 +82,10 @@ class RadarSeriesModel extends SeriesModel<RadarSeriesOption> {
coordinateSystem: Radar;
+ useColorPaletteOnData = true;
+
+ hasSymbolVisual = true;
+
// Overwrite
init(option: RadarSeriesOption) {
super.init.apply(this, arguments as any);
diff --git a/src/chart/radar/RadarView.ts b/src/chart/radar/RadarView.ts
index b96deb0..98698b6 100644
--- a/src/chart/radar/RadarView.ts
+++ b/src/chart/radar/RadarView.ts
@@ -24,7 +24,7 @@ import ChartView from '../../view/Chart';
import RadarSeriesModel, { RadarSeriesDataItemOption } from './RadarSeries';
import ExtensionAPI from '../../ExtensionAPI';
import List from '../../data/List';
-import { ZRColor, DisplayState, ECElement } from '../../util/types';
+import { DisplayState, ECElement, ColorString } from '../../util/types';
import GlobalModel from '../../model/Global';
import { VectorArray } from 'zrender/src/core/vector';
@@ -54,7 +54,6 @@ class RadarView extends ChartView {
function createSymbol(data: List<RadarSeriesModel>, idx: number) {
const symbolType = data.getItemVisual(idx, 'symbol') as string || 'circle';
- const color = data.getItemVisual(idx, 'color') as ZRColor;
if (symbolType === 'none') {
return;
}
@@ -62,7 +61,7 @@ class RadarView extends ChartView {
data.getItemVisual(idx, 'symbolSize')
);
const symbolPath = symbolUtil.createSymbol(
- symbolType, -1, -1, 2, 2, color
+ symbolType, -1, -1, 2, 2
);
symbolPath.attr({
style: {
@@ -144,6 +143,9 @@ class RadarView extends ChartView {
})
.update(function (newIdx, oldIdx) {
const itemGroup = oldData.getItemGraphicEl(oldIdx) as graphic.Group;
+
+ graphic.clearStates(itemGroup);
+
const polyline = itemGroup.childAt(0) as graphic.Polyline;
const polygon = itemGroup.childAt(1) as graphic.Polygon;
const symbolGroup = itemGroup.childAt(2) as graphic.Group;
@@ -180,7 +182,9 @@ class RadarView extends ChartView {
const polyline = itemGroup.childAt(0) as graphic.Polyline;
const polygon = itemGroup.childAt(1) as graphic.Polygon;
const symbolGroup = itemGroup.childAt(2) as graphic.Group;
- const color = data.getItemVisual(idx, 'color');
+ // Radar uses the visual encoded from itemStyle.
+ const itemStyle = data.getItemVisual(idx, 'style');
+ const color = itemStyle.fill;
group.add(itemGroup);
@@ -216,12 +220,13 @@ class RadarView extends ChartView {
const polygonEmphasisState = polygon.ensureState('emphasis');
polygonEmphasisState.style = hoverAreaStyleModel.getAreaStyle();
- const itemStyle = itemModel.getModel('itemStyle').getItemStyle(['color']);
const itemHoverStyle = itemModel.getModel(['emphasis', 'itemStyle']).getItemStyle();
const labelModel = itemModel.getModel('label');
const labelHoverModel = itemModel.getModel(['emphasis', 'label']);
symbolGroup.eachChild(function (symbolPath: RadarSymbol) {
- symbolPath.setStyle(itemStyle);
+ symbolPath.useStyle(itemStyle);
+ symbolPath.setColor(color);
+
const pathEmphasisState = symbolPath.ensureState('emphasis');
pathEmphasisState.style = zrUtil.clone(itemHoverStyle);
let defaultText = data.get(data.dimensions[symbolPath.__dimIdx], idx);
@@ -234,12 +239,12 @@ class RadarView extends ChartView {
labelDataIndex: idx,
labelDimIndex: symbolPath.__dimIdx,
defaultText: defaultText as string,
- autoColor: color
+ autoColor: color as ColorString
}
);
});
- (itemGroup as ECElement).highDownOnUpdate = function (fromState: DisplayState, toState: DisplayState) {
+ (itemGroup as ECElement).onStateChange = function (fromState: DisplayState, toState: DisplayState) {
polygon.attr('ignore', toState === 'emphasis' ? hoverPolygonIgnore : polygonIgnore);
};
graphic.enableHoverEmphasis(itemGroup);
diff --git a/src/chart/scatter.ts b/src/chart/scatter.ts
index 896a43a..91d5721 100644
--- a/src/chart/scatter.ts
+++ b/src/chart/scatter.ts
@@ -18,16 +18,13 @@
*/
import * as echarts from '../echarts';
-// import * as zrUtil from 'zrender/src/core/util';
import './scatter/ScatterSeries';
import './scatter/ScatterView';
-import visualSymbol from '../visual/symbol';
import layoutPoints from '../layout/points';
// In case developer forget to include grid component
import '../component/gridSimple';
-echarts.registerVisual(visualSymbol('scatter', 'circle'));
echarts.registerLayout(layoutPoints('scatter'));
diff --git a/src/chart/scatter/ScatterSeries.ts b/src/chart/scatter/ScatterSeries.ts
index d1c58b2..e6b721b 100644
--- a/src/chart/scatter/ScatterSeries.ts
+++ b/src/chart/scatter/ScatterSeries.ts
@@ -86,6 +86,8 @@ class ScatterSeriesModel extends SeriesModel<ScatterSeriesOption> {
static readonly dependencies = ['grid', 'polar', 'geo', 'singleAxis', 'calendar'];
+ hasSymbolVisual = true;
+
getInitialData(option: ScatterSeriesOption, ecModel: GlobalModel): List {
return createListFromArray(this.getSource(), this, {
useEncodeDefaulter: true
diff --git a/src/chart/sunburst.ts b/src/chart/sunburst.ts
index 2f7edd8..8922feb 100644
--- a/src/chart/sunburst.ts
+++ b/src/chart/sunburst.ts
@@ -24,10 +24,8 @@ import './sunburst/SunburstSeries';
import './sunburst/SunburstView';
import './sunburst/sunburstAction';
-import dataColor from '../visual/dataColor';
import sunburstLayout from './sunburst/sunburstLayout';
import dataFilter from '../processor/dataFilter';
-echarts.registerVisual(zrUtil.curry(dataColor, 'sunburst'));
echarts.registerLayout(zrUtil.curry(sunburstLayout, 'sunburst'));
echarts.registerProcessor(zrUtil.curry(dataFilter, 'sunburst'));
diff --git a/src/chart/sunburst/SunburstPiece.ts b/src/chart/sunburst/SunburstPiece.ts
index 4b526ea..1095a6e 100644
--- a/src/chart/sunburst/SunburstPiece.ts
+++ b/src/chart/sunburst/SunburstPiece.ts
@@ -19,9 +19,9 @@
import * as zrUtil from 'zrender/src/core/util';
import * as graphic from '../../util/graphic';
-import { ZRColor, ColorString } from '../../util/types';
+import { ColorString } from '../../util/types';
import { TreeNode } from '../../data/Tree';
-import SunburstSeriesModel, { SunburstSeriesNodeOption, SunburstSeriesOption } from './SunburstSeries';
+import SunburstSeriesModel, { SunburstSeriesNodeItemOption, SunburstSeriesOption } from './SunburstSeries';
import GlobalModel from '../../model/Global';
import { AllPropTypes } from 'zrender/src/core/types';
@@ -62,7 +62,7 @@ class SunburstPiece extends graphic.Group {
const text = new graphic.Text({
z2: DEFAULT_TEXT_Z,
- silent: node.getModel<SunburstSeriesNodeOption>().get(['label', 'silent'])
+ silent: node.getModel<SunburstSeriesNodeItemOption>().get(['label', 'silent'])
});
sector.setTextContent(text);
@@ -98,7 +98,7 @@ class SunburstPiece extends graphic.Group {
const sector = this.childAt(0) as graphic.Sector;
graphic.getECData(sector).dataIndex = node.dataIndex;
- const itemModel = node.getModel<SunburstSeriesNodeOption>();
+ const itemModel = node.getModel<SunburstSeriesNodeItemOption>();
const layout = node.getLayout();
// if (!layout) {
// console.log(node.getLayout());
@@ -106,11 +106,9 @@ class SunburstPiece extends graphic.Group {
const sectorShape = zrUtil.extend({}, layout);
sectorShape.label = null;
- const visualColor = getNodeColor(node, seriesModel, ecModel);
-
- fillDefaultColor(node, seriesModel, visualColor);
-
- const normalStyle = itemModel.getModel('itemStyle').getItemStyle();
+ // const visualColor = getNodeColor(node, seriesModel, ecModel);
+ // fillDefaultColor(node, seriesModel, visualColor);
+ const normalStyle = node.getVisual('style');
let style;
if (state === 'normal') {
style = normalStyle;
@@ -120,13 +118,13 @@ class SunburstPiece extends graphic.Group {
.getItemStyle();
style = zrUtil.merge(stateStyle, normalStyle);
}
- style = zrUtil.defaults(
- {
- lineJoin: 'bevel',
- fill: style.fill || visualColor
- },
- style
- );
+ // style = zrUtil.defaults(
+ // {
+ // lineJoin: 'bevel',
+ // fill: style.fill || visualColor
+ // },
+ // style
+ // );
if (firstCreate) {
sector.setShape(sectorShape);
@@ -160,7 +158,7 @@ class SunburstPiece extends graphic.Group {
}, seriesModel);
}
- this._updateLabel(seriesModel, visualColor, state);
+ this._updateLabel(seriesModel, style.fill, state);
const cursorStyle = itemModel.getShallow('cursor');
cursorStyle && sector.attr('cursor', cursorStyle);
@@ -212,7 +210,7 @@ class SunburstPiece extends graphic.Group {
visualColor: ColorString,
state: 'emphasis' | 'normal' | 'highlight' | 'downplay'
) {
- const itemModel = this.node.getModel<SunburstSeriesNodeOption>();
+ const itemModel = this.node.getModel<SunburstSeriesNodeItemOption>();
const normalModel = itemModel.getModel('label');
const labelModel = state === 'normal' || state === 'emphasis'
? normalModel
@@ -321,7 +319,7 @@ class SunburstPiece extends graphic.Group {
}
label.attr('rotation', rotate);
- type LabelOption = SunburstSeriesNodeOption['label'];
+ type LabelOption = SunburstSeriesNodeItemOption['label'];
function getLabelAttr<T extends keyof LabelOption>(name: T): LabelOption[T] {
const stateAttr = labelModel.get(name);
if (stateAttr == null) {
@@ -372,58 +370,58 @@ class SunburstPiece extends graphic.Group {
export default SunburstPiece;
-/**
- * Get node color
- */
-function getNodeColor(
- node: TreeNode,
- seriesModel: SunburstSeriesModel,
- ecModel: GlobalModel
-) {
- // Color from visualMap
- let visualColor = node.getVisual('color');
- const visualMetaList = node.getVisual('visualMeta');
- if (!visualMetaList || visualMetaList.length === 0) {
- // Use first-generation color if has no visualMap
- visualColor = null;
- }
-
- // Self color or level color
- let color = node.getModel<SunburstSeriesNodeOption>().get(['itemStyle', 'color']);
- if (color) {
- return color;
- }
- else if (visualColor) {
- // Color mapping
- return visualColor;
- }
- else if (node.depth === 0) {
- // Virtual root node
- return ecModel.option.color[0];
- }
- else {
- // First-generation color
- const length = ecModel.option.color.length;
- color = ecModel.option.color[getRootId(node) % length];
- }
- return color;
-}
-
-/**
- * Get index of root in sorted order
- *
- * @param {TreeNode} node current node
- * @return {number} index in root
- */
-function getRootId(node: TreeNode) {
- let ancestor = node;
- while (ancestor.depth > 1) {
- ancestor = ancestor.parentNode;
- }
-
- const virtualRoot = node.getAncestors()[0];
- return zrUtil.indexOf(virtualRoot.children, ancestor);
-}
+// /**
+// * Get node color
+// */
+// function getNodeColor(
+// node: TreeNode,
+// seriesModel: SunburstSeriesModel,
+// ecModel: GlobalModel
+// ) {
+// // Color from visualMap
+// let visualColor = node.getVisual('color');
+// const visualMetaList = node.getVisual('visualMeta');
+// if (!visualMetaList || visualMetaList.length === 0) {
+// // Use first-generation color if has no visualMap
+// visualColor = null;
+// }
+
+// // Self color or level color
+// let color = node.getModel<SunburstSeriesNodeItemOption>().get(['itemStyle', 'color']);
+// if (color) {
+// return color;
+// }
+// else if (visualColor) {
+// // Color mapping
+// return visualColor;
+// }
+// else if (node.depth === 0) {
+// // Virtual root node
+// return ecModel.option.color[0];
+// }
+// else {
+// // First-generation color
+// const length = ecModel.option.color.length;
+// color = ecModel.option.color[getRootId(node) % length];
+// }
+// return color;
+// }
+
+// /**
+// * Get index of root in sorted order
+// *
+// * @param {TreeNode} node current node
+// * @return {number} index in root
+// */
+// function getRootId(node: TreeNode) {
+// let ancestor = node;
+// while (ancestor.depth > 1) {
+// ancestor = ancestor.parentNode;
+// }
+
+// const virtualRoot = node.getAncestors()[0];
+// return zrUtil.indexOf(virtualRoot.children, ancestor);
+// }
function isNodeHighlighted(
node: TreeNode,
@@ -445,7 +443,7 @@ function isNodeHighlighted(
}
// Fix tooltip callback function params.color incorrect when pick a default color
-function fillDefaultColor(node: TreeNode, seriesModel: SunburstSeriesModel, color: ZRColor) {
- const data = seriesModel.getData();
- data.setItemVisual(node.dataIndex, 'color', color);
-}
+// function fillDefaultColor(node: TreeNode, seriesModel: SunburstSeriesModel, color: ZRColor) {
+// const data = seriesModel.getData();
+// data.setItemVisual(node.dataIndex, 'color', color);
+// }
diff --git a/src/chart/sunburst/SunburstSeries.ts b/src/chart/sunburst/SunburstSeries.ts
index 6211e01..be7b077 100644
--- a/src/chart/sunburst/SunburstSeries.ts
+++ b/src/chart/sunburst/SunburstSeries.ts
@@ -42,11 +42,11 @@ interface SunburstDataParams extends CallbackDataParams {
treePathInfo: {
name: string,
dataIndex: number
- value: SunburstSeriesNodeOption['value']
+ value: SunburstSeriesNodeItemOption['value']
}[]
}
-export interface SunburstSeriesNodeOption {
+export interface SunburstSeriesNodeItemOption {
name?: string
nodeClick?: 'rootToNode' | 'link'
@@ -71,7 +71,7 @@ export interface SunburstSeriesNodeOption {
value?: OptionDataValue | OptionDataValue[]
- children?: SunburstSeriesNodeOption[]
+ children?: SunburstSeriesNodeItemOption[]
collapsed?: boolean
@@ -152,6 +152,8 @@ class SunburstSeriesModel extends SeriesModel<SunburstSeriesOption> {
private _viewRoot: TreeNode;
+ useColorPaletteOnData = true;
+
getInitialData(option: SunburstSeriesOption, ecModel: GlobalModel) {
// Create a virtual root.
const root = { name: option.name, children: option.data };
@@ -183,7 +185,7 @@ class SunburstSeriesModel extends SeriesModel<SunburstSeriesOption> {
const params = super.getDataParams.apply(this, arguments as any) as SunburstDataParams;
const node = this.getData().tree.getNodeByDataIndex(dataIndex);
- params.treePathInfo = wrapTreePathInfo<SunburstSeriesNodeOption['value']>(node, this);
+ params.treePathInfo = wrapTreePathInfo<SunburstSeriesNodeItemOption['value']>(node, this);
return params;
}
@@ -292,7 +294,7 @@ class SunburstSeriesModel extends SeriesModel<SunburstSeriesOption> {
-function completeTreeValue(dataNode: SunburstSeriesNodeOption) {
+function completeTreeValue(dataNode: SunburstSeriesNodeItemOption) {
// Postorder travel tree.
// If value of none-leaf node is not set,
// calculate it by suming up the value of all children.
diff --git a/src/chart/sunburst/SunburstView.ts b/src/chart/sunburst/SunburstView.ts
index b5ce867..bef20f9 100644
--- a/src/chart/sunburst/SunburstView.ts
+++ b/src/chart/sunburst/SunburstView.ts
@@ -21,7 +21,7 @@ import * as zrUtil from 'zrender/src/core/util';
import ChartView from '../../view/Chart';
import SunburstPiece from './SunburstPiece';
import DataDiffer from '../../data/DataDiffer';
-import SunburstSeriesModel, { SunburstSeriesNodeOption } from './SunburstSeries';
+import SunburstSeriesModel, { SunburstSeriesNodeItemOption } from './SunburstSeries';
import GlobalModel from '../../model/Global';
import ExtensionAPI from '../../ExtensionAPI';
import { TreeNode } from '../../data/Tree';
@@ -210,12 +210,12 @@ class SunburstView extends ChartView {
if (!targetFound
&& node.piece && node.piece.childAt(0) === e.target
) {
- const nodeClick = node.getModel<SunburstSeriesNodeOption>().get('nodeClick');
+ const nodeClick = node.getModel<SunburstSeriesNodeItemOption>().get('nodeClick');
if (nodeClick === 'rootToNode') {
this._rootToNode(node);
}
else if (nodeClick === 'link') {
- const itemModel = node.getModel<SunburstSeriesNodeOption>();
+ const itemModel = node.getModel<SunburstSeriesNodeItemOption>();
const link = itemModel.get('link');
if (link) {
const linkTarget = itemModel.get('target', true)
diff --git a/src/chart/sunburst/sunburstLayout.ts b/src/chart/sunburst/sunburstLayout.ts
index 195ec83..f1da06c 100644
--- a/src/chart/sunburst/sunburstLayout.ts
+++ b/src/chart/sunburst/sunburstLayout.ts
@@ -21,7 +21,7 @@ import { parsePercent } from '../../util/number';
import * as zrUtil from 'zrender/src/core/util';
import GlobalModel from '../../model/Global';
import ExtensionAPI from '../../ExtensionAPI';
-import SunburstSeriesModel, { SunburstSeriesNodeOption, SunburstSeriesOption } from './SunburstSeries';
+import SunburstSeriesModel, { SunburstSeriesNodeItemOption, SunburstSeriesOption } from './SunburstSeries';
import { TreeNode } from '../../data/Tree';
// let PI2 = Math.PI * 2;
@@ -119,7 +119,7 @@ export default function (
let rStart = r0 + rPerLevel * depth;
let rEnd = r0 + rPerLevel * (depth + 1);
- const itemModel = node.getModel<SunburstSeriesNodeOption>();
+ const itemModel = node.getModel<SunburstSeriesNodeItemOption>();
// @ts-ignore. TODO this is not provided to developer yet. Rename it.
if (itemModel.get('r0') != null) {
// @ts-ignore
diff --git a/src/chart/themeRiver/themeRiverVisual.ts b/src/chart/sunburst/sunburstVisual.ts
similarity index 52%
rename from src/chart/themeRiver/themeRiverVisual.ts
rename to src/chart/sunburst/sunburstVisual.ts
index 7140528..97eb785 100644
--- a/src/chart/themeRiver/themeRiverVisual.ts
+++ b/src/chart/sunburst/sunburstVisual.ts
@@ -17,32 +17,21 @@
* under the License.
*/
-import {createHashMap} from 'zrender/src/core/util';
import GlobalModel from '../../model/Global';
-import ThemeRiverSeriesModel from './ThemeRiverSeries';
+import SunburstSeriesModel, { SunburstSeriesNodeItemOption } from './SunburstSeries';
+import { extend } from 'zrender/src/core/util';
export default function (ecModel: GlobalModel) {
- ecModel.eachSeriesByType('themeRiver', function (seriesModel: ThemeRiverSeriesModel) {
- const data = seriesModel.getData();
- const rawData = seriesModel.getRawData();
- const colorList = seriesModel.get('color');
- const idxMap = createHashMap<number>();
-
- data.each(function (idx) {
- idxMap.set(data.getRawIndex(idx), idx);
- });
-
- rawData.each(function (rawIndex) {
- const name = rawData.getName(rawIndex);
- const color = colorList[(seriesModel.nameMap.get(name) - 1) % colorList.length];
- rawData.setItemVisual(rawIndex, 'color', color);
-
- const idx = idxMap.get(rawIndex);
-
- if (idx != null) {
- data.setItemVisual(idx, 'color', color);
- }
+ ecModel.eachSeriesByType('graph', function (seriesModel: SunburstSeriesModel) {
+ const data = seriesModel.getData();
+ const tree = data.tree;
+ tree.eachNode(function (node) {
+ const model = node.getModel<SunburstSeriesNodeItemOption>();
+ // TODO Optimize
+ const style = model.getModel('itemStyle').getItemStyle();
+ const existsStyle = data.ensureUniqueItemVisual(node.dataIndex, 'style');
+ extend(existsStyle, style);
});
});
-}
\ No newline at end of file
+}
diff --git a/src/chart/themeRiver.ts b/src/chart/themeRiver.ts
index 26f136c..582003b 100644
--- a/src/chart/themeRiver.ts
+++ b/src/chart/themeRiver.ts
@@ -24,9 +24,7 @@ import './themeRiver/ThemeRiverSeries';
import './themeRiver/ThemeRiverView';
import themeRiverLayout from './themeRiver/themeRiverLayout';
-import themeRiverVisual from './themeRiver/themeRiverVisual';
import dataFilter from '../processor/dataFilter';
echarts.registerLayout(themeRiverLayout);
-echarts.registerVisual(themeRiverVisual);
echarts.registerProcessor(dataFilter('themeRiver'));
\ No newline at end of file
diff --git a/src/chart/themeRiver/ThemeRiverSeries.ts b/src/chart/themeRiver/ThemeRiverSeries.ts
index cee81ee..5e28bf2 100644
--- a/src/chart/themeRiver/ThemeRiverSeries.ts
+++ b/src/chart/themeRiver/ThemeRiverSeries.ts
@@ -87,6 +87,8 @@ class ThemeRiverSeriesModel extends SeriesModel<ThemeRiverSeriesOption> {
coordinateSystem: Single;
+ useColorPaletteOnData = true;
+
/**
* @override
*/
diff --git a/src/chart/themeRiver/ThemeRiverView.ts b/src/chart/themeRiver/ThemeRiverView.ts
index 3fa1a8d..f42e220 100644
--- a/src/chart/themeRiver/ThemeRiverView.ts
+++ b/src/chart/themeRiver/ThemeRiverView.ts
@@ -76,7 +76,7 @@ class ThemeRiverView extends ChartView {
}
const points0 = [];
const points1 = [];
- let color;
+ let style;
const indices = layersSeries[idx].indices;
let j = 0;
for (; j < indices.length; j++) {
@@ -88,7 +88,7 @@ class ThemeRiverView extends ChartView {
points0.push([x, y0]);
points1.push([x, y0 + y]);
- color = data.getItemVisual(indices[j], 'color');
+ style = data.getItemVisual(indices[j], 'style');
}
let polygon: ECPolygon;
@@ -154,12 +154,7 @@ class ThemeRiverView extends ChartView {
}
const hoverItemStyleModel = seriesModel.getModel(['emphasis', 'itemStyle']);
- const itemStyleModel = seriesModel.getModel('itemStyle');
-
-
- polygon.setStyle(extend({
- fill: color
- }, itemStyleModel.getItemStyle(['color'])));
+ polygon.setStyle(style);
graphic.enableHoverEmphasis(polygon, hoverItemStyleModel.getItemStyle());
}
diff --git a/src/chart/tree.ts b/src/chart/tree.ts
index e498d25..52b14c5 100644
--- a/src/chart/tree.ts
+++ b/src/chart/tree.ts
@@ -23,8 +23,8 @@ import './tree/TreeSeries';
import './tree/TreeView';
import './tree/treeAction';
-import visualSymbol from '../visual/symbol';
import treeLayout from './tree/treeLayout';
+import treeVisual from './tree/treeVisual';
-echarts.registerVisual(visualSymbol('tree', 'circle'));
echarts.registerLayout(treeLayout);
+echarts.registerLayout(treeVisual);
diff --git a/src/chart/tree/TreeSeries.ts b/src/chart/tree/TreeSeries.ts
index 2149e5b..4f24538 100644
--- a/src/chart/tree/TreeSeries.ts
+++ b/src/chart/tree/TreeSeries.ts
@@ -137,6 +137,11 @@ class TreeSeriesModel extends SeriesModel<TreeSeriesOption> {
layoutInfo: LayoutRect;
+ hasSymbolVisual = true;
+
+ // Do it self.
+ ignoreStyleOnData = true;
+
/**
* Init a tree data structure from data in option series
* @param option the object used to config echarts view
diff --git a/src/chart/tree/TreeView.ts b/src/chart/tree/TreeView.ts
index 580510a..2d16448 100644
--- a/src/chart/tree/TreeView.ts
+++ b/src/chart/tree/TreeView.ts
@@ -224,6 +224,9 @@ class TreeView extends ChartView {
symbolEl && removeNode(oldData, oldIdx, symbolEl, group, seriesModel, seriesScope);
return;
}
+ if (symbolEl) {
+ graphic.clearStates(symbolEl);
+ }
// Update node and edge
updateNode(data, newIdx, symbolEl, group, seriesModel, seriesScope);
})
diff --git a/src/chart/map/mapVisual.ts b/src/chart/tree/treeVisual.ts
similarity index 59%
rename from src/chart/map/mapVisual.ts
rename to src/chart/tree/treeVisual.ts
index 031d40c..b4f9332 100644
--- a/src/chart/map/mapVisual.ts
+++ b/src/chart/tree/treeVisual.ts
@@ -1,7 +1,3 @@
-import GlobalModel from '../../model/Global';
-import MapSeries from './MapSeries';
-import { ZRColor } from '../../util/types';
-
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
@@ -21,19 +17,21 @@ import { ZRColor } from '../../util/types';
* under the License.
*/
+import GlobalModel from '../../model/Global';
+import TreeSeriesModel, { TreeSeriesNodeItemOption } from './TreeSeries';
+import { extend } from 'zrender/src/core/util';
export default function (ecModel: GlobalModel) {
- ecModel.eachSeriesByType('map', function (seriesModel: MapSeries) {
- const colorList = seriesModel.get('color') as ZRColor[];
- const itemStyleModel = seriesModel.getModel('itemStyle');
-
- const areaColor = itemStyleModel.get('areaColor');
- const color = itemStyleModel.get('color')
- || colorList[seriesModel.seriesIndex % colorList.length];
- seriesModel.getData().setVisual({
- 'areaColor': areaColor,
- 'color': color
+ ecModel.eachSeriesByType('tree', function (seriesModel: TreeSeriesModel) {
+ const data = seriesModel.getData();
+ const tree = data.tree;
+ tree.eachNode(function (node) {
+ const model = node.getModel<TreeSeriesNodeItemOption>();
+ // TODO Optimize
+ const style = model.getModel('itemStyle').getItemStyle();
+ const existsStyle = data.ensureUniqueItemVisual(node.dataIndex, 'style');
+ extend(existsStyle, style);
});
});
-}
\ No newline at end of file
+}
diff --git a/src/chart/treemap/TreemapView.ts b/src/chart/treemap/TreemapView.ts
index 5ecb9a8..8111b91 100644
--- a/src/chart/treemap/TreemapView.ts
+++ b/src/chart/treemap/TreemapView.ts
@@ -864,7 +864,7 @@ function renderNode(
}
else {
bg.invisible = false;
- const visualBorderColor = thisNode.getVisual('borderColor', true);
+ const visualBorderColor = thisNode.getVisual('style').stroke;
const emphasisBorderColor = itemStyleEmphasisModel.get('borderColor');
const normalStyle = getItemStyleNormal(itemStyleNormalModel);
normalStyle.fill = visualBorderColor;
@@ -916,7 +916,8 @@ function renderNode(
}
else {
content.invisible = false;
- const visualColor = thisNode.getVisual('color', true);
+ // TODO. Optimize.
+ const visualColor = thisNode.getVisual('style').fill;
const normalStyle = getItemStyleNormal(itemStyleNormalModel);
normalStyle.fill = visualColor;
const emphasisStyle = getItemStyleEmphasis(itemStyleEmphasisModel);
diff --git a/src/chart/treemap/treemapVisual.ts b/src/chart/treemap/treemapVisual.ts
index f26909d..0ff4b8e 100644
--- a/src/chart/treemap/treemapVisual.ts
+++ b/src/chart/treemap/treemapVisual.ts
@@ -79,6 +79,7 @@ function travelTree(
) {
const nodeModel = node.getModel<TreemapSeriesNodeItemOption>();
const nodeLayout = node.getLayout();
+ const data = node.hostTree.data;
// Optimize
if (!nodeLayout || nodeLayout.invisible || !nodeLayout.isInView) {
@@ -91,6 +92,7 @@ function travelTree(
nodeItemStyleModel, designatedVisual, levelItemStyle, seriesItemStyleModel
);
+ const existsStyle = data.ensureUniqueItemVisual(node.dataIndex, 'style');
// calculate border color
let borderColor = nodeItemStyleModel.get('borderColor');
const borderColorSaturation = nodeItemStyleModel.get('borderColorSaturation');
@@ -100,13 +102,13 @@ function travelTree(
thisNodeColor = calculateColor(visuals);
borderColor = calculateBorderColor(borderColorSaturation, thisNodeColor);
}
- node.setVisual('borderColor', borderColor);
+ existsStyle.stroke = borderColor;
const viewChildren = node.viewChildren;
if (!viewChildren || !viewChildren.length) {
thisNodeColor = calculateColor(visuals);
// Apply visual to this node.
- node.setVisual('color', thisNodeColor);
+ existsStyle.fill = thisNodeColor;
}
else {
const mapping = buildVisualMapping(
diff --git a/src/component/axis/AngleAxisView.ts b/src/component/axis/AngleAxisView.ts
index 3a95368..48f1eea 100644
--- a/src/component/axis/AngleAxisView.ts
+++ b/src/component/axis/AngleAxisView.ts
@@ -163,7 +163,6 @@ const angelAxisElementsBuilders: Record<typeof elementList[number], AngleAxisEle
silent: true
});
}
- shape.style.fill = null;
group.add(shape);
},
diff --git a/src/component/axis/AxisBuilder.ts b/src/component/axis/AxisBuilder.ts
index 940b6ac..ed95b41 100644
--- a/src/component/axis/AxisBuilder.ts
+++ b/src/component/axis/AxisBuilder.ts
@@ -635,6 +635,7 @@ function createTicks(
},
style: tickLineStyle,
z2: 2,
+ autoBatch: true,
silent: true
});
tickEl.anid = anidPrefix + '_' + ticksCoords[i].tickValue;
diff --git a/src/component/axis/CartesianAxisView.ts b/src/component/axis/CartesianAxisView.ts
index 5c677fa..711b487 100644
--- a/src/component/axis/CartesianAxisView.ts
+++ b/src/component/axis/CartesianAxisView.ts
@@ -141,6 +141,7 @@ const axisElementBuilders: Record<typeof selfBuilderAttrs[number], AxisElementBu
axisGroup.add(new graphic.Line({
anid: tickValue != null ? 'line_' + ticksCoords[i].tickValue : null,
subPixelOptimize: true,
+ autoBatch: true,
shape: {
x1: p1[0],
y1: p1[1],
@@ -194,6 +195,7 @@ const axisElementBuilders: Record<typeof selfBuilderAttrs[number], AxisElementBu
axisGroup.add(new graphic.Line({
anid: 'minor_line_' + minorTicksCoords[i][k].tickValue,
subPixelOptimize: true,
+ autoBatch: true,
shape: {
x1: p1[0],
y1: p1[1],
diff --git a/src/component/axis/axisSplitHelper.ts b/src/component/axis/axisSplitHelper.ts
index 6d92f92..83af2d3 100644
--- a/src/component/axis/axisSplitHelper.ts
+++ b/src/component/axis/axisSplitHelper.ts
@@ -117,6 +117,7 @@ export function rectCoordAxisBuildSplitArea(
style: zrUtil.defaults({
fill: areaColors[colorIndex]
}, areaStyle),
+ autoBatch: true,
silent: true
}));
diff --git a/src/component/brush/brushAction.ts b/src/component/brush/brushAction.ts
index bb407f0..86c09d0 100644
--- a/src/component/brush/brushAction.ts
+++ b/src/component/brush/brushAction.ts
@@ -28,7 +28,7 @@ interface BrushPayload extends Payload {
}
echarts.registerAction(
- {type: 'brush', event: 'brush' /*, update: 'updateView' */},
+ {type: 'brush', event: 'brush', update: 'updateVisual' },
function (payload: BrushPayload, ecModel: GlobalModel) {
ecModel.eachComponent(
{mainType: 'brush', query: payload},
diff --git a/src/component/helper/MapDraw.ts b/src/component/helper/MapDraw.ts
index 21ce559..11d1a1d 100644
--- a/src/component/helper/MapDraw.ts
+++ b/src/component/helper/MapDraw.ts
@@ -141,9 +141,9 @@ class MapDraw {
regionsGroup.removeAll();
- const itemStyleAccessPath = ['itemStyle'] as const;
+ const itemStyleAccessPath = 'itemStyle';
const hoverItemStyleAccessPath = ['emphasis', 'itemStyle'] as const;
- const labelAccessPath = ['label'] as const;
+ const labelAccessPath = 'label';
const hoverLabelAccessPath = ['emphasis', 'label'] as const;
const nameMap = zrUtil.createHashMap<RegionsGroup>();
@@ -170,6 +170,9 @@ class MapDraw {
const itemStyleModel = regionModel.getModel(itemStyleAccessPath);
// @ts-ignore FIXME:TS fix the "compatible with each other"?
const hoverItemStyleModel = regionModel.getModel(hoverItemStyleAccessPath);
+
+ // NOTE: DONT use 'style' in visual when drawing map.
+ // This component is used for drawing underlying map for both geo component and map series.
const itemStyle = getFixedItemStyle(itemStyleModel);
const hoverItemStyle = getFixedItemStyle(hoverItemStyleModel);
@@ -186,9 +189,10 @@ class MapDraw {
// But visual color of series is used in symbol drawing
//
// Visual color for each series is for the symbol draw
- const visualColor = data.getItemVisual(dataIdx, 'color', true);
- if (visualColor) {
- itemStyle.fill = visualColor;
+ const style = data.getItemVisual(dataIdx, 'style');
+ const globalStyle = data.getVisual('style');
+ if (style !== globalStyle) {
+ itemStyle.fill = style.fill;
}
}
diff --git a/src/component/legend/LegendView.ts b/src/component/legend/LegendView.ts
index 6783978..ecff71e 100644
--- a/src/component/legend/LegendView.ts
+++ b/src/component/legend/LegendView.ts
@@ -28,16 +28,18 @@ import LegendModel, { LegendOption, LegendSelectorButtonOption, LegendTooltipFor
import GlobalModel from '../../model/Global';
import ExtensionAPI from '../../ExtensionAPI';
import {
- ColorString,
ZRTextAlign,
ZRColor,
ItemStyleOption,
ZRRectLike,
ECElement,
- CommonTooltipOption
+ CommonTooltipOption,
+ ColorString
} from '../../util/types';
import Model from '../../model/Model';
import Displayable from 'zrender/src/graphic/Displayable';
+import { PathStyleProps } from 'zrender/src/graphic/Path';
+import { parse, stringify } from 'zrender/src/tool/color';
const curry = zrUtil.curry;
const each = zrUtil.each;
@@ -192,20 +194,9 @@ class LegendView extends ComponentView {
// Legend to control series.
if (seriesModel) {
const data = seriesModel.getData();
- let color = data.getVisual('color');
- let borderColor = data.getVisual('borderColor');
-
- // If color is a callback function
- if (typeof color === 'function') {
- // Use the first data
- color = color(seriesModel.getDataParams(0));
- }
-
- // If borderColor is a callback function
- if (typeof borderColor === 'function') {
- // Use the first data
- borderColor = borderColor(seriesModel.getDataParams(0));
- }
+ const style = data.getVisual('style');
+ const color = style.fill;
+ const borderColor = style.stroke;
// Using rect symbol defaultly
const legendSymbolType = data.getVisual('legendSymbol') || 'roundRect';
@@ -241,8 +232,17 @@ class LegendView extends ComponentView {
const idx = provider.indexOfName(name);
- const color = provider.getItemVisual(idx, 'color');
- const borderColor = provider.getItemVisual(idx, 'borderColor');
+ const style = provider.getItemVisual(idx, 'style') as PathStyleProps;
+ const borderColor = style.stroke;
+ let color = style.fill;
+ const colorArr = parse(style.fill as ColorString);
+ // Color may be set to transparent in visualMap when data is out of range.
+ // Do not show nothing.
+ if (colorArr && colorArr[3] === 0) {
+ colorArr[3] = 0.2;
+ // TODO color is set to 0, 0, 0, 0. Should show correct RGBA
+ color = stringify(colorArr, 'rgba');
+ }
const legendSymbolType = 'roundRect';
@@ -329,8 +329,8 @@ class LegendView extends ComponentView {
legendSymbolType: string,
symbolType: string,
itemAlign: LegendOption['align'],
- color: ColorString,
- borderColor: ColorString,
+ color: ZRColor,
+ borderColor: ZRColor,
selectMode: LegendOption['selectedMode']
) {
const itemWidth = legendModel.get('itemWidth');
diff --git a/src/component/marker/MarkAreaView.ts b/src/component/marker/MarkAreaView.ts
index da9c27e..3be84b9 100644
--- a/src/component/marker/MarkAreaView.ts
+++ b/src/component/marker/MarkAreaView.ts
@@ -26,7 +26,7 @@ import * as graphic from '../../util/graphic';
import * as markerHelper from './markerHelper';
import MarkerView from './MarkerView';
import { retrieve, mergeAll, map, defaults, curry, filter, HashMap } from 'zrender/src/core/util';
-import { ScaleDataValue, ParsedValue } from '../../util/types';
+import { ScaleDataValue, ParsedValue, ZRColor } from '../../util/types';
import { CoordinateSystem, isCoordinateSystemType } from '../../coord/CoordinateSystem';
import MarkAreaModel, { MarkArea2DDataItemOption } from './MarkAreaModel';
import SeriesModel from '../../model/Series';
@@ -37,6 +37,7 @@ import GlobalModel from '../../model/Global';
import ExtensionAPI from '../../ExtensionAPI';
import MarkerModel from './MarkerModel';
import { makeInner } from '../../util/model';
+import { getVisualFromData } from '../../visual/helper';
interface MarkAreaDrawGroup {
group: graphic.Group
@@ -244,10 +245,19 @@ class MarkAreaView extends MarkerView {
return getSingleMarkerEndPoint(areaData, idx, dim, seriesModel, api);
}));
+ const style = areaData.getItemModel<MarkAreaMergedItemOption>(idx).getModel('itemStyle').getItemStyle();
+ const color = getVisualFromData(seriesData, 'color') as ZRColor;
+ if (!style.fill) {
+ style.fill = color;
+ if (typeof style.fill === 'string') {
+ style.fill = colorUtil.modifyAlpha(style.fill, 0.4);
+ }
+ }
+ if (!style.stroke) {
+ style.stroke = color;
+ }
// Visual
- areaData.setItemVisual(idx, {
- color: seriesData.getVisual('color')
- });
+ areaData.setItemVisual(idx, 'style', style);
});
@@ -263,6 +273,7 @@ class MarkAreaView extends MarkerView {
})
.update(function (newIdx, oldIdx) {
const polygon = inner(polygonGroup).data.getItemGraphicEl(oldIdx) as graphic.Polygon;
+ graphic.clearStates(polygon);
graphic.updateProps(polygon, {
shape: {
points: areaData.getItemLayout(newIdx)
@@ -281,16 +292,8 @@ class MarkAreaView extends MarkerView {
const itemModel = areaData.getItemModel<MarkAreaMergedItemOption>(idx);
const labelModel = itemModel.getModel('label');
const labelHoverModel = itemModel.getModel(['emphasis', 'label']);
- const color = areaData.getItemVisual(idx, 'color');
- polygon.useStyle(
- defaults(
- itemModel.getModel('itemStyle').getItemStyle(),
- {
- fill: colorUtil.modifyAlpha(color, 0.4),
- stroke: color
- }
- )
- );
+ const style = areaData.getItemVisual(idx, 'style');
+ polygon.useStyle(areaData.getItemVisual(idx, 'style'));
graphic.setLabelStyle(
polygon, labelModel, labelHoverModel,
@@ -298,7 +301,8 @@ class MarkAreaView extends MarkerView {
labelFetcher: maModel,
labelDataIndex: idx,
defaultText: areaData.getName(idx) || '',
- autoColor: color
+ autoColor: typeof style.fill === 'string'
+ ? colorUtil.modifyAlpha(style.fill, 1) : '#000'
}
);
diff --git a/src/component/marker/MarkLineView.ts b/src/component/marker/MarkLineView.ts
index 0254bab..cf0b933 100644
--- a/src/component/marker/MarkLineView.ts
+++ b/src/component/marker/MarkLineView.ts
@@ -25,7 +25,7 @@ import MarkerView from './MarkerView';
import {getStackedDimension} from '../../data/helper/dataStackHelper';
import { CoordinateSystem, isCoordinateSystemType } from '../../coord/CoordinateSystem';
import MarkLineModel, { MarkLine2DDataItemOption, MarkLineOption } from './MarkLineModel';
-import { ScaleDataValue } from '../../util/types';
+import { ScaleDataValue, ColorString } from '../../util/types';
import SeriesModel from '../../model/Series';
import { __DEV__ } from '../../config';
import { getECData } from '../../util/graphic';
@@ -48,6 +48,8 @@ import {
} from 'zrender/src/core/util';
import ComponentView from '../../view/Component';
import { makeInner } from '../../util/model';
+import { LineDataVisual } from '../../visual/commonVisualTypes';
+import { getItemVisualFromData, getVisualFromData } from '../../visual/helper';
// Item option for configuring line and each end of symbol.
// Line option. be merged from configuration of two ends.
@@ -308,7 +310,7 @@ class MarkLineView extends MarkerView {
const fromData = mlData.from;
const toData = mlData.to;
- const lineData = mlData.line;
+ const lineData = mlData.line as List<MarkLineModel, LineDataVisual>;
inner(mlModel).from = fromData;
inner(mlModel).to = toData;
@@ -332,20 +334,26 @@ class MarkLineView extends MarkerView {
// Update visual and layout of line
lineData.each(function (idx) {
- const lineColor = lineData.getItemModel<MarkLineMergedItemOption>(idx).get(['lineStyle', 'color']);
- lineData.setItemVisual(idx, {
- color: lineColor || fromData.getItemVisual(idx, 'color')
- });
+ const lineStyle = lineData.getItemModel<MarkLineMergedItemOption>(idx)
+ .getModel('lineStyle').getLineStyle();
+ // lineData.setItemVisual(idx, {
+ // color: lineColor || fromData.getItemVisual(idx, 'color')
+ // });
lineData.setItemLayout(idx, [
fromData.getItemLayout(idx),
toData.getItemLayout(idx)
]);
+ if (lineStyle.stroke == null) {
+ lineStyle.stroke = getItemVisualFromData(fromData, idx, 'color') as ColorString;
+ }
+
lineData.setItemVisual(idx, {
- 'fromSymbolSize': fromData.getItemVisual(idx, 'symbolSize'),
- 'fromSymbol': fromData.getItemVisual(idx, 'symbol'),
- 'toSymbolSize': toData.getItemVisual(idx, 'symbolSize'),
- 'toSymbol': toData.getItemVisual(idx, 'symbol')
+ fromSymbolSize: fromData.getItemVisual(idx, 'symbolSize') as number,
+ fromSymbol: fromData.getItemVisual(idx, 'symbol'),
+ toSymbolSize: toData.getItemVisual(idx, 'symbolSize') as number,
+ toSymbol: toData.getItemVisual(idx, 'symbol'),
+ style: lineStyle
});
});
@@ -370,10 +378,15 @@ class MarkLineView extends MarkerView {
data, idx, isFrom, seriesModel, api
);
+ const style = itemModel.getModel('itemStyle').getItemStyle();
+ if (style.fill == null) {
+ style.fill = getVisualFromData(seriesData, 'color') as ColorString;
+ }
+
data.setItemVisual(idx, {
symbolSize: itemModel.get('symbolSize') || (symbolSize as number[])[isFrom ? 0 : 1],
symbol: itemModel.get('symbol', true) || (symbolType as string[])[isFrom ? 0 : 1],
- color: itemModel.get(['itemStyle', 'color']) || seriesData.getVisual('color')
+ style
});
}
diff --git a/src/component/marker/MarkPointView.ts b/src/component/marker/MarkPointView.ts
index af65086..370d05f 100644
--- a/src/component/marker/MarkPointView.ts
+++ b/src/component/marker/MarkPointView.ts
@@ -32,6 +32,8 @@ import MarkerModel from './MarkerModel';
import ExtensionAPI from '../../ExtensionAPI';
import { HashMap, isFunction, map, defaults, filter, curry } from 'zrender/src/core/util';
import { getECData } from '../../util/graphic';
+import { getVisualFromData } from '../../visual/helper';
+import { ZRColor } from '../../util/types';
function updateMarkerLayout(
mpData: List<MarkPointModel>,
@@ -131,11 +133,16 @@ class MarkPointView extends MarkerView {
}
}
+ const style = itemModel.getModel('itemStyle').getItemStyle();
+ const color = getVisualFromData(seriesData, 'color') as ZRColor;
+ if (!style.fill) {
+ style.fill = color;
+ }
+
mpData.setItemVisual(idx, {
symbol: symbol,
symbolSize: symbolSize,
- color: itemModel.get(['itemStyle', 'color'])
- || seriesData.getVisual('color')
+ style
});
});
diff --git a/src/component/toolbox/ToolboxView.ts b/src/component/toolbox/ToolboxView.ts
index daf8328..4ecee54 100644
--- a/src/component/toolbox/ToolboxView.ts
+++ b/src/component/toolbox/ToolboxView.ts
@@ -291,7 +291,7 @@ class ToolboxView extends ComponentView {
const textContent = icon.getTextContent();
const emphasisTextState = textContent && textContent.states.emphasis;
// May be background element
- if (emphasisTextState && titleText) {
+ if (emphasisTextState && !zrUtil.isFunction(emphasisTextState) && titleText) {
const emphasisTextStyle = emphasisTextState.style || (emphasisTextState.style = {});
const rect = textContain.getBoundingRect(
titleText, ZRText.makeFont(emphasisTextStyle)
diff --git a/src/component/visualMap/visualEncoding.ts b/src/component/visualMap/visualEncoding.ts
index 90f9d13..e21ff38 100644
--- a/src/component/visualMap/visualEncoding.ts
+++ b/src/component/visualMap/visualEncoding.ts
@@ -24,6 +24,7 @@ import VisualMapping from '../../visual/VisualMapping';
import VisualMapModel, { VisualMeta } from './VisualMapModel';
import { StageHandlerProgressExecutor, BuiltinVisualProperty, ParsedValue } from '../../util/types';
import SeriesModel from '../../model/Series';
+import { getVisualFromData } from '../../visual/helper';
const VISUAL_PRIORITY = echarts.PRIORITY.VISUAL.COMPONENT;
@@ -94,7 +95,7 @@ function getColorVisual(
const mappings = visualMapModel.targetVisuals[valueState];
const visualTypes = VisualMapping.prepareVisualTypes(mappings);
const resultVisual: Partial<Record<BuiltinVisualProperty, any>> = {
- color: seriesModel.getData().getVisual('color') // default color.
+ color: getVisualFromData(seriesModel.getData(), 'color') // default color.
};
for (let i = 0, len = visualTypes.length; i < len; i++) {
diff --git a/src/data/Graph.ts b/src/data/Graph.ts
index 98633d0..6453c21 100644
--- a/src/data/Graph.ts
+++ b/src/data/Graph.ts
@@ -422,34 +422,34 @@ function createGraphDataProxyMixin<Host extends GraphEdge | GraphNode>(
/**
* @param Default 'value'. can be 'a', 'b', 'c', 'd', 'e'.
*/
- getValue: function (this: Host, dimension?: DimensionLoose): ParsedValue {
+ getValue(this: Host, dimension?: DimensionLoose): ParsedValue {
const data = this[hostName][dataName];
return data.get(data.getDimension(dimension || 'value'), this.dataIndex);
},
-
- setVisual: function (this: Host, key: string | Dictionary<any>, value?: any) {
+ // TODO: TYPE stricter type.
+ setVisual(this: Host, key: string | Dictionary<any>, value?: any) {
this.dataIndex >= 0
- && this[hostName][dataName].setItemVisual(this.dataIndex, key as string, value);
+ && this[hostName][dataName].setItemVisual(this.dataIndex, key as any, value);
},
- getVisual: function (this: Host, key: string, ignoreParent?: boolean) {
- return this[hostName][dataName].getItemVisual(this.dataIndex, key, ignoreParent);
+ getVisual(this: Host, key: string) {
+ return this[hostName][dataName].getItemVisual(this.dataIndex, key as any);
},
- setLayout: function (this: Host, layout: any, merge?: boolean) {
+ setLayout(this: Host, layout: any, merge?: boolean) {
this.dataIndex >= 0
&& this[hostName][dataName].setItemLayout(this.dataIndex, layout, merge);
},
- getLayout: function (this: Host) {
+ getLayout(this: Host) {
return this[hostName][dataName].getItemLayout(this.dataIndex);
},
- getGraphicEl: function (this: Host): Element {
+ getGraphicEl(this: Host): Element {
return this[hostName][dataName].getItemGraphicEl(this.dataIndex);
},
- getRawIndex: function (this: Host) {
+ getRawIndex(this: Host) {
return this[hostName][dataName].getRawIndex(this.dataIndex);
}
};
diff --git a/src/data/List.ts b/src/data/List.ts
index 9297b5e..16777a6 100644
--- a/src/data/List.ts
+++ b/src/data/List.ts
@@ -39,9 +39,11 @@ import {
} from '../util/types';
import {parseDate} from '../util/number';
import {isDataItemOption} from '../util/model';
+import { getECData } from '../util/graphic';
+import { PathStyleProps } from 'zrender/src/graphic/Path';
import type Graph from './Graph';
import type Tree from './Tree';
-import { getECData } from '../util/graphic';
+import type { VisualMeta } from '../component/visualMap/VisualMapModel';
const isObject = zrUtil.isObject;
@@ -77,7 +79,6 @@ type DataTypedArrayConstructor = typeof Uint32Array | typeof Int32Array | typeof
type DataArrayLikeConstructor = typeof Array | DataTypedArrayConstructor;
-
type DimValueGetter = (
this: List,
dataItem: any,
@@ -112,7 +113,6 @@ type MapCb2<Ctx> = (this: CtxOrList<Ctx>, x: ParsedValue, y: ParsedValue, idx: n
type MapCb<Ctx> = (this: CtxOrList<Ctx>, ...args: any) => ParsedValue | ParsedValue[];
-
const TRANSFERABLE_PROPERTIES = [
'hasItemOption', '_nameList', '_idList', '_invertedIndicesMap',
'_rawData', '_chunkSize', '_chunkCount', '_dimValueGetter',
@@ -122,8 +122,29 @@ const CLONE_PROPERTIES = [
'_extent', '_approximateExtent', '_rawExtent'
];
+export interface DefaultDataVisual {
+ style: PathStyleProps
+ // Brush type determined which prop should be set with encoded color.
+ // It's only available on the global visual. Use getVisual('brushType') to access it.
+ // It will be set in visual/style.ts module in the first priority.
+ brushType: 'fill' | 'stroke'
+
+ symbol?: string
+ symbolSize?: number | number[]
+ symbolKeepAspect?: boolean
+
+ liftZ?: number
+ // For legend.
+ legendSymbol?: string
+
+ // visualMap will inject visualMeta data
+ visualMeta?: VisualMeta[]
+}
-class List<HostModel extends Model = Model> {
+class List<
+ HostModel extends Model = Model,
+ Visual extends DefaultDataVisual = DefaultDataVisual
+> {
readonly type = 'list';
@@ -168,10 +189,6 @@ class List<HostModel extends Model = Model> {
// Item visual properties after visual coding
private _itemVisuals: Dictionary<any>[] = [];
- // Key: visual type, Value: boolean
- // @readonly
- hasItemVisual: Dictionary<boolean> = {};
-
// Item layout properties after layout
private _itemLayouts: any[] = [];
@@ -1596,8 +1613,8 @@ class List<HostModel extends Model = Model> {
/**
* Get visual property.
*/
- getVisual(key: string): any {
- const visual = this._visual;
+ getVisual<K extends keyof Visual>(key: K): Visual[K] {
+ const visual = this._visual as Visual;
return visual && visual[key];
}
@@ -1610,19 +1627,94 @@ class List<HostModel extends Model = Model> {
* 'color': color
* });
*/
- setVisual(key: string, val: any): void;
- setVisual(kvObj: Dictionary<any>): void;
- setVisual(key: string | Dictionary<any>, val?: any): void {
- if (isObject(key)) {
- for (const name in key) {
- if (key.hasOwnProperty(name)) {
- this.setVisual(name, key[name]);
- }
+ 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;
+ }
+
+ /**
+ * Make sure itemVisual property is unique
+ */
+ // TODO: use key to save visual to reduce memory.
+ // eslint-disable-next-line
+ 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) {
+ val = this.getVisual(key);
+
+ // TODO Performance?
+ if (zrUtil.isArray(val)) {
+ val = val.slice() as unknown as Visual[K];
}
- return;
+ else if (isObject(val)) {
+ val = zrUtil.extend({}, val);
+ }
+
+ itemVisual[key] = val;
}
- this._visual = this._visual || {};
- this._visual[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 = [];
}
/**
@@ -1677,61 +1769,6 @@ class List<HostModel extends Model = Model> {
}
/**
- * Get visual property of single data item
- */
- getItemVisual(idx: number, key: string, ignoreParent?: boolean): any {
- const itemVisual = this._itemVisuals[idx];
- const val = itemVisual && itemVisual[key];
- if (val == null && !ignoreParent) {
- // Use global visual property
- return this.getVisual(key);
- }
- 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
- * });
- */
- setItemVisual(idx: number, key: string, value: any): void;
- setItemVisual(idx: number, kvObject: Dictionary<any>): void;
- setItemVisual(idx: number, key: string | Dictionary<any>, value?: any): void {
- const itemVisual = this._itemVisuals[idx] || {};
- const hasItemVisual = this.hasItemVisual;
- this._itemVisuals[idx] = itemVisual;
-
- if (isObject(key)) {
- for (const name in key) {
- if (key.hasOwnProperty(name)) {
- itemVisual[name] = key[name];
- hasItemVisual[name] = true;
- }
- }
- return;
- }
- itemVisual[key] = value;
- hasItemVisual[key] = true;
- }
-
- /**
- * Clear itemVisuals and list visual.
- */
- clearAllVisual(): void {
- this._visual = {};
- this._itemVisuals = [];
- this.hasItemVisual = {};
- }
-
- /**
* Set graphic element relative to data. It can be set as null
*/
setItemGraphicEl(idx: number, el: Element): void {
diff --git a/src/data/Tree.ts b/src/data/Tree.ts
index 255d757..8152ff9 100644
--- a/src/data/Tree.ts
+++ b/src/data/Tree.ts
@@ -239,18 +239,19 @@ export class TreeNode {
* 'color': color
* });
*/
+ // TODO: TYPE
setVisual(key: string, value: any): void
setVisual(obj: Dictionary<any>): void
setVisual(key: string | Dictionary<any>, value?: any) {
this.dataIndex >= 0
- && this.hostTree.data.setItemVisual(this.dataIndex, key as string, value);
+ && this.hostTree.data.setItemVisual(this.dataIndex, key as any, value);
}
/**
* Get item visual
*/
- getVisual(key: string, ignoreParent?: boolean): any {
- return this.hostTree.data.getItemVisual(this.dataIndex, key, ignoreParent);
+ getVisual(key: string): any {
+ return this.hostTree.data.getItemVisual(this.dataIndex, key as any);
}
getRawIndex(): number {
diff --git a/src/echarts.ts b/src/echarts.ts
index ff4709e..6a4c646 100644
--- a/src/echarts.ts
+++ b/src/echarts.ts
@@ -40,7 +40,7 @@ import ChartView, {ChartViewConstructor} from './view/Chart';
import * as graphic from './util/graphic';
import * as modelUtil from './util/model';
import {throttle} from './util/throttle';
-import seriesColor from './visual/seriesColor';
+import {seriesStyleTask, dataStyleTask} from './visual/style';
import aria from './visual/aria';
import loadingDefault from './loading/default';
import Scheduler from './stream/Scheduler';
@@ -69,6 +69,8 @@ import IncrementalDisplayable from 'zrender/src/graphic/IncrementalDisplayable';
// At least canvas renderer.
import 'zrender/src/canvas/canvas';
+import { seriesSymbolTask, dataSymbolTask } from './visual/symbol';
+import { getVisualFromData, getItemVisualFromData } from './visual/helper';
declare let global: any;
type ModelFinder = modelUtil.ModelFinder;
@@ -97,6 +99,7 @@ const PRIORITY_VISUAL_GLOBAL = 2000;
const PRIORITY_VISUAL_CHART = 3000;
const PRIORITY_VISUAL_POST_CHART_LAYOUT = 3500;
const PRIORITY_VISUAL_COMPONENT = 4000;
+const PRIORITY_VISUAL_CHART_DATA_CUSTOM = 4500; // visual property in data
// FIXME
// necessary?
const PRIORITY_VISUAL_BRUSH = 5000;
@@ -114,7 +117,8 @@ export const PRIORITY = {
CHART: PRIORITY_VISUAL_CHART,
POST_CHART_LAYOUT: PRIORITY_VISUAL_POST_CHART_LAYOUT,
COMPONENT: PRIORITY_VISUAL_COMPONENT,
- BRUSH: PRIORITY_VISUAL_BRUSH
+ BRUSH: PRIORITY_VISUAL_BRUSH,
+ CHART_ITEM: PRIORITY_VISUAL_CHART_DATA_CUSTOM
}
};
@@ -745,8 +749,8 @@ class ECharts extends Eventful {
: null;
return dataIndexInside != null
- ? data.getItemVisual(dataIndexInside, visualType)
- : data.getVisual(visualType);
+ ? getItemVisualFromData(data, dataIndexInside, visualType)
+ : getVisualFromData(data, visualType);
}
/**
@@ -1292,7 +1296,6 @@ class ECharts extends Eventful {
updateTransform: function (this: ECharts, payload: Payload): void {
const ecModel = this._model;
- const ecIns = this;
const api = this._api;
// update before setOption
@@ -1303,8 +1306,8 @@ class ECharts extends Eventful {
// ChartView.markUpdateMethod(payload, 'updateTransform');
const componentDirtyList = [];
- ecModel.eachComponent(function (componentType, componentModel) {
- const componentView = ecIns.getViewOfComponentModel(componentModel);
+ ecModel.eachComponent((componentType, componentModel) => {
+ const componentView = this.getViewOfComponentModel(componentModel);
if (componentView && componentView.__alive) {
if (componentView.updateTransform) {
const result = componentView.updateTransform(componentModel, ecModel, api, payload);
@@ -1317,8 +1320,8 @@ class ECharts extends Eventful {
});
const seriesDirtyMap = zrUtil.createHashMap();
- ecModel.eachSeries(function (seriesModel) {
- const chartView = ecIns._chartsMap[seriesModel.__viewId];
+ ecModel.eachSeries((seriesModel) => {
+ const chartView = this._chartsMap[seriesModel.__viewId];
if (chartView.updateTransform) {
const result = chartView.updateTransform(seriesModel, ecModel, api, payload);
result && result.update && seriesDirtyMap.set(seriesModel.uid, 1);
@@ -1337,7 +1340,7 @@ class ECharts extends Eventful {
// Currently, not call render of components. Geo render cost a lot.
// renderComponents(ecIns, ecModel, api, payload, componentDirtyList);
- renderSeries(ecIns, ecModel, api, payload, seriesDirtyMap);
+ renderSeries(this, ecModel, api, payload, seriesDirtyMap);
performPostUpdateFuncs(ecModel, this._api);
},
@@ -1363,25 +1366,40 @@ class ECharts extends Eventful {
},
updateVisual: function (this: ECharts, payload: Payload): void {
- updateMethods.update.call(this, payload);
+ // updateMethods.update.call(this, payload);
- // let ecModel = this._model;
+ const ecModel = this._model;
- // // update before setOption
- // if (!ecModel) {
- // return;
- // }
+ // update before setOption
+ if (!ecModel) {
+ return;
+ }
- // ChartView.markUpdateMethod(payload, 'updateVisual');
+ // clear all visual
+ ecModel.eachSeries(function (seriesModel) {
+ seriesModel.getData().clearAllVisual();
+ });
- // clearColorPalette(ecModel);
+ // Perform visual
+ ChartView.markUpdateMethod(payload, 'updateVisual');
- // // Keep pipe to the exist pipeline because it depends on the render task of the full pipeline.
- // this._scheduler.performVisualTasks(ecModel, payload, {visualType: 'visual', setDirty: true});
+ clearColorPalette(ecModel);
- // render(this, this._model, this._api, payload);
+ // Keep pipe to the exist pipeline because it depends on the render task of the full pipeline.
+ this._scheduler.performVisualTasks(ecModel, payload, {visualType: 'visual', setDirty: true});
- // performPostUpdateFuncs(ecModel, this._api);
+ ecModel.eachComponent((componentType, componentModel) => { // TODO componentType may be series.
+ const componentView = this.getViewOfComponentModel(componentModel);
+ componentView && componentView.__alive
+ && componentView.updateVisual(componentModel, ecModel, this._api, payload);
+ });
+
+ ecModel.eachSeries((seriesModel) => {
+ const chartView = this._chartsMap[seriesModel.__viewId];
+ chartView.updateVisual(seriesModel, ecModel, this._api, payload);
+ });
+
+ performPostUpdateFuncs(ecModel, this._api);
},
updateLayout: function (this: ECharts, payload: Payload): void {
@@ -2323,7 +2341,13 @@ export function getMap(mapName: string) {
-registerVisual(PRIORITY_VISUAL_GLOBAL, seriesColor);
+// Buitlin global visual
+registerVisual(PRIORITY_VISUAL_GLOBAL, seriesStyleTask);
+registerVisual(PRIORITY_VISUAL_CHART_DATA_CUSTOM, dataStyleTask);
+
+registerVisual(PRIORITY_VISUAL_GLOBAL, seriesSymbolTask);
+registerVisual(PRIORITY_VISUAL_CHART_DATA_CUSTOM, dataSymbolTask);
+
registerPreprocessor(backwardCompat);
registerProcessor(PRIORITY_PROCESSOR_DATASTACK, dataStack);
registerLoading('default', loadingDefault);
diff --git a/src/model/Model.ts b/src/model/Model.ts
index 7dd5e93..5f7d787 100644
--- a/src/model/Model.ts
+++ b/src/model/Model.ts
@@ -132,8 +132,8 @@ class Model<Opt extends ModelOption = ModelOption> { // TODO: TYPE use unkown
const option = this.option;
let val = option == null ? option : option[key];
- if (val == null) {
- const parentModel = !ignoreParent && getParent(this, key as string);
+ if (val == null && !ignoreParent) {
+ const parentModel = getParent(this, key as string);
if (parentModel) {
// FIXME:TS do not know how to make it works
val = parentModel.getShallow(key);
diff --git a/src/model/Series.ts b/src/model/Series.ts
index 9c898df..e370663 100644
--- a/src/model/Series.ts
+++ b/src/model/Series.ts
@@ -57,6 +57,7 @@ import Source from '../data/Source';
import Axis from '../coord/Axis';
import { GradientObject } from 'zrender/src/graphic/Gradient';
import type { BrushCommonSelectorsForSeries, BrushSelectableArea } from '../component/brush/selector';
+import makeStyleMapper from './mixin/makeStyleMapper';
const inner = modelUtil.makeInner<{
data: List
@@ -131,14 +132,30 @@ class SeriesModel<Opt extends SeriesOption = SeriesOption> extends ComponentMode
// Injected outside
pipelineContext: PipelineContext;
+
+ // ---------------------------------------
+ // Props to tell echarts about how to do visual encoding.
+ // ---------------------------------------
// legend visual provider to the legend component
legendVisualProvider: LegendVisualProvider;
- // Access path of color for visual
- visualColorAccessPath: string[];
-
- // Access path of borderColor for visual
- visualBorderColorAccessPath: string[];
+ // Access path of style for visual
+ visualStyleAccessPath: string;
+ // Which property is treated as main color. Which can get from the palette.
+ visualColorBrushType: 'fill' | 'stroke';
+ // Style mapping rules.
+ visualStyleMapper: ReturnType<typeof makeStyleMapper>;
+ // If ignore style on data. It's only for global visual/style.ts
+ // Perhaps series it self will handle it.
+ ignoreStyleOnData: boolean;
+ // If use palette on each data.
+ useColorPaletteOnData: boolean;
+ // If do symbol visual encoding
+ hasSymbolVisual: boolean;
+ // Default symbol type.
+ defaultSymbol: string;
+ // Symbol provide to legend.
+ legendSymbol: string;
readonly preventUsingHoverLayer: boolean;
@@ -146,8 +163,13 @@ class SeriesModel<Opt extends SeriesOption = SeriesOption> extends ComponentMode
const proto = SeriesModel.prototype;
proto.type = 'series.__base__';
proto.seriesIndex = 0;
- proto.visualColorAccessPath = ['itemStyle', 'color'];
- proto.visualBorderColorAccessPath = ['itemStyle', 'borderColor'];
+ proto.useColorPaletteOnData = false;
+ proto.ignoreStyleOnData = false;
+ proto.hasSymbolVisual = false;
+ proto.defaultSymbol = 'circle';
+ // Make sure the values can be accessed!
+ proto.visualStyleAccessPath = 'itemStyle';
+ proto.visualColorBrushType = 'fill';
})();
@@ -458,7 +480,8 @@ class SeriesModel<Opt extends SeriesOption = SeriesOption> extends ComponentMode
const value = this.getRawValue(dataIndex) as any;
const isValueArr = zrUtil.isArray(value);
- const color = data.getItemVisual(dataIndex, 'color') as ZRColor;
+ const style = data.getItemVisual(dataIndex, 'style');
+ const color = style[this.visualColorBrushType];
let colorStr: ColorString;
if (zrUtil.isString(color)) {
colorStr = color;
@@ -563,7 +586,6 @@ class SeriesModel<Opt extends SeriesOption = SeriesOption> extends ComponentMode
return this.get('progressiveThreshold');
}
-
// /**
// * @see {module:echarts/stream/Scheduler}
// */
diff --git a/src/model/mixin/areaStyle.ts b/src/model/mixin/areaStyle.ts
index 309593a..2227dac 100644
--- a/src/model/mixin/areaStyle.ts
+++ b/src/model/mixin/areaStyle.ts
@@ -22,14 +22,15 @@ import Model from '../Model';
import { AreaStyleOption } from '../../util/types';
import { PathStyleProps } from 'zrender/src/graphic/Path';
-const getAreaStyle = makeStyleMapper([
+export const AREA_STYLE_KEY_MAP = [
['fill', 'color'],
['shadowBlur'],
['shadowOffsetX'],
['shadowOffsetY'],
['opacity'],
['shadowColor']
-]);
+];
+const getAreaStyle = makeStyleMapper(AREA_STYLE_KEY_MAP);
type AreaStyleProps = Pick<PathStyleProps,
'fill'
diff --git a/src/model/mixin/dataFormat.ts b/src/model/mixin/dataFormat.ts
index a0f2c72..475a419 100644
--- a/src/model/mixin/dataFormat.ts
+++ b/src/model/mixin/dataFormat.ts
@@ -20,7 +20,7 @@
import {retrieveRawValue} from '../../data/helper/dataProvider';
import {getTooltipMarker, formatTpl} from '../../util/format';
import { getTooltipRenderMode } from '../../util/model';
-import { DataHost, DisplayState, TooltipRenderMode, CallbackDataParams } from '../../util/types';
+import { DataHost, DisplayState, TooltipRenderMode, CallbackDataParams, ColorString } from '../../util/types';
import GlobalModel from '../Global';
import Element from 'zrender/src/Element';
@@ -52,8 +52,9 @@ class DataFormatMixin {
const rawDataIndex = data.getRawIndex(dataIndex);
const name = data.getName(dataIndex);
const itemOpt = data.getRawDataItem(dataIndex);
- const color = data.getItemVisual(dataIndex, 'color');
- const borderColor = data.getItemVisual(dataIndex, 'borderColor');
+ const style = data.getItemVisual(dataIndex, 'style');
+ const color = style && style.fill as ColorString;
+ const borderColor = style && style.stroke as ColorString;
const tooltipModel = this.ecModel.getComponent('tooltip');
// @ts-ignore FIXME:TooltipModel
const renderModeOption = tooltipModel && tooltipModel.get('renderMode');
diff --git a/src/model/mixin/itemStyle.ts b/src/model/mixin/itemStyle.ts
index 15a7e80..c0c88e0 100644
--- a/src/model/mixin/itemStyle.ts
+++ b/src/model/mixin/itemStyle.ts
@@ -22,7 +22,7 @@ import Model from '../Model';
import { ItemStyleOption } from '../../util/types';
import { PathStyleProps } from 'zrender/src/graphic/Path';
-const getItemStyle = makeStyleMapper([
+export const ITEM_STYLE_KEY_MAP = [
['fill', 'color'],
['stroke', 'borderColor'],
['lineWidth', 'borderWidth'],
@@ -31,7 +31,9 @@ const getItemStyle = makeStyleMapper([
['shadowOffsetX'],
['shadowOffsetY'],
['shadowColor']
-]);
+];
+
+const getItemStyle = makeStyleMapper(ITEM_STYLE_KEY_MAP);
type ItemStyleKeys = 'fill'
| 'stroke'
diff --git a/src/model/mixin/lineStyle.ts b/src/model/mixin/lineStyle.ts
index 075c1a6..88512de 100644
--- a/src/model/mixin/lineStyle.ts
+++ b/src/model/mixin/lineStyle.ts
@@ -22,7 +22,7 @@ import Model from '../Model';
import { LineStyleOption } from '../../util/types';
import { PathStyleProps } from 'zrender/src/graphic/Path';
-const getLineStyle = makeStyleMapper([
+export const LINE_STYLE_KEY_MAP = [
['lineWidth', 'width'],
['stroke', 'color'],
['opacity'],
@@ -30,7 +30,9 @@ const getLineStyle = makeStyleMapper([
['shadowOffsetX'],
['shadowOffsetY'],
['shadowColor']
-]);
+];
+
+const getLineStyle = makeStyleMapper(LINE_STYLE_KEY_MAP);
type LineStyleKeys = 'lineWidth'
| 'stroke'
diff --git a/src/model/mixin/makeStyleMapper.ts b/src/model/mixin/makeStyleMapper.ts
index 0fced21..e08e42a 100644
--- a/src/model/mixin/makeStyleMapper.ts
+++ b/src/model/mixin/makeStyleMapper.ts
@@ -22,14 +22,18 @@
import * as zrUtil from 'zrender/src/core/util';
import Model from '../Model';
import { Dictionary } from 'zrender/src/core/types';
+import { PathStyleProps } from 'zrender/src/graphic/Path';
-export default function (properties: readonly string[][]) {
+export default function (properties: readonly string[][], ignoreParent?: boolean) {
// Normalize
for (let i = 0; i < properties.length; i++) {
if (!properties[i][1]) {
properties[i][1] = properties[i][0];
}
}
+
+ ignoreParent = ignoreParent || false;
+
return function (model: Model, excludes?: readonly string[], includes?: readonly string[]) {
const style: Dictionary<any> = {};
for (let i = 0; i < properties.length; i++) {
@@ -39,11 +43,12 @@ export default function (properties: readonly string[][]) {
) {
continue;
}
- const val = model.getShallow(propName);
+ const val = model.getShallow(propName, ignoreParent);
if (val != null) {
style[properties[i][0]] = val;
}
}
- return style;
+ // TODO Text or image?
+ return style as PathStyleProps;
};
}
\ No newline at end of file
diff --git a/src/util/graphic.ts b/src/util/graphic.ts
index 311f883..1b9540e 100644
--- a/src/util/graphic.ts
+++ b/src/util/graphic.ts
@@ -62,7 +62,16 @@ import {
} from './types';
import GlobalModel from '../model/Global';
import { makeInner } from './model';
-import { isFunction, retrieve2, extend, keys, trim, isArrayLike, map, defaults } from 'zrender/src/core/util';
+import {
+ isFunction,
+ retrieve2,
+ extend,
+ keys,
+ trim,
+ isArrayLike,
+ map,
+ defaults
+} from 'zrender/src/core/util';
const mathMax = Math.max;
@@ -97,7 +106,7 @@ type ExtendedProps = {
__highByOuter: number
__highDownSilentOnTouch: boolean
- __highDownOnUpdate: (fromState: DisplayState, toState: DisplayState) => void
+ __onStateChange: (fromState: DisplayState, toState: DisplayState) => void
__highDownDispatcher: boolean
};
@@ -367,17 +376,24 @@ function singleEnterEmphasis(el: Element) {
return;
}
const disp = el as Displayable;
- const emphasisStyle = disp.states.emphasis.style;
- const currentFill = disp.style && disp.style.fill;
- const currentStroke = disp.style && disp.style.stroke;
+
+ let emphasisStyle;
+ let currentFill;
+ let currentStroke;
+ // state may be a function
+ if (!(typeof disp.states.emphasis === 'function')) {
+ emphasisStyle = disp.states.emphasis.style;
+ currentFill = disp.style && disp.style.fill;
+ currentStroke = disp.style && disp.style.stroke;
+ }
el.useState('emphasis');
- if (disp.style) { // Is not group
- if (emphasisStyle && !hasFillOrStroke(emphasisStyle.fill)) {
+ if (emphasisStyle && (currentFill || currentStroke)) {
+ if (!hasFillOrStroke(emphasisStyle.fill)) {
disp.style.fill = liftColor(currentFill);
}
- if (emphasisStyle && !hasFillOrStroke(emphasisStyle.stroke)) {
+ if (!hasFillOrStroke(emphasisStyle.stroke)) {
disp.style.stroke = liftColor(currentStroke);
}
disp.z2 += Z2_EMPHASIS_LIFT;
@@ -393,29 +409,51 @@ function singleEnterEmphasis(el: Element) {
function singleEnterNormal(el: Element) {
el.clearStates();
-
(el as ExtendedElement).__highlighted = false;
}
-function traverseUpdate<T>(
+function updateElementState<T>(
el: ExtendedElement,
updater: (this: void, el: Element, commonParam?: T) => void,
commonParam?: T
) {
- // If root is group, also enter updater for `highDownOnUpdate`.
+ // If root is group, also enter updater for `onStateChange`.
let fromState: DisplayState = NORMAL;
let toState: DisplayState = NORMAL;
let trigger;
- // See the rule of `highDownOnUpdate` on `graphic.setAsHighDownDispatcher`.
+ // See the rule of `onStateChange` on `graphic.setAsHighDownDispatcher`.
el.__highlighted && (fromState = EMPHASIS, trigger = true);
updater(el, commonParam);
el.__highlighted && (toState = EMPHASIS, trigger = true);
+ trigger && el.__onStateChange && el.__onStateChange(fromState, toState);
+}
- el.isGroup && el.traverse(function (child) {
- !child.isGroup && updater(child, commonParam);
+function traverseUpdateState<T>(
+ el: ExtendedElement,
+ updater: (this: void, el: Element, commonParam?: T) => void,
+ commonParam?: T
+) {
+ updateElementState(el, updater, commonParam);
+ el.isGroup && el.traverse(function (child: ExtendedElement) {
+ updateElementState(child, updater, commonParam);
});
- trigger && el.__highDownOnUpdate && el.__highDownOnUpdate(fromState, toState);
+}
+
+/**
+ * If we reuse elements when rerender.
+ * DONT forget to clearStates before we update the style and shape.
+ * Or we may update on the wrong state instead of normal state.
+ */
+export function clearStates(el: Element) {
+ if (el.isGroup) {
+ el.traverse(function (child) {
+ child.clearStates();
+ });
+ }
+ else {
+ el.clearStates();
+ }
}
/**
@@ -444,24 +482,24 @@ export function enterEmphasisWhenMouseOver(el: Element, e: ElementEvent) {
!shouldSilent(el, e)
// "emphasis" event highlight has higher priority than mouse highlight.
&& !(el as ExtendedElement).__highByOuter
- && traverseUpdate((el as ExtendedElement), singleEnterEmphasis);
+ && traverseUpdateState((el as ExtendedElement), singleEnterEmphasis);
}
export function leaveEmphasisWhenMouseOut(el: Element, e: ElementEvent) {
!shouldSilent(el, e)
// "emphasis" event highlight has higher priority than mouse highlight.
&& !(el as ExtendedElement).__highByOuter
- && traverseUpdate((el as ExtendedElement), singleEnterNormal);
+ && traverseUpdateState((el as ExtendedElement), singleEnterNormal);
}
export function enterEmphasis(el: Element, highlightDigit?: number) {
(el as ExtendedElement).__highByOuter |= 1 << (highlightDigit || 0);
- traverseUpdate((el as ExtendedElement), singleEnterEmphasis);
+ traverseUpdateState((el as ExtendedElement), singleEnterEmphasis);
}
export function leaveEmphasis(el: Element, highlightDigit?: number) {
!((el as ExtendedElement).__highByOuter &= ~(1 << (highlightDigit || 0)))
- && traverseUpdate((el as ExtendedElement), singleEnterNormal);
+ && traverseUpdateState((el as ExtendedElement), singleEnterNormal);
}
function shouldSilent(el: Element, e: ElementEvent) {
@@ -485,14 +523,14 @@ function shouldSilent(el: Element, e: ElementEvent) {
*/
export function enableHoverEmphasis(el: Element, hoverStyle?: ZRStyleProps) {
setAsHighDownDispatcher(el, true);
- traverseUpdate(el as ExtendedElement, enableElementHoverEmphasis, hoverStyle);
+ traverseUpdateState(el as ExtendedElement, enableElementHoverEmphasis, hoverStyle);
}
/**
* @param {module:zrender/Element} el
- * @param {Function} [el.highDownOnUpdate] Called when state updated.
+ * @param {Function} [el.onStateChange] Called when state updated.
* Since `setHoverStyle` has the constraint that it must be called after
- * all of the normal style updated, `highDownOnUpdate` is not needed to
+ * all of the normal style updated, `onStateChange` is not needed to
* trigger if both `fromState` and `toState` is 'normal', and needed to
* trigger if both `fromState` and `toState` is 'emphasis', which enables
* to sync outside style settings to "emphasis" state.
@@ -504,7 +542,7 @@ export function enableHoverEmphasis(el: Element, hoverStyle?: ZRStyleProps) {
* @param {string} toState Can be "normal" or "emphasis".
*
* FIXME
- * CAUTION: Do not expose `highDownOnUpdate` outside echarts.
+ * CAUTION: Do not expose `onStateChange` outside echarts.
* Because it is not a complete solution. The update
* listener should not have been mount in element,
* and the normal/emphasis state should not have
@@ -525,13 +563,13 @@ export function enableHoverEmphasis(el: Element, hoverStyle?: ZRStyleProps) {
export function setAsHighDownDispatcher(el: Element, asDispatcher: boolean) {
const disable = asDispatcher === false;
const extendedEl = el as ExtendedElement;
- // Make `highDownSilentOnTouch` and `highDownOnUpdate` only work after
+ // Make `highDownSilentOnTouch` and `onStateChange` only work after
// `setAsHighDownDispatcher` called. Avoid it is modified by user unexpectedly.
if ((el as ECElement).highDownSilentOnTouch) {
extendedEl.__highDownSilentOnTouch = (el as ECElement).highDownSilentOnTouch;
}
- if ((el as ECElement).highDownOnUpdate) {
- extendedEl.__highDownOnUpdate = (el as ECElement).highDownOnUpdate;
+ if ((el as ECElement).onStateChange) {
+ extendedEl.__onStateChange = (el as ECElement).onStateChange;
}
// Simple optimize, since this method might be
@@ -606,10 +644,6 @@ export function setLabelStyle<LDI>(
) {
opt = opt || EMPTY_OBJ;
const isSetOnText = targetEl instanceof ZRText;
- const labelFetcher = opt.labelFetcher;
- const labelDataIndex = opt.labelDataIndex;
- const labelDimIndex = opt.labelDimIndex;
-
// This scenario, `label.normal.show = true; label.emphasis.show = false`,
// is not supported util someone requests.
@@ -619,26 +653,27 @@ export function setLabelStyle<LDI>(
// Consider performance, only fetch label when necessary.
// If `normal.show` is `false` and `emphasis.show` is `true` and `emphasis.formatter` is not set,
// label should be displayed, where text is fetched by `normal.formatter` or `opt.defaultText`.
- let baseText;
+ let richText = isSetOnText ? targetEl as ZRText : null;
if (showNormal || showEmphasis) {
+ const labelFetcher = opt.labelFetcher;
+ const labelDataIndex = opt.labelDataIndex;
+ const labelDimIndex = opt.labelDimIndex;
+
+ let baseText;
if (labelFetcher) {
baseText = labelFetcher.getFormattedLabel(labelDataIndex, 'normal', null, labelDimIndex);
}
if (baseText == null) {
baseText = isFunction(opt.defaultText) ? opt.defaultText(labelDataIndex, opt) : opt.defaultText;
}
- }
- const normalStyleText = baseText;
- const emphasisStyleText = retrieve2(
- labelFetcher
- ? labelFetcher.getFormattedLabel(labelDataIndex, 'emphasis', null, labelDimIndex)
- : null,
- baseText
- );
+ const normalStyleText = baseText;
+ const emphasisStyleText = retrieve2(
+ labelFetcher
+ ? labelFetcher.getFormattedLabel(labelDataIndex, 'emphasis', null, labelDimIndex)
+ : null,
+ baseText
+ );
- let richText = isSetOnText ? targetEl as ZRText : null;
- // Optimize: If style.text is null, text will not be drawn.
- if (showNormal || showEmphasis) {
if (!isSetOnText) {
// Reuse the previous
richText = targetEl.getTextContent();
@@ -1414,4 +1449,4 @@ export {
RadialGradient,
BoundingRect,
Path
-};
+};
\ No newline at end of file
diff --git a/src/util/symbol.ts b/src/util/symbol.ts
index 011ec0e..a0bedde 100644
--- a/src/util/symbol.ts
+++ b/src/util/symbol.ts
@@ -29,6 +29,7 @@ import { ZRColor } from './types';
type ECSymbol = graphic.Path & {
__isEmptyBrush?: boolean
setColor: (color: ZRColor, innerColor?: string) => void
+ getColor: () => ZRColor
};
type SymbolCtor = { new(): ECSymbol };
type SymbolShapeMaker = (x: number, y: number, w: number, h: number, shape: Dictionary<any>) => void;
@@ -171,10 +172,11 @@ const Arrow = graphic.Path.extend({
/**
* Map of path contructors
*/
+// TODO Use function to build symbol path.
const symbolCtors: Dictionary<SymbolCtor> = {
-
- // TODO
- line: graphic.Line as unknown as SymbolCtor,
+ // Use small height rect to simulate line.
+ // Avoid using stroke.
+ line: graphic.Rect as unknown as SymbolCtor,
rect: graphic.Rect as unknown as SymbolCtor,
@@ -194,14 +196,16 @@ const symbolCtors: Dictionary<SymbolCtor> = {
};
+// NOTICE Only use fill. No line!
const symbolShapeMakers: Dictionary<SymbolShapeMaker> = {
- line: function (x, y, w, h, shape: graphic.Line['shape']) {
- // FIXME
- shape.x1 = x;
- shape.y1 = y + h / 2;
- shape.x2 = x + w;
- shape.y2 = y + h / 2;
+ line: function (x, y, w, h, shape: graphic.Rect['shape']) {
+ const thickness = 2;
+ // A thin line
+ shape.x = x;
+ shape.y = y + h / 2 - thickness / 2;
+ shape.width = w;
+ shape.height = thickness;
},
rect: function (x, y, w, h, shape: graphic.Rect['shape']) {
@@ -310,18 +314,14 @@ const SymbolClz = graphic.Path.extend({
function symbolPathSetColor(this: ECSymbol, color: ZRColor, innerColor?: string) {
if (this.type !== 'image') {
const symbolStyle = this.style;
- const symbolShape = this.shape;
- if (symbolShape && symbolShape.symbolType === 'line') {
- symbolStyle.stroke = color;
- }
- else if (this.__isEmptyBrush) {
+ if (this.__isEmptyBrush) {
symbolStyle.stroke = color;
symbolStyle.fill = innerColor || '#fff';
+ // TODO Same width with lineStyle in LineView.
+ symbolStyle.lineWidth = 2;
}
else {
- // FIXME 判断图形默认是填充还是描边,使用 onlyStroke ?
- symbolStyle.fill && (symbolStyle.fill = color);
- symbolStyle.stroke && (symbolStyle.stroke = color);
+ symbolStyle.fill = color;
}
this.markRedraw();
}
@@ -377,9 +377,12 @@ export function createSymbol(
(symbolPath as ECSymbol).__isEmptyBrush = isEmpty;
+ // TODO Should deprecate setColor
(symbolPath as ECSymbol).setColor = symbolPathSetColor;
- (symbolPath as ECSymbol).setColor(color);
+ if (color) {
+ (symbolPath as ECSymbol).setColor(color);
+ }
return symbolPath as ECSymbol;
}
diff --git a/src/util/types.ts b/src/util/types.ts
index 4e4ea3c..0503ec8 100644
--- a/src/util/types.ts
+++ b/src/util/types.ts
@@ -105,7 +105,7 @@ export interface ECElement extends Element {
formatterParams?: unknown;
};
highDownSilentOnTouch?: boolean;
- highDownOnUpdate?: (fromState: 'normal' | 'emphasis', toState: 'normal' | 'emphasis') => void;
+ onStateChange?: (fromState: 'normal' | 'emphasis', toState: 'normal' | 'emphasis') => void;
}
export interface DataHost {
diff --git a/src/view/Chart.ts b/src/view/Chart.ts
index 4813eda..7c00696 100644
--- a/src/view/Chart.ts
+++ b/src/view/Chart.ts
@@ -35,7 +35,6 @@ import {
} from '../util/types';
import { SeriesTaskContext, SeriesTask } from '../stream/Scheduler';
import List from '../data/List';
-import { graphic } from '../export';
const inner = modelUtil.makeInner<{
updateMethod: keyof ChartView
@@ -195,15 +194,6 @@ function elSetState(el: Element, state: DisplayState, highlightDigit: number) {
if (el) {
state === 'emphasis' ? graphicUtil.enterEmphasis(el, highlightDigit)
: graphicUtil.leaveEmphasis(el, highlightDigit);
-
- if (el.isGroup
- // Simple optimize.
- && !graphicUtil.isHighDownDispatcher(el)
- ) {
- for (let i = 0, len = (el as Group).childCount(); i < len; i++) {
- elSetState((el as Group).childAt(i), state, highlightDigit);
- }
- }
}
}
diff --git a/src/visual/LegendVisualProvider.ts b/src/visual/LegendVisualProvider.ts
index ebea252..c62297e 100644
--- a/src/visual/LegendVisualProvider.ts
+++ b/src/visual/LegendVisualProvider.ts
@@ -62,7 +62,7 @@ class LegendVisualProvider {
getItemVisual(dataIndex: number, key: string): any {
// Get encoded visual properties from final filtered data.
const dataWithEncodedVisual = this._getDataWithEncodedVisual();
- return dataWithEncodedVisual.getItemVisual(dataIndex, key);
+ return dataWithEncodedVisual.getItemVisual(dataIndex, key as any);
}
}
diff --git a/src/chart/tree.ts b/src/visual/commonVisualTypes.ts
similarity index 72%
copy from src/chart/tree.ts
copy to src/visual/commonVisualTypes.ts
index e498d25..53647e7 100644
--- a/src/chart/tree.ts
+++ b/src/visual/commonVisualTypes.ts
@@ -17,14 +17,12 @@
* under the License.
*/
-import * as echarts from '../echarts';
+import { DefaultDataVisual } from '../data/List';
-import './tree/TreeSeries';
-import './tree/TreeView';
-import './tree/treeAction';
+export interface LineDataVisual extends DefaultDataVisual {
+ fromSymbol: string
+ toSymbol: string
+ fromSymbolSize: number
+ toSymbolSize: number
+}
-import visualSymbol from '../visual/symbol';
-import treeLayout from './tree/treeLayout';
-
-echarts.registerVisual(visualSymbol('tree', 'circle'));
-echarts.registerLayout(treeLayout);
diff --git a/src/visual/dataColor.ts b/src/visual/dataColor.ts
deleted file mode 100644
index ff3d9e8..0000000
--- a/src/visual/dataColor.ts
+++ /dev/null
@@ -1,95 +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.
-*/
-
-// Pick color from palette for each data item.
-// Applicable for charts that require applying color palette
-// in data level (like pie, funnel, chord).
-import {createHashMap} from 'zrender/src/core/util';
-import { StageHandler, ItemStyleOption } from '../util/types';
-import SeriesModel from '../model/Series';
-
-interface SeriesModelWithPaletteScope extends SeriesModel {
- __paletteScope: any
-}
-
-export default function (seriesType: string): StageHandler {
- return {
- getTargetSeries: function (ecModel) {
- // Pie and funnel may use diferrent scope
- const paletteScope = {};
- const seiresModelMap = createHashMap<SeriesModel>();
-
- ecModel.eachSeriesByType(seriesType, function (seriesModel) {
- (seriesModel as SeriesModelWithPaletteScope).__paletteScope = paletteScope;
- seiresModelMap.set(seriesModel.uid, seriesModel);
- });
-
- return seiresModelMap;
- },
- reset: function (seriesModel) {
- const dataAll = seriesModel.getRawData();
- const idxMap: {[key: number]: number} = {};
- const data = seriesModel.getData();
-
- data.each(function (idx) {
- const rawIdx = data.getRawIndex(idx);
- idxMap[rawIdx] = idx;
- });
-
- dataAll.each(function (rawIdx) {
- const filteredIdx = idxMap[rawIdx];
-
- // If series.itemStyle.normal.color is a function. itemVisual may be encoded
- const singleDataColor = filteredIdx != null
- && data.getItemVisual(filteredIdx, 'color', true);
-
- const singleDataBorderColor = filteredIdx != null
- && data.getItemVisual(filteredIdx, 'borderColor', true);
-
- let itemModel;
- if (!singleDataColor || !singleDataBorderColor) {
- // FIXME Performance
- itemModel = dataAll.getItemModel<{itemStyle: ItemStyleOption}>(rawIdx);
- }
-
- if (!singleDataColor) {
- const color = itemModel.get(['itemStyle', 'color'])
- || seriesModel.getColorFromPalette(
- dataAll.getName(rawIdx) || (rawIdx + ''),
- (seriesModel as SeriesModelWithPaletteScope).__paletteScope,
- dataAll.count()
- );
- // Data is not filtered
- if (filteredIdx != null) {
- data.setItemVisual(filteredIdx, 'color', color);
- }
- }
-
- if (!singleDataBorderColor) {
- const borderColor = itemModel.get(['itemStyle', 'borderColor']);
-
- // Data is not filtered
- if (filteredIdx != null) {
- data.setItemVisual(filteredIdx, 'borderColor', borderColor);
- }
- }
- });
- }
- };
-}
\ No newline at end of file
diff --git a/src/visual/helper.ts b/src/visual/helper.ts
new file mode 100644
index 0000000..affe031
--- /dev/null
+++ b/src/visual/helper.ts
@@ -0,0 +1,87 @@
+/*
+* 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.
+*/
+
+/**
+ * A mapping of visual provided to deverloper and visual stored in the List module.
+ * To developer:
+ * 'color', 'opacity', 'symbol', 'symbolSize'...
+ * In the List module storage:
+ * 'style', 'symbol', 'symbolSize'...
+ */
+import List from '../data/List';
+import { __DEV__ } from '../config';
+
+
+export function getItemVisualFromData(data: List, dataIndex: number, key: string) {
+ switch (key) {
+ case 'color':
+ const style = data.getItemVisual(dataIndex, 'style');
+ return style[data.getVisual('brushType')];
+ case 'opacity':
+ return data.getItemVisual(dataIndex, 'style').opacity;
+ case 'symbol':
+ case 'symbolSize':
+ case 'liftZ':
+ return data.getItemVisual(dataIndex, key);
+ default:
+ if (__DEV__) {
+ console.warn(`Unknown visual type ${key}`);
+ }
+ }
+}
+
+export function getVisualFromData(data: List, key: string) {
+ switch (key) {
+ case 'color':
+ const style = data.getVisual('style');
+ return style[data.getVisual('brushType')];
+ case 'opacity':
+ return data.getVisual('style').opacity;
+ case 'symbol':
+ case 'symbolSize':
+ case 'liftZ':
+ return data.getVisual(key);
+ default:
+ if (__DEV__) {
+ console.warn(`Unknown visual type ${key}`);
+ }
+ }
+}
+
+export function setItemVisualFromData(data: List, dataIndex: number, key: string, value: any) {
+ switch (key) {
+ case 'color':
+ // Make sure not sharing style object.
+ const style = data.ensureUniqueItemVisual(dataIndex, 'style');
+ style[data.getVisual('brushType')] = value;
+ break;
+ case 'opacity':
+ data.ensureUniqueItemVisual(dataIndex, 'style').opacity = value;
+ break;
+ case 'symbol':
+ case 'symbolSize':
+ case 'liftZ':
+ data.setItemVisual(dataIndex, key, value);
+ break;
+ default:
+ if (__DEV__) {
+ console.warn(`Unknown visual type ${key}`);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/visual/seriesColor.ts b/src/visual/seriesColor.ts
deleted file mode 100644
index 0f47e8d..0000000
--- a/src/visual/seriesColor.ts
+++ /dev/null
@@ -1,75 +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.
-*/
-
-import Gradient from 'zrender/src/graphic/Gradient';
-import {isFunction} from 'zrender/src/core/util';
-import { StageHandler } from '../util/types';
-
-const seriesColorTask: StageHandler = {
- createOnAllSeries: true,
- performRawSeries: true,
- reset: function (seriesModel, ecModel) {
- const data = seriesModel.getData();
- const colorAccessPath = seriesModel.visualColorAccessPath
- || ['itemStyle', 'color'];
- // Set in itemStyle
- let color = seriesModel.get(colorAccessPath as any);
- const colorCallback = (isFunction(color) && !(color instanceof Gradient))
- ? color : null;
- // Default color
- if (!color || colorCallback) {
- color = seriesModel.getColorFromPalette(
- // TODO series count changed.
- seriesModel.name, null, ecModel.getSeriesCount()
- );
- }
-
- data.setVisual('color', color);
-
- const borderColorAccessPath = seriesModel.visualBorderColorAccessPath || ['itemStyle', 'borderColor'];
- const borderColor = seriesModel.get(borderColorAccessPath as any);
- data.setVisual('borderColor', borderColor);
-
- // Only visible series has each data be visual encoded
- if (!ecModel.isSeriesFiltered(seriesModel)) {
- if (colorCallback) {
- data.each(function (idx) {
- data.setItemVisual(
- idx, 'color', colorCallback(seriesModel.getDataParams(idx))
- );
- });
- }
-
- return {
- dataEach: data.hasItemOption ? function (data, idx) {
- const itemModel = data.getItemModel(idx);
- const color = itemModel.get(colorAccessPath as any, true);
- const borderColor = itemModel.get(borderColorAccessPath as any, true);
- if (color != null) {
- data.setItemVisual(idx, 'color', color);
- }
- if (borderColor != null) {
- data.setItemVisual(idx, 'borderColor', borderColor);
- }
- } : null
- };
- }
- }
-};
-export default seriesColorTask;
\ No newline at end of file
diff --git a/src/visual/style.ts b/src/visual/style.ts
new file mode 100644
index 0000000..3d66948
--- /dev/null
+++ b/src/visual/style.ts
@@ -0,0 +1,165 @@
+/*
+* 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 { isFunction, extend } from 'zrender/src/core/util';
+import { StageHandler, CallbackDataParams, ZRColor } from '../util/types';
+import makeStyleMapper from '../model/mixin/makeStyleMapper';
+import { ITEM_STYLE_KEY_MAP } from '../model/mixin/itemStyle';
+import { LINE_STYLE_KEY_MAP } from '../model/mixin/lineStyle';
+import SeriesModel from '../model/Series';
+import Model from '../model/Model';
+
+interface SeriesModelWithPaletteScope extends SeriesModel {
+ __paletteScope: any
+}
+
+const defaultStyleMappers = {
+ itemStyle: makeStyleMapper(ITEM_STYLE_KEY_MAP, true),
+ lineStyle: makeStyleMapper(LINE_STYLE_KEY_MAP, true)
+};
+
+const defaultColorKey = {
+ lineStyle: 'stroke',
+ itemStyle: 'fill'
+} as const;
+
+function getStyleMapper(seriesModel: SeriesModel, stylePath: string) {
+ const styleMapper = seriesModel.visualStyleMapper
+ || defaultStyleMappers[stylePath as 'itemStyle' | 'lineStyle'];
+ if (!styleMapper) {
+ console.warn(`Unkown style type '${stylePath}'.`);
+ return defaultStyleMappers.itemStyle;
+ }
+ return styleMapper;
+}
+
+function getDefaultColorKey(seriesModel: SeriesModel, stylePath: string): 'stroke' | 'fill' {
+ // return defaultColorKey[stylePath] ||
+ const colorKey = seriesModel.visualColorBrushType
+ || defaultColorKey[stylePath as 'itemStyle' | 'lineStyle'];
+
+ if (!colorKey) {
+ console.warn(`Unkown style type '${stylePath}'.`);
+ return 'fill';
+ }
+
+ return colorKey;
+}
+
+type ColorCallback = (params: CallbackDataParams) => ZRColor;
+
+const seriesStyleTask: StageHandler = {
+ createOnAllSeries: true,
+ performRawSeries: true,
+ reset(seriesModel, ecModel) {
+ const data = seriesModel.getData();
+ const stylePath = seriesModel.visualStyleAccessPath
+ || 'itemStyle';
+ // Set in itemStyle
+ const styleModel = seriesModel.getModel(stylePath as any);
+ const getStyle = getStyleMapper(seriesModel, stylePath);
+
+ const globalStyle = getStyle(styleModel);
+
+ // TODO
+ const colorKey = getDefaultColorKey(seriesModel, stylePath);
+ const color = globalStyle[colorKey];
+
+ // TODO style callback
+ const colorCallback = isFunction(color) ? color as unknown as ColorCallback : null;
+ // Default
+ if (!globalStyle[colorKey] || colorCallback) { // TODO Better handling on callback
+ globalStyle[colorKey] = seriesModel.getColorFromPalette(
+ // TODO series count changed.
+ seriesModel.name, null, ecModel.getSeriesCount()
+ );
+ }
+
+ data.setVisual('style', globalStyle);
+ data.setVisual('brushType', colorKey);
+
+ // Only visible series has each data be visual encoded
+ if (!ecModel.isSeriesFiltered(seriesModel)) {
+ if (colorCallback) {
+ return {
+ dataEach(data, idx) {
+ data.each(function (idx) {
+ const dataParams = seriesModel.getDataParams(idx);
+ const itemStyle = extend({}, globalStyle);
+ itemStyle[colorKey] = colorCallback(dataParams);
+ });
+ }
+ };
+ }
+ }
+ }
+};
+
+const sharedModel = new Model();
+const dataStyleTask: StageHandler = {
+ createOnAllSeries: true,
+ performRawSeries: true,
+ reset(seriesModel, ecModel) {
+ if (seriesModel.ignoreStyleOnData) {
+ return;
+ }
+
+ const data = seriesModel.getData();
+ const stylePath = seriesModel.visualStyleAccessPath
+ || 'itemStyle';
+ // Set in itemStyle
+ const getStyle = getStyleMapper(seriesModel, stylePath);
+ const colorKey = getDefaultColorKey(seriesModel, stylePath);
+
+ const idxMap: {[key: number]: number} = {};
+ data.each(function (idx) {
+ const rawIdx = data.getRawIndex(idx);
+ idxMap[idx] = rawIdx;
+ });
+
+ return {
+ dataEach: data.hasItemOption ? function (data, idx) {
+ // Not use getItemModel for performance considuration
+ const rawItem = data.getRawDataItem(idx) as any;
+ if (rawItem && rawItem[stylePath]) {
+ sharedModel.option = rawItem[stylePath];
+ const style = getStyle(sharedModel);
+
+ const existsStyle = data.ensureUniqueItemVisual(idx, 'style');
+ extend(existsStyle, style);
+ }
+
+ if (seriesModel.useColorPaletteOnData) {
+ const dataAll = seriesModel.getRawData();
+ const existsStyle = data.ensureUniqueItemVisual(idx, 'style');
+ const rawIdx = idxMap[idx];
+ if (!existsStyle[colorKey]) {
+ // Get color from palette.
+ existsStyle[colorKey] = seriesModel.getColorFromPalette(
+ dataAll.getName(rawIdx) || (rawIdx + ''),
+ (seriesModel as SeriesModelWithPaletteScope).__paletteScope,
+ dataAll.count()
+ );
+ }
+ }
+ } : null
+ };
+ }
+};
+export {seriesStyleTask, dataStyleTask};
\ No newline at end of file
diff --git a/src/visual/symbol.ts b/src/visual/symbol.ts
index 5d3cfe5..444f448 100644
--- a/src/visual/symbol.ts
+++ b/src/visual/symbol.ts
@@ -30,79 +30,111 @@ import List from '../data/List';
import SeriesModel from '../model/Series';
import GlobalModel from '../model/Global';
-export default function (seriesType: string, defaultSymbolType: string, legendSymbol?: string): StageHandler {
- // Encoding visual for all series include which is filtered for legend drawing
- return {
- seriesType: seriesType,
-
- // For legend.
- performRawSeries: true,
-
- reset: function (
- seriesModel: SeriesModel<SeriesOption & SymbolOptionMixin<CallbackDataParams>>,
- ecModel: GlobalModel
- ) {
- const data = seriesModel.getData();
-
- const symbolType = seriesModel.get('symbol');
- const symbolSize = seriesModel.get('symbolSize');
- const keepAspect = seriesModel.get('symbolKeepAspect');
-
- const hasSymbolTypeCallback = isFunction(symbolType);
- const hasSymbolSizeCallback = isFunction(symbolSize);
- const hasCallback = hasSymbolTypeCallback || hasSymbolSizeCallback;
- const seriesSymbol = (!hasSymbolTypeCallback && symbolType) ? symbolType : defaultSymbolType;
- const seriesSymbolSize = !hasSymbolSizeCallback ? symbolSize : null;
-
- data.setVisual({
- legendSymbol: legendSymbol || seriesSymbol,
- // If seting callback functions on `symbol` or `symbolSize`, for simplicity and avoiding
- // to bring trouble, we do not pick a reuslt from one of its calling on data item here,
- // but just use the default value. Callback on `symbol` or `symbolSize` is convenient in
- // some cases but generally it is not recommanded.
- symbol: seriesSymbol,
- symbolSize: seriesSymbolSize,
- symbolKeepAspect: keepAspect
- });
-
- // Only visible series has each data be visual encoded
- if (ecModel.isSeriesFiltered(seriesModel)) {
- return;
- }
+// Encoding visual for all series include which is filtered for legend drawing
+const seriesSymbolTask: StageHandler = {
- function dataEach(data: List, idx: number) {
- if (hasCallback) {
- const rawValue = seriesModel.getRawValue(idx);
- const params = seriesModel.getDataParams(idx);
- hasSymbolTypeCallback && data.setItemVisual(
- idx, 'symbol', (symbolType as SymbolCallback<CallbackDataParams>)(rawValue, params)
- );
- hasSymbolSizeCallback && data.setItemVisual(
- idx, 'symbolSize', (symbolSize as SymbolSizeCallback<CallbackDataParams>)(rawValue, params)
- );
- }
-
- if (data.hasItemOption) {
- const itemModel = data.getItemModel<SymbolOptionMixin>(idx);
- const itemSymbolType = itemModel.getShallow('symbol', true);
- const itemSymbolSize = itemModel.getShallow('symbolSize', true);
- const itemSymbolKeepAspect = itemModel.getShallow('symbolKeepAspect', true);
-
- // If has item symbol
- if (itemSymbolType != null) {
- data.setItemVisual(idx, 'symbol', itemSymbolType);
- }
- if (itemSymbolSize != null) {
- // PENDING Transform symbolSize ?
- data.setItemVisual(idx, 'symbolSize', itemSymbolSize);
- }
- if (itemSymbolKeepAspect != null) {
- data.setItemVisual(idx, 'symbolKeepAspect', itemSymbolKeepAspect);
- }
- }
- }
+ createOnAllSeries: true,
+
+ // For legend.
+ performRawSeries: true,
+
+ reset: function (
+ seriesModel: SeriesModel<SeriesOption & SymbolOptionMixin<CallbackDataParams>>,
+ ecModel: GlobalModel
+ ) {
+ const data = seriesModel.getData();
- return { dataEach: (data.hasItemOption || hasCallback) ? dataEach : null };
+ if (seriesModel.legendSymbol) {
+ data.setVisual('legendSymbol', seriesModel.legendSymbol);
}
- };
-}
+
+ if (!seriesModel.hasSymbolVisual) {
+ return;
+ }
+
+ const symbolType = seriesModel.get('symbol');
+ const symbolSize = seriesModel.get('symbolSize');
+ const keepAspect = seriesModel.get('symbolKeepAspect');
+
+ const hasSymbolTypeCallback = isFunction(symbolType);
+ const hasSymbolSizeCallback = isFunction(symbolSize);
+ const hasCallback = hasSymbolTypeCallback || hasSymbolSizeCallback;
+ const seriesSymbol = (!hasSymbolTypeCallback && symbolType) ? symbolType : seriesModel.defaultSymbol;
+ const seriesSymbolSize = !hasSymbolSizeCallback ? symbolSize : null;
+
+ data.setVisual({
+ legendSymbol: seriesModel.legendSymbol || seriesSymbol as string,
+ // If seting callback functions on `symbol` or `symbolSize`, for simplicity and avoiding
+ // to bring trouble, we do not pick a reuslt from one of its calling on data item here,
+ // but just use the default value. Callback on `symbol` or `symbolSize` is convenient in
+ // some cases but generally it is not recommanded.
+ symbol: seriesSymbol as string,
+ symbolSize: seriesSymbolSize as number | number[],
+ symbolKeepAspect: keepAspect
+ });
+
+ // Only visible series has each data be visual encoded
+ if (ecModel.isSeriesFiltered(seriesModel)) {
+ return;
+ }
+
+ function dataEach(data: List, idx: number) {
+ const rawValue = seriesModel.getRawValue(idx);
+ const params = seriesModel.getDataParams(idx);
+ hasSymbolTypeCallback && data.setItemVisual(
+ idx, 'symbol', (symbolType as SymbolCallback<CallbackDataParams>)(rawValue, params)
+ );
+ hasSymbolSizeCallback && data.setItemVisual(
+ idx, 'symbolSize', (symbolSize as SymbolSizeCallback<CallbackDataParams>)(rawValue, params)
+ );
+ }
+
+ return { dataEach: hasCallback ? dataEach : null };
+ }
+};
+
+const dataSymbolTask: StageHandler = {
+
+ createOnAllSeries: true,
+
+ // For legend.
+ performRawSeries: true,
+
+ reset: function (
+ seriesModel: SeriesModel<SeriesOption & SymbolOptionMixin<CallbackDataParams>>,
+ ecModel: GlobalModel
+ ) {
+ if (!seriesModel.hasSymbolVisual) {
+ return;
+ }
+ // Only visible series has each data be visual encoded
+ if (ecModel.isSeriesFiltered(seriesModel)) {
+ return;
+ }
+
+ const data = seriesModel.getData();
+
+ function dataEach(data: List, idx: number) {
+ const itemModel = data.getItemModel<SymbolOptionMixin>(idx);
+ const itemSymbolType = itemModel.getShallow('symbol', true);
+ const itemSymbolSize = itemModel.getShallow('symbolSize', true);
+ const itemSymbolKeepAspect = itemModel.getShallow('symbolKeepAspect', true);
+
+ // If has item symbol
+ if (itemSymbolType != null) {
+ data.setItemVisual(idx, 'symbol', itemSymbolType);
+ }
+ if (itemSymbolSize != null) {
+ // PENDING Transform symbolSize ?
+ data.setItemVisual(idx, 'symbolSize', itemSymbolSize);
+ }
+ if (itemSymbolKeepAspect != null) {
+ data.setItemVisual(idx, 'symbolKeepAspect', itemSymbolKeepAspect);
+ }
+ }
+
+ return { dataEach: data.hasItemOption ? dataEach : null };
+ }
+};
+
+export {seriesSymbolTask, dataSymbolTask};
\ No newline at end of file
diff --git a/src/visual/visualSolution.ts b/src/visual/visualSolution.ts
index 5ae42fa..accd72d 100644
--- a/src/visual/visualSolution.ts
+++ b/src/visual/visualSolution.ts
@@ -31,6 +31,7 @@ import {
StageHandlerProgressExecutor
} from '../util/types';
import List from '../data/List';
+import { getItemVisualFromData, setItemVisualFromData } from './helper';
const each = zrUtil.each;
@@ -148,11 +149,11 @@ export function applyVisual<VisualState extends string, Scope>(
let dataIndex: number;
function getVisual(key: string) {
- return data.getItemVisual(dataIndex, key);
+ return getItemVisualFromData(data, dataIndex, key) as string | number;
}
function setVisual(key: string, value: any) {
- data.setItemVisual(dataIndex, key, value);
+ setItemVisualFromData(data, dataIndex, key, value);
}
if (dimension == null) {
@@ -214,11 +215,11 @@ export function incrementalApplyVisual<VisualState extends string>(
}
function getVisual(key: string) {
- return data.getItemVisual(dataIndex, key);
+ return getItemVisualFromData(data, dataIndex, key) as string | number;
}
function setVisual(key: string, value: any) {
- data.setItemVisual(dataIndex, key, value);
+ setItemVisualFromData(data, dataIndex, key, value);
}
let dataIndex: number;
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@echarts.apache.org
For additional commands, e-mail: commits-help@echarts.apache.org