Khrys
Khrys

Reputation: 2774

Change the bar color in gantt chat based on value

I would like to change the color of the bar in the gantt chart based in the value I am passing. When Percent done equals of higher than 100 the bar should be red. Is it possible?

https://jsfiddle.net/1cez1duf/

google.charts.load('current', {'packages':['gantt'], 'language': 'pt-br'});
google.charts.setOnLoadCallback(drawChart);

function drawChart() {

    var data = new google.visualization.DataTable();
    data.addColumn('string', 'Task ID');
    data.addColumn('string', 'Task Name');
    data.addColumn('string', 'Resource');
    data.addColumn('date', 'Start Date');
    data.addColumn('date', 'End Date');
    data.addColumn('number', 'Duration');
    data.addColumn('number', 'Percent done');
    data.addColumn('string', 'Dependencies');

    data.addRows([    
        ['C10', 'C10', 'Xa', new Date(2015, 3, 20), new Date(2016, 8, 30), null, 109, null],
        ['C15', 'C15', 'Xa', new Date(2016, 5, 2), new Date(2016, 9, 31), null, 111, null],
        ['C20', 'C20', 'Xa', new Date(2016, 8, 15), new Date(2016, 10, 25), null, 88, null],
        ['C21', 'C21', 'Xa', new Date(2016, 8, 1), new Date(2016, 10, 25), null, 90, null]
    ]);

    var options = {
        width: "100%",
        hAxis: {
            textStyle: {
                fontName: ["Roboto Condensed"]
            }
        },
        gantt: {
            labelStyle: {
                fontSize: 12,
                color: '#757575'
            }
        }
    };

    var chart = new google.visualization.Gantt(document.getElementById('chart_div'));
    chart.draw(data, options);
}

Upvotes: 2

Views: 2064

Answers (1)

WhiteHat
WhiteHat

Reputation: 61222

there aren't any standard options to change bar color by value

but you can change the chart elements manually

recommend using a MutationObserver as the chart will try to change the bar color back to the default, on any interactivity such as hover or select

the order of the bars should follow the rows in the data

see following working snippet...

google.charts.load('current', {
  callback: drawChart,
  packages: ['gantt']
});

function drawChart() {
  var data = new google.visualization.DataTable();
  data.addColumn('string', 'Task ID');
  data.addColumn('string', 'Task Name');
  data.addColumn('string', 'Resource');
  data.addColumn('date', 'Start Date');
  data.addColumn('date', 'End Date');
  data.addColumn('number', 'Duration');
  data.addColumn('number', 'Percent done');
  data.addColumn('string', 'Dependencies');

  data.addRows([

  ['C10', 'C10', 'Xa', new Date(2015, 3, 20), new Date(2016, 8, 30), null, 109, null],
  ['C15', 'C15', 'Xa', new Date(2016, 5, 2), new Date(2016, 9, 31), null, 111, null],
  ['C20', 'C20', 'Xa', new Date(2016, 8, 15), new Date(2016, 10, 25), null, 88, null],
  ['C21', 'C21', 'Xa', new Date(2016, 8, 1), new Date(2016, 10, 25), null, 90, null]
  ]);

  var options = {
    width: '100%',
    hAxis: {
      textStyle: {
        fontName: ['Roboto Condensed']
      }
    },
    gantt: {
      labelStyle: {
        fontSize: 12,
        color: '#757575'
      }
    }
  };

  var container = document.getElementById('chart_div');
  var chart = new google.visualization.Gantt(container);

  // monitor activity, change bar color
  var observer = new MutationObserver(function (mutations) {
    Array.prototype.forEach.call(container.getElementsByTagName('path'), function(bar, index) {
      if (data.getValue(index, 6) > 100) {
        bar.setAttribute('fill', '#a52714');
      }
    });
  });
  observer.observe(container, {
    childList: true,
    subtree: true
  });

  chart.draw(data, options);
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div"></div>

EDIT

it appears when there is partial completion, the "bar" is split with two colors
the lighter shade being represented by a 'rect' element
you could change this to a lighter shade of red
use the Y coordinate of the 'path' to find the correct 'rect'

also, need to sort the data in the same order as displayed in the chart...

see following working snippet...

google.charts.load('current', {
  callback: drawChart,
  packages: ['gantt']
});

function drawChart() {
  var data = new google.visualization.DataTable();
  data.addColumn('string', 'Task ID');
  data.addColumn('string', 'Task Name');
  data.addColumn('string', 'Resource');
  data.addColumn('date', 'Start Date');
  data.addColumn('date', 'End Date');
  data.addColumn('number', 'Duration');
  data.addColumn('number', 'Percent done');
  data.addColumn('string', 'Dependencies');

  data.addRows([
    ['C10', 'C10', 'Xa', new Date(2016, 2, 23), new Date(2016, 10, 30), null, 94.84, null],
    ['C15', 'C15', 'Xa', new Date(2016, 4, 1), new Date(2016, 11, 29), null, 82.64, null],
    ['C20', 'C20', 'Xa', new Date(2016, 7, 1), new Date(2016, 10, 25), null, 93.1, null],
    ['C25', 'C25', 'Xa', new Date(2016, 3, 11), new Date(2016, 10, 25), null, 96.49, null],
    ['C30', 'C30', 'Xa', new Date(2016, 9, 3), new Date(2017, 1, 28), null, 30.41, null],
    ['C35', 'C35', 'Xa', new Date(2016, 3, 8), new Date(2016, 5, 24), null, 113.78, null]
  ]);
  data.sort([{column: 3}]);

  var w = window,
    d = document,
    e = d.documentElement,
    g = d.getElementsByTagName('body')[0],
    xWidth = w.innerWidth || e.clientWidth || g.clientWidth,
    yHeight = w.innerHeight|| e.clientHeight|| g.clientHeight;

  var options = {
    height: 600,
    width: "100%",
    hAxis: {
      textStyle: {
        fontName: ["Roboto Condensed"]
      }
    },
    gantt: {
      labelStyle: {
      fontName: ["Roboto Condensed"],
      fontSize: 12,
      color: '#757575'
      }
    }
  };
  var container = document.getElementById('chart_div');
  var chart = new google.visualization.Gantt(container);

  // monitor activity, change bar color
  var observer = new MutationObserver(function (mutations) {
    Array.prototype.forEach.call(container.getElementsByTagName('path'), function(bar, index) {
      var barY;
      if (data.getValue(index, 6) > 100) {
        bar.setAttribute('fill', '#b71c1c');
        barY = bar.getAttribute('d').split(' ')[2];
        Array.prototype.forEach.call(container.getElementsByTagName('rect'), function(bar) {
          if (bar.getAttribute('y') === barY) {
            bar.setAttribute('fill', '#f44336');
          }
        });
      }
    });
  });
  observer.observe(container, {
    childList: true,
    subtree: true
  });

  chart.draw(data, options);
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div"></div>

Upvotes: 2

Related Questions