Skip to content

Style Helpers & Palettes ​

Comprehensive guide to using Style Helpers for data-driven visualization with colorblind-safe palettes.

Overview ​

Style Helpers transform algorithm results into visual properties. They provide:

  • Research-backed, colorblind-safe color palettes
  • Consistent, professional aesthetic
  • Easy mapping from data values to visual properties

Color Palettes ​

Sequential Palettes (Continuous Data: 0 → 1) ​

For continuous data like centrality scores or normalized values:

PaletteColorsUse CaseColorblind Safe
viridis (default)Purple → Teal → YellowGeneral continuous data✅ Yes
plasmaPurple → Pink → YellowHigh contrast needed✅ Yes
infernoBlack → Red → YellowEmphasis on extremes✅ Yes
bluesLight → Dark BlueProfessional, subtle✅ Yes
greensLight → Dark GreenGrowth, positive metrics✅ Yes
orangesLight → Dark OrangeActivity, heat✅ Yes
typescript
import { StyleHelpers } from '@graphty/graphty-element';

// Map 0-1 value to color
const color = StyleHelpers.color.sequential.viridis(0.7);
const blueColor = StyleHelpers.color.sequential.blues(0.5);

Categorical Palettes (Discrete Groups) ​

For distinct categories like communities or types:

PaletteColorsUse CaseColorblind Safe
okabeIto (default)8 colorsUniversal safe choice✅ Yes
paulTolVibrant7 colorsHigh saturation✅ Yes
paulTolMuted9 colorsSofter aesthetic✅ Yes
ibmCarbon5 colorsEnterprise design✅ Yes
pastel8 colorsLighter appearance✅ Yes
typescript
// Map category index to color
const color = StyleHelpers.color.categorical.okabeIto(2);
const vibrantColor = StyleHelpers.color.categorical.paulTolVibrant(0);

Diverging Palettes (Midpoint Data: -1 ↔ 0 ↔ +1) ​

For data with a meaningful center point:

PaletteColorsUse CaseColorblind Safe
purpleGreen (default)Purple ← White → GreenGeneral diverging✅ Yes
blueOrangeBlue ← White → OrangeAlternative✅ Yes
redBlueRed ← White → BlueTemperature only⚠️ No
typescript
// Map -1 to +1 value to color
const color = StyleHelpers.color.diverging.purpleGreen(0.5);
const negative = StyleHelpers.color.diverging.purpleGreen(-0.8);

Binary Palettes (Boolean: true/false) ​

For binary states like selected/unselected:

PaletteColorsUse CaseColorblind Safe
blueHighlight (default)Blue vs GraySelection, highlight✅ Yes
greenSuccessGreen vs GraySuccess states✅ Yes
orangeWarningOrange vs GrayWarning states✅ Yes
typescript
// Map boolean to color
const color = StyleHelpers.color.binary.blueHighlight(true);
const inactiveColor = StyleHelpers.color.binary.blueHighlight(false);

Why These Colors? ​

Okabe-Ito Palette ​

Designed by Masataka Okabe and Kei Ito (2008) specifically for colorblind accessibility. Adopted as the R 4.0 default. Each color is distinguishable under all forms of color vision deficiency.

Paul Tol Palettes ​

Mathematically optimized palettes by Paul Tol (2021) using color science principles. Tested for Deuteranopia, Protanopia, and Tritanopia.

Viridis/Plasma/Inferno ​

Developed for matplotlib by Stéfan van der Walt and Nathaniel Smith. Perceptually uniform (equal steps look equal) and colorblind-safe.

ColorBrewer ​

Cynthia Brewer's research-backed palettes widely used in cartography and data visualization.

Size Helpers ​

Map values to node sizes:

typescript
// Linear scaling
const size = StyleHelpers.size.linear(value, { min: 0.5, max: 3.0 });

// Logarithmic (for power-law data like degree distribution)
const logSize = StyleHelpers.size.log(value, { min: 0.5, max: 3.0 });

// Discrete bins
const binSize = StyleHelpers.size.bins(value, [0.5, 1.0, 1.5, 2.0, 3.0]);

Opacity Helpers ​

Map values to transparency:

typescript
// Linear opacity
const opacity = StyleHelpers.opacity.linear(value);

// Threshold (below = 0, above = 1)
const threshOpacity = StyleHelpers.opacity.threshold(value, 0.5);

Label Helpers ​

Format values for labels:

typescript
// Format as percentage
const label = StyleHelpers.label.percentage(0.847); // "84.7%"

// Format with rank
const rankLabel = StyleHelpers.label.rankLabel(node, 'degree'); // "#3"

// Top N only (returns label only for top N nodes)
const topLabel = StyleHelpers.label.topN(node, 'pagerank', 10);

Edge Width Helpers ​

Map edge weights to width:

typescript
const width = StyleHelpers.edgeWidth.linear(weight, { min: 0.5, max: 3.0 });

Combined Helpers ​

Apply multiple visual properties at once:

typescript
// Color AND size from same value
const { color, size } = StyleHelpers.combined.colorAndSize(value);

// Full spectrum: color, size, opacity, label
const styles = StyleHelpers.combined.fullSpectrum(value);

Animation Helpers ​

For animated visualizations:

typescript
// Easing functions
const eased = StyleHelpers.animation.easeOutCubic(t);

// Pulse effect
const pulse = StyleHelpers.animation.pulse(t, { frequency: 2 });

Using with Algorithms ​

Complete example combining algorithms with style helpers:

typescript
// Run algorithm
await graph.runAlgorithm('graphty', 'degree');

// Find max degree for normalization
const maxDegree = Math.max(
  ...graph.getNodes().map(n => n.algorithmResults['graphty:degree'] || 0)
);

// Apply style helper
graph.styleManager.addLayer({
  selector: '*',
  styles: {
    node: {
      color: (node) => StyleHelpers.color.sequential.viridis(
        (node.algorithmResults['graphty:degree'] || 0) / maxDegree
      ),
      size: (node) => StyleHelpers.size.log(
        node.algorithmResults['graphty:degree'] || 0,
        { min: 0.5, max: 2.5 }
      )
    }
  }
});

Colorblind Safety Guidelines ​

Do ​

  • Use default palettes (all tested for accessibility)
  • Use Okabe-Ito for categorical data (8 distinct colors)
  • Use single-hue palettes (blues, greens) for sequential data
  • Test with colorblind simulation tools

Don't ​

  • Use red-green to indicate opposite meanings
  • Use more than 7-9 categorical colors
  • Rely solely on color to convey information

Accessibility Features ​

typescript
import { colorblindSimulation } from '@graphty/graphty-element';

// Simulate how colors appear to colorblind users
const deuteranopia = colorblindSimulation.simulateDeuteranopia('#ff0000');
const protanopia = colorblindSimulation.simulateProtanopia('#ff0000');

// Check if a palette is safe
const isSafe = colorblindSimulation.isPaletteSafe(myColors);

Interactive Examples ​