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

Use keyboard to navigate plotly charts #562

Open
johnpauls opened this issue May 24, 2016 · 20 comments
Open

Use keyboard to navigate plotly charts #562

johnpauls opened this issue May 24, 2016 · 20 comments
Labels
feature something new P2 considered for next cycle

Comments

@johnpauls
Copy link

I like plotly and its integration with R's ggplot, but I find that I cannot use the keyboard to interact with plotly charts or the button bar at the top of the charts. This is a concern when making websites more accessible to people with disabilities. Could this be added?

@chriddyp
Copy link
Member

thanks for reporting @johnpauls ! could you elaborate more on what you would expect the keyboard interactions to be?

@johnpauls
Copy link
Author

@chriddyp In the US there is a law, referred to as section 508, that governs web compliance for the federal government (at least) and is used as a benchmark by others. Basically one part says that anything you can do with the mouse you should be able to do with just the keyboard (note - not a lawyer).

So I guess at least you would want to be able to activate/interact with all of the controls on the button bar and click the colors on the legends (where appropriate) by tabbing through them or something similar. It would also be good if you could use the keyboard move the cursor to hover over the various charts and see the information that is displayed (coordinates or values or whatever).

Thanks

@mdtusz
Copy link
Contributor

mdtusz commented May 24, 2016

It is possible we could add these in the future, but I'm not sure whether we should beyond very basic interactions. Plotly.js' main focus is on plotting the data and exposing an interface to view it - in my opinion, specific key events should be managed by the consumers of plots (i.e. webpages they are embedded in).

Simple pan/zoom controls would be useful (z for zoom in, shift+z for zoom out, arrow keys to navigate) and not too too difficult to implement. Legends would be a bit more difficult to make keyboard-friendly because visual aids would need to be added (they are in SVG, not HTML), and any sort of cursor on the plot would be a fairly significant addition.

For now, if you are embedding plots in a webpage and need a11y, I'd suggest using the javascript API to bind whatever actions are required to keys - it's a difficult thing to generalize beyond zooming and scrolling, but those are both fairly easily implemented by changing axis ranges and calling Plotly.relayout.

var graph = document.getElementById('graph');

Plotly.plot(graph, [{
  x: [1, 2, 3],
  y: [2, 3, 4]
}], {});

// Basic example to zoom on z
window.addEventListener('keyup', function(e){
  var key = e.keyCode ? e.keyCode : e.which;

  // 'z' key is 90
  if(key === 90) {
    var oldRange = graph._fullLayout.xaxis.range;
    var oldMin = oldRange[0];
    var oldMax = oldRange[1];

    var scaling = e.shiftKey ? -0.1 : 0.1;

    var newRange = [
      oldRange[0] + (oldMax - oldMin) * scaling,
      oldRange[1] - (oldMax - oldMin) * scaling
    ];
    Plotly.relayout(graph, 'xaxis.range', newRange);
  }
});

And a live jsbin

@johnpauls
Copy link
Author

Thanks for this suggestion. For what its worth, my hope it to use plotly to create graphics in R and then server them on the web using RStudio's shiny /shiny server . I would like to avoid adding the extra javascript, but it is good to know that it can be done.

@legg33
Copy link

legg33 commented Apr 20, 2017

I'd like this feature, too.

Some pretty basic shortcuts would already help tremendously especially when you have to use a laptop trackpad. I previously used matplotlibs interactive window and immediatly tried to use the shortcuts in plotly, too. The matplotlib toolbar shortcuts are listed here:

https://matplotlib.org/users/navigation_toolbar.html

@carmacleod
Copy link

Typical keyboard interaction for a custom component is to use the TAB key (and SHIFT+TAB) to navigate into and out of the component, and to use arrow keys (UP, DOWN, LEFT, RIGHT) to navigate within the component.
Please try using your keyboard in any of these Oracle JET charts/visualizations. Notice also that they also use aria-label where invisible labels are needed for screen reader users, and sometimes they use role="img" or role="separator" and other aria to help clarify what various things represent.

@etpinard
Copy link
Contributor

From #3989

Is it possible to have shortcuts for interactions with the graph?

E.g. I would like to have

  • panning with the arrow keys left, right, up, down
  • zooming with + and -
  • horizontal zooming with ctrl+left and ctrl+right
  • vertical zooming with ctrl+up and ctrl+down
  • unzoom both u, horizontal unzoom alt+x, vertical unzoom alt+y
  • previous zoom p
  • toggle grid g
  • snapshot (copy as png to clibboard) ctrl+c

(partly taken from gnuplot).

@mzechmeister
Copy link

Thanks for pointing me here.

How I can fed this javascript snippet outlined above by @mdtusz from python to the html document?

@mzechmeister
Copy link

I created a some more key bindings, that be tested here https://jsfiddle.net/jrL34keb/1/.

I found no way pass the additional javascript to python via the plot function.
But there are functions https://github.com/plotly/plotly.py/blob/dc1111170d017911699d0f940850c45bd4f3e98e/plotly/offline/offline.py#L371
which have a post_script argument.
As a bad hack, I made a decorator to a function, which generates itself post_javascript code, in order to append the binding script.

When putting the following code at the top of the python script, it appends automatically key bindings in every offline.plot call.

import plotly

import plotly.plotly as py
import plotly.graph_objs as go
bind_script = '''
var graph = document.getElementsByClassName("plotly-graph-div js-plotly-plot")[0];
var update;

function pan(axis, dx, mode=1) {
    axis += 'axis';
    var [min, max] = graph._fullLayout[axis].range;
    dx *= max - min;
    update[axis+'.range'] = [min+dx, max+mode*dx];
}

function panX(dx) {pan('x', dx)}
function panY(dy) {pan('y', dy)}
function zoomX(dx) {pan('x', dx, -1)}
function zoomY(dy) {pan('y', dy, -1)}

document.addEventListener("keydown", function(e){
    var key = e.key;
    if (e.ctrlKey) key = 'Ctrl+' + key;
    console.log(e, key);
    var fac = 0.1;   // pan and zoom factor
    update = {};
    var extremes = graph._fullData[0]._extremes;  // only first data set
    switch (key) {
        case 'Ctrl+ArrowRight': zoomX(fac); break;
        case 'Ctrl+ArrowLeft': zoomX(-fac); break;
        case 'Ctrl+ArrowUp': zoomY(fac); break;
        case 'Ctrl+ArrowDown': zoomY(-fac); break;
        case '+': zoomX(fac); zoomY(fac); break;
        case '-': zoomX(-fac); zoomY(-fac); break;
        case 'X': case 'U':
             update['xaxis.range'] = [extremes.x.min[0].val, extremes.x.max[0].val];
        case 'Y': case 'U':
             update['yaxis.range'] = [extremes.y.min[0].val, extremes.y.max[0].val]; break;
        case 'x': case 'u':
             update['xaxis.autorange'] = true;
        case 'y': case 'u':
             update['yaxis.autorange'] = true; break;
        case '0': update['yaxis.range[0]'] = 0; break;
        case 'ArrowRight': panX(fac); break;
        case 'ArrowLeft': panX(-fac); break;
        case 'ArrowUp': panY(fac); break;
        case 'ArrowDown': panY(-fac); break;
        case 'Home': panX(-1.); break;
        case 'End': panX(1.); break;
        case 'PageUp': panY(1.); break;
        case 'PageDown': panY(-1.); break;
        default: return;
    }
    Plotly.relayout(graph, update);
});
'''


def script_decorator(func):
    # append binding script
    def function_wrapper(*x):
        return (func(*x) or '') + bind_script
    return function_wrapper

plotly.offline.offline.build_save_image_post_script = script_decorator(plotly.offline.offline.build_save_image_post_script)

@mizeljko
Copy link

Is there any update on being able to navigate through plotly chart using keyboard?

@fzyzcjy
Copy link

fzyzcjy commented Mar 30, 2020

I wonder whether there are any updates? Thanks!

@GitHunter0
Copy link

GitHunter0 commented Jun 17, 2020

Just Zoom In, Zoom Out and Pan shortcuts alone should be great. Thank you.

@jackparmer
Copy link
Contributor

jackparmer commented Sep 10, 2020

This issue has been tagged with NEEDS SPON$OR

A community PR for this feature would certainly be welcome, but our experience is deeper features like this are difficult to complete without the Plotly maintainers leading the effort.

What Sponsorship includes:

  • Completion of this feature to the Sponsor's satisfaction, in a manner coherent with the rest of the Plotly.js library and API
  • Tests for this feature
  • Long-term support (continued support of this feature in the latest version of Plotly.js)
  • Documentation at plotly.com/javascript
  • Possibility of integrating this feature with Plotly Graphing Libraries (Python, R, F#, Julia, MATLAB, etc)
  • Possibility of integrating this feature with Dash
  • Feature announcement on community.plotly.com with shout out to Sponsor (or can remain anonymous)
  • Gratification of advancing the world's most downloaded, interactive scientific graphing libraries (>50M downloads across supported languages)

Please include the link to this issue when contacting us to discuss.

@dotcode
Copy link

dotcode commented Jun 22, 2021

A couple of links that may prove of interest: WebAIM describe how keyboard accessibility is one of the most important aspects of web accessibility.

Also an interesting talk from Google about how designing for accessibility improves product quality and benefits everyone.

@trmdev
Copy link

trmdev commented Feb 2, 2022

Is there any new version released for plotly.js Keyboard accessibility.

@jacobq
Copy link

jacobq commented Apr 25, 2022

This issue has been tagged with NEEDS SPON$OR
...

Given that I personally don't have $20k to throw at this but would happily donate 0.1% of that to help it get done, is there an existing process setup that would facilitate this getting crowd-sponsored? Can we designate this issue on GitHub Sponsorships? (If Dash customers have this same problem maybe they could upvote it somehow?)

@hasen6
Copy link

hasen6 commented Apr 11, 2023

This issue has been tagged with NEEDS SPON$OR

A community PR for this feature would certainly be welcome, but our experience is deeper features like this are difficult to complete without the Plotly maintainers leading the effort.

What Sponsorship includes:

  • Completion of this feature to the Sponsor's satisfaction, in a manner coherent with the rest of the Plotly.js library and API
  • Tests for this feature
  • Long-term support (continued support of this feature in the latest version of Plotly.js)
  • Documentation at plotly.com/javascript
  • Possibility of integrating this feature with Plotly Graphing Libraries (Python, R, F#, Julia, MATLAB, etc)
  • Possibility of integrating this feature with Dash
  • Feature announcement on community.plotly.com with shout out to Sponsor (or can remain anonymous)
  • Gratification of advancing the world's most downloaded, interactive scientific graphing libraries (>50M downloads across supported languages)

Please include the link to this issue when contacting us to discuss.

All that stuff seems unnecessary, since the result is nothing has been done in seven years. I think at this point we'd all be happy with basic keyboard controls that are not configurable. Surely wouldn't need any support for this feature either since it'd be so basic and testing would surely be minimal since the functionality is already there, it's just the key strokes triggering the same actions. I'm sure users of plotly that want this feature would be willing to contribute to have it realised. Also there's always ChatGPT to help too these days.

@mzechmeister
Copy link

BTW, the javascript part of my snippet I posted above is now maintained as a standalone file:
https://github.com/mzechmeister/csvplotter/blob/main/zoom_pan.js
The project readme explains the available shortcuts.

@LeoDiep
Copy link

LeoDiep commented May 24, 2024

I would like to give my idea about using key arrow left, right for the slider to redraw frames. moving slider by frames is not easily control especially when you have a very long range, so keyboard would be more convinient when you want to go through frame by frame easily

@gvwilson gvwilson self-assigned this Jun 5, 2024
@deven298
Copy link

+1 for adding keyboard shortcuts for exploring the graph. This will be very helpful. Will keep an eye here!

@gvwilson gvwilson removed their assignment Aug 2, 2024
@gvwilson gvwilson added P2 considered for next cycle and removed ♥ NEEDS SPON$OR labels Aug 2, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature something new P2 considered for next cycle
Projects
None yet
Development

No branches or pull requests