elastic-charts
elastic-charts copied to clipboard
Tooltip redesign
Is your feature request related to a problem? Please describe.
As the chart functionality has grown over the past several months the current tooltip design has come to show its limitations for more complex charts.
Related to #580
Related issues/requests
- [x] #922
- [x] #835
- [x] #623
- [ ] #919
- [x] #872
- [x] #815
- [x] #562
- [ ] #655
- [x] #607
- [x] #296
- [x] #275
- [x] ~#241~
Related to tooltip placement:
- [x] #921
- [ ] #297
- [ ] #927
Describe the solution you'd like
The tooltip should be redesigned to handle all of the following use cases.
Multiple x or other values
Up until now, the tooltip is designed with the x value being constant for all values in the tooltip. This is no longer a valid assumption. Possibilities include a table style tooltip or indented values.
Table style
Indented style
The issue with the table style tooltip is that the field names for x, y, mark, etc. could be very long, creating a very wide tooltip that is less useful.
Aggregate values like min, max, etc.
When multiple values are allowed the logical progression would be to allow for aggregate values to be used per tooltip item. The indented files could be a better way to show this alongside the respective value, see mock up below.
Multiple values from the same series
Up until now, the tooltip would never have two of the same series in the tooltip with the exception of the banded values.
Having multiple values in the tooltip from series based on an extension of the current tooltip design would repeat the series name for each. This seems redundant and avoidable.
Upper and lower (aka banded) values
Currently, we support this style but the items are repeated for each series and the order is not configurable.
Describe alternatives you've considered
A clear and concise description of any alternative solutions or features you've considered.
Additional context
Add any other context or screenshots about the feature request here.
Checklist
- [x] this request is checked against already exist requests
- [x] every related Kibana issue is listed under
Kibana Cross Issues
list - [x]
kibana cross issue
tag is associated to the issue if any kibana cross issue is present
Also thought about a collapsed mode where if multiple values are to be displayed, they only appear in detail when hovered over a point/bar. Otherwise, they would be a simplified item, similar to what there is now.
@cchaos would be happy to get your insight on this whenever you have the time. Thanks!
I'd like to link this Kibana issue here so we can think of it when redesigning the tooltip https://github.com/elastic/kibana/issues/60013#issuecomment-638194954
@miukimiu Could you help out on the design side for this?
Yes, I can help. 🙌
Hey @miukimiu, any update on this design?
To add to this issue.
I think we might want to separate the cursor/crosshair styles from the tooltip styles/options.
The cursor/crosshairs should look something like...
const CrosshairType = Object.freeze({
VerticalCursor: 'vertical' as const,
Crosshairs: 'cross' as const,
Follow: 'follow' as const,
None: 'none' as const,
});
type CrosshairProps = {
snap?: boolean;
type?:
}
And the tooltip props should be something like...
type TooltipProps = TooltipPortalSettings<'chart'> & {
type?: 'simple' | 'complex' | 'table'; // future tooltip types
headerFormatter?: TooltipValueFormatter;
unit?: string;
customTooltip?: CustomTooltip;
};
Doing this could allow showing the crosshairs while hiding the tooltip and vice versa.
Hi @nich07as,
I'll prioritize this and I might have designs next week.
Tooltip should pass original datum
within the TooltipValue
to allow for users to extend the tooltip with additional properties outside of just the y
value.
cc: @smith
@miukimiu any timeline on this yet?
Already mentioned on Slack but posting for visibility: This is needed for https://github.com/elastic/kibana/issues/88852 which is scheduled for 7.13 🙏
Just linking a slide deck that tries to justify (see 1st page) the increasing separation of how we gather some focus info (x,y -> glyphs -> point(s)) and what and how we render, as well as adds an example for chart-as-tooltip
Topic: How do we handle very long tooltips. See https://github.com/elastic/kibana/pull/94247#pullrequestreview-612340782
The purpose of data visualization is to allow the high bandwidth sensation and ingest of information, and patterns therein, by our visual faculties. Make larger amounts of data perceivable in one glance.
The purpose of a tooltip is to provide contextual information for something that's in current focus.
Traditional tooltips consist of one or a few properties (eg. name/value) for one, or very few items.
A tooltip is a display of a subset of data, activated upon focusing on a subset of data in the original viz.
What applies to the role of original dataviz equally applies to what's shown inside the tooltip.
We wouldn't visualize an array of dozens of numbers, key/values or tuples in a table and call it a day—we would contemplate what the right form is to show the data (show top 5, and "Other"? show a viz? show a pageable/scrollable table?)
I think, equally, once the number of data points reaches the not too precise "few", a decision needs to be made:
- should the tooltip itself show a smaller amount, eg. first 5 rows, and allow scrolling to show more if needed?
- should it just be linked to a scrollable table that's beside the chart?
- should it be a non-scrollable, more granular display below the chart, ie. single row detail as here or here?
- should the tooltip display something that is more appropriate for the contents; eg. here, it's a single layer partitioning, so it could show a treemap in a normal rectangle
- should the tooltip only show the values for the hovered sub-bar, eg. the green rectangle?
- if eg. only the green is in focus (FR?) should the tooltip show a single value, or a time series?
- should the tooltip be made pinnable, to make it conducive to scrolling?
- should the tooltip just give up and limit its height to eg. 50% of chart height? (OK it can protrude, but we don't know, by how much)
#1 is not an option, because our tooltip is activated on hover, and is dependent on what we hover over within the chart, which means, there can't be interaction over the tooltip itself, such as scroll.
I think the tooltip has the inherent problem that it occludes data; the larger it is, the more it obscures. Sometimes, even regular sized tooltips are counterproductive. To provide more flexibility, we can
- extract out, and separate from the tooltip, the user gesture that currently leads to the tooltip activation; we can call it hover, and we should avoid calling it anything relating to tooltip; we shouldn't find "tooltip" anywhere in its source
- there are other gestures, eg.
click
,boxSelect
etc., in theory, also linkable to a tooltip or similar - allow our charts specification to have a
<CalloutTooltip>
spec; within this spec, the user could specify that it's activated byhover
; and what values, with what formatter, order, etc. should be done - basically, it's like a tabular display specification (this can even be a default, eg. if the user doesn't specify or disable anything, it's still present) - as an alternative, provide space below the chart, similar to eg. current small multiples
title
on the bottom, to render user formatted content on hover; ie. add an<Annotation>
or some such to the spec, with an appropriate formatter, referencinghover
- the crosshair line becomes something analogous to
<CalloutTooltip>
- it might even show some naked value (eg. time) on the top of the chart where the crosshair line ends, where there's no graphic below it;<CalloutTooltip>
has no idea whatsoever abouthover
, this word occurs 0 times in its code - these things could be hooked up to
hover
, but also to eg.click
, so it'd be possible to bring up a table or treemap with a single click on a bar, which can be hovered (I don't suggest full inception) - the specifictions in
Chart
are responsible for enlisting the criteria (fields) that are part of the filtering aspect of the hover/tooltip; eg. should it filter the hovered time bin (bar), or the hovered country (color) or both? This gets more complex with small multiples, bubble charts and scatterplots, so I'd prefer the flexibility of just specifying how the subsetting of the data is done, eg. by listing the fields that are criteria for equality filtering - this subsetting specification technically (and internally) lives between the hover gesture and the
<CalloutTooltip>
component, because one might want to drive multiple data from the same source (eg. show a crosshair in all small multiples, but show a tooltip only in the currently hovered one) - ie. the subsetting specification can be its ownTransform
spec, at least internally... - ... and the
Transform
is responsible for things like selecting only the top geom, or all geoms that fall below the cursor, or all geoms that are fully contained inside aboxSelect
, or all geoms that partially overlap with theboxSelect
- ... but to make it simple for the user, maybe they could add subsetting spec to the downstream terminal of
hover
or the upstream terminal of<CalloutTooltip>
(or both) - such approach for shorthand notation has plenty of examples in web standards (I think, such shorthands must be superficial, ie. they should be immediately converted to the internal API that has a Transform spec, channeling data from the gesture (and screen space geom data and relevant original data) to the rendering component)
We implemented something close to these examples for a bubble chart in APM in Kibana: https://github.com/elastic/kibana/pull/95577/files#diff-725dd22b1f6bbad4aa7a6186755643fdfd9d139de10f8ba32a2abf565af4e28a
It works, but took quite a bit of copying from the elastic-charts source and assumes those classnames continue to work. It also may have been helpful if the arguments passed through components as well as data, so I could have something like:
({ ContainerComponent, HeaderComponent, values }) => <ContainerComponent>
<HeaderComponent>
<MyCustomTooltipBody {...values} />
</HeaderComponent>
</ContainerComponent>
(not that specific API, but the feature of being able to compose pieces of the tooltip.)
we're going to need the ability to have multiple actions on a selection or range selection of data because of these cases:
- filtering (most common case today)
- take selection "somewhere else" - in observability, for example, "open in APM"
- creating annotations (although, this could be handled with an authoring 'mode' on the vis editor side) CC @MichaelMarcialis
i've also added these to the requirements doc that mirrors this meta
Hi all! I've been working on this tooltip redesign and I'll try to recap here the main aspects of the exploration I made.
Three important things:
- This work is not final, it's the first step of a conversation that we all are going to have in order to find the best solution for our tooltip. The goal of this exploration is to start discussing around it, please feel free to comment or to contribute in any way.
- I'm not fully respecting our design system, in parallel I'll be fixing this
- This would not have been possible without the previous work made by @miukimiu who made a really great first exploration from which I took a lot
Let's now get into the main part.
Concept
The first step of complexity that I would love to introduce is the possibility for the tooltip to be different according to the element that triggers it. Datapoints and background can have different set of elements that appear within the tooltip.
To be sure that users will always be able to access the background we should introduce a little inner margin at the top of the chart, this concept will be useful for other purposes as well (overall look & feel, scale rounding to pretty numbers...)
Floating vs Sticky
Everything is debatable, but I'm afraid that if we want to solve for all the requested features and issues that we have, we can't avoid defining a behaviour that will make the tooltip to stick on the chart and to be clickable. (Long list of categories and therefore scrollable tooltip, possibility to select the categories that we want, copy-paste values...) In this exploration the tooltip is floating when hovering elements and gets sticky once the users click.
Actions
The concept of introducing actions within the tooltip is not new, the Observability team has this in mind already and it could be really interesting for making the data exploration easier, faster and more impactful. Actions could differ according to the context but they can include things like:
- Create a new annotation
- Filter by time and by categories
- Go back in time
- Exclude non relevant points from dataseries
Possibilities here are endless and more important than this, it could be customised for all our different solutions.
Modular structure
The most important feature in this exploration is the tooltip flexibility, this would be granted by a modular structure able to accept different kind of elements according to the context. This way all the different teams will be able to customise how the tooltip behave following their needs. (eg. the same tooltip could be different in Observability and Discover, even if on the same typology of chart)
Tooltip Design & alternatives
The base design is quite simple, this new version includes the bottom bar with instructions on how to make it sticky.
These alternatives show how we can deal with different contexts and typology of information.
Behaviour
This is how we could make this to work. I'm posting here 3 animations (please consider that they are only prototypes made in Figma, they are not 100% what I'm envisioning but we are close). First of all let's start with the classic animation, when the users interact with a datapoint. The hover event shows the data values, the click event makes the tooltip sticky and allow the suers to interact with it.
NOTE: the proximity between the mouse click and the actions is crucial here, we'll have to be sure to position the tooltip correctly in order to minimise the users effort in activating these actions.
Second, here is what happen when the users interact with the background. There is already a little discussion about the data categories that disappear and it might be better to have them even after the click, this is exactly the kind of configuration that we have to talk about in order to find the best behaviour
Last one, the click & drag interaction. A bit more different to make in Figma but we can get the concept. While you drag the tooltip overview tells you how many elements have been selected and once you release the click you get the whole tooltip.
I know this get in conflict with the idea of panning along timeseries with the drag, we'll have to see how to make this work if we want to keep both functionalities.
Edge cases and exceptions
Few cases where we might want to create exceptions or at least to take in consideration how the tooltip should behave.
NOTE: please feel free to add any additional case that you have in mind, this is exactly the kind of issues that we have to solve! 🙂
In the end, as you can see there is a lot to work on! Hopefully the base concept behind this exploration should be good enough to solve most of the problems that we currently have or at least to be the starting point for that. As I said my goal is to start a conversation so please feel free to contribute, to comment and to add any kind of issue/feature that I might have forgot, I'm sure there is a lot of them! 🙂
Thanks, @gvnmagni. This is looking great!
I'm not fully respecting our design system, in parallel I'll be fixing this
Let me know when you reach the point of using Elastic UI, and likely, we can share some UI patterns. As @ryankeairns pointed out in the Product Requirement doc there are some designs patterns for actions inside the popover that we can reuse to have some consistency (filter in, filter out..): https://github.com/elastic/eui/issues/5132.
@gvnmagni great writeup, very thorough! The examples and prototypes paint a clear picture of where things are heading and leave me feeling excited for this to develop. Providing contextual data/actions based upon where you hover or click is resonating with me as is the scalability of the popover design you've put forth.
I look forward to participating in discussions, running through some use cases, and collaborating with the DataViz, Obs/Solution, and EUI teams.
Linking this other interesting requirement: https://github.com/elastic/kibana/issues/124034 add charts in tooltip
Been wanting to add a couple anecdotes & POCs for a while, finally found some time to put the examples together.
Pinnable
First up is tooltips that stay open indefinitely when pinned. On hover, the tooltip displays and the user can interact with any elements in the tooltip itself. To remain open when the anchor+tooltip is no longer under the user's cursor, each tooltip can individually be pinned open.
https://codesandbox.io/s/tooltip-exploration-pinning-2mdqc?file=/src/App.js
https://user-images.githubusercontent.com/313125/153497064-bab386c0-ffb1-41b8-b075-121438459026.mov
Delayed-sticky
This is a pattern I came across while playing Crusader Kings III. Tooltips open on hover but aren't interactive until some period of time expires (3s in my demo). I hate this pattern (as do others), and it took me an embarrassing amount of time to understand what caused a tooltip to remain open or not. Including here because it's a pattern in the wild, with an ask that we don't do anything like this 😅
https://codesandbox.io/s/tooltip-exploration-timed-fr8xe?file=/src/App.js
https://user-images.githubusercontent.com/313125/153497510-a3cd3816-36d5-4946-a3e5-6c18631925f5.mov
As it works in Crusader Kings, note the spinner in the top-right of the popovers to indicate time remaining in the delay.
https://user-images.githubusercontent.com/313125/153502275-1626ccd1-110b-46f3-873e-faaa86fab3d3.mp4
Thank you Chandler, I really appreciated the two examples, let me add a couple of considerations.
Pinnable
This option got me really interested because it would reduce the number of clicks required to get to interact with the tooltip and we will definitely have to take this in consideration. The only downside that I see is that moving through very close data points could be difficult if the tooltip stays on the interface, in your example the tooltip will cover the datapoints that live above the hovered one and to get to them we would have to move around to make the tooltip disappear and then get to the desired datapoints. This could became frustrating really fast
Delayed-sticky
I promise we won't do anything like this 🙂 Even though got me questioning myself why they did something like that, it really doesn't seem a good choice but there should be a reason
My 2 cents on these types of interactions:
Creating a new convention around the interaction of tooltips/popovers is tricky and would need to be fully tested. I would honestly advise against it because our products need to be fast to learn and quickly aid in the user's task vs needing to learn a new interaction. I think there's a very simple solution/guideline we can adhere to that would mostly solve this issue for all usages.
Interactive vs non-interactive tooltips:
A. If the anchoring element is interactive itself (button, link), the tooltip cannot contain any other interactive contents. This enforces the primary action to always be the interaction of the anchor and keeping the tooltip contents as strictly extra guidance that is not necessary for usability. B. If the anchoring element is not-interactive itself, but is strictly to open the tooltip/popover, then the tooltip can have interactive contents. This does not mean that they have to click to view the tooltip, it just means that the interaction on the element forces focus onto the element which would also render the tooltip. If the user's focus then transfers to the tooltip contents, the tooltip continues to remain visible.
These guideances are very similar currently in how we differentiate between tooltips and popovers (the components themselves), with the exception of allowing popovers on hover or tooltips to contain focusable elements.
There are other ways to allow quick access to functions that may have normally been the anchor's primary action, like allowing a specific key+click combination.
The trouble with "pinnable" tooltips, is that the user still has no control over the position of this element which means it's pretty unuseful when you have multiple that overlay each other.
To circle it back to charts specifically, if we're relying on tooltips for users to see the raw values of several points at once, we're using them wrong.
To circle it back to charts specifically, if we're relying on tooltips for users to see the raw values of several points at once, we're using them wrong.
Hi @cchaos can you please expand on this?
Mainly that if they only way that user's can compare the data values is by needing to open several tooltips, then we're overcomplicating what a chart is (which is usually a quick summary to visualize patterns) and we should be allowing user to view the raw data instead through some other mechanism / drilldown.
Totally agree. pinnable
tooltips should not be considered (at least within charts).
I think we agree that the design proposed by @gvnmagni goes in the direction of B
with a single tooltip/popover instance open at a time.
B. If the anchoring element is not-interactive itself, but is strictly to open the tooltip/popover, then the tooltip can have interactive contents.
I'd like to know your opinion @cchaos about the use of right-click
when the anchoring element is interactive itself, like for HTML links where you can right-click and open in new tab.
Right click action should be used sparingly and only as another means to the same action. It alienates touch screen users and has low discoverability. So as a shortcut to certain actions, sure, but not as the only way to that action.
Thank you Caroline! Just wanted to confirm that it's not planned to allow users to open up multiple tooltips on the same chart, values that can be compared will take place within the same tooltip (single categories of a stacked barchart, for example).
for custom tooltip patterns, there's a request for new line character support on TSVB today https://github.com/elastic/kibana/issues/66088
Another use case for having custom tooltips is in APM where the comparison features enables the user to compare two timeseries (related issue)
Current tooltip
![](https://user-images.githubusercontent.com/209966/174825785-ce523b2a-8d38-4592-9b68-3295aa726111.png)
Suggested tooltip
![](https://user-images.githubusercontent.com/209966/174826651-a8f0f9a0-b963-46ff-8bea-a699d3ee95f2.png)