diff --git a/src/chart/line/LineSeries.ts b/src/chart/line/LineSeries.ts index 9faf5c5175..820958ae44 100644 --- a/src/chart/line/LineSeries.ts +++ b/src/chart/line/LineSeries.ts @@ -120,6 +120,8 @@ export interface LineSeriesOption extends SeriesOption { @@ -152,6 +154,8 @@ class LineSeriesModel extends SeriesModel { clip: true, + loop: false, + label: { position: 'top' }, diff --git a/src/chart/line/LineView.ts b/src/chart/line/LineView.ts index 435fa2a90c..e02d3fea48 100644 --- a/src/chart/line/LineView.ts +++ b/src/chart/line/LineView.ts @@ -657,6 +657,8 @@ class LineView extends ChartView { const connectNulls = seriesModel.get('connectNulls'); + const loop = isCoordSysPolar && seriesModel.get('loop'); + const isIgnoreFunc = showSymbol && !isCoordSysPolar && getIsIgnoreFunc(seriesModel, data, coordSys as Cartesian2D); @@ -725,10 +727,10 @@ class LineView extends ChartView { } } - polyline = this._newPolyline(points); + polyline = this._newPolyline(points, loop); if (isAreaChart) { polygon = this._newPolygon( - points, stackedOnPoints + points, stackedOnPoints, loop ); }// If areaStyle is removed else if (polygon) { @@ -749,7 +751,7 @@ class LineView extends ChartView { if (isAreaChart && !polygon) { // If areaStyle is added polygon = this._newPolygon( - points, stackedOnPoints + points, stackedOnPoints, loop ); } else if (polygon && !isAreaChart) { @@ -1019,7 +1021,7 @@ class LineView extends ChartView { polygon && setStatesFlag(polygon, toState); } - _newPolyline(points: ArrayLike) { + _newPolyline(points: ArrayLike, loop: boolean) { let polyline = this._polyline; // Remove previous created polyline if (polyline) { @@ -1028,7 +1030,8 @@ class LineView extends ChartView { polyline = new ECPolyline({ shape: { - points + points, + loop }, segmentIgnoreThreshold: 2, z2: 10 @@ -1041,7 +1044,7 @@ class LineView extends ChartView { return polyline; } - _newPolygon(points: ArrayLike, stackedOnPoints: ArrayLike) { + _newPolygon(points: ArrayLike, stackedOnPoints: ArrayLike, loop: boolean) { let polygon = this._polygon; // Remove previous created polygon if (polygon) { @@ -1051,6 +1054,7 @@ class LineView extends ChartView { polygon = new ECPolygon({ shape: { points, + loop, stackedOnPoints: stackedOnPoints }, segmentIgnoreThreshold: 2 diff --git a/src/chart/line/poly.ts b/src/chart/line/poly.ts index 181c215696..d919739793 100644 --- a/src/chart/line/poly.ts +++ b/src/chart/line/poly.ts @@ -211,12 +211,29 @@ function drawSegment( return k; } +function getSmoothableLoopedPoints(shape: ECPolygonShape) { + let points = (shape.points as number[]); + + if (shape.connectNulls) { + const nonNull: number[] = []; + for (let i = 0; i < points.length; i += 2) { + if (!isPointNull(points[i], points[i + 1])) { + nonNull.push(points[i], points[i + 1]); + } + } + points = nonNull; + } + + return [points[points.length - 2], points[points.length - 1], ...points, points[0], points[1]]; +} + class ECPolylineShape { points: ArrayLike; smooth = 0; smoothConstraint = true; smoothMonotone: 'x' | 'y' | 'none'; connectNulls: boolean; + loop = false; } interface ECPolylineProps extends PathProps { @@ -245,8 +262,15 @@ export class ECPolyline extends Path { } buildPath(ctx: PathProxy, shape: ECPolylineShape) { - const points = shape.points; + if (shape.loop) { + return ECPolygon.prototype.buildPath.call(this, ctx, { + ...shape, + stackedOnPoints: [], + stackedOnSmooth: 0 + }); + } + const points = shape.points; let i = 0; let len = points.length / 2; @@ -369,7 +393,8 @@ export class ECPolygon extends Path { } buildPath(ctx: PathProxy, shape: ECPolygonShape) { - const points = shape.points; + const shouldSmoothLoopedPoints = shape.loop && shape.smooth; + const points = shouldSmoothLoopedPoints ? getSmoothableLoopedPoints(shape) : shape.points; const stackedOnPoints = shape.stackedOnPoints; let i = 0; @@ -391,13 +416,14 @@ export class ECPolygon extends Path { } while (i < len) { const k = drawSegment( - ctx, points, i, len, len, + ctx, points, + shouldSmoothLoopedPoints ? i - 1 : i, len, shouldSmoothLoopedPoints ? len - 1 : len, 1, shape.smooth, smoothMonotone, shape.connectNulls ); drawSegment( - ctx, stackedOnPoints, i + k - 1, k, len, + ctx, stackedOnPoints, i + k - 1, k, shouldSmoothLoopedPoints ? len - 1 : len, -1, shape.stackedOnSmooth, smoothMonotone, shape.connectNulls diff --git a/test/line-loop.html b/test/line-loop.html new file mode 100644 index 0000000000..3a46167be1 --- /dev/null +++ b/test/line-loop.html @@ -0,0 +1,235 @@ + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file