Loading...

D3.js online editor

Write, Run & Share D3.js code online using OneCompiler's D3.js online editor for free. It's one of the robust, feature-rich online editors for D3.js.

About D3.js

D3.js (Data-Driven Documents) is a powerful JavaScript library for creating dynamic, interactive data visualizations in web browsers. D3 binds data to DOM elements and applies data-driven transformations using SVG, HTML, and CSS.

Syntax help

Selections

Selections allow you to select and manipulate DOM elements using d3.select() for single elements and d3.selectAll() for multiple elements.

// Select and modify elements
d3.select("#chart").style("background-color", "#f0f0f0")
d3.selectAll("p").style("color", "blue")

// Chaining methods
d3.select("body").append("div").attr("class", "container").text("Hello, D3!")

Data Binding

D3's data binding connects data to DOM elements. The join() method (D3 v5+) handles creating, updating, and removing elements.

const data = [10, 20, 30, 40, 50]

// Modern join() method
d3.select("#chart")
  .selectAll("div")
  .data(data)
  .join("div")
  .attr("class", "bar")
  .style("width", (d) => d * 10 + "px")

// Using key functions for object identity
const users = [
  { id: 1, name: "Alice" },
  { id: 2, name: "Bob" },
]

d3.selectAll(".user")
  .data(users, (d) => d.id)
  .join("div")
  .text((d) => d.name)

Scales

Scales map data values to visual values like positions, sizes, or colors.

// Linear scale
const xScale = d3.scaleLinear().domain([0, 100]).range([0, 500])

// Band scale (categorical)
const yScale = d3
  .scaleBand()
  .domain(["A", "B", "C", "D"])
  .range([0, 200])
  .padding(0.1)

// Color scales
const colorScale = d3
  .scaleOrdinal()
  .domain(["apple", "banana"])
  .range(["red", "yellow"])

// Sequential color scale
const heatScale = d3
  .scaleSequential()
  .domain([0, 100])
  .interpolator(d3.interpolateViridis)

// Time scale
const timeScale = d3
  .scaleTime()
  .domain([new Date(2023, 0, 1), new Date(2023, 11, 31)])
  .range([0, 800])

Axes

D3 provides axis generators that create axis elements from scales.

const xScale = d3.scaleLinear().domain([0, 100]).range([0, 400])
const xAxis = d3
  .axisBottom(xScale)
  .ticks(5)
  .tickFormat((d) => d + "%")

svg.append("g").attr("transform", `translate(0, ${height})`).call(xAxis)

SVG Shapes

D3 works primarily with SVG elements for rendering visualizations.

const svg = d3
  .select("#chart")
  .append("svg")
  .attr("width", 600)
  .attr("height", 400)

// Rectangle
svg
  .append("rect")
  .attr("x", 50)
  .attr("y", 50)
  .attr("width", 100)
  .attr("height", 60)
  .attr("fill", "steelblue")

// Circle
svg
  .append("circle")
  .attr("cx", 250)
  .attr("cy", 80)
  .attr("r", 40)
  .attr("fill", "coral")

// Text
svg
  .append("text")
  .attr("x", 100)
  .attr("y", 280)
  .attr("font-size", "24px")
  .text("Hello, D3!")

Paths and Shapes

D3 provides shape generators for creating complex paths like lines, areas, and arcs.

// Line generator
const lineData = [
  { x: 0, y: 30 },
  { x: 50, y: 60 },
  { x: 100, y: 20 },
]

const lineGenerator = d3
  .line()
  .x((d) => d.x)
  .y((d) => d.y)
  .curve(d3.curveMonotoneX)

svg
  .append("path")
  .datum(lineData)
  .attr("d", lineGenerator)
  .attr("fill", "none")
  .attr("stroke", "steelblue")

// Arc generator (for pie charts)
const arcGenerator = d3.arc().innerRadius(0).outerRadius(80)
const pieData = d3.pie()([30, 50, 20])

svg
  .selectAll(".arc")
  .data(pieData)
  .join("path")
  .attr("d", arcGenerator)
  .attr("fill", (d, i) => d3.schemeCategory10[i])

Transitions

D3 transitions animate changes to DOM elements smoothly.

// Basic transition
d3.select("rect")
  .transition()
  .duration(1000)
  .attr("width", 200)
  .attr("fill", "orange")

// Staggered animation
d3.selectAll("circle")
  .transition()
  .duration(500)
  .delay((d, i) => i * 100)
  .attr("r", 30)

// Easing functions
d3.select("rect").transition().ease(d3.easeBounce).attr("y", 100)

// Chaining transitions
d3.select("rect")
  .transition()
  .duration(500)
  .attr("fill", "red")
  .transition()
  .duration(500)
  .attr("width", 200)

Events and Interactivity

Use the on() method to add event handlers for user interactions.

// Click and hover events
d3.selectAll("rect")
  .on("click", function (event, d) {
    d3.select(this).attr("fill", "red")
  })
  .on("mouseover", function () {
    d3.select(this).attr("opacity", 0.7)
  })
  .on("mouseout", function () {
    d3.select(this).attr("opacity", 1)
  })

// Drag behavior
const drag = d3.drag().on("drag", function (event) {
  d3.select(this).attr("cx", event.x).attr("cy", event.y)
})

svg.selectAll("circle").call(drag)

Loading Data

D3 provides methods for loading data from external files.

// Load JSON
d3.json("data.json").then((data) => createChart(data))

// Load CSV with type conversion
d3.csv("data.csv", (d) => ({
  name: d.name,
  value: +d.value,
})).then((data) => console.log(data))

// Load multiple files
Promise.all([d3.json("data1.json"), d3.csv("data2.csv")]).then(
  ([data1, data2]) => {
    createVisualization(data1, data2)
  }
)

Bar Chart Example

Complete example of an animated bar chart:

const data = [
  { category: "A", value: 30 },
  { category: "B", value: 80 },
  { category: "C", value: 45 },
  { category: "D", value: 60 },
]

const margin = { top: 20, right: 30, bottom: 40, left: 50 }
const width = 600 - margin.left - margin.right
const height = 400 - margin.top - margin.bottom

const svg = d3
  .select("#chart")
  .append("svg")
  .attr("width", width + margin.left + margin.right)
  .attr("height", height + margin.top + margin.bottom)
  .append("g")
  .attr("transform", `translate(${margin.left},${margin.top})`)

const x = d3
  .scaleBand()
  .domain(data.map((d) => d.category))
  .range([0, width])
  .padding(0.2)

const y = d3
  .scaleLinear()
  .domain([0, d3.max(data, (d) => d.value)])
  .nice()
  .range([height, 0])

svg
  .append("g")
  .attr("transform", `translate(0,${height})`)
  .call(d3.axisBottom(x))
svg.append("g").call(d3.axisLeft(y))

svg
  .selectAll(".bar")
  .data(data)
  .join("rect")
  .attr("x", (d) => x(d.category))
  .attr("width", x.bandwidth())
  .attr("y", height)
  .attr("height", 0)
  .attr("fill", "steelblue")
  .transition()
  .duration(800)
  .delay((d, i) => i * 100)
  .attr("y", (d) => y(d.value))
  .attr("height", (d) => height - y(d.value))