Skip to content
Irene Ros edited this page May 22, 2013 · 5 revisions

Layers: Overview

What is a layer?

A layer in d3.chart is simply a concept that encapsulates a single chain of:

  • binding data to elements
  • inserting new elements
  • handling lifecycle events and their callbacks

For example:

  • In a bar chart, a layer might constitute the set of bars that are rendered in accordance with the data
  • In a treemap, a layer might be the set of rectangles that make up the area of the treemap.
  • In a map that has 3 different type of marks, each set of markers might constitute a different layer.

You can have multiple layers all referencing the same data. A layer can only bind data once to a single type of element.

How does a layer compare to d3?

Take for example (jsBin) the following d3 chart that renders red circles along an x-axis and adds labels above the circles with the value being drawn like so:

layers sample 1
var data = [10,30,40,50,70,80,120];

// make our chart base
var chart = d3.select("#test")
  .append("svg")
  .attr("height", 200)
  .attr("width", 200);

// draw the circles
var circles = chart.append("g")
  .selectAll("circle")
  .data(data)
  .enter()
    .insert("circle")
    .attr("cx", function(d) { return d; })
    .attr("cy", 100)
    .attr("r", 4)
    .style("fill", "red");

// draw the labels
var labels = chart.append("g")
  .selectAll("text")
  .data(data)
  .enter()
    .insert("text")
    .attr("x", function(d){ return d; })
    .attr("y", 90)
    .style("font-size", 8)
    .style("text-anchor", "middle")
    .text(function(d) { return d; });

Looking at the above code, it's pretty clear that we have two conceptual layers: "circles" and "labels." How would we go about creating this chart with d3.chart?

d3.chart("CircleChart", {
  initialize: function() {
    
    // create a circle layer
    this.layer("circles", this.base.append("g"), {
      dataBind: function(data) {
        return this.selectAll("circle")
          .data(data);
      },
      insert: function() {
        return this.insert("circle")
          .attr("cy", 100)
          .attr("r", 4)
          .style("fill", "red");
      }
    });

    // create a labels layer
    this.layer("labels", this.base.append("g"), {
      dataBind: function(data) {
        return this.selectAll("text")
          .data(data);
      },
      insert: function() {
        return this.insert("text")
          .attr("y", 90)
          .style("font-size", 8)
          .style("text-anchor", "middle");
      }
    });
    
    // when new elements come in, put them through the
    // enter callback, positioning them appropriatly
    this.layer("circles").on("enter", function() {
      return this.attr("cx", function(d) { 
        return d; 
      });
    });

    this.layer("labels").on("enter", function() {
      return this.attr("x", function(d){ 
        return d; 
      }).text(function(d) { 
        return d; 
      });
    });
  }
});

var data = [10,30,40,50,70,80,120];
var chart = d3.select("#test")
  .append("svg")
  .style("width", 200)
  .style("height", 200)
  .chart("CircleChart");

chart.draw(data);
Clone this wiki locally