chartsgoogle-visualizationgoogle-barchart

Custom styling Google bar chart


Is there a possibility to accomplish a Google barchart to look like this?

enter image description here

  1. The end of each bar with custom styling
  2. Annotation comes below the line (GOAL 10.3)

Solution

  • you can use the chart layout method to add an icon, or any element, to the end of the bar.

      // add icon to bar
      var barBounds = layout.getBoundingBox('bar#0#0');
      var icon = chart.getContainer().appendChild(document.createElement('span'));
      icon.className = 'icon';
      icon.style.top = (barBounds.top + containerBounds.top - 3) + 'px';
      icon.style.left = (barBounds.left + containerBounds.left + (barBounds.width) - 24) + 'px';
      icon.innerHTML = '<i class="fas fa-arrow-alt-circle-right"></i>';
    

    also, instead of drawing the annotation and trying to prevent the chart from moving it,
    we can leave it out and add our own custom annotation...

      // add annotation
      var labelCopy = svg.getElementsByTagName('text')[0];
      var annotation = labelCopy.cloneNode(true);
      svg.appendChild(annotation);
      annotation.setAttribute('text-anchor', 'middle');
      annotation.textContent = data.getValue(0, data.getNumberOfColumns() -1);
      annotation.setAttribute('x', xLoc);
      annotation.setAttribute('y',
        layout.getYLocation(0) + (parseInt(annotation.getAttribute('font-size')) * 3)
      );
    

    see following working snippet...

    google.charts.load('current', {
      packages: ['corechart']
    }).then(drawHorizontalChart_portal_name_stella_york_horz_month_points);
    
    function drawHorizontalChart_portal_name_stella_york_horz_month_points() {
        var data = google.visualization.arrayToDataTable([
            ["", "Goal Achieved", {role: 'style'}, "GOAL 13.1 points", {role: 'style'}, {role: 'annotation'}],
            [1, 1.5, "opacity: .75;", 13.1, "opacity: 0;", "GOAL 13.1 points"]
        ]);
    
        var view = new google.visualization.DataView(data);
        view.setColumns([0, 1, 3, 4]);
    
        var options = {
            title: '',
            width: '100%',
            height: 132,
            chartArea: {
              height: '100%',
              width: '100%',
              top: 36,
              left: 18,
              right: 18,
              bottom: 48
            },
            hAxis: {
                title: '',
                minValue: 0,
                gridlines: {
                    count: 6
                },
                format: '0'
            },
            bar: {
                groupWidth: "60%"
            },
            legend: {
                position: "top"
            },
            series: {
                0: {
                    color: '#70b5c5',
                    visibleInLegend: false
                }, // Goal Achieved
                1: {
                    color: '#000000',
                    type: 'line',
                    annotations: {
                        textStyle: {
                            color: '#000000'
                        },
                        stem: {
                            color: 'transparent',
                            length: -128
                        },
                        vertical: true
                    }
                } // Target Goal
            },
            vAxis: {
                gridlines: {
                    color: 'transparent'
                },
                ticks: [{v: 1, f: ''}]
            }
        };
    
        var chart = new google.visualization.BarChart(document.getElementById("portal-name-stella-york-horz-month-points"));
    
        google.visualization.events.addListener(chart, 'click', function(e) {
          console.log(JSON.stringify(e));
        });
    
        google.visualization.events.addListener(chart, 'ready', function () {
          // init variables
          var layout = chart.getChartLayoutInterface();
          var containerBounds = chart.getContainer().getBoundingClientRect();
          var svg = chart.getContainer().getElementsByTagName('svg')[0];
          var svgNS = svg.namespaceURI;
          var xLoc = drawVAxisLine(chart, layout, data.getValue(0, 3));
    
          // add image to bar
          var barBounds = layout.getBoundingBox('bar#0#0');
          var icon = chart.getContainer().appendChild(document.createElement('span'));
          icon.className = 'icon';
          icon.style.top = (barBounds.top + containerBounds.top - 3) + 'px';
          icon.style.left = (barBounds.left + containerBounds.left + (barBounds.width) - 24) + 'px';
          icon.innerHTML = '<i class="fas fa-arrow-alt-circle-right"></i>';
    
          // add annotation
          var labelCopy = svg.getElementsByTagName('text')[0];
          var annotation = labelCopy.cloneNode(true);
          svg.appendChild(annotation);
          annotation.setAttribute('text-anchor', 'middle');
          annotation.textContent = data.getValue(0, data.getNumberOfColumns() -1);
          annotation.setAttribute('x', xLoc);
          annotation.setAttribute('y',
            layout.getYLocation(0) + (parseInt(annotation.getAttribute('font-size')) * 3)
          );
        });
    
        chart.draw(view, options);
    }
    
    jQuery(window).resize(function() {
        drawHorizontalChart_portal_name_stella_york_horz_month_points();
    });
    
    
    function drawVAxisLine(chart, layout, value) {
        var chartArea = layout.getChartAreaBoundingBox();
        var svg = chart.getContainer().getElementsByTagName('svg')[0];
        var xLoc = layout.getXLocation(value)
        svg.appendChild(createLine(xLoc, chartArea.top + chartArea.height, xLoc, chartArea.top, '#000000', 2)); // axis line
        return xLoc;
    }
    
    function createLine(x1, y1, x2, y2, color, w) {
        var line = document.createElementNS('http://www.w3.org/2000/svg', 'line');
        line.setAttribute('x1', x1);
        line.setAttribute('y1', y1);
        line.setAttribute('x2', x2);
        line.setAttribute('y2', y2);
        line.setAttribute('stroke', color);
        line.setAttribute('stroke-width', w);
        return line;
    }
    .icon {
      font-size: 32px;
      position: absolute;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <script src="https://www.gstatic.com/charts/loader.js"></script>
    <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.3.1/css/all.css" integrity="sha384-mzrmE5qonljUremFsqc01SB46JvROS7bZs3IO2EmfFsd15uHvIt+Y8vEf7N7fWAU" crossorigin="anonymous">
    <div id="portal-name-stella-york-horz-month-points"></div>