From cf414a29fac6045b7c3fe154b297093e299ee358 Mon Sep 17 00:00:00 2001 From: Ovilia Date: Thu, 10 Oct 2019 18:03:34 +0800 Subject: [PATCH 1/9] feat: add sausage shape --- src/util/graphic.js | 5 +++ src/util/symbol.js | 77 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 82 insertions(+) diff --git a/src/util/graphic.js b/src/util/graphic.js index 0ca633d3f1..1d098061bc 100644 --- a/src/util/graphic.js +++ b/src/util/graphic.js @@ -42,6 +42,7 @@ import RadialGradient from 'zrender/src/graphic/RadialGradient'; import BoundingRect from 'zrender/src/core/BoundingRect'; import IncrementalDisplayable from 'zrender/src/graphic/IncrementalDisplayable'; import * as subPixelOptimizeUtil from 'zrender/src/graphic/helper/subPixelOptimize'; +import fixPathClipWithShadow from 'zrender/src/graphic/helper/fixClipWithShadow'; var mathMax = Math.max; @@ -75,6 +76,10 @@ export function extendShape(opts) { return Path.extend(opts); } +export function fixClipWithShadow() { + return fixPathClipWithShadow(Path.prototype.brush); +} + /** * Extend path */ diff --git a/src/util/symbol.js b/src/util/symbol.js index 602ebfb544..99f4eec583 100644 --- a/src/util/symbol.js +++ b/src/util/symbol.js @@ -129,6 +129,72 @@ var Pin = graphic.extendShape({ } }); +/** + * Sausage: similar to sector, but have half circle on both sides + * @inner + */ +var Sausage = graphic.extendShape({ + + type: 'sausage', + + shape: { + + cx: 0, + + cy: 0, + + r0: 0, + + r: 0, + + startAngle: 0, + + endAngle: Math.PI * 2, + + clockwise: true + }, + + brush: graphic.fixClipWithShadow(), + + buildPath: function (ctx, shape) { + + var x = shape.cx; + var y = shape.cy; + var r0 = Math.max(shape.r0 || 0, 0); + var r = Math.max(shape.r, 0); + var dr = (r - r0) * 0.5; + var rCenter = r0 + dr; + var startAngle = shape.startAngle; + var endAngle = shape.endAngle; + var clockwise = shape.clockwise; + + var unitX = Math.cos(startAngle); + var unitY = Math.sin(startAngle); + + ctx.moveTo(unitX * r0 + x, unitY * r0 + y); + + ctx.arc(unitX * rCenter + x, unitY * rCenter + y, dr, + Math.PI + startAngle, startAngle, !clockwise); + + ctx.arc(x, y, r, startAngle, endAngle, !clockwise); + + ctx.arc( + Math.cos(endAngle) * rCenter + x, + Math.sin(endAngle) * rCenter + x, + dr, + endAngle, + endAngle + Math.PI, + !clockwise + ); + + if (r0 !== 0) { + ctx.arc(x, y, r0, endAngle, startAngle, clockwise); + } + + ctx.closePath(); + } +}); + /** * Arrow shape * @inner @@ -179,6 +245,8 @@ var symbolCtors = { pin: Pin, + sausage: Sausage, + arrow: Arrow, triangle: Triangle @@ -209,6 +277,15 @@ var symbolShapeMakers = { shape.r = Math.min(w, h) / 4; }, + sausage: function (x, y, w, h, shape) { + shape.r = Math.min(w, h) / 2; + shape.r0 = shape.r / 2; + shape.cx = x + w / 2; + shape.cy = y + h / 2; + shape.startAngle = -Math.PI / 6; + shape.endAngle = Math.PI / 6 * 7; + }, + square: function (x, y, w, h, shape) { var size = Math.min(w, h); shape.x = x; From 6a7cbdee42a9db0ed8bf38b9b9864a27c66808a3 Mon Sep 17 00:00:00 2001 From: Ovilia Date: Mon, 14 Oct 2019 17:37:35 +0800 Subject: [PATCH 2/9] feat(polar): support radius for polar bars --- src/chart/bar/BarSeries.js | 6 +++++- src/chart/bar/BarView.js | 16 ++++++++++------ src/layout/barPolar.js | 5 +++-- src/util/graphic.js | 7 +++++-- src/util/symbol.js | 39 ++++++++++++++++++++++---------------- 5 files changed, 46 insertions(+), 27 deletions(-) diff --git a/src/chart/bar/BarSeries.js b/src/chart/bar/BarSeries.js index 477a584b93..0f34f9c6c4 100644 --- a/src/chart/bar/BarSeries.js +++ b/src/chart/bar/BarSeries.js @@ -53,6 +53,10 @@ export default BaseBarSeries.extend({ defaultOption: { // If clipped // Only available on cartesian2d - clip: true + clip: true, + + // If use caps on two sides of bars + // Only available on tangential polar bar + roundCap: false } }); diff --git a/src/chart/bar/BarView.js b/src/chart/bar/BarView.js index 310ddffd1d..f15f9c4115 100644 --- a/src/chart/bar/BarView.js +++ b/src/chart/bar/BarView.js @@ -97,6 +97,7 @@ export default echarts.extendChartView({ var coordSysClipArea = coord.getArea && coord.getArea(); var needsClip = seriesModel.get('clip', true); + var roundCap = seriesModel.get('roundCap', true); // If there is clipPath created in large mode. Remove it. group.removeClipPath(); @@ -123,7 +124,7 @@ export default echarts.extendChartView({ } var el = elementCreator[coord.type]( - data, dataIndex, itemModel, layout, isHorizontalOrRadial, animationModel + dataIndex, layout, isHorizontalOrRadial, animationModel, false, roundCap ); data.setItemGraphicEl(dataIndex, el); group.add(el); @@ -157,7 +158,7 @@ export default echarts.extendChartView({ } else { el = elementCreator[coord.type]( - data, newIndex, itemModel, layout, isHorizontalOrRadial, animationModel, true + newIndex, layout, isHorizontalOrRadial, animationModel, true, roundCap ); } @@ -281,7 +282,7 @@ var clip = { var elementCreator = { cartesian2d: function ( - data, dataIndex, itemModel, layout, isHorizontal, + dataIndex, layout, isHorizontal, animationModel, isUpdate ) { var rect = new graphic.Rect({shape: zrUtil.extend({}, layout)}); @@ -302,15 +303,18 @@ var elementCreator = { }, polar: function ( - data, dataIndex, itemModel, layout, isRadial, - animationModel, isUpdate + dataIndex, layout, isRadial, + animationModel, isUpdate, roundCap ) { // Keep the same logic with bar in catesion: use end value to control // direction. Notice that if clockwise is true (by default), the sector // will always draw clockwisely, no matter whether endAngle is greater // or less than startAngle. var clockwise = layout.startAngle < layout.endAngle; - var sector = new graphic.Sector({ + + var ShapeClass = (!isRadial && roundCap) ? graphic.Sausage : graphic.Sector; + + var sector = new ShapeClass({ shape: zrUtil.defaults({clockwise: clockwise}, layout) }); diff --git a/src/layout/barPolar.js b/src/layout/barPolar.js index 88d7641a97..bcdc1a66cf 100644 --- a/src/layout/barPolar.js +++ b/src/layout/barPolar.js @@ -79,6 +79,8 @@ function barLayoutPolar(seriesType, ecModel, api) { var valueDim = data.mapDimension(valueAxis.dim); var baseDim = data.mapDimension(baseAxis.dim); var stacked = isDimensionStacked(data, valueDim /*, baseDim*/); + var clampLayout = baseDim !== 'radius' + || !seriesModel.get('roundCap', true); var valueAxisStart = valueAxis.getExtent()[0]; @@ -130,8 +132,7 @@ function barLayoutPolar(seriesType, ecModel, api) { } // tangential sector else { - // angleAxis must be clamped. - var angleSpan = valueAxis.dataToAngle(value, true) - valueAxisStart; + var angleSpan = valueAxis.dataToAngle(value, clampLayout) - valueAxisStart; var radius = baseAxis.dataToRadius(baseValue); if (Math.abs(angleSpan) < barMinAngle) { diff --git a/src/util/graphic.js b/src/util/graphic.js index 1d098061bc..969b4e4ed6 100644 --- a/src/util/graphic.js +++ b/src/util/graphic.js @@ -43,6 +43,7 @@ import BoundingRect from 'zrender/src/core/BoundingRect'; import IncrementalDisplayable from 'zrender/src/graphic/IncrementalDisplayable'; import * as subPixelOptimizeUtil from 'zrender/src/graphic/helper/subPixelOptimize'; import fixPathClipWithShadow from 'zrender/src/graphic/helper/fixClipWithShadow'; +import {Sausage} from './symbol'; var mathMax = Math.max; @@ -76,8 +77,8 @@ export function extendShape(opts) { return Path.extend(opts); } -export function fixClipWithShadow() { - return fixPathClipWithShadow(Path.prototype.brush); +export function fixClipWithShadow(conditionCheck) { + return fixPathClipWithShadow(Path.prototype.brush, conditionCheck); } /** @@ -1435,6 +1436,7 @@ function nearZero(val) { // by users, although we do not recommend that. registerShape('circle', Circle); registerShape('sector', Sector); +registerShape('sausage', Sausage); registerShape('ring', Ring); registerShape('polygon', Polygon); registerShape('polyline', Polyline); @@ -1449,6 +1451,7 @@ export { Text, Circle, Sector, + Sausage, Ring, Polygon, Polyline, diff --git a/src/util/symbol.js b/src/util/symbol.js index 99f4eec583..8113258d1b 100644 --- a/src/util/symbol.js +++ b/src/util/symbol.js @@ -133,7 +133,7 @@ var Pin = graphic.extendShape({ * Sausage: similar to sector, but have half circle on both sides * @inner */ -var Sausage = graphic.extendShape({ +export var Sausage = graphic.extendShape({ type: 'sausage', @@ -154,10 +154,11 @@ var Sausage = graphic.extendShape({ clockwise: true }, - brush: graphic.fixClipWithShadow(), + brush: graphic.fixClipWithShadow(function () { + return this.startAngle === this.endAngle; + }), buildPath: function (ctx, shape) { - var x = shape.cx; var y = shape.cy; var r0 = Math.max(shape.r0 || 0, 0); @@ -168,27 +169,33 @@ var Sausage = graphic.extendShape({ var endAngle = shape.endAngle; var clockwise = shape.clockwise; - var unitX = Math.cos(startAngle); - var unitY = Math.sin(startAngle); + var unitStartX = Math.cos(startAngle); + var unitStartY = Math.sin(startAngle); + var unitEndX = Math.cos(endAngle); + var unitEndY = Math.sin(endAngle); + + var lessThanCircle = clockwise + ? endAngle - startAngle < Math.PI * 2 + : startAngle - endAngle < Math.PI * 2; - ctx.moveTo(unitX * r0 + x, unitY * r0 + y); + if (lessThanCircle) { + ctx.moveTo(unitStartX * r0 + x, unitStartY * r0 + y); - ctx.arc(unitX * rCenter + x, unitY * rCenter + y, dr, - Math.PI + startAngle, startAngle, !clockwise); + ctx.arc(unitStartX * rCenter + x, unitStartY * rCenter + y, dr, + -Math.PI + startAngle, startAngle, !clockwise); + } ctx.arc(x, y, r, startAngle, endAngle, !clockwise); - ctx.arc( - Math.cos(endAngle) * rCenter + x, - Math.sin(endAngle) * rCenter + x, - dr, - endAngle, - endAngle + Math.PI, - !clockwise - ); + ctx.moveTo(unitEndX * r + x, unitEndY * r + y); + + ctx.arc(unitEndX * rCenter + x, unitEndY * rCenter + y, dr, + endAngle - Math.PI * 2, endAngle - Math.PI, !clockwise); if (r0 !== 0) { ctx.arc(x, y, r0, endAngle, startAngle, clockwise); + + ctx.moveTo(unitStartX * r0 + x, unitEndY * r0 + y); } ctx.closePath(); From e50f0498000bac05c95cf514bb10387f92630abd Mon Sep 17 00:00:00 2001 From: Ovilia Date: Mon, 14 Oct 2019 17:43:55 +0800 Subject: [PATCH 3/9] test(polar): add test for polar bars with roundCap --- test/polar-rounded.html | 256 ++++++++++++++++++++++++ test/runTest/actions/__meta__.json | 3 +- test/runTest/actions/polar-rounded.json | 1 + 3 files changed, 259 insertions(+), 1 deletion(-) create mode 100644 test/polar-rounded.html create mode 100644 test/runTest/actions/polar-rounded.json diff --git a/test/polar-rounded.html b/test/polar-rounded.html new file mode 100644 index 0000000000..53585a5cfc --- /dev/null +++ b/test/polar-rounded.html @@ -0,0 +1,256 @@ + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+ +
+ + + + + + + + + + + + + + + + + + diff --git a/test/runTest/actions/__meta__.json b/test/runTest/actions/__meta__.json index 723bed1438..5a2dcc4a00 100644 --- a/test/runTest/actions/__meta__.json +++ b/test/runTest/actions/__meta__.json @@ -134,5 +134,6 @@ "dataZoom-scroll": 3, "map-contour": 2, "map-default": 1, - "map-labels": 1 + "map-labels": 1, + "polar-rounded": 1 } \ No newline at end of file diff --git a/test/runTest/actions/polar-rounded.json b/test/runTest/actions/polar-rounded.json new file mode 100644 index 0000000000..169b11bd72 --- /dev/null +++ b/test/runTest/actions/polar-rounded.json @@ -0,0 +1 @@ +[{"name":"Action 1","ops":[{"type":"mousemove","time":409,"x":85,"y":209},{"type":"mousemove","time":618,"x":70,"y":180},{"type":"mousedown","time":737,"x":69,"y":180},{"type":"mousemove","time":843,"x":69,"y":180},{"type":"mouseup","time":860,"x":69,"y":180},{"time":861,"delay":400,"type":"screenshot-auto"},{"type":"mousedown","time":1719,"x":69,"y":180},{"type":"mouseup","time":1837,"x":69,"y":180},{"time":1838,"delay":400,"type":"screenshot-auto"},{"type":"mousedown","time":2790,"x":69,"y":180},{"type":"mouseup","time":2918,"x":69,"y":180},{"time":2919,"delay":400,"type":"screenshot-auto"},{"type":"mousedown","time":4274,"x":69,"y":180},{"type":"mouseup","time":4387,"x":69,"y":180},{"time":4388,"delay":400,"type":"screenshot-auto"},{"type":"mousedown","time":5857,"x":69,"y":180},{"type":"mouseup","time":5944,"x":69,"y":180},{"time":5945,"delay":400,"type":"screenshot-auto"},{"type":"mousemove","time":6877,"x":69,"y":180},{"type":"mousemove","time":7077,"x":146,"y":130},{"type":"mousemove","time":7277,"x":661,"y":48},{"type":"mousemove","time":7477,"x":793,"y":43}],"scrollY":1290,"scrollX":0,"timestamp":1571045937004}] \ No newline at end of file From b5e6ba7e8c9a5a198dd0b3dd7d40cdc1607c2a51 Mon Sep 17 00:00:00 2001 From: Ovilia Date: Tue, 15 Oct 2019 16:33:01 +0800 Subject: [PATCH 4/9] feat(polar): supports radius array for polar --- src/component/axis/AngleAxisView.js | 31 +++++++++++++++++------------ src/coord/polar/polarCreator.js | 19 +++++++++++++++--- 2 files changed, 34 insertions(+), 16 deletions(-) diff --git a/src/component/axis/AngleAxisView.js b/src/component/axis/AngleAxisView.js index 90678b4240..5fd14eeae6 100644 --- a/src/component/axis/AngleAxisView.js +++ b/src/component/axis/AngleAxisView.js @@ -96,19 +96,24 @@ export default AxisView.extend({ _axisLine: function (angleAxisModel, polar, ticksAngles, radiusExtent) { var lineStyleModel = angleAxisModel.getModel('axisLine.lineStyle'); - var circle = new graphic.Circle({ - shape: { - cx: polar.cx, - cy: polar.cy, - r: radiusExtent[getRadiusIdx(polar)] - }, - style: lineStyleModel.getLineStyle(), - z2: 1, - silent: true - }); - circle.style.fill = null; - - this.group.add(circle); + for (var rx = 0; rx < radiusExtent.length; ++rx) { + // Draw a circle for radius like [0, 100], and two circles for [20, 100] + if (radiusExtent[rx] > 0) { + var circle = new graphic.Circle({ + shape: { + cx: polar.cx, + cy: polar.cy, + r: radiusExtent[rx] + }, + style: lineStyleModel.getLineStyle(), + z2: 1, + silent: true + }); + circle.style.fill = null; + + this.group.add(circle); + } + } }, /** diff --git a/src/coord/polar/polarCreator.js b/src/coord/polar/polarCreator.js index d8f93e85df..9c45256179 100644 --- a/src/coord/polar/polarCreator.js +++ b/src/coord/polar/polarCreator.js @@ -47,10 +47,23 @@ function resizePolar(polar, polarModel, api) { var radiusAxis = polar.getRadiusAxis(); var size = Math.min(width, height) / 2; - var radius = parsePercent(polarModel.get('radius'), size); + + var radius = polarModel.get('radius'); + if (radius == null) { + radius = [0, "100%"]; + } + else if (typeof radius === 'number' || typeof radius === 'string') { + // r0 = 0 + radius = [0, radius]; + } + radius = [ + parsePercent(radius[0], size), + parsePercent(radius[1], size) + ]; + radiusAxis.inverse - ? radiusAxis.setExtent(radius, 0) - : radiusAxis.setExtent(0, radius); + ? radiusAxis.setExtent(radius[1], radius[0]) + : radiusAxis.setExtent(radius[0], radius[1]); } /** From e5adac3afe19b1532600713a41a0848107db372e Mon Sep 17 00:00:00 2001 From: Ovilia Date: Tue, 15 Oct 2019 16:33:28 +0800 Subject: [PATCH 5/9] test(polar): update polar tests --- test/polar-rounded.html | 32 ++++++++++++++++--------- test/runTest/actions/__meta__.json | 2 +- test/runTest/actions/polar-rounded.json | 2 +- 3 files changed, 23 insertions(+), 13 deletions(-) diff --git a/test/polar-rounded.html b/test/polar-rounded.html index 53585a5cfc..5badccce70 100644 --- a/test/polar-rounded.html +++ b/test/polar-rounded.html @@ -45,6 +45,8 @@
+
+ + + + From 3f3c34d15d9b172901087981c6022730ceafdd6b Mon Sep 17 00:00:00 2001 From: Ovilia Date: Wed, 16 Oct 2019 15:26:07 +0800 Subject: [PATCH 7/9] style: fix code style --- src/util/symbol.js | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/util/symbol.js b/src/util/symbol.js index 8113258d1b..25a7603016 100644 --- a/src/util/symbol.js +++ b/src/util/symbol.js @@ -181,16 +181,20 @@ export var Sausage = graphic.extendShape({ if (lessThanCircle) { ctx.moveTo(unitStartX * r0 + x, unitStartY * r0 + y); - ctx.arc(unitStartX * rCenter + x, unitStartY * rCenter + y, dr, - -Math.PI + startAngle, startAngle, !clockwise); + ctx.arc( + unitStartX * rCenter + x, unitStartY * rCenter + y, dr, + -Math.PI + startAngle, startAngle, !clockwise + ); } ctx.arc(x, y, r, startAngle, endAngle, !clockwise); ctx.moveTo(unitEndX * r + x, unitEndY * r + y); - ctx.arc(unitEndX * rCenter + x, unitEndY * rCenter + y, dr, - endAngle - Math.PI * 2, endAngle - Math.PI, !clockwise); + ctx.arc( + unitEndX * rCenter + x, unitEndY * rCenter + y, dr, + endAngle - Math.PI * 2, endAngle - Math.PI, !clockwise + ); if (r0 !== 0) { ctx.arc(x, y, r0, endAngle, startAngle, clockwise); From e6ab1fda57c7a7d5ae4039b379944e508ee03506 Mon Sep 17 00:00:00 2001 From: Ovilia Date: Fri, 18 Oct 2019 10:45:30 +0800 Subject: [PATCH 8/9] fix: remove fixClipWithShadow --- src/util/graphic.js | 5 ----- src/util/symbol.js | 4 ---- 2 files changed, 9 deletions(-) diff --git a/src/util/graphic.js b/src/util/graphic.js index 6591c4d0cc..569d8a6a9b 100644 --- a/src/util/graphic.js +++ b/src/util/graphic.js @@ -42,7 +42,6 @@ import RadialGradient from 'zrender/src/graphic/RadialGradient'; import BoundingRect from 'zrender/src/core/BoundingRect'; import IncrementalDisplayable from 'zrender/src/graphic/IncrementalDisplayable'; import * as subPixelOptimizeUtil from 'zrender/src/graphic/helper/subPixelOptimize'; -import fixPathClipWithShadow from 'zrender/src/graphic/helper/fixClipWithShadow'; import {Sausage} from './symbol'; @@ -77,10 +76,6 @@ export function extendShape(opts) { return Path.extend(opts); } -export function fixClipWithShadow(conditionCheck) { - return fixPathClipWithShadow(Path.prototype.brush, conditionCheck); -} - /** * Extend path */ diff --git a/src/util/symbol.js b/src/util/symbol.js index 25a7603016..59d2b7cfb4 100644 --- a/src/util/symbol.js +++ b/src/util/symbol.js @@ -154,10 +154,6 @@ export var Sausage = graphic.extendShape({ clockwise: true }, - brush: graphic.fixClipWithShadow(function () { - return this.startAngle === this.endAngle; - }), - buildPath: function (ctx, shape) { var x = shape.cx; var y = shape.cy; From 58025dd69e42ab492777e91ec54fadd1f04c7704 Mon Sep 17 00:00:00 2001 From: Ovilia Date: Fri, 18 Oct 2019 11:33:27 +0800 Subject: [PATCH 9/9] fix: forgot to remove circles --- src/component/axis/AngleAxisView.js | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/src/component/axis/AngleAxisView.js b/src/component/axis/AngleAxisView.js index 10e141eea2..cff1689b9c 100644 --- a/src/component/axis/AngleAxisView.js +++ b/src/component/axis/AngleAxisView.js @@ -128,25 +128,6 @@ export default AxisView.extend({ } shape.style.fill = null; this.group.add(shape); - - for (var rx = 0; rx < radiusExtent.length; ++rx) { - // Draw a circle for radius like [0, 100], and two circles for [20, 100] - if (radiusExtent[rx] > 0) { - var circle = new graphic.Circle({ - shape: { - cx: polar.cx, - cy: polar.cy, - r: radiusExtent[rx] - }, - style: lineStyleModel.getLineStyle(), - z2: 1, - silent: true - }); - circle.style.fill = null; - - this.group.add(circle); - } - } }, /**