or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

chart-management.mdchart-types.mdindex.mdplugins.mdscales.mdutilities.mdvisual-elements.md
tile.json

scales.mddocs/

Scales

Data-to-pixel conversion and axis rendering for different data types. Scales handle the transformation between data values and pixel coordinates on the chart canvas.

Capabilities

Linear Scale

Handles linear numeric data with equal intervals.

class LinearScale extends Scale {
  static id: 'linear';
  static defaults: object;
  
  getPixelForValue(value: number): number;
  getValueForPixel(pixel: number): number;
  getLabelForValue(value: number): string;
  getDecimalForPixel(pixel: number): number;
}

interface LinearScaleOptions {
  type: 'linear';
  position?: 'left' | 'right' | 'top' | 'bottom' | 'center' | { [scaleId: string]: number };
  axis?: 'x' | 'y';
  offset?: boolean;
  beginAtZero?: boolean;
  bounds?: 'data' | 'ticks';
  clip?: boolean;
  grace?: number | string;
  min?: number;
  max?: number;
  suggestedMin?: number;
  suggestedMax?: number;
  ticks?: TickOptions;
  title?: TitleOptions;
  grid?: GridLineOptions;
  border?: BorderOptions;
}

Usage Example:

const config = {
  type: 'line',
  data: { /* data */ },
  options: {
    scales: {
      y: {
        type: 'linear',
        beginAtZero: true,
        min: 0,
        max: 100,
        ticks: {
          stepSize: 10
        }
      }
    }
  }
};

Category Scale

Handles categorical/ordinal data with discrete labels.

class CategoryScale extends Scale {
  static id: 'category';
  static defaults: object;
  
  getPixelForValue(value: string | number): number;
  getValueForPixel(pixel: number): number;
  getLabelForValue(value: string | number): string;
  getLabels(): string[];
}

interface CategoryScaleOptions {
  type: 'category';
  position?: 'left' | 'right' | 'top' | 'bottom' | 'center' | { [scaleId: string]: number };
  axis?: 'x' | 'y';
  offset?: boolean;
  labels?: string[];
  min?: string | number;
  max?: string | number;
  ticks?: TickOptions;
  title?: TitleOptions;
  grid?: GridLineOptions;
  border?: BorderOptions;
}

Usage Example:

const config = {
  type: 'bar',
  data: {
    labels: ['Red', 'Blue', 'Yellow', 'Green'],
    datasets: [{ /* dataset */ }]
  },
  options: {
    scales: {
      x: {
        type: 'category',
        labels: ['Custom Red', 'Custom Blue', 'Custom Yellow', 'Custom Green']
      }
    }
  }
};

Logarithmic Scale

Handles logarithmic numeric data with exponential intervals.

class LogarithmicScale extends Scale {
  static id: 'logarithmic';
  static defaults: object;
  
  getPixelForValue(value: number): number;
  getValueForPixel(pixel: number): number;
  getLabelForValue(value: number): string;
}

interface LogarithmicScaleOptions {
  type: 'logarithmic';
  position?: 'left' | 'right' | 'top' | 'bottom' | 'center' | { [scaleId: string]: number };
  axis?: 'x' | 'y';
  min?: number;
  max?: number;
  suggestedMin?: number;
  suggestedMax?: number;
  ticks?: TickOptions;
  title?: TitleOptions;
  grid?: GridLineOptions;
  border?: BorderOptions;
}

Time Scale

Handles time-based data with temporal intervals.

class TimeScale extends Scale {
  static id: 'time';
  static defaults: object;
  
  getPixelForValue(value: string | number | Date): number;
  getValueForPixel(pixel: number): number;
  getLabelForValue(value: string | number | Date): string;
}

interface TimeScaleOptions {
  type: 'time';
  position?: 'left' | 'right' | 'top' | 'bottom' | 'center' | { [scaleId: string]: number };
  axis?: 'x' | 'y';
  adapters?: DateAdapter;
  bounds?: 'data' | 'ticks';
  offset?: boolean;
  min?: string | number | Date;
  max?: string | number | Date;
  suggestedMin?: string | number | Date;
  suggestedMax?: string | number | Date;
  time?: TimeOptions;
  ticks?: TickOptions;
  title?: TitleOptions;
  grid?: GridLineOptions;
  border?: BorderOptions;
}

interface TimeOptions {
  displayFormats?: {
    millisecond?: string;
    second?: string;
    minute?: string;
    hour?: string;
    day?: string;
    week?: string;
    month?: string;
    quarter?: string;
    year?: string;
  };
  isoWeekday?: boolean | number;
  parser?: string | ((value: unknown) => Date);
  round?: TimeUnit;
  tooltipFormat?: string;
  unit?: TimeUnit;
  stepSize?: number;
  minUnit?: TimeUnit;
}

type TimeUnit = 'millisecond' | 'second' | 'minute' | 'hour' | 'day' | 'week' | 'month' | 'quarter' | 'year';

interface DateAdapter {
  formats(): { [key: string]: string };
  parse(value: unknown, format?: string): Date | null;
  format(time: Date, format: string): string;
  add(time: Date, amount: number, unit: TimeUnit): Date;
  diff(max: Date, min: Date, unit: TimeUnit): number;
  startOf(time: Date, unit: TimeUnit, weekday?: number): Date;
  endOf(time: Date, unit: TimeUnit): Date;
}

Usage Example:

const config = {
  type: 'line',
  data: {
    datasets: [{
      label: 'Time Series',
      data: [
        { x: '2023-01-01', y: 10 },
        { x: '2023-02-01', y: 20 },
        { x: '2023-03-01', y: 15 }
      ]
    }]
  },
  options: {
    scales: {
      x: {
        type: 'time',
        time: {
          unit: 'month',
          displayFormats: {
            month: 'MMM YYYY'
          }
        }
      }
    }
  }
};

Time Series Scale

Optimized time scale for large time series datasets.

class TimeSeriesScale extends TimeScale {
  static id: 'timeseries';
  static defaults: object;
}

interface TimeSeriesScaleOptions extends TimeScaleOptions {
  type: 'timeseries';
  bounds: 'data'; // Always 'data' for timeseries
  offset: false;   // Always false for timeseries
}

Radial Linear Scale

Handles radial numeric data for radar charts.

class RadialLinearScale extends Scale {
  static id: 'radialLinear';
  static defaults: object;
  
  getPixelForValue(value: number, index?: number): number;
  getValueForPixel(pixel: number): number;
  getLabelForValue(value: number): string;
  getIndexAngle(index: number): number;
  getDistanceFromCenterForValue(value: number): number;
  getValueForDistanceFromCenter(distance: number): number;
}

interface RadialLinearScaleOptions {
  type: 'radialLinear';
  animate?: boolean;
  angleLines?: AngleLineOptions;
  beginAtZero?: boolean;
  grid?: GridLineOptions;
  min?: number;
  max?: number;
  pointLabels?: PointLabelOptions;
  startAngle?: number;
  ticks?: TickOptions;
  title?: TitleOptions;
}

interface AngleLineOptions {
  display?: boolean;
  color?: Color;
  lineWidth?: number;
  borderDash?: number[];
  borderDashOffset?: number;
}

interface PointLabelOptions {
  display?: boolean;
  callback?: (label: string, index: number) => string;
  color?: Color;
  font?: FontSpec;
  padding?: number;
  centerPointLabels?: boolean;
}

Base Scale Interface

Common interface implemented by all scales.

interface Scale {
  readonly id: string;
  readonly type: string;
  readonly ctx: CanvasRenderingContext2D;
  readonly chart: Chart;
  
  // Core conversion methods
  getPixelForValue(value: unknown, index?: number): number;
  getValueForPixel(pixel: number): unknown;
  getPixelForTick(index: number): number;
  getPixelForDecimal(decimal: number): number;
  getDecimalForPixel(pixel: number): number;
  getBaseValue(): number;
  getBasePixel(): number;
  
  // Label methods
  getLabelForValue(value: unknown): string;
  
  // Lifecycle methods
  beforeLayout(): void;
  afterLayout(): void;
  beforeUpdate(mode: UpdateMode): void;
  update(width: number, height: number, margins: ChartArea): void;
  afterUpdate(mode: UpdateMode): void;
  
  // Drawing methods
  beforeDraw(): void;
  draw(chartArea: ChartArea): void;
  afterDraw(): void;
  
  // Utility methods
  isHorizontal(): boolean;
  buildTicks(): Tick[];
  configure(): void;
  fit(): void;
}

Scale Registration

Scales must be registered before use in charts.

import {
  Chart,
  LinearScale,
  CategoryScale,
  TimeScale,
  LogarithmicScale,
  RadialLinearScale,
  TimeSeriesScale
} from 'chart.js';

// Register scales
Chart.register(
  LinearScale,
  CategoryScale,
  TimeScale,
  LogarithmicScale,
  RadialLinearScale,
  TimeSeriesScale
);

Types

type ScaleType = 'linear' | 'logarithmic' | 'category' | 'time' | 'timeseries' | 'radialLinear';

interface TickOptions {
  display?: boolean;
  align?: 'start' | 'center' | 'end' | 'inner';
  callback?: (tickValue: number | string, index: number, ticks: Tick[]) => string | string[] | number | number[];
  color?: Color | Color[];
  count?: number;
  crossAlign?: 'near' | 'center' | 'far';
  font?: FontSpec | FontSpec[];
  includeBounds?: boolean;
  labelOffset?: number;
  maxRotation?: number;
  maxTicksLimit?: number;
  minRotation?: number;
  mirror?: boolean;
  padding?: number;
  precision?: number;
  sampleSize?: number;
  showLabelBackdrop?: boolean;
  source?: 'auto' | 'data' | 'labels';
  stepSize?: number;
  textStrokeColor?: Color | Color[];
  textStrokeWidth?: number | number[];
  z?: number;
}

interface TitleOptions {
  display?: boolean;
  align?: 'start' | 'center' | 'end';
  color?: Color;
  font?: FontSpec;
  padding?: Padding;
  text?: string | string[];
}

interface GridLineOptions {
  display?: boolean;
  circular?: boolean;
  color?: Color | Color[];
  lineWidth?: number | number[];
  drawBorder?: boolean;
  drawOnChartArea?: boolean;
  drawTicks?: boolean;
  tickBorderDash?: number[];
  tickBorderDashOffset?: number;
  tickColor?: Color | Color[];
  tickLength?: number;
  tickWidth?: number;
  offset?: boolean;
  z?: number;
}

interface BorderOptions {
  display?: boolean;
  color?: Color;
  width?: number;
  dash?: number[];
  dashOffset?: number;
  z?: number;
}

interface Tick {
  value: number;
  label?: string;
  major?: boolean;
}

interface ChartArea {
  left: number;
  top: number;
  right: number;
  bottom: number;
  width: number;
  height: number;
}

interface FontSpec {
  family?: string;
  size?: number;
  style?: 'normal' | 'italic' | 'oblique';
  weight?: string | number;
  lineHeight?: number | string;
}

interface Padding {
  top?: number;
  right?: number;
  bottom?: number;
  left?: number;
}