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(bullet): the tooltip shows up around the drawn part of the chart only #1278

Merged
merged 21 commits into from
Aug 4, 2021

Conversation

monfera
Copy link
Contributor

@monfera monfera commented Jul 30, 2021

Summary

An overall bounding box of all graphical elements is computed, with some padding especially around text and potentially thin bounding box rectangle shapes for Fitts law compliance. The tooltip now only activates within this padded, rectangular capture zone. The bounding box is approximate, as the user has no exact notion of which pixel is still gauge/goal/bullet and which isn't.

tooltip

Closes #1187

Details

Preparational PR, which was just refactoring: #1246

Implementation details: the bullet/gauge/goal is composited from three geoms:

  • line
  • arc
  • text

Each of them gained a method for computing an overall bounding box around it. While it'd be possible to convert the chart to SVG or HTML and use DOM event capture, either way there would still be a need for at least an extra element in the DOM tree. Due to Fitts law and other considerations, drawn shapes are only a subset of where the tooltip must activate.

It's a draft PR because the individual methods need further tweaks, to solve text alignment and layout offset issues.

There are other small type and code layout improvements resulting from drive-by-coding. Each commit is either functional, or explicitly one of these misc improvements (mostly).

Issues

Checklist

  • The proper chart type label was added (e.g. :xy, :partition) if the PR involves a specific chart type
  • The proper feature label was added (e.g. :interactions, :axis) if the PR involves a specific chart feature
  • Whenever possible, please check if the closing issue is connected to a running GH project
  • This was checked for cross-browser compatibility

@monfera monfera added :tooltip Related to hover tooltip :goal/gauge (old) Old Goal/Gauge chart related issues labels Jul 30, 2021
@monfera monfera marked this pull request as draft July 30, 2021 16:22
Copy link
Collaborator

@nickofthyme nickofthyme left a comment

Choose a reason for hiding this comment

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

Code changes LTGM, much more organized!

@@ -61,8 +77,8 @@ export class Arc implements Mark {
protected readonly x: number;
protected readonly y: number;
protected readonly radius: number;
protected readonly startAngle: number;
protected readonly endAngle: number;
protected readonly startAngle: Radian;
Copy link
Collaborator

Choose a reason for hiding this comment

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

👍🏼

@monfera monfera marked this pull request as ready for review August 2, 2021 14:57
Comment on lines 100 to 105
const x = e.clientX - box.left;
const y = e.clientY - box.top;
const capture = fullBoundingBox(this.ctx, this.props.geoms);
if (capture.x0 <= x && x <= capture.x1 && capture.y0 <= y && y <= capture.y1) {
return picker(x - chartCenter.x, y - chartCenter.y);
}
Copy link
Member

Choose a reason for hiding this comment

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

This will execute the fullBoundingBox call at 60FPS, recalculating everytime the same capture rectangle.
Can we just reuse the one coming from the getCaptureBoundingBox selector?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks, good catch, done in a54735c

Comment on lines +189 to +190
this.setCanvasTextState(ctx);
const box = ctx.measureText(this.text);
Copy link
Member

Choose a reason for hiding this comment

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

Can we reuse measureText that also brings in the font, size etc?

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 thought about it, but these bounding box methods are mirrors of the actual rendering code (this.setCanvasTextState(ctx) and precise input is fully shared), so it's already as close to font, size etc. as possible. The function measureText in src/common assumes text Box objects which are only used in most partition charts, due to the multirow layout, where its purpose is, adaptive font sizing and line breaks, so it's not a close fit currently.

It'd be a good idea to eventually migrate bullet graphs to that though: the user would specify the bounding box into which the bullet/goal titles must fit. It'd be a larger, API-involving task. Also, then the bounding box would be given, because that's what the user wants to fill.

If you meant CanvasTextBBoxCalculator, it's a heavier weight machinery that attaches/detaches to the DOM tree, stateful, allocates resources to dispose etc., it didn't seem necessary here. Also, the method in the PR is safe when introducing some other text property (say, we add fontStyle or some such), because the same code is called for text styling, while the CanvasTextBBoxCalculator needs explicit passing of properties one by one. I'm interested in learning about the circumstances where CanvasTextBBoxCalculator works but a simpler approach wouldn't.

Comment on lines 116 to 119
const angleFrom: Radian = Math.floor(this.startAngle / arcBoxSamplePitch) * arcBoxSamplePitch;
const angleTo: Radian = Math.ceil(this.endAngle / arcBoxSamplePitch) * arcBoxSamplePitch;

for (let angle: Radian = angleFrom; angle <= angleTo; angle += arcBoxSamplePitch) {
Copy link
Member

Choose a reason for hiding this comment

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

We need to be sure that angleFrom <= angleTo if not this will end up in a infinite loop

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks, good catch!

Copy link
Contributor Author

@monfera monfera Aug 3, 2021

Choose a reason for hiding this comment

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

The code bit has been updated for this issue

@monfera monfera requested a review from markov00 August 3, 2021 16:14
Copy link
Contributor

@rshen91 rshen91 left a comment

Choose a reason for hiding this comment

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

LGTM! Nice refactoring and story addition, tested locally.

Copy link
Collaborator

@nickofthyme nickofthyme left a comment

Choose a reason for hiding this comment

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

LGTM!

@monfera monfera merged commit a96cbb4 into elastic:master Aug 4, 2021
github-actions bot pushed a commit that referenced this pull request Aug 6, 2021
# [33.2.0](v33.1.0...v33.2.0) (2021-08-06)

### Bug Fixes

* heatmap snap domain to interval ([#1253](#1253)) ([b439182](b439182)), closes [#1165](#1165)
* hex colors to allow alpha channel ([#1274](#1274)) ([03b4f42](03b4f42))

### Features

* **bullet:** the tooltip shows up around the drawn part of the chart only ([#1278](#1278)) ([a96cbb4](a96cbb4))
* **legend:** multiline labels with maxLines option ([#1285](#1285)) ([e0eb096](e0eb096))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
:goal/gauge (old) Old Goal/Gauge chart related issues :tooltip Related to hover tooltip
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Bullet] Tooltips shouldn't appear on the entire canvas
4 participants