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

Fix offset on doughnut charts #10469

Merged
merged 1 commit into from
Aug 3, 2022
Merged

Fix offset on doughnut charts #10469

merged 1 commit into from
Aug 3, 2022

Conversation

Zivangu9
Copy link
Contributor

@Zivangu9 Zivangu9 commented Jul 6, 2022

Fix #10465

Adding another half offset can fix the cropped graphics error.

Reproducible sample

I use the examples that doc-code-hub gave in the issue
https://stackblitz.com/edit/web-platform-dr6rsv?file=js%2Fdata.js,index.html

@@ -272,7 +272,7 @@ export default class DoughnutController extends DatasetController {
const options = this.resolveDataElementOptions(i);
max = Math.max(max, options.offset || 0, options.hoverOffset || 0);
}
return max;
return max * 1.5;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How was 1.5 determined here?

Copy link
Contributor Author

@Zivangu9 Zivangu9 Jul 7, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Each arc is offset from center 1/4 offset

const offset = (options.offset || 0) / 2;

radiusOffset = offset / 2;

ctx.translate(Math.cos(halfAngle) * radiusOffset, Math.sin(halfAngle) * radiusOffset);

Except when the arc measures more than 180 degrees, in that case is 1/2 offset
And this is the cause of the problem, if there is an arc greater than 180 the offset is increased by an extra 1/2
if (this.circumference >= PI) {
radiusOffset = offset;
}

In addition to the separation from the center to the radius of the arc, the radiusOffset is increased again
const endAngle = drawArc(ctx, this, radiusOffset, spacing);

I just saw that if there are 2 arcs of 180 the offset would be doubled

@Zivangu9
Copy link
Contributor Author

Zivangu9 commented Jul 8, 2022

Do you think the solution is correct, or should I look for a different one?

@etimberg
Copy link
Member

etimberg commented Jul 9, 2022

@Zivangu9 sorry, I didn't have internet yesterday

I think I understand where this is coming from. Would it be possible to add a test for the 2 arcs that are each 180 degrees? I'd be curious to see how this performs

@Zivangu9
Copy link
Contributor Author

Zivangu9 commented Jul 9, 2022

I was testing with two 180 degree arcs and now I understand a little better.
The center offset is always 1/4, but the radius increment is 1/2 for 180 degree arcs, so when it's 2 180 arcs it's just 1.5 offset. When it is only one arc greater than 180 it becomes 1.25. And if there are no arcs greater than 180, the increment is 1 offset.
https://stackblitz.com/edit/web-platform-dr6rsv?file=js%2Fdata.js,index.html

@etimberg
Copy link
Member

etimberg commented Jul 9, 2022

It almost looks like the angle changes should only apply to arcs that are not 180 degrees exactly.

@kurkle
Copy link
Member

kurkle commented Jul 10, 2022

There is a jump at the end of the animation, when the arcs reach 180 degree circumference. That is another problem.

I think a proper fix would be getting rid of this kind of condition in the arc element.

@kurkle
Copy link
Member

kurkle commented Jul 10, 2022

I experimented a little with it.
Replaced

if (this.circumference >= PI) {
radiusOffset = offset;
}

with

      const fix = 1 + Math.sin(-Math.min(PI, circumference));
      radiusOffset = offset / 2 * fix;

to make the animations smooth for large arcs. @etimberg any thoughts?

https://stackblitz.com/edit/web-platform-ayr13m?file=js%2Fdata.js

@etimberg
Copy link
Member

I experimented a little with it. Replaced

if (this.circumference >= PI) {
radiusOffset = offset;
}

with

      const fix = 1 + Math.sin(-Math.min(PI, circumference));
      radiusOffset = offset / 2 * fix;

to make the animations smooth for large arcs. @etimberg any thoughts?

https://stackblitz.com/edit/web-platform-ayr13m?file=js%2Fdata.js

The animation in that version looks really good 👍

@Zivangu9
Copy link
Contributor Author

That seems like a better solution to the problem, do I make the changes in the PR?

Fix offset on doughnut charts
@stockiNail
Copy link
Contributor

sorry if I'm jumping in the thread. Issue #10220 was addressing the issue about hover offset (similar of the offset one).
I didn't check the PR in deep, but I was thinking if make sense to address hoverOffset option and not only the offset one.

@kurkle
Copy link
Member

kurkle commented Jul 11, 2022

@stockiNail probably the same issue.

@LeeLenaleee
Copy link
Collaborator

Since this can drastically change how some charts are shown I am not sure if this should be considered a bug fix or a breaking change

@kurkle kurkle added this to the Version 3.9.0 milestone Jul 18, 2022
@etimberg
Copy link
Member

Hmm, not sure if this is breaking or not. The previous behaviour was pretty buggy.

@LeeLenaleee
Copy link
Collaborator

That is true, but since we want to start working on V4 after 3.9 I think it will be the safer option to postpone it till V4

@etimberg
Copy link
Member

Fair, if we aim to get a 3.9 out quickly this won't have to sit around for a while

@kurkle kurkle merged commit 9ab50e6 into chartjs:master Aug 3, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Pie cropped when using Offset in dataset (with specific data)
5 participants