Skip to content

Commit

Permalink
feat(a11y): add aria-label to <svg> elements (#1892)
Browse files Browse the repository at this point in the history
* feat(a11y): add aria-label to <svg> elements

* qa
  • Loading branch information
theiliad authored Sep 16, 2024
1 parent da5f195 commit 65d40e5
Show file tree
Hide file tree
Showing 40 changed files with 131 additions and 45 deletions.
9 changes: 3 additions & 6 deletions packages/core/src/components/axes/axis.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,12 +56,9 @@ export class Axis extends Component {
const options = this.getOptions()
const isAxisVisible = getProperty(options, 'axes', axisPosition, 'visible')

const svg = this.getComponentContainer() as D3Selection<
SVGGraphicsElement,
any,
HTMLElement,
any
>
const svg = this.getComponentContainer({
ariaLabel: 'axes'
}) as D3Selection<SVGGraphicsElement, any, HTMLElement, any>
const { width, height } = DOMUtils.getSVGElementSize(svg, {
useAttrs: true
})
Expand Down
4 changes: 3 additions & 1 deletion packages/core/src/components/axes/grid-brush.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@ export class ChartBrush extends Component {
const svg = this.parent

// use this area to display selection above all graphs
const frontSelectionArea = this.getComponentContainer()
const frontSelectionArea = this.getComponentContainer({
isPresentational: true
})
if (!svg) throw new Error('SVG was not defined')
const backdrop = DOMUtils.appendOrSelect(
svg as Selection<SVGGraphicsElement, any, HTMLElement, any>,
Expand Down
5 changes: 4 additions & 1 deletion packages/core/src/components/axes/grid.ts
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,10 @@ export class Grid extends Component {
const [yScaleEnd, yScaleStart] = mainYScale.range()

// Get height from the grid
this.backdrop = DOMUtils.appendOrSelect(svg, 'svg.chart-grid-backdrop')
this.backdrop = DOMUtils.appendOrSelect(svg, 'svg.chart-grid-backdrop').attr(
'role',
'presentation'
)
const backdropRect = DOMUtils.appendOrSelect(
this.backdrop,
isXGridEnabled || isYGridEnabled
Expand Down
4 changes: 3 additions & 1 deletion packages/core/src/components/axes/hover-axis.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@ export class HoverAxis extends Axis {
super.destroy()

const axisPosition = this.configs.position as 'left' | 'right' | 'top' | 'bottom'
const svg = this.getComponentContainer()
const svg = this.getComponentContainer({
ariaLabel: 'axes'
})
const container = DOMUtils.appendOrSelect(svg, `g.axis.${axisPosition}`)

const self = this
Expand Down
5 changes: 3 additions & 2 deletions packages/core/src/components/axes/toolbar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,9 @@ export class Toolbar extends Component {
// @ts-ignore
// eslint-disable-next-line @typescript-eslint/no-unused-vars
render(animate = true) {
const container = this.getComponentContainer()
.attr('role', 'toolbar')
const container = this.getComponentContainer({
ariaLabel: 'toolbar'
}).attr('role', 'group')

const isDataLoading = getProperty(this.getOptions(), 'data', 'loading')

Expand Down
4 changes: 3 additions & 1 deletion packages/core/src/components/axes/zero-line.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@ export class ZeroLine extends Component {
(minDomainValue > 0 && maxDomainValue < 0) || (minDomainValue < 0 && maxDomainValue > 0)

// Grab container SVG
const svg = this.getComponentContainer()
const svg = this.getComponentContainer({
isPresentational: true
})

// show zero line only if is necessary, otherwise make sure tto remove zero line if the chart
// previously had a domain that went into negatives
Expand Down
4 changes: 3 additions & 1 deletion packages/core/src/components/axes/zoom-bar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,9 @@ export class ZoomBar extends Component {
// @ts-ignore
// eslint-disable-next-line @typescript-eslint/no-unused-vars
render(animate = true) {
const svg = this.getComponentContainer()
const svg = this.getComponentContainer({
ariaLabel: 'zoom bar'
})

const isTopZoomBarLoading = this.services.zoom.isZoomBarLoading(AxisPositions.TOP)
const isTopZoomBarLocked = this.services.zoom.isZoomBarLocked(AxisPositions.TOP)
Expand Down
17 changes: 16 additions & 1 deletion packages/core/src/components/component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,13 @@ export class Component {
return this.parent
}

getComponentContainer(configs = { withinChartClip: false }) {
getComponentContainer(
configs: {
ariaLabel?: string | null
isPresentational?: boolean
withinChartClip?: boolean
} = { ariaLabel: null, isPresentational: false, withinChartClip: false }
) {
if (this.type) {
const chartprefix = getProperty(this.model.getOptions(), 'style', 'prefix')

Expand All @@ -103,6 +109,14 @@ export class Component {
}${idSelector}.${carbonPrefix}--${chartprefix}--${this.type}`
)

if (configs.ariaLabel) {
container.attr('aria-label', configs.ariaLabel)
}

if (configs.isPresentational) {
container.attr('role', 'presentation')
}

if (configs.withinChartClip) {
// get unique chartClipId int this chart from model
const chartClipId = this.model.get('chartClipId')
Expand All @@ -126,6 +140,7 @@ export class Component {

return container.attr('width', '100%').attr('height', '100%')
}

return this.parent
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,9 @@ export class ColorScaleLegend extends Legend {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
render(animate = false) {
const options = this.getOptions()
const svg = this.getComponentContainer()
const svg = this.getComponentContainer({
ariaLabel: 'legend'
})
const { width } = DOMUtils.getSVGElementSize(svg, {
useAttrs: true
})
Expand Down
4 changes: 3 additions & 1 deletion packages/core/src/components/essentials/highlights.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,9 @@ export class Highlight extends Component {
})

// Grab container SVG
const svg = this.getComponentContainer({ withinChartClip: true })
const svg = this.getComponentContainer({
ariaLabel: 'highlight areas',
withinChartClip: true })

// Update data on all axis highlight groups
const highlightAxisGroups = svg
Expand Down
5 changes: 4 additions & 1 deletion packages/core/src/components/essentials/threshold.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,10 @@ export class Threshold extends Component {
})

// Grab container SVG
const svg = this.getComponentContainer({ withinChartClip: true })
const svg = this.getComponentContainer({
ariaLabel: 'threshold lines',
withinChartClip: true
})

// Update data on all axis threshold groups
const thresholdAxisGroups = svg
Expand Down
4 changes: 3 additions & 1 deletion packages/core/src/components/essentials/title-meter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@ export class MeterTitle extends Title {
render(animate = false) {
const dataset = getProperty(this.model.getDisplayData(), 0)
const options = this.getOptions()
const svg = this.getComponentContainer()
const svg = this.getComponentContainer({
ariaLabel: 'meter title'
})
const { groupMapsTo } = options.data
const meterTitle = options.locale.translations.meter.title
const proportional = getProperty(options, 'meter', 'proportional')
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/components/graphs/alluvial.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export class Alluvial extends Component {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
render(animate = true) {
// svg and container widths
const svg = this.getComponentContainer({ withinChartClip: true })
const svg = this.getComponentContainer({ ariaLabel: 'alluvial graphs', withinChartClip: true })
svg.html('')

const { width, height } = DOMUtils.getSVGElementSize(svg, {
Expand Down
5 changes: 4 additions & 1 deletion packages/core/src/components/graphs/area-stacked.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,10 @@ export class StackedArea extends Component {
}

render(animate = true) {
const svg = this.getComponentContainer({ withinChartClip: true })
const svg = this.getComponentContainer({
ariaLabel: 'stacked area graphs',
withinChartClip: true
})
const self = this
const options = this.getOptions()
const { groupMapsTo } = options.data
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/components/graphs/area.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export class Area extends Component {
}

render(animate = true) {
const svg = this.getComponentContainer({ withinChartClip: true })
const svg = this.getComponentContainer({ ariaLabel: 'area graphs', withinChartClip: true })
const options = this.getOptions()
let domain = [0, 0]

Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/components/graphs/bar-grouped.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ export class GroupedBar extends Bar {
this.setGroupScale()

// Grab container SVG
const svg = this.getComponentContainer({ withinChartClip: true })
const svg = this.getComponentContainer({ ariaLabel: 'grouped bar graphs', withinChartClip: true })

const allDataLabels = uniq(
displayData.map((datum: any) => {
Expand Down
5 changes: 4 additions & 1 deletion packages/core/src/components/graphs/bar-simple.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,10 @@ export class SimpleBar extends Bar {
const { groupMapsTo } = options.data

// Grab container SVG
const svg = this.getComponentContainer({ withinChartClip: true })
const svg = this.getComponentContainer({
ariaLabel: 'bar graphs',
withinChartClip: true
})

const data = this.model.getDisplayData(this.configs.groups)

Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/components/graphs/bar-stacked.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export class StackedBar extends Bar {

render(animate: boolean) {
// Grab container SVG
const svg = this.getComponentContainer({ withinChartClip: true })
const svg = this.getComponentContainer({ ariaLabel: 'stacked bar graphs', withinChartClip: true })

// Chart options mixed with the internal configurations
const options = this.getOptions()
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/components/graphs/boxplot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export class Boxplot extends Component {

render(animate: boolean) {
// Grab container SVG
const svg = this.getComponentContainer({ withinChartClip: true })
const svg = this.getComponentContainer({ ariaLabel: 'box plots', withinChartClip: true })

const options = this.getOptions()
const { groupMapsTo } = options.data
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/components/graphs/bullet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ export class Bullet extends Component {
const { groupMapsTo } = options.data

// Grab container SVG
const svg = this.getComponentContainer({ withinChartClip: true })
const svg = this.getComponentContainer({ ariaLabel: 'bullet graphs', withinChartClip: true })

const data = this.model.getDisplayData(this.configs.groups)

Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/components/graphs/choropleth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export class Choropleth extends GeoProjection {
render(animate = true) {
super.render()
const data = (this.model as ChoroplethModel).getCombinedData()
const svg = this.getComponentContainer({ withinChartClip: true })
const svg = this.getComponentContainer({ ariaLabel: 'map', withinChartClip: true })

const geo = svg.select('g.geo')
geo
Expand Down
5 changes: 4 additions & 1 deletion packages/core/src/components/graphs/circle-pack.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,10 @@ export class CirclePack extends Component {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
render(animate = true) {
// svg and container widths
const svg = this.getComponentContainer({ withinChartClip: true })
const svg = this.getComponentContainer({
ariaLabel: 'circle packs',
withinChartClip: true
})
const { width, height } = DOMUtils.getSVGElementSize(this.parent as any, {
useAttrs: true
})
Expand Down
13 changes: 11 additions & 2 deletions packages/core/src/components/graphs/donut.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,20 @@ export class Donut extends Pie {
// if there are no data, remove the center content
// that is the old one and do nothing
if (this.model.isDataEmpty()) {
this.getComponentContainer().select('g.center').remove()
this.getComponentContainer({
ariaLabel: 'donut graph'
})
.select('g.center')
.remove()
return
}

const svg = DOMUtils.appendOrSelect(this.getComponentContainer(), 'g.center')
const svg = DOMUtils.appendOrSelect(
this.getComponentContainer({
ariaLabel: 'donut graph'
}),
'g.center'
)
const options = this.getOptions()

// Compute the outer radius needed
Expand Down
4 changes: 3 additions & 1 deletion packages/core/src/components/graphs/gauge.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,9 @@ export class Gauge extends Component {
// @ts-ignore
// eslint-disable-next-line @typescript-eslint/no-unused-vars
render(animate = true) {
const svg = this.getComponentContainer().attr('width', '100%').attr('height', '100%')
const svg = this.getComponentContainer({
ariaLabel: 'gauge graph'
}).attr('width', '100%').attr('height', '100%')
const options = this.getOptions()

const value = this.getValue()
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/components/graphs/heatmap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ export class Heatmap extends Component {
// @ts-ignore
// eslint-disable-next-line @typescript-eslint/no-unused-vars
render(animate = true) {
const svg = this.getComponentContainer({ withinChartClip: true })
const svg = this.getComponentContainer({ ariaLabel: 'heatmap', withinChartClip: true })
// Lower the chart so the axes are always visible
svg.lower()

Expand Down
4 changes: 3 additions & 1 deletion packages/core/src/components/graphs/histogram.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@ export class Histogram extends Component {

render(animate: boolean) {
// Grab container SVG
const svg = this.getComponentContainer()
const svg = this.getComponentContainer({
ariaLabel: 'histogram bars'
})

// Chart options mixed with the internal configurations
const options = this.model.getOptions()
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/components/graphs/line.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export class Line extends Component {
}

render(animate = true) {
const svg = this.getComponentContainer({ withinChartClip: true })
const svg = this.getComponentContainer({ ariaLabel: 'lines', withinChartClip: true })
const { cartesianScales, curves } = this.services

const getDomainValue = (d: any) => cartesianScales.getDomainValue(d)
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/components/graphs/lollipop.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export class Lollipop extends Scatter {

render(animate: boolean) {
// Grab container SVG
const svg = this.getComponentContainer({ withinChartClip: true })
const svg = this.getComponentContainer({ ariaLabel: 'lines', withinChartClip: true })

const options = this.model.getOptions()

Expand Down
4 changes: 3 additions & 1 deletion packages/core/src/components/graphs/meter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,9 @@ export class Meter extends Component {

render(animate = true) {
const self = this
const svg = this.getComponentContainer()
const svg = this.getComponentContainer({
ariaLabel: 'meter lines'
})
const options = this.getOptions()
const proportional = getProperty(options, 'meter', 'proportional')
const data = this.model.getDisplayData()
Expand Down
4 changes: 3 additions & 1 deletion packages/core/src/components/graphs/pie.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,9 @@ export class Pie extends Component {

render(animate = true) {
const self = this
const svg = this.getComponentContainer()
const svg = this.getComponentContainer({
ariaLabel: 'pie graph'
})

const options = this.getOptions()
const { groupMapsTo } = options.data
Expand Down
4 changes: 3 additions & 1 deletion packages/core/src/components/graphs/radar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,9 @@ export class Radar extends Component {
}

render(animate = true) {
const svg = this.getComponentContainer()
const svg = this.getComponentContainer({
ariaLabel: 'radar graph'
})
const { width, height } = DOMUtils.getSVGElementSize(svg, {
useAttrs: true
})
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/components/graphs/scatter-stacked.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export class StackedScatter extends Scatter {
return
}
// Grab container SVG
const svg = this.getComponentContainer({ withinChartClip: true })
const svg = this.getComponentContainer({ ariaLabel: 'scatter points', withinChartClip: true })

const options = this.getOptions()
const { groupMapsTo } = options.data
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/components/graphs/scatter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ export class Scatter extends Component {
}

// Grab container SVG
const svg = this.getComponentContainer({ withinChartClip: true })
const svg = this.getComponentContainer({ ariaLabel: 'scatter points', withinChartClip: true })

const options = this.getOptions()
const { groupMapsTo } = options.data
Expand Down
4 changes: 3 additions & 1 deletion packages/core/src/components/graphs/tree.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,9 @@ export class Tree extends Component {
// @ts-ignore
// eslint-disable-next-line @typescript-eslint/no-unused-vars
render(animate = true) {
const svg = this.getComponentContainer()
const svg = this.getComponentContainer({
ariaLabel: 'tree diagram'
})

// Empty out the svg before rendering the tree
svg.html('')
Expand Down
Loading

0 comments on commit 65d40e5

Please sign in to comment.