or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

animation.mdchart-types.mdcore-plotting.mddata-streaming.mddata-updates.mdexport-utilities.mdindex.mdinteractive-components.mdlayout-system.mdtrace-management.md

trace-management.mddocs/

0

# Trace Management

1

2

Functions for adding, removing, and reordering traces in existing plots. These functions allow dynamic manipulation of plot data series without recreating the entire plot.

3

4

## Capabilities

5

6

### addTraces

7

8

Adds new traces to an existing plot at specified positions.

9

10

```javascript { .api }

11

/**

12

* Adds new traces to an existing plot

13

* @param graphDiv - DOM element ID (string) or element reference

14

* @param traces - Single trace object or array of trace objects to add

15

* @param newIndices - Position(s) to insert traces (optional, defaults to end)

16

* @returns Promise that resolves to the graph div element

17

*/

18

function addTraces(

19

graphDiv: string | HTMLElement,

20

traces: Partial<PlotlyTrace> | Partial<PlotlyTrace>[],

21

newIndices?: number | number[]

22

): Promise<HTMLElement>;

23

```

24

25

**Usage Examples:**

26

27

```javascript

28

import Plotly from 'plotly.js-dist';

29

30

// Add a single trace to the end

31

const newTrace = {

32

x: [1, 2, 3, 4],

33

y: [5, 6, 7, 8],

34

type: 'scatter',

35

name: 'New Series'

36

};

37

await Plotly.addTraces('chart', newTrace);

38

39

// Add multiple traces

40

const newTraces = [

41

{

42

x: [1, 2, 3],

43

y: [10, 11, 12],

44

type: 'bar',

45

name: 'Bar Series'

46

},

47

{

48

x: [1, 2, 3],

49

y: [2, 4, 6],

50

type: 'scatter',

51

mode: 'lines',

52

name: 'Line Series'

53

}

54

];

55

await Plotly.addTraces('chart', newTraces);

56

57

// Add trace at specific position (index 1)

58

await Plotly.addTraces('chart', newTrace, 1);

59

60

// Add multiple traces at specific positions

61

await Plotly.addTraces('chart', newTraces, [0, 2]);

62

63

// Add trace with complex configuration

64

const complexTrace = {

65

x: [1, 2, 3, 4, 5],

66

y: [10, 15, 13, 17, 20],

67

type: 'scatter',

68

mode: 'lines+markers',

69

name: 'Complex Series',

70

line: {

71

color: 'rgb(255, 127, 14)',

72

width: 3

73

},

74

marker: {

75

color: 'rgba(255, 127, 14, 0.8)',

76

size: 8,

77

symbol: 'circle'

78

},

79

hovertemplate: 'X: %{x}<br>Y: %{y}<extra></extra>'

80

};

81

await Plotly.addTraces('chart', complexTrace);

82

```

83

84

### deleteTraces

85

86

Removes traces from an existing plot by their indices.

87

88

```javascript { .api }

89

/**

90

* Removes traces from an existing plot

91

* @param graphDiv - DOM element ID (string) or element reference

92

* @param indices - Single trace index or array of trace indices to remove

93

* @returns Promise that resolves to the graph div element

94

*/

95

function deleteTraces(

96

graphDiv: string | HTMLElement,

97

indices: number | number[]

98

): Promise<HTMLElement>;

99

```

100

101

**Usage Examples:**

102

103

```javascript

104

// Remove single trace by index

105

await Plotly.deleteTraces('chart', 0); // Remove first trace

106

107

// Remove multiple traces

108

await Plotly.deleteTraces('chart', [0, 2, 4]); // Remove traces at indices 0, 2, and 4

109

110

// Remove last trace

111

const currentTraces = document.getElementById('chart').data.length;

112

await Plotly.deleteTraces('chart', currentTraces - 1);

113

114

// Remove all traces except the first one

115

const totalTraces = document.getElementById('chart').data.length;

116

const indicesToRemove = Array.from({length: totalTraces - 1}, (_, i) => i + 1);

117

await Plotly.deleteTraces('chart', indicesToRemove);

118

119

// Conditional removal based on trace properties

120

const chartDiv = document.getElementById('chart');

121

const tracesToRemove = [];

122

chartDiv.data.forEach((trace, index) => {

123

if (trace.name && trace.name.includes('temporary')) {

124

tracesToRemove.push(index);

125

}

126

});

127

if (tracesToRemove.length > 0) {

128

await Plotly.deleteTraces('chart', tracesToRemove);

129

}

130

```

131

132

### moveTraces

133

134

Reorders traces in an existing plot by moving them to new positions.

135

136

```javascript { .api }

137

/**

138

* Reorders traces in an existing plot

139

* @param graphDiv - DOM element ID (string) or element reference

140

* @param currentIndices - Current position(s) of traces to move

141

* @param newIndices - New position(s) for the traces (optional, defaults to end)

142

* @returns Promise that resolves to the graph div element

143

*/

144

function moveTraces(

145

graphDiv: string | HTMLElement,

146

currentIndices: number | number[],

147

newIndices?: number | number[]

148

): Promise<HTMLElement>;

149

```

150

151

**Usage Examples:**

152

153

```javascript

154

// Move single trace to end

155

await Plotly.moveTraces('chart', 0); // Move first trace to end

156

157

// Move trace to specific position

158

await Plotly.moveTraces('chart', 2, 0); // Move trace from index 2 to index 0

159

160

// Move multiple traces

161

await Plotly.moveTraces('chart', [0, 1], [2, 3]); // Move traces 0,1 to positions 2,3

162

163

// Swap two traces

164

await Plotly.moveTraces('chart', [0, 1], [1, 0]);

165

166

// Move trace to second position

167

await Plotly.moveTraces('chart', 3, 1); // Move trace from index 3 to index 1

168

169

// Reorder multiple traces to end

170

await Plotly.moveTraces('chart', [1, 3, 5]); // Move traces 1, 3, 5 to end

171

```

172

173

## Advanced Trace Management Patterns

174

175

### Dynamic Trace Creation

176

177

```javascript

178

// Create traces based on data categories

179

const categories = ['A', 'B', 'C'];

180

const colors = ['red', 'blue', 'green'];

181

182

const traces = categories.map((category, index) => ({

183

x: data.filter(d => d.category === category).map(d => d.x),

184

y: data.filter(d => d.category === category).map(d => d.y),

185

type: 'scatter',

186

mode: 'markers',

187

name: `Category ${category}`,

188

marker: { color: colors[index] }

189

}));

190

191

await Plotly.addTraces('chart', traces);

192

```

193

194

### Trace Lifecycle Management

195

196

```javascript

197

class TraceManager {

198

constructor(chartId) {

199

this.chartId = chartId;

200

this.traceIds = new Map(); // Map custom IDs to plot indices

201

}

202

203

async addTrace(customId, traceData) {

204

await Plotly.addTraces(this.chartId, traceData);

205

const chartDiv = document.getElementById(this.chartId);

206

const newIndex = chartDiv.data.length - 1;

207

this.traceIds.set(customId, newIndex);

208

}

209

210

async removeTrace(customId) {

211

const index = this.traceIds.get(customId);

212

if (index !== undefined) {

213

await Plotly.deleteTraces(this.chartId, index);

214

this.traceIds.delete(customId);

215

// Update remaining indices

216

this.traceIds.forEach((value, key) => {

217

if (value > index) {

218

this.traceIds.set(key, value - 1);

219

}

220

});

221

}

222

}

223

224

async updateTrace(customId, updates) {

225

const index = this.traceIds.get(customId);

226

if (index !== undefined) {

227

await Plotly.restyle(this.chartId, updates, index);

228

}

229

}

230

}

231

```

232

233

### Conditional Trace Display

234

235

```javascript

236

// Toggle traces based on user selection

237

async function toggleTracesByCategory(category, visible) {

238

const chartDiv = document.getElementById('chart');

239

const indicesToUpdate = [];

240

241

chartDiv.data.forEach((trace, index) => {

242

if (trace.name && trace.name.includes(category)) {

243

indicesToUpdate.push(index);

244

}

245

});

246

247

const visibility = visible ? true : 'legendonly';

248

await Plotly.restyle('chart', {'visible': visibility}, indicesToUpdate);

249

}

250

251

// Show only top N traces by some metric

252

async function showTopTraces(n, sortBy = 'max') {

253

const chartDiv = document.getElementById('chart');

254

const traceMetrics = chartDiv.data.map((trace, index) => ({

255

index,

256

metric: sortBy === 'max' ? Math.max(...trace.y) : trace.y.reduce((a, b) => a + b, 0)

257

}));

258

259

traceMetrics.sort((a, b) => b.metric - a.metric);

260

const topIndices = traceMetrics.slice(0, n).map(t => t.index);

261

const hiddenIndices = traceMetrics.slice(n).map(t => t.index);

262

263

if (hiddenIndices.length > 0) {

264

await Plotly.restyle('chart', {'visible': 'legendonly'}, hiddenIndices);

265

}

266

if (topIndices.length > 0) {

267

await Plotly.restyle('chart', {'visible': true}, topIndices);

268

}

269

}

270

```

271

272

## Event Handling

273

274

Trace management functions emit specific events:

275

276

```javascript { .api }

277

interface TraceEvents {

278

'plotly_traceadded': (eventData: { traceIndices: number[] }) => void;

279

'plotly_tracedeleted': (eventData: { traceIndices: number[] }) => void;

280

'plotly_tracesmoved': (eventData: {

281

previousIndices: number[];

282

currentIndices: number[];

283

}) => void;

284

}

285

```

286

287

**Usage Examples:**

288

289

```javascript

290

const chartDiv = document.getElementById('my-chart');

291

292

chartDiv.on('plotly_traceadded', (eventData) => {

293

console.log('Traces added at indices:', eventData.traceIndices);

294

});

295

296

chartDiv.on('plotly_tracedeleted', (eventData) => {

297

console.log('Traces deleted from indices:', eventData.traceIndices);

298

});

299

300

chartDiv.on('plotly_tracesmoved', (eventData) => {

301

console.log('Traces moved:', {

302

from: eventData.previousIndices,

303

to: eventData.currentIndices

304

});

305

});

306

```

307

308

## Error Handling

309

310

```javascript

311

// Handle invalid trace indices

312

try {

313

await Plotly.deleteTraces('chart', [0, 1, 2]);

314

} catch (error) {

315

if (error.message.includes('index')) {

316

console.error('Invalid trace index specified');

317

}

318

}

319

320

// Validate trace data before adding

321

function validateTrace(trace) {

322

if (!trace.type) {

323

throw new Error('Trace must have a type');

324

}

325

if (trace.type === 'scatter' && (!trace.x || !trace.y)) {

326

throw new Error('Scatter traces must have x and y data');

327

}

328

return true;

329

}

330

331

try {

332

validateTrace(newTrace);

333

await Plotly.addTraces('chart', newTrace);

334

} catch (error) {

335

console.error('Invalid trace data:', error.message);

336

}

337

```

338

339

## Performance Considerations

340

341

- Adding many traces individually is slower than adding them in batch

342

- Use `moveTraces()` instead of delete + add for reordering

343

- Consider using `visible: 'legendonly'` instead of deleting traces if they might be needed again

344

- For frequently changing trace sets, consider using `react()` with a complete data array

345

346

## Types

347

348

```javascript { .api }

349

interface PlotlyTrace {

350

type: string;

351

name?: string;

352

visible?: boolean | 'legendonly';

353

showlegend?: boolean;

354

x?: any[];

355

y?: any[];

356

z?: any[];

357

mode?: string;

358

marker?: MarkerConfig;

359

line?: LineConfig;

360

fill?: string;

361

fillcolor?: string;

362

opacity?: number;

363

hovertemplate?: string;

364

customdata?: any[];

365

meta?: any;

366

uid?: string;

367

[key: string]: any;

368

}

369

370

interface MarkerConfig {

371

color?: string | string[];

372

size?: number | number[];

373

symbol?: string | string[];

374

opacity?: number | number[];

375

line?: {

376

color?: string | string[];

377

width?: number | number[];

378

};

379

}

380

381

interface LineConfig {

382

color?: string;

383

width?: number;

384

dash?: string;

385

shape?: string;

386

smoothing?: number;

387

}

388

```