最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Display text on rect using D3.js - Stack Overflow

programmeradmin1浏览0评论

I am developing Normalized stacked bar chart using d3.js,and trying to append a text on rect.It is getting appended when i inspect in browser.But it is not visible.I want something like this,

Here is my code,

var margin = {top: 20, right: 100, bottom: 30, left: 40},
    width = 400 - margin.left - margin.right,
    height = 200 - margin.top - margin.bottom;

var x = d3.scale.ordinal()
    .rangeRoundBands([0, width], .11);

var y = d3.scale.linear()
    .rangeRound([height, 0]);

var color = d3.scale.ordinal()
    .range(["#404041", "#00adef", "#bbbdc0", "#d1d2d4", "#d3d3d3"]);

var xAxis = d3.svg.axis()
    .scale(x)
    .orient("bottom");

var yAxis = d3.svg.axis()
    .scale(y)
    .orient("left")
    .tickFormat(d3.format("10"));

var svg = d3.select("body").append("svg")
    .attr("width", width + margin.left + margin.right)
    .attr("height", height + margin.top + margin.bottom + 20)
    .append("g")
    .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

d3.json("Nstackedbardata.json", function(error, data) {
  color.domain(d3.keys(data[0]).filter(function(key) { return key !== "State"; }));

  data.forEach(function(d) {
    var y0 = 0;
    d.ages = color.domain().map(function(name) {return {name: name, y0: y0, y1: y0 += +d[name]}; });
    d.ages.forEach(function(d) { d.y0 /= y0; d.y1 /= y0; });
  });

  data.sort(function(a, b) { return b.ages[0].y1 - a.ages[0].y1; });

  x.domain(data.map(function(d) { return d.State; }));


  svg.append("g")
      .attr("class", "x axis")
      .attr("transform", "translate(0," + height + ")")
      .call(xAxis)
      .style("fill", "#bbbdc0")
      .append("text")
      .attr("class","barChartAxisValue");
    var insertLinebreaks = function (d) {
        var el = d3.select(this);
        var words = d.split(' ');
        el.text('');

        for (var i = 0; i < words.length; i++) {
            var tspan = el.append('tspan').text(words[i]);
            if (i > 0)
                tspan.attr('x', 0).attr('dy', '12');
        }
    };
    svg.selectAll('g.x.axis g text').each(insertLinebreaks);
  svg.append("g")
      .attr("class", "y axis")
      .call(yAxis)
      .style("fill", "#bbbdc0")
      .append("text")
      .attr("class","barChartAxisValue")
      .attr("transform", "rotate(-90)")
      .attr("x",-70)
      .attr("y", -15)
      .attr("dy", ".71em")
      .style("text-anchor", "middle")
      .text("Percentage");

  var state = svg.selectAll(".state")
      .data(data)
    .enter().append("g")
      .attr("class", "state")
      .attr("transform", function(d) { return "translate(" + x(d.State) + ",0)"; });


  var sandeep= state.selectAll("rect")
      .data(function(d) { return d.ages; })
      .enter().append("rect")
      .attr("width", x.rangeBand())
      .attr("y", function(d) { return y(d.y1); })
      .attr("height", function(d) { return y(d.y0) - y(d.y1); })
      .style("fill", function(d) { return color(d.name);})
      .append("text")
      .attr("fill","#fff")
       .style("stroke-width", 1)
      .style({"font-size":"18px","z-index":"999999999"})
      .style("text-anchor", "middle")
      .text(function(d) { return ((d.y1-d.y0)*100).toFixed(0);});


});

I am developing Normalized stacked bar chart using d3.js,and trying to append a text on rect.It is getting appended when i inspect in browser.But it is not visible.I want something like this,

Here is my code,

var margin = {top: 20, right: 100, bottom: 30, left: 40},
    width = 400 - margin.left - margin.right,
    height = 200 - margin.top - margin.bottom;

var x = d3.scale.ordinal()
    .rangeRoundBands([0, width], .11);

var y = d3.scale.linear()
    .rangeRound([height, 0]);

var color = d3.scale.ordinal()
    .range(["#404041", "#00adef", "#bbbdc0", "#d1d2d4", "#d3d3d3"]);

var xAxis = d3.svg.axis()
    .scale(x)
    .orient("bottom");

var yAxis = d3.svg.axis()
    .scale(y)
    .orient("left")
    .tickFormat(d3.format("10"));

var svg = d3.select("body").append("svg")
    .attr("width", width + margin.left + margin.right)
    .attr("height", height + margin.top + margin.bottom + 20)
    .append("g")
    .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

d3.json("Nstackedbardata.json", function(error, data) {
  color.domain(d3.keys(data[0]).filter(function(key) { return key !== "State"; }));

  data.forEach(function(d) {
    var y0 = 0;
    d.ages = color.domain().map(function(name) {return {name: name, y0: y0, y1: y0 += +d[name]}; });
    d.ages.forEach(function(d) { d.y0 /= y0; d.y1 /= y0; });
  });

  data.sort(function(a, b) { return b.ages[0].y1 - a.ages[0].y1; });

  x.domain(data.map(function(d) { return d.State; }));


  svg.append("g")
      .attr("class", "x axis")
      .attr("transform", "translate(0," + height + ")")
      .call(xAxis)
      .style("fill", "#bbbdc0")
      .append("text")
      .attr("class","barChartAxisValue");
    var insertLinebreaks = function (d) {
        var el = d3.select(this);
        var words = d.split(' ');
        el.text('');

        for (var i = 0; i < words.length; i++) {
            var tspan = el.append('tspan').text(words[i]);
            if (i > 0)
                tspan.attr('x', 0).attr('dy', '12');
        }
    };
    svg.selectAll('g.x.axis g text').each(insertLinebreaks);
  svg.append("g")
      .attr("class", "y axis")
      .call(yAxis)
      .style("fill", "#bbbdc0")
      .append("text")
      .attr("class","barChartAxisValue")
      .attr("transform", "rotate(-90)")
      .attr("x",-70)
      .attr("y", -15)
      .attr("dy", ".71em")
      .style("text-anchor", "middle")
      .text("Percentage");

  var state = svg.selectAll(".state")
      .data(data)
    .enter().append("g")
      .attr("class", "state")
      .attr("transform", function(d) { return "translate(" + x(d.State) + ",0)"; });


  var sandeep= state.selectAll("rect")
      .data(function(d) { return d.ages; })
      .enter().append("rect")
      .attr("width", x.rangeBand())
      .attr("y", function(d) { return y(d.y1); })
      .attr("height", function(d) { return y(d.y0) - y(d.y1); })
      .style("fill", function(d) { return color(d.name);})
      .append("text")
      .attr("fill","#fff")
       .style("stroke-width", 1)
      .style({"font-size":"18px","z-index":"999999999"})
      .style("text-anchor", "middle")
      .text(function(d) { return ((d.y1-d.y0)*100).toFixed(0);});


});
Share Improve this question asked Dec 17, 2013 at 4:50 PreethiPreethi 3392 gold badges6 silver badges20 bronze badges
Add a comment  | 

2 Answers 2

Reset to default 13

You cannot append text elements to rect elements.

Instead, you should keep them as separate children of the parent g:

  var sandeep= state.selectAll(".data")
      .data(function(d) { return d.ages; })
      .enter();

   sandeep.append("rect")
      .classed('data', true)
      .attr("width", x.rangeBand())
      .attr("y", function(d) { return y(d.y1); })
      .attr("height", function(d) { return y(d.y0) - y(d.y1); })
      .style("fill", function(d) { return color(d.name);});

   sandeep
      .append("text")
      .classed('data', true)
      .attr("y", function(d) { return (y(d.y1) + y(d.y0)) / 2; }) // Center text
      .attr("fill","#fff")
      .style("stroke-width", 1)
      .style({"font-size":"18px","z-index":"999999999"})
      .style("text-anchor", "middle")
      .text(function(d) { return ((d.y1-d.y0)*100).toFixed(0);});

This is a response to ShaMoh's question on the accepted answer. I would have put this in a comment under his comment but im not allowed to yet.

I know that this is hella old and ShaMoh is probably dead by now, or has solved his issue, but for anybody who finds this and is wondering what is wrong with his plnkr code:

He defines "bar" as a rect element appended to "serie", one for each d in data in this code:

var bar = serie.selectAll("rect")
            .data(function (d) {
                return d;
            })
            .enter().append("rect")

Then, later he appends his "text" to "bar" (which is a 'rect' element):

 bar.append("text")
            .attr("x", function (d) {
                return x(d[1]);
            })
            .attr("dy", "1.35em")
            .text(function (d) { return d; });

So he ends up with a 'g' grouping element classed as "serie", with a 'rect' element for each d in .data, and a 'text' element appended to each 'rect':

What he needs to do is append his 'text' element to his 'g' grouping element, which he calls "serie". That way his 'g' holds the 'rect's appended to it, onefor each slice of the bar, plus the 'text' elements appened. Instead of being appended to the 'rect', and not displayed, the text is appended to the same 'g' as the 'rect':

 <g class="serie">
     <rect></rect>
     <rect></rect>
     <text></text>
    </g>
发布评论

评论列表(0)

  1. 暂无评论