Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: support round cap for polar bars #11393

Merged
merged 11 commits into from
Oct 18, 2019
6 changes: 5 additions & 1 deletion src/chart/bar/BarSeries.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
});
16 changes: 10 additions & 6 deletions src/chart/bar/BarView.js
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand All @@ -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);
Expand Down Expand Up @@ -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
);
}

Expand Down Expand Up @@ -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)});
Expand All @@ -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)
});

Expand Down
31 changes: 18 additions & 13 deletions src/component/axis/AngleAxisView.js
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}
},
Ovilia marked this conversation as resolved.
Show resolved Hide resolved

/**
Expand Down
19 changes: 16 additions & 3 deletions src/coord/polar/polarCreator.js
Original file line number Diff line number Diff line change
Expand Up @@ -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') {
Ovilia marked this conversation as resolved.
Show resolved Hide resolved
// 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]);
}

/**
Expand Down
5 changes: 3 additions & 2 deletions src/layout/barPolar.js
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Ovilia marked this conversation as resolved.
Show resolved Hide resolved
|| !seriesModel.get('roundCap', true);

var valueAxisStart = valueAxis.getExtent()[0];

Expand Down Expand Up @@ -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) {
Expand Down
8 changes: 8 additions & 0 deletions src/util/graphic.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ 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';


var mathMax = Math.max;
Expand Down Expand Up @@ -75,6 +77,10 @@ export function extendShape(opts) {
return Path.extend(opts);
}

export function fixClipWithShadow(conditionCheck) {
return fixPathClipWithShadow(Path.prototype.brush, conditionCheck);
Ovilia marked this conversation as resolved.
Show resolved Hide resolved
}

/**
* Extend path
*/
Expand Down Expand Up @@ -1430,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);
Expand All @@ -1444,6 +1451,7 @@ export {
Text,
Circle,
Sector,
Sausage,
Ring,
Polygon,
Polyline,
Expand Down
84 changes: 84 additions & 0 deletions src/util/symbol.js
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,79 @@ var Pin = graphic.extendShape({
}
});

/**
* Sausage: similar to sector, but have half circle on both sides
* @inner
*/
export 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(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);
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 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;

if (lessThanCircle) {
ctx.moveTo(unitStartX * r0 + x, unitStartY * r0 + y);

ctx.arc(unitStartX * rCenter + x, unitStartY * rCenter + y, dr,
-Math.PI + startAngle, startAngle, !clockwise);
Ovilia marked this conversation as resolved.
Show resolved Hide resolved
}

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);

if (r0 !== 0) {
ctx.arc(x, y, r0, endAngle, startAngle, clockwise);

ctx.moveTo(unitStartX * r0 + x, unitEndY * r0 + y);
}

ctx.closePath();
}
});

/**
* Arrow shape
* @inner
Expand Down Expand Up @@ -179,6 +252,8 @@ var symbolCtors = {

pin: Pin,

sausage: Sausage,

arrow: Arrow,

triangle: Triangle
Expand Down Expand Up @@ -209,6 +284,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;
Expand Down
Loading