1

I'm trying to draw a line chart with both negative and positive values which maps it on the respective quadrants with the same color, but I want to change the color of lines above and below the x-axis.

        var data = new google.visualization.DataTable();
        data.addColumn("string", "Year");
        data.addColumn("number", "Effective Investible Surplus");            
        data.addRows(dataSet);
        this.formatNumber.format(data,1);//indian currency format
        var options = {
            legend: this.legendStyle,
            areaOpacity: 0.8,
            backgroundColor: '#f5f1e7',
            animation: {
                startup: true,
                duration: 300,
                easing: 'linear',
            },
            hAxis: {
                title: "Years",
                titleTextStyle: this.chartTitleText
            },
            vAxis: {
                title: "Rupees",
                titleTextStyle: this.chartTitleText,
                format: this.numberPattern
            },
            colors: ["#b3dda7"]
        };
        var chart = new google.visualization.AreaChart(
            document.getElementById("chart_div")
        );
        chart.draw(data, options);
    });
WhiteHat
  • 59,912
  • 7
  • 51
  • 133

1 Answers1

0

first, in order to change the color of a single series,
you will need to use a 'style' role.
we can use a data view with a calculated column to determine which color each row should be.

however, due to the nature of how the area chart is drawn,
you will need to insert a row with a y-axis value of 0,
every where the value crosses the x-axis.
otherwise, you will have an area that is split in half with each color.

next, since you are using a string for the x-axis (discrete axis),
we will have repeating labels every where we had to insert a new row.

to avoid, we can use option hAxis.showTextEvery with a value of 2.
this will prevent repeating labels,
but will also cause some labels not to appear.

see following working snippet...

google.charts.load('current', {
  packages: ['corechart']
}).then(function () {
  var dataSet = [
    ['2010', 0],
    ['2011', 20],
    ['2012', -40],
    ['2013', 10],
    ['2014', -10],
    ['2015', 20],
    ['2016', 10],
    ['2017', -20],
    ['2018', 20],
    ['2019', -20]
  ];

  // add a value of zero where the value crosses the x-axis
  for (var i = (dataSet.length - 1); i >= 0; i--) {
    var val = dataSet[i][1];
    if ((i-1) >= 0) {
      var nextVal = dataSet[i-1][1];
      if ((val >= 0) && (nextVal < 0)) {
        dataSet.splice(i, 0, [dataSet[i][0], 0]);
      } else if ((val < 0) && (nextVal >= 0)) {
        dataSet.splice(i, 0, [dataSet[i][0], 0]);
      }
    }
  }


  var data = new google.visualization.DataTable();
  data.addColumn('string', 'Year');
  data.addColumn('number', 'Effective Investible Surplus');
  data.addRows(dataSet);

  // create data view to add color
  var dataView = new google.visualization.DataView(data);
  dataView.setColumns([
    // include x & y column index
    0, 1,
    // add calculated color
    {
      calc: function(data, row) {
        var color = '#b3dda7';
        var val = data.getValue(row, 1);
        var nextVal = 0;
        if (row > 0) {
          nextVal = data.getValue(row - 1, 1);
        }
        if ((val < 0) || ((val === 0) && (nextVal < 0))) {
          color = '#f08080';
        }
        return color;
      },
      type: 'string',
      role: 'style'
    }
  ]);

  var options = {
    legend: 'none',
    areaOpacity: 0.8,
    backgroundColor: '#f5f1e7',
    animation: {
      startup: true,
      duration: 300,
      easing: 'linear',
    },
    hAxis: {
      title: 'Years',
      format: '0000',
      showTextEvery: 2
    },
    vAxis: {
      title: 'Rupees'
    }
  };

  var chart = new google.visualization.AreaChart(document.getElementById("chart"));
  chart.draw(dataView, options);
});
<div id="chart"></div>
<script src="https://www.gstatic.com/charts/loader.js"></script>
WhiteHat
  • 59,912
  • 7
  • 51
  • 133
  • Exactly this is what I needed, much appreciated.One more thing Is there any way we can set the backgroundColor for chartArea below x-axis ? – Santosh Ranjan Oct 22 '19 at 07:20
  • there are no options for this, but you can add another area series, with a value of the max negative value for every row. [here is an example](https://stackoverflow.com/a/39671447/5090771)... – WhiteHat Oct 22 '19 at 11:08
  • is there a way i can add a new legend for the negative values with the legend color same as for the line color below x axis ? – Santosh Ranjan Dec 26 '19 at 09:42
  • Check [this answer](https://stackoverflow.com/a/36064828/5090771)... – WhiteHat Dec 26 '19 at 16:21