0

I am working through a tutorial in Scott Murray's amazing "Interactive Data Visualization For The Web" (my second attempt...I got too frustrated and gave up before) and got to an extra credit segment of an interactive bar chart tutorial. The on click trigger adds new bars from randomly generated data...but the labels don't update. He left in an initial code block to "create" the text labels leaving the challenge of updating based on the code. So I looked at the code used to update the bars...

var bars = svg.selectAll("rect")
    .data(dataset);                         

bars.enter()
    .append("rect")                         
    .attr("x", w)
    .attr("y", function(d) {
        return h - yScale(d);
    })
    .attr("width", xScale.bandwidth())
    .attr("height", function(d) {
        return yScale(d);
    })
    .attr("fill", function(d) {
        return "rgb(0, 0, " + Math.round(d * 10) + ")";
    })
    .merge(bars)
    .transition()
    .duration(500)
    .attr("x", function(d, i) {
        return xScale(i);
    })
    .attr("y", function(d) {
        return h - yScale(d);
    })
    .attr("width", xScale.bandwidth())
    .attr("height", function(d) {
    return yScale(d);
    });

...and interpolated that with the original code block used to create the initial labels...

svg.selectAll("text")
    .data(dataset)
    .enter()
    .append("text")
    .text(function(d) {
        return d;
    })
    .attr("text-anchor", "middle")
    .attr("x", function(d, i) {
        return xScale(i) + xScale.bandwidth() / 2;
    })
    .attr("y", function(d) {
        return h - yScale(d) + 14;
    })
    .attr("font-family", "sans-serif")
    .attr("font-size", "11px")
    .attr("fill", "white");

so with that in mind this is what I came up with...

var labels = svg.selectAll("text")
    .data(dataset);

labels.enter()      
    .append("text")
    .text(function(d) {
        return d;
    })
    .attr("text-anchor", "middle")
    .attr("x", w)
    .attr("y", function(d) {
        return h - yScale(d) + 14;
    })
    .attr("font-family", "sans-serif")
    .attr("font-size", "11px")
    .attr("fill", "white");
    })
    .merge(labels)
    .transition()
    .duration(500)
    .text(function(d) {
        return d;
    })
    .attr("text-anchor", "middle")
    .attr("x", function(d, i) {
        return xScale(i) + xScale.bandwidth() / 2;
    })
    .attr("y", function(d) {
        return h - yScale(d) + 14;
    });

At least to the point where it doesn't break the bar update code...but it gets stuck at the .merge(labels) line with an Uncaught ReferenceError: labels is not defined and the labels don't update. If I define a variable called "labels" (exactly the same way "bars" are) shouldn't that be all that's required to define?

1 Answers1

-1

I have found the complete example on github, and modified it and had no problem with the following modification

      var labels = svg.selectAll("text")
         .data(dataset);
      labels.enter()
         .append("text")
         .text(function(d) { return d; })
         .attr("text-anchor", "middle")
         .attr("x", function(d, i) {
             return w + xScale.bandwidth() / 2;
         })
         .attr("y", function(d) {
             return h - yScale(d) + 14;
         })
         .attr("font-family", "sans-serif")
         .attr("font-size", "11px")
         .attr("fill", "white")
         .merge(labels)
         .transition()
         .duration(500)
         .text(function(d) {
             return d;
         })
         .attr("x", function(d, i) {
             return xScale(i) + xScale.bandwidth() / 2;
         })
         .attr("y", function(d) {
             return h - yScale(d) + 14;
         });
rioV8
  • 24,506
  • 3
  • 32
  • 49
  • Thank you rioV8! Now it no longer breaks at .merge(labels) but I get an **Uncaught SyntaxError: Unexpected end of input** at the last }); so close yet not quite. can you link to the Github sample code? – David Foster Graphics Jul 27 '18 at 13:05
  • @DavidFosterGraphics https://github.com/alignedleft/d3-book/blob/master/chapter_09/25_adding_values.html and I used https://d3js.org/d3.v5.min.js instead of the d3 that is part of the repository. – rioV8 Jul 27 '18 at 15:29
  • Ah....I'm using d3.v4 as that's what the current book is specifically written with. – David Foster Graphics Jul 27 '18 at 15:38
  • That should not be the problem because v4 and v5 have the same syntax for this graph. Is the code now working for you. The Error suggests you have made some typo regarding `{}` or `()` – rioV8 Jul 27 '18 at 15:41
  • Just tried with d3.v4.min.js and it behaves as expected. – rioV8 Jul 27 '18 at 16:10
  • I actually copied and pasted exactly as written and it's giving me the error. Same exact syntax. Same error. Frustrating. Thanks for your help...I guess I'll move on and come back to this. – David Foster Graphics Jul 27 '18 at 17:59
  • Try to find the problem by skinning each select operation and add 1 modify operation at the time to see which one is the real cause of the error (the `text()` or `attr()` or ...) – rioV8 Jul 27 '18 at 18:08
  • Fixed it...pretty sure I was missing a final `});` at the end of the code. Your advice to take it one operation at a time was key. Thank you so much. – David Foster Graphics Jul 31 '18 at 17:46