Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Adding 'measures' label to D3 bullet chart

I'm working with D3's bullet chart and am trying to figure out how to display the actual measures number just to the right of the measures rectangle. Since I want to do this for every bullet chart, I figure it'd be best to do it right in the bullet.js code. I'm rather new to D3 so any help would be much appreciated! Here is the link to Mike Bostock's bullet chart example with the bullet.js included at the bottom.

It looks like the measures code is handled in this snippet:

// Update the measure rects.
            var measure = g.selectAll("rect.measure")
                .data(measurez);

            measure.enter().append("rect")
                .attr("class", function (d, i) { return "measure s" + i; })
                .attr("width", w0)
                .attr("height", height / 3)
                .attr("x", reverse ? x0 : 0)
                .attr("y", height / 3)                    
              .transition()
                .duration(duration)
                .attr("width", w1)
                .attr("x", reverse ? x1 : 0);  

            measure.transition()
                .duration(duration)
                .attr("width", w1)
                .attr("height", height / 3)
                .attr("x", reverse ? x1 : 0)
                .attr("y", height / 3);

I thought I could just add something like this after the rect is appended but I've had no such luck.

measure.enter().append("text")
.attr("dy", "1em")
.text(function (d) { return d.measurez; })
.attr("x", reverse ? x0 : 0)
.attr("y", height / 3)
.transition()
.duration(duration)
.attr("width", w1)
.attr("x", reverse ? x1 : 0);

Thank you in advance for your consideration!

like image 789
Will Weld Avatar asked Sep 04 '26 18:09

Will Weld


1 Answers

You almost got it -- there're just two small things to consider. First, you can't call .enter() twice. Once the enter selection has been operated on, it's merged into the update selection and your second selection will be empty. This is fixed easily by saving the selection in a variable, but in this case I would recommend making a separate selection for the text labels.

var measureLabel = g.selectAll("text.measure")
      .data(measurez);
measureLabel.enter()....;

Second, to position the text to the right of the rect, you need to take not only the position, but also the width into account when computing the position of the text element. Also, you can omit a few elements that are not relevant to text elements.

measureLabel.enter()
      .append("text")
      .attr("class", function(d, i) { return "measure s" + i; })
      .attr("dy", "1em")
      .attr("dx", "1em")
      .text(String)
      .attr("x", reverse ? function(d) { return w0(d) + x0(d); } : w0)
      .attr("y", height / 3);

  measureLabel.transition()
      .duration(duration)
      .attr("x", reverse ? function(d) { return w1(d) + x1(d); } : w1);

Complete example here.

like image 91
Lars Kotthoff Avatar answered Sep 07 '26 07:09

Lars Kotthoff