3
votes

I have a ScatterChart where I need to draw a diagonal line (of the function y=x) that serves as a visual aid. Is it possible ? if so, how can I do it?

2

2 Answers

4
votes

Another solution is that you can use Scatter chart with multi-series, and set lineWidth = 1 and pointSize = 0 for Line charts!

See the following example:

function main() {
  const xMin = -2 * Math.PI;
  const xMax = 2 * Math.PI;
  const f1 = x => Math.cos(x) + Math.random();
  const f2 = x => Math.cos(x);

  const x = linspace(xMin, xMax, 20);
  const y1 = x.map(f1);
  const y2 = x.map(f2);

  scatterLineChart(document.getElementById('scatter-line-chart'), x, [y1, y2], 'Scatter: Cos(x) + Noise, Line: Cos(x)', 'x', ['Cos(x) + Noise', 'Cos(x)']);
}

function linspace(a, b, n = 100) {
  const data = new Array(n);

  const d = (b - a) / (n - 1);

  data[0] = a;
  data[n - 1] = b;

  n = n - 1;
  for (let i = 1; i < n; i++) {
    data[i] = data[i - 1] + d;
  }

  return data;
}

function createSeriesDataTable(x, ys, xLabel, yLabels) {
  // data
  const data = new google.visualization.DataTable();

  // - columns
  data.addColumn('number', xLabel);
  yLabels.forEach(yLabel => {
    data.addColumn('number', yLabel);
  });

  // - rows
  const n = x.length;
  const m = ys.length;
  const rows = Array(n);
  for (let i = 0; i < n; i++) {
    rows[i] = Array(1 + m);
    rows[i][0] = x[i];
    for (let j = 0; j < m; j++) {
      rows[i][j + 1] = ys[j][i];
    }
  }
  data.addRows(rows);

  // return
  return data;
}

function scatterLineChart(parentElement, x, ys, title, xLabel, yLabels) {
  google.charts.load('current', {
    'packages': ['corechart']
  });
  google.charts.setOnLoadCallback(drawChart);

  function drawChart() {
    const data = createSeriesDataTable(x, ys, xLabel, yLabels);
    const options = {
      title: title,
      series: {
        1: {
          lineWidth: 3,
          pointSize: 0,
          curveType: 'function'
        },
      },
      legend: 'none'

    };

    const chart = new google.visualization.ScatterChart(parentElement);
    chart.draw(data, options);
  }
}

main();
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="scatter-line-chart"></div>
3
votes

you can use a ComboChart to display both scatter and line series'

and a DataView to provide the function for y=x

see following working snippet...

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

function drawChart() {
  var data = new google.visualization.DataTable();
  data.addColumn('number', 'x');
  data.addColumn('number', 'y0');
  data.addRows([
    [1,  37.8],
    [2,  30.9],
    [3,  25.4],
    [4,  11.7],
    [5,  11.9],
    [6,   8.8],
    [7,   7.6],
    [8,  12.3],
    [9,  16.9],
    [10, 12.8],
    [11,  5.3],
    [12,  6.6],
    [13,  4.8],
    [14,  4.2]
  ]);

  var view = new google.visualization.DataView(data);
  view.setColumns([0, 1, {
    label: 'y1=x',
    type: 'number',
    calc: function (dt, row) {
      return dt.getValue(row, 0)
    }
  }]);

  var options = {
    seriesType: 'scatter',
    series: {
      1: {
        type: 'line'
      }
    }
  };

  var chart = new google.visualization.ComboChart(document.getElementById('chart_div'));
  chart.draw(view, options);
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div"></div>