JavaScript data visualization library for creating interactive charts, graphs, and scientific visualizations
81
Functions for adding, removing, and reordering traces in existing plots. These functions allow dynamic manipulation of plot data series without recreating the entire plot.
Adds new traces to an existing plot at specified positions.
/**
* Adds new traces to an existing plot
* @param graphDiv - DOM element ID (string) or element reference
* @param traces - Single trace object or array of trace objects to add
* @param newIndices - Position(s) to insert traces (optional, defaults to end)
* @returns Promise that resolves to the graph div element
*/
function addTraces(
graphDiv: string | HTMLElement,
traces: Partial<PlotlyTrace> | Partial<PlotlyTrace>[],
newIndices?: number | number[]
): Promise<HTMLElement>;Usage Examples:
import Plotly from 'plotly.js-dist';
// Add a single trace to the end
const newTrace = {
x: [1, 2, 3, 4],
y: [5, 6, 7, 8],
type: 'scatter',
name: 'New Series'
};
await Plotly.addTraces('chart', newTrace);
// Add multiple traces
const newTraces = [
{
x: [1, 2, 3],
y: [10, 11, 12],
type: 'bar',
name: 'Bar Series'
},
{
x: [1, 2, 3],
y: [2, 4, 6],
type: 'scatter',
mode: 'lines',
name: 'Line Series'
}
];
await Plotly.addTraces('chart', newTraces);
// Add trace at specific position (index 1)
await Plotly.addTraces('chart', newTrace, 1);
// Add multiple traces at specific positions
await Plotly.addTraces('chart', newTraces, [0, 2]);
// Add trace with complex configuration
const complexTrace = {
x: [1, 2, 3, 4, 5],
y: [10, 15, 13, 17, 20],
type: 'scatter',
mode: 'lines+markers',
name: 'Complex Series',
line: {
color: 'rgb(255, 127, 14)',
width: 3
},
marker: {
color: 'rgba(255, 127, 14, 0.8)',
size: 8,
symbol: 'circle'
},
hovertemplate: 'X: %{x}<br>Y: %{y}<extra></extra>'
};
await Plotly.addTraces('chart', complexTrace);Removes traces from an existing plot by their indices.
/**
* Removes traces from an existing plot
* @param graphDiv - DOM element ID (string) or element reference
* @param indices - Single trace index or array of trace indices to remove
* @returns Promise that resolves to the graph div element
*/
function deleteTraces(
graphDiv: string | HTMLElement,
indices: number | number[]
): Promise<HTMLElement>;Usage Examples:
// Remove single trace by index
await Plotly.deleteTraces('chart', 0); // Remove first trace
// Remove multiple traces
await Plotly.deleteTraces('chart', [0, 2, 4]); // Remove traces at indices 0, 2, and 4
// Remove last trace
const currentTraces = document.getElementById('chart').data.length;
await Plotly.deleteTraces('chart', currentTraces - 1);
// Remove all traces except the first one
const totalTraces = document.getElementById('chart').data.length;
const indicesToRemove = Array.from({length: totalTraces - 1}, (_, i) => i + 1);
await Plotly.deleteTraces('chart', indicesToRemove);
// Conditional removal based on trace properties
const chartDiv = document.getElementById('chart');
const tracesToRemove = [];
chartDiv.data.forEach((trace, index) => {
if (trace.name && trace.name.includes('temporary')) {
tracesToRemove.push(index);
}
});
if (tracesToRemove.length > 0) {
await Plotly.deleteTraces('chart', tracesToRemove);
}Reorders traces in an existing plot by moving them to new positions.
/**
* Reorders traces in an existing plot
* @param graphDiv - DOM element ID (string) or element reference
* @param currentIndices - Current position(s) of traces to move
* @param newIndices - New position(s) for the traces (optional, defaults to end)
* @returns Promise that resolves to the graph div element
*/
function moveTraces(
graphDiv: string | HTMLElement,
currentIndices: number | number[],
newIndices?: number | number[]
): Promise<HTMLElement>;Usage Examples:
// Move single trace to end
await Plotly.moveTraces('chart', 0); // Move first trace to end
// Move trace to specific position
await Plotly.moveTraces('chart', 2, 0); // Move trace from index 2 to index 0
// Move multiple traces
await Plotly.moveTraces('chart', [0, 1], [2, 3]); // Move traces 0,1 to positions 2,3
// Swap two traces
await Plotly.moveTraces('chart', [0, 1], [1, 0]);
// Move trace to second position
await Plotly.moveTraces('chart', 3, 1); // Move trace from index 3 to index 1
// Reorder multiple traces to end
await Plotly.moveTraces('chart', [1, 3, 5]); // Move traces 1, 3, 5 to end// Create traces based on data categories
const categories = ['A', 'B', 'C'];
const colors = ['red', 'blue', 'green'];
const traces = categories.map((category, index) => ({
x: data.filter(d => d.category === category).map(d => d.x),
y: data.filter(d => d.category === category).map(d => d.y),
type: 'scatter',
mode: 'markers',
name: `Category ${category}`,
marker: { color: colors[index] }
}));
await Plotly.addTraces('chart', traces);class TraceManager {
constructor(chartId) {
this.chartId = chartId;
this.traceIds = new Map(); // Map custom IDs to plot indices
}
async addTrace(customId, traceData) {
await Plotly.addTraces(this.chartId, traceData);
const chartDiv = document.getElementById(this.chartId);
const newIndex = chartDiv.data.length - 1;
this.traceIds.set(customId, newIndex);
}
async removeTrace(customId) {
const index = this.traceIds.get(customId);
if (index !== undefined) {
await Plotly.deleteTraces(this.chartId, index);
this.traceIds.delete(customId);
// Update remaining indices
this.traceIds.forEach((value, key) => {
if (value > index) {
this.traceIds.set(key, value - 1);
}
});
}
}
async updateTrace(customId, updates) {
const index = this.traceIds.get(customId);
if (index !== undefined) {
await Plotly.restyle(this.chartId, updates, index);
}
}
}// Toggle traces based on user selection
async function toggleTracesByCategory(category, visible) {
const chartDiv = document.getElementById('chart');
const indicesToUpdate = [];
chartDiv.data.forEach((trace, index) => {
if (trace.name && trace.name.includes(category)) {
indicesToUpdate.push(index);
}
});
const visibility = visible ? true : 'legendonly';
await Plotly.restyle('chart', {'visible': visibility}, indicesToUpdate);
}
// Show only top N traces by some metric
async function showTopTraces(n, sortBy = 'max') {
const chartDiv = document.getElementById('chart');
const traceMetrics = chartDiv.data.map((trace, index) => ({
index,
metric: sortBy === 'max' ? Math.max(...trace.y) : trace.y.reduce((a, b) => a + b, 0)
}));
traceMetrics.sort((a, b) => b.metric - a.metric);
const topIndices = traceMetrics.slice(0, n).map(t => t.index);
const hiddenIndices = traceMetrics.slice(n).map(t => t.index);
if (hiddenIndices.length > 0) {
await Plotly.restyle('chart', {'visible': 'legendonly'}, hiddenIndices);
}
if (topIndices.length > 0) {
await Plotly.restyle('chart', {'visible': true}, topIndices);
}
}Trace management functions emit specific events:
interface TraceEvents {
'plotly_traceadded': (eventData: { traceIndices: number[] }) => void;
'plotly_tracedeleted': (eventData: { traceIndices: number[] }) => void;
'plotly_tracesmoved': (eventData: {
previousIndices: number[];
currentIndices: number[];
}) => void;
}Usage Examples:
const chartDiv = document.getElementById('my-chart');
chartDiv.on('plotly_traceadded', (eventData) => {
console.log('Traces added at indices:', eventData.traceIndices);
});
chartDiv.on('plotly_tracedeleted', (eventData) => {
console.log('Traces deleted from indices:', eventData.traceIndices);
});
chartDiv.on('plotly_tracesmoved', (eventData) => {
console.log('Traces moved:', {
from: eventData.previousIndices,
to: eventData.currentIndices
});
});// Handle invalid trace indices
try {
await Plotly.deleteTraces('chart', [0, 1, 2]);
} catch (error) {
if (error.message.includes('index')) {
console.error('Invalid trace index specified');
}
}
// Validate trace data before adding
function validateTrace(trace) {
if (!trace.type) {
throw new Error('Trace must have a type');
}
if (trace.type === 'scatter' && (!trace.x || !trace.y)) {
throw new Error('Scatter traces must have x and y data');
}
return true;
}
try {
validateTrace(newTrace);
await Plotly.addTraces('chart', newTrace);
} catch (error) {
console.error('Invalid trace data:', error.message);
}moveTraces() instead of delete + add for reorderingvisible: 'legendonly' instead of deleting traces if they might be needed againreact() with a complete data arrayinterface PlotlyTrace {
type: string;
name?: string;
visible?: boolean | 'legendonly';
showlegend?: boolean;
x?: any[];
y?: any[];
z?: any[];
mode?: string;
marker?: MarkerConfig;
line?: LineConfig;
fill?: string;
fillcolor?: string;
opacity?: number;
hovertemplate?: string;
customdata?: any[];
meta?: any;
uid?: string;
[key: string]: any;
}
interface MarkerConfig {
color?: string | string[];
size?: number | number[];
symbol?: string | string[];
opacity?: number | number[];
line?: {
color?: string | string[];
width?: number | number[];
};
}
interface LineConfig {
color?: string;
width?: number;
dash?: string;
shape?: string;
smoothing?: number;
}Install with Tessl CLI
npx tessl i tessl/npm-plotly-js-distdocs
evals
scenario-1
scenario-2
scenario-3
scenario-4
scenario-5
scenario-6
scenario-7
scenario-8
scenario-9
scenario-10