feat: Ajoute tableaux versions accessibles

pull/2573/head
Benjamin Arias 2023-03-16 10:57:11 +01:00 committed by Jérémy Rialland
parent 22f598ae7f
commit b253c7a746
4 changed files with 191 additions and 14 deletions

View File

@ -1,6 +1,6 @@
import { formatValue } from 'publicodes'
import { ComponentProps, ReactElement } from 'react'
import { useTranslation } from 'react-i18next'
import { Trans, useTranslation } from 'react-i18next'
import {
Bar,
ComposedChart,
@ -18,6 +18,8 @@ import { Body } from '@/design-system/typography/paragraphs'
import { useDarkMode } from '@/hooks/useDarkMode'
import { RealResponsiveContainer } from '@/pages/statistiques/Chart'
import FoldingMessage from '../ui/FoldingMessage'
type Data =
| Array<{ date: string; nombre: number }>
| Array<{ date: string; nombre: Record<string, number> }>
@ -57,6 +59,7 @@ export default function PagesChart({ data, sync = true }: PagesChartProps) {
const ComposedChartWithRole = (
props: ComponentProps<typeof ComposedChart> | { role: string }
): ReactElement => <ComposedChart {...props} />
console.log(flattenedData)
return (
<Body as="div">
@ -73,7 +76,9 @@ export default function PagesChart({ data, sync = true }: PagesChartProps) {
layout="horizontal"
data={flattenedData}
syncId={sync ? '1' : undefined}
aria-label={t('Graphique des principaux simulateurs')}
aria-label={t(
'Graphique des principaux simulateurs, présence dune alternative accessible après limage'
)}
role="img"
>
<Legend />
@ -108,10 +113,63 @@ export default function PagesChart({ data, sync = true }: PagesChartProps) {
))}
</ComposedChartWithRole>
</RealResponsiveContainer>
<AccessibleVersion data={flattenedData} />
</Body>
)
}
const AccessibleVersion = ({ data }: PagesChartProps) => {
const { t } = useTranslation()
return (
<FoldingMessage
title={t('Version accessible des données')}
unfoldButtonLabel={t('Afficher la version accessible')}
>
<table role="table" style={{ textAlign: 'center', width: '100%' }}>
<caption className="sr-only">
<Trans>
Tableau présentant le nombre de visites par page et par mois.
</Trans>
</caption>
<thead>
<tr>
<th scope="col">
<Trans>Date</Trans>
</th>
{/* Dynamically add the page keys as th */}
{Object.keys(data[0].nombre).map((key) => (
<th scope="col" key={key}>
{key}
</th>
))}
</tr>
</thead>
<tbody>
{data.map((item) => {
const date = new Date(item.date)
const year = date.getFullYear()
const month = date.getMonth() + 1
return (
<tr key={item.date}>
<td>{`${
String(month).length === 1 ? `0${month}` : month
}/${year}`}</td>
{Object.entries(item.nombre).map(([key, value]) => {
return (
<td key={`${item.date}-${String(key)}`}>{value ?? 0}</td>
)
})}
</tr>
)
})}
</tbody>
</table>
</FoldingMessage>
)
}
function formatMonth(date: string | Date) {
return new Date(date).toLocaleString('default', {
month: 'short',

View File

@ -118,7 +118,7 @@ export default function VisitsChart({
data={flattenData}
syncId={sync ? '1' : undefined}
aria-label={t(
'Graphique statistiques détaillés du nombre visites par jour'
'Graphique statistiques détaillés du nombre visites par jour, présence dune alternative accessible après limage'
)}
role="img"
>

View File

@ -10,6 +10,7 @@ import {
} from 'recharts'
import { StyledLegend } from '@/components/charts/PagesCharts'
import FoldingMessage from '@/components/ui/FoldingMessage'
import { Radio, ToggleGroup } from '@/design-system'
import { Emoji } from '@/design-system/emoji'
import { Spacing } from '@/design-system/layout'
@ -46,6 +47,7 @@ type SatisfactionChartProps = {
data: Array<{
date: string
nombre: Record<string, number>
percent: Record<string, number>
}>
}
@ -96,7 +98,9 @@ export default function SatisfactionChart({ data }: SatisfactionChartProps) {
<RealResponsiveContainer width="100%" height={400}>
<BarChartWithRole
data={flattenData}
aria-label={t('Graphique statistiques détaillés de la satisfaction')}
aria-label={t(
'Graphique statistiques détaillés de la satisfaction, présence dune alternative accessible après limage'
)}
role="img"
>
<XAxis
@ -140,10 +144,74 @@ export default function SatisfactionChart({ data }: SatisfactionChartProps) {
))}
</BarChartWithRole>
</RealResponsiveContainer>
<AccessibleVersion data={flattenData} dataType={dataType} />
</Body>
)
}
const AccessibleVersion = ({
data,
dataType,
}: SatisfactionChartProps & { dataType: string }) => {
const { t } = useTranslation()
const dataKey = dataType === 'pourcentage' ? 'percent' : 'nombre'
return (
<FoldingMessage
title={t('Version accessible des données')}
unfoldButtonLabel={t('Afficher la version accessible')}
>
<table role="table" style={{ textAlign: 'center', width: '100%' }}>
<caption className="sr-only">
<Trans>
Tableau présentant le nombre de visites par page et par mois en{' '}
{dataType === 'pourcentage' ? 'pourcentage' : 'nombres'}.
</Trans>
</caption>
<thead>
<tr>
<th scope="col">
<Trans>Date</Trans>
</th>
<th scope="col">
<Trans>Très bien</Trans>
</th>
<th scope="col">
<Trans>Bien</Trans>
</th>
<th scope="col">
<Trans>Moyen</Trans>
</th>
<th scope="col">
<Trans>Mauvais</Trans>
</th>
</tr>
</thead>
<tbody>
{data.map((item) => {
const date = new Date(item.date)
const year = date.getFullYear()
const month = date.getMonth() + 1
return (
<tr key={item.date}>
<td>{`${
String(month).length === 1 ? `0${month}` : month
}/${year}`}</td>
<td>{item[dataKey]['très bien'] ?? 0}</td>
<td>{item[dataKey].bien ?? 0}</td>
<td>{item[dataKey].moyen ?? 0}</td>
<td>{item[dataKey].mauvais ?? 0}</td>
</tr>
)
})}
</tbody>
</table>
</FoldingMessage>
)
}
const ChangeJanuary2022 = () => {
return (
<Body style={{ maxWidth: '350px' }}>

View File

@ -1,12 +1,13 @@
import { formatValue } from 'publicodes'
import { useCallback, useEffect, useMemo, useState } from 'react'
import { Trans } from 'react-i18next'
import { Trans, useTranslation } from 'react-i18next'
import { useSearchParams } from 'react-router-dom'
import { BrushProps } from 'recharts'
import styled from 'styled-components'
import { toAtString } from '@/components/ATInternetTracking'
import PagesChart from '@/components/charts/PagesCharts'
import FoldingMessage from '@/components/ui/FoldingMessage'
import { useScrollToHash } from '@/components/utils/markdown'
import { Message } from '@/design-system'
import InfoBulle from '@/design-system/InfoBulle'
@ -191,6 +192,8 @@ const StatsDetail = ({ stats }: StatsDetailProps) => {
(searchParams.get('module') as Chapter2) ?? ''
)
const { t } = useTranslation()
useEffect(() => {
const paramsEntries = [
['periode', period !== defaultPeriod ? period : ''],
@ -229,7 +232,11 @@ const StatsDetail = ({ stats }: StatsDetailProps) => {
const satisfaction = useMemo(() => {
return filterByChapter2(stats.satisfaction as Pageish[], chapter2)
}, [chapter2])
}, [chapter2]) as Array<{
date: string
nombre: Record<string, number>
percent: Record<string, number>
}>
const [[startDateIndex, endDateIndex], setDateIndex] = useState<
[startIndex: number, endIndex: number]
@ -333,14 +340,58 @@ const StatsDetail = ({ stats }: StatsDetailProps) => {
<div id="visites-panel">
<H3>Visites</H3>
{visites.length ? (
<Chart
key={period + visites.length.toString()}
period={period}
data={visites}
onDateChange={handleDateChange}
startIndex={startDateIndex}
endIndex={endDateIndex}
/>
<>
<Chart
key={period + visites.length.toString()}
period={period}
data={visites}
onDateChange={handleDateChange}
startIndex={startDateIndex}
endIndex={endDateIndex}
/>
<FoldingMessage
title={t('Version accessible des données')}
unfoldButtonLabel={t('Afficher la version accessible')}
>
<table
role="table"
style={{ textAlign: 'center', width: '100%' }}
>
<caption className="sr-only">
<Trans>
Tableau présentant le nombre de visites sur le site
mon-entreprise par mois ou par jours.
</Trans>
</caption>
<thead>
<tr>
<th scope="col">
<Trans>{period}</Trans>
</th>
<th scope="col">
<Trans>Nombre de visites</Trans>
</th>
</tr>
</thead>
<tbody>
{visites.map((visite) => {
const visiteDateParts = visite.date.split('-')
return (
<tr key={visite.date}>
<td>
{period === 'mois'
? `${visiteDateParts[1]}-${visiteDateParts[2]}`
: visite.date}
</td>
<td>{visite.nombre}</td>
</tr>
)
})}
</tbody>
</table>
</FoldingMessage>
</>
) : (
<Message type="info">Aucune donnée disponible.</Message>
)}