Related
I'm finding myself in over my head on this web development project, and was hoping someone could help me better understand why one of my google charts will not draw on my page.
I have a working test page with the chart drawing how I want it, this is the jsfiddle for it so you can have the exact code if you wish to test
http://jsfiddle.net/dlaliberte/pfTqP/
I pulled the code directly from this page where it works, and put it into my page that already has 4 other working google charts on it. Now when I add in this chart it doesn't give me any errors but it just will not draw.
I'm going to post the javascript for the first chart that works and the chart I'm trying to fix (separated with '###'), and the spot on my page where it's set to draw, I'm hoping someone with more experience could help me spot where the issue is coming from, as after several hours of tweaking and running over it I'm still not sure what's going wrong.
//################################### UPDATED JAVASCRIPT ####################################
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
<script src="js/bootstrap.min.js"></script>
<script src="js/jquery.csv.min.js"></script>
<script type="text/javascript"> // load the visualisation API
google.charts.load('visualization', 'current', '1.1',
{
callback: drawCharts,
packages: ['corechart', 'controls']
});
/* Set a callback to run when the Google Visualization API is loaded.
google.charts.setOnLoadCallback(drawLineChart);
google.charts.setOnLoadCallback(drawBarChart);
google.setOnLoadCallback(drawVisualization);
*/
function drawCharts() {
drawLineChart();
drawBarChart();
drawBarVisualization();
drawPieVisualization();
drawVisualization();
}
function drawLineChart() {
var jsonData = $.ajax({
url: "getData.php",
dataType: "json",
async: false
}).responseText;
// Create our data table out of JSON data loaded from server.
var data = new google.visualization.DataTable(jsonData);
var options = {
title: 'Average Ratings',
'vAxis': { title: "Average Rating" },
'width': 1100,
'height': 540,
'legend': { position: 'bottom'},
'is3D':true,
'padding': 20,
'backgroundColor': 'Ivory',
'color':'Black',
hAxis: {
textStyle:{color: 'Black', weight: 'bold'}
},
series:
{
0: { color: 'Black', pointShape: 'square'},
}
}
// Instantiate and draw our chart, passing in some options.
var chart = new google.visualization.LineChart(document.getElementById('chart_div'));
chart.draw(data, options);
google.visualization.events.addListener('testBtn', 'click',
function(event) {
data.sort({column: 0, desc: false});
chart.draw(data, options);
});
changeLineRange = function() {
data.sort({column: 0, desc: false});
chart.draw(data, options);
};
changeLineRangeBack = function() {
data.sort({column: 0, desc: true});
chart.draw(data, options);
};
}
function drawBarChart() {
var jsonData = $.ajax({
url: "getData.php",
dataType: "json",
async: false
}).responseText;
// Create our data table out of JSON data loaded from server.
var data = new google.visualization.DataTable(jsonData);
var options = {
title: 'Average Ratings',
'vAxis': { title: "Average Rating" },
'width': 700,
'height': 540,
'legend':{position:'top',alignment:'start'},
'is3D':true,
'padding': 20,
'backgroundColor': 'Ivory',
series: {
0: { color: 'Black' },
},
'hAxis': {
title: "Date",
gridlines: { count: 3, color: '#CCC' },
format: 'dd-MMM-yyyy'
}
}
// Instantiate and draw our chart, passing in some options.
var chart2 = new google.visualization.ColumnChart(document.getElementById('bar_chart_div'));
chart2.draw(data, options);
changeOptions = function() {
chart2.setOption('is3D', true);
chart2.draw();
};
}
$(document).ready(function(){
$('[data-toggle="popover"]').popover();
});
$('#myTabs a').click(function (e) {
e.preventDefault()
$(this).tab('show')
})
//Triple Line Chart
function drawVisualization() {
$.get("MockWeek.csv", function(csvString) {
// transform the CSV string into a 2-dimensional array
var arrayData = $.csv.toArrays(csvString, {onParseValue: $.csv.hooks.castToScalar}, {onParseValue: $.csv.hooks.castToScalar});
// this new DataTable object holds all the data
var data = new google.visualization.arrayToDataTable(arrayData);
// CAPACITY - En-route ATFM delay - YY - CHART
var crt_ertdlyYY = new google.visualization.ChartWrapper({
chartType: 'LineChart',
containerId: 'crt_ertdlyYY',
dataTable: data,
options:{
'title': 'Average Ratings',
'vAxis': { title: "Average Rating" },
'width': 1100,
'height': 540,
'backgroundColor': 'Ivory',
'color':'Black',
'hAxis': {
title: "Date",
gridlines: { count: 3, color: '#CCC' },
format: 'dd-MMM-yyyy'
},
title: 'KWh Usage - Temperature Projected',
titleTextStyle : {color: 'Black', fontSize: 14},
curveType: 'function'
}
});
crt_ertdlyYY.draw();
changeRange = function() {
data.sort({column: 0, desc: false});
crt_ertdlyYY.draw();
};
changeRangeBack = function() {
data.sort({column: 0, desc: true});
crt_ertdlyYY.draw();
};
});
}
google.setOnLoadCallback(drawVisualization)
//Triple Pie Chart
function drawPieVisualization() {
$.get("Thornton.M2.csv", function(csvString) {
// transform the CSV string into a 2-dimensional array
var arrayData = $.csv.toArrays(csvString, {onParseValue: $.csv.hooks.castToScalar}, {onParseValue: $.csv.hooks.castToScalar});
// this new DataTable object holds all the data
var data = new google.visualization.arrayToDataTable(arrayData);
// CAPACITY - En-route ATFM delay - YY - CHART
var pieMain = new google.visualization.ChartWrapper({
chartType: 'BarChart',
containerId: 'pieMain',
dataTable: data,
options:{
title: 'Bar Chart Test',
'vAxis': { title: "Bar Chart Test" },
'width': 1100,
'height': 530,
'backgroundColor': 'Ivory',
'color':'Black',
'hAxis': {
title: "Date",
gridlines: { count: 3, color: '#CCC' },
format: 'dd-MMM-yyyy'
},
title: 'Bar Chart Test',
titleTextStyle : {color: 'Black', fontSize: 16},
}
});
pieMain.draw();
});
}
google.setOnLoadCallback(drawPieVisualization)
changeRange = function() {
pieMain.sort({column: 0, desc: false});
pieMain.draw();
};
changeRangeBack = function() {
pieMain.sort({column: 0, desc: true});
pieMain.draw();
};
function drawVisualization() {
var dashboard = new google.visualization.Dashboard(
document.getElementById('dashboard'));
var control = new google.visualization.ControlWrapper({
'controlType': 'ChartRangeFilter',
'containerId': 'control',
'options': {
// Filter by the date axis.
'filterColumnIndex': 0,
'ui': {
'chartType': 'LineChart',
'chartOptions': {
'chartArea': {'width': '90%'},
'hAxis': {'baselineColor': 'none' }
},
// Display a single series that shows the closing value of the stock.
// Thus, this view has two columns: the date (axis) and the stock value (line series).
'chartView': {
'columns': [0, 3]
},
// 1 day in milliseconds = 24 * 60 * 60 * 1000 = 86,400,000
'minRangeSize': 86400000
}
},
// Initial range: 2012-02-09 to 2012-03-20.
'state': {'range': {'start': new Date(2012, 1, 9), 'end': new Date(2012, 2, 20)}}
});
var chart = new google.visualization.ChartWrapper({
'chartType': 'CandlestickChart',
'containerId': 'chart',
'options': {
// Use the same chart area width as the control for axis alignment.
'chartArea': {'height': '80%', 'width': '90%'},
'hAxis': {'slantedText': false},
'vAxis': {'viewWindow': {'min': 0, 'max': 2000}},
'legend': {'position': 'none'}
},
// Convert the first column from 'date' to 'string'.
'view': {
'columns': [
{
'calc': function(dataTable, rowIndex) {
return dataTable.getFormattedValue(rowIndex, 0);
},
'type': 'string'
}, 1, 2, 3, 4]
}
});
var data = new google.visualization.DataTable();
data.addColumn('date', 'Date');
data.addColumn('number', 'Stock low');
data.addColumn('number', 'Stock open');
data.addColumn('number', 'Stock close');
data.addColumn('number', 'Stock high');
// Create random stock values, just like it works in reality.
var open, close = 300;
var low, high;
for (var day = 1; day < 121; ++day) {
var change = (Math.sin(day / 2.5 + Math.PI) + Math.sin(day / 3) - Math.cos(day * 0.7)) * 150;
change = change >= 0 ? change + 10 : change - 10;
open = close;
close = Math.max(50, open + change);
low = Math.min(open, close) - (Math.cos(day * 1.7) + 1) * 15;
low = Math.max(0, low);
high = Math.max(open, close) + (Math.cos(day * 1.3) + 1) * 15;
var date = new Date(2012, 0 ,day);
data.addRow([date, Math.round(low), Math.round(open), Math.round(close), Math.round(high)]);
}
dashboard.bind(control, chart);
dashboard.draw(data);
}
</script>
And here is the spot I'm drawing the chart on my page, it's in a set of 4 tabs so the user can tab through different charts, so far it's worked perfectly.
<div class="col-md-12">
<h2 align="center" class="featurette-heading">Current Demand -<span style="color: Ivory;"> Hourly Usage</span></h2>
<br/>
<ul class="nav nav-tabs" role="tablist" data-tabs="tabs">
<li role="presentation" class="active">Usage</li>
<li role="presentation">Demand</li>
<li role="presentation">Daily</li>
<li role="presentation">Monthly</li>
</ul>
<div class="tab-content">
<div role="tabpanel" class="tab-pane fade in active" align="center" id="home"> <div class="chart" id="chart_div"></div>
<button class="btn btn-primary raised" onclick="changeLineRange();">
Ascending
</button>
<button class="btn btn-primary raised" onclick="changeLineRangeBack();">
Descending
</button><br /></div>
<div role="tabpanel" class="tab-pane fade" align="center" id="profile"><div class="chart" id="crt_ertdlyYY"></div>
<button class="btn btn-primary raised" onclick="changeRange();">
Ascending
</button>
<button class="btn btn-primary raised" onclick="changeRangeBack();">
Descending
</button><br /></div>
// ############################## THIS IS THE TAB PANEL WHERE I'M DRAWING THE NEW CHART ############################
<div role="tabpanel" class="tab-pane fade">
<div class="chart" id="dashboard">
<div id="chart" style='width: 915px; height: 300px;'></div>
<div id="control" style='width: 915px; height: 50px;'></div>
</div>
</div>
<div role="tabpanel" class="tab-pane fade" id="settings"><div class="chart" id="pieMain"></div></div>
</div>
</div>
I'm not sure what else you might need to see, again I'm out of my element here and trying to get a grasp on how to achieve this, thanks!
there are a couple issues here...
first, code is mixed from both the old and new versions of google charts
the old library uses jsapi to load the library
<script src="http://www.google.com/jsapi"></script>
the new library uses the gstatic library
<script src="https://www.gstatic.com/charts/loader.js"></script>
according to the release notes...
The version of Google Charts that remains available via the jsapi loader is no longer being updated consistently. Please use the new gstatic loader from now on.
next, the load statement and callback should only be used once per page
once the callback fires, you can draw as many charts as needed
the callback can also be placed directly in the load statement
try setup similar to the following...
google.charts.load('current', {
callback: drawCharts,
packages: ['controls', 'corechart']
});
function drawCharts() {
drawLineChart();
drawVisualization();
}
function drawLineChart() {
...
}
function drawVisualization() {
...
}
I've managed to implement a continuous axis google chart on my page and got it formatted the way I want it. Now my requirements have changed and I'm trying to load this chart from a CSV as opposed to hard coded and randomly generated data.
I've confused myself and gotten in over my head on how to convert my working chart into pulling from a CSV. I'm going to post a few things here,
One of my other charts that utilizes a CSV, this is what I was trying to recreate
My working continuous axis chart running off hard coded data
My current state of the chart now that I've tried to implement the change.
Here is #1:
function drawPieVisualization() {
$.get("Thornton.M2.csv", function(csvString) {
// transform the CSV string into a 2-dimensional array
var arrayData = $.csv.toArrays(csvString, {onParseValue: $.csv.hooks.castToScalar}, {onParseValue: $.csv.hooks.castToScalar});
// this new DataTable object holds all the data
var data = new google.visualization.arrayToDataTable(arrayData);
// CAPACITY - En-route ATFM delay - YY - CHART
var pieMain = new google.visualization.ChartWrapper({
chartType: 'BarChart',
containerId: 'pieMain',
dataTable: data,
options:{
title: 'Bar Chart Test',
'vAxis': { title: "Bar Chart Test" },
'width': 1100,
'height': 540,
'backgroundColor': 'Ivory',
'color':'Black',
'hAxis': {
title: "Date",
gridlines: { count: 3, color: '#CCC' },
format: 'dd-MMM-yyyy'
},
title: 'Bar Chart Test',
titleTextStyle : {color: 'Black', fontSize: 16},
}
});
pieMain.draw();
});
}
google.setOnLoadCallback(drawPieVisualization)
changeRange = function() {
pieMain.sort({column: 0, desc: false});
pieMain.draw();
};
changeRangeBack = function() {
pieMain.sort({column: 0, desc: true});
pieMain.draw();
};
Here is #2:
function drawVisualization() {
var data = new google.visualization.DataTable();
data.addColumn('date', 'Date');
data.addColumn('number', 'Value');
// add 100 rows of pseudo-random-walk data
for (var i = 0, val = 50; i < 100; i++) {
val += ~~(Math.random() * 5) * Math.pow(-1, ~~(Math.random() * 2));
if (val < 0) {
val += 5;
}
if (val > 100) {
val -= 5;
}
data.addRow([new Date(2014, 0, i + 1), val]);
}
var chart = new google.visualization.ChartWrapper({
chartType: 'ComboChart',
containerId: 'slider_chart_div',
options: {
'title': 'Average Ratings',
'vAxis': { title: "Average Rating" },
'backgroundColor': 'Ivory',
'color':'Black',
width: 1100,
height: 400,
// omit width, since we set this in CSS
chartArea: {
width: '75%' // this should be the same as the ChartRangeFilter
}
}
});
var control = new google.visualization.ControlWrapper({
controlType: 'ChartRangeFilter',
containerId: 'control_div',
options: {
filterColumnIndex: 0,
ui: {
chartOptions: {
'backgroundColor': 'Ivory',
'color':'Black',
width: 1100,
height: 50,
// omit width, since we set this in CSS
chartArea: {
width: '75%' // this should be the same as the ChartRangeFilter
}
}
}
}
});
var dashboard = new google.visualization.Dashboard(document.querySelector('#dashboard_div'));
dashboard.bind([control], [chart]);
dashboard.draw(data);
function zoomLastDay () {
var range = data.getColumnRange(0);
control.setState({
range: {
start: new Date(range.max.getFullYear(), range.max.getMonth(), range.max.getDate() - 1),
end: range.max
}
});
control.draw();
}
function zoomLastWeek () {
var range = data.getColumnRange(0);
control.setState({
range: {
start: new Date(range.max.getFullYear(), range.max.getMonth(), range.max.getDate() - 7),
end: range.max
}
});
control.draw();
}
function zoomLastMonth () {
// zoom here sets the month back 1, which can have odd effects when the last month has more days than the previous month
// eg: if the last day is March 31, then zooming last month will give a range of March 3 - March 31, as this sets the start date to February 31, which doesn't exist
// you can tweak this to make it function differently if you want
var range = data.getColumnRange(0);
control.setState({
range: {
start: new Date(range.max.getFullYear(), range.max.getMonth() - 1, range.max.getDate()),
end: range.max
}
});
control.draw();
}
var runOnce = google.visualization.events.addListener(dashboard, 'ready', function () {
google.visualization.events.removeListener(runOnce);
if (document.addEventListener) {
document.querySelector('#lastDay').addEventListener('click', zoomLastDay);
document.querySelector('#lastWeek').addEventListener('click', zoomLastWeek);
document.querySelector('#lastMonth').addEventListener('click', zoomLastMonth);
}
else if (document.attachEvent) {
document.querySelector('#lastDay').attachEvent('onclick', zoomLastDay);
document.querySelector('#lastWeek').attachEvent('onclick', zoomLastWeek);
document.querySelector('#lastMonth').attachEvent('onclick', zoomLastMonth);
}
else {
document.querySelector('#lastDay').onclick = zoomLastDay;
document.querySelector('#lastWeek').onclick = zoomLastWeek;
document.querySelector('#lastMonth').onclick = zoomLastMonth;
}
});
}
And Here is #3:
function drawVisualization() {
$.get("Source7Days.csv", function(csvString) {
// transform the CSV string into a 2-dimensional array
var arrayData = $.csv.toArrays(csvString, {onParseValue: $.csv.hooks.castToScalar}, {onParseValue: $.csv.hooks.castToScalar});
// this new DataTable object holds all the data
var data = new google.visualization.arrayToDataTable(arrayData);
var chart = new google.visualization.ChartWrapper({
chartType: 'ComboChart',
containerId: 'slider_chart_div',
dataTable: data,
options: {
'title': 'Average Ratings',
'vAxis': { title: "Average Rating" },
'backgroundColor': 'Ivory',
'color':'Black',
width: 1100,
height: 400,
// omit width, since we set this in CSS
chartArea: {
width: '75%' // this should be the same as the ChartRangeFilter
}
}
});
var control = new google.visualization.ControlWrapper({
controlType: 'ChartRangeFilter',
containerId: 'control_div',
options: {
filterColumnIndex: 0,
ui: {
chartOptions: {
'backgroundColor': 'Ivory',
'color':'Black',
width: 1100,
height: 50,
// omit width, since we set this in CSS
chartArea: {
width: '75%' // this should be the same as the ChartRangeFilter
}
}
}
}
});
var dashboard = new google.visualization.Dashboard(document.querySelector('#dashboard_div'));
dashboard.bind([control], [chart]);
dashboard.draw(data);
function zoomLastDay () {
var range = data.getColumnRange(0);
control.setState({
range: {
start: new Date(range.max.getFullYear(), range.max.getMonth(), range.max.getDate() - 1),
end: range.max
}
});
control.draw();
}
function zoomLastWeek () {
var range = data.getColumnRange(0);
control.setState({
range: {
start: new Date(range.max.getFullYear(), range.max.getMonth(), range.max.getDate() - 7),
end: range.max
}
});
control.draw();
}
function zoomLastMonth () {
// zoom here sets the month back 1, which can have odd effects when the last month has more days than the previous month
// eg: if the last day is March 31, then zooming last month will give a range of March 3 - March 31, as this sets the start date to February 31, which doesn't exist
// you can tweak this to make it function differently if you want
var range = data.getColumnRange(0);
control.setState({
range: {
start: new Date(range.max.getFullYear(), range.max.getMonth() - 1, range.max.getDate()),
end: range.max
}
});
control.draw();
}
var runOnce = google.visualization.events.addListener(dashboard, 'ready', function () {
google.visualization.events.removeListener(runOnce);
if (document.addEventListener) {
document.querySelector('#lastDay').addEventListener('click', zoomLastDay);
document.querySelector('#lastWeek').addEventListener('click', zoomLastWeek);
document.querySelector('#lastMonth').addEventListener('click', zoomLastMonth);
}
else if (document.attachEvent) {
document.querySelector('#lastDay').attachEvent('onclick', zoomLastDay);
document.querySelector('#lastWeek').attachEvent('onclick', zoomLastWeek);
document.querySelector('#lastMonth').attachEvent('onclick', zoomLastMonth);
}
else {
document.querySelector('#lastDay').onclick = zoomLastDay;
document.querySelector('#lastWeek').onclick = zoomLastWeek;
document.querySelector('#lastMonth').onclick = zoomLastMonth;
}
});
}
)}
And here is a sample of the CSV Data I'm utilizing
Time,Value
2017/05/22 00:05:00,6710.4305066168
2017/05/22 00:10:00,6667.5043776631
2017/05/22 00:15:00,6615.6655550003
2017/05/22 00:20:00,6554.988194257
2017/05/22 00:25:00,6532.4164219201
2017/05/22 00:30:00,6520.8965539932
The bottom part 'runOnce' in both #2 and #3 are to change the slider control on the chart from 1 day - 1 week - or 1 month of range on the chart, for clarification.
My chart is currently giving me the errors:
One or more participants failed to draw(). (Two of these)
And
The filter cannot operate on a column of type string. Column type must
be one of: number, date, datetime or timeofday. Column role must be
domain, and correlate to a continuous axis.
the second error message reveals that arrayToDataTable
creates the first column as --> type: 'string'
instead of --> type: 'date'
use a DataView to convert the string to a date
you can create calculated columns in a data view using method --> setColumns
use view in place of data when drawing the dashboard
see following snippet...
$.get("Source7Days.csv", function(csvString) {
var arrayData = $.csv.toArrays(csvString, {onParseValue: $.csv.hooks.castToScalar}, {onParseValue: $.csv.hooks.castToScalar});
// this is a static method, "new" keyword should not be used here
var data = google.visualization.arrayToDataTable(arrayData);
// create view
var view = new google.visualization.DataView(data);
view.setColumns([
// first column is calculated
{
calc: function (dt, row) {
// convert string to date
return new Date(dt.getValue(row, 0));
},
label: data.getColumnLabel(0),
type: 'date'
},
// just use index # for second column
1
]);
var chart = new google.visualization.ChartWrapper({
chartType: 'ComboChart',
containerId: 'slider_chart_div',
options: {
title: 'Average Ratings',
vAxis: { title: 'Average Rating' },
backgroundColor: 'Ivory',
color: 'Black',
width: 1100,
height: 400,
chartArea: {
width: '75%'
}
}
});
var control = new google.visualization.ControlWrapper({
controlType: 'ChartRangeFilter',
containerId: 'control_div',
options: {
filterColumnIndex: 0,
ui: {
chartOptions: {
backgroundColor: 'Ivory',
color: 'Black',
width: 1100,
height: 50,
chartArea: {
width: '75%'
}
}
}
}
});
var dashboard = new google.visualization.Dashboard(document.querySelector('#dashboard_div'));
dashboard.bind([control], [chart]);
// use data view
dashboard.draw(view);
...
My JSON array, which I'm getting by ajax response, looks like that:
[["\u041f\u0435\u0440\u0438\u043e\u0434","\u041a\u043b\u0438\u0435\u043d\u0442\u044b","\u0421\u0434\u0435\u043b\u043a\u0438","\u0421\u0443\u043c\u043c\u0430 \u0441\u0434\u0435\u043b\u043e\u043a","\u041e\u043f\u043b\u0430\u0447\u0435\u043d\u043d\u044b\u0435 \u0441\u0434\u0435\u043b\u043a\u0438"],["2017-02-18",0,0,0,0],["2017-02-19",1,0,0,0],["2017-02-20",2,0,0,0],["2017-02-21",4,1,64000,0],["2017-02-22",0,0,0,0],["2017-02-23",3,0,0,0],["2017-02-24",1,0,0,0],["2017-02-25",0,0,0,0],["2017-02-26",2,0,0,0],["2017-02-27",1,1,50000,0],["2017-02-28",1,0,0,0]...etc
So, everythings works fine, my X-axis labels looks good, but I can't understand how can I:
1) make them in date format for Google Chart understand that this is date and
2) group them by month by clicking some button
All problems come from my way of Google Charts implementing.
Here's the code.
function drawChart() {
var obj ='[["\u041f\u0435\u0440\u0438\u043e\u0434","\u041a\u043b\u0438\u0435\u043d\u0442\u044b","\u0421\u0434\u0435\u043b\u043a\u0438","\u0421\u0443\u043c\u043c\u0430 \u0441\u0434\u0435\u043b\u043e\u043a","\u041e\u043f\u043b\u0430\u0447\u0435\u043d\u043d\u044b\u0435 \u0441\u0434\u0435\u043b\u043a\u0438"],["2017-02-18",0,0,0,0],["2017-02-19",1,0,0,0],["2017-02-20",2,0,0,0],["2017-02-21",4,1,64000,0],["2017-02-22",0,0,0,0],["2017-02-23",3,0,0,0],["2017-02-24",1,0,0,0],["2017-02-25",0,0,0,0],["2017-02-26",2,0,0,0],["2017-02-27",1,1,50000,0],["2017-02-28",1,0,0,0],["2017-03-01",0,0,0,0],["2017-03-02",6,0,0,0],["2017-03-03",2,0,0,0],["2017-03-04",1,0,0,0],["2017-03-05",1,0,0,0],["2017-03-06",10,0,0,0],["2017-03-07",1,0,0,0],["2017-03-08",1,0,0,0],["2017-03-09",0,0,0,0],["2017-03-10",9,0,0,0],["2017-03-11",0,0,0,0],["2017-03-12",3,0,0,0],["2017-03-13",3,0,0,0],["2017-03-14",1,0,0,0],["2017-03-15",6,0,0,0],["2017-03-16",1,0,0,0],["2017-03-17",1,0,0,0],["2017-03-18",0,0,0,0],["2017-03-19",5,0,0,0],["2017-03-20",5,0,0,0]]';
data = google.visualization.arrayToDataTable($.parseJSON(obj));
var options = {
crosshair: {
trigger: 'both',
orientation: 'vertical'
},
focusTarget: 'category',
chartArea:{left:40,top:40,width:"85%"},
hAxis: {
format: 'MM'
},
vAxes: {
0: {},
1: {title: 'Cумма'},
},
series: {0: {targetAxisIndex:0},
1:{targetAxisIndex:0},
2:{targetAxisIndex:1},
3:{targetAxisIndex:1},
},
animation:{
duration: 750,
// easing: 'out',
startup: true
},
backgroundColor: 'aliceblue'
};
var chart = new google.visualization.LineChart(
document.getElementById('chart_div')
);
chart.draw(data, options);
}
google.charts.load('current', {'packages':['corechart']});
google.charts.setOnLoadCallback(drawChart);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="http://www.google.com/jsapi?ext.js"></script>
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div" style="width: 100%; height: 400px;"></div>
1) for google to recognize the first column as a date, need to use the following format in the json...
"Date(year, month, day, hours, minutes, days, seconds, milliseconds)"
e.g.
["Date(2017, 1, 18)",0,0,0,0],["Date(2017, 1, 19)",1,0,0,0],
month is zero-based --> 1 = Feb
or, you can use a view and a calculated column to convert, see snippet...
2) use the group() method to group by month
see following working snippet...
function drawChart() {
var obj ='[["\u041f\u0435\u0440\u0438\u043e\u0434","\u041a\u043b\u0438\u0435\u043d\u0442\u044b","\u0421\u0434\u0435\u043b\u043a\u0438","\u0421\u0443\u043c\u043c\u0430 \u0441\u0434\u0435\u043b\u043e\u043a","\u041e\u043f\u043b\u0430\u0447\u0435\u043d\u043d\u044b\u0435 \u0441\u0434\u0435\u043b\u043a\u0438"],["2017-02-18",0,0,0,0],["2017-02-19",1,0,0,0],["2017-02-20",2,0,0,0],["2017-02-21",4,1,64000,0],["2017-02-22",0,0,0,0],["2017-02-23",3,0,0,0],["2017-02-24",1,0,0,0],["2017-02-25",0,0,0,0],["2017-02-26",2,0,0,0],["2017-02-27",1,1,50000,0],["2017-02-28",1,0,0,0],["2017-03-01",0,0,0,0],["2017-03-02",6,0,0,0],["2017-03-03",2,0,0,0],["2017-03-04",1,0,0,0],["2017-03-05",1,0,0,0],["2017-03-06",10,0,0,0],["2017-03-07",1,0,0,0],["2017-03-08",1,0,0,0],["2017-03-09",0,0,0,0],["2017-03-10",9,0,0,0],["2017-03-11",0,0,0,0],["2017-03-12",3,0,0,0],["2017-03-13",3,0,0,0],["2017-03-14",1,0,0,0],["2017-03-15",6,0,0,0],["2017-03-16",1,0,0,0],["2017-03-17",1,0,0,0],["2017-03-18",0,0,0,0],["2017-03-19",5,0,0,0],["2017-03-20",5,0,0,0]]';
var data = google.visualization.arrayToDataTable($.parseJSON(obj));
// create date formatter
var formatDate = new google.visualization.DateFormat({
pattern: 'MM'
});
// create view with calculated column
var view = new google.visualization.DataView(data);
view.setColumns([
// col 0 - x
{
label: 'date',
type: 'date',
calc: function (dt, row) {
return new Date(dt.getValue(row, 0))
}
},
// col 1 - y
1
]);
// group by month
var groupData = google.visualization.data.group(
// data table
view,
// group by fields
[{column: 0, type: 'string', modifier: function (xValue) {
return formatDate.formatValue(new Date(xValue));
}}],
// aggregate fields
[
{
aggregation: google.visualization.data.sum,
column: 1,
label: 'Total',
type: 'number'
}
]
);
var options = {
crosshair: {
trigger: 'both',
orientation: 'vertical'
},
focusTarget: 'category',
chartArea:{left:40,top:40,width:"85%"},
hAxis: {
format: 'MM'
},
vAxes: {
0: {},
1: {title: 'C????'},
},
series: {0: {targetAxisIndex:0},
1:{targetAxisIndex:0},
2:{targetAxisIndex:1},
3:{targetAxisIndex:1},
},
animation:{
duration: 750,
easing: 'inAndOut',
startup: true
},
backgroundColor: 'aliceblue'
};
var chart = new google.visualization.LineChart(
document.getElementById('chart_div')
);
// draw grouped data
chart.draw(groupData, options);
}
google.charts.load('current', {
callback: function () {
drawChart();
window.addEventListener('resize', drawChart, false);
},
packages:['corechart']
});
<script src="https://www.gstatic.com/charts/loader.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<div id="chart_div"></div>
I have a page that displays data using LineChart with a ChartRangeFilter control.
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<script type="text/javascript">
google.load('visualization', '1', {packages: ['controls', 'charteditor']});
google.setOnLoadCallback(drawChart);
function drawChart() {
var data = new google.visualization.DataTable();
data.addColumn('date', 'X');
data.addColumn('number', 'Y1');
data.addColumn('number', 'Y2');
for (var i = 0; i < 12; i++) {
data.addRow([new Date(2016, i,1), Math.floor(Math.random() * 200), Math.floor(Math.random() * 200)]);
}
var dash = new google.visualization.Dashboard(document.getElementById('dashboard'));
var control = new google.visualization.ControlWrapper({
controlType: 'ChartRangeFilter',
containerId: 'control_div',
options: {
filterColumnIndex: 0,
ui: {
chartOptions: {
height: 50,
width: 600,
chartArea: {
width: '80%'
}
},
chartView: {
columns: [0, 1]
}
}
}
});
var chart = new google.visualization.ChartWrapper({
chartType: 'LineChart',
containerId: 'chart_div'
});
function setOptions (wrapper) {
wrapper.setOption('width', 620);
wrapper.setOption('chartArea.width', '80%');
}
setOptions(chart);
dash.bind([control], [chart]);
dash.draw(data);
google.visualization.events.addListener(control, 'statechange', function () {
var v = control.getState();
document.getElementById('dbgchart').innerHTML = v.range.start+ ' to ' +v.range.end;
return 0;
});
}
</script>
<div id="dashboard">
<div id="chart_div"></div>
<div id="control_div"></div>
<p><span id='dbgchart'></span></p>
</div>
And here's a working JSFiddle.
Here the control starts from Jan 1. When I change start range to Jan 2, the graph date starts to show from Feb. I could not identify the reason for this. Can anyone help me in this? In the end range it is working fine it seems.
In this example, on 'statechange' -- the value for the begin and end months, for the selected chart range, are modified to ensure data points are plotted.
The chart is then redrawn with updated options.
google.charts.load('44', {
callback: drawChart,
packages: ['controls', 'corechart']
});
function drawChart() {
var data = new google.visualization.DataTable();
data.addColumn('date', 'X');
data.addColumn('number', 'Y1');
data.addColumn('number', 'Y2');
data.addRow([new Date(2016, 0, 1), 1,123]);
data.addRow([new Date(2016, 1, 1), 6,42 ]);
data.addRow([new Date(2016, 2, 1), 4,49 ]);
data.addRow([new Date(2016, 3, 1), 23,486 ]);
data.addRow([new Date(2016, 4, 1), 89,476 ]);
data.addRow([new Date(2016, 5, 1), 46,444 ]);
data.addRow([new Date(2016, 6, 1), 178,442 ]);
data.addRow([new Date(2016, 7, 1), 12,274 ]);
data.addRow([new Date(2016, 8, 1), 123,4934 ]);
data.addRow([new Date(2016, 9, 1), 144,4145 ]);
data.addRow([new Date(2016, 10, 1), 135,946 ]);
data.addRow([new Date(2016, 11, 1), 178,747 ]);
var control = new google.visualization.ControlWrapper({
controlType: 'ChartRangeFilter',
containerId: 'control_div',
options: {
filterColumnIndex: 0,
ui: {
chartOptions: {
height: 50,
width: 600,
chartArea: {
width: '80%'
}
}
}
}
});
var chart = new google.visualization.ChartWrapper({
chartType: 'LineChart',
containerId: 'chart_div',
options: {
width: 620,
chartArea: {
width: '80%'
},
hAxis: {
format: 'MMM',
slantedText: false,
maxAlternation: 1
}
}
});
function setOptions() {
var firstDate;
var lastDate;
var v = control.getState();
if (v.range) {
document.getElementById('dbgchart').innerHTML = v.range.start + ' to ' + v.range.end;
firstDate = new Date(v.range.start.getTime() + 1);
lastDate = new Date(v.range.end.getTime() - 1);
data.setValue(v.range.start.getMonth(), 0, firstDate);
data.setValue(v.range.end.getMonth(), 0, lastDate);
} else {
firstDate = data.getValue(0, 0);
lastDate = data.getValue(data.getNumberOfRows() - 1, 0);
}
var ticks = [];
for (var i = firstDate.getMonth(); i <= lastDate.getMonth(); i++) {
ticks.push(data.getValue(i, 0));
}
chart.setOption('hAxis.ticks', ticks);
chart.setOption('hAxis.viewWindow.min', firstDate);
chart.setOption('hAxis.viewWindow.max', lastDate);
if (dash) {
chart.draw();
}
}
setOptions();
google.visualization.events.addListener(control, 'statechange', setOptions);
var dash = new google.visualization.Dashboard(document.getElementById('dashboard'));
dash.bind([control], [chart]);
dash.draw(data);
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="dashboard">
<div id="chart_div"></div>
<div id="control_div"></div>
<p><span id='dbgchart'></span></p>
</div>
It is because you only have one value for January (1st the jan) and when you set the start range to jan 2 the next value in your data if for Feb 1st.
The month value for month in the data object is zero-based.
How exactly do I use the jquery ui slider instead of a numberrange filter. I have an idea of how each work, but am unsure how this needs to be related to the chart data.
EDIT: Whole code(sorry about comments):
<!DOCTYPE html>
<head>
<title>Google Chart Example</title>
<script src="https://www.google.com/jsapi"></script>
<script src="http://code.jquery.com/jquery-1.10.1.min.js"></script>
<!-- <script src="http://prithwis.x10.bz/charts/jquery.csv-0.71.js"></script> -->
<script src="https://jquery-csv.googlecode.com/files/jquery.csv-0.71.js"></script>
<script src="http://code.jquery.com/ui/1.10.4/jquery-ui.js"></script>
<link href="http://code.jquery.com/ui/1.10.4/themes/ui-lightness/jquery-ui.css" rel="stylesheet">
<!--script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jqueryui/1/jquery-ui.min.js"></script-->
<!--script src="http://code.jquery.com/jquery-1.10.2.js"></script-->
<script type="text/javascript">
google.load('visualization', '1.1', {packages: ['controls']});
google.setOnLoadCallback(drawVisualization);
function drawVisualization() {
// Prepare the data
//$.get("abc.csv - abc.csv.csv", function(csvString) {
$.get("Data_Actual_V2.csv", function(csvString) {
// transform the CSV string into a 2-dimensional array
var arrayData = $.csv.toArrays(csvString, {onParseValue: $.csv.hooks.castToScalar});
// use arrayData to load the select elements with the appropriate options
for (var i = 1; i < arrayData[0].length; i++) { // i starts from 1, not 0 because the first column is text
// this adds the given option to both select elements
$("select").append("<option value='" + i + "'>" + arrayData[0][i] + "</option");
}
// set the default selection
$("#range option[value='1']").attr("selected","selected");
// this new DataTable object holds all the data
var data = new google.visualization.arrayToDataTable(arrayData);
var columnsTable = new google.visualization.DataTable();
columnsTable.addColumn('number', 'colIndex');
columnsTable.addColumn('string', 'colLabel');
var initState = {
selectedValues: []
};
// put the columns into this data table (skip column 0)
for (var i = 2; i < data.getNumberOfColumns(); i++) {
columnsTable.addRow([i, data.getColumnLabel(i)]);
}
initState.selectedValues.push(data.getColumnLabel(4));
var CountryPicker = new google.visualization.ControlWrapper({
controlType: 'CategoryFilter',
containerId: 'control3',
options: {
filterColumnLabel: 'Location',
ui: {
labelStacking: 'vertical',
allowTyping: false,
allowMultiple: true,
caption: 'Country',
label: 'Country'
}
}
});
/*var slider2 = new google.visualization.ControlWrapper({
//'controlType': 'DateRangeFilter',
'controlType': 'NumberRangeFilter',
'containerId': 'control4',
'options': {
//'ui.format': 'pattern:"yyyy"',
// 'ui.format': 'fractionDigits: 0',
'filterColumnLabel': 'Year',
'ui': { 'format': { 'fractionDigits':'0',
'groupingSymbol':'' } }
},
}); */
//Define a chart to show AML CFT Risk per country
var options1 = {
title: 'A',
displayMode: 'regions',
//width: 1000,
datalessRegionColor: 'C0C0C0',
hAxis: {title: 'Year', }
colorAxis: {
values: [0, 12.5, 25, 37.5, 50, 62.5, 75, 87.5, 100],
colors: ['#3366FF','#33CCCC', '#00FFFF', '#CCFFFF', '#00FF00', '#FFFF99','#FFCC00','#FF9900','#FF0000'],
minValue: 0,
maxValue: 100,
}
}
var xA;
//var yB = 4;
/*var view1 = { // Defines data to show in geoChart
columns: [x1, y1] //[0,4]
}*/
var geoChart = new google.visualization.ChartWrapper({
chartType: 'GeoChart',
containerId: 'chart1',
options: options1,
view: {
columns: [0, 4]
}
});
$(function() {
$('#slider').slider({
disabled: true,
range: 'min',
value: 44,
min: 1969,
max: 2013,
change: function(event, ui) {
$('#header').text('debug=' + ui.value);
//options1.minValue = ui.value;/////HERE TO LINK TO ABOVE
xA = ui.value;
console.log(xA);
//drawChart();
setChartView();
}
});
});
var GenderPicker = new google.visualization.ControlWrapper({
controlType: 'CategoryFilter',
containerId: 'control2',
dataTable: columnsTable,
options: {
filterColumnLabel: 'colLabel',
ui: {
label: 'Columns',
allowTyping: false,
allowMultiple: false,
allowNone: false,
selectedValuesLayout: 'belowStacked'
}
},
state: initState
});
function setChartView() {
var state = GenderPicker.getState();
var row;
var view = {
columns: [0]
};
for (var i = 0; i < state.selectedValues.length; i++) {
row = columnsTable.getFilteredRows([{
column: 1,
value: state.selectedValues[i]
}])[0];
view.columns.push(columnsTable.getValue(row, 0));
}
// sort the indices into their original order
view.columns.sort(function (a, b) {
return (a - b);
});
geoChart.setView(view);
geoChart.draw();
}
google.visualization.events.addListener(GenderPicker, 'statechange', setChartView);
google.visualization.events.addOneTimeListener(geoChart, 'ready', function () {
$('#slider').slider('enable');
setChartView();
});
var dashboard = new google.visualization.Dashboard(document.getElementById('dashboard'));
dashboard.bind([CountryPicker/*, slider2*/],[geoChart]). // consolidated all of the bind calls
// Draw the dashboard
draw(data);
GenderPicker.draw();
});
}
<body>
<div id="dashboard">
<table>
<tr style='vertical-align: top'>
<td style='width: 300px; font-size: 0.9em;'>
<div id="control1"></div>
<div id="control2"></div>
<div id="control3"></div>
<div id="control4"></div>
<div id="slider"></div>
<h3 id ="header">Sometext</h3>
</td>
<td style='width: 600px'>
<div style="float: left;" id="chart1"></div>
</td>
</tr>
</table>
</div>
</body>
</html>
Have been trying to follow: Using jQuery slider to change Google chart viewWindow
With a bit of this as well: https://stackoverflow.com/questions/26154248/how-to-display-various-controlwrappers-from-2-datatables-with-a-single-geochart?noredirect=1#comment41031194_26154248
EDIT V2
I solved it by using the standard google slider, and assigning my jquery slider value to it's 'highValue'. I then set the div containing the google slider to display: none.
var slider2 = new google.visualization.ControlWrapper({
'controlType': 'NumberRangeFilter',
'containerId': 'control4',
'options': {
'filterColumnLabel': 'Year',
'ui': { 'format': { 'fractionDigits':'0',
'groupingSymbol':'' } }
},
});
$(function() {
$('#slider').slider({
disabled: true,
range: 'min',
value: 53,
min: 1960,
max: 2013,
change: function(event, ui) {
$('#header').text('debug=' + ui.value);
//options1.minValue = ui.value;/////HERE TO LINK TO ABOVE
xA = ui.value;
console.log(xA);
//drawChart();
slider2.setState({'highValue': ui.value});
slider2.draw();
setChartView();
}
});
});
<div id="control4" style="display: none;"></div>
Definitely, not the nicest or most correct method of doing this, however it did solve the problem.