How fill area in GoogleCharts AreaChart with gradient color?
Asked Answered
E

2

5

With my google Chart I use this options:

chartOptions: {
                hAxis: {
                    title: 'Tasks'
                },
                vAxis: {
                    title: 'Duration'
                },
                animation:{
                    duration: 2000,
                    startup: true
                },
                colors: ['#6f9654']


            }

How Can I change the color of the area under the graph and how can I fill it with a gradient? (I don't want to fill the background of the whole diagramm)

I don't find any docs on google documentation so far. Is it even possible? Is there a trick?

UPDATE: The Result on @whiteHats solution with my adaptations.: enter image description here

Erythrite answered 1/11, 2018 at 16:9 Comment(2)
Hey. It look super cool. I am struggled how to implement it. Could it be possible to see your solution with the adaptations?Grapevine
See my comment under the correct answer.Erythrite
R
9

no options for gradient fill of the chart area,
but you can add your own...

first, add your gradient definition to the html somewhere.
this element should not be hidden with display: none,
otherwise, some browsers may ignore it.
setting the size to zero pixels seems to work.

<svg style="width:0;height:0;position:absolute;" aria-hidden="true" focusable="false">
  <linearGradient id="my-gradient" x2="1" y2="1">
    <stop offset="0%" stop-color="#447799" />
    <stop offset="50%" stop-color="#224488" />
    <stop offset="100%" stop-color="#112266" />
  </linearGradient>
</svg>

next, we need to be able to identify the <rect> element that makes up the chart area.
here, a default background color is used.

var chartOptions = {
  chartArea: {
      backgroundColor: '#447799'
  },
  ...

then we find the <rect> element with the default background, and set the fill attribute.
normally, we could set the gradient fill on the chart's 'ready' event,
but since you're using animation, the gradient will get overridden as the animation occurs.
we could also set the fill on the chart's 'animationfinish' event,
but then there would not be a gradient during animation.

as such, we have to use a MutationObserver, and set the fill every time the svg is mutated (drawn).

see following working snippet...

google.charts.load('current', {
  packages:['corechart']
}).then(function () {
  var dataTable = new google.visualization.DataTable({
    cols: [
      {label: 'x', type: 'number'},
      {label: 'y', type: 'number'}
    ],
    rows: [
      {c:[{v: 0}, {v: 25}]},
      {c:[{v: 5}, {v: 25}]},
      {c:[{v: 10}, {v: 25}]},
      {c:[{v: 15}, {v: 25}]},
      {c:[{v: 20}, {v: 25}]},
      {c:[{v: 25}, {v: 25}]},
      {c:[{v: 30}, {v: 25}]},
      {c:[{v: 40}, {v: 25}]},
      {c:[{v: 45}, {v: 25}]},
      {c:[{v: 50}, {v: 25}]},
      {c:[{v: 55}, {v: 25}]},
      {c:[{v: 60}, {v: 25}]},
      {c:[{v: 65}, {v: 25}]},
      {c:[{v: 70}, {v: 25}]}
    ]
  });

  var chartOptions = {
    chartArea: {
        backgroundColor: '#447799'
    },
    height: 600,
    hAxis: {
        title: 'Tasks'
    },
    vAxis: {
        title: 'Duration'
    },
    animation:{
        duration: 2000,
        startup: true
    },
    colors: ['#6f9654']
  };

  var container = document.getElementById("chart_div");
  var chart = new google.visualization.AreaChart(container);

  google.visualization.events.addListener(chart, 'ready', function () {
    var observer = new MutationObserver(function () {
      container.getElementsByTagName('svg')[0].setAttribute('xmlns', 'http://www.w3.org/2000/svg');
      Array.prototype.forEach.call(container.getElementsByTagName('rect'), function(rect) {
        if (rect.getAttribute('fill') === '#447799') {
          rect.setAttribute('fill', 'url(#my-gradient) #447799');
        }
      });
    });
    observer.observe(container, {
      childList: true,
      subtree: true
    });
  });

  chart.draw(dataTable, chartOptions);
});
<script src="https://www.gstatic.com/charts/loader.js"></script>

<div id="chart_div"></div>

<svg style="width:0;height:0;position:absolute;" aria-hidden="true" focusable="false">
  <linearGradient id="my-gradient" x2="1" y2="1">
    <stop offset="0%" stop-color="#447799" />
    <stop offset="50%" stop-color="#224488" />
    <stop offset="100%" stop-color="#112266" />
  </linearGradient>
</svg>
Reversal answered 1/11, 2018 at 16:55 Comment(2)
If I use "path" instead of "rect" it does the trick. and I changed my gradient to <linearGradient id="my-gradient" x1="0%" y1="0%" x2="0%" y2="100%" > which looks now very nice.Erythrite
@Erythrite Awesome! I implemented your version, and my chart is awesome now! Thanks!Mima
C
0

It's documented in Google charts references page. https://developers.google.com/chart/interactive/docs/gallery/linechart

Checkout the annotations.boxStyle section for gradients.

var options = {
  annotations: {
    boxStyle: {
      // Color of the box outline.
      stroke: '#888',
      // Thickness of the box outline.
      strokeWidth: 1,
      // x-radius of the corner curvature.
      rx: 10,
      // y-radius of the corner curvature.
      ry: 10,
      // Attributes for linear gradient fill.
      gradient: {
        // Start color for gradient.
        color1: '#fbf6a7',
        // Finish color for gradient.
        color2: '#33b679',
        // Where on the boundary to start and
        // end the color1/color2 gradient,
        // relative to the upper left corner
        // of the boundary.
        x1: '0%', y1: '0%',
        x2: '100%', y2: '100%',
        // If true, the boundary for x1,
        // y1, x2, and y2 is the box. If
        // false, it's the entire chart.
        useObjectBoundingBoxUnits: true
      }
    }
  }
};
Cchaddie answered 1/3 at 4:7 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.