You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@echarts.apache.org by wa...@apache.org on 2021/03/01 16:08:38 UTC

[echarts] branch fix/markLine-symbol created (now 01e2da5)

This is an automated email from the ASF dual-hosted git repository.

wangzx pushed a change to branch fix/markLine-symbol
in repository https://gitbox.apache.org/repos/asf/echarts.git.


      at 01e2da5  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.

This branch includes the following new commits:

     new 01e2da5  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.

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.



---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@echarts.apache.org
For additional commands, e-mail: commits-help@echarts.apache.org


[echarts] 01/01: 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.

Posted by wa...@apache.org.
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 <yh...@all-my-life.cn>
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: commits-unsubscribe@echarts.apache.org
For additional commands, e-mail: commits-help@echarts.apache.org