简体   繁体   中英

How to add numbers to bars with D3.js?

I've created a chart and it works fine, but I can't find out how to add numbers to columns. Numbers appear only if I hover the columns. Tried different variants:

svg.selectAll("text").
data(data).
enter().
append("svg:text").
attr("x", function(datum, index) { return x(index) + barWidth; }).
attr("y", function(datum) { return height - y(datum.days); }).
attr("dx", -barWidth/2).
attr("dy", "1.2em").
attr("text-anchor", "middle").
text(function(datum) { return datum.days;}).
attr("fill", "white");

A link to my example: https://jsfiddle.net/rinatoptimus/db98bzyk/5/

Alternate idea to @gerardofurtado is to instead of a rect append a g , then group the text and rect together. This prevents the need for double-data binding.

var bars = svg.selectAll(".bar")
  .data(newData)
  .enter().append("g")
  .attr("class", "bar")
  // this might be affected:
  .attr("transform", function(d, i) {
    return "translate(" + i * barWidth + ",0)";
  });

bars.append("rect")
  .attr("y", function(d) {
    return y(d.days);
  })
  .attr("height", function(d) {
    return height - y(d.days) + 1;
  })
  .style({
    fill: randomColor
  }) // color  bars
  .attr("width", barWidth - 1)
  .on('mouseover', tip.show)
  .on('mouseout', tip.hide);

bars.append("text")
  .text(function(d) {
    return d.days;
  })
  .attr("y", function(d) {
    return y(d.days);
  })
  .attr("x", barWidth / 2)
  .style("text-anchor", "middle");

Updated fiddle .

When you do this:

svg.selectAll("text")

you are selecting text elements that already exist in your SVG. In an enter selection, it's important selecting something that doesn't exist :

svg.selectAll(".text")
    .data(newData)
    .enter()
    .append("svg:text")
    .attr("x", function(datum) {
        return x(datum.name) + x.rangeBand()/2
    })
    .attr("y", function(datum) {
        return y(datum.days) - 10;
    })
    .attr("text-anchor", "middle")
    .text(function(datum) {
        return datum.days;
    })
    .attr("fill", "white");

Here is your fiddle: https://jsfiddle.net/c210osht/

You could try using the d3fc bar series component , which allows you to add data-labels via the decorate pattern .

Here's what the code would look like:

var svgBar = fc.seriesSvgBar()
    .xScale(xScale)
    .yScale(yScale)
    .crossValue(function(_, i) { return i; })
    .mainValue(function(d) { return d; })
    .decorate(function(selection) {
      selection.enter()
        .append("text")
        .style("text-anchor", "middle")
        .attr("transform", "translate(0, -10)")
        .text(function(d) { return d3.format(".2f")(d); })
        .attr("fill", "black");
    });

Here's a codepen with the complete example .

Disclosure : I am a core contributor to the d3fc project!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM