Skip to content

Commit

Permalink
Merge pull request #19076 from linghaoSu/feat/pie_pad-angle
Browse files Browse the repository at this point in the history
feat(pie): add padAngle for pie
  • Loading branch information
Ovilia authored Sep 15, 2023
2 parents fbee94d + 4ce776c commit b37d67c
Show file tree
Hide file tree
Showing 3 changed files with 195 additions and 13 deletions.
3 changes: 3 additions & 0 deletions src/chart/pie/PieSeries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,8 @@ export interface PieSeriesOption extends
clockwise?: boolean
startAngle?: number
endAngle?: number | 'auto'
padAngle?: number;

minAngle?: number
minShowLabelAngle?: number

Expand Down Expand Up @@ -219,6 +221,7 @@ class PieSeriesModel extends SeriesModel<PieSeriesOption> {
clockwise: true,
startAngle: 90,
endAngle: 'auto',
padAngle: 0,
// 最小角度改为0
minAngle: 0,

Expand Down
72 changes: 59 additions & 13 deletions src/chart/pie/pieLayout.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,10 +94,14 @@ export default function pieLayout(

let startAngle = -seriesModel.get('startAngle') * RADIAN;
let endAngle = seriesModel.get('endAngle');
const padAngle = seriesModel.get('padAngle') * RADIAN;

endAngle = endAngle === 'auto' ? startAngle - PI2 : -endAngle * RADIAN;

const minAngle = seriesModel.get('minAngle') * RADIAN;

const minAndPadAngle = minAngle + padAngle;

let validDataCount = 0;
data.each(valueDim, function (value: number) {
!isNaN(value) && validDataCount++;
Expand All @@ -118,6 +122,7 @@ export default function pieLayout(

const dir = clockwise ? 1 : -1;
const angles = [startAngle, endAngle];
const halfPadAngle = dir * padAngle / 2;
normalizeArcAngles(angles, !clockwise);

[startAngle, endAngle] = angles;
Expand Down Expand Up @@ -159,19 +164,34 @@ export default function pieLayout(
angle = angleRange / validDataCount;
}

if (angle < minAngle) {
angle = minAngle;
restAngle -= minAngle;

if (angle < minAndPadAngle) {
angle = minAndPadAngle;
restAngle -= minAndPadAngle;
}
else {
valueSumLargerThanMinAngle += value;
}

const endAngle = currentAngle + dir * angle;

// calculate display angle
let actualStartAngle = 0;
let actualEndAngle = 0;

if (padAngle > angle) {
actualStartAngle = currentAngle + dir * angle / 2;
actualEndAngle = actualStartAngle;
}
else {
actualStartAngle = currentAngle + halfPadAngle;
actualEndAngle = endAngle - halfPadAngle;
}

data.setItemLayout(idx, {
angle: angle,
startAngle: currentAngle,
endAngle: endAngle,
startAngle: actualStartAngle,
endAngle: actualEndAngle,
clockwise: clockwise,
cx: cx,
cy: cy,
Expand All @@ -184,19 +204,32 @@ export default function pieLayout(
currentAngle = endAngle;
});

// Some sector is constrained by minAngle
// Some sector is constrained by minAngle and padAngle
// Rest sectors needs recalculate angle
if (restAngle < PI2 && validDataCount) {
// Average the angle if rest angle is not enough after all angles is
// Constrained by minAngle
// Constrained by minAngle and padAngle
if (restAngle <= 1e-3) {
const angle = angleRange / validDataCount;
data.each(valueDim, function (value: number, idx: number) {
if (!isNaN(value)) {
const layout = data.getItemLayout(idx);
layout.angle = angle;
layout.startAngle = startAngle + dir * idx * angle;
layout.endAngle = startAngle + dir * (idx + 1) * angle;

let actualStartAngle = 0;
let actualEndAngle = 0;

if (angle < padAngle) {
actualStartAngle = startAngle + dir * (idx + 1 / 2) * angle;
actualEndAngle = actualStartAngle;
}
else {
actualStartAngle = startAngle + dir * idx * angle + halfPadAngle;
actualEndAngle = startAngle + dir * (idx + 1) * angle - halfPadAngle;
}

layout.startAngle = actualStartAngle;
layout.endAngle = actualEndAngle;
}
});
}
Expand All @@ -206,10 +239,23 @@ export default function pieLayout(
data.each(valueDim, function (value: number, idx: number) {
if (!isNaN(value)) {
const layout = data.getItemLayout(idx);
const angle = layout.angle === minAngle
? minAngle : value * unitRadian;
layout.startAngle = currentAngle;
layout.endAngle = currentAngle + dir * angle;
const angle = layout.angle === minAndPadAngle
? minAndPadAngle : value * unitRadian;

let actualStartAngle = 0;
let actualEndAngle = 0;

if (angle < padAngle) {
actualStartAngle = currentAngle + dir * angle / 2;
actualEndAngle = actualStartAngle;
}
else {
actualStartAngle = currentAngle + halfPadAngle;
actualEndAngle = currentAngle + dir * angle - halfPadAngle;
}

layout.startAngle = actualStartAngle;
layout.endAngle = actualEndAngle;
currentAngle += dir * angle;
}
});
Expand Down
133 changes: 133 additions & 0 deletions test/pie-pad-angle.html

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit b37d67c

Please sign in to comment.