Update Google chart with data received from server - javascript

How can I make a chart change with new data? I get data back from an API call to my server, which I can see in the console. How do I update the chart with it?
map.on('singleclick', function(evt) {
var coordinate = evt.coordinate;
var hdms = ol.proj.transform(
coordinate, 'EPSG:3857', 'EPSG:4326');
$.get("http://127.0.0.1:5000/stats?lat="+hdms[1]+"&lon="+hdms[0],
function(data) {
console.log( data );
});
);
}

1) load google first
google.charts.load can replace --> $(document).ready (or similar)
2) create chart
3) get data
something like...
google.charts.load('current', {
packages: ['corechart']
}).then(function () {
// save reference to chart here
var chart = new google.visualization.LineChart(document.getElementById('chart_div'));
map.on('singleclick', function(evt) {
var coordinate = evt.coordinate;
var hdms = ol.proj.transform(
coordinate, 'EPSG:3857', 'EPSG:4326');
$.get("http://127.0.0.1:5000/stats?lat="+hdms[1]+"&lon="+hdms[0],
function(data) {
console.log( data );
// draw chart here
chart.draw(data);
});
);
};
});
UPDATE
you must create a DataTable to draw the chart
there are a few ways to create the data table
1) you can use JSON, but it must be in the following format, as found here
var jsonData = {
cols: [
{label: 'x', type: 'number'},
{label: 'y', type: 'number'}
],
rows: [
{c:[{v: 0}, {v: 0}]},
{c:[{v: 1}, {v: 1}]}
]
}
var dataTable = new google.visualization.DataTable(jsonData);
2) you can use simple array data, and static method arrayToDataTable
var arrayData = [
['x', 'y'],
[0, 0],
[1, 1]
];
var dataTable = google.visualization.arrayToDataTable(arrayData);
3) or manually add columns and rows
var dataTable = new google.visualization.DataTable();
dataTable.addColumn('number', 'x');
dataTable.addColumn('number', 'y');
dataTable.addRow([0, 0]);
// -- or addRows --
dataTable.addRows([
[0, 0],
[1, 1]
]);

Related

Google Charts - Format vAxis point instead of comma

How to format vAxis in google charts that would display vertical scale with points instead of commas.
Example(now): 100,000
Example(then): 100.000
I know that the trick is with 'format' function, but I can't get it to work like i want.
I am trying to format it like with this:
vAxis: {minValue:0, format:'##.##'}
if the format option does not meet your needs,
you can use the ticks option to provide custom labels
using object notation, you can provide both the...
v: - value for the axis
f: - formatted value for the label
{v: 100000, f: '100.000'}
see following working snippet
the NumberFormat class is used, in an attempt to create the format
(not sure exactly what is needed)
data table method getColumnRange is used to find the range of the y-axis
a loop builds each tick for the axis labels...
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([
[0, 500000],
[1, 500000],
[2, 200000],
[3, 700000],
[4, 400000]
]);
var formatNumber = new google.visualization.NumberFormat({
groupingSymbol: '.',
fractionDigits: 0
});
var ticksY = [];
var yRange = data.getColumnRange(1);
for (var i = 0; i <= yRange.max; i=i+100000) {
ticksY.push({
v: i,
f: formatNumber.formatValue(i)
});
}
var options = {
vAxis: {
ticks: ticksY
}
};
var chart = new google.visualization.LineChart(
document.getElementById('chart_div')
);
chart.draw(data, options);
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div"></div>
Try this :
vAxis.format:{format:'##.##'}

js chart non uniform x values

Is there a JS Charting lib that supports multiple curces, having unequal steps?
Consider data like that:
Curve 1 (x/y pairs) RED in Sample:
[1, 10] [10, 20] [20,20]
Curve 2 Green in Sample:
[1, 2] [5, 6] [10,10] [11,12] [15,15] [20,20]
This should result in 2 Curves with x RANGE from 1..20. The first only has 3 data points that should be connected by a line. The second has 6 Points in the same x value range.
Which JS Charting library can handle that?
most likely, any chart lib can handle,
just need to load the data in the format the chart accepts
here, google charts is used to draw the chart
google charts has a method to join tables
so, just create two data tables, one for each x range
the resulting joined table will fill in the missing values with null
as such, need option for interpolateNulls so there are no breaks in the lines
see following working snippet...
google.charts.load('current', {
callback: drawChart,
packages:['corechart']
});
function drawChart() {
var x0 = [
[1, 10], [10, 20], [20,20]
];
var x1 = [
[1, 2], [5, 6], [10,10], [11,12], [15,15], [20,20]
];
var data0 = google.visualization.arrayToDataTable(x0, true);
var data1 = google.visualization.arrayToDataTable(x1, true);
var joinData = google.visualization.data.join(
data0, data1, 'full', [[0, 0]], [1], [1]
);
var options = {
height: 400,
interpolateNulls: true,
legend: {
position: 'none'
},
vAxis: {
viewWindow: {
max: 30
}
},
hAxis: {
viewWindow: {
max: 30
}
}
};
var container = document.getElementById('chart_div');
var chart = new google.visualization.LineChart(container);
chart.draw(joinData, options);
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div"></div>

How to add percentage label without changing order by Google Chat

I want to add percentage marks to number labels and found a option for it.
{hAxis: {format: 'percent'}}
But it also multiple the number by 100.
For instance, {hAxis: { format:'#,###%'} } displays the values "1,000%", "750%", and "50%" for values 10, 7.5, and 0.5.
https://developers.google.com/chart/interactive/docs/customizing_axes#number-formats
How can I just add % to the labels?
you could try adding custom axis labels, or ticks...
using object notation, you can provide both a...
value (v:) and a formatted value (f:)
then using google's NumberFormat class, build each tick manually...
var formatPercent = new google.visualization.NumberFormat({
suffix: '%'
});
...
ticks.push({
v: data.getValue(i, 0),
f: formatPercent.formatValue(data.getValue(i, 0))
});
...
hAxis: {
ticks: ticks
}
see following working snippet...
google.charts.load('current', {
callback: drawChart,
packages:['corechart']
});
function drawChart() {
var data = google.visualization.arrayToDataTable([
['X', 'Y'],
[1, 1],
[10, 2],
[20, 3],
[30, 4]
]);
var formatPercent = new google.visualization.NumberFormat({
pattern: '#,##0',
suffix: '%'
});
var ticks = [];
for (var i = 0; i < data.getNumberOfRows(); i++) {
ticks.push({
v: data.getValue(i, 0),
f: formatPercent.formatValue(data.getValue(i, 0))
});
}
var chart = new google.visualization.LineChart(document.getElementById('chart_div'));
chart.draw(data, {
hAxis: {
ticks: ticks
}
});
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div"></div>

How to plot indicator circle onto google charts line chart

Google charts' line chart
So, at the moment, I'm just getting used to google charts. But in future, I'm looking to plot a function. Once that line is drawn, I'd like to add a dynamic indicator circle that will travel along the path of the line as I adjust the values that plotted the line.
So to summarise:
Plot a permanent line from a function*
Have a circle that travels the path of the line as I adjust the values of the function. (main question)
New to google charts and not sure how easily you can do something like this.
To maybe clarify: I will be using a slider to control a value, as I move the slider the line will not change, but an "indicator" circle will change position to fit the new values; i.e. plotting a circle dynamically as the value changes.
Not sure if it helps, but my current graph looks simply like this:
google.charts.load('current', {'packages':['corechart']});
google.charts.setOnLoadCallback(drawChart);
drawChart();
function drawChart() {
var data = google.visualization.arrayToDataTable([
['somVar1', 'someVar2'],
['0.001' , 0.02],
['0.003' , 0.07],
['0.01' , 0.2],
['0.03' , 0.6 ],
['0.1' , 1.8],
['0.3' , 4.8],
['1' , 10],
['3' , 15.2 ],
['10' , 18.2 ],
['30' , 19.4],
['100' , 19.8],
['300' , 19.93],
['1000' , 19.98],
]);
//Graph styling and legend
var options = {
title: 'sumVar2 (%)',
curveType: 'function',
legend: { position: 'bottom' },
vAxis: { title: 'someVar2 %'},
hAxis: { title: 'someVar1'}
};
var chart = new google.visualization.LineChart(document.getElementById('lineGraph'));
chart.draw(data, options);
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="lineGraph" style="width: 900px; height: 500px"></div>
*(unfortunately with google charts, it looks like I have to do this by finding the range of values and spitting them out into an array - rather than being able to plot straight from a mathematical function)
the DataView Class can be used to provide a function as the value for a series
use the setColumns method to set the function
you can pass a column index for an existing DataTable column or
a custom object with the calculation function
here, a DataView is created from a DataTable,
it uses the first column from the DataTable,
the next column is a function
var dataView = new google.visualization.DataView(dataTable);
dataView.setColumns([0, {
calc: function (data, row) {
return (2 * data.getValue(row, 0)) + 7;
},
type: 'number',
label: 'Y1'
}]);
you can set multiple column functions,
but you cannot use the values from one function in another,
in the same DataView
to get around, reference the previous DataView in the current function
otherwise, you would have to dump the values to a new table,
then use the new table in another view to set the next function
you can modify the series options to create points rather than a line, i.e.
series: {
1: {
lineWidth: 0,
pointSize: 8
}
}
the following working snippet demonstrates how to save a reference to the first function, and use it later, such as when the chart's 'ready' event fires
google.charts.load('current', {
callback: function () {
// DataTable X only
var dataTable = google.visualization.arrayToDataTable([
['X'],
[0.001],
[0.003],
[0.01],
[0.03],
[0.1],
[0.3],
[1],
[3],
[10],
[30],
[100],
[300],
[1000],
]);
// use DataView to provide function for Y
var dataView = new google.visualization.DataView(dataTable);
// y1=2x+7
var yCol1 = {
calc: function (data, row) {
return (2 * data.getValue(row, 0)) + 7;
},
type: 'number',
label: 'Y1'
};
// use above object as Y1
dataView.setColumns([0, yCol1]);
var container = document.getElementById('chart_div');
var chart = new google.visualization.LineChart(container);
// draw Y2 when chart finishes drawing
google.visualization.events.addOneTimeListener(chart, 'ready', function () {
// add Y2 column
dataView.setColumns([0, yCol1, {
// y2=y1+(2x-1)
calc: function (data, row) {
//use reference to previous dataView
return dataView.getValue(row, 1) + ((2 * data.getValue(row, 0)) - 1);
},
type: 'number',
label: 'Y2'
}]);
chart.draw(dataView, {
series: {
1: {
lineWidth: 0,
pointSize: 8
}
}
});
});
chart.draw(dataView);
},
packages: ['corechart']
});
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div"></div>
EDIT
the same concept can be used to avoid having an array for the X values as well
just need to set an initial number of rows on a DataTable
see following working snippet...
google.charts.load('current', {
callback: function () {
// create blank table for the view
var dataTable = new google.visualization.DataTable();
dataTable.addColumn('number', 'X');
dataTable.addRows(20);
// use DataView to provide function for X
var dataView = new google.visualization.DataView(dataTable);
var xCol = {
calc: function (data, row) {
return (row + 1) * 0.3;
},
type: 'number',
label: 'X'
};
dataView.setColumns([xCol]);
// function for Y --> y1=2x+7
var yCol1 = {
calc: function (data, row) {
return (2 * dataView.getValue(row, 0)) + 7;
},
type: 'number',
label: 'Y1'
};
dataView.setColumns([xCol, yCol1]);
var container = document.getElementById('chart_div');
var chart = new google.visualization.LineChart(container);
// draw Y2 when chart finishes drawing
google.visualization.events.addOneTimeListener(chart, 'ready', function () {
// add Y2 column
dataView.setColumns([xCol, yCol1, {
// y2=y1+(2x-1)
calc: function (data, row) {
//use reference to previous dataView
return dataView.getValue(row, 1) + ((2 * data.getValue(row, 0)) - 1);
},
type: 'number',
label: 'Y2'
}]);
chart.draw(dataView, {
series: {
1: {
lineWidth: 0,
pointSize: 8
}
}
});
});
chart.draw(dataView);
},
packages: ['corechart']
});
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div"></div>

Google Chart Error

When trying to plot a Line Chart using the Google Charts code I get this error
Error: Type mismatch. Value 0.8 does not match type number in column index 0
The '0.8' is referring to the value p1 in the code.
function drawChart() {
// Create the data table.
var data = new google.visualization.DataTable();
data.addColumn('number', 'Topping');
data.addColumn('number', 'Slices');
data.addRows([
[p1,1.89],
[ch_period[17],5],
[3,2],
[5,2],
[5,2],
[6,7]
]);
// Set chart options
var options = {'title':'How Much Pizza I Ate Last Night',
'width':400,
'height':300};
// Instantiate and draw our chart, passing in some options.
var chart = new google.visualization.LineChart(document.getElementById('chart_div'));
chart.draw(data, options);
I've made a jsfiddle with your code that works: http://jsfiddle.net/kychan/Dfx4V/1/
var p1 = parseInt('4'),
ch_period = {'17':4};
function drawChart() {
// Create the data table.
var data = new google.visualization.DataTable();
data.addColumn('number', 'Topping');
data.addColumn('number', 'Slices');
data.addRows([
[p1, 1.89],
[ch_period[17], 5],
[3, 2],
[5, 2],
[5, 2],
[6, 7]
]);
// Set chart options
var options = {
'title': 'How Much Pizza I Ate Last Night',
'width': 400,
'height': 300
};
// Instantiate and draw our chart, passing in some options.
var chart = new google.visualization.LineChart(document.getElementById('chart_div'));
chart.draw(data, options);
}
drawChart();
The problem was that p1 (and maybe ch_period) isn't the type number. Thus you must make it a number using parseInt(p1) / parseInt(ch_period) or manually assign it to a number.

Categories