Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Show values on top of bars in a barChart

I have a bar chart with ordinal scale for the x-axis. I want to display the y-values on the top of each bar or in the bottom of each bar. It would be also acceptable to display the y-values when one hovers over the bar. Is there a function or a way in a dc.js to do that? Here is the jsfiddle and my code is below the pic>

Edit: Here is my code: HTML

<body>
    <div id='Chart'>
    </div>
</body>

JS

var data = [{
    Category: "A",
    ID: "1"
}, {
    Category: "A",
    ID: "1"
}, {
    Category: "A",
    ID: "1"
}, {
    Category: "A",
    ID: "2"
}, {
    Category: "A",
    ID: "2"
}, {
    Category: "B",
    ID: "1"
}, {
    Category: "B",
    ID: "1"
}, {
    Category: "B",
    ID: "1"
}, {
    Category: "B",
    ID: "2"
}, {
    Category: "B",
    ID: "3"
}, {
    Category: "B",
    ID: "3"
}, {
    Category: "B",
    ID: "3"
}, {
    Category: "B",
    ID: "4"
}, {
    Category: "C",
    ID: "1"
}, {
    Category: "C",
    ID: "2"
}, {
    Category: "C",
    ID: "3"
}, {
    Category: "C",
    ID: "4"
}, {
    Category: "C",
    ID: "4"
},{
    Category: "C",
    ID: "5"
}];

var ndx = crossfilter(data);

var XDimension = ndx.dimension(function (d) {
    return d.Category;
});

var YDimension = XDimension.group().reduceCount(function (d) {
    return d.value;
});


dc.barChart("#Chart")
    .width(480).height(300)
    .dimension(XDimension)
    .group(YDimension)
    .transitionDuration(500)
    .xUnits(dc.units.ordinal)
    .label(function(d) {return d.value})
    .x(d3.scale.ordinal().domain(XDimension)) 

dc.renderAll();
like image 372
Koba Avatar asked Jul 29 '14 22:07

Koba


People also ask

How do you show a value on top of a bar chart?

Add data labels Click the chart, and then click the Chart Design tab. Click Add Chart Element and select Data Labels, and then select a location for the data label option. Note: The options will differ depending on your chart type. If you want to show your data label inside a text bubble shape, click Data Callout.

How do I show labels on top of bar chart in tableau?

On the Marks card, click Label, and then select Show mark labels. To add another field to the mark labels, drag that field to Label on the Marks card.


2 Answers

Check updated jsfiddle

.renderlet(function(chart){

    var barsData = [];
    var bars = chart.selectAll('.bar').each(function(d) { barsData.push(d); });

    //Remove old values (if found)
    d3.select(bars[0][0].parentNode).select('#inline-labels').remove();
    //Create group for labels 
    var gLabels = d3.select(bars[0][0].parentNode).append('g').attr('id','inline-labels');

    for (var i = bars[0].length - 1; i >= 0; i--) {

        var b = bars[0][i];
        //Only create label if bar height is tall enough
        if (+b.getAttribute('height') < 18) continue;
        
        gLabels
            .append("text")
            .text(barsData[i].data.value)
            .attr('x', +b.getAttribute('x') + (b.getAttribute('width')/2) )
            .attr('y', +b.getAttribute('y') + 15)
            .attr('text-anchor', 'middle')
            .attr('fill', 'white');
    }

})

If you don't want the labels visible when the bars redraw (for example when bars change after user filters/clicks other chart) you can move the check of old values from de renderlet to the to a preRedraw listener.

.on("preRedraw", function(chart){

    //Remove old values (if found)
    chart.select('#inline-labels').remove();

})

Alternative

D3-ish way

Demo jsfiddle

.renderlet(function (chart) {
    
    //Check if labels exist
    var gLabels = chart.select(".labels");
    if (gLabels.empty()){
        gLabels = chart.select(".chart-body").append('g').classed('labels', true);
    }
    
    var gLabelsData = gLabels.selectAll("text").data(chart.selectAll(".bar")[0]);
    
    gLabelsData.exit().remove(); //Remove unused elements
    
    gLabelsData.enter().append("text") //Add new elements
    
    gLabelsData
    .attr('text-anchor', 'middle')
    .attr('fill', 'white')
    .text(function(d){
        return d3.select(d).data()[0].data.value
    })
    .attr('x', function(d){ 
        return +d.getAttribute('x') + (d.getAttribute('width')/2); 
    })
    .attr('y', function(d){ return +d.getAttribute('y') + 15; })
    .attr('style', function(d){
        if (+d.getAttribute('height') < 18) return "display:none";
    });
    
})
like image 64
dimirc Avatar answered Nov 03 '22 23:11

dimirc


In dc.js version 3.* . You can just use .renderLabel(true). It will print the value at top

like image 37
Alauddin Ahmed Avatar answered Nov 03 '22 23:11

Alauddin Ahmed