0

While testing a data visualisation code based on D3.js, I am constantly running into some confusion regarding Bostock's suggestion on data update pattern and d3.selectAll() function. Please allow me to quote in the following a piece of code to explain what I am trying to achieve. As I am fairly new to this powerful D3 library, please bear with me if you find these questions naive.

So, let me state the problem. I created an object called curve and I attempt to call it later while fetching the data to plot the curve and further update it as a new dataset appears or the axis range has changed.

var newCurve = function(Id) {
  'use strict';

   var curvePath = function (data) {
     'use strict';

     var line = d3.line()
       .x(function(d) { return this.x(d.x); }.bind(this))
       .y(function(d) { return this.y(d.y); }.bind(this));

     var curve = this.g.selectAll('path.line')
       .data(data, function(d) { return d.y; });

     curve.exit().remove();

     curve.enter()
      .append("path")
        .attr("id", Id)
        .attr("stroke-width", 1.0)
        .attr('d', line(data));

    return curve;
  }

  // method to feed data to line path
  var curveDataFetch = function(data) {
    'use strict';

    var curve = curvePath.bind(this)(data);

  }.bind(this);

  return {
    'curvePath'  : curvePath,
    'curveDataFetch'  : curveDataFetch
  };

};   

Just to clarify that in the above the this variable is pointing to an object that contains the x and y functions of d3.js used to map the x and y domains (and define axes). Argument Id is simply a string for the id assigned to all paths. In general, this pattern works fine. A line can be created properly by calling this function from inside, for example, d3.csv or d3.json, while fetching the data.

However, there are 2 issues.

First, in case a new dataset is to be plotted or the range of axis has changed, it appears that I can't directly call the curveDataFetch method to transition the data. What I need to do is to remove physically by selecting all paths elements created in the previous line and re-plot it again. Otherwise, the previous line still exists. What is the general pattern to allow an easy data update?

Second, I tried to use d3.selectAll(Id) to select all paths under the same id (as I intentionally assign the same id to all paths created here), it appeared that only the first element was actually selected. How can I select all these elements?

Your wisdom will be highly appreciated.

X...
  • 173
  • 1
  • 2
  • 12
  • 2
    *"as I intentionally assign the same id to all paths"*... IDs have to be **unique**. Use class instead. – Gerardo Furtado Jul 03 '17 at 12:47
  • @Gerado: Thanks. I doubt if this is the problem. The same trick applies well to bar charts. – X... Jul 04 '17 at 07:20
  • This can (sometimes) work, but it is an invalid HTML. Have a look here: https://stackoverflow.com/questions/7262195/several-elements-with-the-same-id-responding-to-one-css-id-selector – Gerardo Furtado Jul 04 '17 at 07:23
  • So, if I have several lines on the same graph and I want to identify them, shall I generate dynamically one class for each line or bar? – X... Jul 04 '17 at 07:31
  • Yes, just change your `.attr("id", Id)` for `.attr("class", Id)`. – Gerardo Furtado Jul 04 '17 at 07:33
  • Thanks, Gerardo. I am learning. Any suggestions on the update pattern? – X... Jul 04 '17 at 07:35

0 Answers0