CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-plotly-js

The open source JavaScript graphing library that powers Plotly with comprehensive data visualization capabilities including statistical charts, 3D graphs, scientific visualizations, and interactive plotting features.

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

Overview
Eval results
Files

events.mddocs/

Events and Interactions

Complete event system for handling user interactions, plot updates, and custom behaviors.

Capabilities

Event Management

Methods for adding, removing, and managing event listeners on plots.

/**
 * Event listener management methods
 */
interface EventMethods {
  /**
   * Add event listener to plot
   * @param event - Event name
   * @param handler - Event handler function
   */
  on(event: string, handler: Function): void;

  /**
   * Add one-time event listener
   * @param event - Event name
   * @param handler - Event handler function that will be called only once
   */
  once(event: string, handler: Function): void;

  /**
   * Remove specific event listener
   * @param event - Event name
   * @param handler - Specific handler function to remove
   */
  removeListener(event: string, handler: Function): void;

  /**
   * Remove all listeners for a specific event
   * @param event - Event name
   */
  removeAllListeners(event: string): void;

  /**
   * Emit/trigger an event
   * @param event - Event name
   * @param data - Event data to pass to handlers
   */
  emit(event: string, data?: any): void;
}

Usage Examples:

// Add event listener
const myDiv = document.getElementById('myDiv');

myDiv.on('plotly_click', function(data) {
    console.log('Plot clicked:', data);
});

// One-time listener
myDiv.once('plotly_afterplot', function() {
    console.log('Plot created for the first time');
});

// Remove specific listener
function clickHandler(data) {
    console.log('Clicked:', data);
}
myDiv.on('plotly_click', clickHandler);
myDiv.removeListener('plotly_click', clickHandler);

// Remove all listeners for an event
myDiv.removeAllListeners('plotly_hover');

Plot Lifecycle Events

Events that fire during plot creation, updates, and destruction.

/**
 * Plot lifecycle event names and their data structures
 */
interface PlotLifecycleEvents {
  'plotly_beforeplot': {};
  'plotly_afterplot': {};
  'plotly_redraw': {};
  'plotly_restyle': {
    data: any[];
    traces: number[];
  };
  'plotly_relayout': {
    layout: Partial<Layout>;
  };
  'plotly_update': {
    data: any[];
    layout: Partial<Layout>;
    traces: number[];
  };
  'plotly_react': {
    data: any[];
    layout: Partial<Layout>;
  };
  'plotly_framework': any;
  'plotly_purge': {};
}

Usage Examples:

// Listen for plot creation
myDiv.on('plotly_afterplot', function() {
    console.log('Plot has been created');
    // Initialize any custom behaviors
});

// Listen for restyle events
myDiv.on('plotly_restyle', function(eventData) {
    console.log('Traces restyled:', eventData.traces);
    console.log('Update data:', eventData.data);
});

// Listen for layout changes
myDiv.on('plotly_relayout', function(eventData) {
    console.log('Layout updated:', eventData.layout);
    if (eventData.layout['xaxis.range']) {
        console.log('X-axis range changed');
    }
});

// Listen for combined updates
myDiv.on('plotly_update', function(eventData) {
    console.log('Plot updated');
    console.log('Data changes:', eventData.data);
    console.log('Layout changes:', eventData.layout);
});

User Interaction Events

Events triggered by user interactions with the plot.

/**
 * User interaction event data structures
 */
interface InteractionEvents {
  'plotly_click': {
    points: PlotlyClickPoint[];
    event: MouseEvent;
  };
  'plotly_hover': {
    points: PlotlyHoverPoint[];
    event: MouseEvent;
    xpx: number;
    ypx: number;
  };
  'plotly_unhover': {
    points: PlotlyHoverPoint[];
    event: MouseEvent;
  };
  'plotly_selected': {
    points: PlotlySelectedPoint[];
    selection?: SelectionRange;
  };
  'plotly_deselect': {};
  'plotly_brushing': {
    range: BrushRange;
  };
  'plotly_brushed': {
    range: BrushRange;
  };
  'plotly_doubleclick': {};
  'plotly_zoom': {};
  'plotly_pan': {};
}

interface PlotlyClickPoint {
  curveNumber: number;
  pointNumber: number | number[];
  pointIndex: number;
  x: any;
  y: any;
  z?: any;
  data: any;
  fullData: any;
  xaxis: any;
  yaxis: any;
}

interface PlotlyHoverPoint extends PlotlyClickPoint {
  bbox: {
    x0: number;
    x1: number;
    y0: number;
    y1: number;
  };
  distance: number;
}

interface PlotlySelectedPoint extends PlotlyClickPoint {
  selected?: boolean;
}

interface SelectionRange {
  x: [number, number];
  y: [number, number];
}

interface BrushRange {
  x: [number, number];
  y: [number, number];
}

Usage Examples:

// Handle click events
myDiv.on('plotly_click', function(data) {
    const point = data.points[0];
    console.log('Clicked point:', {
        trace: point.curveNumber,
        index: point.pointNumber,
        x: point.x,
        y: point.y
    });
    
    // Highlight clicked point
    Plotly.restyle(myDiv, {
        'marker.color': 'red'
    }, [point.curveNumber]);
});

// Handle hover events
myDiv.on('plotly_hover', function(data) {
    const point = data.points[0];
    console.log('Hovering over:', point.x, point.y);
    
    // Update external display
    document.getElementById('info').innerHTML = 
        `Value: ${point.y} at ${point.x}`;
});

myDiv.on('plotly_unhover', function() {
    document.getElementById('info').innerHTML = '';
});

// Handle selection events
myDiv.on('plotly_selected', function(data) {
    console.log('Selected points:', data.points.length);
    
    if (data.points.length > 0) {
        const selectedData = data.points.map(pt => ({
            x: pt.x,
            y: pt.y,
            trace: pt.curveNumber
        }));
        console.log('Selected data:', selectedData);
    }
});

// Handle brush selection
myDiv.on('plotly_brushed', function(data) {
    console.log('Brushed area:', data.range);
    
    // Filter data in another chart based on selection
    const xRange = data.range.x;
    const yRange = data.range.y;
    
    // Update related visualization
    updateSecondaryChart(xRange, yRange);
});

Animation Events

Events related to plot animations and frame transitions.

/**
 * Animation event data structures
 */
interface AnimationEvents {
  'plotly_animating': {};
  'plotly_animatingframe': {
    frame: any;
    animation: any;
  };
  'plotly_animated': {};
  'plotly_animationinterrupted': {};
}

Usage Examples:

// Track animation progress
myDiv.on('plotly_animating', function() {
    console.log('Animation started');
    document.getElementById('status').innerHTML = 'Animating...';
});

myDiv.on('plotly_animatingframe', function(data) {
    console.log('Frame:', data.frame.name);
});

myDiv.on('plotly_animated', function() {
    console.log('Animation completed');
    document.getElementById('status').innerHTML = 'Complete';
});

// Handle interrupted animations
myDiv.on('plotly_animationinterrupted', function() {
    console.log('Animation was interrupted');
    document.getElementById('status').innerHTML = 'Interrupted';
});

Programmatic Hover and Interaction

Methods for triggering hover effects and interactions programmatically.

/**
 * Programmatic interaction methods
 */
interface ProgrammaticInteractions {
  /**
   * Trigger hover effect on specific points
   * @param gd - Graph div element
   * @param hoverData - Array of points to hover over
   * @param hoverOpts - Hover options and styling
   */
  hover(gd: any, hoverData: HoverData[], hoverOpts?: HoverOptions): void;

  /**
   * Clear all hover effects
   * @param gd - Graph div element
   */
  unhover(gd: any): void;

  /**
   * Create standalone hover box (not attached to plot)
   * @param hoverData - Hover data for the box
   * @param opts - Positioning and styling options
   */
  loneHover(hoverData: HoverData, opts: LoneHoverOptions): HTMLElement;

  /**
   * Remove standalone hover box
   * @param container - Container element with hover box
   */
  loneUnhover(container: HTMLElement): void;
}

interface HoverData {
  curveNumber: number;
  pointNumber: number;
  x?: any;
  y?: any;
  z?: any;
}

interface HoverOptions {
  xpx?: number;
  ypx?: number;
  hovermode?: 'closest' | 'x' | 'y' | 'x unified' | 'y unified';
}

interface LoneHoverOptions {
  container: HTMLElement;
  x0: number;
  x1: number;
  y0: number;
  y1: number;
  anchorX?: number;
  anchorY?: number;
  colorIndex?: number;
}

Usage Examples:

// Programmatically trigger hover
function highlightPoint(traceIndex, pointIndex) {
    Plotly.Fx.hover(myDiv, [{
        curveNumber: traceIndex,
        pointNumber: pointIndex
    }]);
}

// Clear hover
function clearHighlight() {
    Plotly.Fx.unhover(myDiv);
}

// Create standalone hover box
function showCustomTooltip(x, y, text) {
    const container = document.getElementById('tooltip-container');
    
    Plotly.Fx.loneHover({
        x: x,
        y: y,
        text: text,
        color: 'blue'
    }, {
        container: container,
        x0: 100,
        x1: 200,
        y0: 50,
        y1: 100
    });
}

// Remove standalone hover
function hideCustomTooltip() {
    const container = document.getElementById('tooltip-container');
    Plotly.Fx.loneUnhover(container);
}

Custom Event Handlers

Examples of common event handling patterns and custom behaviors.

Usage Examples:

// Cross-filter pattern - link multiple charts
function linkCharts(chart1, chart2) {
    chart1.on('plotly_selected', function(data) {
        if (data.points.length > 0) {
            const selectedIds = data.points.map(pt => pt.customdata);
            
            // Filter second chart based on selection
            const filteredTrace = filterTraceByIds(chart2Data, selectedIds);
            Plotly.react(chart2, [filteredTrace], chart2Layout);
        }
    });
    
    chart1.on('plotly_deselect', function() {
        // Reset second chart
        Plotly.react(chart2, chart2Data, chart2Layout);
    });
}

// Zoom synchronization between charts
function synchronizeZoom(chart1, chart2) {
    chart1.on('plotly_relayout', function(eventData) {
        if (eventData['xaxis.range[0]'] !== undefined) {
            Plotly.relayout(chart2, {
                'xaxis.range': eventData['xaxis.range']
            });
        }
    });
    
    chart2.on('plotly_relayout', function(eventData) {
        if (eventData['xaxis.range[0]'] !== undefined) {
            Plotly.relayout(chart1, {
                'xaxis.range': eventData['xaxis.range']
            });
        }
    });
}

// Custom click behavior - drill down
myDiv.on('plotly_click', function(data) {
    const point = data.points[0];
    
    if (point.customdata && point.customdata.drillDown) {
        // Load drill-down data
        loadDrillDownData(point.customdata.category)
            .then(newData => {
                Plotly.react(myDiv, newData, newLayout);
            });
    }
});

// Responsive behavior on window resize
window.addEventListener('resize', function() {
    Plotly.Plots.resize(myDiv);
});

// Custom selection behavior
myDiv.on('plotly_selected', function(data) {
    if (data.points.length > 0) {
        // Calculate statistics for selected points
        const values = data.points.map(pt => pt.y);
        const stats = {
            count: values.length,
            sum: values.reduce((a, b) => a + b, 0),
            mean: values.reduce((a, b) => a + b, 0) / values.length,
            min: Math.min(...values),
            max: Math.max(...values)
        };
        
        // Update statistics display
        updateStatsDisplay(stats);
    }
});

Event Data Reference

Common Event Properties

/**
 * Common properties available in most event data objects
 */
interface BaseEventData {
  event?: MouseEvent | TouchEvent;
  points?: PlotlyPoint[];
  range?: any;
  lassoPoints?: any;
}

interface PlotlyPoint {
  curveNumber: number;
  pointNumber: number | number[];
  pointIndex: number;
  x: any;
  y: any;
  z?: any;
  data: any;
  fullData: any;
  xaxis: any;
  yaxis: any;
  bbox?: {
    x0: number;
    x1: number;
    y0: number;
    y1: number;
  };
  distance?: number;
  customdata?: any;
  text?: string;
  hovertext?: string;
}

Event Timing and Performance

/**
 * Event timing considerations and performance options
 */
interface EventTiming {
  // Debounce hover events for performance
  hoverDebounce?: number;
  
  // Throttle selection events
  selectionThrottle?: number;
  
  // Disable events for performance
  staticPlot?: boolean;
}

Usage Examples:

// Debounced hover handler for performance
let hoverTimeout;
myDiv.on('plotly_hover', function(data) {
    clearTimeout(hoverTimeout);
    hoverTimeout = setTimeout(() => {
        // Process hover data
        processHoverData(data);
    }, 100);
});

// Throttled selection handler
let lastSelectionTime = 0;
myDiv.on('plotly_selected', function(data) {
    const now = Date.now();
    if (now - lastSelectionTime > 200) {
        processSelection(data);
        lastSelectionTime = now;
    }
});

Install with Tessl CLI

npx tessl i tessl/npm-plotly-js

docs

3d-charts.md

basic-charts.md

core-plotting.md

events.md

export-utilities.md

index.md

layout.md

statistical-charts.md

tile.json