Skip to content
Irene Ros edited this page May 23, 2013 · 3 revisions

FAQs

How do I access the chart again once I'm inside a lifecycle event callback?

There are two ways you can do it in. The context of a lifecycle event is a d3 selection but it has been ammended to give you access to the chart it belongs to. You can access it like so:

d3.chart("Circles", {
  initialize: function() {
    this.layer("circle").on("enter", function() {

      // get access to the chart
      var chart = this.chart();

      // get the fill
      return this.style("fill", chart.fill());
    });
  },
  
  // getter setter for a fill
  fill : function(newFill) {
    if (arguments.length === 0) {
      return this.currentFill;
    }
    this.currentFill = newFill;
  }
});

Alternatively, if you are binding your layer callbacks inside your initialize method, you can always set a var outside the scope to point to the chart like so:

d3.chart("CirclesChart").extend("CustomColorCirclesChart", {
  initialize: function() {
    
    // set the context chart outside the scope
    var chart = this;

    this.layer("circle").on("enter", function() {

      // get the fill, note we're using the chart
      // variable defined above outside this function.
      return this.style("fill", chart.fill());
    });
  },
  
  // getter setter for a fill
  fill : function(newFill) {
    if (arguments.length === 0) {
      return this.currentFill;
    }
    this.currentFill = newFill;
  }
});

Are there two different event types?

Yes. There are.

Lifecycle events are layer specific. Each layer has its own set of behaviors and as such you can hook into each layer individually using lifecycle events like so:

d3.chart("CirclesChart").extend("RedCirclesChart", {
  initialize: function() {
    
    // hook into the enter event and change the
    // entering circles' color to red.
    this.layer("circle").on("enter", function() {
      return this.style("fill", "red");
    });
  }
});

On the other hand there are chart specific events. They are primarily useful to notify other components on your page about what is happening in your chart. For example if a user clicked on an element of your chart, you might want to notify any potential listeners that a selection occured.

For example (see jsBin):

d3.chart("CircleChart", {
  initialize: function() {
    var chart = this;
    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")
          .on("click", function(d) {
            // when a user clicks a circle, just broadcast
            // the value that it represents. Note that `chart`
            // was defined above in the initialize method.
            chart.trigger("selected", d);
          });
      }
    });
  
    this.layer("circles").on("enter", function() {
      return this.attr("cx", 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");

// when we recieve a "selected" event, just console.log
// it for now.
chart.on("selected", function(d) {
  console.log(d);
});

chart.draw(data);
Clone this wiki locally