Search code examples
javascriptchartsbar-chartgoogle-visualization

Want to add top padding on annotation text in bar chart in Google Chart (Visualization)


I am using Google Chart's bar graph chart. There are annotation for every bar at the top, inside of the bar and I want create more space (more than default) between bar top line and annotation text. I have not find any way to create top padding (or top margin) around annotation text.

Here is my code:

var data = google.visualization.arrayToDataTable([
                [USER_AVERAGE, 'User Average', { role: 'style' }],
                ['SANDRA COOMBS', 8.6, '#008FBE'],
                ['STEVE ADAMS', 4.3, '#008FBE'],
            ]);

            var view = new google.visualization.DataView(data);
            view.setColumns([0, 1, 2,
                {
                    calc: "stringify",
                    sourceColumn: 1,
                    type: "string",
                    role: "annotation"
                }]);
            var options = {
                legend: {
                    position: 'none'
                },
                chartArea: { width: width, height: height, right: right },
                isStacked: true,
                orientation: orientation.orientation,
                fontSize: '12',
                fontName: 'OpenSans-Regular',
                hAxis: {
                    viewWindowMode: 'maximized',
                },
                vAxis: {
                    viewWindowMode: 'maximized',
                },
                animation: {
                    startup: true,
                    duration: 1500,
                    easing: 'out',
                },
            };
            var chart = new google.visualization.ColumnChart(document.getElementById("averageDaysChart"));
            chart.draw(view.toDataTable(), options);

Solution

  • there are no config options for annotation padding, position, or the like...

    however, you can move them manually on the chart's 'animationfinish' event
    but, a MutationObserver must be used,
    because the chart will move them back on interactivity,
    such as when you hover the column.

    see following working snippet for an example of moving the annotations...

    google.charts.load('current', {
      packages: ['corechart']
    }).then(function () {
      var data = google.visualization.arrayToDataTable([
          ['USER_AVERAGE', 'User Average', { role: 'style' }],
          ['SANDRA COOMBS', 8.6, '#008FBE'],
          ['STEVE ADAMS', 4.3, '#008FBE'],
      ]);
    
      var view = new google.visualization.DataView(data);
      view.setColumns([0, 1, 2,
          {
              calc: "stringify",
              sourceColumn: 1,
              type: "string",
              role: "annotation"
          }]);
      var options = {
          legend: {
              position: 'none'
          },
          //chartArea: { width: width, height: height, right: right },
          isStacked: true,
          //orientation: orientation.orientation,
          fontSize: '12',
          fontName: 'OpenSans-Regular',
          hAxis: {
              viewWindowMode: 'maximized',
          },
          vAxis: {
              viewWindowMode: 'maximized',
          },
          animation: {
              startup: true,
              duration: 1500,
              easing: 'out',
          },
      };
    
      var container = document.getElementById("averageDaysChart");
      var chart = new google.visualization.ColumnChart(container);
    
      google.visualization.events.addListener(chart, 'animationfinish', function () {
        moveAnnotations();
        var observer = new MutationObserver(moveAnnotations);
        observer.observe(container, {
          childList: true,
          subtree: true
        });
      });
    
      var originalY = {};
      function moveAnnotations() {
        var labels = container.getElementsByTagName('text');
        Array.prototype.forEach.call(labels, function(label) {
          if ((!isNaN(parseFloat(label.textContent))) && (label.getAttribute('text-anchor') === 'middle')) {
            if (!originalY.hasOwnProperty(label.textContent)) {
              originalY[label.textContent] = parseFloat(label.getAttribute('y'));
            }
            label.setAttribute('y', originalY[label.textContent] + 20);
          }
        });
      }
    
      chart.draw(view.toDataTable(), options);
    });
    <script src="https://www.gstatic.com/charts/loader.js"></script>
    <div id="averageDaysChart"></div>