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

Add tooltip annotation functionality #7127

Draft
wants to merge 65 commits into
base: master
Choose a base branch
from
Draft

Conversation

kb-
Copy link

@kb- kb- commented Aug 22, 2024

This PR addresses #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)
331887266-f7258b47-6eb2-4c3c-a3ce-f23899fe57e1
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)**
    image
  • ✓ 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
  • ✓ 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
  • 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);

@kb-
Copy link
Author

kb- commented Aug 28, 2024

This is my first contribution to a large project like this.

Most CI tests pass, but I need some help for the mock-validation test. test\image\mocks\tooltip_heatmap.json
It looks like I have to add the tooltip and tooltiptemplate attributes to each trace type attributes.js.

I've been able to add tooltiptemplate (string) to the heatmap trace attributes. src\traces\heatmap\attributes.js
But I don't know how to add tooltip (object; it should accept the same attributes than annotations)

node tasks/test_mock.js tooltip_heatmap

validating tooltip_heatmap
Expected false to be true
file: tooltip_heatmap
[
{
"code": "unused",
"container": "data",
"trace": 0,
"path": [
"tooltip"
],
"astr": "tooltip",
"msg": "In data trace 0, container tooltip did not get coerced"
}
]

C:\Users\olivi\Documents\code\plotly.js\tasks\test_mock.js:44
throw error;
^
Failed at {
"mocks": [
"tooltip_heatmap"
]
}
(Use node --trace-uncaught ... to show where the exception was thrown)

@gvwilson
Copy link
Contributor

@kb- I'll try to get someone to have a look next week - thanks.

@gvwilson gvwilson added feature something new community community contribution P3 not needed for current cycle labels Aug 28, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
community community contribution feature something new P3 not needed for current cycle
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants