D3

D3 Bind Data

Binding data to elements using d3 will not make explicit changes to the element: the data will not show up in the DOM.

Update, Enter, Exit

.data() will return an update, an enter, and an exit selection

|500

Creating Elements Using Data

Suppose we have an empty svg element and an array of data. We want to create three rectangles inside of the svg with the data.

const specialdata = [75, 150, 200];

d3.select("svg")
  .selectAll("rect")
  .data(specialdata)
  .enter() // placeholder elements
  .append("rect") // change/append placeholder elements with rectangles
    .attr("x", d => d)
    .attr("y", d => d)
    .attr("width", "50")
    .attr("height", "30")
    .attr("fill", "pink");
Create a Bar Chart

let bardata = [300, 100, 150, 225, 75, 275];
svg = d3.select("body")
  .append("svg")
    .attr("width", "700")
    .attr("height", "400");
    
let bars = svg.selectAll("rect")
  .data(bardata);

bars.enter()
  .append("rect")
    .attr("x", 0)
    .attr("y",  (d, i) => i * 25 + 10)
    .attr("width", d => d)
    .attr("height", "20")
    .attr("fill", "pink");

Merge

The above examples manipulate the update, enter, and exit selection respectively.
To do some manipulations on the broader selection after some manipulations on some selection, we can use the .merge(other_selection) function.

For example:

const newdata = [123, 52, 232, 90, 34, 12, 189, 110];
const svg = d3.select("svg");
const circ = svg.selectAll("circle")
  .data(newdata);
  
circ.enter()  // 2 placeholders
  .append("circle")  // placeholders -> circles
     .attr("cx", "100")  // acts on enter selection only
     .attr("cy", (d, i) => (i - 5) * 50)
     .attr("r", "20")
     .attr("fill", "red")
  .merge(circ) // merge circ(update) into circ.enter
     .transition()
     .duration(2000)
     .attr("cx", "200");

Combine with a function:

function changedata(data) {
  const bars = d3.select("svg#gup") 
    .selectAll("rect")
    .data(data);    // bars is the update selection
    
  bars.enter()
    .append("rect")
      .attr("x", "30")  // until merge, acts on
      .attr("y", (d, i) => i * 50) // enter selection only
      .attr("height", "35")  
      .attr("fill", "lightgreen")
    .merge(bars) // merge in the update selection
      .attr("width", d => d); // acts on all bars
      
  bars.exit()
    .remove();
}

The above function works no matter if bars.enter() or bars.exit() is empty.

Groups

We can manually create groups by creating a parent element <g> for that group. For example:

const svg = d3.select("svg");
const specialdata = [100, 250, 300];

const bars = 
  d3.select("svg")
    .append("g") // group parent element
      .attr("id", "rects")
    .selectAll("rect") // rects in the group g
    .data(specialdata)
    .enter()
    .append("rect")
      .attr("x", d => d)
      .attr("y", d => d)
      .attr("width", "50")
      .attr("height", "30")
      .attr("fill", "red");
Creative Commons License by zcysxy