Color in Google's Timeline Chart bars based in the a specific value

Khrys picture Khrys · Apr 24, 2014 · Viewed 16.5k times · Source

I would like to create groups of colors for the bars. The example below is raw. I would like to add a column with a category type, and based on that category I will color the bar.

Something like:

Column

dataTable.addColumn({ type: 'string', id: 'Category' });

Line

[ 'GROUP #1', 'CategoryA', 'C00001', new Date(2014, 0, 1), new Date(2014, 0, 31) ],
[ 'GROUP #1', 'CategoryA', 'C00002', new Date(2014, 1, 1), new Date(2014, 1, 28) ],
[ 'GROUP #1', 'CategoryA', 'C00003', new Date(2014, 3, 1),  new Date(2014, 3, 15) ],
[ 'GROUP #1', 'CategoryB', 'C00003', new Date(2014, 0, 21),  new Date(2014, 2, 19) ],
[ 'GROUP #1', 'CategoryA', 'C00004', new Date(2014, 0, 1),  new Date(2014, 0, 15) ],
[ 'GROUP #2', 'CategoryC', 'C00005', new Date(2014, 2, 8),  new Date(2014, 2, 15) ],
[ 'GROUP #3', 'CategoryC', 'C00006', new Date(2014, 5, 1),  new Date(2014, 5, 15) ],
[ 'GROUP #4', 'CategoryA', 'C00007', new Date(2014, 1, 15),  new Date(2014, 1, 25) ]]);

Based on Category the bar should have a specific color.

Fiddle

google.load("visualization", "1", {packages: ["timeline"]});
google.setOnLoadCallback(drawChart);

function drawChart() {
    var container = document.getElementById('example4.2');
    var chart = new google.visualization.Timeline(container);
    var dataTable = new google.visualization.DataTable();

    dataTable.addColumn({ type: 'string', id: 'Group' });
    dataTable.addColumn({ type: 'string', id: 'ID' });
    dataTable.addColumn({ type: 'date', id: 'Start' });
    dataTable.addColumn({ type: 'date', id: 'End' });
    dataTable.addRows([
        [ 'GROUP #1', 'C00001', new Date(2014, 0, 1), new Date(2014, 0, 31) ],
        [ 'GROUP #1', 'C00002', new Date(2014, 1, 1), new Date(2014, 1, 28) ],
        [ 'GROUP #1', 'C00003', new Date(2014, 3, 1),  new Date(2014, 3, 15) ],
        [ 'GROUP #1', 'C00003', new Date(2014, 0, 21),  new Date(2014, 2, 19) ],
        [ 'GROUP #1', 'C00004', new Date(2014, 0, 1),  new Date(2014, 0, 15) ],
        [ 'GROUP #2', 'C00005', new Date(2014, 2, 8),  new Date(2014, 2, 15) ],
        [ 'GROUP #3', 'C00006', new Date(2014, 5, 1),  new Date(2014, 5, 15) ],
        [ 'GROUP #4', 'C00007', new Date(2014, 1, 15),  new Date(2014, 1, 25) ]]);

    var rowHeight = 41;
    var chartHeight = (dataTable.getNumberOfRows() + 1) * rowHeight;

    var options = {
        timeline: { 
            groupByRowLabel: true,
            rowLabelStyle: {
                fontName: 'Roboto Condensed',
                fontSize: 14,
                color: '#333333'
            },
            barLabelStyle: {
                fontName: 'Roboto Condensed',
                fontSize: 14
            }
        },                          
        avoidOverlappingGridLines: true,
        height: chartHeight,
        width: '100%'
    };

    chart.draw(dataTable, options);
}

Answer

asgallant picture asgallant · May 6, 2014

There's nothing in the Timeline visualization that will do this for you, but you can set the colors option to whatever you need to get the bars the right color. You can parse the DataTable to build the colors array, and then use a DataView to hide your category column from the Timeline (since the Timeline wouldn't know what to do with it). Here's an example:

function drawChart() {
    var container = document.getElementById('example4.2');
    var chart = new google.visualization.Timeline(container);
    var dataTable = new google.visualization.DataTable();

    dataTable.addColumn({ type: 'string', id: 'Group' });
    dataTable.addColumn({ type: 'string', id: 'Category' });
    dataTable.addColumn({ type: 'string', id: 'ID' });
    dataTable.addColumn({ type: 'date', id: 'Start' });
    dataTable.addColumn({ type: 'date', id: 'End' });
    dataTable.addRows([
        [ 'GROUP #1', 'CategoryA', 'C00001', new Date(2014, 0, 1), new Date(2014, 0, 31) ],
        [ 'GROUP #1', 'CategoryA', 'C00002', new Date(2014, 1, 1), new Date(2014, 1, 28) ],
        [ 'GROUP #1', 'CategoryA', 'C00003', new Date(2014, 3, 1),  new Date(2014, 3, 15) ],
        [ 'GROUP #1', 'CategoryB', 'C00003', new Date(2014, 0, 21),  new Date(2014, 2, 19) ],
        [ 'GROUP #1', 'CategoryA', 'C00004', new Date(2014, 0, 1),  new Date(2014, 0, 15) ],
        [ 'GROUP #2', 'CategoryC', 'C00005', new Date(2014, 2, 8),  new Date(2014, 2, 15) ],
        [ 'GROUP #3', 'CategoryC', 'C00006', new Date(2014, 5, 1),  new Date(2014, 5, 15) ],
        [ 'GROUP #4', 'CategoryA', 'C00007', new Date(2014, 1, 15),  new Date(2014, 1, 25) ]
    ]);

    var colors = [];
    var colorMap = {
        // should contain a map of category -> color for every category
        CategoryA: '#e63b6f',
        CategoryB: '#19c362',
        CategoryC: '#592df7'
    }
    for (var i = 0; i < dataTable.getNumberOfRows(); i++) {
        colors.push(colorMap[dataTable.getValue(i, 1)]);
    }

    var rowHeight = 41;
    var chartHeight = (dataTable.getNumberOfRows() + 1) * rowHeight;

    var options = {
        timeline: { 
            groupByRowLabel: true,
            rowLabelStyle: {
                fontName: 'Roboto Condensed',
                fontSize: 14,
                color: '#333333'
            },
            barLabelStyle: {
                fontName: 'Roboto Condensed',
                fontSize: 14
            }
        },                          
        avoidOverlappingGridLines: true,
        height: chartHeight,
        width: '100%',
        colors: colors
    };

    // use a DataView to hide the category column from the Timeline
    var view = new google.visualization.DataView(dataTable);
    view.setColumns([0, 2, 3, 4]);

    chart.draw(view, options);
}
google.load('visualization', '1', {packages:['timeline'], callback: drawChart});

See it working here: http://jsfiddle.net/asgallant/7A88H/