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

Remove empty labels from being candidates for overlap checking #19982

Open
wants to merge 4 commits into
base: master
Choose a base branch
from

Conversation

JesseSDevaney
Copy link

Bug Fix: This PR is intended to update the hideOverlap functionality to prevent empty labels ("") from being considered as candidates for the overlap checking.

  • Perhaps there is a better way of ignoring labels with no text, such as setting them to ignore = true in the label creation process and then checking if a label is ignored before doing the overlapping comparison check, but I was unsure if that was the right way to go. I am open to suggestions!

Details

Before: What was the problem?

Empty labels cause non-empty labels to be hidden

hideOverlap = true
Screenshot from 2024-05-28 20-13-54

hideOverlap = false
Screenshot from 2024-05-28 20-13-42

After: How does it behave after the fixing?

Empty labels no longer cause non-empty labels to be hidden

hideOverlap = true
Screenshot from 2024-05-28 20-10-38

hideOverlap = false
Screenshot from 2024-05-28 20-10-48

Document Info

  • This PR doesn't relate to document changes

Others

Merging options

  • Please squash the commits into a single one when merging.

Copy link
Contributor

github-actions bot commented Jun 19, 2024

The changes brought by this PR can be previewed at: https://echarts.apache.org/examples/editor?version=PR-19982@205b2b1

Copy link
Contributor

@Ovilia Ovilia left a comment

Choose a reason for hiding this comment

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

Please fix the lint problem first.

I don't think it's the correct way to fix this problem by hiding the empty text. It's better to find out why empty labelItem.rect is overlapping with others.

@JesseSDevaney
Copy link
Author

JesseSDevaney commented Jun 19, 2024

Please fix the lint problem first.


I don't think it's the correct way to fix this problem by hiding the empty text. It's better to find out why empty labelItem.rect is overlapping with others.

If empty labels are not hidden, they will still be considered in the overlapping process (labelLayoutHelper#L311-L364):

  1. Empty labels still have a bounding rect, it is just a bounding rect with zero width and zero height - i.e. a point
  2. Since they still have a bounding rect, you can still check if they are overlapping - i.e. does a non-empty label have a bounding rect that encompasses the empty labels point?
    • yes -> overlapping
    • no -> not overlapping
  3. Taking 1 and 2 together gives us: if an empty label point gets added to the displayedLabels list (see labelLayoutHelper.ts#L328) and a subsequent non-empty label has a bounding rect that encompasses the empty label, it will not be displayed for no reason other then that the empty label got added to the list before it and that there is no check to prevent empty labels from being added to the displayedLabels list

See my graphic below for visual context:

how-overlapping-labels-are-calculated-in-echarts

@Ovilia
Copy link
Contributor

Ovilia commented Jun 21, 2024

Thanks for the detailed explanation! It helped a lot.

Could we change the code of overlapping check algorithm to take special account for those text with zero width or zero height so that they always return false when overlapping checking.

The reason whiy I think we should update the checking algorithm instead of avoid adding text is that we need to make sure this problem fixed in a lower level so that in other places there won't be such cases if we forget to avoid adding empty text, or when the text content is dynamic.

@JesseSDevaney
Copy link
Author

Could we change the code of overlapping check algorithm to take special account for those text with zero width or zero height so that they always return false when overlapping checking.

The reason whiy I think we should update the checking algorithm instead of avoid adding text is that we need to make sure this problem fixed in a lower level so that in other places there won't be such cases if we forget to avoid adding empty text, or when the text content is dynamic.

I created a corresponding PR in the ZRender repository, where the overlapping check algorithm is.

Would you mind taking a look at that new PR and let me know if this was the kind of fix you were thinking of?

@@ -315,6 +315,13 @@ export function hideOverlap(labelList: LabelLayoutInfo[]) {
const transform = labelItem.transform;
const label = labelItem.label;
const labelLine = labelItem.labelLine;

// if the label has no text, remove it as a candidate for overlap checking
if (label.style?.text === '') {
Copy link
Contributor

Choose a reason for hiding this comment

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

After discussing with other members, we tend to believe it's better to make the change here instead of in ZRender because it may be controversial to define whether it's overlapping for an object with empty height/width inside other elements. So we still need to do the change here. I'll close the ZRender PR.

I think the overall logic is great, only that it may make greater sense if we could check the width and height of the text here instead of checking text === ''. And we try to use ?. in ECharts to reduce the compiled size, so label.style && lable.style.text is a better way to check like this.

Thanks for your contribution!

Copy link
Author

Choose a reason for hiding this comment

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

Thank you for the update.

I updated the conditional to check the width and height of the bounding rectangle instead of checking the label's text itself.

Let me know if the updated conditional is what you were expecting.

Thank you for your help, Ovilia!

@@ -321,6 +321,13 @@ export function hideOverlap(labelList: LabelLayoutInfo[]) {
globalRect.height -= 0.1;
globalRect.x += 0.05;
globalRect.y += 0.05;
// if a labels bounding rect has no width or height (i.e. no text)
// it should not be shown
if (globalRect.width <= 0 && globalRect.height <= 0) {
Copy link
Contributor

Choose a reason for hiding this comment

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

globalRect is the unioned bounding rect of the current label and previous labels. So should it be wiser to check labelItem.rect.width === 0 || labelItem.rect.height === 0 instead, before globalRect.copy(labelItem.rect)?

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.

2 participants