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.
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
}
}
}
}
};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']
}
}
}
};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;
}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'
}
}
}
}
}
};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
}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;
}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;
}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
);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;
}