diff --git a/app/components/Compare/FacetBarChart.vue b/app/components/Compare/FacetBarChart.vue index bc52fda4f2..79e373888d 100644 --- a/app/components/Compare/FacetBarChart.vue +++ b/app/components/Compare/FacetBarChart.vue @@ -142,6 +142,7 @@ const config = computed(() => { return { theme: isDarkMode.value ? 'dark' : '', a11y: { + includeTable: true, translations: { keyboardNavigation: $t('package.trends.chart_assistive_text.keyboard_navigation_vertical'), tableAvailable: $t('package.trends.chart_assistive_text.table_available'), diff --git a/app/components/Compare/FacetScatterChart.vue b/app/components/Compare/FacetScatterChart.vue index 634a2cbaab..dd87cd8a91 100644 --- a/app/components/Compare/FacetScatterChart.vue +++ b/app/components/Compare/FacetScatterChart.vue @@ -136,6 +136,9 @@ function buildExportFilename(extension: string): string { const config = computed(() => { return { + a11y: { + includeTable: true, + }, theme: isDarkMode.value ? 'dark' : '', userOptions: { buttons: { diff --git a/app/components/Package/DailyDownloadsHeatmap.vue b/app/components/Package/DailyDownloadsHeatmap.vue index ab4bdef01b..0991d6fb1d 100644 --- a/app/components/Package/DailyDownloadsHeatmap.vue +++ b/app/components/Package/DailyDownloadsHeatmap.vue @@ -26,6 +26,13 @@ type DailyDataPoint = { const props = defineProps<{ packageName: string }>() const chartRef = useTemplateRef('chartRef') +const showDataTable = shallowRef(false) +const chartPanel = useTemplateRef('chartPanel') +const { height: renderedChartHeight } = useElementSize(chartPanel) +const lastChartHeight = shallowRef(0) +watch(renderedChartHeight, height => { + if (height > 0) lastChartHeight.value = height +}) const { locale, localeProperties } = useI18n() const isRTL = computed(() => localeProperties.value.dir === 'rtl') @@ -219,6 +226,40 @@ const heatmap = computed(() => { const dataset = computed(() => heatmap.value.dataset) +const tableRows = computed(() => { + const yesterday = addDays(toUtcDay(new Date()), -1) + const { weekStarts, dataset: rows, reportedDates, anomalousDates } = heatmap.value + const maximum = Math.max(0, ...rows.flatMap(row => row.values)) + + return weekStarts.flatMap((weekStart, weekIndex) => + WEEK_DAYS.flatMap((_, dayIndex) => { + const date = addDays(parseIsoDate(weekStart), dayIndex) + if (date > yesterday) return [] + const key = toIsoDate(date) + const rawValue = rows[dayIndex]?.values[weekIndex] ?? 0 + const value = + reportedDates.has(key) && !anomalousDates.has(key) && rawValue > 0 ? rawValue : null + return [ + { + date: date.getTime(), + value, + color: + value == null + ? colors.value.bg + : `color-mix(in srgb, ${accent.value} ${maximum > 0 ? (value / maximum) * 100 : 0}%, ${colors.value.bg})`, + }, + ] + }), + ) +}) + +const tableDataset = computed(() => [ + { + name: props.packageName, + series: tableRows.value.map(row => row.value), + }, +]) + function computeMinMax(value: number, maxVal: number, date: string | null) { return { value: compactNumberFormatter.value.format(value), @@ -607,174 +648,208 @@ function getLegendContent(svg: VueUiHeatmapSvgSlotProps['svg']) {
- -
- - - - -