Skip to content

fix(polar): angleAxis extent when boundaryGap is false #20184

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

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 9 additions & 3 deletions src/coord/polar/polarCreator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,9 +102,15 @@
// Fix extent of category angle axis
if (angleAxis.type === 'category' && !angleAxis.onBand) {
const extent = angleAxis.getExtent();
const diff = 360 / (angleAxis.scale as OrdinalScale).count();
Copy link
Contributor Author

Choose a reason for hiding this comment

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

We can see that the old code takes 360 as the range of endAngle to startAngle, which is not always the case.

angleAxis.inverse ? (extent[1] += diff) : (extent[1] -= diff);
angleAxis.setExtent(extent[0], extent[1]);
const angleModel = angleAxis.model;
const endAngle = angleModel.get('endAngle');
const spanAngle = (endAngle == null ? 360 : endAngle - angleModel.get('startAngle'))
* (angleAxis.inverse ? -1 : 1) ;

Check failure on line 108 in src/coord/polar/polarCreator.ts

View workflow job for this annotation

GitHub Actions / lint (18.x)

Unexpected whitespace before semicolon
const diff = spanAngle / (angleAxis.scale as OrdinalScale).count();
if (Math.abs(spanAngle + diff) >= 360) {
extent[1] += Math.abs(diff);
angleAxis.setExtent(extent[0], extent[1]);
Copy link
Member

@100pah 100pah Nov 4, 2024

Choose a reason for hiding this comment

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

In the current modified approach, this cases are not reasonable enougth:

image (already have a overlap between bar C and bar D) image (endAngle changes a little (from -195 to -198) but the appearance changes significantly.)

I think the "adjusting the extent" is a compromise. It's counter intuitive (the adjusted endAngle is not what use specified) but with out that user have avoid overlap manually.

I just try to modify it: make it keep at a "max span" when there is no enough space.

    // Fix extent of category angle axis
    if (angleAxis.type === 'category' && !angleAxis.onBand) {
        const extent = angleAxis.getExtent();
        let spanAngle = normalizeAngle((normalizeAngle(extent[1]) + 360 - normalizeAngle(extent[0])));
        if (angleAxis.inverse) {
            spanAngle = 360 - spanAngle;
        }
        const spanLimit = 360 - 360 / (angleAxis.scale as OrdinalScale).count();
        if (spanAngle >= spanLimit) {
            extent[1] = extent[0] + (angleAxis.inverse ? -1 : 1) * spanLimit;
            angleAxis.setExtent(extent[0], extent[1]);
        }
    }
    // FIXME: this kind of function should be placed in some common util file? (or similar one already exists?)
    // Normalize an angle value to `[0, 360)`.
    function normalizeAngle(val: number) {
        val = val % 360;
        val < 0 && (val += 360);
        return val;
    }

(it's just a illustrative code to show my current understanding.)

But about clockwise (inverse). I haven't understood the logic yet.
The current behavior (before this PR modified) seems weird:

image

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm not quite sure if we should use normalizeAngle because it erases some information. For example, with extent: [90, -450], it's more intuitive to understand this as a circle and a half. With normalizeAngle((normalizeAngle(extent[1]) + 360 - normalizeAngle(extent[0]))); we get => normalizeAngle(90 + 360 - 270) => normalizeAngle(180) => 180, which is a half circle. We could say we don't support a circle and a half as spanAngle so that one circle is used, but a half circle? I don't think this is expected with extent: [90, -450].

So I implemented this with a simpler logic: let spanAngle = (extent[1] - extent[0]) * (angleAxis.inverse ? -1 : 1);, which I tested to be right. Correct me if I'm wrong.

As for clockwise: false, I think this should be regarded as another bug because it's not introduced in this PR so I suggest fixing this in future PRs.

}
}
}

Expand Down
87 changes: 85 additions & 2 deletions test/bar-polar-basic-radial.html

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

1 change: 1 addition & 0 deletions test/runTest/actions/__meta__.json

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

1 change: 1 addition & 0 deletions test/runTest/actions/bar-polar-basic-radial.json

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

Loading