Skip to content

Series & Data โ€‹

Learn how to work with data series in SciChart Engine.

Interactive Demo โ€‹

๐Ÿ“Š 0 points ๐Ÿš€ 0 FPS

Scroll to zoom โ€ข Drag to pan โ€ข Multiple series support

What is a Series? โ€‹

A series represents a single dataset visualized on the chart. Each series has:

  • ID: Unique identifier
  • Type: How data is rendered (line, scatter, or both)
  • Data: X and Y values as TypedArrays
  • Style: Visual properties (color, width, etc.)

Creating Series โ€‹

Line Series โ€‹

typescript
chart.addSeries({
  id: 'temperature',
  type: 'line',
  data: {
    x: new Float32Array([0, 1, 2, 3, 4]),
    y: new Float32Array([20, 22, 21, 23, 22]),
  },
  style: { 
    color: '#ff6b6b', 
    width: 2 
  },
})

Scatter Series โ€‹

typescript
chart.addSeries({
  id: 'measurements',
  type: 'scatter',
  data: { x, y },
  style: { 
    color: '#4ecdc4', 
    pointSize: 6 
  },
})

Line with Points โ€‹

typescript
chart.addSeries({
  id: 'samples',
  type: 'both',
  data: { x, y },
  style: { 
    color: '#ffe66d', 
    width: 1.5, 
    pointSize: 4 
  },
})

Bar Series โ€‹

typescript
chart.addBar({
  id: 'sales',
  data: {
    x: new Float32Array([1, 2, 3, 4, 5]),
    y: new Float32Array([120, 150, 180, 210, 190]),
  },
  style: {
    color: '#00f2ff',
    barWidth: 0.6
  }
})

Heatmap Series โ€‹

typescript
chart.addHeatmap({
  id: 'matrix',
  data: {
    xValues: [0, 1, 2],
    yValues: [0, 1, 2],
    zValues: new Float32Array([1, 2, 3, 4, 5, 6, 7, 8, 9])
  },
  style: {
    colorScale: { name: 'viridis', min: 0, max: 10 }
  }
})

Candlestick Series โ€‹

typescript
chart.addSeries({
  id: 'stock-price',
  type: 'candlestick',
  data: {
    x: timestamps,
    open: openValues,
    high: highValues,
    low: lowValues,
    close: closeValues,
  },
  style: {
    bullishColor: '#26a69a', // Green
    bearishColor: '#ef5350', // Red
    barWidth: 0.8
  }
})

Stacked Series โ€‹

Group multiple series together by using the same stackId. They will be rendered on top of each other.

typescript
chart.addSeries({
  id: 'layer-1',
  type: 'area', // Usually stacked as area/band
  stackId: 'my-group',
  data: { x, y: y1 },
  style: { color: '#ff6b6b' }
})

chart.addSeries({
  id: 'layer-2',
  type: 'area',
  stackId: 'my-group',
  data: { x, y: y2 },
  style: { color: '#4ecdc4' }
})

Gauge Series (KPIs) โ€‹

Visualize single values within a range.

typescript
chart.addSeries({
  id: 'speed',
  type: 'gauge',
  data: { value: 65, min: 0, max: 120 },
  style: {
    label: 'Speed (km/h)',
    needleColor: '#00ccff',
    ranges: [
      { from: 0, to: 60, color: 'rgba(76, 175, 80, 0.4)' },
      { from: 90, to: 120, color: 'rgba(244, 67, 54, 0.4)' }
    ]
  }
})

Sankey Series (Flows) โ€‹

Visualize distribution flows between categories.

typescript
chart.addSeries({
  id: 'flow',
  type: 'sankey',
  data: {
    nodes: [{ id: 'A', name: 'Source' }, { id: 'B', name: 'Target' }],
    links: [{ source: 'A', target: 'B', value: 100 }]
  }
})

Data Requirements โ€‹

TypedArrays Required

SciChart Engine requires Float32Array or Float64Array for data. Regular JavaScript arrays will cause errors.

typescript
// โœ… Correct
const x = new Float32Array([1, 2, 3, 4, 5])
const y = new Float32Array([10, 20, 15, 25, 30])

// โŒ Wrong - will cause errors
const x = [1, 2, 3, 4, 5]
const y = [10, 20, 15, 25, 30]

Why TypedArrays? โ€‹

  1. Memory efficiency: Fixed-size, contiguous memory
  2. GPU upload: Direct transfer to WebGL buffers
  3. Performance: No type coercion overhead
  4. Precision: Float64 for scientific accuracy

Converting from Arrays โ€‹

typescript
// From regular array
const regularArray = [1, 2, 3, 4, 5]
const typedArray = new Float32Array(regularArray)

// From generator
const n = 1000
const x = new Float32Array(n)
for (let i = 0; i < n; i++) {
  x[i] = i
}

Updating Data โ€‹

Replace All Data โ€‹

typescript
chart.updateSeries('temperature', {
  x: newXData,
  y: newYData,
})

Append Data (Streaming) โ€‹

typescript
// Add new points to existing data
chart.updateSeries('stream', {
  x: new Float32Array([nextX]),
  y: new Float32Array([nextY]),
  append: true,
})

Efficient Appending โ€‹

For real-time data, pre-allocate and copy:

typescript
function appendPoints(prevX, prevY, newPoints) {
  const newX = new Float32Array(prevX.length + newPoints.length)
  const newY = new Float32Array(prevY.length + newPoints.length)
  
  newX.set(prevX)
  newY.set(prevY)
  
  for (let i = 0; i < newPoints.length; i++) {
    newX[prevX.length + i] = newPoints[i].x
    newY[prevY.length + i] = newPoints[i].y
  }
  
  return { x: newX, y: newY }
}

Managing Series โ€‹

Get Series โ€‹

typescript
const series = chart.getSeries('temperature')

// Series methods
series.getId()         // 'temperature'
series.getType()       // 'line'
series.getData()       // { x: Float32Array, y: Float32Array }
series.getPointCount() // 5
series.getBounds()     // { xMin, xMax, yMin, yMax }
series.isVisible()     // true

Get All Series โ€‹

typescript
const allSeries = chart.getAllSeries()

allSeries.forEach(s => {
  console.log(`${s.getId()}: ${s.getPointCount()} points`)
})

Remove Series โ€‹

typescript
chart.removeSeries('temperature')

Toggle Visibility โ€‹

typescript
const series = chart.getSeries('temperature')
series.setVisible(false)  // Hide
series.setVisible(true)   // Show

Change Type Dynamically โ€‹

typescript
const series = chart.getSeries('data')
series.setType('scatter') // Switch from line to scatter

Update Style โ€‹

typescript
const series = chart.getSeries('temperature')
series.setStyle({ 
  color: '#00ff00',
  width: 3 
})

Multiple Series โ€‹

typescript
// Add multiple series
chart.addSeries({
  id: 'sensor-1',
  data: { x: time, y: sensor1Data },
  style: { color: '#ff6b6b' },
})

chart.addSeries({
  id: 'sensor-2',
  data: { x: time, y: sensor2Data },
  style: { color: '#4ecdc4' },
})

chart.addSeries({
  id: 'sensor-3',
  data: { x: time, y: sensor3Data },
  style: { color: '#ffe66d' },
})

Multiple Y-Axes โ€‹

SciChart Engine supports multiple Y-axes. This is useful for comparing series with different units (e.g., Current and Potential).

1. Register Additional Axis โ€‹

typescript
const chart = createChart({
  container,
  xAxis: { label: 'Time / s' },
  yAxis: [
    { id: 'primary', label: 'Current / ยตA', position: 'left' },
    { id: 'secondary', label: 'Potential / V', position: 'right' }
  ]
})

Use the yAxisId property to specify which axis a series belongs to:

typescript
chart.addSeries({
  id: 'current',
  yAxisId: 'primary',
  data: { x, y: currentData },
  style: { color: '#00f2ff' }
})

chart.addSeries({
  id: 'potential',
  yAxisId: 'secondary',
  data: { x, y: potentialData },
  style: { color: '#ff6b6b' }
})

3. Dynamic Axis Management โ€‹

You can add or remove axes at runtime:

typescript
// Add a new axis
chart.addYAxis({
  id: 'dynamic-axis',
  label: 'New Unit',
  position: 'right',
  offset: 50 // Push axis further to the right
});

// Update an existing axis
chart.updateYAxis('primary', {
  label: 'Updated Label',
  auto: false,
  min: 0,
  max: 100
});

Series Bounds โ€‹

Each series calculates its data bounds:

typescript
const series = chart.getSeries('data')
const bounds = series.getBounds()

console.log(`X range: ${bounds.xMin} to ${bounds.xMax}`)
console.log(`Y range: ${bounds.yMin} to ${bounds.yMax}`)

The chart uses these bounds for auto-scaling.

Best Practices โ€‹

1. Use Meaningful IDs โ€‹

typescript
// โœ… Good
chart.addSeries({ id: 'temperature-sensor-1', ... })

// โŒ Bad
chart.addSeries({ id: 's1', ... })

2. Pre-allocate for Large Data โ€‹

typescript
// โœ… Good - allocate once
const n = 1000000
const x = new Float32Array(n)
const y = new Float32Array(n)

// Fill data...

chart.addSeries({ id: 'big', data: { x, y } })

3. Batch Updates โ€‹

typescript
// โœ… Good - update once with all new points
chart.updateSeries('stream', {
  x: new Float32Array(100),  // 100 new points
  y: new Float32Array(100),
  append: true,
})

// โŒ Bad - 100 separate updates
for (let i = 0; i < 100; i++) {
  chart.updateSeries('stream', {
    x: new Float32Array([point.x]),
    y: new Float32Array([point.y]),
    append: true,
  })
}

4. Clean Up Unused Series โ€‹

typescript
// Remove series when no longer needed
chart.removeSeries('old-data')

Released under the MIT License.