Google Charts stacked columns with different annotations for each piece of the column

user2888319 picture user2888319 · Jan 16, 2014 · Viewed 9.6k times · Source

I hope you can help me with this:

I have a chart of stacked columns, all of them with two values to stack in each column. I have successfully created the chart BUT I need to add an annotation for each piece of each column (I don't know the proper name for it) indicating the percentage of the total represented by the piece in it's own column.

In the example given below, I would need to set the annotations so it would show the stacked columns and, for the first column should have an annotation on the "Good" area with value "60%" and another annotation for the "Bad" area of "40%", and so on.

So far, I have managed to include one annotation that shows the percentage value for the "Bad" area, which floates to the top of each column. I would need help to properly define the annotation for each area of the column and, hopefully, place it centered in it's given area.

Thank you in advance for your help.

TL;DR: I need centered annotations for each piece of each column.

<body>
        <div id="chart" style="width: 900px; height: 500px; border: 1px solid black;">
        </div>
    </body>
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<script type="text/javascript">
    google.load("visualization", "1", { packages: ["corechart"] });
    google.setOnLoadCallback(drawChart);
    function drawChart() {
        var data = google.visualization.arrayToDataTable([
          ['Date', 'Good', 'Bad'],
          [Date(2013, 11, 1), 3, 2],
          [Date(2013, 11, 2), 5, 3],
          [Date(2013, 11, 3), 9, 2],
          [Date(2013, 11, 4), 6, 3]
        ]);

        var view = new google.visualization.DataView(data);

        view.setColumns([{
            label: 'Date',
            type: 'string',
            calc: function (dt, row) {
                var str = dt.getValue(row, 0);
                return { v: str, f: str.toString('dd/MM/aaaa') };
            }
        }
             , {
                 label: 'Good',
                 type: 'number',
                 calc: function (dt, row) {
                     var good = dt.getValue(row, 1);
                     var bad = dt.getValue(row, 2);
                     return { v: good / (good + bad), f: good.toString() };
                 }
             }, {
                 label: 'Bad',
                 type: 'number',
                 calc: function (dt, row) {
                     var good = dt.getValue(row, 1);
                     var bad = dt.getValue(row, 2);
                     return { v: bad / (good + bad), f: bad.toString() };
                 }
             },
             {
                 role: 'annotation',
                 type: 'string',
                 calc: function (dt, row) {
                     var good = dt.getValue(row, 1);
                     var bad = dt.getValue(row, 2);
                     var perc = (bad / (good + bad)) * 100;
                     var ann = parseFloat(Math.round(perc).toFixed(2)) + "%";
                     return { v: ann, f: ann.toString() };
                 }
             }]);

        var options = {
            title: 'Daily deeds',
            isStacked: true,
            vAxis: { format: '#.##%' }
        };

        var chart = new google.visualization.ColumnChart(document.getElementById('chart'));
        chart.draw(view, options);
    }
</script>

Answer

asgallant picture asgallant · Jan 16, 2014

You need to add another annotation column after your "Good" column:

view.setColumns([{
    label: 'Date',
    type: 'string',
    calc: function (dt, row) {
        var str = dt.getValue(row, 0);
        return { v: str, f: str.toString('dd/MM/aaaa') };
    }
}, {
    label: 'Good',
    type: 'number',
    calc: function (dt, row) {
        var good = dt.getValue(row, 1);
        var bad = dt.getValue(row, 2);
        return { v: good / (good + bad), f: good.toString() };
    }
}, {
    role: 'annotation',
    type: 'string',
    calc: function (dt, row) {
        var good = dt.getValue(row, 1);
        var bad = dt.getValue(row, 2);
        var perc = (good / (good + bad)) * 100;
        var ann = perc.toFixed(2) + "%";
        return ann;
    }
}, {
    label: 'Bad',
    type: 'number',
    calc: function (dt, row) {
        var good = dt.getValue(row, 1);
        var bad = dt.getValue(row, 2);
        return { v: bad / (good + bad), f: bad.toString() };
    }
}, {
    role: 'annotation',
    type: 'string',
    calc: function (dt, row) {
        var good = dt.getValue(row, 1);
        var bad = dt.getValue(row, 2);
        var perc = (bad / (good + bad)) * 100;
        var ann = perc.toFixed(2) + "%";
        return ann;
    }
}]);