plotly.js
plotly.js copied to clipboard
Add tooltip annotation functionality
This PR addresses https://github.com/plotly/plotly.js/issues/7054
The tooltip function can be activated by a new modebar button.
It allows to add an annotation to every clicked point. By default, tooltips contain x, y and when available z, or ohlc data (open, high, low, close).
Tooltips can be customized with an optional tooltiptemplate (leverages existing hovertemplate code) and tooltip annotation options (leverages existing annotations code)
I added examples for various plot types in \test\image\mocks
Additional interactivity:
When a plot is created with editable: true
, the tooltips can be dragged around for placement or deleted interactively. Their text can also be edited. To delete a tooltip, click on its text and delete it.
Compatibility:
(active for plots with hasCartesian or hasGL2D)
- ✓ bar
- x barpolar (not active)
-
~ box (missing information in data.points[0], the tooltip is not very useful)
- ✓ candlestick
- x carpet (not active, same for hover and spike)
- x choropleth (not active)
- x choroplethmap (not active)
- x choroplethmapbox (not active)
- x cone (not active)
- ✓ contour
- x contourcarpet (not active, same for hover and spike)
- x densitymap (not active)
- x densitymapbox (not active)
- ~ funnel (wrong placement) Should disable? not very useful for this graph
- x funnelarea (not active)
- ✓ heatmap
- ~~✓ heatmapgl~~(trace type no longer exists)
- ✓ histogram
- ✓ histogram2d
- ✓ histogram2dcontour
- x icicle (not active)
- x image (not active)
- x indicator (not active)
- x isosurface (not active)
- x mesh3d (not active)
- ✓ ohlc
- x parcats (not active)
- x parcoords (not active)
- x pie (not active)
- ~~✓ pointcloud~~(trace type no longer exists)
- x sankey (not active)
- ✓ scatter
- x scatter3d (not active)
-
x scattercarpet:
- wrong placement, a and b missing, wrong y.
- note: implemented hover has a wrong y too (more obvious in scattercarpet-text)
- x scattergeo (not active)
- ✓ scattergl
- x scattermap (not active)
- x scattermapbox (not active)
- x scatterpolar (not active)
- x scatterpolargl (not active)
- x scattersmith (not active)
- x scatterternary (not active)
- ✓ splom
- x streamtube (not active)
- x sunburst (not active)
- x surface (not active)
- x table (not active, not useful)
- x treemap (not useful)
- x violin (missing information in data.points[0])
- x volume (not active)
- ✓ waterfall
Usage example:
// Generate date and time values
function generateDateTime(start, count) {
var dates = [];
var current = new Date(start);
for (var i = 0; i < count; i++) {
dates.push(new Date(current));
current.setHours(current.getHours() + 7);
}
return dates;
}
// Generate random y-values
function generateRandomYValues(count) {
return Array.from({ length: count }, function() {
return Math.random() * 20;
});
}
// Generate data points
var xValues = generateDateTime('2024-04-01T12:00:00Z', 10);
var trace1 = {
name: 'Trace 1',
x: generateDateTime('2024-04-01T12:00:00Z', 5),
y: generateRandomYValues(5),
type: 'scatter',
// Tooltip Template with:
// trace name,
// hour-minute-second,
// y value in exponential notation with 2 digits
tooltiptemplate: "%{fullData.name}<br>%{x|%H:%M:%S}<br>y: %{y:.2e}",
// Tooltip annotation custom format:
tooltip: {
align: 'left',
arrowcolor: 'blue',
arrowhead: 2, // Arrow type
arrowsize: 1.2,
arrowwidth: 1,
font: {
color: 'red',
family: 'Arial',
size: 16
},
showarrow: true,
xanchor: 'left'
}
};
var trace2 = {
name: 'Trace 2',
x: generateDateTime('2024-04-01T12:00:00Z', 5),
y: generateRandomYValues(5),
type: 'scatter',
// Tooltip uses default template and annotation format
};
var data = [trace1, trace2];
var layout = {
title: 'Custom Tooltip Example'
};
var config = {
editable: true, // editable allows Tooltip drag-positioning and deletion
modeBarButtonsToAdd: ['tooltip'] // Add the tooltip button
};
Plotly.newPlot('plot', data, layout, config);