Skip to content

Commit

Permalink
Add basic accessibility features for describing pie chart image detai…
Browse files Browse the repository at this point in the history
…ls and percentages
  • Loading branch information
nickviola committed Jun 18, 2024
1 parent 112e456 commit adfdc52
Showing 1 changed file with 203 additions and 5 deletions.
208 changes: 203 additions & 5 deletions frontend/src/pages/Risk/VulnerabilityPieChart.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,16 @@
import React from 'react';
import { useHistory } from 'react-router-dom';
import { ResponsivePie } from '@nivo/pie';
import {
ResponsivePie,

Check warning on line 4 in frontend/src/pages/Risk/VulnerabilityPieChart.tsx

View workflow job for this annotation

GitHub Actions / lint

'ResponsivePie' is defined but never used
ComputedDatum,

Check warning on line 5 in frontend/src/pages/Risk/VulnerabilityPieChart.tsx

View workflow job for this annotation

GitHub Actions / lint

'ComputedDatum' is defined but never used
PieTooltipProps,

Check warning on line 6 in frontend/src/pages/Risk/VulnerabilityPieChart.tsx

View workflow job for this annotation

GitHub Actions / lint

'PieTooltipProps' is defined but never used
PieCustomLayerProps,

Check warning on line 7 in frontend/src/pages/Risk/VulnerabilityPieChart.tsx

View workflow job for this annotation

GitHub Actions / lint

'PieCustomLayerProps' is defined but never used
ResponsivePieCanvas
} from '@nivo/pie';
import { Paper } from '@mui/material';
import { Point } from './Risk';
import * as RiskStyles from './style';
import { arc } from 'd3-shape';

Check warning on line 13 in frontend/src/pages/Risk/VulnerabilityPieChart.tsx

View workflow job for this annotation

GitHub Actions / lint

'arc' is defined but never used

const VulnerabilityPieChart = (props: {
title: string;
Expand All @@ -14,20 +21,77 @@ const VulnerabilityPieChart = (props: {
const history = useHistory();
const { title, data, colors, type } = props;
const { cardRoot, cardSmall, header, chartSmall } = RiskStyles.classesRisk;

// console.log('VulnerabilityPieChart props:', props); // Debugging

// const getTooltip = ({ datum }: PieTooltipProps<any>) => {
// const totalValue = data.reduce((acc, curr) => acc + curr.value, 0);
// const percentage = ((datum.value / totalValue) * 100).toFixed(2);
// return (
// <div
// role="tooltip"
// aria-label={`${datum.id}: ${datum.value} (${percentage}%)`}
// >
// <strong>
// {datum.id}: {datum.value} ({percentage}%)
// </strong>
// </div>
// );
// };

// const customLayer = (props: PieCustomLayerProps<any>) => {
// const pieArc = arc<any>()
// .innerRadius(0)
// .outerRadius(Math.min(props.centerX, props.centerY));

// return (
// <g>
// {props.dataWithArc.map((arcDatum) => {
// const centroid = pieArc.centroid(arcDatum.arc);
// const percentage = (
// (arcDatum.value / data.reduce((acc, curr) => acc + curr.value, 0)) *
// 100
// ).toFixed(2);
// return (
// <g
// key={arcDatum.id}
// transform={`translate(${centroid[0]},${centroid[1]})`}
// ></g>
// );
// })}
// </g>
// );
// };

const ariaLabel =
`${title} pie chart. ` +
data
.map(
(point) =>
`${point.id}: ${point.value} (${(
(point.value / data.reduce((acc, curr) => acc + curr.value, 0)) *
100
).toFixed(2)}%)`
)
.join(', ');

return (
<Paper elevation={0} className={cardRoot}>
<div className={cardSmall}>
<div className={header}>
<h2>{title}</h2>
</div>
<div className={chartSmall}>
<ResponsivePie
<div className={chartSmall} aria-label={ariaLabel}>
{/* <div role="img" aria-label={ariaLabel}> */}
<ResponsivePieCanvas
data={data as any}
innerRadius={0.5}
padAngle={0.7}
arcLabelsSkipAngle={10}
arcLinkLabelsSkipAngle={10}
colors={colors}
cornerRadius={3}
sortByValue={true}
activeOuterRadiusOffset={8}
borderWidth={1}
margin={{
left: 30,
right: 50,
Expand All @@ -39,10 +103,144 @@ const VulnerabilityPieChart = (props: {
history.push(`/inventory/vulnerabilities?severity=${event.id}`);
}
}}
// arcLabel={(datum) => `${datum.id} (${datum.value})`}
// arcLinkLabel={(datum) => `${datum.id}: ${datum.value}`}
arcLabel={(datum) => `(${datum.value})`}
arcLabelsSkipAngle={10}
arcLabelsTextColor={{
from: 'color',
modifiers: [['darker', 3]]
}}
arcLinkLabelsSkipAngle={10}
arcLinkLabel={(datum) => `${datum.id}`}
arcLinkLabelsThickness={3}
arcLinkLabelsColor={{ from: 'color' }}
arcLinkLabelsTextColor={{
from: 'color',
modifiers: [['darker', 3]]
}}
defs={[
{
id: 'dots',
type: 'patternDots',
background: 'inherit',
color: 'rgba(255, 255, 255, 0.3)',
size: 4,
padding: 1,
stagger: true
},
{
id: 'lines',
type: 'patternLines',
background: 'inherit',
color: 'rgba(255, 255, 255, 0.3)',
rotation: -45,
lineWidth: 6,
spacing: 10
}
]}
fill={[
{
match: {
id: 'High'
},
id: 'dots'
},
{
match: {
id: 'Medium'
},
id: 'dots'
},
{
match: {
id: 'Low'
},
id: 'dots'
},
{
match: {
id: 'Critical'
},
id: 'dots'
},
{
match: {
id: 'scala'
},
id: 'lines'
},
{
match: {
id: 'lisp'
},
id: 'lines'
},
{
match: {
id: 'elixir'
},
id: 'lines'
},
{
match: {
id: 'javascript'
},
id: 'lines'
}
]}
// legends={[
// {
// anchor: 'right',
// direction: 'column',
// justify: false,
// translateX: 60,
// translateY: 56,
// itemsSpacing: 6,
// itemWidth: 100,
// itemHeight: 18,
// itemTextColor: '#999',
// itemDirection: 'left-to-right',
// itemOpacity: 1,
// symbolSize: 18,
// symbolShape: 'circle',
// effects: [
// {
// on: 'hover',
// style: {
// itemTextColor: '#000'
// }
// }
// ]
// }
// ]}
legends={[
{
anchor: 'bottom-left',
direction: 'column',
justify: false,
translateX: 0,
translateY: 0,
itemWidth: 25,
itemHeight: 20,
itemsSpacing: 0,
symbolSize: 20,
itemDirection: 'left-to-right'
}
]}
layers={[
'arcs',
'arcLabels',
'arcLinkLabels',
'legends'
//customLayer
]}
/>
{/* </div> */}
</div>
</div>
</Paper>
);
};

export default VulnerabilityPieChart;

0 comments on commit adfdc52

Please sign in to comment.