D3 - Getting text on the top of rectangles in Vertical Bar chart

后端 未结 2 1025
囚心锁ツ
囚心锁ツ 2021-01-23 20:27

I am making a vertical bar chart with D3 successfully. I further want the value of frequency to lie on the top of each rectangle. I am able to get the complete structure and rec

2条回答
  •  南方客
    南方客 (楼主)
    2021-01-23 20:45

    The problem here is simple: you cannot append a text element inside a rect element.

    The text element will show up when you inspect the DOM, but this doesn't mean that it works, and no text will be actually painted in the SVG.

    So, it should be:

     g.selectAll(".text")
          .data(data)
          .enter()
          .append("text")
          .attr("dy", ".75em")
          .attr("y", function(d) { return y(d.frequency); })
          .attr("x", function(d) { return x(d.letter); })
          .attr("text-anchor", "middle")
          .text(function(d) { return d.frequency; });
    

    Note that I changed

    .text(function(d) { return y(d.frequency); });
    

    which makes no sense, to:

    .text(function(d) { return d.frequency; });
    

    Here is a demo with your code:

    var data = [{
        "letter": "A",
        "frequency": "5.01"
    }, {
        "letter": "B",
        "frequency": "7.80"
    }, {
        "letter": "C",
        "frequency": "15.35"
    }, {
        "letter": "D",
        "frequency": "22.70"
    }, {
        "letter": "E",
        "frequency": "34.25"
    }, {
        "letter": "F",
        "frequency": "10.21"
    }, {
        "letter": "G",
        "frequency": "7.68"
    }, ];
    
    
    //Setting up of our svg with proper calculations 
    var svg = d3.select("body")
        .append("svg").attr("width", 500).attr("height", 300);
    var margin = {
        top: 40,
        right: 20,
        bottom: 40,
        left: 40
    };
    var width = svg.attr("width") - margin.left - margin.right;
    var height = svg.attr("height") - margin.top - margin.bottom;
    
    //Plotting our base area in svg in which chart will be shown 
    var g = svg.append("g").attr("transform", "translate(" + margin.left + "," + margin.top + ")");
    
    //X and Y scaling 
    var x = d3.scaleBand().rangeRound([0, width]).padding(0.4);
    var y = d3.scaleLinear().rangeRound([height, 0]);
    
    x.domain(data.map(function(d) {
        return d.letter;
    }));
    y.domain([0, d3.max(data, function(d) {
        return +d.frequency;
    })]);
    
    //Final Plotting 
    
    //for x axis 
    g.append("g")
        .call(d3.axisBottom(x))
        .attr("transform", "translate(0," + height + ")");
    
    //for y axis 
    g.append("g")
        .call(d3.axisLeft(y))
        .append("text").attr("transform", "rotate(-90)").attr("text-anchor", "end");
    
    //for rectangles 
    g.selectAll(".bar")
        .data(data)
        .enter()
        .append("rect")
        .attr("class", "bar")
        .attr("x", function(d) {
            return x(d.letter);
        })
        .attr("y", function(d) {
            return y(d.frequency);
        })
        .attr("width", x.bandwidth())
        .attr("height", function(d) {
            return height - y(d.frequency);
        });
    
    g.selectAll(".text")
        .data(data)
        .enter()
        .append("text")
        .attr("dy", ".75em")
        .attr("y", function(d) {
            return y(d.frequency) - 16;
        })
        .attr("x", function(d) {
            return x(d.letter) + x.bandwidth() / 2;
        })
        .attr("text-anchor", "middle")
        .text(function(d) {
            return d.frequency;
        });

提交回复
热议问题