Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Drawing visual Lines in Google Charts

I'm writing a Google Chart. It has stacked columns. On top of that I want to draw 2 lines, which indicate min and max allowed value.

enter image description here

The only solution I came up with, was modifying the first example of ComboCharts. My result looks like this:

enter image description here

Which isn't sufficient. The graph is variable, so if there's only 1 Quartal shown, the line will solely be a dot. My Questions are:

  • Is there a way to draw the line further, so it hits the left and right boundary of the Graph?
  • Can I draw markup lines into the graph, without pretending it's another datapoint?

You can fiddle with a ComboChart here if you want.

like image 941
Gordon Mohrin Avatar asked May 08 '14 07:05

Gordon Mohrin


People also ask

Can you draw on a Google chart?

Every chart supports a draw() method that takes two values: a DataTable (or a DataView ) object that holds your data, and an optional chart options object.


2 Answers

Maybe a bit late but I faced the same issue. I was trying to set max and min lines into a line chart with a lot of data points in the serie and I wanted to avoid adding new series with a lot of repeated points so I used overlays ( https://developers.google.com/chart/interactive/docs/overlays#javascript2 ).

Here are an example, It's just a draft in which I'm working now but maybe can help:

<html>
  <head>
    <script
      type="text/javascript"
      src="https://www.gstatic.com/charts/loader.js"
    ></script>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.0/jquery.min.js"></script>
    <style>
      #container {
        position: relative;
        width: 900px;
        height: 500px;
      }
      .min-bar {
        height: 1px;
        background-color: red;
        position: absolute;
        left: 0;
        right: 0;
      }
    </style>
    <script type="text/javascript">
      $(function() {
        $.get(
          "https://firebasestorage.googleapis.com/v0/b/manasav-pricetracker.appspot.com/o/products%2F-L6O-CtBKZAc2NTCFq7Z.data?alt=media&token=60e06bb6-59b7-41a9-8fd0-f82f4ddc75f2",
          function(data) {
            google.charts.load("current", { packages: ["corechart"] });
            google.charts.setOnLoadCallback(drawChart);

            var downloadedData = JSON.parse("[" + data);

            function drawChart() {
              var dataTable = [["Time", "New"]];
              let min = Number.MAX_VALUE;

              let rowMin;
              for (var i in downloadedData) {
                var d = downloadedData[i];
                if (d.new < min) {
                  rowMin = i;
                  min = d.new;
                }
                dataTable.push([new Date(d.date), d.new]);
              }

              var data = google.visualization.arrayToDataTable(dataTable);

              var options = {
                title: "Price evolution",
                legend: { position: "bottom" },
                trendlines: { 0: {} }
              };

              var chart = new google.visualization.LineChart(
                document.getElementById("curve_chart")
              );

              function placeMarker(dataTable) {
                var cli = this.getChartLayoutInterface();
                var chartArea = cli.getChartAreaBoundingBox();
                document.querySelector(".min-bar").style.top =
                  Math.floor(cli.getYLocation(min)) + "px";

                document.querySelector(".min-bar").style.left =
                  Math.floor(cli.getXLocation(dataTable.getValue(0,0))) - 25 + "px";

                  document.querySelector(".min-bar").style.right =
                  (document.querySelector("#container").offsetWidth - Math.floor(cli.getXLocation(dataTable.getValue(dataTable.getNumberOfRows()-1,0)))) - 25 + "px";
                // document.querySelector(".min-bar").style.top =
                // Math.floor(cli.getXLocation(dataTable.getValue(rowMin, 1))) +
                // "px";
              }
              google.visualization.events.addListener(
                chart,
                "ready",
                placeMarker.bind(chart, data)
              );
              chart.draw(data, options);
            }
          }
        );
      });
    </script>
  </head>
  <body>
    <div id="container">
      <div id="curve_chart" style="width: 900px; height: 500px"></div>
      <div class="min-bar"></div>
    </div>
  </body>
</html>

Jsfiddle demo => https://jsfiddle.net/jRubia/8z7ao1nh/

like image 151
Javier de la Rubia Avatar answered Oct 19 '22 05:10

Javier de la Rubia


You can't get the lines to go edge-to-edge with a discrete (string-based) x-axis. If you switch to a continuous (number, date, datetime, timeofday) axis, then you can add one row before your real data and one row after that contain the goal lines (and nulls for the other data series):

function drawChart() {
    var data = new google.visualization.DataTable();
    data.addColumn('number', 'Quarter');
    data.addColumn('number', 'Value 1');
    data.addColumn('number', 'Value 2');
    data.addColumn('number', 'Value 3');
    data.addColumn('number', 'Goal 1');
    data.addColumn('number', 'Goal 2');
    data.addRows([
        [0, null, null, null, 10, 14],
        [1, 5, 4, 7, null, null],
        [2, 6, 9, 6, null, null],
        [3, 2, 6, 4, null, null],
        [5, null, null, null, 10, 14]
    ]);

    var chart = new google.visualization.ComboChart(document.querySelector('#chart_div'));
    chart.draw(data, {
        height: 400,
        width: 600,
        isStacked: true,
        legend: {
            position: 'top'
        },
        seriesType: 'bars',
        interpolateNulls: true,
        series: {
            3: {
                type: 'line'
            },
            4: {
                type: 'line'
            }
        },
        hAxis: {
            format: 'Q#',
            ticks: [1, 2, 3, 4],
            viewWindow: {
                min: 0.5,
                max: 4.5
            }
        },
        chartArea: {
            left: '10%',
            width: '80%'
        }
    });
}
google.load('visualization', '1', {packages:['corechart'], callback: drawChart});

See working example: http://jsfiddle.net/asgallant/W67qU/

like image 41
asgallant Avatar answered Oct 19 '22 05:10

asgallant