1+ import { getTheme } from '..' ;
12import type { VersionToColorMap , VersionsMap } from '../../types/versions' ;
23
34import { getMajorVersion , getMinorVersion } from './parseVersion' ;
@@ -9,23 +10,62 @@ export const hashCode = (s: string) => {
910 } , 0 ) ;
1011} ;
1112
12- // TODO: colors used in charts as well, need to move to constants
13- // 11 distinct colors from https://mokole.com/palette.html
14- export const COLORS = [
15- '#008000' , // green
16- '#4169e1' , // royalblue
17- '#ffd700' , // gold
18- '#ff8c00' , // darkorange
19- '#808000' , // olive
20- '#e9967a' , // darksalmon
21- '#ff1493' , // deeppink
22- '#00bfff' , // deepskyblue
23- '#da70d6' , // orchid
24- '#8b4513' , //saddlebrown
25- '#b22222' , // firebrick
13+ const DARK_COLORS = [
14+ [ '#D50C38' , '#FF2051' , '#FB3A64' , '#FF6989' ] ,
15+ [ '#EB3320' , '#FF503E' , '#FF8376' , '#FFA399' ] ,
16+ [ '#F47B10' , '#FF9B43' , '#FFB06A' , '#FFC693' ] ,
17+ [ '#FFEA00' , '#FFEE31' , '#FFF480' , '#FFF8A9' ] ,
18+ [ '#83D400' , '#B1FF33' , '#CBFF78' , '#DDFFA7' ] ,
19+ [ '#27C98B' , '#16FFA6' , '#4CFFBA' , '#9BFFD8' ] ,
20+ [ '#0EDBDE' , '#0CFBFF' , '#63FDFF' , '#B1FEFF' ] ,
21+ [ '#2059FF' , '#4070FF' , '#658BFF' , '#A1B9FF' ] ,
22+ [ '#AB07E3' , '#C92CFF' , '#DD78FF' , '#E79FFF' ] ,
23+ [ '#E71498' , '#FF34B3' , '#FF75CB' , '#FFB0E1' ] ,
2624] ;
2725
28- export const DEFAULT_COLOR = '#3cb371' ; // mediumseagreen
26+ const LIGHT_COLORS = [
27+ [ '#F4315B' , '#FF426B' , '#FF7391' , '#FF8BA4' ] ,
28+ [ '#FF6050' , '#FF7A6D' , '#FFAFA6' , '#FFBCB5' ] ,
29+ [ '#FF9233' , '#FFAD65' , '#FFC593' , '#FFD3AC' ] ,
30+ [ '#FFEA00' , '#FFEE31' , '#FFF480' , '#FFF8A9' ] ,
31+ [ '#A1EE26' , '#B1FF33' , '#CBFF78' , '#DDFFA7' ] ,
32+ [ '#31EBA4' , '#16FFA6' , '#4CFFBA' , '#9BFFD8' ] ,
33+ [ '#2EE4E8' , '#0CFBFF' , '#63FDFF' , '#B1FEFF' ] ,
34+ [ '#386BFF' , '#4070FF' , '#658BFF' , '#A1B9FF' ] ,
35+ [ '#C73AF7' , '#C92CFF' , '#DD78FF' , '#E79FFF' ] ,
36+ [ '#FF49BB' , '#FF34B3' , '#FF75CB' , '#FFB0E1' ] ,
37+ ] ;
38+
39+ export function getColors ( ) {
40+ return getTheme ( ) === 'dark' ? DARK_COLORS : LIGHT_COLORS ;
41+ }
42+
43+ /** Calculates sub color index */
44+ export function getMinorVersionColorVariant ( minorIndex : number , minorQuantity : number ) {
45+ // We have 4 sub colors for each color
46+ // For 4+ minors first 25% will be colored with the first most bright color
47+ // Every next 25% will be colored with corresponding color
48+ // Do not use all colors if there are less than 4 minors
49+
50+ if ( minorQuantity === 1 ) {
51+ return 0 ;
52+ }
53+ // Use only 2 colors
54+ if ( minorQuantity === 2 ) {
55+ return Math . floor ( ( 2 * minorIndex ) / minorQuantity ) ;
56+ }
57+ // Use only 3 colors
58+ if ( minorQuantity === 3 ) {
59+ return Math . floor ( ( 3 * minorIndex ) / minorQuantity ) ;
60+ }
61+
62+ // Max minor index is minorQuantity - 1
63+ // So result values always will be in range from 0 to 3
64+ return Math . floor ( ( 4 * minorIndex ) / minorQuantity ) ;
65+ }
66+
67+ // TODO: replace with color suggested by designer
68+ export const DEFAULT_COLOR = 'saddlebrown' ;
2969
3070export const getVersionsMap = ( versions : string [ ] , initialMap : VersionsMap = new Map ( ) ) => {
3171 versions . forEach ( ( version ) => {
@@ -47,20 +87,23 @@ export const getVersionToColorMap = (versionsMap: VersionsMap) => {
4787 } ;
4888 } ) ;
4989
90+ const colors = getColors ( ) ;
91+
5092 const versionToColor : VersionToColorMap = new Map ( ) ;
5193 // not every version is colored, therefore iteration index can't be used consistently
5294 // init with the colors length to put increment right after condition for better readability
53- let currentColorIndex = COLORS . length - 1 ;
95+ let currentColorIndex = colors . length - 1 ;
5496
5597 clustersVersions
5698 // ascending by version name, just for consistency
5799 // sorting only impacts color choose for a version
58100 . sort ( ( a , b ) => a . hash - b . hash )
59101 . forEach ( ( item ) => {
60102 if ( / ^ ( \w + - ) ? s t a b l e / . test ( item . version ) ) {
61- currentColorIndex = ( currentColorIndex + 1 ) % COLORS . length ;
103+ currentColorIndex = ( currentColorIndex + 1 ) % colors . length ;
62104
63- versionToColor . set ( item . version , COLORS [ currentColorIndex ] ) ;
105+ // Use fisrt color for major
106+ versionToColor . set ( item . version , colors [ currentColorIndex ] [ 0 ] ) ;
64107
65108 const minors = Array . from ( versionsMap . get ( item . version ) || [ ] )
66109 . filter ( ( v ) => v !== item . version )
@@ -78,14 +121,12 @@ export const getVersionToColorMap = (versionsMap: VersionsMap) => {
78121 // so the newer version gets the brighter color
79122 . sort ( ( a , b ) => b . hash - a . hash )
80123 . forEach ( ( minor , minorIndex ) => {
81- const majorColor = COLORS [ currentColorIndex ] ;
82- const opacityPercent = Math . max (
83- 100 - minorIndex * ( 100 / minorQuantity ) ,
84- 20 ,
124+ const minorColorVariant = getMinorVersionColorVariant (
125+ minorIndex ,
126+ minorQuantity ,
85127 ) ;
86- const hexOpacity = Math . round ( ( opacityPercent * 255 ) / 100 ) . toString ( 16 ) ;
87- const versionColor = `${ majorColor } ${ hexOpacity } ` ;
88- versionToColor . set ( minor . version , versionColor ) ;
128+ const minorColor = colors [ currentColorIndex ] [ minorColorVariant ] ;
129+ versionToColor . set ( minor . version , minorColor ) ;
89130 } ) ;
90131 } else {
91132 versionToColor . set ( item . version , DEFAULT_COLOR ) ;
0 commit comments