or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

color-parsing.mdcubehelix-color-space.mdhsl-color-space.mdindex.mdlab-color-space.mdlch-color-space.mdrgb-color-space.md
tile.json

cubehelix-color-space.mddocs/

Cubehelix Color Space

Dave Green's Cubehelix color space operations providing monotonic lightness transitions ideal for data visualization. Cubehelix generates color scales that maintain perceptual ordering even when converted to grayscale.

Capabilities

Cubehelix Color Construction

Create Cubehelix colors optimized for scientific visualization and accessibility.

/**
 * Creates Cubehelix color from numeric values
 * @param h - Hue angle in degrees (color wheel position)
 * @param s - Saturation (0=grayscale, 1=full color, can exceed 1)
 * @param l - Lightness (0=black, 1=white, values outside range are valid)
 * @param opacity - Alpha channel (0-1), defaults to 1
 * @returns Cubehelix color object
 */
function cubehelix(h: number, s: number, l: number, opacity?: number): Cubehelix;

/**
 * Creates Cubehelix color from CSS color string
 * @param specifier - CSS color string
 * @returns Cubehelix color object
 */
function cubehelix(specifier: string): Cubehelix;

/**
 * Converts any color object to Cubehelix
 * @param color - Color object to convert
 * @returns Cubehelix color object
 */
function cubehelix(color: Color): Cubehelix;

Usage Examples:

import { cubehelix, rgb } from "d3-color";

// Direct Cubehelix construction
const start = cubehelix(300, 0.5, 0.0);    // Dark purple start
const middle = cubehelix(200, 0.8, 0.5);   // Colorful middle  
const end = cubehelix(80, 0.3, 1.0);       // Light yellow end

// Grayscale (zero saturation maintains monotonic lightness)
const black = cubehelix(0, 0, 0);          // Start of grayscale
const gray = cubehelix(0, 0, 0.5);         // Middle gray
const white = cubehelix(0, 0, 1);          // End of grayscale

// Convert from other formats
const rgbBlue = rgb(0, 0, 255);
const cubeBlue = cubehelix(rgbBlue);       // Convert RGB to Cubehelix

// String parsing
const red = cubehelix("#ff0000");
const green = cubehelix("green");

Cubehelix Color Class

Cubehelix color representation designed for perceptual uniformity and monotonic lightness.

class Cubehelix {
  /** Hue angle in degrees (color wheel position, no wrapping) */
  h: number;
  /** Saturation (0=no color, 1=full saturation, can exceed 1) */
  s: number;
  /** Lightness (0=black, 1=white, values outside range are valid) */
  l: number;
  /** Opacity/alpha channel (0-1) */
  opacity: number;
  
  constructor(h: number, s: number, l: number, opacity: number);
  
  brighter(k?: number): Cubehelix;
  darker(k?: number): Cubehelix;
  rgb(): Rgb;
  displayable(): boolean;
  copy(values?: object): Cubehelix;
  formatHex(): string;
  formatHex8(): string;
  formatRgb(): string;
  formatHsl(): string;
  toString(): string;
}

Monotonic Brightness Manipulation

Adjust brightness while preserving the monotonic lightness property crucial for data visualization.

/**
 * Returns a brighter copy by multiplying lightness
 * @param k - Brightening factor, defaults to 1/0.7 ≈ 1.43
 * @returns New Cubehelix color instance
 */
brighter(k?: number): Cubehelix;

/**
 * Returns a darker copy by multiplying lightness
 * @param k - Darkening factor, defaults to 0.7
 * @returns New Cubehelix color instance
 */
darker(k?: number): Cubehelix;

Brightness Behavior:

  • Brighter: Multiplies lightness by factor (default ~1.43)
  • Darker: Multiplies lightness by factor (default 0.7)
  • Monotonic Property: Brightness changes preserve perceptual ordering
  • Hue and saturation remain unchanged

Usage Examples:

import { cubehelix } from "d3-color";

const color = cubehelix(180, 0.8, 0.5);    // Cyan-ish middle

// Brightness adjustments preserve ordering
const lighter = color.brighter();           // l * 1.43
const darker = color.darker();              // l * 0.7

// Custom brightness factors
const muchBrighter = color.brighter(2);     // l * 2
const slightlyDarker = color.darker(0.9);   // l * 0.9

console.log(color.l);           // 0.5 (original)
console.log(lighter.l);         // ~0.71 (brighter)
console.log(darker.l);          // ~0.35 (darker)

// Hue and saturation preserved
console.log(color.h, lighter.h, darker.h);    // All 180
console.log(color.s, lighter.s, darker.s);    // All 0.8

Color Space Conversion

Convert Cubehelix colors to RGB for display.

/**
 * Converts Cubehelix color to RGB color space
 * @returns New RGB color instance
 */
rgb(): Rgb;

Usage Examples:

import { cubehelix } from "d3-color";

const cubeColor = cubehelix(240, 1, 0.5);   // Blue-ish in Cubehelix
const rgbColor = cubeColor.rgb();           // Convert to RGB

console.log(rgbColor.r, rgbColor.g, rgbColor.b); // RGB channel values

Color Copying

Create modified copies for data visualization color scales.

/**
 * Creates a copy of this color with optional property overrides
 * @param values - Object with properties to override
 * @returns New Cubehelix color instance
 */
copy(values?: {h?: number, s?: number, l?: number, opacity?: number}): Cubehelix;

Usage Examples:

import { cubehelix } from "d3-color";

const baseColor = cubehelix(300, 0.8, 0.5);

// Lightness variations (maintaining monotonicity)
const darker = baseColor.copy({l: 0.2});    // Darker version
const lighter = baseColor.copy({l: 0.8});   // Lighter version

// Saturation variations (color intensity)
const grayscale = baseColor.copy({s: 0});   // Remove color, keep lightness
const muted = baseColor.copy({s: 0.4});     // Reduce saturation
const vivid = baseColor.copy({s: 1.2});     // Increase saturation beyond 1

// Hue variations (color wheel position)
const shifted = baseColor.copy({h: 200});   // Different hue
const rotated = baseColor.copy({h: baseColor.h + 60}); // Rotate hue

// Create color scale endpoints
const startPoint = baseColor.copy({l: 0.1, s: 0.8});  // Dark, colorful
const endPoint = baseColor.copy({l: 0.9, s: 0.2});    // Light, muted

String Formatting

Cubehelix colors inherit all base Color formatting methods via RGB conversion.

/**
 * Returns 6-digit hexadecimal string (via RGB conversion)
 * @returns Hex string like "#ff0000"
 */
formatHex(): string;

/**
 * Returns CSS rgb() string (via RGB conversion)
 * @returns RGB string like "rgb(255, 0, 0)"
 */
formatRgb(): string;

/**
 * Returns CSS hsl() string (via RGB conversion)
 * @returns HSL string like "hsl(0, 100%, 50%)"
 */
formatHsl(): string;

/**
 * Alias for formatRgb()
 * @returns RGB string representation
 */
toString(): string;

Usage Examples:

import { cubehelix } from "d3-color";

const purple = cubehelix(270, 0.8, 0.6);

// All output formats available
console.log(purple.formatHex());  // "#a855f7" (approximately)
console.log(purple.formatRgb());  // "rgb(168, 85, 247)" (approximately)
console.log(purple.formatHsl());  // "hsl(270, 90%, 65%)" (approximately)
console.log(purple.toString());   // "rgb(168, 85, 247)" (approximately)

Displayability

Check if Cubehelix colors can be accurately rendered in RGB.

/**
 * Checks if color is displayable when converted to RGB
 * @returns True if RGB equivalent is displayable
 */
displayable(): boolean;

Usage Examples:

import { cubehelix } from "d3-color";

const normalCube = cubehelix(200, 0.8, 0.5);  // Typical Cubehelix color
const extremeCube = cubehelix(200, 2.0, 1.2); // Very saturated and bright

console.log(normalCube.displayable());   // true (likely)
console.log(extremeCube.displayable());  // false (likely, out of RGB gamut)

Cubehelix Data Visualization Patterns

Common patterns for creating perceptually uniform color scales for data visualization.

Usage Examples:

import { cubehelix } from "d3-color";

// Create monotonic color scale for heatmaps
function createHeatmapScale(steps = 10) {
  const colors = [];
  for (let i = 0; i < steps; i++) {
    const t = i / (steps - 1);
    // Monotonic lightness from dark to light
    const lightness = 0.15 + 0.7 * t;
    // Hue rotation through color spectrum  
    const hue = 300 - 240 * t;  // Purple to yellow
    // Decreasing saturation toward light end
    const saturation = 0.8 * (1 - t * 0.3);
    
    colors.push(cubehelix(hue, saturation, lightness));
  }
  return colors;
}

// Create single-hue brightness scale (maintains hue, varies lightness)
function createBrightnessScale(baseHue, steps = 5) {
  const colors = [];
  for (let i = 0; i < steps; i++) {
    const lightness = 0.2 + (0.6 * i) / (steps - 1);
    colors.push(cubehelix(baseHue, 0.8, lightness));
  }
  return colors;
}

// Create accessible color scale (works in grayscale)
function createAccessibleScale() {
  return [
    cubehelix(300, 0.8, 0.2),  // Dark purple
    cubehelix(250, 0.9, 0.4),  // Medium blue  
    cubehelix(180, 0.7, 0.6),  // Light cyan
    cubehelix(120, 0.5, 0.8),  // Light green
    cubehelix(60, 0.3, 0.9)    // Very light yellow
  ];
  // Even when desaturated, lightness ordering is preserved
}

// Test grayscale conversion (lightness should be monotonic)
const scale = createHeatmapScale(5);
const grayscale = scale.map(color => cubehelix(0, 0, color.l));
console.log("Lightness values:", grayscale.map(c => c.l));
// Should be: [0.15, 0.325, 0.5, 0.675, 0.85] (monotonically increasing)