This is an automated email from the ASF dual-hosted git repository. wangzx pushed a commit to branch fix/markLine-symbol in repository https://gitbox.apache.org/repos/asf/echarts.git
commit 01e2da59277c7b7a094300873854c1cc008f74cc Author: plainheart <[email protected]> AuthorDate: Tue Mar 2 00:07:01 2021 +0800 1) fix: markLine `symbolOffset` doesn't work bug - Resolves #9325 - Resolves #14106 - Resolves #4771 2) feat: `markLine.symbolRotate` can be an array to specify symbol rotation at the two endpoints. - Related #12736, #12392 3) feat: add `markLine.symbolKeepAspect` and fix `symbolKeepAspect` doesn't work bug. 4) feat: `symbolOffset` can be a callback function, close #12495. --- src/chart/helper/Line.ts | 32 +++++++++++++++++++++++--------- src/chart/helper/Symbol.ts | 20 ++++++++------------ src/chart/helper/SymbolDraw.ts | 5 ----- src/component/marker/MarkLineModel.ts | 7 ++++++- src/component/marker/MarkLineView.ts | 20 +++++++++++++++++--- src/data/List.ts | 1 + src/util/types.ts | 4 ++-- src/visual/commonVisualTypes.ts | 8 ++++++-- src/visual/symbol.ts | 20 ++++++++++++++++---- 9 files changed, 79 insertions(+), 38 deletions(-) diff --git a/src/chart/helper/Line.ts b/src/chart/helper/Line.ts index 93d0fb3..797504d 100644 --- a/src/chart/helper/Line.ts +++ b/src/chart/helper/Line.ts @@ -17,14 +17,14 @@ * under the License. */ -import * as zrUtil from 'zrender/src/core/util'; +import { isArray, each, retrieve2 } from 'zrender/src/core/util'; import * as vector from 'zrender/src/core/vector'; import * as symbolUtil from '../../util/symbol'; import ECLinePath from './LinePath'; import * as graphic from '../../util/graphic'; import { enableHoverEmphasis, enterEmphasis, leaveEmphasis, SPECIAL_STATES } from '../../util/states'; import {getLabelStatesModels, setLabelStyle} from '../../label/labelStyle'; -import {round} from '../../util/number'; +import {round, parsePercent} from '../../util/number'; import List from '../../data/List'; import { ZRTextAlign, ZRTextVerticalAlign, LineLabelOption, ColorString } from '../../util/types'; import SeriesModel from '../../model/Series'; @@ -70,12 +70,26 @@ function createSymbol(name: 'fromSymbol' | 'toSymbol', lineData: LineList, idx: const symbolSize = lineData.getItemVisual(idx, name + 'Size' as 'fromSymbolSize' | 'toSymbolSize'); const symbolRotate = lineData.getItemVisual(idx, name + 'Rotate' as 'fromSymbolRotate' | 'toSymbolRotate'); + const symbolOffset = lineData.getItemVisual(idx, name + 'Offset' as 'fromSymbolOffset' | 'toSymbolOffset'); + const symbolKeepAspect = lineData.getItemVisual(idx, name + 'KeepAspect' as 'fromSymbolKeepAspect' | 'toSymbolKeepAspect'); - const symbolSizeArr = zrUtil.isArray(symbolSize) + const symbolSizeArr = isArray(symbolSize) ? symbolSize : [symbolSize, symbolSize]; + + const symbolOffsetArr = isArray(symbolOffset) + ? symbolOffset : [symbolOffset, symbolOffset]; + + symbolOffsetArr[0] = parsePercent(symbolOffsetArr[0], symbolSizeArr[0]); + symbolOffsetArr[1] = parsePercent(retrieve2(symbolOffsetArr[1], symbolOffsetArr[0]),symbolSizeArr[1]); + const symbolPath = symbolUtil.createSymbol( - symbolType, -symbolSizeArr[0] / 2, -symbolSizeArr[1] / 2, - symbolSizeArr[0], symbolSizeArr[1] + symbolType, + -symbolSizeArr[0] / 2 + (symbolOffsetArr as number[])[0], + -symbolSizeArr[1] / 2 + (symbolOffsetArr as number[])[1], + symbolSizeArr[0], + symbolSizeArr[1], + null, + symbolKeepAspect ); (symbolPath as LineECSymbol).__specifiedRotation = symbolRotate == null || isNaN(symbolRotate) @@ -142,7 +156,7 @@ class Line extends graphic.Group { this.add(line); - zrUtil.each(SYMBOL_CATEGORIES, function (symbolCategory) { + each(SYMBOL_CATEGORIES, function (symbolCategory) { const symbol = createSymbol(symbolCategory, lineData, idx); // symbols must added after line to make sure // it will be updated after line#update. @@ -167,7 +181,7 @@ class Line extends graphic.Group { setLinePoints(target.shape, linePoints); graphic.updateProps(line, target, seriesModel, idx); - zrUtil.each(SYMBOL_CATEGORIES, function (symbolCategory) { + each(SYMBOL_CATEGORIES, function (symbolCategory) { const symbolType = (lineData as LineList).getItemVisual(idx, symbolCategory); const key = makeSymbolTypeKey(symbolCategory); // Symbol changed @@ -220,7 +234,7 @@ class Line extends graphic.Group { line.ensureState('select').style = selectLineStyle; // Update symbol - zrUtil.each(SYMBOL_CATEGORIES, function (symbolCategory) { + each(SYMBOL_CATEGORIES, function (symbolCategory) { const symbol = this.childOfName(symbolCategory) as ECSymbol; if (symbol) { // Share opacity and color with line. @@ -275,7 +289,7 @@ class Line extends graphic.Group { label.__position = labelNormalModel.get('position') || 'middle'; let distance = labelNormalModel.get('distance'); - if (!zrUtil.isArray(distance)) { + if (!isArray(distance)) { distance = [distance, distance]; } label.__labelDistance = distance; diff --git a/src/chart/helper/Symbol.ts b/src/chart/helper/Symbol.ts index cea1c1a..6a53bc6 100644 --- a/src/chart/helper/Symbol.ts +++ b/src/chart/helper/Symbol.ts @@ -28,7 +28,7 @@ import { ColorString, BlurScope, AnimationOption } 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'; +import { extend, isArray, retrieve2 } from 'zrender/src/core/util'; import { setLabelStyle, getLabelStatesModels } from '../../label/labelStyle'; import ZRImage from 'zrender/src/graphic/Image'; @@ -216,8 +216,6 @@ class Symbol extends graphic.Group { let focus; let blurScope: BlurScope; - let symbolOffset; - let labelStatesModels; let hoverScale; @@ -230,8 +228,6 @@ class Symbol extends graphic.Group { focus = seriesScope.focus; blurScope = seriesScope.blurScope; - symbolOffset = seriesScope.symbolOffset; - labelStatesModels = seriesScope.labelStatesModels; hoverScale = seriesScope.hoverScale; @@ -250,8 +246,6 @@ class Symbol extends graphic.Group { focus = emphasisModel.get('focus'); blurScope = emphasisModel.get('blurScope'); - symbolOffset = itemModel.getShallow('symbolOffset'); - labelStatesModels = getLabelStatesModels(itemModel); hoverScale = emphasisModel.getShallow('scale'); @@ -259,14 +253,16 @@ class Symbol extends graphic.Group { } const symbolRotate = data.getItemVisual(idx, 'symbolRotate'); - symbolPath.attr('rotation', (symbolRotate || 0) * Math.PI / 180 || 0); - if (symbolOffset) { - symbolPath.x = parsePercent(symbolOffset[0], symbolSize[0]); - symbolPath.y = parsePercent(symbolOffset[1], symbolSize[1]); + let symbolOffset = data.getItemVisual(idx, 'symbolOffset') || 0; + if (!isArray(symbolOffset)) { + symbolOffset = [symbolOffset, symbolOffset]; } + symbolPath.x = parsePercent(symbolOffset[0], symbolSize[0]); + symbolPath.y = parsePercent(retrieve2(symbolOffset[1], symbolOffset[0]) || 0, symbolSize[1]); + cursorStyle && symbolPath.attr('cursor', cursorStyle); const symbolStyle = data.getItemVisual(idx, 'style'); @@ -398,7 +394,7 @@ class Symbol extends graphic.Group { static getSymbolSize(data: List, idx: number) { const symbolSize = data.getItemVisual(idx, 'symbolSize'); - return symbolSize instanceof Array + return isArray(symbolSize) ? symbolSize.slice() : [+symbolSize, +symbolSize]; } diff --git a/src/chart/helper/SymbolDraw.ts b/src/chart/helper/SymbolDraw.ts index aace5bd..28d9f5d 100644 --- a/src/chart/helper/SymbolDraw.ts +++ b/src/chart/helper/SymbolDraw.ts @@ -114,9 +114,6 @@ export interface SymbolDrawSeriesScope { focus?: string blurScope?: BlurScope - symbolRotate?: ScatterSeriesOption['symbolRotate'] - symbolOffset?: (number | string)[] - labelStatesModels: Record<DisplayState, Model<LabelOption>> itemModel?: Model<SymbolDrawItemModelOption> @@ -138,8 +135,6 @@ function makeSeriesScope(data: List): SymbolDrawSeriesScope { focus: emphasisModel.get('focus'), blurScope: emphasisModel.get('blurScope'), - symbolRotate: seriesModel.get('symbolRotate'), - symbolOffset: seriesModel.get('symbolOffset'), hoverScale: emphasisModel.get('scale'), labelStatesModels: getLabelStatesModels(seriesModel), diff --git a/src/component/marker/MarkLineModel.ts b/src/component/marker/MarkLineModel.ts index 44bc99f..4fed8c5 100644 --- a/src/component/marker/MarkLineModel.ts +++ b/src/component/marker/MarkLineModel.ts @@ -60,6 +60,8 @@ export interface MarkLine1DDataItemOption extends MarkLineDataItemOptionBase { */ symbol?: string[] | string symbolSize?: number[] | number + symbolRotate?: number[] | number + symbolOffset: number | string | (number | string)[] } // 2D markLine on any direction @@ -82,6 +84,8 @@ export interface MarkLineOption extends MarkerOption, symbol?: string[] | string symbolSize?: number[] | number + symbolRotate?: number[] | number + symbolOffset?: number | string | (number | string)[] /** * Precision used on statistic method @@ -112,6 +116,7 @@ class MarkLineModel extends MarkerModel<MarkLineOption> { symbolSize: [8, 16], //symbolRotate: 0, + symbolOffset: 0, precision: 2, tooltip: { @@ -137,4 +142,4 @@ class MarkLineModel extends MarkerModel<MarkLineOption> { }; } -export default MarkLineModel; \ No newline at end of file +export default MarkLineModel; diff --git a/src/component/marker/MarkLineView.ts b/src/component/marker/MarkLineView.ts index f0f713e..da7e0cf 100644 --- a/src/component/marker/MarkLineView.ts +++ b/src/component/marker/MarkLineView.ts @@ -319,12 +319,20 @@ class MarkLineView extends MarkerView { let symbolType = mlModel.get('symbol'); let symbolSize = mlModel.get('symbolSize'); + let symbolRotate = mlModel.get('symbolRotate'); + let symbolOffset = mlModel.get('symbolOffset'); if (!isArray(symbolType)) { symbolType = [symbolType, symbolType]; } if (!isArray(symbolSize)) { symbolSize = [symbolSize, symbolSize]; } + if (!isArray(symbolRotate)) { + symbolRotate = [symbolRotate, symbolRotate]; + } + if (!isArray(symbolOffset)) { + symbolOffset = [symbolOffset, symbolOffset]; + } // Update visual and layout of from symbol and to symbol mlData.from.each(function (idx) { @@ -349,9 +357,13 @@ class MarkLineView extends MarkerView { } lineData.setItemVisual(idx, { + fromSymbolKeepAspect: fromData.getItemVisual(idx, 'symbolKeepAspect'), + fromSymbolOffset: fromData.getItemVisual(idx, 'symbolOffset'), fromSymbolRotate: fromData.getItemVisual(idx, 'symbolRotate'), fromSymbolSize: fromData.getItemVisual(idx, 'symbolSize') as number, fromSymbol: fromData.getItemVisual(idx, 'symbol'), + toSymbolKeepAspect: toData.getItemVisual(idx, 'symbolKeepAspect'), + toSymbolOffset: toData.getItemVisual(idx, 'symbolOffset'), toSymbolRotate: toData.getItemVisual(idx, 'symbolRotate'), toSymbolSize: toData.getItemVisual(idx, 'symbolSize') as number, toSymbol: toData.getItemVisual(idx, 'symbol'), @@ -384,9 +396,11 @@ class MarkLineView extends MarkerView { if (style.fill == null) { style.fill = getVisualFromData(seriesData, 'color') as ColorString; } - + const a = symbolOffset data.setItemVisual(idx, { - symbolRotate: itemModel.get('symbolRotate'), + symbolKeepAspect: itemModel.get('symbolKeepAspect'), + symbolOffset: itemModel.get('symbolOffset') || (symbolOffset as (string | number)[])[isFrom ? 0 : 1], + symbolRotate: itemModel.get('symbolRotate', true) || (symbolRotate as number[])[isFrom ? 0 : 1], symbolSize: itemModel.get('symbolSize') || (symbolSize as number[])[isFrom ? 0 : 1], symbol: itemModel.get('symbol', true) || (symbolType as string[])[isFrom ? 0 : 1], style @@ -462,4 +476,4 @@ function createList(coordSys: CoordinateSystem, seriesModel: SeriesModel, mlMode }; } -export default MarkLineView; \ No newline at end of file +export default MarkLineView; diff --git a/src/data/List.ts b/src/data/List.ts index 7a8b245..116dec9 100644 --- a/src/data/List.ts +++ b/src/data/List.ts @@ -135,6 +135,7 @@ export interface DefaultDataVisual { symbolSize?: number | number[] symbolRotate?: number symbolKeepAspect?: boolean + symbolOffset?: string | number | (string | number)[] liftZ?: number // For legend. diff --git a/src/util/types.ts b/src/util/types.ts index 823310c..f9b3923 100644 --- a/src/util/types.ts +++ b/src/util/types.ts @@ -925,7 +925,7 @@ export interface RoamOptionMixin { export type SymbolSizeCallback<T> = (rawValue: any, params: T) => number | number[]; export type SymbolCallback<T> = (rawValue: any, params: T) => string; export type SymbolRotateCallback<T> = (rawValue: any, params: T) => number; -// export type SymbolOffsetCallback<T> = (rawValue: any, params: T) => (string | number)[]; +export type SymbolOffsetCallback<T> = (rawValue: any, params: T) => (string | number)[]; /** * Mixin of option set to control the element symbol. * Include type of symbol, and size of symbol. @@ -944,7 +944,7 @@ export interface SymbolOptionMixin<T = unknown> { symbolKeepAspect?: boolean - symbolOffset?: (string | number)[] + symbolOffset?: (string | number)[] | (unknown extends T ? never : SymbolOffsetCallback<T>) } /** diff --git a/src/visual/commonVisualTypes.ts b/src/visual/commonVisualTypes.ts index 00f180e..e279a4c 100644 --- a/src/visual/commonVisualTypes.ts +++ b/src/visual/commonVisualTypes.ts @@ -22,9 +22,13 @@ import { DefaultDataVisual } from '../data/List'; export interface LineDataVisual extends DefaultDataVisual { fromSymbol: string toSymbol: string - fromSymbolSize: number - toSymbolSize: number + fromSymbolSize: number | number[] + toSymbolSize: number | number[] fromSymbolRotate: number toSymbolRotate: number + fromSymbolOffset: string | number | (string | number)[] + toSymbolOffset: string | number | (string | number)[] + fromSymbolKeepAspect: boolean + toSymbolKeepAspect: boolean } diff --git a/src/visual/symbol.ts b/src/visual/symbol.ts index 99be9f0..b4a8d0a 100644 --- a/src/visual/symbol.ts +++ b/src/visual/symbol.ts @@ -25,7 +25,8 @@ import { SymbolSizeCallback, SymbolCallback, CallbackDataParams, - SymbolRotateCallback + SymbolRotateCallback, + SymbolOffsetCallback } from '../util/types'; import List from '../data/List'; import SeriesModel from '../model/Series'; @@ -57,14 +58,17 @@ const seriesSymbolTask: StageHandler = { const symbolSize = seriesModel.get('symbolSize'); const keepAspect = seriesModel.get('symbolKeepAspect'); const symbolRotate = seriesModel.get('symbolRotate'); + const symbolOffset = seriesModel.get('symbolOffset'); const hasSymbolTypeCallback = isFunction(symbolType); const hasSymbolSizeCallback = isFunction(symbolSize); const hasSymbolRotateCallback = isFunction(symbolRotate); - const hasCallback = hasSymbolTypeCallback || hasSymbolSizeCallback || hasSymbolRotateCallback; + const hasSymbolOffsetCallback = isFunction(symbolOffset); + const hasCallback = hasSymbolTypeCallback || hasSymbolSizeCallback || hasSymbolRotateCallback || hasSymbolOffsetCallback; const seriesSymbol = (!hasSymbolTypeCallback && symbolType) ? symbolType : seriesModel.defaultSymbol; const seriesSymbolSize = !hasSymbolSizeCallback ? symbolSize : null; const seriesSymbolRotate = !hasSymbolRotateCallback ? symbolRotate : null; + const seriesSymbolOffset = !hasSymbolOffsetCallback ? symbolOffset : null; data.setVisual({ legendSymbol: seriesModel.legendSymbol || seriesSymbol as string, @@ -75,7 +79,8 @@ const seriesSymbolTask: StageHandler = { symbol: seriesSymbol as string, symbolSize: seriesSymbolSize as number | number[], symbolKeepAspect: keepAspect, - symbolRotate: seriesSymbolRotate as number + symbolRotate: seriesSymbolRotate as number, + symbolOffset: seriesSymbolOffset as (string | number)[] }); // Only visible series has each data be visual encoded @@ -95,6 +100,9 @@ const seriesSymbolTask: StageHandler = { hasSymbolRotateCallback && data.setItemVisual( idx, 'symbolRotate', (symbolRotate as SymbolRotateCallback<CallbackDataParams>)(rawValue, params) ); + hasSymbolOffsetCallback && data.setItemVisual( + idx, 'symbolOffset', (symbolOffset as SymbolOffsetCallback<CallbackDataParams>)(rawValue, params) + ); } return { dataEach: hasCallback ? dataEach : null }; @@ -127,6 +135,7 @@ const dataSymbolTask: StageHandler = { const itemSymbolType = itemModel.getShallow('symbol', true); const itemSymbolSize = itemModel.getShallow('symbolSize', true); const itemSymbolRotate = itemModel.getShallow('symbolRotate', true); + const itemSymbolOffset = itemModel.getShallow('symbolOffset', true); const itemSymbolKeepAspect = itemModel.getShallow('symbolKeepAspect', true); // If has item symbol @@ -140,6 +149,9 @@ const dataSymbolTask: StageHandler = { if (itemSymbolRotate != null) { data.setItemVisual(idx, 'symbolRotate', itemSymbolRotate); } + if (itemSymbolOffset != null) { + data.setItemVisual(idx, 'symbolOffset', itemSymbolOffset); + } if (itemSymbolKeepAspect != null) { data.setItemVisual(idx, 'symbolKeepAspect', itemSymbolKeepAspect); } @@ -149,4 +161,4 @@ const dataSymbolTask: StageHandler = { } }; -export {seriesSymbolTask, dataSymbolTask}; \ No newline at end of file +export {seriesSymbolTask, dataSymbolTask}; --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
