/

3D Lines Chart

Render multiple 3D polylines as thick ribbons in WebGL. Visualize trajectories, flight paths, and multi-series data flowing through three-dimensional space.

Quick Start

import { Lines3D } from "@chartts/gl"
 
const chart = Lines3D("#chart", {
  data: {
    series: [
      {
        name: "Path A",
        values: [10, 25, 18, 35, 28, 42, 30],
        x: [0, 1, 2, 3, 4, 5, 6],
        z: [0, 1, 2, 1, 3, 2, 4],
        color: "#6c9eff",
      },
      {
        name: "Path B",
        values: [5, 15, 30, 22, 38, 20, 45],
        x: [0, 1, 2, 3, 4, 5, 6],
        z: [2, 3, 1, 4, 2, 5, 3],
        color: "#5eead4",
      },
    ],
  },
  lineWidth: 3,
  orbit: { autoRotate: true },
})

That renders two thick 3D polylines flowing through space with distinct colors. Each line is rendered as a triangle-strip ribbon for consistent width at any viewing angle. Orbit controls let you rotate around the lines to see depth relationships.

When to Use 3D Lines Charts

3D lines charts show multiple paths or trajectories in three-dimensional space. They excel at revealing how multiple series relate spatially.

Use a 3D lines chart when:

  • Comparing multiple trajectories or paths through 3D space
  • Visualizing flight paths, particle traces, or physical trajectories
  • Showing multi-series time data where z represents a third variable
  • You need to compare the shape and direction of several 3D paths

Don't use a 3D lines chart when:

  • A single path is the focus (use a Line3D chart for clarity)
  • Data is 2D with no meaningful z dimension (use a standard line chart)
  • You need precise value reading at each point (3D perspective distorts)
  • The paths overlap heavily and create visual clutter

Props Reference

PropTypeDefaultDescription
dataGLChartDatarequiredChart data with series array of GLSeries3D objects
lineWidthnumber2Ribbon width in pixels. Scaled by device pixel ratio
cameraCameraOptionsauto-fitCamera position and target. Auto-calculated from data bounds if omitted
orbitboolean | OrbitConfigtrueEnable orbit controls with optional auto-rotation
lightPartial<LightConfig>defaultLighting configuration for the scene
theme'dark' | 'light' | GLTheme'dark'Color theme for background, line palette, text, and grid
animatebooleantrueEnable fade-in animation on mount
tooltipbooleantrueShow tooltip on hover with series name, index, and value

Multi-Series 3D Lines

Each series becomes a separate polyline with its own color. Colors can be set per-series or drawn from the theme palette automatically.

Lines3D("#chart", {
  data: {
    series: [
      {
        name: "Altitude Track 1",
        values: [100, 250, 400, 350, 500, 450, 600],
        x: [0, 10, 20, 30, 40, 50, 60],
        z: [0, 5, 10, 15, 20, 25, 30],
      },
      {
        name: "Altitude Track 2",
        values: [50, 150, 300, 250, 400, 350, 550],
        x: [0, 10, 20, 30, 40, 50, 60],
        z: [5, 10, 15, 20, 25, 30, 35],
      },
      {
        name: "Altitude Track 3",
        values: [200, 180, 350, 300, 450, 500, 480],
        x: [0, 10, 20, 30, 40, 50, 60],
        z: [10, 15, 20, 25, 30, 35, 40],
      },
    ],
  },
  lineWidth: 4,
})

When no explicit color is set on a series, it receives the next color from the theme palette. The default dark theme provides 8 distinct colors that cycle for additional series.


Ribbon Rendering

Lines are rendered as triangle-strip ribbons with screen-space width. This means the line width stays consistent regardless of the camera distance or angle. The ribbon always faces the camera, so lines remain visible from any orbit position.

// Thin lines for dense multi-series data
Lines3D("#chart", {
  data: denseData,
  lineWidth: 1,
})
 
// Thick ribbons for emphasis
Lines3D("#chart", {
  data: highlightData,
  lineWidth: 6,
})

The line width is multiplied by the device pixel ratio automatically, so lines appear the same physical size on retina and standard displays.


Orbit Controls

Orbit controls are essential for 3D line charts because depth relationships are only visible when you can rotate the scene.

Lines3D("#chart", {
  data: lineData,
  orbit: {
    autoRotate: true,
    autoRotateSpeed: 0.3,
  },
})
  • Click and drag to rotate the camera around the lines
  • Scroll to zoom in and out
  • Right-click drag to pan the view

Accessibility

  • Tooltip shows the series name, point index, and value on hover for each vertex
  • Each series has a distinct color from the palette for visual differentiation
  • The ground grid provides spatial reference for the 3D positions
  • Animation fades lines in smoothly, drawing attention to the overall shapes

Real-World Examples

Flight trajectory comparison

Lines3D("#flights", {
  data: {
    series: [
      {
        name: "Flight AA101",
        values: [0, 5000, 15000, 28000, 35000, 35000, 28000, 15000, 5000, 0],
        x: [0, 50, 120, 200, 300, 400, 500, 580, 650, 700],
        z: [0, 10, 25, 40, 55, 70, 85, 95, 105, 110],
        color: "#6c9eff",
      },
      {
        name: "Flight UA202",
        values: [0, 8000, 20000, 32000, 38000, 38000, 30000, 18000, 6000, 0],
        x: [0, 40, 100, 180, 280, 380, 480, 560, 640, 700],
        z: [5, 15, 30, 50, 65, 80, 90, 100, 108, 115],
        color: "#fbbf24",
      },
    ],
  },
  lineWidth: 3,
  orbit: { autoRotate: true, autoRotateSpeed: 0.2 },
})

Multi-sensor temperature traces

Lines3D("#sensors", {
  data: {
    series: [
      {
        name: "Sensor Floor 1",
        values: [20, 21, 22, 23, 22, 21, 20, 19, 20, 21],
        x: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
        z: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
      },
      {
        name: "Sensor Floor 2",
        values: [22, 23, 24, 25, 24, 23, 22, 21, 22, 23],
        x: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
        z: [3, 3, 3, 3, 3, 3, 3, 3, 3, 3],
      },
      {
        name: "Sensor Floor 3",
        values: [24, 25, 26, 27, 26, 25, 24, 23, 24, 25],
        x: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
        z: [6, 6, 6, 6, 6, 6, 6, 6, 6, 6],
      },
    ],
  },
  lineWidth: 4,
  theme: "dark",
})

Other Charts