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.
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 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;
}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:
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.8Convert 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 valuesCreate 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, mutedCubehelix 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)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)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)