diff --git a/src/chart/line/LineSeries.ts b/src/chart/line/LineSeries.ts index 9faf5c5175..438a344d3a 100644 --- a/src/chart/line/LineSeries.ts +++ b/src/chart/line/LineSeries.ts @@ -112,7 +112,7 @@ export interface LineSeriesOption extends SeriesOption { symbolSize: 4, symbolRotate: null, + // true: show symbol + // false: hide symbol + // 'single': will show symbol between null value. showSymbol: true, // `false`: follow the label interval strategy. // `true`: show all symbols. diff --git a/src/chart/line/LineView.ts b/src/chart/line/LineView.ts index 9672eb720b..706501b8ae 100644 --- a/src/chart/line/LineView.ts +++ b/src/chart/line/LineView.ts @@ -400,6 +400,43 @@ function getIsIgnoreFunc( }; } +function getIsSingleSymbolIgnore( + seriesModel: LineSeriesModel, + data: SeriesData, + coordSys: Cartesian2D +) { + const intervalAxis = coordSys.getAxesByScale('interval')[0]; + + if (!intervalAxis) { + return; + } + + const intervalDataDim = data.mapDimension(intervalAxis.dim); + + const count = data.count(); + + const singleDataIdxStateList: boolean[] = []; + + for (let i = 0; i < count; i++) { + const intervalValue = data.get(intervalDataDim, i); + + if (typeof intervalValue === 'number' && isNaN(intervalValue)) { + singleDataIdxStateList[i] = false; + } + else { + singleDataIdxStateList[i] = true; + } + + } + + + return function (dataIndex: number) { + return singleDataIdxStateList[dataIndex - 1] + || !singleDataIdxStateList[dataIndex] + || singleDataIdxStateList[dataIndex + 1]; + }; +} + function canShowAllSymbolForCategory( categoryAxis: Axis2D, data: SeriesData @@ -657,8 +694,14 @@ class LineView extends ChartView { const connectNulls = seriesModel.get('connectNulls'); - const isIgnoreFunc = showSymbol && !isCoordSysPolar - && getIsIgnoreFunc(seriesModel, data, coordSys as Cartesian2D); + const isIgnoreFunc = showSymbol === true ? !isCoordSysPolar + && getIsIgnoreFunc(seriesModel, data, coordSys as Cartesian2D) + : ( + !isCoordSysPolar + && showSymbol === 'single' + && connectNulls === false + && getIsSingleSymbolIgnore(seriesModel, data, coordSys as Cartesian2D) + ); // Remove temporary symbols const oldData = this._data; @@ -701,14 +744,16 @@ class LineView extends ChartView { if ( !(polyline && prevCoordSys.type === coordSys.type && step === this._step) ) { - showSymbol && symbolDraw.updateData(data, { - isIgnore: isIgnoreFunc, - clipShape: clipShapeForSymbol, - disableAnimation: true, - getSymbolPoint(idx) { - return [points[idx * 2], points[idx * 2 + 1]]; - } - }); + if (showSymbol === true || (showSymbol === 'single' && !connectNulls)) { + symbolDraw.updateData(data, { + isIgnore: isIgnoreFunc, + clipShape: clipShapeForSymbol, + disableAnimation: true, + getSymbolPoint(idx) { + return [points[idx * 2], points[idx * 2 + 1]]; + } + }); + } hasAnimation && this._initSymbolLabelAnimation( data, @@ -779,14 +824,16 @@ class LineView extends ChartView { // Always update, or it is wrong in the case turning on legend // because points are not changed. - showSymbol && symbolDraw.updateData(data, { - isIgnore: isIgnoreFunc, - clipShape: clipShapeForSymbol, - disableAnimation: true, - getSymbolPoint(idx) { - return [points[idx * 2], points[idx * 2 + 1]]; - } - }); + if (showSymbol === true || (showSymbol === 'single' && !connectNulls)) { + symbolDraw.updateData(data, { + isIgnore: isIgnoreFunc, + clipShape: clipShapeForSymbol, + disableAnimation: true, + getSymbolPoint(idx) { + return [points[idx * 2], points[idx * 2 + 1]]; + } + }); + } // In the case data zoom triggered refreshing frequently // Data may not change if line has a category axis. So it should animate nothing. diff --git a/test/lines-single-symbol.html b/test/lines-single-symbol.html new file mode 100644 index 0000000000..9848718061 --- /dev/null +++ b/test/lines-single-symbol.html @@ -0,0 +1,207 @@ + + + + + + + + + + + + + + +
+
+
+
+ + + + + + + \ No newline at end of file diff --git a/test/runTest/actions/__meta__.json b/test/runTest/actions/__meta__.json index 26eac6dd21..d15998bd1b 100644 --- a/test/runTest/actions/__meta__.json +++ b/test/runTest/actions/__meta__.json @@ -133,6 +133,7 @@ "line-sampling": 2, "line-visual2": 2, "lines-bus": 1, + "lines-single-symbol": 5, "lines-symbolSize-update": 1, "map": 3, "map-contour": 2, diff --git a/test/runTest/actions/lines-single-symbol.json b/test/runTest/actions/lines-single-symbol.json new file mode 100644 index 0000000000..9f4b9bf6d9 --- /dev/null +++ b/test/runTest/actions/lines-single-symbol.json @@ -0,0 +1 @@ +[{"name":"Action 1","ops":[{"type":"mousemove","time":431,"x":774,"y":200},{"type":"mousemove","time":631,"x":718,"y":191},{"type":"mousemove","time":841,"x":757,"y":160},{"type":"screenshot","time":1246}],"scrollY":0,"scrollX":0,"timestamp":1691718419649},{"name":"Action 2","ops":[{"type":"screenshot","time":463}],"scrollY":290,"scrollX":0,"timestamp":1691718424580},{"name":"Action 3","ops":[{"type":"screenshot","time":389}],"scrollY":608,"scrollX":0,"timestamp":1691718427485},{"name":"Action 4","ops":[{"type":"screenshot","time":461}],"scrollY":884,"scrollX":0,"timestamp":1691718430826},{"name":"Action 5","ops":[{"type":"screenshot","time":578}],"scrollY":921,"scrollX":0,"timestamp":1691718433229}] \ No newline at end of file