From 1aa2c0f178f9bf27fd380466bbb661c7d752a93c Mon Sep 17 00:00:00 2001 From: Birm Date: Thu, 18 Jul 2024 17:40:56 -0400 Subject: [PATCH 1/2] add figure role to charts for a11y --- source/components/VisualTools/Chart/BarChart.js | 8 +++++--- source/components/VisualTools/Chart/DensityChart.js | 2 +- source/components/VisualTools/Chart/Heatmap.js | 2 +- source/components/VisualTools/Chart/Histogram.js | 2 +- source/components/VisualTools/Chart/HorizontalBarChart.js | 2 +- source/components/VisualTools/Chart/KMCurve.js | 2 +- .../components/VisualTools/Chart/ParallelCoordinates.js | 2 +- source/components/VisualTools/Chart/PieChart.js | 2 +- source/components/VisualTools/Chart/ScatterChart.js | 2 +- 9 files changed, 13 insertions(+), 11 deletions(-) diff --git a/source/components/VisualTools/Chart/BarChart.js b/source/components/VisualTools/Chart/BarChart.js index ba55572..fc29046 100644 --- a/source/components/VisualTools/Chart/BarChart.js +++ b/source/components/VisualTools/Chart/BarChart.js @@ -113,7 +113,8 @@ function BarChart(props) { .attr('class', `${className}`) .attr('x', (d) => scaleRef.current.x(d[fields.x])) .attr('width', scaleRef.current.x.bandwidth()) - .attr('y', hightRef.current); + .attr('y', hightRef.current) + .attr('role', 'graphics-symbol'); enterBars .on('mousemove', tooltipHandlers.mousemove) .on('mouseleave', tooltipHandlers.mouseleave) @@ -168,7 +169,8 @@ function BarChart(props) { .select(self.current) .append('svg') .attr('width', rect.width) - .attr('height', rect.height); + .attr('height', rect.height) + .attr('role', 'img'); // create viewer viewerRef.current = svg .append('g') @@ -206,7 +208,7 @@ function BarChart(props) { }, 100); }, [props.filters, props.filterData, props.layout]); - return
; + return
; } export default BarChart; diff --git a/source/components/VisualTools/Chart/DensityChart.js b/source/components/VisualTools/Chart/DensityChart.js index d603bbb..361c5d0 100644 --- a/source/components/VisualTools/Chart/DensityChart.js +++ b/source/components/VisualTools/Chart/DensityChart.js @@ -167,7 +167,7 @@ function DensityChart(props) { .attr('fill', (d) => color(d.value)); }, 100); }, [props.layout, props.filters, props.filterData]); - return
; + return
; } export default DensityChart; diff --git a/source/components/VisualTools/Chart/Heatmap.js b/source/components/VisualTools/Chart/Heatmap.js index 71521d7..23fe80f 100644 --- a/source/components/VisualTools/Chart/Heatmap.js +++ b/source/components/VisualTools/Chart/Heatmap.js @@ -131,7 +131,7 @@ function Heatmap(props) { }, 100); }, [props.layout, props.filters, props.filterData]); - return
; + return
; } export default Heatmap; diff --git a/source/components/VisualTools/Chart/Histogram.js b/source/components/VisualTools/Chart/Histogram.js index 793df4f..1a41deb 100644 --- a/source/components/VisualTools/Chart/Histogram.js +++ b/source/components/VisualTools/Chart/Histogram.js @@ -142,7 +142,7 @@ function Histogram({ .style('fill', '#4682B4'); }, 100); }, [filters, filterData, layout]); - return
; + return
; } export default Histogram; diff --git a/source/components/VisualTools/Chart/HorizontalBarChart.js b/source/components/VisualTools/Chart/HorizontalBarChart.js index 34842a6..0531176 100644 --- a/source/components/VisualTools/Chart/HorizontalBarChart.js +++ b/source/components/VisualTools/Chart/HorizontalBarChart.js @@ -186,7 +186,7 @@ function HorizontalBarChart(props) { }, 100); }, [props.filters, props.filterData, props.layout]); - return
; + return
; } export default HorizontalBarChart; diff --git a/source/components/VisualTools/Chart/KMCurve.js b/source/components/VisualTools/Chart/KMCurve.js index d2e532e..f76908d 100644 --- a/source/components/VisualTools/Chart/KMCurve.js +++ b/source/components/VisualTools/Chart/KMCurve.js @@ -208,7 +208,7 @@ export default class KMCurve extends PureComponent { } render() { - return
; + return
; } } diff --git a/source/components/VisualTools/Chart/ParallelCoordinates.js b/source/components/VisualTools/Chart/ParallelCoordinates.js index f0a2235..5e77685 100644 --- a/source/components/VisualTools/Chart/ParallelCoordinates.js +++ b/source/components/VisualTools/Chart/ParallelCoordinates.js @@ -161,7 +161,7 @@ function ParallelCoordinates(props) { }, 100); }, [props.filters, props.filterData, props.layout]); - return
; + return
; } export default ParallelCoordinates; diff --git a/source/components/VisualTools/Chart/PieChart.js b/source/components/VisualTools/Chart/PieChart.js index d5b42f8..c74ad2f 100644 --- a/source/components/VisualTools/Chart/PieChart.js +++ b/source/components/VisualTools/Chart/PieChart.js @@ -151,7 +151,7 @@ function PieChart(props) { return (
-
+
); } diff --git a/source/components/VisualTools/Chart/ScatterChart.js b/source/components/VisualTools/Chart/ScatterChart.js index 371ca82..b31feb4 100644 --- a/source/components/VisualTools/Chart/ScatterChart.js +++ b/source/components/VisualTools/Chart/ScatterChart.js @@ -199,7 +199,7 @@ export default class ScatterChart extends PureComponent { render() { return ( -
+
); } } From e5070bc7d766da9897c57db6c60524f60d53bdca Mon Sep 17 00:00:00 2001 From: Birm Date: Thu, 18 Jul 2024 17:41:15 -0400 Subject: [PATCH 2/2] add one test per chart type --- tests/BarChart.test.js | 41 ++++++++++++++++++++++++++++++ tests/DensityChart.test.js | 34 +++++++++++++++++++++++++ tests/Heatmap.test.js | 41 ++++++++++++++++++++++++++++++ tests/Histogram.test.js | 41 ++++++++++++++++++++++++++++++ tests/HorizontalBarChart.test.js | 41 ++++++++++++++++++++++++++++++ tests/KMCurve.test.js | 42 +++++++++++++++++++++++++++++++ tests/ParallelCoordinates.test.js | 39 ++++++++++++++++++++++++++++ tests/PieChart.test.js | 41 ++++++++++++++++++++++++++++++ tests/ScatterChart.test.js | 40 +++++++++++++++++++++++++++++ 9 files changed, 360 insertions(+) create mode 100644 tests/BarChart.test.js create mode 100644 tests/DensityChart.test.js create mode 100644 tests/Heatmap.test.js create mode 100644 tests/Histogram.test.js create mode 100644 tests/HorizontalBarChart.test.js create mode 100644 tests/KMCurve.test.js create mode 100644 tests/ParallelCoordinates.test.js create mode 100644 tests/PieChart.test.js create mode 100644 tests/ScatterChart.test.js diff --git a/tests/BarChart.test.js b/tests/BarChart.test.js new file mode 100644 index 0000000..07585bb --- /dev/null +++ b/tests/BarChart.test.js @@ -0,0 +1,41 @@ +import React from 'react'; +import { render, screen, fireEvent } from '@testing-library/react'; +import BarChart from '../source/components/VisualTools/Chart/BarChart'; + +const mockData = [ + { category: 'A' }, + { category: 'B' }, + { category: 'A' }, + { category: 'C' }, + { category: 'B' }, + { category: 'A' }, + ]; + +const mockFields = { + x: 'category', + isList: false, +}; + +const mockLayout = { width: 500, currentCols: 1 }; +const mockFilters = []; +const mockTitle = 'Test Bar Chart'; +const mockId = 'test-bar-chart'; + +describe('BarChart Vis Component', () => { + it('renders', () => { + render( + + ); + const chartElement = screen.getByRole('figure', { hidden: true }); + expect(chartElement).toBeInTheDocument(); + }); +}); diff --git a/tests/DensityChart.test.js b/tests/DensityChart.test.js new file mode 100644 index 0000000..2d289e6 --- /dev/null +++ b/tests/DensityChart.test.js @@ -0,0 +1,34 @@ +import React from 'react'; +import { render } from '@testing-library/react'; +import DensityChart from '../source/components/VisualTools/Chart/DensityChart'; + +const mockData = [ + { x: 10, y: 20 }, + { x: 15, y: 25 }, + { x: 20, y: 30 }, +]; + +const mockFields = { x: 'x', y: 'y' }; +const mockLayout = { width: 500, currentCols: 1 }; +const mockFilters = []; +const mockTitle = 'Test Density Chart'; +const mockFilterAdded = []; +const mockId = 'test-density-chart'; + +describe('DensityChart Component', () => { + it('renders', () => { + render( + + ); + expect(document.getElementById(mockId)).toBeInTheDocument(); + }); +}); diff --git a/tests/Heatmap.test.js b/tests/Heatmap.test.js new file mode 100644 index 0000000..38a1260 --- /dev/null +++ b/tests/Heatmap.test.js @@ -0,0 +1,41 @@ +import React from 'react'; +import { render } from '@testing-library/react'; +import Heatmap from '../source/components/VisualTools/Chart/Heatmap'; +import '@testing-library/jest-dom'; + +const mockData = [ + { x: 'A', y: '1', z: 10 }, + { x: 'B', y: '1', z: 20 }, + { x: 'A', y: '2', z: 30 }, +]; + +const mockFields = { + x: 'x', + y: 'y', + z: 'z', +}; + +const mockFilters = []; +const mockFilterAdded = []; +const mockTitle = 'Test Heatmap Chart'; +const mockId = 'test-heatmap-chart'; +const mockLayout = { + width: 500, + currentCols: 2, +}; + +test('renders without crashing', () => { + render( + + ); + expect(document.getElementById(mockId)).toBeInTheDocument(); +}); diff --git a/tests/Histogram.test.js b/tests/Histogram.test.js new file mode 100644 index 0000000..bbd4299 --- /dev/null +++ b/tests/Histogram.test.js @@ -0,0 +1,41 @@ +import React from 'react'; +import { render, screen, fireEvent } from '@testing-library/react'; +import Histogram from '../source/components/VisualTools/Chart/Histogram'; + +const mockData = [ + { category: 10 }, + { category: 11 }, + { category: 12 }, + { category: 12 }, + { category: 15 }, + { category: 21 }, + ]; + +const mockFields = { + x: 'category' +}; + +const mockLayout = { width: 500, currentCols: 1 }; +const mockFilters = []; +const mockTitle = 'Test Histogram Chart'; +const mockId = 'test-histogram-chart'; + +describe('Histogram Vis Component', () => { + it('renders', () => { + render( + + ); + const chartElement = screen.getByRole('figure', { hidden: true }); + expect(chartElement).toBeInTheDocument(); + }); +}); diff --git a/tests/HorizontalBarChart.test.js b/tests/HorizontalBarChart.test.js new file mode 100644 index 0000000..4997b2f --- /dev/null +++ b/tests/HorizontalBarChart.test.js @@ -0,0 +1,41 @@ +import React from 'react'; +import { render, screen, fireEvent } from '@testing-library/react'; +import HorizontalBarChart from '../source/components/VisualTools/Chart/HorizontalBarChart'; + +const mockData = [ + { category: 'A' }, + { category: 'B' }, + { category: 'A' }, + { category: 'C' }, + { category: 'B' }, + { category: 'A' }, + ]; + +const mockFields = { + x: 'category', + isList: false, +}; + +const mockLayout = { width: 500, currentCols: 1 }; +const mockFilters = []; +const mockTitle = 'Test Horiz Bar Chart'; +const mockId = 'test-horiz-bar-chart'; + +describe('HorizontalBarChart Vis Component', () => { + it('renders', () => { + render( + + ); + const chartElement = screen.getByRole('figure', { hidden: true }); + expect(chartElement).toBeInTheDocument(); + }); +}); diff --git a/tests/KMCurve.test.js b/tests/KMCurve.test.js new file mode 100644 index 0000000..b5e66af --- /dev/null +++ b/tests/KMCurve.test.js @@ -0,0 +1,42 @@ +import React from 'react'; +import { render, screen, fireEvent } from '@testing-library/react'; +import KMCurve from '../source/components/VisualTools/Chart/KMCurve'; + +const mockData = [ + { collapsed_stage: 'stage_x/NR', time: 1, event: 'event', group: 'group1' }, + { collapsed_stage: 'stage_x/NR', time: 2, event: 'event', group: 'group1' }, + { collapsed_stage: 'stage_x/NR', time: 3, event: 'censor', group: 'group1' }, + { collapsed_stage: 'stage_x/NR', time: 1, event: 'event', group: 'group2' }, + { collapsed_stage: 'stage_x/NR', time: 2, event: 'censor', group: 'group2' }, +]; + +const mockFields = { + x: 'group', + time: { field: 'time' }, + event: { field: 'event', eventValue: 'event', censoredValue: 'censor' }, + group: { field: 'group' }, + }; + +const mockLayout = { width: 500, currentCols: 1 }; +const mockFilters = []; +const mockTitle = 'Test KMCurve Chart'; +const mockId = 'test-km-curve-chart'; + +describe('KMCurve Vis Component', () => { + it('renders', () => { + render( + + ); + const chartElement = screen.getByRole('figure', { hidden: true }); + expect(chartElement).toBeInTheDocument(); + }); +}); diff --git a/tests/ParallelCoordinates.test.js b/tests/ParallelCoordinates.test.js new file mode 100644 index 0000000..01148ca --- /dev/null +++ b/tests/ParallelCoordinates.test.js @@ -0,0 +1,39 @@ +import React from 'react'; +import { render, screen, fireEvent } from '@testing-library/react'; +import ParallelCoordinates from '../source/components/VisualTools/Chart/ParallelCoordinates'; + +const mockData = [ + { dimension1: 10, dimension2: 20, dimension3: 30 }, + { dimension1: 15, dimension2: 25, dimension3: 35 }, + { dimension1: 20, dimension2: 30, dimension3: 40 }, + { dimension1: 25, dimension2: 35, dimension3: 45 }, + { dimension1: 30, dimension2: 40, dimension3: 50 }, +]; + +const mockFields = { + y: ['dimension1', 'dimension2', 'dimension3'], +}; + +const mockLayout = { width: 500, currentCols: 1 }; +const mockFilters = []; +const mockTitle = 'Test Parallel Coordinates Chart'; +const mockId = 'test-parallel-coords-chart'; + +describe('ParallelCoordinates Vis Component', () => { + it('renders', () => { + render( + + ); + const chartElement = screen.getByRole('figure', { hidden: true }); + expect(chartElement).toBeInTheDocument(); + }); +}); diff --git a/tests/PieChart.test.js b/tests/PieChart.test.js new file mode 100644 index 0000000..78b29a4 --- /dev/null +++ b/tests/PieChart.test.js @@ -0,0 +1,41 @@ +import React from 'react'; +import { render, screen, fireEvent } from '@testing-library/react'; +import PieChart from '../source/components/VisualTools/Chart/PieChart'; + +const mockData = [ + { category: 'A' }, + { category: 'B' }, + { category: 'A' }, + { category: 'C' }, + { category: 'B' }, + { category: 'A' }, +]; + +const mockFields = { +x: 'category', +isList: false, +}; + +const mockLayout = { width: 500, currentCols: 1 }; +const mockFilters = []; +const mockTitle = 'Test Pie Chart'; +const mockId = 'test-pie-chart'; + +describe('PieChart Vis Component', () => { + it('renders', () => { + render( + + ); + const chartElement = screen.getByRole('figure', { hidden: true }); + expect(chartElement).toBeInTheDocument(); + }); +}); diff --git a/tests/ScatterChart.test.js b/tests/ScatterChart.test.js new file mode 100644 index 0000000..c1e9a42 --- /dev/null +++ b/tests/ScatterChart.test.js @@ -0,0 +1,40 @@ +import React from 'react'; +import { render, screen, fireEvent } from '@testing-library/react'; +import ScatterChart from '../source/components/VisualTools/Chart/ScatterChart'; + +const mockData = [ + { dimension1: 10, dimension2: 20}, + { dimension1: 15, dimension2: 25}, + { dimension1: 20, dimension2: 30}, + { dimension1: 25, dimension2: 35}, + { dimension1: 30, dimension2: 40}, +]; + +const mockFields = { + x: 'dimension1', + y: 'dimension2' +}; + +const mockLayout = { width: 500, currentCols: 1 }; +const mockFilters = []; +const mockTitle = 'Test Scatter Chart'; +const mockId = 'test-scatter-chart'; + +describe('ScatterChart Vis Component', () => { + it('renders', () => { + render( + + ); + const chartElement = screen.getByRole('figure', { hidden: true }); + expect(chartElement).toBeInTheDocument(); + }); +});