Google Visualization stacked bar chart: colors and labels for each value
Asked Answered
T

2

14

I'm using Google Visulaization API to render a chart showing a single row with multiple values, like this: Chart example

with the following code:

var data = google.visualization.arrayToDataTable([
           ['', '0%', '25%', '50%', '75%', '100%', {role: 'annotation'}],
           ['Mood', 3, 7, 20, 25, 45, '']
    ]);

var options = {
    isStacked: true,
    hAxis: { minValue: 0 }
}

var chart = new google.visualization.BarChart(document.getElementById('mood_chart'));
chart.draw(data, options);

Now I would like to customize the colors and add a label to every piece of the row.

If I do this:

var data = google.visualization.arrayToDataTable([
    ['', '0%', '25%', '50%', '75%', '100%', {role: 'annotation'}, {role: 'style'}],
    ['Mood', 3, 7, 20, 25, 45, 'ABC', '#f50']
]);

Then this only applies to the last value: (note the legend has also the wrong color) Second chart

And if I put an array of strings instead of a single label an error is given.

Is it possible to do what I am trying to do? How?

Throb answered 24/6, 2015 at 9:11 Comment(2)
I have an interactive demo for this answer here.Litalitany
Ooops, that was meant to start an answer.Litalitany
L
40

I have an interactive demo for this answer here.

The simple answer is that the annotation and style columns of the data table apply to the data column before them. Add annotation columns after each data column to add annotations to each value.

This is also why your colors differ from your legend. To apply colors to a series you do that from your options object. The style role of the data table affects an individual value without changing the option for the whole series.

var data = google.visualization.arrayToDataTable([
  ['', '0%', {role: 'annotation'}, '25%', {role: 'annotation'},
    '50%', {role: 'annotation'}, '75%', {role: 'annotation'},
    '100%', {role: 'annotation'}],
  ['Mood', 3, 'ABC', 7, 'DEF', 20, 'GHI', 25, 'JKL', 25, 'MNO']
]);

For assigning colors manually your options will look something like this:

var options = {
  isStacked: true,
  hAxis: {
    minValue: 0
  },
  series: {
    0:{color:'#222'},
    1:{color:'#555'},
    2:{color:'#888'},
    3:{color:'#AAA'},
    4:{color:'#EEE'}
  }
};

My colors were just random greys because I can calculate the colors in my head that way. The series index is independant of the data table column, so it just assigns indexes to columns with data values.

Litalitany answered 24/6, 2015 at 15:39 Comment(4)
Ooooh thanks! Could you please edit the answer and add also the code for the colors?Throb
I'll tinker around with that after lunch. I'm not sure if the series index will be the same as the column index when you have annotations like this, so I'll have to try it out.Litalitany
Added example of assigning a color to a series, and updated the plunk.Litalitany
Works like a charm! Thanks for this answer. I was looking for a solution like this! Weird that this is not mentioned in the Google chart api documentation.Ellipsoid
S
1

In case someone would like to add the color series from json, i found a way to do that. It took quite some time to figure it out for me so here goes if anyone can use it.

Problem is that arrays of colors cannot be of type Array but must be object with objects.

Fetching colors from Controller (ASP.Net MVC):

/*array for colors to be convertet later*/
var mycolors = new Array();

function getColors() {
        var postData = {};
        postData.Ids = {1,2,3};
        $.ajax({
            type: "POST",
            url: "@Url.Action("GoogleStackedBarchartColors", "MyController")",
            data: postData,
            dataType: "text",
            success: function (d, status, request) {
            /*some logging*/
            console.log(d);
            console.log($.parseJSON(d));

            var colors = $.parseJSON(d);
            /*I change the Type to object*/
            mycolors.__proto__ = Object; /*The magic part*/
            var i = 0;
            colors.forEach(function (element) {
                mycolors[i] = element;
                i = i + 1;
            });

And then in properties of the chart

var options = {

            width: '100%',
            height: 500,
            bar: { groupWidth: '75%' },
            bars: 'vertical',
            legend: { 'position': 'top', maxLines: 3 },
            isStacked: 'true',
            series: mycolors /*Here we have the object containing colors*/

        };
Scrutineer answered 20/4, 2018 at 10:6 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.