vendredi 13 novembre 2015

D3 dispatch a function listening for statechange on checkboxes generated in another function

I'm writing a D3 app. I'm following the guidelines to create interactivity with the resuable D3 pattern, here and here: Interactivity with the d3 reusable pattern http://ift.tt/1WWzfag

What I want to do is to write a function that listens to checkboxes statechanges that were generated in a separate function. The idea is that these checkboxes will affect data selection inside D3 chart (keys to manipulate the D3 chart).

I reproduced the exact same example found here http://ift.tt/1WWzfag and it works fine. So my question is how do I implement interactivity with these checkboxes?

What I tried is at the code block labeled /ADD INTERACTIVITY FOR CHECKBOXES/:

if(!d3.chart) d3.chart = {};

d3.chart.histogram = function() {
  var g;
  var data;
  var width = 400;
  var height = 400;
  var cx = 10;
  var numberBins = 5;
  var dispatch = d3.dispatch(chart, "hover");

  function chart(container) {
    g = container;

    update();
  }
  chart.update = update;

  function update() {

    console.log("Data in update(): " + JSON.stringify(data));

    var hist = d3.layout.histogram()
    .value(function(d) { return d.count })
    .range([0, d3.max(data, function(d){ return d.count }) ])
    .bins(numberBins);
    var layout = hist(data);

    var maxLength = d3.max(layout, function(d) { return d.length });
    var widthScale = d3.scale.linear()
    .domain([0, maxLength])
    .range([0, width])

    var yScale = d3.scale.ordinal()
    .domain(d3.range(numberBins))
    .rangeBands([height, 0], 0.1)

    var colorScale = d3.scale.category20();


    var rects = g.selectAll("rect")
    .data(layout)

    rects.enter().append("rect")

    rects
    .transition()
    .attr({
      y: function(d,i) {
        return yScale(i)
      },
      x: 50,
      height: yScale.rangeBand(),
      width: function(d,i) {
        return widthScale(d.length)
      },
      fill: function(d, i) { return colorScale(i) }
    })
    rects.exit().transition().remove();


    rects.on("mouseover", function(d) {
      d3.select(this).style("fill", "orange")
      console.log("hist over", d)
      dispatch.hover(d)
    })
    rects.on("mouseout", function(d) {
      d3.select(this).style("fill", "")
      dispatch.stateChange
    })


     /*ADD INTERACTIVITY FOR CHECKBOXES. Here #sampleChecks is the id */
     d3.selectAll("#sampleChecks")
       .on('change', function(){
          var selectedData = eval(d3.select(this).property('value'));
          console.log(selectedData); //prints 'undefined'

     });

  }

  chart.data = function(value) {
    if(!arguments.length) return data;
    data = value;
    return chart;
  }
  chart.width = function(value) {
    if(!arguments.length) return width;
    width = value;
    return chart;
  }
  chart.height = function(value) {
    if(!arguments.length) return height;
    height = value;
    return chart;
  }

  return d3.rebind(chart, dispatch, "on");
}

HTML elements context:

...
<div id="sampleChecks" class="checkBoxContainer">
...
   <td><input type="checkbox" id="Hibernia1" value="Hibernia1" name="checkboxes" unchecked sample></td>
   <td><input type="checkbox" id="Hibernia2" value="Hibernia2" name="checkboxes" unchecked sample></td>
    ...

If I change d3.selectAll("#sampleChecks") with d3.selectAll("#Hibernia1") the console prints the selected element, but I'd like to get what checkbox id inside #sampleChecks were state changed.




Aucun commentaire:

Enregistrer un commentaire