or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

axes.mdbar-charts.mdevents.mdindex.mdinterpolation.mdline-charts.mdpie-charts.mdsvg-utilities.mdutils.md
tile.json

events.mddocs/

Event System

Chartist provides a comprehensive event system built on the EventEmitter class that allows developers to hook into chart lifecycle events, drawing operations, and user interactions. This enables custom animations, styling, and behavior modifications.

Capabilities

EventEmitter Class

Core event system class providing event registration, removal, and emission capabilities.

/**
 * Event emitter class for handling chart events
 */
class EventEmitter {
  /** Register event listener for specific event */
  on(event: string, listener: EventListener): EventEmitter;
  
  /** Register catch-all event listener for any event */
  on(event: '*', listener: AllEventsListener): EventEmitter;
  
  /** Remove event listener */
  off(event: string, listener?: EventListener): EventEmitter;
  
  /** Emit event with optional data */
  emit<T>(event: string, data: T): void;
}

type EventListener<T = any> = (data: T) => void;
type AllEventsListener<T = any> = (data: T) => void;

Chart Lifecycle Events

Events that occur during chart creation and updates.

interface ChartCreatedEvent {
  type: 'created';
  svg: Svg;
  options: any;
  responsiveOptions: ResponsiveOptions[];
}

interface ChartDataEvent {
  type: 'data';
  data: ChartData;
}

interface ChartOptionsChangedEvent {
  type: 'optionsChanged';
  previousOptions: any;
  currentOptions: any;
}

interface ChartResponsiveEvent {
  type: 'responsiveOptionsChanged';
  previousResponsiveOptions: ResponsiveOptions[];
  currentResponsiveOptions: ResponsiveOptions[];
}

Usage Examples:

import { LineChart } from "chartist";

const chart = new LineChart('.chart-container', data, options);

// Handle chart creation
chart.on('created', (data: ChartCreatedEvent) => {
  console.log('Chart created with SVG:', data.svg);
  console.log('Chart options:', data.options);
  
  // Add custom elements after creation
  data.svg.elem('text', {
    x: 10,
    y: 20,
    'font-size': '14px'
  }).text('Custom Title');
});

// Handle data updates
chart.on('data', (data: ChartDataEvent) => {
  console.log('Chart data updated:', data.data);
});

// Handle responsive changes
chart.on('responsiveOptionsChanged', (data: ChartResponsiveEvent) => {
  console.log('Responsive options changed');
  console.log('Previous:', data.previousResponsiveOptions);
  console.log('Current:', data.currentResponsiveOptions);
});

Drawing Events

Events fired during the drawing process for each chart element.

interface DrawEvent {
  type: 'draw';
  element: Svg;
  group: Svg;
  series: SeriesObject;
  seriesIndex: number;
  meta: any;
}

interface GridDrawEvent extends DrawEvent {
  axis: Axis;
  index: number;
  position: { x1: number; y1: number; x2: number; y2: number };
}

interface LabelDrawEvent extends DrawEvent {
  text: string;
  width: number;
  height: number;
  x: number;
  y: number;
  index: number;
  axis: Axis;
}

Usage Examples:

// Customize grid lines
chart.on('draw', (data: GridDrawEvent) => {
  if (data.type === 'grid') {
    // Style major grid lines differently
    if (data.index % 2 === 0) {
      data.element.attr({
        'stroke-width': '2px',
        'stroke': '#333'
      });
    } else {
      data.element.attr({
        'stroke-width': '1px',
        'stroke': '#ccc',
        'stroke-dasharray': '2,2'
      });
    }
  }
});

// Customize labels
chart.on('draw', (data: LabelDrawEvent) => {
  if (data.type === 'label') {
    // Rotate X-axis labels
    if (data.axis.axisUnit === axisUnits.x) {
      data.element.attr({
        'transform': `rotate(-45 ${data.x} ${data.y})`
      });
    }
    
    // Format Y-axis labels
    if (data.axis.axisUnit === axisUnits.y) {
      data.element.text(`$${data.text}`);
    }
  }
});

Animation Events

Events related to chart animations and transitions.

interface AnimationBeginEvent {
  type: 'animationBegin';
  element: Svg;
  animate: any;
  easing: string | Function;
  from: any;
  to: any;
  duration: number;
}

interface AnimationEndEvent {
  type: 'animationEnd';
  element: Svg;
}

Usage Examples:

// Handle animation lifecycle
chart.on('animationBegin', (data: AnimationBeginEvent) => {
  console.log('Animation started on:', data.element);
  console.log('Duration:', data.duration);
  console.log('Easing:', data.easing);
});

chart.on('animationEnd', (data: AnimationEndEvent) => {
  console.log('Animation completed on:', data.element);
  
  // Chain additional animations
  data.element.animate({
    'stroke-width': '3px'
  }, 200, 'easeOutQuart');
});

Chart-Specific Draw Events

Each chart type has specific draw events for its elements.

Line Chart Events

interface LineDrawEvent extends DrawEvent {
  path: SvgPath;
  chartRect: ChartRect;
  values: number[];
}

interface AreaDrawEvent extends DrawEvent {
  path: SvgPath;
  chartRect: ChartRect;
  values: number[];
}

interface PointDrawEvent extends DrawEvent {
  x: number;
  y: number;
  value: number;
  chartRect: ChartRect;
  index: number;
}

Bar Chart Events

interface BarDrawEvent extends DrawEvent {
  x1: number;
  y1: number;
  x2: number;
  y2: number;
  chartRect: ChartRect;
  value: number;
  index: number;
}

Pie Chart Events

interface SliceDrawEvent extends DrawEvent {
  path: SvgPath;
  center: { x: number; y: number };
  radius: number;
  startAngle: number;
  endAngle: number;
  totalAngle: number;
  value: number;
  index: number;
}

Event-Driven Animations

Create sophisticated animations using draw events:

const chart = new LineChart('.chart-container', data, options);

// Animate line drawing
chart.on('draw', (data) => {
  if (data.type === 'line' || data.type === 'area') {
    const pathLength = data.element._node.getTotalLength();
    
    data.element.attr({
      'stroke-dasharray': pathLength + 'px ' + pathLength + 'px',
      'stroke-dashoffset': pathLength + 'px'
    });
    
    data.element.animate({
      'stroke-dashoffset': '0px'
    }, 1000, 'easeOutQuint');
  }
});

// Animate points with staggered timing
chart.on('draw', (data) => {
  if (data.type === 'point') {
    const seq = data.index;
    const delays = 80;
    
    data.element.attr({
      'stroke-width': '10px',
      'stroke-opacity': 0
    });
    
    setTimeout(() => {
      data.element.animate({
        'stroke-width': '3px',
        'stroke-opacity': 1
      }, 300, 'easeOutQuart');
    }, seq * delays);
  }
});

Custom Event Handling

Create custom event handlers for specific interactions:

class CustomChart extends LineChart {
  constructor(query, data, options, responsiveOptions) {
    super(query, data, options, responsiveOptions);
    
    // Add custom event
    this.on('pointHover', this.handlePointHover.bind(this));
  }
  
  handlePointHover(data) {
    // Custom hover logic
    console.log('Point hovered:', data);
    
    // Emit custom event
    this.emit('customPointHover', {
      value: data.value,
      index: data.index,
      timestamp: Date.now()
    });
  }
}

const customChart = new CustomChart('.chart-container', data, options);

customChart.on('customPointHover', (data) => {
  console.log('Custom point hover event:', data);
});

Event Cleanup

Properly remove event listeners to prevent memory leaks:

const chart = new LineChart('.chart-container', data, options);

// Store reference to listener
const drawListener = (data) => {
  console.log('Draw event:', data.type);
};

// Add listener
chart.on('draw', drawListener);

// Remove specific listener
chart.off('draw', drawListener);

// Remove all listeners for an event
chart.off('draw');

// Clean up when chart is destroyed
function destroyChart() {
  chart.off(); // Remove all listeners
  chart.detach(); // Clean up chart
}

Event Debugging

Debug events and their data:

const chart = new LineChart('.chart-container', data, options);

// Log all events
['created', 'draw', 'animationBegin', 'animationEnd'].forEach(eventType => {
  chart.on(eventType, (data) => {
    console.log(`Event: ${eventType}`, data);
  });
});

// Conditional event handling
chart.on('draw', (data) => {
  if (data.type === 'point' && data.value > 100) {
    console.log('High value point:', data);
    data.element.addClass('high-value');
  }
});