From 09edfec1f26da02eeeb451f008dd2eb9fb8d8ffc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Rivi=C3=A8re?= Date: Thu, 5 Sep 2024 11:50:01 -0400 Subject: [PATCH] =?UTF-8?q?axis=20marks=E2=80=99=20ariaLabel=20option=20(#?= =?UTF-8?q?2162)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * refactor the axis marks’ ariaLabel option * concrete use case: a continuous horizontal crosshair --- src/marks/axis.js | 30 ++++++++++---- test/output/crosshairContinuousX.svg | 60 ++++++++++++++++++++++++++++ test/plots/crosshair.ts | 22 ++++++++++ 3 files changed, 104 insertions(+), 8 deletions(-) create mode 100644 test/output/crosshairContinuousX.svg diff --git a/src/marks/axis.js b/src/marks/axis.js index 406ff70dd5..7c7944a55f 100644 --- a/src/marks/axis.js +++ b/src/marks/axis.js @@ -89,6 +89,7 @@ function axisKy( labelAnchor, labelArrow, labelOffset, + ariaLabel = `${k}-axis`, ...options } ) { @@ -107,6 +108,7 @@ function axisKy( tickPadding, tickRotate, x, + ariaLabel, ...options }) : null, @@ -126,6 +128,7 @@ function axisKy( marginRight, marginBottom, marginLeft, + ariaLabel, ...options }) : null, @@ -150,7 +153,7 @@ function axisKy( } this.dy = cla === "top" ? 3 - marginTop : cla === "bottom" ? marginBottom - 3 : 0; this.dx = anchor === "right" ? clo : -clo; - this.ariaLabel = `${k}-axis label`; + this.ariaLabel = `${ariaLabel} label`; return { facets: [[0]], channels: {text: {value: [formatAxisLabel(k, scale, {anchor, label, labelAnchor: cla, labelArrow})]}} @@ -190,6 +193,7 @@ function axisKx( labelAnchor, labelArrow, labelOffset, + ariaLabel = `${k}-axis`, ...options } ) { @@ -208,6 +212,7 @@ function axisKx( tickPadding, tickRotate, y, + ariaLabel, ...options }) : null, @@ -227,6 +232,7 @@ function axisKx( marginRight, marginBottom, marginLeft, + ariaLabel, ...options }) : null, @@ -248,7 +254,7 @@ function axisKx( this.lineAnchor = anchor; this.dy = anchor === "top" ? -clo : clo; this.dx = cla === "right" ? marginRight - 3 : cla === "left" ? 3 - marginLeft : 0; - this.ariaLabel = `${k}-axis label`; + this.ariaLabel = `${ariaLabel} label`; return { facets: [[0]], channels: {text: {value: [formatAxisLabel(k, scale, {anchor, label, labelAnchor: cla, labelArrow})]}} @@ -275,6 +281,7 @@ function axisTickKy( insetRight = inset, dx = 0, y = k === "y" ? undefined : null, + ariaLabel, ...options } ) { @@ -283,7 +290,7 @@ function axisTickKy( k, data, { - ariaLabel: `${k}-axis tick`, + ariaLabel: `${ariaLabel} tick`, ariaHidden: true }, { @@ -318,6 +325,7 @@ function axisTickKx( insetBottom = inset, dy = 0, x = k === "x" ? undefined : null, + ariaLabel, ...options } ) { @@ -326,7 +334,7 @@ function axisTickKx( k, data, { - ariaLabel: `${k}-axis tick`, + ariaLabel: `${ariaLabel} tick`, ariaHidden: true }, { @@ -363,6 +371,7 @@ function axisTextKy( insetLeft = inset, insetRight = inset, dx = 0, + ariaLabel, y = k === "y" ? undefined : null, ...options } @@ -371,7 +380,7 @@ function axisTextKy( textY, k, data, - {ariaLabel: `${k}-axis tick label`}, + {ariaLabel: `${ariaLabel} tick label`}, { facetAnchor, frameAnchor, @@ -410,6 +419,7 @@ function axisTextKx( insetBottom = inset, dy = 0, x = k === "x" ? undefined : null, + ariaLabel, ...options } ) { @@ -417,7 +427,7 @@ function axisTextKx( textX, k, data, - {ariaLabel: `${k}-axis tick label`}, + {ariaLabel: `${ariaLabel} tick label`}, { facetAnchor, frameAnchor, @@ -466,10 +476,12 @@ function gridKy( x = null, x1 = anchor === "left" ? x : null, x2 = anchor === "right" ? x : null, + ariaLabel = `${k}-grid`, + ariaHidden = true, ...options } ) { - return axisMark(ruleY, k, data, {ariaLabel: `${k}-grid`, ariaHidden: true}, {y, x1, x2, ...gridDefaults(options)}); + return axisMark(ruleY, k, data, {ariaLabel, ariaHidden}, {y, x1, x2, ...gridDefaults(options)}); } function gridKx( @@ -481,10 +493,12 @@ function gridKx( y = null, y1 = anchor === "top" ? y : null, y2 = anchor === "bottom" ? y : null, + ariaLabel = `${k}-grid`, + ariaHidden = true, ...options } ) { - return axisMark(ruleX, k, data, {ariaLabel: `${k}-grid`, ariaHidden: true}, {x, y1, y2, ...gridDefaults(options)}); + return axisMark(ruleX, k, data, {ariaLabel, ariaHidden}, {x, y1, y2, ...gridDefaults(options)}); } function gridDefaults({ diff --git a/test/output/crosshairContinuousX.svg b/test/output/crosshairContinuousX.svg new file mode 100644 index 0000000000..cb919b560c --- /dev/null +++ b/test/output/crosshairContinuousX.svg @@ -0,0 +1,60 @@ + + + + + 60 + 80 + 100 + 120 + 140 + 160 + 180 + + + ↑ Close + + + + 2013 + 2014 + 2015 + 2016 + 2017 + 2018 + 2019 + + + + + + + \ No newline at end of file diff --git a/test/plots/crosshair.ts b/test/plots/crosshair.ts index 516baf7231..7b17e29109 100644 --- a/test/plots/crosshair.ts +++ b/test/plots/crosshair.ts @@ -50,3 +50,25 @@ export async function crosshairLine() { marks: [Plot.lineY(aapl, {x: "Date", y: "Close"}), Plot.crosshairX(aapl, {x: "Date", y: "Close"})] }); } + +export async function crosshairContinuousX() { + const aapl = await d3.csv("data/aapl.csv", d3.autoType); + return Plot.plot({ + height: 270, + x: {nice: true}, + marks: [ + Plot.lineY(aapl, {x: "Date", y: "Close"}), + Plot.gridX(Plot.pointerX({ticks: 1000, ariaLabel: `crosshair-x tick`})), + Plot.axisX( + Plot.pointerX({ + ticks: 1000, + ariaLabel: `crosshair-x label`, + tickFormat: `%Y\n%b`, + textStroke: "var(--plot-background)", + textStrokeWidth: 5, + tickSize: 0 + }) + ) + ] + }); +}