javascriptasp.net-corechartsgoogle-visualization

How to display bar label as the absolute value instead of a negative value using Google Charts API JavaScript in ASP.NET


I have a stacked bar chart that I would like to change the displayed bar label value to the absolute value instead of the negative value. I use the negative value only to draw the chart correctly, however, the true value is not a negative.

enter image description here

Ignoring the positional error for the gray bar label, how do I change the displayed value of -676 to the absolute value (676) for both the chart view and the mouse over display?

JavaScript:

<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
  <script type="text/javascript">

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

      function drawChart() {
          var data = new google.visualization.DataTable();

          var jsonList = @(Json.Serialize(Model.listAllAircraftChartQuarterly))

          var title = 'Quarterly Aircraft Transaction Trend';

          data.addColumn('string', 'Quarter');
          data.addColumn('number', '2023');
          data.addColumn('number', '2022');
          data.addColumn('number', '% Change');
          data.addRows(jsonList.map((p) => {
              return [p.yearQuarter, p.year2top, p.year3bottom, p.year2percent];
          }));

          var formatPercent = new google.visualization.NumberFormat({ pattern: '#.#%' });
          formatPercent.format(data, 3);

          var view = new google.visualization.DataView(data);
          view.setColumns([0, 1,
              {
                  calc: "stringify",
                  sourceColumn: 1,
                  type: "string",
                  role: "annotation"
              },
              2,
              {
                  calc: "stringify",
                  sourceColumn: 2,
                  type: "string",
                  role: "annotation"
              },
              3,
              {
                  calc: "stringify",
                  sourceColumn: 3,
                  type: "string",
                  role: "annotation"
              }
          ]);
          var options = {
              title: title,
              titlePosition: 'out',
              isStacked: true,

              seriesType: "bars",
              vAxes: {
                  0: {
                      textPosition: 'out',
                      viewWindowMode: 'pretty',
                      title: "",
                      viewWindow: { min: -1100, max: 1100 },
                      gridlines: { color: 'lightgray' },
                  },
                  1: {
                      textPosition: 'out',
                      viewWindow: { min: -1, max: 1 },
                      format: 'percent',
                      gridlines: { color: 'transparent' }
                  },
              },
              series: {
                  0: { targetAxisIndex: 0, color: 'blue' },
                  1: { targetAxisIndex: 0, color: 'gray' },
                  2: { targetAxisIndex: 1, color: 'red', type: 'line', lineWidth: 1, lineDashStyle: [4, 4], pointSize: 5 },
              },
              width: '100%',
              height: '300',

              legend: { position: 'top' },
              chartArea: {
                  height: '100%',
                  width: '100%',
                  top: 48,
                  left: 60,
                  right: 60,
                  bottom: 75
              },
              annotations: {
                  highContrast: false,
                  textStyle: {
                      color: 'red',
                      fontSize: 12,
                      bold: true
                  },
                  alwaysOutside: true
              },
          }

          var chart = new google.visualization.ComboChart(document.getElementById('primaryYear2and3'));
          chart.draw(view, options);

          document.getElementById('downloadimg2and3').innerHTML = '<a download="google-chart-image" href="' + chart.getImageURI() +
              '"><button type="button" class="btn btn-outline-dark btn-sm opacity-25 ms-4 mb-3">Download Chart Image</button></a>';

          window.addEventListener('resize', drawChart, false);
      }
  </script>

Researched existing posts for absolute value and Math.abs() usage.


Solution

  • you can use Math.abs(numberValue) to get the absolute value of a number.

    as for using this in the chart for display purposes,
    you can use google's NumberFormat class

    first, the chart uses the formatted value of the number for the annotation and the value displayed on hover.

    if no formatted value is provided, then it uses a default formatted value,
    which is just the number converted to a string.

    in this case, we want to format the value while loading the data table.

    first, create the number formatter...

    var formatNumber = new google.visualization.NumberFormat({ pattern: '#,##0' });
    

    then while loading the data table, we can provide both the value (v) and the formatted value (f) using object notation.
    and we use the formatValue method from the NumberFormat class to get the formatted value for each number, passing it the absolute value.

    data.addRows(jsonList.map((p) => {
       return [
         p.yearQuarter,
         p.year2top,
         {v: p.year3bottom, f: formatNumber.formatValue(Math.abs(p.year3bottom))},
         p.year2percent
       ];
    }));
    

    see following working snippet...

    google.charts.load('current', {
      packages: ['corechart']
    }).then(drawChart);
    
    function drawChart() {
      var data = new google.visualization.DataTable();
    
      //var jsonList = @(Json.Serialize(Model.listAllAircraftChart))
      var jsonList = [
        {yearQuarter: 'Quarter 1', year2top: 469, year3bottom: -676, year2percent: -0.306},
        {yearQuarter: 'Quarter 2', year2top: 580, year3bottom: -739, year2percent: -0.215},
        {yearQuarter: 'Quarter 3', year2top: 566, year3bottom: -623, year2percent: -0.091},
        {yearQuarter: 'Quarter 4', year2top: 817, year3bottom: -800, year2percent: -0.01}
      ];
    
      var title = 'Quarterly Aircraft Transaction Trend';
    
      var formatNumber = new google.visualization.NumberFormat({ pattern: '#,##0' });
    
      data.addColumn('string', 'Quarter');
      data.addColumn('number', '2023');
      data.addColumn('number', '2022');
      data.addColumn('number', '% Change');
      data.addRows(jsonList.map((p) => {
         return [
           p.yearQuarter,
           p.year2top,
           {v: p.year3bottom, f: formatNumber.formatValue(Math.abs(p.year3bottom))},
           p.year2percent
         ];
      }));
    
      var formatPercent = new google.visualization.NumberFormat({ pattern: '#.#%' });
      formatPercent.format(data, 3);
    
      var view = new google.visualization.DataView(data);
      view.setColumns([0, 1,
         {
             calc: "stringify",
             sourceColumn: 1,
             type: "string",
             role: "annotation"
         },
         2,
         {
             calc: "stringify",
             sourceColumn: 2,
             type: "string",
             role: "annotation"
         },
         3,
         {
             calc: "stringify",
             sourceColumn: 3,
             type: "string",
             role: "annotation"
         }
      ]);
      var options = {
         title: title,
         titlePosition: 'out',
         isStacked: true,
    
         seriesType: "bars",
         vAxes: {
             0: {
                 textPosition: 'out',
                 viewWindowMode: 'pretty',
                 title: "",
                 viewWindow: { min: -1100, max: 1100 },
                 gridlines: { color: 'lightgray' },
             },
             1: {
                 textPosition: 'out',
                 viewWindow: { min: -1, max: 1 },
                 format: 'percent',
                 gridlines: { color: 'transparent' }
             },
         },
         series: {
             0: { targetAxisIndex: 0, color: 'blue' },
             1: { targetAxisIndex: 0, color: 'gray', annotations: {stem: {length: -80}} },
             2: { targetAxisIndex: 1, color: 'red', type: 'line', lineWidth: 1, lineDashStyle: [4, 4], pointSize: 5 },
         },
         width: '100%',
         height: '300',
    
         legend: { position: 'top' },
         chartArea: {
             height: '100%',
             width: '100%',
             top: 48,
             left: 60,
             right: 60,
             bottom: 75
         },
         annotations: {
             highContrast: false,
             textStyle: {
                 color: 'red',
                 fontSize: 12,
                 bold: true
             },
             alwaysOutside: true
         },
      }
    
      var chart = new google.visualization.ComboChart(document.getElementById('primaryYear2and3'));
      chart.draw(view, options);
    
      google.visualization.events.addListener(chart, 'ready', function () {
        document.getElementById('downloadimg2and3').innerHTML = '<a download="google-chart-image" href="' + chart.getImageURI() +
           '"><button type="button" class="btn btn-outline-dark btn-sm opacity-25 ms-4 mb-3">Download Chart Image</button></a>';
      });
    
      window.addEventListener('resize', drawChart, false);
    }
    <script src="https://www.gstatic.com/charts/loader.js"></script>
    <div id="primaryYear2and3"></div>
    <div id="downloadimg2and3"></div>