Trowa
Trowa

Reputation: 365

D3 - To add Data Labels to a simple bar chart

I know this is easy and I saw some examples in this forum as well as other websites as well, but I simple can't figure it out.

I'm new in using D3 library to generate the charts. I'm trying to learn by creating bar chart.

My question is how to add the Data Labels into the chart?

Below is the codes I have.

then I have my JS:

    var chartwidth = 800;
    var chartheight = 600;

    var data =  [
      {"Start_Dt":"Jan 15","UnitName":"Unit 1","ProgramName":"ProgramName 1","AttendCnt":159,"NewcomerCnt":10}
      , {"Start_Dt":"Jan 22","UnitName":"Unit 2","ProgramName":"ProgramName 2","AttendCnt":178,"NewcomerCnt":5}
      , {"Start_Dt":"Feb 14","UnitName":"Unit 2","ProgramName":"ProgramName 3","AttendCnt":240,"NewcomerCnt":46}
      , {"Start_Dt":"Feb 19","UnitName":"Unit 1","ProgramName":"ProgramName 4","AttendCnt":201,"NewcomerCnt":10}
      , {"Start_Dt":"Feb 26","UnitName":"Unit 2","ProgramName":"ProgramName 5","AttendCnt":177,"NewcomerCnt":7}
      , {"Start_Dt":"Mar 12","UnitName":"Unit N","ProgramName":"ProgramName N","AttendCnt":184,"NewcomerCnt":3}
    ];                          

    var margin = {top: 20, right: 20, bottom: 300, left: 40},
        width = chartwidth - margin.left - margin.right,
        height = chartheight - margin.top - margin.bottom;

    var formatPercent = d3.format(".0%");
    var formatTime = d3.time.format("%e %B");

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

    var x2 = d3.scale.ordinal()
    .rangeBands([0, width], 0);

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

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

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

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


    data.forEach(function(d) {
      d.AttendCnt = +d.AttendCnt;
    });

    x.domain(data.map(function(d) { return d.Start_Dt + " " + d.ProgramName; }));
    y.domain([0, d3.max(data, function(d) { return d.AttendCnt; })]);

    //Create X Axis
    svg.append("g")
      .attr("class", "x axis")
      .attr("transform", "translate(0," + height + ")")
      .call(xAxis)                        
      .selectAll("text")  
      .style("text-anchor", "end")
      .attr("dx", "-.8em")
      .attr("dy", ".15em")
      .attr("transform", "rotate(-65)" )
      .append("text")
      .attr("y", 25)
      .attr("x",x.rangeBand()/2 )
      .style("text-anchor", "middle")
      .style("font-size", "20px")
      .style("color", "black")
      .text(function(d,i) { return "xxx"; }); 

    //Create Y Axis
    svg.append("g")
      .attr("class", "y axis")
      .call(yAxis)
      .append("text")
      .attr("transform", "rotate(-90)")
      .attr("y", 0)
      .attr("dy", ".71em")
      .style("text-anchor", "end")
      .text("Attendance");

    svg.selectAll(".bar")
      .data(data)                                 
      .enter().append("rect")
      .attr("class", "bar")
      .attr("x", function(d) { return x(d.Start_Dt + " " + d.ProgramName); })
      .attr("width", x.rangeBand())
      .attr("y", function(d) { return y(d.AttendCnt); })
      .attr("height", function(d) { return height - y(d.AttendCnt); });

Before

After

How to modify the codes to get the result I wanted? Tks

Upvotes: 0

Views: 1685

Answers (1)

Yoplaboom
Yoplaboom

Reputation: 554

i haven't tested the code but it could be something like this :

svg.selectAll(".barText")
      .data(data)                                 
      .enter().append("text")
      .attr("class", "barText")
      .attr("x", function(d) { return x(d.Start_Dt + " " + d.ProgramName); })
      .attr("y", function(d) { return height - y(d.AttendCnt); })
      .text(function(d) { return d.AttendCnt; })
      ;

Hope it helps

Upvotes: 2

Related Questions