Skip to content

Displaying axis labels other than x, y & z in the hovering popup using hovertitle attribute #3498

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

Closed
wants to merge 6 commits into from

Conversation

archmoj
Copy link
Contributor

@archmoj archmoj commented Jan 30, 2019

Supersedes #3317.
Fix #2618 and #265.
A new attribute hovertitle could be applied with each axis to enable this feature.
For example in 3D scenes if the x, y, z dimensions are presenting latitude, longitude and elevation (or other coordinates e.g. polar) this info could be displayed in the hovering popup instead of x, y and z.
@plotly/plotly_js

bypass ternary case

fix for pie scatterpolar and scattergeo cases

fix for heatmaps

added hovertitle new attribute on axes

apply hovertitle text and set defaults based on major version

latitude

removed circular dependencies by using a const and added new baseline

removed dflt of hovertitle and used dfltHoverTitle in coerce etc

updated baseline

hovertitle for polar still not working
@nicolaskruchten
Copy link
Contributor

nicolaskruchten commented Feb 1, 2019

I wonder if we shouldn't just prioritize hovertemplate instead and then they can do this directly using the more general mechanism, rather than adding a special attribute just for this?

@antoinerg
Copy link
Contributor

@nicolaskruchten I wonder the same thing since it should be possible to do anything with hovertemplate already 🤔

@nicolaskruchten
Copy link
Contributor

But hovertemplate isn’t supported in 3D land yet ;)

text += (text ? 'z: ' : '') + d.zLabel;
if(d.xLabel !== undefined) text += xLetter + ': ' + d.xLabel + '<br>';
if(d.yLabel !== undefined) text += yLetter + ': ' + d.yLabel + '<br>';
text += (text ? zLetter + ': ' : '') + d.zLabel;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm. So hovertitle for cartesian axes only has an effect for trace with a "z" field. That's ok, but should make that clear in the attribute description.

@@ -118,6 +118,7 @@ var radialAxisAttrs = {
// might need a 'titleside' and even 'titledirection' down the road

hoverformat: axesAttrs.hoverformat,
hovertitle: axesAttrs.hovertitle,
Copy link
Contributor

@etpinard etpinard Feb 12, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could set a "hard" dflt value: 'r' for radialaxis.hovertitle and 'θ' for angularaxis.hovertitle

@@ -304,6 +304,7 @@
"scene": {
"xaxis": {
"title": "Term",
"hovertitle": "Term",
Copy link
Contributor

@etpinard etpinard Feb 12, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding hovertitle to a few mock is ok, but we should really test this issue jasmine tests.

  • https://github.com/plotly/plotly.js/blob/master/test/jasmine/tests/hover_label_test.js for cartesian
  • it('should display to hover labels', function(done) {
    mouseEvent('mousemove', blankPos[0], blankPos[1]);
    assertHoverLabelContent([null, null], 'only on data points');
    function check(content, style, msg) {
    Lib.clearThrottle();
    mouseEvent('mousemove', pointPos[0], pointPos[1]);
    assertHoverLabelContent({nums: content}, msg);
    assertHoverLabelStyle(d3.select('g.hovertext'), style, msg);
    }
    check([
    'Component A: 0.5',
    'B: 0.25',
    'Component C: 0.25'
    ].join('\n'), {
    bgcolor: 'rgb(31, 119, 180)',
    bordercolor: 'rgb(255, 255, 255)',
    fontColor: 'rgb(255, 255, 255)',
    fontSize: 13,
    fontFamily: 'Arial'
    }, 'one label per data pt');
    Plotly.restyle(gd, {
    'hoverlabel.bordercolor': 'blue',
    'hoverlabel.font.family': [['Gravitas', 'Arial', 'Roboto']]
    })
    .then(function() {
    check([
    'Component A: 0.5',
    'B: 0.25',
    'Component C: 0.25'
    ].join('\n'), {
    bgcolor: 'rgb(31, 119, 180)',
    bordercolor: 'rgb(0, 0, 255)',
    fontColor: 'rgb(0, 0, 255)',
    fontSize: 13,
    fontFamily: 'Gravitas'
    }, 'after hoverlabel styling restyle call');
    return Plotly.restyle(gd, 'hoverinfo', [['a', 'b+c', 'b']]);
    })
    .then(function() {
    check('Component A: 0.5', {
    bgcolor: 'rgb(31, 119, 180)',
    bordercolor: 'rgb(0, 0, 255)',
    fontColor: 'rgb(0, 0, 255)',
    fontSize: 13,
    fontFamily: 'Gravitas'
    }, 'after hoverlabel styling restyle call');
    })
    .catch(failTest)
    .then(done);
    });
    for ternary
  • https://github.com/plotly/plotly.js/blob/master/test/jasmine/tests/gl3d_plot_interact_test.js#L107 for gl3d
  • describe('Test scatterpolar hover:', function() {
    var gd;
    afterEach(destroyGraphDiv);
    function run(specs) {
    gd = createGraphDiv();
    var fig = Lib.extendDeep(
    {width: 700, height: 500},
    specs.mock || require('@mocks/polar_scatter.json')
    );
    if(specs.patch) {
    fig = specs.patch(fig);
    }
    var pos = specs.pos || [200, 200];
    return Plotly.plot(gd, fig).then(function() {
    mouseEvent('mousemove', pos[0], pos[1]);
    assertHoverLabelContent(specs);
    });
    }
    [{
    desc: 'base',
    nums: 'r: 4.022892\nθ: 128.342°',
    name: 'Trial 3'
    }, {
    desc: 'with hovertemplate',
    patch: function(fig) {
    fig.data[2].hovertemplate = 'template %{r} %{theta}';
    return fig;
    },
    nums: 'template 4.02289202968 128.342009045',
    name: 'Trial 3'
    }, {
    desc: 'with hovertemplate and empty trace name',
    patch: function(fig) {
    fig.data[2].hovertemplate = 'template %{r} %{theta}';
    fig.data[2].name = '';
    return fig;
    },
    nums: 'template 4.02289202968 128.342009045',
    name: ''
    }, {
    desc: '(no labels - out of sector)',
    patch: function(fig) {
    fig.layout.polar.sector = [15, 75];
    return fig;
    },
    pos: [144, 350],
    nums: '',
    name: ''
    }, {
    desc: 'on a `thetaunit: radians` polar subplot',
    patch: function(fig) {
    fig.layout.polar.angularaxis.thetaunit = 'radians';
    return fig;
    },
    nums: 'r: 4.022892\nθ: 2.239991',
    name: 'Trial 3'
    }, {
    desc: 'on log radial axis',
    patch: function(fig) {
    fig.layout.polar.radialaxis.type = 'log';
    return fig;
    },
    nums: 'r: 1.108937\nθ: 115.4969°',
    name: 'Trial 3'
    }, {
    desc: 'on fills',
    mock: require('@mocks/polar_fills.json'),
    pos: [300, 230],
    nums: 'trace 2',
    name: ''
    }, {
    desc: 'on category axes',
    mock: require('@mocks/polar_categories.json'),
    patch: function(fig) {
    fig.data.forEach(function(t) { t.fill = 'none'; });
    return fig;
    },
    pos: [465, 90],
    nums: 'r: 4\nθ: d',
    name: 'angular cate...'
    }, {
    desc: 'on a subplot with hole>0',
    patch: function(fig) {
    fig.layout.polar.hole = 0.2;
    return fig;
    },
    nums: 'r: 1.108937\nθ: 115.4969°',
    name: 'Trial 3'
    }, {
    desc: 'with custom text scalar',
    patch: function(fig) {
    fig.data.forEach(function(t) { t.text = 'a'; });
    return fig;
    },
    nums: 'r: 4.022892\nθ: 128.342°\na',
    name: 'Trial 3'
    }, {
    desc: 'with custom text array',
    patch: function(fig) {
    fig.data.forEach(function(t) { t.text = t.r.map(String); });
    return fig;
    },
    nums: 'r: 4.022892\nθ: 128.342°\n4.02289202968',
    name: 'Trial 3'
    }]
    .forEach(function(specs) {
    it('should generate correct hover labels ' + specs.desc, function(done) {
    run(specs).catch(failTest).then(done);
    });
    });
    });
    for polar
  • describe('scattercarpet hover labels', function() {
    var gd;
    afterEach(destroyGraphDiv);
    function run(pos, fig, content) {
    gd = createGraphDiv();
    return Plotly.plot(gd, fig).then(function() {
    mouseEvent('mousemove', pos[0], pos[1]);
    assertHoverLabelContent({
    nums: content[0].join('\n'),
    name: content[1]
    });
    });
    }
    it('should generate hover label (base)', function(done) {
    var fig = Lib.extendDeep({}, require('@mocks/scattercarpet.json'));
    run(
    [200, 200], fig,
    [['a: 0.200', 'b: 3.500', 'y: 2.900'], 'a = 0.2']
    )
    .then(done);
    });
    it('should generate hover label with \'hoverinfo\' set', function(done) {
    var fig = Lib.extendDeep({}, require('@mocks/scattercarpet.json'));
    fig.data[5].hoverinfo = 'a+y';
    run(
    [200, 200], fig,
    [['a: 0.200', 'y: 2.900'], null]
    )
    .then(done);
    });
    it('should generate hover label with arrayOk \'hoverinfo\' settings', function(done) {
    var fig = Lib.extendDeep({}, require('@mocks/scattercarpet.json'));
    fig.data[5].hoverinfo = ['a+b', 'a+b', 'a+b', 'b+y'];
    run(
    [200, 200], fig,
    [['b: 3.500', 'y: 2.900'], null]
    )
    .then(done);
    });
    });
    for carpet

Oh and we should also add hovertitle to geo.lonaxis and geo.lataxis as displayed on https://codepen.io/etpinard/pen/gqKjeB

@archmoj
Copy link
Contributor Author

archmoj commented Mar 29, 2019

Closing now that hovertemplate is supported for 3D traces as well.

@archmoj archmoj closed this Mar 29, 2019
@etpinard etpinard deleted the fix2618-hovertitle branch March 29, 2019 19:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature something new
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants