@@ -13,6 +13,12 @@ import { parseRepoUrl } from '#shared/utils/git-providers'
1313import type { PackageMetaResponse } from '#shared/types'
1414import { encodePackageName } from '#shared/utils/npm'
1515import { fetchNpmDownloadsRange } from '~/utils/npm/api'
16+ import type { AltCopyArgs } from 'vue-data-ui'
17+ import {
18+ computeLineChartAnalysis ,
19+ type TrendLineConfig ,
20+ type TrendLineDataset ,
21+ } from '../utils/charts'
1622
1723export type PackumentLikeForTime = {
1824 time ?: Record < string , string >
@@ -405,6 +411,9 @@ export function getNpmPackageCreationDate(packument: PackumentLikeForTime): stri
405411}
406412
407413export function useCharts ( ) {
414+ const { t } = useI18n ( )
415+ const compactNumberFormatter = useCompactNumberFormatter ( )
416+
408417 function resolveDateRange (
409418 evolutionOptions : EvolutionOptions ,
410419 packageCreatedIso : string | null ,
@@ -615,11 +624,69 @@ export function useCharts() {
615624 return next
616625 }
617626
627+ function createAltTextForTrendLineChart ( {
628+ dataset,
629+ config,
630+ } : AltCopyArgs < TrendLineDataset , TrendLineConfig > ) : string {
631+ if ( ! dataset ) return ''
632+
633+ const analysis = dataset . lines . map ( ( { name, series } ) => ( {
634+ name,
635+ ...computeLineChartAnalysis ( series ) ,
636+ dates : config . formattedDates ,
637+ hasEstimation : config . hasEstimation ,
638+ } ) )
639+
640+ const granularity = t ( `package.trends.granularity_${ config . granularity } ` ) . toLocaleLowerCase ( )
641+
642+ const packages_analysis = analysis
643+ . map ( ( pkg , i ) =>
644+ t ( `package.trends.copy_alt.analysis` , {
645+ package_name : pkg . name ,
646+ start_value : config . formattedDatasetValues [ i ] ?. [ 0 ] ?? 0 ,
647+ end_value : config . formattedDatasetValues [ i ] ?. at ( - 1 ) ?? 0 ,
648+ trend : t ( `package.trends.copy_alt.trend_${ pkg . interpretation . trend } ` ) ,
649+ downloads_slope : compactNumberFormatter . value . format ( pkg . slope ) ,
650+ growth_percentage : `${ pkg . progressionPercent ?. toFixed ( 1 ) } %` ,
651+ } ) ,
652+ )
653+ . join ( ', ' )
654+
655+ const isSinglePackage = analysis . length === 1
656+
657+ const estimation_notice = config . hasEstimation
658+ ? ` ${ isSinglePackage ? t ( 'package.trends.copy_alt.estimation' ) : t ( 'package.trends.copy_alt.estimations' ) } `
659+ : ''
660+
661+ // Packages comparison
662+ const compareText = `${ t ( 'package.trends.copy_alt.compare' , { packages : analysis . map ( a => a . name ) . join ( ', ' ) } ) } `
663+ const singlePackageText = `${ t ( 'package.trends.copy_alt.single_package' , { package : analysis ?. [ 0 ] ?. name ?? '' } ) } `
664+ const generalAnalysis = t ( `package.trends.copy_alt.general_description` , {
665+ start_date : analysis ?. [ 0 ] ?. dates [ 0 ] ?. text ,
666+ end_date : analysis ?. [ 0 ] ?. dates . at ( - 1 ) ?. text ,
667+ granularity,
668+ packages_analysis,
669+ watermark : t ( 'package.trends.copy_alt.watermark' ) ,
670+ estimation_notice,
671+ } )
672+
673+ return ( isSinglePackage ? singlePackageText : compareText ) + generalAnalysis
674+ }
675+
676+ async function copyAltTextForTrendLineChart ( {
677+ dataset,
678+ config,
679+ } : AltCopyArgs < TrendLineDataset , TrendLineConfig > ) {
680+ const altText = createAltTextForTrendLineChart ( { dataset, config } )
681+ await config . copy ( altText )
682+ }
683+
618684 return {
619685 fetchPackageDownloadEvolution,
620686 fetchPackageLikesEvolution,
621687 fetchRepoContributorsEvolution,
622688 fetchRepoRefsForPackages,
623689 getNpmPackageCreationDate,
690+ copyAltTextForTrendLineChart,
624691 }
625692}
0 commit comments