Something went wrong. Try again.
Cursor plugin specification and official plugins
Something went wrong. Try again.
4.0 kB · 223 lines
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224---description: Accessibility guidelines for analytics charts and visualizationsglobs: - "**/charts/**/*.tsx" - "**/analytics/**/*.tsx" - "**/dashboard/**/*.tsx" - "**/visualization/**/*.tsx"alwaysApply: false---
# Chart Accessibility Guidelines
Ensure analytics visualizations are accessible to all users.
## Color Contrast
### Don't Rely on Color Alone
```typescript// ✅ Good - use patterns or labels in addition to colordataLabels: { enabled: true, format: "{point.name}: {point.y}",}
// ✅ Good - include values in legendlegend: { labelFormatter: function() { return `${this.name}: ${this.y}`; }}```
### Maintain Sufficient Contrast
```typescript// ✅ Good - high contrast colors from design systemimport { COLORS } from "@/lib/chart-constants";
// The COLORS palette is designed with WCAG AA contrast ratiosseries: [{ color: COLORS.greenPrimary, // Tested for contrast}]```
## Screen Reader Support
### Add Chart Descriptions
```typescript// ✅ Good - describe the chart purposeaccessibility: { enabled: true, description: "Pie chart showing distribution of user intents: 45% Write Code, 28% Ask Questions, 17% Planning, 10% Automation",}```
### Provide Data Table Alternative
```tsx// ✅ Good - offer table view for screen readers<div role="region" aria-label="User activity chart"> <HighchartsReact options={options} /> <details className="sr-only"> <summary>View as table</summary> <table> <caption>User Activity Data</caption> <thead> <tr> <th scope="col">Category</th> <th scope="col">Count</th> </tr> </thead> <tbody> {data.map(item => ( <tr key={item.category}> <td>{item.category}</td> <td>{item.count}</td> </tr> ))} </tbody> </table> </details></div>```
## Keyboard Navigation
### Enable Keyboard Support
```typescript// ✅ Good - enable keyboard navigationaccessibility: { keyboardNavigation: { enabled: true, }}```
## Focus Indicators
### Ensure Visible Focus States
```typescript// ✅ Good - visible focus on interactive elementsplotOptions: { series: { states: { hover: { enabled: true, brightness: 0.1, }, select: { enabled: true, color: COLORS.bluePrimary, } } }}```
## Semantic Labels
### Use Descriptive Titles
```typescript// ✅ Good - descriptive, not generictitle: { text: "Monthly Revenue by Product Category",}
// ❌ Bad - vague titletitle: { text: "Chart 1",}```
### Label Axes Clearly
```typescript// ✅ Good - clear axis labelsxAxis: { title: { text: "Date", }, accessibility: { description: "Dates from January to December 2024", }},yAxis: { title: { text: "Revenue (USD)", }, accessibility: { description: "Revenue in US dollars, ranging from $0 to $100,000", }}```
## Animation Considerations
### Respect Reduced Motion Preferences
```typescript// ✅ Good - disable animation for accessibilitychart: { animation: false,},plotOptions: { series: { animation: false, }}
// Or detect user preferenceconst prefersReducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
chart: { animation: !prefersReducedMotion,}```
## Text Sizing
### Use Readable Font Sizes
```typescript// ✅ Good - minimum 11px for labelsdataLabels: { style: { fontSize: "11px", // Minimum readable size }},legend: { itemStyle: { fontSize: "12px", }}
// ❌ Bad - too small to readdataLabels: { style: { fontSize: "8px", }}```
## Alternative Formats
### Offer Download Options
```tsx// ✅ Good - allow data export<ChartContainer> <HighchartsReact options={options} /> <button onClick={() => downloadAsCSV(data)} aria-label="Download chart data as CSV file" > Download Data </button></ChartContainer>```