Basic Parallel Coordinates Plot — D3.js

A parallel coordinates plot visualizes multivariate data by representing each variable as a vertical axis and each observation as a line connecting values across all axes. This technique is powerful for identifying patterns, clusters, and outliers in high-dimensional datasets where traditional 2D plots fall short. It enables simultaneous comparison of multiple variables for each data point.

Basic Parallel Coordinates Plot rendered with D3.js

Renders

JavaScript source (D3.js)

// anyplot.ai
// parallel-basic: Basic Parallel Coordinates Plot
// Library: d3 7.9.0 | JavaScript 22.23.1
// Quality: 89/100 | Created: 2026-07-24

const t = window.ANYPLOT_TOKENS;
const { width, height } = window.ANYPLOT_SIZE;
const margin = { top: 150, right: 230, bottom: 60, left: 70 };
const iw = width - margin.left - margin.right;
const ih = height - margin.top - margin.bottom;

// Cloud compute instance specs by family — vCPU/memory/storage grow together
// within a family, while price and network throughput separate the families.
// Each axis is scaled to its own min/max (not a shared scale), which is the
// standard normalization for parallel coordinates: every dimension has its
// own units, so a fixed 0-1 range per axis is what makes them comparable.
const dimensions = [
  { key: "vcpu", label: "vCPUs", format: d3.format("d") },
  { key: "memory", label: "Memory (GB)", format: d3.format(",d") },
  { key: "storage", label: "Storage (GB)", format: d3.format(",d") },
  { key: "price", label: "Price ($/hr)", format: (d) => `$${d3.format(".2f")(d)}` },
  { key: "network", label: "Network (Gbps)", format: d3.format(",d") },
];

const data = [
  // General Purpose
  { category: "General Purpose", vcpu: 2, memory: 8, storage: 80, price: 0.08, network: 5 },
  { category: "General Purpose", vcpu: 4, memory: 16, storage: 160, price: 0.16, network: 10 },
  { category: "General Purpose", vcpu: 8, memory: 32, storage: 320, price: 0.32, network: 10 },
  { category: "General Purpose", vcpu: 16, memory: 64, storage: 640, price: 0.64, network: 15 },
  { category: "General Purpose", vcpu: 32, memory: 128, storage: 1280, price: 1.28, network: 20 },
  { category: "General Purpose", vcpu: 48, memory: 192, storage: 1920, price: 1.92, network: 25 },
  // Compute Optimized
  { category: "Compute Optimized", vcpu: 4, memory: 8, storage: 50, price: 0.14, network: 10 },
  { category: "Compute Optimized", vcpu: 8, memory: 16, storage: 100, price: 0.28, network: 15 },
  { category: "Compute Optimized", vcpu: 16, memory: 32, storage: 200, price: 0.56, network: 20 },
  { category: "Compute Optimized", vcpu: 32, memory: 64, storage: 400, price: 1.12, network: 25 },
  { category: "Compute Optimized", vcpu: 48, memory: 96, storage: 600, price: 1.68, network: 30 },
  { category: "Compute Optimized", vcpu: 64, memory: 128, storage: 800, price: 2.24, network: 40 },
  // Memory Optimized
  { category: "Memory Optimized", vcpu: 2, memory: 16, storage: 100, price: 0.13, network: 10 },
  { category: "Memory Optimized", vcpu: 4, memory: 32, storage: 200, price: 0.26, network: 10 },
  { category: "Memory Optimized", vcpu: 8, memory: 64, storage: 400, price: 0.52, network: 15 },
  { category: "Memory Optimized", vcpu: 16, memory: 128, storage: 800, price: 1.04, network: 20 },
  { category: "Memory Optimized", vcpu: 32, memory: 256, storage: 1600, price: 2.08, network: 25 },
  { category: "Memory Optimized", vcpu: 48, memory: 384, storage: 2400, price: 3.12, network: 30 },
  // GPU Accelerated
  { category: "GPU Accelerated", vcpu: 8, memory: 32, storage: 200, price: 0.9, network: 25 },
  { category: "GPU Accelerated", vcpu: 16, memory: 64, storage: 400, price: 1.8, network: 50 },
  { category: "GPU Accelerated", vcpu: 32, memory: 128, storage: 800, price: 3.6, network: 100 },
  { category: "GPU Accelerated", vcpu: 64, memory: 256, storage: 1600, price: 7.2, network: 100 },
  { category: "GPU Accelerated", vcpu: 96, memory: 384, storage: 2400, price: 10.8, network: 200 },
  { category: "GPU Accelerated", vcpu: 128, memory: 512, storage: 3200, price: 14.4, network: 200 },
];

const categories = ["General Purpose", "Compute Optimized", "Memory Optimized", "GPU Accelerated"];

// GPU Accelerated is the natural focal outlier (it dominates every axis), so it
// gets a bolder, more opaque stroke; the other three families overlap heavily in
// the low-value band and are dimmed/thinned to stay traceable without a hairball.
const FOCAL_CATEGORY = "GPU Accelerated";
const TITLE_FONT = "Georgia, 'Times New Roman', serif";

// SVG mount
const svg = d3.select("#container").append("svg").attr("width", width).attr("height", height);
const g = svg.append("g").attr("transform", `translate(${margin.left},${margin.top})`);

// Scales — one shared x position per dimension, one independent y scale per dimension
const xScale = d3.scalePoint().domain(dimensions.map((d) => d.key)).range([0, iw]);
const yScales = Object.fromEntries(
  dimensions.map((d) => [
    d.key,
    d3.scaleLinear().domain(d3.extent(data, (row) => row[d.key])).nice().range([ih, 0]),
  ]),
);
const colorScale = d3.scaleOrdinal().domain(categories).range(t.palette.slice(0, categories.length));

// Data lines — one path per observation, transparent enough to read overlaps
const lineGen = d3.line();
g.selectAll(".instance-line")
  .data(data)
  .join("path")
  .attr("class", "instance-line")
  .attr("d", (row) => lineGen(dimensions.map((d) => [xScale(d.key), yScales[d.key](row[d.key])])))
  .attr("fill", "none")
  .attr("stroke", (row) => colorScale(row.category))
  .attr("stroke-width", (row) => (row.category === FOCAL_CATEGORY ? 3.25 : 2))
  .attr("stroke-opacity", (row) => (row.category === FOCAL_CATEGORY ? 0.85 : 0.48));

// Axes — one vertical d3.axisLeft per dimension, plus the dimension label above it
dimensions.forEach((dim) => {
  const axisG = g.append("g")
    .attr("transform", `translate(${xScale(dim.key)},0)`)
    .call(d3.axisLeft(yScales[dim.key]).ticks(5).tickFormat(dim.format));
  axisG.selectAll("text").attr("fill", t.inkSoft).style("font-size", "13px");
  axisG.selectAll("line").attr("stroke", t.grid);
  axisG.select(".domain").attr("stroke", t.inkSoft).attr("stroke-width", 1.5);

  g.append("text")
    .attr("x", xScale(dim.key)).attr("y", -22)
    .attr("text-anchor", "middle")
    .attr("fill", t.ink).style("font-size", "16px").style("font-weight", "600")
    .text(dim.label);
});

// Legend — instance family swatches in the right margin
const legend = svg.append("g").attr("transform", `translate(${margin.left + iw + 44},${margin.top + 12})`);
legend.append("text")
  .attr("fill", t.inkSoft).style("font-size", "13px").style("font-weight", "600")
  .text("Instance Family");
categories.forEach((cat, i) => {
  const row = legend.append("g").attr("transform", `translate(0,${30 + i * 32})`);
  row.append("rect")
    .attr("width", 16).attr("height", 16).attr("rx", 3)
    .attr("fill", colorScale(cat));
  row.append("text")
    .attr("x", 24).attr("y", 13)
    .attr("fill", t.ink).style("font-size", "14px")
    .style("font-weight", cat === FOCAL_CATEGORY ? "700" : "400")
    .text(cat);
});

// Title
const title = "Cloud Instance Specs · parallel-basic · javascript · d3 · anyplot.ai";
const titleFontSize = Math.max(15, Math.round(24 * 67 / title.length));
svg.append("text")
  .attr("x", width / 2).attr("y", 56)
  .attr("text-anchor", "middle")
  .attr("fill", t.ink)
  .style("font-family", TITLE_FONT)
  .style("font-size", `${titleFontSize}px`)
  .style("font-weight", "600")
  .text(title);

Retrieve this implementation

Runnable source as JSON, for any HTTP client: https://api.anyplot.ai/specs/parallel-basic/d3/code. Any spec id and library id listed in llms-full.txt fit the same URL shape; every URL below is complete and callable.

{
  "spec_id": "parallel-basic",
  "language": "javascript",
  "library": "d3",
  "page": "https://anyplot.ai/parallel-basic/javascript/d3",
  "hub": "https://anyplot.ai/parallel-basic",
  "code_json": "https://api.anyplot.ai/specs/parallel-basic/d3/code",
  "spec_json": "https://api.anyplot.ai/specs/parallel-basic",
  "render_light_png": "https://storage.googleapis.com/anyplot-images/plots/parallel-basic/javascript/d3/plot-light.png",
  "render_dark_png": "https://storage.googleapis.com/anyplot-images/plots/parallel-basic/javascript/d3/plot-dark.png",
  "interactive_light_html": "https://storage.googleapis.com/anyplot-images/plots/parallel-basic/javascript/d3/plot-light.html",
  "interactive_dark_html": "https://storage.googleapis.com/anyplot-images/plots/parallel-basic/javascript/d3/plot-dark.html",
  "quality_score": 89.0,
  "license": "MIT",
  "guide": "https://anyplot.ai/llms.txt"
}

Part of Basic Parallel Coordinates Plot on anyplot.ai.

Other implementations