diff --git a/apps/frontend/src/components/analytics-dashboard/analytics-chart/analytics-chart-constants.ts b/apps/frontend/src/components/analytics-dashboard/analytics-chart/analytics-chart-constants.ts index 20206da55a..123ca99f2b 100644 --- a/apps/frontend/src/components/analytics-dashboard/analytics-chart/analytics-chart-constants.ts +++ b/apps/frontend/src/components/analytics-dashboard/analytics-chart/analytics-chart-constants.ts @@ -41,38 +41,38 @@ export const VISIBLE_PROJECT_STATUS_CHANGE_EVENT_STATUS_SET = export const LIGHT_LEGEND_PALETTE = [ 'hsl(152, 100%, 34%)', - 'hsl(26, 100%, 42%)', - 'hsl(202, 100%, 35%)', - 'hsl(327, 45%, 64%)', - 'hsl(41, 100%, 45%)', - 'hsl(250, 60%, 33%)', - 'hsl(170, 43%, 47%)', - 'hsl(330, 60%, 33%)', - 'hsl(46, 100%, 36%)', - 'hsl(167, 100%, 30%)', - 'hsl(343, 38%, 45%)', - 'hsl(222, 100%, 28%)', - 'hsl(270, 62%, 60%)', - 'hsl(32, 100%, 37%)', - 'hsl(349, 57%, 51%)', - 'hsl(191, 43%, 37%)', + 'hsl(41, 79%, 46%)', + 'hsl(203, 76%, 64%)', + 'hsl(0, 93%, 62%)', + 'hsl(143, 66%, 29%)', + 'hsl(58, 89%, 25%)', + 'hsl(311, 64%, 49%)', + 'hsl(198, 91%, 32%)', + 'hsl(12, 88%, 27%)', + 'hsl(236, 61%, 60%)', + 'hsl(102, 59%, 74%)', + 'hsl(293, 76%, 79%)', + 'hsl(67, 99%, 41%)', + 'hsl(179, 100%, 50%)', + 'hsl(102, 100%, 61%)', + 'hsl(0, 100%, 32%)', ] export const DARK_LEGEND_PALETTE = [ 'hsl(145, 78%, 48%)', - 'hsl(41, 100%, 50%)', - 'hsl(202, 77%, 63%)', - 'hsl(323, 66%, 72%)', - 'hsl(56, 85%, 60%)', - 'hsl(255, 92%, 80%)', - 'hsl(12, 100%, 67%)', - 'hsl(176, 58%, 56%)', - 'hsl(60, 100%, 41%)', - 'hsl(165, 80%, 38%)', - 'hsl(341, 36%, 56%)', - 'hsl(226, 60%, 49%)', - 'hsl(252, 53%, 62%)', - 'hsl(75, 59%, 50%)', - 'hsl(195, 56%, 42%)', - 'hsl(30, 59%, 56%)', + 'hsl(41, 79%, 46%)', + 'hsl(203, 76%, 64%)', + 'hsl(0, 93%, 62%)', + 'hsl(143, 66%, 29%)', + 'hsl(58, 94%, 45%)', + 'hsl(311, 64%, 49%)', + 'hsl(198, 91%, 32%)', + 'hsl(12, 88%, 27%)', + 'hsl(236, 61%, 60%)', + 'hsl(102, 59%, 74%)', + 'hsl(293, 76%, 79%)', + 'hsl(61, 92%, 33%)', + 'hsl(179, 100%, 50%)', + 'hsl(102, 100%, 61%)', + 'hsl(0, 100%, 32%)', ] diff --git a/apps/frontend/src/components/analytics-dashboard/analytics-chart/analytics-chart-utils.ts b/apps/frontend/src/components/analytics-dashboard/analytics-chart/analytics-chart-utils.ts index 0f2fc4f07d..79cb86edc5 100644 --- a/apps/frontend/src/components/analytics-dashboard/analytics-chart/analytics-chart-utils.ts +++ b/apps/frontend/src/components/analytics-dashboard/analytics-chart/analytics-chart-utils.ts @@ -288,6 +288,7 @@ type PaletteRankEntry = { key: string label: string total: number + excludedFromRank?: boolean } function formatDatasetTooltip(projectName: string | undefined): string | undefined { @@ -330,9 +331,12 @@ function buildPaletteColorsByDownloadRank( const colorsByKey = new Map() if (palette.length === 0) return colorsByKey - const sortedEntries = [...entries].sort( - (a, b) => b.total - a.total || a.label.localeCompare(b.label) || a.key.localeCompare(b.key), - ) + const compareEntries = (a: PaletteRankEntry, b: PaletteRankEntry) => + b.total - a.total || a.label.localeCompare(b.label) || a.key.localeCompare(b.key) + const rankedEntries = entries.filter((entry) => !entry.excludedFromRank).sort(compareEntries) + const excludedEntries = entries.filter((entry) => entry.excludedFromRank).sort(compareEntries) + const sortedEntries = [...rankedEntries, ...excludedEntries] + sortedEntries.forEach((entry, index) => { colorsByKey.set(entry.key, getPaletteColorForIndex(index, palette)) }) @@ -340,6 +344,27 @@ function buildPaletteColorsByDownloadRank( return colorsByKey } +function isExcludedFromPaletteRank(breakdownValues: readonly string[]): boolean { + return breakdownValues.some( + (value) => + isUnknownAnalyticsBreakdownValue(value) || isNoDependentAnalyticsBreakdownValue(value), + ) +} + +function buildPaletteRankEntry( + key: string, + breakdownValues: readonly string[], + total: number, + formatLabel: (breakdownValues: readonly string[]) => string, +): PaletteRankEntry { + return { + key, + label: formatLabel(breakdownValues), + total, + excludedFromRank: isExcludedFromPaletteRank(breakdownValues), + } +} + export function getMetricValue( point: Labrinth.Analytics.v3.ProjectAnalytics, activeStat: AnalyticsDashboardStat, @@ -499,11 +524,14 @@ export function buildChartDatasets( }) const colorsByBreakdown = buildPaletteColorsByDownloadRank( - Array.from(dataByBreakdown.keys()).map((breakdownKey) => ({ - key: breakdownKey, - label: formatChartBreakdownLabels(breakdownValuesByKey.get(breakdownKey) ?? []), - total: downloadTotalsByBreakdown.get(breakdownKey) ?? 0, - })), + Array.from(dataByBreakdown.keys()).map((breakdownKey) => + buildPaletteRankEntry( + breakdownKey, + breakdownValuesByKey.get(breakdownKey) ?? [], + downloadTotalsByBreakdown.get(breakdownKey) ?? 0, + formatChartBreakdownLabels, + ), + ), palette, ) @@ -675,11 +703,14 @@ export function buildChartDatasets( }) const colorsByBreakdown = buildPaletteColorsByDownloadRank( - Array.from(dataByProjectBreakdown.keys()).map((breakdownKey) => ({ - key: breakdownKey, - label: formatChartBreakdownLabels(breakdownValuesByKey.get(breakdownKey) ?? []), - total: downloadTotalsByProjectBreakdown.get(breakdownKey) ?? 0, - })), + Array.from(dataByProjectBreakdown.keys()).map((breakdownKey) => + buildPaletteRankEntry( + breakdownKey, + breakdownValuesByKey.get(breakdownKey) ?? [], + downloadTotalsByProjectBreakdown.get(breakdownKey) ?? 0, + formatChartBreakdownLabels, + ), + ), palette, )