From 97315344111d43356bbc581b159ff3a2fb6da831 Mon Sep 17 00:00:00 2001 From: Alec Thomas Date: Tue, 10 Oct 2023 11:44:27 +1100 Subject: [PATCH] feat: deterministically colour deployment names in timeline (#471) Currently uses a curated fixed table, which we can adjust for dark/light modes. Possible future enhancements: - Replace colours with on-the-fly generation if we can figure out a way to make the colours not ugly. - Separate colours for module name and deployment, so it's easier to map module name. Before: Screenshot 2023-10-10 at 11 40 54 am After: Screenshot 2023-10-10 at 11 40 15 am --- console/client/package-lock.json | 6 +++ console/client/package.json | 3 +- .../src/features/timeline/DeploymentLabel.tsx | 47 +++++++++++++++++++ .../client/src/features/timeline/Timeline.tsx | 3 +- 4 files changed, 57 insertions(+), 2 deletions(-) create mode 100644 console/client/src/features/timeline/DeploymentLabel.tsx diff --git a/console/client/package-lock.json b/console/client/package-lock.json index 01ac52d42c..fa2d7a76c1 100644 --- a/console/client/package-lock.json +++ b/console/client/package-lock.json @@ -19,6 +19,7 @@ "@tailwindcss/forms": "^0.5.6", "@vitejs/plugin-react": "^4.0.4", "@viz-js/viz": "3.2.0", + "fnv1a": "^1.1.1", "highlight.js": "^11.8.0", "json-schema": "0.4.0", "json-schema-faker": "0.5.0-rcv.46", @@ -5311,6 +5312,11 @@ "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==", "dev": true }, + "node_modules/fnv1a": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/fnv1a/-/fnv1a-1.1.1.tgz", + "integrity": "sha512-S2HviLR9UyNbt8R+vU6YeQtL8RliPwez9DQEVba5MAvN3Od+RSgKUSL2+qveOMt3owIeBukKoRu2enoOck5uag==" + }, "node_modules/follow-redirects": { "version": "1.15.2", "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", diff --git a/console/client/package.json b/console/client/package.json index c04537a666..e0297fa4ec 100644 --- a/console/client/package.json +++ b/console/client/package.json @@ -37,6 +37,7 @@ "@tailwindcss/forms": "^0.5.6", "@vitejs/plugin-react": "^4.0.4", "@viz-js/viz": "3.2.0", + "fnv1a": "^1.1.1", "highlight.js": "^11.8.0", "json-schema": "0.4.0", "json-schema-faker": "0.5.0-rcv.46", @@ -52,11 +53,11 @@ "@bufbuild/protoc-gen-connect-es": "0.12.0", "@bufbuild/protoc-gen-es": "1.3.0", "@jest/globals": "29.6.2", - "@types/p5": "1.7.0", "@swc/core": "1.3.77", "@swc/jest": "0.2.29", "@testing-library/jest-dom": "6.0.0", "@testing-library/react": "14.0.0", + "@types/p5": "1.7.0", "@types/react": "18.2.20", "@types/react-dom": "18.2.7", "@typescript-eslint/eslint-plugin": "6.4.0", diff --git a/console/client/src/features/timeline/DeploymentLabel.tsx b/console/client/src/features/timeline/DeploymentLabel.tsx new file mode 100644 index 0000000000..e0de9095e2 --- /dev/null +++ b/console/client/src/features/timeline/DeploymentLabel.tsx @@ -0,0 +1,47 @@ +import hash from 'fnv1a' + +// prettier-ignore +const colourTable = [ + '008000', '808000', '000080', '800080', '008080', 'c0c0c0', '00ff00', + 'ffff00', '0000ff', 'ff00ff', '00ffff', 'ffffff', '000000', '00005f', + '000087', '0000af', '0000d7', '0000ff', '005f00', '005f5f', '005f87', + '005faf', '005fd7', '005fff', '008700', '00875f', '008787', '0087af', + '0087d7', '0087ff', '00af00', '00af5f', '00af87', '00afaf', '00afd7', + '00afff', '00d700', '00d75f', '00d787', '00d7af', '00d7d7', '00d7ff', + '00ff00', '00ff5f', '00ff87', '00ffaf', '00ffd7', '00ffff', '5f0000', + '5f005f', '5f0087', '5f00af', '5f00d7', '5f00ff', '5f5f00', '5f5f5f', + '5f5f87', '5f5faf', '5f5fd7', '5f5fff', '5f8700', '5f875f', '5f8787', + '5f87af', '5f87d7', '5f87ff', '5faf00', '5faf5f', '5faf87', '5fafaf', + '5fafd7', '5fafff', '5fd700', '5fd75f', '5fd787', '5fd7af', '5fd7d7', + '5fd7ff', '5fff00', '5fff5f', '5fff87', '5fffaf', '5fffd7', '5fffff', + '870000', '87005f', '870087', '8700af', '8700d7', '8700ff', '875f00', + '875f5f', '875f87', '875faf', '875fd7', '875fff', '878700', '87875f', + '878787', '8787af', '8787d7', '8787ff', '87af00', '87af5f', '87af87', + '87afaf', '87afd7', '87afff', '87d700', '87d75f', '87d787', '87d7af', + '87d7d7', '87d7ff', '87ff00', '87ff5f', '87ff87', '87ffaf', '87ffd7', + '87ffff', 'af0000', 'af005f', 'af0087', 'af00af', 'af00d7', 'af00ff', + 'af5f00', 'af5f5f', 'af5f87', 'af5faf', 'af5fd7', 'af5fff', 'af8700', + 'af875f', 'af8787', 'af87af', 'af87d7', 'af87ff', 'afaf00', 'afaf5f', + 'afaf87', 'afafaf', 'afafd7', 'afafff', 'afd700', 'afd75f', 'afd787', + 'afd7af', 'afd7d7', 'afd7ff', 'afff00', 'afff5f', 'afff87', 'afffaf', + 'afffd7', 'afffff', 'd70000', 'd7005f', 'd70087', 'd700af', 'd700d7', + 'd700ff', 'd75f00', 'd75f5f', 'd75f87', 'd75faf', 'd75fd7', 'd75fff', + 'd78700', 'd7875f', 'd78787', 'd787af', 'd787d7', 'd787ff', 'd7af00', + 'd7af5f', 'd7af87', 'd7afaf', 'd7afd7', 'd7afff', 'd7d700', 'd7d75f', + 'd7d787', 'd7d7af', 'd7d7d7', 'd7d7ff', 'd7ff00', 'd7ff5f', 'd7ff87', + 'd7ffaf', 'd7ffd7', 'd7ffff', 'ff0000', 'ff005f', 'ff0087', 'ff00af', + 'ff00d7', 'ff00ff', 'ff5f00', 'ff5f5f', 'ff5f87', 'ff5faf', 'ff5fd7', + 'ff5fff', 'ff8700', 'ff875f', 'ff8787', 'ff87af', 'ff87d7', 'ff87ff', + 'ffaf00', 'ffaf5f', 'ffaf87', 'ffafaf', 'ffafd7', 'ffafff', 'ffd700', + 'ffd75f', 'ffd787', 'ffd7af', 'ffd7d7', 'ffd7ff', 'ffff00', 'ffff5f', + 'ffff87', 'ffffaf', 'ffffd7', 'ffffff', '080808', '121212', '1c1c1c', + '262626', '303030', '3a3a3a', '444444', '4e4e4e', '585858', '606060', + '666666', '767676', '808080', '8a8a8a', '949494', '9e9e9e', 'a8a8a8', + 'b2b2b2', 'bcbcbc', 'c6c6c6', 'd0d0d0', 'dadada', 'e4e4e4', 'eeeeee', +] + +/** Create a deterministically coloured label for a deployment name. */ +export const DeploymentLabel = ({ name }: { name: string }) => { + const colour = '#' + colourTable[hash(name) % colourTable.length] + return {name} +} diff --git a/console/client/src/features/timeline/Timeline.tsx b/console/client/src/features/timeline/Timeline.tsx index df41ad1519..c74fc7aad0 100644 --- a/console/client/src/features/timeline/Timeline.tsx +++ b/console/client/src/features/timeline/Timeline.tsx @@ -16,6 +16,7 @@ import { TimelineDeploymentCreatedDetails } from './details/TimelineDeploymentCr import { TimelineDeploymentUpdatedDetails } from './details/TimelineDeploymentUpdatedDetails.tsx' import { TimelineLogDetails } from './details/TimelineLogDetails.tsx' import { TimeSettings } from './filters/TimelineTimeControls.tsx' +import { DeploymentLabel } from './DeploymentLabel.tsx' interface Props { timeSettings: TimeSettings @@ -166,7 +167,7 @@ export const Timeline = ({ timeSettings, filters }: Props) => { title={deploymentName(entry)} className='p-1 pr-2 w-40 items-center flex-none truncate text-indigo-500 dark:text-indigo-300' > - {deploymentName(entry)} + {(() => {