percep-uni

Generate and refine perceptual uniform colors. This library can be used in browser as well as on node server.

Usage no npm install needed!

<script type="module">
  import percepUni from 'https://cdn.skypack.dev/percep-uni';
</script>

README

percep-uni Perceptual Uniformity

Generate and refine perceptual uniform colors. This library can be used in browser as well as on node server.

Samples

Stackoverflow network. <>

5 disctinct colors are generated from Purple preset. For each distinct color, sub colorspace has been generated containing 20 colors Each topic node is renderd with a color from sub-colorspace

Stackoverflow

A network of colors of 猪熊佳子 KEIKO INOKUMA 's painting. <>

Sining in the forest force layout of keiko

Force Layout <>

A force layout (Force Atlas 2 is used) of 10 colors as well as each sub colorspaces.

Force Layout

select colors with a preset and hcl selector <>

HCL selector

sort sub colorspace by hue and display as rect tiles. <>

Color Tiles

Tutorials and Concepts

Please visit IWantHue's website for tutorial and concepts

Installation

  1. Install
npm install percep-uni --save
  1. ES6 Usage
import { generateColorPalette } from 'percep-uni';

Development

  1. Clone repository
  2. Run commands
npm install         // install dependencies
npm run dev         // view demos in web browser at localhost:3005
npm run build       // build
npm run test        // run tests only
npm run test:cover  // run tests and view coverage report

Typical Usage with Comments

import {
  reducePresetToHCLPalette,
  getSubColorSpace,
  hclPresetSelector,
  IceCube,
} from 'precep-uni';

const quickHandsOn = () => {
  // use IceCube preset and generate 6 distinct colors
  const palette = reducePresetToHCLPalette(6, IceCube);

  // use a hcl selector to get sub colorspace of the reduced color palette
  const subspaceSamples = getSubColorSpace(palette, c =>
    hclPresetSelector(IceCube, c.hcl)
  );
  /**
     color palette is now:
     { '#62e0d3':
        [ '#49b9b6',
          '#05bcb6',
          '#63c0af'
          ...
          ]
  *
  */

  // sort color palette with prime colorspace
  const primes = Objects.keys(subspaceSamples);

  // sort palette by difference
  const sortedByDiff = sortPalette(
    primes.map(d => chroma.hex(d)),
    'difference'
  );
  // or by hue:
  const sortedByHue = sortPalette(primes.map(d => chroma.hex(d)), 'hue');
};

API

Generate a color palette

# reducePresetToHCLPalette(count, preset, [opt]) <>
reduces a preset to a color palette with HCL selector. This method will grow expensive as count increases. An generated palette is an Array that contains:

{ color: Color { _rgb: [Array] }, // chromajs object
    hex: '#6de2ce',
    hcl: [ 181.09121080324783, 37.506802392206424, 82.85714463619833 ],
    lab: [ 82.85714463619833, -37.50000035557483, -0.7142821710706571 ] },

opt is an optional parameter, settings are:

const DefaultOpt = {
  quality: 50,
  useFV: false,
  ultraPrecision: false,
  colorblind: false,
};

# reduceToPalette(count, selector, [opt]) <>
reduces a preset to a color palette

opt is an optional parameter, settings are:

const DefaultOpt = {
  quality: 50,
  useFV: false,
  ultraPrecision: false,
  colorblind: false,
};

# getSubColorSpace(colors, [selector, distanceType]) <>
gets a sub colorspace of a generated color palette. Available distantTypes are:

  • 'Default'
  • 'Euclidian'
  • 'CMC'
  • 'Compromise'

# selectColorSpace(selector) <>
sample and select color space with a selector. Due to the nature of sampling, this method returns value differently when called multiple times

# sortPalette(colors, [mode, type]) <> Sort color palette. Available modes are:

  • 'difference'
  • 'hue'
  • 'chroma'
  • 'lightness'
  • 'rgb'

the *type* parameter takes effect only when mode is *difference* available types are: * 'Default' * 'Euclidian' * 'CMC' * 'Compromise'

# hclPresetSelector(preset, hcl) <>
HCL selector.

# getColorDistance(lab1, lab2, [type]) <>
get color distance between lab1 and lab2, type could be one of:

  • 'Default'
  • 'Euclidian'
  • 'CMC'
  • 'Compromise'

# presets <> HCL presets:

  • AllHcl
  • DefaultColorSpace
  • ColorBlind
  • FancyLight
  • FancyDark
  • Tarnish
  • Pastel
  • Purple
  • Intense
  • Fluo
  • RedRoses
  • OchreSand
  • IndigoNight
  • YellowLime
  • GreenMint
  • IceCube
  • BlueOcean
  • PurpleWine

# generate(colorsCount, [config]) <>
Generates colors from color space. This is for internal use only for now

config is optional, settings are:

  const {
    selector = () => true,
    forceMode = false, // true for force vector, false for kmeans
    quality = 50,
    ultraPrecision = false,
    distanceType = 'Default',
  } = config;

Motivation

When we need to use categorical colors in data visualizations, ColorBrewer helps to generate distinct/categorical colors and ensures the even distribution. But what if we want to get sub color-space from each single color of the categorical color scheme?

It becomes an interesting idea to me as I draw a force graph with sigma.js or a ribbon chart to represent a network of employees of a company. Categorical colors are used to represent departments, i.e, groups of people. For each group, a set of sub-colorspace is generated to represent employees' other attributes.

This is possible with IWantHue. IWantHue is a standalone application but not a library, I studied IWantHue and made this library: percep-uni.

ALL core algorithms come from IWantHue Thanks to medialab team for creating the fun yet powerful IWantHue

Credits

License

This project is licensed under the MIT License - see the LICENSE file for details