Vega: Extended tooltip support?

Created on 21 Mar 2018  路  5Comments  路  Source: vega/vega

This issue proposes to extend Vega's tooltip support with convenience options that should also facilitate downstream configuration (by Vega-Lite, Altair, etc.). It relates to altair-viz/altair#240 and vega/vega-lite#3560; cc: @kanitw, @domoritz, @jakevdp. Comments welcomed!

Currently Vega supports a tooltip encoding channel, which expects a string (or string-coercible) value, and displays it within a tooltip by setting the HTML "title" attribute of the primary SVG or Canvas element. This basic mechanism can be extended by overriding the handleTooltip method of the base scenegraph Handler class.

Part 1: Tooltip Specification

The main proposal is to provide tooltip specification options beyond a single string:

  1. If the tooltip channel resolves to null or undefined, then no tooltip should be shown.
  2. If the tooltip channel resolves to an Object value (other than Date or Array), then all key-value pairs in the object should be included in the tooltip, one per line (e.g., "key1: value1\nkey2: value2").
  3. If the tooltip channel resolves to an Array, contained values will be recursively processed, with appended brackets ([, ]).
  4. If the tooltip channel resolves to any other value (e.g., boolean, number, string, date) it should be coerced to a string and shown.

Note that the above proposal easily accommodates showing all properties in a data object by setting the tooltip channel value to the backing datum. For example, "tooltip": {"signal": "datum"}.

Part 2: Extensible Tooltip Rendering

The core Vega library will leverage built-in browser support for tooltips via the HTML "title" attribute. More sophisticated approaches (e.g., tooltips shown within custom HTML elements) will remain the responsibility of third-party extensions. Custom tooltip handlers will be responsible for appropriately handling the tooltip channel values passed in by Vega. The additions above are intended to make it easier for extensions to "plug-in" while leveraging spec-level configuration support.

To facilitate local registration of custom tooltip handlers, the Vega View object will be extended with support for setting a custom tooltip handler on a per-View basis. Clients will be able to pass a tooltip handler as an option to the constructor, or potentially using a getter/setter method. See below for an example. These additions will allow individual views to directly employ customized tooltips, without the need for global registration by overriding the Handler prototype chain. (That said, global registration will still be a viable option if desired!)

Issues to Resolve

_Recursion_: Should we support arbitrary levels of nesting (e.g., due to tooltip values containing sub-arrays or sub-objects)? My inclination is to have Vega's default support limit the depth to one level only to prevent massive, unreadable tooltips.

_Array formatting_: Should array values be formatted on a single line of text or on separate lines? I lean towards a single line. Browser tooltips should automatically word-wrap as needed.

_Automatic value formatting_: Tooltip values explicitly defined within a Vega spec can be formatted (e.g., number and date formats) using signal expressions. However, when passing raw values (or objects containing raw values), standard string coercion will not always produce desirable values (e.g., numbers with too many significant digits, full date strings, etc.) Should Vega provide built-in support for more automatic formatting? If so, how? As a starting point I lean towards no built-in "automagic" support, but would be happy to consider workable proposals.

_Tooltip handler registration_: Currently a tooltip handler is a single method that gets invoked in response to encoded tooltip values. As an instance method of the Handler class, it has access to the DOM Canvas or SVG element via the this context. Is more context needed, such as a reference to the overarching View instance or some other means of accessing configuration information? My default position is to keep the design as-is, as third-party code could instantiate custom tooltip handlers with access to config information (via closures, etc.). For example, if custom configuration was included in the usermeta field of a Vega spec, third party code might access that spec and return an appropriately configured tooltip handler to include as a View constructor option. However, I'm open to hearing alternative points of view!

Example

For clarity, here is an example of what I have in mind:

// Vega JSON spec
const spec;

// Instantiate a custom tooltip handler (3rd party code)
// The handler generator may access spec.usermeta.tooltip (or similar) as needed
const tooltipHandler = tooltipHandler(spec);

// Instantiate the Vega View
const view = new vega.View(
  vega.parse(spec),
  {tooltipHandler: tooltipHandler} // register custom tooltip handler
);

Perhaps vega-embed can be extended to support a tooltip generator like that above, and perform this registration as needed? In that case vega-embed would not need to bundle a custom tooltip provider, but could be easily configured to include one when desired.

enhancement

Most helpful comment

We are working on bringing extended tooltip support to Vega-Lite and update Vega-Tooltip.

All 5 comments

Sounds great! Thanks for putting so much thought into this,

cc: @sirahd

Should we support arbitrary levels of nesting (e.g., due to tooltip values containing sub-arrays or sub-objects)? My inclination is to have Vega's default support limit the depth to one level only to prevent massive, unreadable tooltips.

I agree. One level is reasonable to begin with.

That said, given your proposal of array saying "contained values will be recursively processed", I'm not sure the recursing processing would work given we have one-level limit.

Array formatting: Should array values be formatted on a single line of text or on separate lines? I lean towards a single line. Browser tooltips should automatically word-wrap as needed.

Single line is good I think.

Automatic value formatting:

I agree with no auto-magic too.

In that case vega-embed would not need to bundle a custom tooltip provider, but could be easily configured to include one when desired.

I think the HTML tooltip generated by vega-tooltip will still be nicer than HTML title, so I think we should still consider shipping it with Vega embed (with an option to turn it off and uses vanilla tooltip).

Added in v3.3.0! Documentation for adding custom tooltip handlers is included in the View API docs.

I just added docs to all the marks too, e.g. here

We are working on bringing extended tooltip support to Vega-Lite and update Vega-Tooltip.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

mhf-ir picture mhf-ir  路  3Comments

donghaoren picture donghaoren  路  5Comments

chadbr picture chadbr  路  6Comments

rubjo picture rubjo  路  4Comments

divico picture divico  路  4Comments