or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

animations.mdchart-runtime.mdcomponents.mdcompositions.mdcoordinates.mddata-transforms.mdencoding-scales.mdextensions.mdindex.mdinteractions.mdmarks.mdthemes.md
tile.json

encoding-scales.mddocs/

Visual Encoding and Scales

Visual encoding system that maps data values to visual properties like position, color, and size through various scale types.

Capabilities

Visual Encoding

Core encoding system for mapping data fields to visual channels.

/**
 * Encodes data field to visual channel
 * @param channel - Visual channel (x, y, color, size, etc.)
 * @param field - Data field name or encoding function
 */
encode(channel: string, field: string | number | EncodeFunction): MarkNode;

/**
 * Encoding function type for custom data transformations
 */
type EncodeFunction = (data: any, index: number, array: any[]) => any;

/**
 * Available visual channels
 */
type VisualChannel = 
  | "x" | "y" | "z"           // Position channels
  | "color" | "fill" | "stroke" // Color channels  
  | "size" | "radius"         // Size channels
  | "opacity" | "fillOpacity" | "strokeOpacity" // Opacity channels
  | "shape" | "symbol"        // Shape channels
  | "angle" | "rotate"        // Rotation channels
  | "text" | "href"          // Content channels
  | "key" | "groupKey"       // Grouping channels
  | "series";                // Series channels

Basic Encoding Examples:

// Position encoding
chart
  .interval()
  .data(salesData)
  .encode("x", "month")      // X position from month field
  .encode("y", "revenue");   // Y position from revenue field

// Color encoding
chart
  .point()
  .data(dataset)
  .encode("x", "height")
  .encode("y", "weight")
  .encode("color", "gender"); // Color by gender field

// Size encoding
chart
  .point()
  .data(bubbleData)
  .encode("x", "gdp")
  .encode("y", "lifeExpectancy")
  .encode("size", "population"); // Size by population

Scale Configuration

Scale system for controlling how data values map to visual properties.

/**
 * Configures scale for a visual channel
 * @param channel - Visual channel to configure
 * @param options - Scale configuration options
 */
scale(channel: string, options: ScaleOptions): MarkNode;

interface ScaleOptions {
  /** Scale type */
  type?: ScaleType;
  /** Input domain (data values) */
  domain?: any[];
  /** Output range (visual values) */
  range?: any[];
  /** Nice domain boundaries */
  nice?: boolean;
  /** Include zero in domain */
  zero?: boolean;
  /** Reverse the scale */
  reverse?: boolean;
  /** Clamp values to range */
  clamp?: boolean;
  /** Padding for band/point scales */
  padding?: number;
  /** Inner padding for band scales */
  paddingInner?: number;
  /** Outer padding for band scales */
  paddingOuter?: number;
  /** Align bands within range */
  align?: number;
  /** Number of ticks for continuous scales */
  ticks?: number;
  /** Tick values for discrete scales */
  tickCount?: number;
  /** Custom tick format function */
  tickFormat?: (value: any) => string;
  /** Label formatter */
  formatter?: (value: any) => string;
}

type ScaleType = 
  | "linear" | "log" | "pow" | "sqrt" | "time" | "sequential"  // Continuous
  | "ordinal" | "band" | "point" | "threshold"                // Discrete  
  | "identity" | "constant" | "quantile" | "quantize";        // Utility

Continuous Scales

Scales for continuous data types like numbers and dates.

/**
 * Linear scale for numeric data with linear progression
 */
scale(channel: string, options: {
  type: "linear";
  domain?: [number, number];
  range?: [number, number] | string[];
  nice?: boolean;
  zero?: boolean;
  clamp?: boolean;
}): MarkNode;

/**
 * Logarithmic scale for data with exponential relationships
 */
scale(channel: string, options: {
  type: "log";
  base?: number;
  domain?: [number, number];
  range?: [number, number] | any[];
  nice?: boolean;
}): MarkNode;

/**
 * Power scale for data with power law relationships
 */
scale(channel: string, options: {
  type: "pow";
  exponent?: number;
  domain?: [number, number];
  range?: [number, number] | any[];
}): MarkNode;

/**
 * Square root scale (power scale with exponent 0.5)
 */
scale(channel: string, options: {
  type: "sqrt";
  domain?: [number, number];
  range?: [number, number] | any[];
}): MarkNode;

/**
 * Time scale for temporal data
 */
scale(channel: string, options: {
  type: "time";
  domain?: [Date, Date];
  range?: [number, number] | any[];
  nice?: boolean;
}): MarkNode;

Continuous Scale Examples:

// Linear scale with custom domain and range
chart
  .point()
  .data(data)
  .encode("x", "income")
  .scale("x", {
    type: "linear",
    domain: [0, 100000],
    range: [0, 600],
    nice: true
  });

// Logarithmic scale for exponential data
chart
  .point()
  .data(populationData)
  .encode("x", "gdp")
  .encode("y", "population")
  .scale("y", {
    type: "log",
    base: 10,
    domain: [1000, 1000000000]
  });

// Time scale for temporal data
chart
  .line()
  .data(timeSeriesData)
  .encode("x", "date")
  .encode("y", "value")
  .scale("x", {
    type: "time",
    nice: true
  });

Discrete Scales

Scales for categorical and discrete data.

/**
 * Ordinal scale for categorical data
 */
scale(channel: string, options: {
  type: "ordinal";
  domain?: string[];
  range?: any[];
}): MarkNode;

/**
 * Band scale for bar charts and categorical positioning
 */
scale(channel: string, options: {
  type: "band";
  domain?: string[];
  range?: [number, number];
  padding?: number;
  paddingInner?: number;
  paddingOuter?: number;
  align?: number;
}): MarkNode;

/**
 * Point scale for scatter plots with categorical X axis
 */
scale(channel: string, options: {
  type: "point";
  domain?: string[];
  range?: [number, number];
  padding?: number;
  align?: number;
}): MarkNode;

/**
 * Threshold scale for mapping continuous data to discrete ranges
 */
scale(channel: string, options: {
  type: "threshold";
  domain?: number[];
  range?: any[];
}): MarkNode;

Discrete Scale Examples:

// Ordinal color scale
chart
  .point()
  .data(categoricalData)
  .encode("x", "value")
  .encode("y", "score")
  .encode("color", "category")
  .scale("color", {
    type: "ordinal",
    domain: ["A", "B", "C"],
    range: ["red", "green", "blue"]
  });

// Band scale for bar chart
chart
  .interval()
  .data(salesData)
  .encode("x", "product")
  .encode("y", "sales")
  .scale("x", {
    type: "band",
    padding: 0.1,
    paddingOuter: 0.2
  });

// Threshold scale for risk levels
chart
  .point()
  .data(riskData)
  .encode("x", "exposure")
  .encode("color", "riskScore")
  .scale("color", {
    type: "threshold",
    domain: [25, 50, 75],
    range: ["green", "yellow", "orange", "red"]
  });

Color Scales

Specialized scales for color encoding.

/**
 * Sequential color scale for continuous data
 */
scale(channel: string, options: {
  type: "sequential";
  domain?: [number, number];
  range?: string[];
  interpolate?: string; // Color interpolation scheme
  reverse?: boolean;
}): MarkNode;

/**
 * Quantile scale dividing data into equal-sized groups
 */
scale(channel: string, options: {
  type: "quantile";
  domain?: number[];
  range?: string[];
  n?: number; // Number of quantiles
}): MarkNode;

/**
 * Quantize scale dividing domain into uniform segments
 */
scale(channel: string, options: {
  type: "quantize";
  domain?: [number, number];
  range?: string[];
  n?: number; // Number of segments
}): MarkNode;

Color Scale Examples:

// Sequential color scale for heatmap
chart
  .rect()
  .data(heatmapData)
  .encode("x", "category")
  .encode("y", "metric")
  .encode("color", "value")
  .scale("color", {
    type: "sequential",
    range: ["#f7fbff", "#08519c"],
    interpolate: "blues"
  });

// Quantile color scale
chart
  .point()
  .data(distributionData)
  .encode("x", "x")
  .encode("y", "y")
  .encode("color", "density")
  .scale("color", {
    type: "quantile",
    range: ["lightblue", "darkblue"],
    n: 5
  });

Utility Scales

Special-purpose scales for specific use cases.

/**
 * Identity scale (no transformation)
 */
scale(channel: string, options: {
  type: "identity";
}): MarkNode;

/**
 * Constant scale (always returns same value)
 */
scale(channel: string, options: {
  type: "constant";
  value: any;
}): MarkNode;

Advanced Encoding Functions

Custom encoding functions for complex data transformations.

/**
 * Custom encoding function examples
 */

// Dynamic color based on multiple fields
chart
  .point()
  .data(data)
  .encode("color", (d) => {
    if (d.profit > 0) return "green";
    if (d.profit < -1000) return "red";
    return "orange";
  });

// Calculated size encoding
chart
  .point()
  .data(data)
  .encode("size", (d) => Math.sqrt(d.area / Math.PI));

// Conditional text encoding
chart
  .text()
  .data(data)
  .encode("text", (d, i) => i % 2 === 0 ? d.label : "");

// Complex position encoding
chart
  .point()
  .data(data)
  .encode("x", (d) => d.x + Math.random() * 10); // Add jitter

Scale Domains and Ranges

Understanding how domains and ranges work across different scale types.

// Domain: input data values
// Range: output visual values

// Linear scale mapping
scale("x", {
  type: "linear",
  domain: [0, 100],        // Data from 0 to 100
  range: [0, 400]          // Maps to pixels 0 to 400
});

// Color scale mapping  
scale("color", {
  type: "ordinal",
  domain: ["A", "B", "C"], // Category values
  range: ["red", "green", "blue"] // Color values
});

// Size scale mapping
scale("size", {
  type: "linear", 
  domain: [1, 100],        // Data range 1-100
  range: [2, 20]           // Pixel sizes 2-20
});

Scale Nice and Zero Options

Options for improving scale readability.

// Nice domains create round numbers at boundaries
scale("y", {
  type: "linear",
  domain: [1.2, 98.7],
  nice: true              // Rounds to [0, 100]
});

// Zero option includes zero in domain
scale("y", {
  type: "linear", 
  domain: [20, 80],
  zero: true              // Extends to [0, 80]
});

// Combination of nice and zero
scale("y", {
  type: "linear",
  domain: [5, 47],
  nice: true,
  zero: true              // Results in [0, 50]
});