2

Contour Chart

PreviousNext

Filled contour plots for visualizing 3D data on a 2D plane with data point markers.

02468101214X02468101214Y8.4-2.7
"use client"

import { ContourChart } from "@/components/ui/charts"

// Generate sample 2D terrain-like data with multiple peaks
const generateContourData = (): number[][] => {
  const size = 15
  const data: number[][] = []

  for (let j = 0; j < size; j++) {
    const row: number[] = []
    for (let i = 0; i < size; i++) {
      const x = i / (size - 1)
      const y = j / (size - 1)

      // Create multiple peaks and valleys
      let z = 0

      // Main peak (top right area)
      z += 8 * Math.exp(-((x - 0.7) ** 2 + (y - 0.7) ** 2) / 0.05)

      // Secondary peak (center-left)
      z += 4 * Math.exp(-((x - 0.3) ** 2 + (y - 0.5) ** 2) / 0.08)

      // Valley (bottom area)
      z -= 3 * Math.exp(-((x - 0.5) ** 2 + (y - 0.2) ** 2) / 0.1)

      // Small bump (top left)
      z += 2 * Math.exp(-((x - 0.2) ** 2 + (y - 0.8) ** 2) / 0.04)

      // Base noise
      z += Math.sin(x * 10) * Math.cos(y * 8) * 0.5

      row.push(z)
    }
    data.push(row)
  }
  return data
}

const data = generateContourData()

export function ContourChartDemo() {
  return (
    <div className="w-full max-w-3xl">
      <ContourChart
        data={data}
        xAxisLabel="X"
        yAxisLabel="Y"
        levels={12}
        colorScale={[
          "#1e40af",
          "#2563eb",
          "#3b82f6",
          "#60a5fa",
          "#93c5fd",
          "#bfdbfe",
        ]}
        showMarkers={true}
        markerSymbol="x"
        markerSize={6}
        markerColor="#1e40af"
        showGrid={true}
        lineWidth={0.5}
      />
    </div>
  )
}

About

The Contour Chart displays filled regions and iso-lines connecting points of equal value, perfect for visualizing terrain, temperature distributions, or any continuous 3D surface data.

Features:

  • Filled contours - Smooth color-coded regions
  • Multiple color scales - Rainbow, viridis, thermal, ocean, and more
  • Data point markers - X, cross, circle, or diamond markers
  • Interactive tooltips - Hover to see values
  • Customizable levels - Control contour density

Installation

pnpm dlx shadcn@latest add https://ui.simplifying.ai/r/contour-chart.json

Usage

import { CONTOUR_COLOR_SCALES, ContourChart } from "@/components/ui/charts"
 
// 2D array of z-values
const data = [
  [0, 1, 2, 3, 2],
  [1, 4, 6, 4, 1],
  [2, 6, 9, 6, 2],
  [1, 4, 6, 4, 1],
  [0, 1, 2, 3, 2],
]
 
export function Example() {
  return (
    <ContourChart
      data={data}
      levels={10}
      colorScale={CONTOUR_COLOR_SCALES.rainbow}
      showMarkers={true}
      markerSymbol="x"
    />
  )
}

Variants

Lines Only

Contour lines without filled regions.

051015X051015Y5.8-5.8
"use client"

import { ContourChart } from "@/components/ui/charts"

// Generate sample data with interesting contours
const generateContourData = (): number[][] => {
  const size = 20
  const data: number[][] = []

  for (let j = 0; j < size; j++) {
    const row: number[] = []
    for (let i = 0; i < size; i++) {
      const x = (i / (size - 1)) * 4 - 2
      const y = (j / (size - 1)) * 4 - 2
      // Sinusoidal wave pattern
      const z = Math.sin(x) * Math.cos(y) * 5 + Math.sin(x * y) * 2
      row.push(z)
    }
    data.push(row)
  }
  return data
}

const data = generateContourData()

export function ContourChartLinesDemo() {
  return (
    <div className="w-full max-w-3xl">
      <ContourChart
        data={data}
        xAxisLabel="X"
        yAxisLabel="Y"
        levels={15}
        colorScale={[
          "#1e40af",
          "#2563eb",
          "#3b82f6",
          "#60a5fa",
          "#93c5fd",
          "#bfdbfe",
        ]}
        showFill={false}
        showLines={true}
        lineWidth={1.5}
        lineColor="#2563eb"
        showMarkers={false}
        showGrid={true}
      />
    </div>
  )
}

Thermal Heat Map

Heat distribution visualization with thermal color scale.

051015X Position051015Y Position152.70.2
"use client"

import { ContourChart } from "@/components/ui/charts"

// Generate thermal/heat distribution data
const generateThermalData = (): number[][] => {
  const size = 18
  const data: number[][] = []

  for (let j = 0; j < size; j++) {
    const row: number[] = []
    for (let i = 0; i < size; i++) {
      const x = i / (size - 1)
      const y = j / (size - 1)

      // Heat source in center
      const centerHeat =
        100 * Math.exp(-((x - 0.5) ** 2 + (y - 0.5) ** 2) / 0.08)

      // Secondary heat source
      const secondaryHeat =
        60 * Math.exp(-((x - 0.2) ** 2 + (y - 0.7) ** 2) / 0.05)

      // Cooling effect at edges
      const edgeCooling = 20 * (1 - Math.min(x, 1 - x, y, 1 - y) * 5)

      row.push(centerHeat + secondaryHeat - edgeCooling + 20)
    }
    data.push(row)
  }
  return data
}

const data = generateThermalData()

export function ContourChartThermalDemo() {
  return (
    <div className="w-full max-w-3xl">
      <ContourChart
        data={data}
        xAxisLabel="X Position"
        yAxisLabel="Y Position"
        levels={10}
        colorScale={[
          "#1e40af",
          "#2563eb",
          "#3b82f6",
          "#60a5fa",
          "#93c5fd",
          "#bfdbfe",
        ]}
        showMarkers={false}
        showGrid={false}
        lineWidth={0.3}
        lineColor="#60a5fa"
      />
    </div>
  )
}

Topographic Style

Ocean-themed with circle markers for elevation data.

0246810Longitude0246810Latitude2534.4249.6
"use client"

import { ContourChart } from "@/components/ui/charts"

// Generate data representing elevation/topography
const generateTopographyData = (): number[][] => {
  const size = 12
  const data: number[][] = []

  for (let j = 0; j < size; j++) {
    const row: number[] = []
    for (let i = 0; i < size; i++) {
      const x = i / (size - 1)
      const y = j / (size - 1)

      // Mountain ridge
      const ridge =
        1500 * Math.exp(-((y - 0.6) ** 2) / 0.1) * (1 + Math.sin(x * 8) * 0.3)

      // Valley
      const valley = -500 * Math.exp(-((x - 0.3) ** 2 + (y - 0.3) ** 2) / 0.05)

      // Rolling hills
      const hills = 300 * Math.sin(x * 6) * Math.cos(y * 4)

      // Base elevation
      const base = 500

      row.push(base + ridge + valley + hills)
    }
    data.push(row)
  }
  return data
}

const data = generateTopographyData()

export function ContourChartScatterDemo() {
  return (
    <div className="w-full max-w-3xl">
      <ContourChart
        data={data}
        xAxisLabel="Longitude"
        yAxisLabel="Latitude"
        levels={8}
        colorScale={[
          "#1e40af",
          "#2563eb",
          "#3b82f6",
          "#60a5fa",
          "#93c5fd",
          "#bfdbfe",
        ]}
        showMarkers={true}
        markerSymbol="circle"
        markerSize={5}
        markerColor="#1e40af"
        showGrid={true}
        lineWidth={1}
        lineColor="#1e40af"
      />
    </div>
  )
}

API Reference

PropTypeDefaultDescription
datanumber[][]required2D array of z-values
pointsContourPoint[]-Optional scatter points to overlay
levelsnumber10Number of contour levels
showFillbooleantrueShow filled contour regions
showLinesbooleantrueShow contour lines
lineWidthnumber0.5Contour line width
lineColorstring"rgba(0,0,0,0.3)"Line color
colorScalestring[]CONTOUR_COLOR_SCALES.rainbowColor gradient array
showMarkersbooleantrueShow data point markers
markerSymbol"x" | "cross" | "circle" | "diamond""x"Marker shape
markerSizenumber8Marker size in pixels
markerColorstring"#333333"Marker color
showGridbooleantrueShow background grid
xAxisLabelstring-X-axis label
yAxisLabelstring-Y-axis label

Color Scales

Built-in color scales available via CONTOUR_COLOR_SCALES:

import { CONTOUR_COLOR_SCALES } from "@/components/ui/charts"
 
// Available scales:
CONTOUR_COLOR_SCALES.rainbow // Blue → Cyan → Green → Yellow → Red
CONTOUR_COLOR_SCALES.viridis // Purple → Blue → Green → Yellow
CONTOUR_COLOR_SCALES.coolwarm // Blue → White → Red
CONTOUR_COLOR_SCALES.ocean // Deep blue gradient
CONTOUR_COLOR_SCALES.thermal // Purple → Red → Yellow
CONTOUR_COLOR_SCALES.blue // Light to dark blue

Custom Color Scale

<ContourChart
  data={data}
  colorScale={["#fee2e2", "#ef4444", "#7f1d1d"]} // Red gradient
/>

Marker Symbols

// X marks (default)
<ContourChart data={data} markerSymbol="x" />
 
// Cross marks
<ContourChart data={data} markerSymbol="cross" />
 
// Circle marks
<ContourChart data={data} markerSymbol="circle" />
 
// Diamond marks
<ContourChart data={data} markerSymbol="diamond" />
 
// No markers
<ContourChart data={data} showMarkers={false} />

Notes

  • The data prop expects a 2D array where each cell represents a z-value at that grid position
  • Contour levels are automatically calculated based on the min/max values in your data
  • For optimal visualization, use at least 5x5 grid size; smaller grids may not produce smooth contours
  • Data point markers help viewers understand the underlying grid structure
  • Built-in color scales are optimized for accessibility and clarity