diff --git a/src/containers/Versions/Versions.tsx b/src/containers/Versions/Versions.tsx index 417a7feef..7e0042e89 100644 --- a/src/containers/Versions/Versions.tsx +++ b/src/containers/Versions/Versions.tsx @@ -32,7 +32,7 @@ export function VersionsContainer({cluster, loading}: VersionsContainerProps) { {tablets: false, fieldsRequired: ['SystemState', 'SubDomainKey']}, {pollingInterval: autoRefreshInterval}, ); - const versionToColor = useVersionToColorMap(); + const versionToColor = useVersionToColorMap(cluster); const versionsValues = useGetVersionValues({cluster, versionToColor, clusterLoading: loading}); diff --git a/src/styles/index.scss b/src/styles/index.scss index 75de0026c..9ae0d76a0 100644 --- a/src/styles/index.scss +++ b/src/styles/index.scss @@ -2,6 +2,7 @@ @forward './themes.scss'; @forward './unipika.scss'; @forward './illustrations.scss'; +@forward './versions.scss'; body { --ydb-drawer-veil-z-index: 2; diff --git a/src/styles/versions.scss b/src/styles/versions.scss new file mode 100644 index 000000000..14b1c1371 --- /dev/null +++ b/src/styles/versions.scss @@ -0,0 +1,106 @@ +.g-root { + &_theme_light, + &_theme_light-hc { + --versions-red-1: #f4315b; + --versions-red-2: #ff426b; + --versions-red-3: #ff7391; + --versions-red-4: #ff8ba4; + + --versions-orange-red-1: #ff6050; + --versions-orange-red-2: #ff7a6d; + --versions-orange-red-3: #ffafa6; + --versions-orange-red-4: #ffbcb5; + + --versions-orange-1: #ff9233; + --versions-orange-2: #ffad65; + --versions-orange-3: #ffc593; + --versions-orange-4: #ffd3ac; + + --versions-yellow-1: #ffea00; + --versions-yellow-2: #ffee31; + --versions-yellow-3: #fff480; + --versions-yellow-4: #fff8a9; + + --versions-green-1: #a1ee26; + --versions-green-2: #b1ff33; + --versions-green-3: #cbff78; + --versions-green-4: #ddffa7; + + --versions-teal-1: #31eba4; + --versions-teal-2: #16ffa6; + --versions-teal-3: #4cffba; + --versions-teal-4: #9bffd8; + + --versions-cyan-1: #2ee4e8; + --versions-cyan-2: #0cfbff; + --versions-cyan-3: #63fdff; + --versions-cyan-4: #b1feff; + + --versions-blue-1: #386bff; + --versions-blue-2: #4070ff; + --versions-blue-3: #658bff; + --versions-blue-4: #a1b9ff; + + --versions-purple-1: #c73af7; + --versions-purple-2: #c92cff; + --versions-purple-3: #dd78ff; + --versions-purple-4: #e79fff; + + --versions-pink-1: #ff49bb; + --versions-pink-2: #ff34b3; + --versions-pink-3: #ff75cb; + --versions-pink-4: #ffb0e1; + } + &_theme_dark, + &_theme_dark-hc { + --versions-red-1: #d50c38; + --versions-red-2: #ff2051; + --versions-red-3: #fb3a64; + --versions-red-4: #ff6989; + + --versions-orange-red-1: #eb3320; + --versions-orange-red-2: #ff503e; + --versions-orange-red-3: #ff8376; + --versions-orange-red-4: #ffa399; + + --versions-orange-1: #f47b10; + --versions-orange-2: #ff9b43; + --versions-orange-3: #ffb06a; + --versions-orange-4: #ffc693; + + --versions-yellow-1: #ffea00; + --versions-yellow-2: #ffee31; + --versions-yellow-3: #fff480; + --versions-yellow-4: #fff8a9; + + --versions-green-1: #83d400; + --versions-green-2: #b1ff33; + --versions-green-3: #cbff78; + --versions-green-4: #ddffa7; + + --versions-teal-1: #27c98b; + --versions-teal-2: #16ffa6; + --versions-teal-3: #4cffba; + --versions-teal-4: #9bffd8; + + --versions-cyan-1: #0edbde; + --versions-cyan-2: #0cfbff; + --versions-cyan-3: #63fdff; + --versions-cyan-4: #b1feff; + + --versions-blue-1: #2059ff; + --versions-blue-2: #4070ff; + --versions-blue-3: #658bff; + --versions-blue-4: #a1b9ff; + + --versions-purple-1: #ab07e3; + --versions-purple-2: #c92cff; + --versions-purple-3: #dd78ff; + --versions-purple-4: #e79fff; + + --versions-pink-1: #e71498; + --versions-pink-2: #ff34b3; + --versions-pink-3: #ff75cb; + --versions-pink-4: #ffb0e1; + } +} diff --git a/src/utils/clusterVersionColors.ts b/src/utils/clusterVersionColors.ts index a97c17379..0a88ed78e 100644 --- a/src/utils/clusterVersionColors.ts +++ b/src/utils/clusterVersionColors.ts @@ -3,7 +3,13 @@ import uniqBy from 'lodash/uniqBy'; import type {MetaClusterVersion} from '../types/api/meta'; import type {VersionToColorMap} from '../types/versions'; -import {COLORS, DEFAULT_COLOR, getMinorVersion, hashCode} from './versions'; +import { + COLORS, + DEFAULT_COLOR, + getMinorVersion, + getMinorVersionColorVariant, + hashCode, +} from './versions'; const UNDEFINED_COLOR_INDEX = '__no_color__'; @@ -40,11 +46,14 @@ export const getVersionColors = (versionMap: VersionsMap) => { // baseColorIndex is numeric as we check if it is UNDEFINED_COLOR_INDEX before const currentColorIndex = Number(baseColorIndex) % COLORS.length; const minorQuantity = item.size; - const majorColor = COLORS[currentColorIndex]; - const opacityPercent = Math.max(100 - minorIndex * (100 / minorQuantity), 20); - const hexOpacity = Math.round((opacityPercent * 255) / 100).toString(16); - const versionColor = `${majorColor}${hexOpacity}`; - versionToColor.set(minor, versionColor); + + const minorColorVariant = getMinorVersionColorVariant( + minorIndex, + minorQuantity, + ); + const minorColor = COLORS[currentColorIndex][minorColorVariant]; + + versionToColor.set(minor, minorColor); } }); } diff --git a/src/utils/versions/getVersionsColors.ts b/src/utils/versions/getVersionsColors.ts index 1e2f760d1..a641ed096 100644 --- a/src/utils/versions/getVersionsColors.ts +++ b/src/utils/versions/getVersionsColors.ts @@ -9,23 +9,94 @@ export const hashCode = (s: string) => { }, 0); }; -// TODO: colors used in charts as well, need to move to constants -// 11 distinct colors from https://mokole.com/palette.html export const COLORS = [ - '#008000', // green - '#4169e1', // royalblue - '#ffd700', // gold - '#ff8c00', // darkorange - '#808000', // olive - '#e9967a', // darksalmon - '#ff1493', // deeppink - '#00bfff', // deepskyblue - '#da70d6', // orchid - '#8b4513', //saddlebrown - '#b22222', // firebrick + [ + 'var(--versions-red-1)', + 'var(--versions-red-2)', + 'var(--versions-red-3)', + 'var(--versions-red-4)', + ], + [ + 'var(--versions-orange-red-1)', + 'var(--versions-orange-red-2)', + 'var(--versions-orange-red-3)', + 'var(--versions-orange-red-4)', + ], + [ + 'var(--versions-orange-1)', + 'var(--versions-orange-2)', + 'var(--versions-orange-3)', + 'var(--versions-orange-4)', + ], + [ + 'var(--versions-yellow-1)', + 'var(--versions-yellow-2)', + 'var(--versions-yellow-3)', + 'var(--versions-yellow-4)', + ], + [ + 'var(--versions-green-1)', + 'var(--versions-green-2)', + 'var(--versions-green-3)', + 'var(--versions-green-4)', + ], + [ + 'var(--versions-teal-1)', + 'var(--versions-teal-2)', + 'var(--versions-teal-3)', + 'var(--versions-teal-4)', + ], + [ + 'var(--versions-cyan-1)', + 'var(--versions-cyan-2)', + 'var(--versions-cyan-3)', + 'var(--versions-cyan-4)', + ], + [ + 'var(--versions-blue-1)', + 'var(--versions-blue-2)', + 'var(--versions-blue-3)', + 'var(--versions-blue-4)', + ], + [ + 'var(--versions-purple-1)', + 'var(--versions-purple-2)', + 'var(--versions-purple-3)', + 'var(--versions-purple-4)', + ], + [ + 'var(--versions-pink-1)', + 'var(--versions-pink-2)', + 'var(--versions-pink-3)', + 'var(--versions-pink-4)', + ], ]; -export const DEFAULT_COLOR = '#3cb371'; // mediumseagreen +export const DEFAULT_COLOR = 'var(--g-color-base-generic-medium)'; + +/** Calculates sub color index */ +export function getMinorVersionColorVariant(minorIndex: number, minorQuantity: number) { + // We have 4 sub colors for each color + // For 4+ minors first 25% will be colored with the first most bright color + // Every next 25% will be colored with corresponding color + // Do not use all colors if there are less than 4 minors + + if (minorQuantity === 1) { + return 0; + } + // Use only 2 colors + if (minorQuantity === 2) { + return Math.floor((2 * minorIndex) / minorQuantity); + } + // Use only 3 colors + if (minorQuantity === 3) { + return Math.floor((3 * minorIndex) / minorQuantity); + } + + // Max minor index is minorQuantity - 1 + // So result values always will be in range from 0 to 3 + return Math.floor((4 * minorIndex) / minorQuantity); +} export const getVersionsMap = (versions: string[], initialMap: VersionsMap = new Map()) => { versions.forEach((version) => { @@ -60,7 +131,8 @@ export const getVersionToColorMap = (versionsMap: VersionsMap) => { if (/^(\w+-)?stable/.test(item.version)) { currentColorIndex = (currentColorIndex + 1) % COLORS.length; - versionToColor.set(item.version, COLORS[currentColorIndex]); + // Use fisrt color for major + versionToColor.set(item.version, COLORS[currentColorIndex][0]); const minors = Array.from(versionsMap.get(item.version) || []) .filter((v) => v !== item.version) @@ -78,14 +150,12 @@ export const getVersionToColorMap = (versionsMap: VersionsMap) => { // so the newer version gets the brighter color .sort((a, b) => b.hash - a.hash) .forEach((minor, minorIndex) => { - const majorColor = COLORS[currentColorIndex]; - const opacityPercent = Math.max( - 100 - minorIndex * (100 / minorQuantity), - 20, + const minorColorVariant = getMinorVersionColorVariant( + minorIndex, + minorQuantity, ); - const hexOpacity = Math.round((opacityPercent * 255) / 100).toString(16); - const versionColor = `${majorColor}${hexOpacity}`; - versionToColor.set(minor.version, versionColor); + const minorColor = COLORS[currentColorIndex][minorColorVariant]; + versionToColor.set(minor.version, minorColor); }); } else { versionToColor.set(item.version, DEFAULT_COLOR);