Search code examples
chartsgoogle-visualization

Add percentage change between two points annotation to chart while maintaining value points


I have the following chart that calculates premium for each month.

<script type="text/javascript">
    google.load("visualization", "1", { packages: ["corechart"] });
    google.setOnLoadCallback(drawChart);
    function drawChart() {



        var options = {
            title: 'Monthly Total Production',
            curveType: 'function',
            legend: { position: 'bottom' },
            height: 600,
            vAxis: {
                viewWindow: { min: 0 },
                format: 'currency',
            },




        };
        $.ajax({

            type: "POST",
            url: "url",
            data: '{}',
            contentType: "application/json; charset=utf-8",
            dataType: "json",
            success: function (r) {
                var data = google.visualization.arrayToDataTable(r.d);
                var chart = new google.visualization.LineChart($("#monthlyProductionChart")[0]);
                var view = new google.visualization.DataView(data);
                view.setColumns([0, 1, {
                    calc: "stringify",
                    sourceColumn: 1,
                    type: "string",
                    role: "annotation"
                },]);
                chart.draw(view, options);
            },
            failure: function (r) {
                alert(r.d);
            },
            error: function (r) {
                alert(r.d);
            }
        });
    }


</script>

Result:

enter image description here

Currently the chart displays the premium correctly for each month. However, I want to add an annotation that calculates the percentage change between every two points.

Example output:

enter image description here

Thanks


Solution

  • when using a calculated column for setColumns,
    you can use a custom function, instead of the calc: "stringify"

    the function will receive two arguments,
    the data table and the row index.
    the function should return the value to be displayed (the annotation).

    view.setColumns([0, 1, {
      calc: function (dt, row) {
        if (row > 0) {
          var valCur = dt.getValue(row, 1);
          var valPrev = dt.getValue(row - 1, 1);
          if (valPrev > 0) {
            return formatNumber.formatValue((valCur - valPrev) / valPrev);
          }
        }
        return null;
      },
      role: 'annotation',
      type: 'string'
    }]);
    

    see following working snippet...

    google.charts.load('current', {
      packages: ['corechart']
    }).then(function () {
      var data = google.visualization.arrayToDataTable([
        ['Month', 'Value'],
        ['Jan', 10],
        ['Feb', 30],
        ['Mar', 45],
        ['Apr', 50],
        ['May', 55],
        ['Jun', 45]
      ]);
    
      var formatNumber = new google.visualization.NumberFormat({
        pattern: '#,##0%'
      });
    
      var view = new google.visualization.DataView(data);
      view.setColumns([0, 1, {
        calc: function (dt, row) {
          if (row > 0) {
            var valCur = dt.getValue(row, 1);
            var valPrev = dt.getValue(row - 1, 1);
            if (valPrev > 0) {
              return formatNumber.formatValue((valCur - valPrev) / valPrev);
            }
          }
          return null;
        },
        role: 'annotation',
        type: 'string'
      }]);
    
      var chart = new google.visualization.LineChart(document.getElementById('chart_div'));
      chart.draw(view);
    });
    <script src="https://www.gstatic.com/charts/loader.js"></script>
    <div id="chart_div"></div>