elastic-charts icon indicating copy to clipboard operation
elastic-charts copied to clipboard

Tooltip redesign

Open nickofthyme opened this issue 4 years ago • 34 comments

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 image

Indented style image

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.

image

Multiple values from the same series

image

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.

image

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

nickofthyme avatar Apr 01 '20 15:04 nickofthyme

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.

nickofthyme avatar Apr 01 '20 17:04 nickofthyme

@cchaos would be happy to get your insight on this whenever you have the time. Thanks!

nickofthyme avatar Apr 01 '20 17:04 nickofthyme

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

markov00 avatar Jun 04 '20 14:06 markov00

@miukimiu Could you help out on the design side for this?

cchaos avatar Jun 10 '20 16:06 cchaos

Yes, I can help. 🙌

miukimiu avatar Jun 11 '20 15:06 miukimiu

Hey @miukimiu, any update on this design?

nickofthyme avatar Aug 03 '20 16:08 nickofthyme

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.

nickofthyme avatar Jan 26 '21 18:01 nickofthyme

Hi @nich07as,

I'll prioritize this and I might have designs next week.

miukimiu avatar Jan 28 '21 12:01 miukimiu

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

nickofthyme avatar Feb 24 '21 15:02 nickofthyme

@miukimiu any timeline on this yet?

nickofthyme avatar Feb 25 '21 18:02 nickofthyme

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 🙏

sorenlouv avatar Feb 25 '21 23:02 sorenlouv

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

monfera avatar Mar 11 '21 15:03 monfera

Topic: How do we handle very long tooltips. See https://github.com/elastic/kibana/pull/94247#pullrequestreview-612340782

charts_flickering_scrollbar2

nickofthyme avatar Mar 15 '21 16:03 nickofthyme

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:

  1. should the tooltip itself show a smaller amount, eg. first 5 rows, and allow scrolling to show more if needed?
  2. should it just be linked to a scrollable table that's beside the chart?
  3. should it be a non-scrollable, more granular display below the chart, ie. single row detail as here or here?
  4. 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
  5. should the tooltip only show the values for the hovered sub-bar, eg. the green rectangle?
  6. if eg. only the green is in focus (FR?) should the tooltip show a single value, or a time series?
  7. should the tooltip be made pinnable, to make it conducive to scrolling?
  8. 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 by hover; 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, referencing hover
  • 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 about hover, 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 own Transform 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 a boxSelect, or all geoms that partially overlap with the boxSelect
  • ... 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)

monfera avatar Mar 16 '21 10:03 monfera

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.)

smith avatar Mar 30 '21 18:03 smith

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

ghudgins avatar Oct 20 '21 20:10 ghudgins

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:

  1. 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.
  2. I'm not fully respecting our design system, in parallel I'll be fixing this
  3. 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. Hover elements

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...)

Inner margin

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.

Wireframe Tooltip

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:

  1. Create a new annotation
  2. Filter by time and by categories
  3. Go back in time
  4. 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)

Structure

Tooltip Design & alternatives

The base design is quite simple, this new version includes the bottom bar with instructions on how to make it sticky.

tooltip design

These alternatives show how we can deal with different contexts and typology of information.

tooltip alternatives

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.

Datapoint

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

Grid

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.

Clik   drag

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! 🙂

Frame 16 Frame 9 Frame 14 Frame 7 Frame 10

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! 🙂

gvnmagni avatar Dec 15 '21 11:12 gvnmagni

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.

miukimiu avatar Dec 15 '21 12:12 miukimiu

@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.

ryankeairns avatar Dec 15 '21 13:12 ryankeairns

Linking this other interesting requirement: https://github.com/elastic/kibana/issues/124034 add charts in tooltip

markov00 avatar Feb 04 '22 14:02 markov00

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

chandlerprall avatar Feb 10 '22 21:02 chandlerprall

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

gvnmagni avatar Feb 11 '22 10:02 gvnmagni

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.

cchaos avatar Feb 14 '22 15:02 cchaos

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?

markov00 avatar Feb 14 '22 17:02 markov00

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.

cchaos avatar Feb 14 '22 17:02 cchaos

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.

markov00 avatar Feb 14 '22 17:02 markov00

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.

cchaos avatar Feb 14 '22 17:02 cchaos

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).

gvnmagni avatar Feb 15 '22 13:02 gvnmagni

for custom tooltip patterns, there's a request for new line character support on TSVB today https://github.com/elastic/kibana/issues/66088

ghudgins avatar Feb 15 '22 16:02 ghudgins

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

Suggested tooltip

sorenlouv avatar Jun 21 '22 14:06 sorenlouv