0

There is a similar thread here but the answer isn't clear and there is no clear example to follow.

I need to dynamically add series to a Google Charts graph. Suppose each successive click of a button should add a new series from my array. Right now it just replaces it. What should I do?

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

var currentclick = 0;

// My Data
var titles = ['Year1','Year2','Year3','Year4'];
var nums = [ [44,12,33,22], [33,11,7,8], [2,1,65,44] ];

$('#addSeries').click(function() {

   if (currentclick < 3) {
       draw(nums, currentclick);
   }
   currentclick++;
});

function draw(arr, seriesnum) {
  var chartData = new google.visualization.DataTable();
 chartData.addColumn('string', 'Year');
 chartData.addColumn('number', 'Value');  
  
  var chartRowArray = $.makeArray();
 for (var i = 0; i < 4; i++) {
  chartRowArray.push( [ titles[i], arr[seriesnum][i] ] );
 } 
 chartData.addRows(chartRowArray);
  var chart = new google.visualization.LineChart(document.getElementById('chartarea'));
  chart.draw(chartData, null);
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<button id="addSeries">Add Next Series</button>

<div id="chartarea">
</div>
gene b.
  • 10,512
  • 21
  • 115
  • 227

2 Answers2

1
  • You want to add a line chart from the data of nums every time when you clicked "Add Next Series" button.

If my understanding is correct, how about this modification? I think that there are several answers for your situation. So please think of this as just one of several answers.

Modification point:

  • In this modification, chartRowArray is declared as a global variable. When the button is clicked, the data is added to chartRowArray. By this, the line chars are added to the existing chart.

Modified script:

// Init
google.charts.load('current', {'packages':['corechart']});
var currentclick = 0;

// My Data
var titles = ['Year1','Year2','Year3','Year4'];
var nums = [ [44,12,33,22], [33,11,7,8], [2,1,65,44] ];

$('#addSeries').click(function() {
  if (currentclick < 3) {
    draw(nums, currentclick);
  }
  currentclick++;
});

// Below script was modified.
var chartRowArray = $.makeArray(); // Added

function draw(arr, seriesnum) {
  var chartData = new google.visualization.DataTable();
  chartData.addColumn('string', 'Year');
  for (var i = 0; i < seriesnum + 1; i++) { // Added
    chartData.addColumn('number', 'Value');
  }
  if (seriesnum === 0) { // Added
    for (var i = 0; i < 4; i++) {
      chartRowArray.push( [ titles[i], arr[seriesnum][i] ] );
    } 
  } else { // Added
    for (var i = 0; i < 4; i++) {
      chartRowArray[i].push(arr[seriesnum][i]);
    } 
  }
  chartData.addRows(chartRowArray);
  var chart = new google.visualization.LineChart(document.getElementById('chartarea'));
  chart.draw(chartData, null);
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button id="addSeries">Add Next Series</button>
<div id="chartarea"></div>

If I misunderstood your question and this was not the result you want, I apologize.

Tanaike
  • 181,128
  • 11
  • 97
  • 165
  • Thanks, the idea of making it a global variable really helped. The example of known NumSeries being known in advance is a bit primitive because I don't know how many series I'll have. Also, I simplified the If-clause to handle the initial condition. I'll post my working simplified version in a moment. – gene b. May 26 '19 at 14:27
  • @gene b. Thank you for replying and additional information. I'm glad your issue was resolved. And I upvoted your answer. – Tanaike May 26 '19 at 22:10
1

The key thing is the final structure of the data.

The Column Array should be

0: Year
1: Value
2: Value
etc.

The Column array is added 1-by-1 as chartData.addColumn(type, name).

The data's Row Array should be

0:  
   0: Year1
   1: 44
   2: 33
1:
   0: Year2
   1: 12
   2: 11
etc.

The Row Array is added in one shot as chartData.addRows(rowArray).

Knowing this, I made both RowArray / ColArray global variables that get modified on the fly (thanks for the idea Tainake) and for the initial conditions when the arrays are empty, I construct or initialize them for the first time.

Working example below. Thanks again for the help!

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

var currentclick = 0;

// My Data
var titles = ['Year1','Year2','Year3','Year4'];
var nums = [ [44,12,33,22], [33,11,7,8], [2,1,65,44] ];
var chartColArray = $.makeArray(); // Global var
var chartRowArray = $.makeArray(); // Global var

$('#addSeries').click(function() {

   if (currentclick < 3) {
       draw(nums, currentclick);
   }
   currentclick++;
});

function draw(arr, seriesnum) {
 var chartData = new google.visualization.DataTable();
 
 // For initial Column, push 'Year'; otherwise, push 'Value'
 if (chartColArray.length == 0) {
  chartColArray.push('Year');
 }
 chartColArray.push('Value');
 // addColumn() has to be 1-by-1-by-1, there is no addColumns(colarray)
 $.each(chartColArray, function(index, item) {
  (index == 0 ? chartData.addColumn('string', item) : chartData.addColumn('number', item));
 });
 
 for (var i = 0; i < 4; i++) {
        // For initial Row subarray, create subarray and push 'Year Series'; 
        // otherwise, push actual 'Series' value
  if (chartRowArray[i] == undefined) {
   chartRowArray[i] = $.makeArray();
   chartRowArray[i].push(titles[seriesnum]);
  }
  chartRowArray[i].push(nums[seriesnum][i]);
 }
 chartData.addRows(chartRowArray);

 // Instantiate and draw the chart.
 var chart = new google.visualization.LineChart(document.getElementById('chartarea'));
 chart.draw(chartData, null);
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<button id="addSeries">Add Next Series</button>

<div id="chartarea">
</div>
gene b.
  • 10,512
  • 21
  • 115
  • 227