plotly / plotly.js

Open-source JavaScript charting library behind Plotly and Dash
https://plotly.com/javascript/
MIT License
16.75k stars 1.84k forks source link

Use keyboard to navigate plotly charts #562

Open johnpauls opened 8 years ago

johnpauls commented 8 years ago

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 commented 8 years ago

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

johnpauls commented 8 years ago

@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 commented 8 years ago

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 commented 8 years ago

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 commented 7 years ago

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 commented 5 years ago

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 commented 5 years ago

From #3989

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

E.g. I would like to have

mzechmeister commented 5 years ago

Thanks for pointing me here.

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

mzechmeister commented 5 years ago

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 commented 4 years ago

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

fzyzcjy commented 4 years ago

I wonder whether there are any updates? Thanks!

GitHunter0 commented 4 years ago

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

jackparmer commented 3 years ago

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:

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

dotcode commented 3 years ago

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 commented 2 years ago

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

jacobq commented 2 years ago

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 commented 1 year ago

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 commented 1 year ago

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 commented 1 month ago

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

deven298 commented 3 weeks ago

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