animint / animint2

Animated interactive grammar of graphics
https://animint.github.io/animint2/
59 stars 20 forks source link

Animints Don't Render Alt Text #106

Open ampurr opened 10 months ago

ampurr commented 10 months ago

In R Markdown, it's possible to use the fig.alt knitr code chunk option to add alt text to static data visualizations. Like this:

{r, fig.alt = "A scatterplot of something really cool. 😎"}
cool <- ggplot(cool_dataset) + geom_point() + ...

But this option doesn't work for animints. So this doesn't work right:

{r, fig.alt = "A really cool interactive scatterplot. 🐯"}
animint(cool)

Maybe a future GSOC contributor can fix this as part of a larger Accessibility for Animint2 project?

ampurr commented 10 months ago

Some sources that might be helpful to this future contributor, in alphabetical order:

ampurr commented 10 months ago

An alternative solution is to add a function that lets users add alt text to their animints. That's probably easier than figuring out how knitr adds alt text and then change it.

tdhock commented 10 months ago

I thought alt text was only for images? Animints are rendered as <svg> elements. Maybe we could add role="img" as mentioned on https://css-tricks.com/accessible-svgs/ ?

ampurr commented 10 months ago

You're right. However, I'd consider an SVG an image, even though it's not an <img>. But you're in charge—if you disagree, we can close the issue. :>

Yeah, I think role="img" would be part of the solution. But it seems like accessible SVGs rely on <title>. So we can't use something <svg alt="foobar">.

I've never looked into how knitr works. I think we'd need it to output the role and the <title>.

ampurr commented 10 months ago

Two asides:

  1. Unlike an <img>, animints have SVG <text> elements and other elements that can be accessed by a screenreader. That makes our job harder, since we'll have to take that into account when thinking about animint accessibility.
  2. Animints are <table>s. I've never thought about the semantics of data visualizations before, so I'm not sure this is right or not. Maybe there's research on this. 🤔
tdhock commented 10 months ago

you are right, each animint is actually a table containing several svg elements. I don't think you should hack the knit_print.animint function. That would only change animints inside of Rmds, but accessibility applies to all animints (even outside of rendered Rmds). Instead I would suggest modifying the inst/htmljs/animint.js code, which creates the table and svg elements.

ampurr commented 10 months ago

That makes sense. So the person would be modifying the JS code and creating a make_alt_text function alongside it?

tdhock commented 10 months ago

You are right, according to that page, we just need to add a <title> element as the first sub-element of each svg.

Inside the <svg>, add: 
<title>A short title of the SVG</title>
    must be the first child of it’s parent element
    will be used as a tooltip as the pointing device moves over it

For existing code like

animint(timeSeries=ggplot..., scatter=ggplot...)

We could provide some reasonable default like "plot of timeSeries" and "plot of scatter" We could also allow user to override per plot via

animint(timeSeries=ggplot()+theme_animint(title="some plot")

which we could render in JS as

<title id="title_timeSeries">some plot</title>
ampurr commented 10 months ago

That makes sense. I feel conflicted about the default alt txt idea, but I'll think about it and give my thoughts after I'm done with the reference website stuff. :>