# Utilities

Helper functions for common operations, calculations, and canvas manipulation. The helpers module provides utility functions organized by category for various chart-related tasks.

## Capabilities

### Color Utilities

Functions for color parsing, manipulation, and conversion.

```javascript { .api }
/**
 * Parse and create color objects
 * @param value - Color string, gradient, or pattern
 * @returns Color object with RGBA properties
 */
function color(value: string | CanvasGradient | CanvasPattern): Color;

/**
 * Generate hover color variant
 * @param color - Base color
 * @returns Darker/lighter variant for hover state
 */
function getHoverColor(color: Color): Color;

/**
 * Check if value is a pattern or gradient
 * @param value - Value to check
 * @returns True if pattern or gradient
 */
function isPatternOrGradient(value: unknown): value is CanvasGradient | CanvasPattern;
```

**Usage Example:**

```javascript
import { color, getHoverColor } from 'chart.js/helpers';

// Parse color
const blue = color('rgba(54, 162, 235, 0.8)');
console.log(blue.r, blue.g, blue.b, blue.a); // 54, 162, 235, 0.8

// Generate hover color
const hoverBlue = getHoverColor(blue);
```

### Core Utilities

Basic utility functions for type checking and value handling.

```javascript { .api }
/**
 * Check if value is an array
 * @param value - Value to check
 * @returns True if array
 */
function isArray(value: unknown): value is unknown[];

/**
 * Check if value is an object
 * @param value - Value to check
 * @returns True if object (not null, array, or primitive)
 */
function isObject(value: unknown): value is object;

/**
 * Check if value is null or undefined
 * @param value - Value to check
 * @returns True if null or undefined
 */
function isNullOrUndef(value: unknown): value is null | undefined;

/**
 * No-operation function
 * @returns void
 */
function noop(): void;

/**
 * Generate unique identifier
 * @returns Unique string ID
 */
function uid(): string;

/**
 * Return value or default if undefined
 * @param value - Value to check
 * @param defaultValue - Default to return
 * @returns Value or default
 */
function valueOrDefault<T>(value: T | undefined, defaultValue: T): T;

/**
 * Clamp value to range
 * @param value - Value to clamp
 * @param min - Minimum value
 * @param max - Maximum value
 * @returns Clamped value
 */
function clamp(value: number, min: number, max: number): number;
```

### Canvas Utilities

Functions for canvas drawing and manipulation.

```javascript { .api }
/**
 * Clear entire canvas
 * @param ctx - Canvas rendering context
 */
function clearCanvas(ctx: CanvasRenderingContext2D): void;

/**
 * Clip canvas to specified area
 * @param ctx - Canvas rendering context
 * @param area - Area to clip to
 */
function clipArea(ctx: CanvasRenderingContext2D, area: ChartArea): void;

/**
 * Restore canvas from clipping
 * @param ctx - Canvas rendering context
 * @param area - Previously clipped area
 */
function unclipArea(ctx: CanvasRenderingContext2D, area: ChartArea): void;

/**
 * Draw point shape at coordinates
 * @param ctx - Canvas rendering context
 * @param options - Point style options
 * @param x - X coordinate
 * @param y - Y coordinate
 */
function drawPoint(ctx: CanvasRenderingContext2D, options: PointOptions, x: number, y: number): void;

/**
 * Render text with alignment and rotation
 * @param ctx - Canvas rendering context
 * @param text - Text to render
 * @param x - X coordinate
 * @param y - Y coordinate
 * @param options - Text rendering options
 */
function renderText(ctx: CanvasRenderingContext2D, text: string, x: number, y: number, options?: TextOptions): void;

/**
 * Measure text dimensions
 * @param ctx - Canvas rendering context
 * @param text - Text to measure
 * @param font - Font specification
 * @returns Text metrics
 */
function measureText(ctx: CanvasRenderingContext2D, text: string, font?: FontSpec): TextMetrics;
```

**Usage Example:**

```javascript
import { clearCanvas, drawPoint, renderText } from 'chart.js/helpers';

const ctx = canvas.getContext('2d');

// Clear canvas
clearCanvas(ctx);

// Draw custom point
drawPoint(ctx, {
  pointStyle: 'star',
  radius: 10,
  backgroundColor: 'gold'
}, 100, 100);

// Render text
renderText(ctx, 'Custom Label', 100, 120, {
  color: 'black',
  font: { size: 14, weight: 'bold' },
  textAlign: 'center'
});
```

### Collection Utilities

Functions for array and object manipulation.

```javascript { .api }
/**
 * Iterate over collection
 * @param loopable - Array or object to iterate
 * @param fn - Function to call for each item
 * @param thisArg - Context for function calls
 */
function each<T>(loopable: T[] | { [key: string]: T }, fn: (item: T, index: number | string) => void, thisArg?: unknown): void;

/**
 * Find index in array matching condition
 * @param array - Array to search
 * @param callback - Condition function
 * @returns Index or -1 if not found
 */
function findIndex<T>(array: T[], callback: (item: T, index: number) => boolean): number;

/**
 * Filter collection by condition
 * @param collection - Collection to filter
 * @param filterCallback - Filter function
 * @returns Filtered array
 */
function where<T>(collection: T[], filterCallback: (item: T) => boolean): T[];

/**
 * Get unique values from array
 * @param array - Input array
 * @returns Array with unique values
 */
function uniq<T>(array: T[]): T[];

/**
 * Create array with specified length and fill value
 * @param length - Array length
 * @param value - Fill value
 * @returns Filled array
 */
function array<T>(length: number, value: T): T[];
```

### Configuration Utilities

Functions for resolving and merging configuration options.

```javascript { .api }
/**
 * Resolve scriptable options
 * @param inputs - Option inputs to resolve
 * @param context - Resolution context
 * @param index - Data index
 * @param info - Additional info object
 * @returns Resolved value
 */
function resolve<T>(inputs: T[], context?: object, index?: number, info?: object): T;

/**
 * Merge objects conditionally
 * @param target - Target object
 * @param source - Source object
 * @returns Merged object
 */
function mergeIf(target: object, source: object): object;

/**
 * Deep merge objects
 * @param target - Target object
 * @param source - Source object(s)
 * @returns Merged object
 */
function merge(target: object, ...source: object[]): object;

/**
 * Deep clone object or array
 * @param source - Object to clone
 * @returns Cloned object
 */
function clone<T>(source: T): T;
```

### DOM Utilities

Functions for DOM element manipulation and event handling.

```javascript { .api }
/**
 * Get canvas element from various inputs
 * @param item - Canvas, context, or selector
 * @returns Canvas element
 */
function getCanvas(item: string | HTMLCanvasElement | CanvasRenderingContext2D): HTMLCanvasElement;

/**
 * Get relative position of event within chart
 * @param event - DOM event
 * @param chart - Chart instance
 * @returns Relative coordinates
 */
function getRelativePosition(event: Event, chart: Chart): Point;

/**
 * Calculate maximum size for canvas
 * @param canvas - Canvas element
 * @param width - Desired width
 * @param height - Desired height
 * @param aspectRatio - Aspect ratio to maintain
 * @returns Maximum size object
 */
function getMaximumSize(canvas: HTMLCanvasElement, width?: number, height?: number, aspectRatio?: number): Size;

/**
 * Get device pixel ratio
 * @returns Device pixel ratio
 */
function getDevicePixelRatio(): number;

/**
 * Add event listener with options
 * @param element - DOM element
 * @param type - Event type
 * @param listener - Event listener
 * @param options - Event options
 */
function addEventListener(element: Element, type: string, listener: EventListener, options?: AddEventListenerOptions): void;

/**
 * Remove event listener
 * @param element - DOM element  
 * @param type - Event type
 * @param listener - Event listener
 */
function removeEventListener(element: Element, type: string, listener: EventListener): void;
```

### Math Utilities

Mathematical helper functions for calculations.

```javascript { .api }
/**
 * Check if two numbers are approximately equal
 * @param x - First number
 * @param y - Second number
 * @param epsilon - Tolerance
 * @returns True if approximately equal
 */
function almostEquals(x: number, y: number, epsilon: number): boolean;

/**
 * Check if number is almost a whole number
 * @param x - Number to check
 * @param epsilon - Tolerance
 * @returns True if almost whole
 */
function almostWhole(x: number, epsilon: number): boolean;

/**
 * Convert degrees to radians
 * @param degrees - Angle in degrees
 * @returns Angle in radians
 */
function toRadians(degrees: number): number;

/**
 * Convert radians to degrees
 * @param radians - Angle in radians
 * @returns Angle in degrees
 */
function toDegrees(radians: number): number;

/**
 * Calculate distance between two points
 * @param pt1 - First point
 * @param pt2 - Second point
 * @returns Distance
 */
function distanceBetweenPoints(pt1: Point, pt2: Point): number;

/**
 * Linear interpolation between values
 * @param a - Start value
 * @param b - End value
 * @param t - Interpolation factor (0-1)
 * @returns Interpolated value
 */
function lerp(a: number, b: number, t: number): number;

/**
 * Get angle of line between two points
 * @param pt1 - First point
 * @param pt2 - Second point
 * @returns Angle in radians
 */
function getAngleFromPoint(pt1: Point, pt2: Point): number;
```

### RTL (Right-to-Left) Utilities

Functions for right-to-left text support.

```javascript { .api }
/**
 * Get RTL helper for canvas
 * @param rtl - RTL mode
 * @param canvas - Canvas element
 * @returns RTL helper object
 */
function getRtlHelper(rtl: boolean, canvas: HTMLCanvasElement): RtlHelper;

interface RtlHelper {
  x(x: number): number;
  setWidth(width: number): void;
  textAlign(align: string): string;
  xPlus(x: number, value: number): number;
  leftForLtr(x: number, itemWidth: number): number;
}
```

### Interpolation Utilities

Functions for value interpolation and animation.

```javascript { .api }
/**
 * Interpolate between objects
 * @param from - Start object
 * @param to - End object
 * @param factor - Interpolation factor (0-1)
 * @returns Interpolated object
 */
function interpolate<T>(from: T, to: T, factor: number): T;

/**
 * Get interpolator function for property
 * @param property - Property name
 * @returns Interpolator function
 */
function getInterpolator(property: string): (from: unknown, to: unknown, factor: number) => unknown;
```

## Helper Module Access

All helpers are available through the helpers namespace:

```javascript { .api }
import { helpers } from 'chart.js';

// Access utilities via helpers object
const { color, isArray, clearCanvas } = helpers;

// Or import specific helpers
import { color, isArray, clearCanvas } from 'chart.js/helpers';
```

## Types

```javascript { .api }
interface Point {
  x: number;
  y: number;
}

interface Size {
  width: number;
  height: number;
}

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

interface Color {
  r: number;
  g: number;
  b: number;
  a: number;
}

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

interface PointOptions {
  pointStyle: PointStyle | HTMLImageElement | HTMLCanvasElement;
  radius: number;
  backgroundColor?: Color;
  borderColor?: Color;
  borderWidth?: number;
  rotation?: number;
}

interface TextOptions {
  color?: Color;
  font?: FontSpec;
  textAlign?: CanvasTextAlign;
  textBaseline?: CanvasTextBaseline;
  rotation?: number;
}

type PointStyle = 'circle' | 'cross' | 'crossRot' | 'dash' | 'line' | 'rect' | 'rectRounded' | 'rectRot' | 'star' | 'triangle';
```