From f2f38a60dc1aef036fff8572440714eba58dfb8e Mon Sep 17 00:00:00 2001 From: Tymoteusz Czech <2625371+Tymek@users.noreply.github.com> Date: Wed, 13 Mar 2024 10:46:32 +0100 Subject: [PATCH] Insights dashboard chart colors (#6504) Improved consistent colors for charts ![image](https://github.com/Unleash/unleash/assets/2625371/f3cb66ec-89f4-46c3-b98d-e28fd4bc5cb5) --- .../UpdatesPerEnvironmentTypeChart.tsx | 23 +++++++++++-- .../executive-dashboard-utils.ts | 16 ---------- .../hooks/useMetricsSummary.ts | 3 +- .../hooks/useProjectChartData.ts | 3 +- .../hooks/useProjectColor.ts | 28 ++++++++++++++++ frontend/src/themes/colors.ts | 32 +++++++++++++++++++ frontend/src/themes/dark-theme.ts | 1 + frontend/src/themes/theme.ts | 1 + frontend/src/themes/themeTypes.ts | 1 + 9 files changed, 88 insertions(+), 20 deletions(-) delete mode 100644 frontend/src/component/executiveDashboard/executive-dashboard-utils.ts create mode 100644 frontend/src/component/executiveDashboard/hooks/useProjectColor.ts diff --git a/frontend/src/component/executiveDashboard/componentsChart/UpdatesPerEnvironmentTypeChart/UpdatesPerEnvironmentTypeChart.tsx b/frontend/src/component/executiveDashboard/componentsChart/UpdatesPerEnvironmentTypeChart/UpdatesPerEnvironmentTypeChart.tsx index 518d817914..56c42cef87 100644 --- a/frontend/src/component/executiveDashboard/componentsChart/UpdatesPerEnvironmentTypeChart/UpdatesPerEnvironmentTypeChart.tsx +++ b/frontend/src/component/executiveDashboard/componentsChart/UpdatesPerEnvironmentTypeChart/UpdatesPerEnvironmentTypeChart.tsx @@ -7,7 +7,6 @@ import { } from 'openapi'; import { LineChart, NotEnoughData } from '../../components/LineChart/LineChart'; import { usePlaceholderData } from 'component/executiveDashboard/hooks/usePlaceholderData'; -import { getProjectColor } from '../../executive-dashboard-utils'; interface IUpdatesPerEnvironmnetTypeChart { environmentTypeTrends: ExecutiveSummarySchema['environmentTypeTrends']; @@ -39,10 +38,30 @@ const groupByDate = ( return grouped; }; +const useEnvironmentTypeColor = () => { + const theme = useTheme(); + + return (environmentType: string) => { + switch (environmentType) { + case 'production': + return theme.palette.charts.series[3]; + case 'staging': + return theme.palette.charts.series[1]; + case 'development': + return theme.palette.charts.series[0]; + case 'test': + return theme.palette.charts.series[2]; + default: + return theme.palette.charts.series[4]; + } + }; +}; + export const UpdatesPerEnvironmentTypeChart: VFC< IUpdatesPerEnvironmnetTypeChart > = ({ environmentTypeTrends, isLoading }) => { const theme = useTheme(); + const getEnvironmentTypeColor = useEnvironmentTypeColor(); const notEnoughData = environmentTypeTrends?.length < 2; const placeholderData = usePlaceholderData({ fill: true, type: 'double' }); @@ -51,7 +70,7 @@ export const UpdatesPerEnvironmentTypeChart: VFC< const labels = environmentTypeTrends?.map((item) => item.date); const datasets = Object.entries(grouped).map( ([environmentType, trends]) => { - const color = getProjectColor(environmentType); + const color = getEnvironmentTypeColor(environmentType); return { label: environmentType, data: trends.map((item) => item.totalUpdates), diff --git a/frontend/src/component/executiveDashboard/executive-dashboard-utils.ts b/frontend/src/component/executiveDashboard/executive-dashboard-utils.ts deleted file mode 100644 index 7c682425a8..0000000000 --- a/frontend/src/component/executiveDashboard/executive-dashboard-utils.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { colors } from 'themes/colors'; - -export const getProjectColor = (str: string): string => { - if (str === 'default') { - // Special case for default project - use primary color - return colors.purple[800]; - } - - let hash = 0; - - for (let i = 0; i < str.length; i++) { - hash = str.charCodeAt(i) + ((hash << 5) - hash); - } - const c = (hash & 0x00ffffff).toString(16).toUpperCase(); - return `#${'00000'.substring(0, 6 - c.length)}${c}`; -}; diff --git a/frontend/src/component/executiveDashboard/hooks/useMetricsSummary.ts b/frontend/src/component/executiveDashboard/hooks/useMetricsSummary.ts index 9d4dc5ddf3..0c08bd0a7f 100644 --- a/frontend/src/component/executiveDashboard/hooks/useMetricsSummary.ts +++ b/frontend/src/component/executiveDashboard/hooks/useMetricsSummary.ts @@ -4,7 +4,7 @@ import { ExecutiveSummarySchema, ExecutiveSummarySchemaMetricsSummaryTrendsItem, } from 'openapi'; -import { getProjectColor } from '../executive-dashboard-utils'; +import { useProjectColor } from './useProjectColor'; type MetricsSummaryTrends = ExecutiveSummarySchema['metricsSummaryTrends']; @@ -33,6 +33,7 @@ export const useMetricsSummary = ( metricsSummaryTrends: MetricsSummaryTrends, ) => { const theme = useTheme(); + const getProjectColor = useProjectColor(); const data = useMemo(() => { const groupedMetrics = groupDataByProject(metricsSummaryTrends); diff --git a/frontend/src/component/executiveDashboard/hooks/useProjectChartData.ts b/frontend/src/component/executiveDashboard/hooks/useProjectChartData.ts index 595018203e..94b2ffbc63 100644 --- a/frontend/src/component/executiveDashboard/hooks/useProjectChartData.ts +++ b/frontend/src/component/executiveDashboard/hooks/useProjectChartData.ts @@ -3,13 +3,14 @@ import { ExecutiveSummarySchema, ExecutiveSummarySchemaProjectFlagTrendsItem, } from '../../../openapi'; -import { getProjectColor } from '../executive-dashboard-utils'; +import { useProjectColor } from './useProjectColor'; import { useTheme } from '@mui/material'; type ProjectFlagTrends = ExecutiveSummarySchema['projectFlagTrends']; export const useProjectChartData = (projectFlagTrends: ProjectFlagTrends) => { const theme = useTheme(); + const getProjectColor = useProjectColor(); const data = useMemo(() => { const groupedFlagTrends = projectFlagTrends.reduce< diff --git a/frontend/src/component/executiveDashboard/hooks/useProjectColor.ts b/frontend/src/component/executiveDashboard/hooks/useProjectColor.ts new file mode 100644 index 0000000000..456b523753 --- /dev/null +++ b/frontend/src/component/executiveDashboard/hooks/useProjectColor.ts @@ -0,0 +1,28 @@ +import { useMemo } from 'react'; +import { useTheme } from '@mui/material'; +import useProjects from 'hooks/api/getters/useProjects/useProjects'; + +export const useProjectColor = () => { + const { projects } = useProjects(); + const theme = useTheme(); + const colors = theme.palette.charts.series; + + const projectsSortedByCreatedAt = useMemo( + () => + projects + .sort( + (a, b) => + new Date(a.createdAt).getTime() - + new Date(b.createdAt).getTime(), + ) + .map((project) => project.id), + [projects], + ); + + const getProjectColor = (str: string): string => { + const index = projectsSortedByCreatedAt.indexOf(str); + return colors[index % colors.length]; + }; + + return getProjectColor; +}; diff --git a/frontend/src/themes/colors.ts b/frontend/src/themes/colors.ts index 47cba0aba6..b6312b0364 100644 --- a/frontend/src/themes/colors.ts +++ b/frontend/src/themes/colors.ts @@ -107,4 +107,36 @@ export const colors = { '#9EC4E3', '#F8B6CC', ] as string[], + chartSeries: [ + '#816DD3', + '#FDB627', + '#64A608', + '#CE6FAD', + '#158FCC', + '#F15A2B', + '#E8C140', + '#BA3961', + '#A49C8F', + '#34BCB4', + '#7C83CC', + '#CF8376', + '#D7E022', + '#5999E2', + '#39B54A', + '#E57377', + '#4FB9E7', + '#AA65EF', + '#F7941E', + '#A82070', + '#1D82C4', + '#7BA992', + '#E24848', + '#9C3C96', + '#1C75BC', + '#DA9828', + '#DD3876', + '#2F8460', + '#C36D50', + '#4652B2', + ] as string[], } as const; diff --git a/frontend/src/themes/dark-theme.ts b/frontend/src/themes/dark-theme.ts index 469e0ce826..9d375011b7 100644 --- a/frontend/src/themes/dark-theme.ts +++ b/frontend/src/themes/dark-theme.ts @@ -302,6 +302,7 @@ const theme = { gradientStale: '#8A3E45', gradientPotentiallyStale: '#875D21', }, + series: colors.chartSeries, }, }, }; diff --git a/frontend/src/themes/theme.ts b/frontend/src/themes/theme.ts index 9cce1feac9..94c70a1f21 100644 --- a/frontend/src/themes/theme.ts +++ b/frontend/src/themes/theme.ts @@ -287,6 +287,7 @@ export const theme = { gradientStale: colors.red[300], gradientPotentiallyStale: colors.orange[500], }, + series: colors.chartSeries, }, }, }; diff --git a/frontend/src/themes/themeTypes.ts b/frontend/src/themes/themeTypes.ts index f3b8622099..e04237d63d 100644 --- a/frontend/src/themes/themeTypes.ts +++ b/frontend/src/themes/themeTypes.ts @@ -145,6 +145,7 @@ declare module '@mui/material/styles' { gradientStale: string; gradientPotentiallyStale: string; }; + series: string[]; }; } interface Theme extends CustomTheme {}