|
@@ -20,7 +20,37 @@ type TooltipLineItem = {
|
|
|
shapeSize?: number
|
|
shapeSize?: number
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-function getVChartDefaultColors(domainLength: number) {
|
|
|
|
|
|
|
+const THEME_CHART_COLOR_VARIABLES = [
|
|
|
|
|
+ '--chart-1',
|
|
|
|
|
+ '--chart-2',
|
|
|
|
|
+ '--chart-3',
|
|
|
|
|
+ '--chart-4',
|
|
|
|
|
+ '--chart-5',
|
|
|
|
|
+] as const
|
|
|
|
|
+
|
|
|
|
|
+function getThemeChartColors(themeKey?: string): string[] {
|
|
|
|
|
+ if (typeof document === 'undefined') return []
|
|
|
|
|
+ void themeKey
|
|
|
|
|
+
|
|
|
|
|
+ const bodyStyle = window.getComputedStyle(document.body)
|
|
|
|
|
+ const rootStyle = window.getComputedStyle(document.documentElement)
|
|
|
|
|
+
|
|
|
|
|
+ return THEME_CHART_COLOR_VARIABLES.map((name) => {
|
|
|
|
|
+ return (
|
|
|
|
|
+ bodyStyle.getPropertyValue(name) || rootStyle.getPropertyValue(name)
|
|
|
|
|
+ ).trim()
|
|
|
|
|
+ }).filter(Boolean)
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+function getVChartDefaultColors(domainLength: number, themeKey?: string) {
|
|
|
|
|
+ const themeColors = getThemeChartColors(themeKey)
|
|
|
|
|
+ if (themeColors.length > 0) {
|
|
|
|
|
+ return Array.from(
|
|
|
|
|
+ { length: Math.max(domainLength, themeColors.length) },
|
|
|
|
|
+ (_, index) => themeColors[index % themeColors.length]
|
|
|
|
|
+ )
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
const scheme =
|
|
const scheme =
|
|
|
vchartDefaultDataScheme.find(
|
|
vchartDefaultDataScheme.find(
|
|
|
(item) => !item.maxDomainLength || domainLength <= item.maxDomainLength
|
|
(item) => !item.maxDomainLength || domainLength <= item.maxDomainLength
|
|
@@ -49,7 +79,8 @@ function renderQuotaCompat(rawQuota: number, digits = 4): string {
|
|
|
export function processChartData(
|
|
export function processChartData(
|
|
|
data: QuotaDataItem[],
|
|
data: QuotaDataItem[],
|
|
|
timeGranularity: TimeGranularity = 'day',
|
|
timeGranularity: TimeGranularity = 'day',
|
|
|
- t?: TFunction
|
|
|
|
|
|
|
+ t?: TFunction,
|
|
|
|
|
+ themeKey?: string
|
|
|
): ProcessedChartData {
|
|
): ProcessedChartData {
|
|
|
const tt: TFunction = t ?? ((x) => x)
|
|
const tt: TFunction = t ?? ((x) => x)
|
|
|
const otherLabel = tt('Other')
|
|
const otherLabel = tt('Other')
|
|
@@ -240,7 +271,10 @@ export function processChartData(
|
|
|
const sortedTimes = Array.from(timeModelMap.keys()).sort()
|
|
const sortedTimes = Array.from(timeModelMap.keys()).sort()
|
|
|
const sortedModels = [...allModels].sort()
|
|
const sortedModels = [...allModels].sort()
|
|
|
const modelColorDomain = Array.from(new Set([...sortedModels, otherLabel]))
|
|
const modelColorDomain = Array.from(new Set([...sortedModels, otherLabel]))
|
|
|
- const modelColorRange = getVChartDefaultColors(modelColorDomain.length)
|
|
|
|
|
|
|
+ const modelColorRange = getVChartDefaultColors(
|
|
|
|
|
+ modelColorDomain.length,
|
|
|
|
|
+ themeKey
|
|
|
|
|
+ )
|
|
|
const otherColor = modelColorRange[modelColorDomain.indexOf(otherLabel)]
|
|
const otherColor = modelColorRange[modelColorDomain.indexOf(otherLabel)]
|
|
|
const otherTooltipColor =
|
|
const otherTooltipColor =
|
|
|
typeof otherColor === 'string' ? otherColor : '#FF8A00'
|
|
typeof otherColor === 'string' ? otherColor : '#FF8A00'
|
|
@@ -665,7 +699,7 @@ export function processChartData(
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-const USER_COLORS = [
|
|
|
|
|
|
|
+const USER_COLOR_FALLBACKS = [
|
|
|
'#5B8FF9',
|
|
'#5B8FF9',
|
|
|
'#5AD8A6',
|
|
'#5AD8A6',
|
|
|
'#F6BD16',
|
|
'#F6BD16',
|
|
@@ -682,11 +716,20 @@ export function processUserChartData(
|
|
|
data: QuotaDataItem[],
|
|
data: QuotaDataItem[],
|
|
|
timeGranularity: TimeGranularity = 'day',
|
|
timeGranularity: TimeGranularity = 'day',
|
|
|
t?: TFunction,
|
|
t?: TFunction,
|
|
|
- limit = 10
|
|
|
|
|
|
|
+ limit = 10,
|
|
|
|
|
+ themeKey?: string
|
|
|
): ProcessedUserChartData {
|
|
): ProcessedUserChartData {
|
|
|
const tt: TFunction = t ?? ((x) => x)
|
|
const tt: TFunction = t ?? ((x) => x)
|
|
|
const { config } = getCurrencyDisplay()
|
|
const { config } = getCurrencyDisplay()
|
|
|
const quotaPerUnit = config.quotaPerUnit
|
|
const quotaPerUnit = config.quotaPerUnit
|
|
|
|
|
+ const themeUserColors = getThemeChartColors(themeKey)
|
|
|
|
|
+ const userColorRange =
|
|
|
|
|
+ themeUserColors.length > 0
|
|
|
|
|
+ ? Array.from(
|
|
|
|
|
+ { length: Math.max(limit, themeUserColors.length) },
|
|
|
|
|
+ (_, index) => themeUserColors[index % themeUserColors.length]
|
|
|
|
|
+ )
|
|
|
|
|
+ : USER_COLOR_FALLBACKS
|
|
|
|
|
|
|
|
const formatVal = (raw: number) => renderQuotaCompat(raw, 2)
|
|
const formatVal = (raw: number) => renderQuotaCompat(raw, 2)
|
|
|
|
|
|
|
@@ -704,7 +747,7 @@ export function processUserChartData(
|
|
|
subtext: tt('No data available'),
|
|
subtext: tt('No data available'),
|
|
|
},
|
|
},
|
|
|
legends: { visible: false },
|
|
legends: { visible: false },
|
|
|
- color: { type: 'ordinal', range: USER_COLORS },
|
|
|
|
|
|
|
+ color: { type: 'ordinal', range: userColorRange },
|
|
|
background: { fill: 'transparent' },
|
|
background: { fill: 'transparent' },
|
|
|
},
|
|
},
|
|
|
spec_user_trend: {
|
|
spec_user_trend: {
|
|
@@ -719,7 +762,7 @@ export function processUserChartData(
|
|
|
subtext: tt('No data available'),
|
|
subtext: tt('No data available'),
|
|
|
},
|
|
},
|
|
|
legends: { visible: true, selectMode: 'single' },
|
|
legends: { visible: true, selectMode: 'single' },
|
|
|
- color: { type: 'ordinal', range: USER_COLORS },
|
|
|
|
|
|
|
+ color: { type: 'ordinal', range: userColorRange },
|
|
|
point: { visible: false },
|
|
point: { visible: false },
|
|
|
background: { fill: 'transparent' },
|
|
background: { fill: 'transparent' },
|
|
|
},
|
|
},
|
|
@@ -749,7 +792,7 @@ export function processUserChartData(
|
|
|
|
|
|
|
|
const userColorMap = topUsers.reduce<Record<string, string>>(
|
|
const userColorMap = topUsers.reduce<Record<string, string>>(
|
|
|
(acc, user, i) => {
|
|
(acc, user, i) => {
|
|
|
- acc[user] = USER_COLORS[i % USER_COLORS.length]
|
|
|
|
|
|
|
+ acc[user] = userColorRange[i % userColorRange.length]
|
|
|
return acc
|
|
return acc
|
|
|
},
|
|
},
|
|
|
{}
|
|
{}
|