├── .gitignore ├── .prettierrc.json ├── src ├── index.mjs ├── use-colormap.mjs ├── use-themed-colormap.mjs ├── colormaps.mjs └── make-colormap.mjs ├── scripts └── export.mjs ├── .github └── workflows │ └── main.yml ├── .pre-commit-config.yaml ├── LICENSE ├── package.json └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .next 3 | node_modules 4 | dst 5 | -------------------------------------------------------------------------------- /.prettierrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "tabWidth": 2, 3 | "semi": false, 4 | "singleQuote": true, 5 | "printWidth": 80, 6 | "quoteProps": "as-needed", 7 | "jsxSingleQuote": true 8 | } 9 | -------------------------------------------------------------------------------- /src/index.mjs: -------------------------------------------------------------------------------- 1 | export { default as useColormap } from './use-colormap' 2 | export { default as useThemedColormap } from './use-themed-colormap' 3 | export { default as makeColormap } from './make-colormap' 4 | export { default as colormaps } from './colormaps' 5 | -------------------------------------------------------------------------------- /src/use-colormap.mjs: -------------------------------------------------------------------------------- 1 | import { useMemo } from 'react' 2 | import makeColormap from './make-colormap' 3 | 4 | const useColormap = (name, options) => { 5 | const colormap = useMemo(() => { 6 | return makeColormap(name, options) 7 | }, [name, options?.count, options?.format, options?.mode]) 8 | 9 | return colormap 10 | } 11 | 12 | export default useColormap 13 | -------------------------------------------------------------------------------- /src/use-themed-colormap.mjs: -------------------------------------------------------------------------------- 1 | import { useColorMode } from 'theme-ui' 2 | import useColormap from './use-colormap' 3 | 4 | const useThemedColormap = (name, options) => { 5 | const [mode] = useColorMode() 6 | 7 | let colorMode = mode 8 | 9 | if (!['light', 'dark'].includes(mode)) { 10 | console.warn( 11 | `Unexpected \`theme-ui-color-mode\`, ${mode}. Using \`dark\` as fallback.` 12 | ) 13 | colorMode = 'dark' 14 | } 15 | return useColormap(name, { ...options, mode: colorMode }) 16 | } 17 | 18 | export default useThemedColormap 19 | -------------------------------------------------------------------------------- /scripts/export.mjs: -------------------------------------------------------------------------------- 1 | import fs from 'fs' 2 | import colormaps from '../src/colormaps.mjs' 3 | import makeColormap from '../src/make-colormap.mjs' 4 | 5 | const out = {} 6 | 7 | colormaps.forEach((d) => { 8 | out[d.name + '-light'] = makeColormap(d.name, 'light', 256, 'rgb').map((d) => 9 | d.map((d) => parseFloat((d / 255).toFixed(6))) 10 | ) 11 | out[d.name + '-dark'] = makeColormap(d.name, 'dark', 256, 'rgb').map((d) => 12 | d.map((d) => parseFloat((d / 255).toFixed(6))) 13 | ) 14 | }) 15 | 16 | fs.writeFileSync('export/colormaps.json', JSON.stringify(out)) 17 | -------------------------------------------------------------------------------- /.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: [push, pull_request] 4 | 5 | jobs: 6 | build: 7 | runs-on: ubuntu-latest 8 | 9 | strategy: 10 | matrix: 11 | node-version: [14.x, 16.x] 12 | 13 | steps: 14 | - uses: actions/checkout@v2 15 | - name: Use Node.js ${{ matrix.node-version }} 16 | uses: actions/setup-node@v2.4.0 17 | with: 18 | node-version: ${{ matrix.node-version }} 19 | - run: npm install 20 | - run: npm run build --if-present 21 | 22 | lint: 23 | runs-on: ubuntu-latest 24 | steps: 25 | - uses: actions/checkout@v1 26 | - uses: actions/setup-python@v2.2.2 27 | - uses: pre-commit/action@v2.0.3 28 | -------------------------------------------------------------------------------- /.pre-commit-config.yaml: -------------------------------------------------------------------------------- 1 | repos: 2 | - repo: https://github.com/pre-commit/mirrors-prettier 3 | rev: 'v2.5.1' 4 | hooks: 5 | - id: prettier 6 | language_version: system 7 | files: "\\.(\ 8 | css|less|scss\ 9 | |graphql|gql\ 10 | |html\ 11 | |js|jsx|mjs\ 12 | |json\ 13 | |ts|tsx\ 14 | |vue\ 15 | |yaml|yml\ 16 | )$" 17 | - repo: https://github.com/pre-commit/mirrors-prettier 18 | rev: 'v2.5.1' 19 | hooks: 20 | - id: prettier 21 | language_version: system 22 | name: prettier-markdown 23 | entry: prettier --write --parser mdx 24 | files: "\\.(\ 25 | |md|markdown|mdown|mkdn\ 26 | |mdx\ 27 | )$" 28 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 carbonplan 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@carbonplan/colormaps", 3 | "version": "4.0.0", 4 | "description": "color scales for data visualization", 5 | "main": "dst/index.js", 6 | "module": "dst/index.esm.js", 7 | "scripts": { 8 | "build": "rimraf dst && microbundle src/index.mjs -o dst/index.js --no-compress --jsx React.createElement -f modern,es,cjs --jsxFragment React.Fragment && node scripts/export.mjs", 9 | "watch": "microbundle watch src/index.mjs -o dst/index.js --no-compress --jsx React.createElement -f modern,es,cjs --jsxFragment React.Fragment", 10 | "format": "prettier --write 'src/**/*.js'", 11 | "export": "node scripts/export.mjs" 12 | }, 13 | "repository": { 14 | "type": "git", 15 | "url": "git+https://github.com/carbonplan/colormaps.git" 16 | }, 17 | "keywords": [ 18 | "carbonplan", 19 | "color", 20 | "colormap", 21 | "scale" 22 | ], 23 | "author": "freeman-lab", 24 | "license": "MIT", 25 | "bugs": { 26 | "url": "https://github.com/carbonplan/colormaps/issues" 27 | }, 28 | "files": [ 29 | "dst" 30 | ], 31 | "homepage": "https://github.com/carbonplan/colormaps#readme", 32 | "dependencies": { 33 | "chroma-js": "~2.2.0", 34 | "theme-ui": ">=0.15.0" 35 | }, 36 | "peerDependencies": { 37 | "react": ">=18", 38 | "react-dom": ">=18" 39 | }, 40 | "devDependencies": { 41 | "microbundle": "^0.13.0", 42 | "prettier": "^2.2.1", 43 | "rimraf": "3.0.2" 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/colormaps.mjs: -------------------------------------------------------------------------------- 1 | const colormaps = [ 2 | { name: 'reds', type: 'sequentialSingleHue' }, 3 | { name: 'oranges', type: 'sequentialSingleHue' }, 4 | { name: 'yellows', type: 'sequentialSingleHue' }, 5 | { name: 'greens', type: 'sequentialSingleHue' }, 6 | { name: 'teals', type: 'sequentialSingleHue' }, 7 | { name: 'blues', type: 'sequentialSingleHue' }, 8 | { name: 'purples', type: 'sequentialSingleHue' }, 9 | { name: 'pinks', type: 'sequentialSingleHue' }, 10 | { name: 'greys', type: 'sequentialSingleHue' }, 11 | { name: 'fire', type: 'sequentialMultiHue' }, 12 | { name: 'earth', type: 'sequentialMultiHue' }, 13 | { name: 'water', type: 'sequentialMultiHue' }, 14 | { name: 'heart', type: 'sequentialMultiHue' }, 15 | { name: 'wind', type: 'sequentialMultiHue' }, 16 | { name: 'warm', type: 'sequentialMultiHue' }, 17 | { name: 'cool', type: 'sequentialMultiHue' }, 18 | { name: 'browngreen', type: 'sequentialMultiHue' }, 19 | { name: 'blueprecip', type: 'sequentialMultiHue' }, 20 | { name: 'difredblue', type: 'diverging' }, 21 | { name: 'difbluered', type: 'diverging' }, 22 | { name: 'difbrowngreen', type: 'diverging' }, 23 | { name: 'BuYlRd', type: 'diverging' }, 24 | { name: 'pinkgreen', type: 'diverging' }, 25 | { name: 'redteal', type: 'diverging' }, 26 | { name: 'orangeblue', type: 'diverging' }, 27 | { name: 'yellowpurple', type: 'diverging' }, 28 | { name: 'redgrey', type: 'diverging' }, 29 | { name: 'orangegrey', type: 'diverging' }, 30 | { name: 'yellowgrey', type: 'diverging' }, 31 | { name: 'greengrey', type: 'diverging' }, 32 | { name: 'tealgrey', type: 'diverging' }, 33 | { name: 'bluegrey', type: 'diverging' }, 34 | { name: 'purplegrey', type: 'diverging' }, 35 | { name: 'pinkgrey', type: 'diverging' }, 36 | { name: 'rainbow', type: 'cyclical' }, 37 | { name: 'sinebow', type: 'cyclical' }, 38 | ] 39 | 40 | export default colormaps 41 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | 3 | 4 | 5 | CarbonPlan monogram. 6 | 7 | 8 |

9 | 10 | # carbonplan / colormaps 11 | 12 | **color scales for data visualization** 13 | 14 | [![CI](https://github.com/carbonplan/colormaps/actions/workflows/main.yml/badge.svg)](https://github.com/carbonplan/colormaps/actions/workflows/main.yml) 15 | ![NPM Version](https://img.shields.io/npm/v/@carbonplan/colormaps) 16 | [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT) 17 | 18 | This simple package contains a variety of colormaps for our data visualization needs at CarbonPlan. A primary use case is when rendering maps, but other uses will arise as well. Colormaps are designed to be both aesthetically pleasing and perceptually balanced, and all should work in both light and dark mode. 19 | 20 | See them demoed at [`carbonplan.org/design/colormaps`](https://carbonplan.org/design/colormaps). 21 | 22 | ## installation 23 | 24 | Add to your package using `npm` 25 | 26 | ``` 27 | npm i @carbonplan/colormaps 28 | ``` 29 | 30 | ## usage 31 | 32 | The primary entry point is the `makeColormap` function, which just requires a name. 33 | 34 | ```js 35 | import { makeColormap } from '@carbonplan/colormaps' 36 | 37 | const colormap = makeColormap('warm') 38 | ``` 39 | 40 | This returns an array of colors. You can pass options including the `count` of colors, the mode (`light` or `dark`), and the format (`rgb` or `hex`). For example, the following will return `7` equispaced values from the `warm` colormap in `hex` format and `light` mode. 41 | 42 | ``` 43 | const colormap = makeColormap('warm', {count: 7, mode: 'light', format: 'hex'}) 44 | ``` 45 | 46 | In a React context, you can also use the provided hook. 47 | 48 | ```js 49 | import { useColormap } from '@carbonplan/colormaps' 50 | 51 | const colormap = useColormap('warm') 52 | ``` 53 | 54 | This hook has as dependencies the name as well as any options. 55 | 56 | Finally, for use with `theme-ui`, we offer a hook that depends on the current `theme-ui` mode, so that changing the `theme-ui` mode will change the colormap. 57 | 58 | ```js 59 | import { useThemedColormap } from '@carbonplan/colormaps' 60 | 61 | const colormap = useThemedColormap('warm') 62 | ``` 63 | 64 | You can also retrieve a list of available colormaps with both names and types. Useful for building menu selections and similar listings. 65 | 66 | ```js 67 | import { colormaps } from '@carbonplan/colormaps' 68 | 69 | console.log(colormaps.filter((d) => d.type === 'diverging').map((d) => d.name)) 70 | ``` 71 | 72 | ## note 73 | 74 | We are currently pinning to version 2.2 of `chroma-js` due to a [change](https://github.com/gka/chroma.js/commit/a0245db2da9b98b68056a212d1c0afdeb3250e0e) in the bezier implementation that changed our intended colormaps in an undesirable way. 75 | 76 | ## license 77 | 78 | All the code in this repository is [MIT](https://choosealicense.com/licenses/mit/)-licensed, but we request that you please provide attribution if reusing any of our digital content (graphics, logo, articles, etc.). 79 | 80 | ## about us 81 | 82 | CarbonPlan is a nonprofit organization that uses data and science for climate action. We aim to improve the transparency and scientific integrity of climate solutions with open data and tools. Find out more at [carbonplan.org](https://carbonplan.org/) or get in touch by [opening an issue](https://github.com/carbonplan/compliance-users/issues/new) or [sending us an email](mailto:hello@carbonplan.org). 83 | -------------------------------------------------------------------------------- /src/make-colormap.mjs: -------------------------------------------------------------------------------- 1 | import chroma from 'chroma-js' 2 | import colormaps from './colormaps.mjs' 3 | 4 | const makeColormap = (name, options) => { 5 | const { count = 255, format = 'rgb', mode = 'dark' } = options 6 | 7 | if (!colormaps.map((d) => d.name).includes(name)) { 8 | throw Error(`requested colormap '${name}' is not defined`) 9 | } 10 | 11 | if (!['light', 'dark'].includes(mode)) { 12 | throw Error(`invalid mode '${mode}'`) 13 | } 14 | 15 | if (!Number.isInteger(count) || !(count > 0)) { 16 | throw Error(`invalid count '${count}'`) 17 | } 18 | 19 | const red = '#f57273' 20 | const orange = '#e39046' 21 | const yellow = '#c2b04c' 22 | const green = '#80ba69' 23 | const forest = '#41752d' 24 | const teal = '#64b9c4' 25 | const blue = '#85a2f7' 26 | const purple = '#c088de' 27 | const pink = '#db81ae' 28 | const grey = '#9aa3b3' 29 | const brown = '#964B00' 30 | const difred = '#FF0000' 31 | const difblue = '#0000FF' 32 | const difbrown = '#a6611a' 33 | const difgreen = '#018571' 34 | const white = '#FFFFFF' 35 | 36 | let start, middle, end 37 | 38 | if (mode === 'dark') { 39 | start = chroma('#1b1e23').brighten(0) 40 | middle = chroma('#808080').brighten(0.6) 41 | end = chroma('#ebebec') 42 | } 43 | 44 | if (mode === 'light') { 45 | start = chroma('#FFFFFF').darken(0) 46 | middle = chroma('#808080').brighten(0.75) 47 | end = chroma('#1b1e23') 48 | } 49 | 50 | let ramp 51 | let bezier = true 52 | let correctLightness = false 53 | 54 | switch (name) { 55 | case 'reds': 56 | correctLightness = true 57 | ramp = [start, red] 58 | break 59 | case 'oranges': 60 | correctLightness = true 61 | ramp = [start, orange] 62 | break 63 | case 'yellows': 64 | correctLightness = true 65 | ramp = [start, yellow] 66 | break 67 | case 'greens': 68 | correctLightness = true 69 | ramp = [start, green] 70 | break 71 | case 'teals': 72 | correctLightness = true 73 | ramp = [start, teal] 74 | break 75 | case 'blues': 76 | correctLightness = true 77 | ramp = [start, blue] 78 | break 79 | case 'purples': 80 | correctLightness = true 81 | ramp = [start, purple] 82 | break 83 | case 'pinks': 84 | correctLightness = true 85 | ramp = [start, pink] 86 | break 87 | case 'greys': 88 | correctLightness = true 89 | ramp = [start, middle] 90 | break 91 | case 'fire': 92 | correctLightness = true 93 | if (mode === 'dark') { 94 | ramp = [ 95 | start, 96 | chroma(red).darken(1), 97 | chroma.mix(red, orange, 0.45, 'lab').darken(0.5), 98 | chroma(orange), 99 | chroma(orange).brighten(0.5), 100 | ] 101 | } 102 | if (mode === 'light') { 103 | ramp = [ 104 | start, 105 | chroma(orange).brighten(1), 106 | chroma.mix(orange, red, 0.25, 'lab').brighten(0.5), 107 | chroma(red), 108 | chroma(red).darken(0.5), 109 | ] 110 | } 111 | break 112 | case 'earth': 113 | correctLightness = true 114 | if (mode === 'dark') { 115 | ramp = [ 116 | start, 117 | chroma(green).darken(1), 118 | chroma.mix(green, yellow, 0.45, 'lab').darken(0.5), 119 | chroma(yellow), 120 | chroma(yellow).brighten(0.5), 121 | ] 122 | } 123 | if (mode === 'light') { 124 | ramp = [ 125 | start, 126 | chroma(yellow).brighten(1), 127 | chroma.mix(yellow, green, 0.25, 'lab').brighten(0.5), 128 | chroma(green), 129 | chroma(green).darken(0.5), 130 | ] 131 | } 132 | break 133 | case 'water': 134 | correctLightness = true 135 | if (mode === 'dark') { 136 | ramp = [ 137 | start, 138 | chroma(blue).darken(1), 139 | chroma.mix(blue, teal, 0.45, 'lab').darken(0.5), 140 | chroma(teal), 141 | chroma(teal).brighten(0.5), 142 | ] 143 | } 144 | if (mode === 'light') { 145 | ramp = [ 146 | start, 147 | chroma(teal).brighten(1), 148 | chroma.mix(teal, blue, 0.25, 'lab').brighten(0.5), 149 | chroma(blue), 150 | chroma(blue).darken(0.5), 151 | ] 152 | } 153 | break 154 | case 'heart': 155 | correctLightness = true 156 | if (mode === 'dark') { 157 | ramp = [ 158 | start, 159 | chroma(purple).darken(1), 160 | chroma.mix(purple, pink, 0.45, 'lab').darken(0.5), 161 | chroma(pink), 162 | chroma(pink).brighten(0.5), 163 | ] 164 | } 165 | if (mode === 'light') { 166 | ramp = [ 167 | start, 168 | chroma(pink).brighten(1), 169 | chroma.mix(pink, purple, 0.25, 'lab').brighten(0.5), 170 | chroma(purple), 171 | chroma(purple).darken(0.5), 172 | ] 173 | } 174 | break 175 | case 'wind': 176 | correctLightness = true 177 | if (mode === 'dark') { 178 | ramp = [ 179 | start, 180 | chroma(grey).darken(1), 181 | chroma.mix(grey, grey, 0.45, 'lab').darken(0.5), 182 | chroma(grey), 183 | chroma(grey).brighten(0.5), 184 | ] 185 | } 186 | if (mode === 'light') { 187 | ramp = [ 188 | start, 189 | chroma(grey).brighten(1), 190 | chroma.mix(grey, grey, 0.25, 'lab').brighten(0.5), 191 | chroma(grey), 192 | chroma(grey).darken(0.5), 193 | ] 194 | } 195 | break 196 | case 'warm': 197 | correctLightness = true 198 | if (mode === 'dark') { 199 | const preRamp = [ 200 | chroma(purple).darken(1.5), 201 | chroma(pink).darken(1), 202 | chroma(red).darken(0.5), 203 | chroma(orange), 204 | chroma(yellow).brighten(0.5), 205 | ] 206 | const pre = chroma.bezier(preRamp).scale().colors(4) 207 | ramp = [start, pre[0], pre[1], pre[2], pre[3]] 208 | } 209 | if (mode === 'light') { 210 | const preRamp = [ 211 | chroma(yellow).brighten(1.5), 212 | chroma(orange).brighten(1), 213 | chroma(red).brighten(0.5), 214 | chroma(pink), 215 | chroma(purple).darken(0.5), 216 | ] 217 | const pre = chroma.bezier(preRamp).scale().colors(4) 218 | ramp = [start, pre[0], pre[1], pre[2], pre[3]] 219 | } 220 | break 221 | case 'cool': 222 | correctLightness = true 223 | if (mode === 'dark') { 224 | const preRamp = [ 225 | chroma(purple).darken(1.5), 226 | chroma(blue).darken(1), 227 | chroma(teal).darken(0.5), 228 | chroma(green), 229 | chroma(yellow).brighten(0.5), 230 | ] 231 | const pre = chroma.bezier(preRamp).scale().colors(4) 232 | ramp = [start, pre[0], pre[1], pre[2], pre[3]] 233 | } 234 | if (mode === 'light') { 235 | const preRamp = [ 236 | chroma(yellow).brighten(1.5), 237 | chroma(green).brighten(1), 238 | chroma(teal).brighten(0.5), 239 | chroma(blue), 240 | chroma(purple).darken(0.5), 241 | ] 242 | const pre = chroma.bezier(preRamp).scale().colors(4) 243 | ramp = [start, pre[0], pre[1], pre[2], pre[3]] 244 | } 245 | break 246 | case 'pinkgreen': 247 | bezier = false 248 | ramp = [pink, start, green] 249 | break 250 | case 'redteal': 251 | bezier = false 252 | ramp = [red, start, teal] 253 | break 254 | case 'difbluered': 255 | bezier = false 256 | ramp = [...chroma.brewer['RdBu']].reverse() 257 | break 258 | case 'difredblue': 259 | bezier = false 260 | ramp = chroma.brewer['RdBu'] 261 | break 262 | case 'difbrowngreen': 263 | bezier = false 264 | ramp = chroma.brewer['BrBG'] 265 | break 266 | case 'BuYlRd': 267 | bezier = false 268 | ramp = [...chroma.brewer['RdYlBu']].reverse() 269 | break 270 | case 'blueprecip': 271 | bezier = false 272 | // console.log("THIS SHOULD GET PRINTED MAKE COLORMAP"); 273 | // ramp = [green, start, middle] 274 | // ramp = [green, white, blue]; 275 | // ramp = [orange, start, blue]; 276 | // ramp = chroma.brewer['PuBuGn'] 277 | ramp = [white, '#b3cde0', '#6497b1', '#005b96', '#03396c', '#011f4b'] 278 | // WhiteBlueGreenYellowRed 279 | // ramp = [brown, blue, green, forest]; 280 | // shades of teal 281 | // ramp = [white, '#D1EBEB','#A8D7D7','#83C3C4','#63AFB0','#469B9D', 282 | // '#2E8889','#1B7476','#0B6162','#004D4F'] 283 | // shade of green 284 | // ramp = ['#F5F5DC', '#CBE3CD', '#A7CEAD', '#749079', '#4D6A67'] 285 | // shade of green 286 | 287 | // this is a good one 288 | // ramp = [white, blue, green, yellow, red]; 289 | break 290 | case 'browngreen': 291 | bezier = false 292 | // ramp = chroma.brewer['Viridis'].reverse() 293 | // ramp = ['#543005','#00441b'] // brown, green 294 | // ramp = chroma.brewer['YlGnBu'] 295 | ramp = chroma.brewer['BrBG'] 296 | break 297 | case 'orangeblue': 298 | bezier = false 299 | ramp = [orange, start, blue] 300 | break 301 | case 'yellowpurple': 302 | bezier = false 303 | ramp = [yellow, start, purple] 304 | break 305 | case 'redgrey': 306 | bezier = false 307 | ramp = [red, start, middle] 308 | break 309 | case 'orangegrey': 310 | bezier = false 311 | ramp = [orange, start, middle] 312 | break 313 | case 'yellowgrey': 314 | bezier = false 315 | ramp = [yellow, start, middle] 316 | break 317 | case 'greengrey': 318 | bezier = false 319 | ramp = [green, start, middle] 320 | break 321 | case 'tealgrey': 322 | bezier = false 323 | ramp = [teal, start, middle] 324 | break 325 | case 'bluegrey': 326 | bezier = false 327 | ramp = [blue, start, middle] 328 | break 329 | case 'purplegrey': 330 | bezier = false 331 | ramp = [purple, start, middle] 332 | break 333 | case 'pinkgrey': 334 | bezier = false 335 | ramp = [pink, start, middle] 336 | break 337 | case 'rainbow': 338 | bezier = false 339 | if (mode === 'dark') { 340 | ramp = [ 341 | chroma(purple), 342 | chroma(blue), 343 | chroma(teal), 344 | chroma(green), 345 | chroma(yellow), 346 | chroma(orange), 347 | chroma(red), 348 | chroma(pink), 349 | ] 350 | } 351 | if (mode === 'light') { 352 | ramp = [ 353 | chroma(purple), 354 | chroma(blue), 355 | chroma(teal), 356 | chroma(green), 357 | chroma(yellow), 358 | chroma(orange), 359 | chroma(red), 360 | chroma(pink), 361 | ] 362 | } 363 | break 364 | case 'sinebow': 365 | bezier = false 366 | if (mode === 'dark') { 367 | ramp = [ 368 | chroma(red), 369 | chroma(orange), 370 | chroma(yellow), 371 | chroma(green), 372 | chroma(teal), 373 | chroma(blue), 374 | chroma(purple), 375 | chroma(pink), 376 | ] 377 | } 378 | if (mode === 'light') { 379 | ramp = [ 380 | chroma(red), 381 | chroma(orange), 382 | chroma(yellow), 383 | chroma(green), 384 | chroma(teal), 385 | chroma(blue), 386 | chroma(purple), 387 | chroma(pink), 388 | ] 389 | } 390 | break 391 | } 392 | 393 | let scale 394 | if (bezier) { 395 | scale = chroma.bezier(ramp).scale() 396 | } else { 397 | scale = chroma.scale(ramp).mode('lab') 398 | } 399 | if (correctLightness) { 400 | scale = scale.correctLightness() 401 | } 402 | 403 | return scale.colors(count, format) 404 | } 405 | 406 | export default makeColormap 407 | --------------------------------------------------------------------------------