Related
I'd like to create column chart with X axis numeric values 1, 2, 3, 4 ... N and Y value of course different on every column.
I can't find out how to change labels on X line under bars, to string. For example - 1 could be marked as Elephant, 2 as Horse etc.
I could use string as X values, but then there is no way to get zoom working. At least, I didn't find any way to get it working.
simple example with strings, I'd like to achieve same appearance as this one, but with numeric values on X axis.
google.charts.load('current', {packages: ['corechart', 'bar']});
google.charts.setOnLoadCallback(drawBasic);
function drawBasic() {
var data = new google.visualization.DataTable();
data.addColumn('number', 'animal');
data.addColumn('number', 'count');
data.addRows([
['Elephant', 5],
['Horse', 2],
['Dog', 7],
['Cat', 4],
]);
var options = {
explorer: {
axis: 'horizontal',
keepInBounds: true,
},
title: 'Testing',
hAxis: {
title: 'Animal',
},
vAxis: {
title: 'number'
}
};
var chart = new google.visualization.ColumnChart(
document.getElementById('chart_div'));
chart.draw(data, options);
}
Chart should look like this, but with working zoom:
Chart example
to use string labels on a continuous axis,
you will need to provide your own ticks
using object notation, provide the value (v:) and formatted value (f:)
{v: 1, f: 'Elephant'}
see following working snippet...
google.charts.load('current', {
callback: drawBasic,
packages: ['corechart']
});
function drawBasic() {
var data = new google.visualization.DataTable();
data.addColumn('number', 'animal');
data.addColumn('number', 'count');
data.addRows([
[1, 5],
[2, 2],
[3, 7],
[4, 4]
]);
var options = {
explorer: {
axis: 'horizontal'
},
title: 'Testing',
hAxis: {
ticks: [
{v: 1, f: 'Elephant'},
{v: 2, f: 'Horse'},
{v: 3, f: 'Dog'},
{v: 4, f: 'Cat'}
],
title: 'Animal',
},
vAxis: {
title: 'number'
}
};
var chart = new google.visualization.ColumnChart(
document.getElementById('chart_div')
);
chart.draw(data, options);
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div"></div>
The following works fine (see jsfiddle) except when the table is filtered via one of the control wrappers. It seems that currentRow and rowIndex always have the same number e.g. google.visualization.DataView#getTableRowIndex(currentRow) doesn't do any translation; it simply spits out the same number that's passed in. How must the row index be properly translated so that one can obtain the desired row from the underlying google.visualization.DataTable?
function drawChart()
{
var dataTable = new google.visualization.DataTable();
dataTable.addColumn('date', 'Request Date');
dataTable.addColumn('string', 'To Do');
dataTable.addColumn('date', 'Target Complete Date');
dataTable.addColumn('number', 'Duration');
dataTable.addColumn('date', 'Date Completed');
dataTable.addColumn('number', 'ID');
dataTable.addRow([
new Date(2014, 1, 24),
'To do item 1',
new Date(2014, 1, 27),
3.5,
new Date(2014, 1, 26),
1000
]);
dataTable.addRow([
new Date(2014, 2, 24),
'To do item 2',
new Date(2014, 2, 27),
1.5,
new Date(2014, 2, 26),
1001
]);
dataTable.addRow([
new Date(2014, 3, 24),
'To do item 3',
new Date(2014, 3, 27),
7.5,
new Date(2014, 3, 26),
1002
]);
dataTable.addRow([
new Date(2014, 4, 24),
'To do item 4',
new Date(2014, 4, 27),
4.5,
new Date(2014, 4, 26),
1003
]);
dataTable.addRow([
new Date(2014, 5, 24),
'To do item 5',
new Date(2014, 5, 27),
2.5,
new Date(2014, 5, 26),
1004
]);
// Format the duration column so that it shows two decimal places.
var durationFormatter = new google.visualization.NumberFormat({ 'fractionDigits': 2 });
durationFormatter.format(dataTable, 3); // Apply formatter to duration column
// Table chart
var cssClassNames = {
'headerRow': 'dataHeaderRow',
'tableRow': 'dataTableRow',
'oddTableRow': 'dataOddTableRow',
'selectedTableRow': 'dataSelectedTableRow',
'hoverTableRow': 'dataHoverTableRow',
'headerCell': 'dataHeaderCell',
'tableCell': 'dataTableCell',
'rowNumberCell': 'dataRowNumberCell'
};
var tableChartOptions = {
'cssClassNames': cssClassNames,
'alternatingRowStyle': true,
'page': 'enable',
'pageSize': 10,
'pagingSymbols': {
prev: '<span class="fa fa-arrow-left"></span>',
next: '<span class="fa fa-arrow-right"></span>'
},
'pagingButtonsConfiguration': 'auto',
'sort': 'enable',
'sortAscending': true,
'sortColumn': 0, // <-- Initially sort by column 0: date column.
'title': 'Completed To Do List',
'width': '100%'
};
// Prevent the database ID (column 5 in underlying data table) from being
// displayed via a data view.
var rawDataView_NoID = new google.visualization.DataView(dataTable);
rawDataView_NoID.setColumns([0, 1, 2, 3, 4]);
var chartWrapper = new google.visualization.ChartWrapper({
'chartType': 'Table', // <-- google.visualization.Table
'containerId': 'loggedInCompletedToDoChart_div',
'options': tableChartOptions
} );
// The chart must be ready before the select listener can be created.
google.visualization.events.addListener(
chartWrapper,
'ready',
function () {
var visualization_table = chartWrapper.getChart(); // <-- google.visualization.Table
google.visualization.events.addListener(
visualization_table,
'select',
function () {
// Chart wrapper in this case is configured to allow only
// a single row selection. Hence, an array of length 1.
var selection = visualization_table.getSelection()[0];
var currentRow, rowIndex, duration, entryId;
if (selection !== undefined) {
currentRow = selection.row;
rowIndex = chartWrapper.getDataTable().getTableRowIndex(currentRow);
duration = dataTable.getFormattedValue(rowIndex, 3);
// entryId is available in underlying data table -- not in data view.
entryId = dataTable.getFormattedValue(rowIndex, 5);
alert(entryId); // Only correct when no filtering takes place.
}
}
);});
// Define Filter controls
var toDoFilter = new google.visualization.ControlWrapper({
'controlType': 'StringFilter',
'containerId': 'loggedInCompletedToDo_ToDo_SearchInputElement_div',
'options': {
'filterColumnLabel': 'To Do',
'matchType': 'any'
}});
var durationFilter = new google.visualization.ControlWrapper({
'controlType': 'NumberRangeFilter',
'containerId': 'loggedInCompletedToDo_Duration_SearchInputElement_div',
'options': {
'filterColumnLabel': 'Duration',
'ui': {
'format': { 'fractionDigits': 2 },
'step': 0.25
}
} } );
// Create the dashboard.
var dashboard = new google.visualization.Dashboard(
document.getElementById('loggedInCompletedToDoDashboard_div')
).
// Configure the filters to affect the chart content
bind([ toDoFilter, durationFilter ], chartWrapper).
// Draw the dashboard
draw(rawDataView_NoID);
}
google.load('visualization', '1.0', {packages: ['table', 'controls']});
google.setOnLoadCallback(drawChart);
EDIT:
I've noticed that the problem only occurs with the first control wrapper passed to the bind function. In other words with the following configuration the row selection stops working correctly if the To Do filter is used:
bind([ toDoFilter, durationFilter ], chartWrapper).
and if I swap the order of the filters then the row selection stops working correctly if the Duration filter is used:
bind([ durationFilter, toDoFilter ], chartWrapper).
If I chain the method invocations as follows the first control wrapper object in the chain is the one that causes row selection to not work properly (just as the first control wrapper object in the array, above, did) and, worse, doing it this way causes the select handler to be invoked 14 times in a row with a single click of the mouse:
bind(durationFilter, chartWrapper).
bind(toDoFilter, chartWrapper).
According to the API reference:
bind(controls, charts)
Binds one or more Controls to one or more other dashboard participants (either charts or other controls), so that all of the latter are redrawn whenever any of the former collects a programmatic or user interaction that affects the data managed by the dashboard. Returns the dashboard instance itself for chaining multiple bind() calls together.
controls - Either a single one or an array of google.visualization.ControlWrapper instances defining the controls to bind.
charts - Either a single one or an array of google.visualization.ChartWrapper instances defining the charts the that will be driven the by the controls.
You can avoid this by just referencing the data passed to the ChartWrapper instead of trying to translate back to the original DataTable. Change this:
currentRow = selection.row;
rowIndex = chartWrapper.getDataTable().getTableRowIndex(currentRow);
duration = dataTable.getFormattedValue(rowIndex, 3);
to this:
duration = chartWrapper.getDataTable().getFormattedValue(selection.row, 3);
Also, ChartWrappers now support the "select" event natively, so you don't need to wrap them with a "ready" event:
google.visualization.events.addListener(chartWrapper, 'select', function () {
// selection handling
});
I'm trying to create a Google chart that looks like the following:
http://chart.googleapis.com/chart?cht=bvs&chs=200x125&chd=t2:10,50,60,80,40%7C50,60,100,40,20%7C30,70,90,95,45&chco=4d89f900,c6d9fd&chbh=20&chds=0,160&chm=H,336699,2,-1,1:22
Basically, I just want to represent the max, min, and average all on one chart, but I can't seem to figure out how to do this. I know it's possible using markers with the old URL-based charts, but they're being deprecated and it doesn't look like the new API supports markers yet.
I tried using candlesticks, but the only way I got it working was with a skinny line and a horizontal line in the middle, so it looked like a bunch of plus signs rather than floating columns with line markers. I know I could also technically stack a column chart with a stepped area chart, but then the line is continuous across all entries, which I don't want.
Thanks.
EDIT: Using jmac's method and intervals, I came up with this:
function drawVisualization() {
// Create and populate the data table.
var data = new google.visualization.DataTable();
data.addColumn('string', 'label');
data.addColumn('number', 'filler');
data.addColumn('number', 'range');
data.addColumn({type:'number', role:'interval'});
data.addRows([
['A', 3, 4, 2],
['B', 2, 5, 4],
['C', 4, 4, 1],
['D', 5, 2, 1],
['E', 1, 8, 4],
]);
// Create and draw the visualization.
var ac = new google.visualization.ColumnChart(document.getElementById('visualization'));
ac.draw(data, {
width: 600,
isStacked: true,
series: [{color:'transparent'},{color:'silver'},{color:'silver'}],
vAxis: {gridlines: {color: 'transparent'}, textPosition: 'none'},
focusTarget: 'category',
intervals: { 'style': 'bars', 'barWidth': 1.3, 'lineWidth': 2 },
});
}
I don't have enough reputation to post an image of what it looks like yet, but if you paste it in here you can see it: https://code.google.com/apis/ajax/playground/?type=visualization#column_chart
Also, since it still highlights the filler area when you mouse over it, I found a css hack to hide the highlighting on mouse over:
#chart-div {
svg g g g g rect {
stroke-width:0px;
}
}
You can use "box" style intervals to accomplish what you want:
function drawChart () {
var data = new google.visualization.DataTable();
data.addColumn('string', 'Category');
data.addColumn('number', 'Min');
data.addColumn('number', 'Average');
data.addColumn('number', 'Max');
data.addRows([
['Foo', 3, 5, 7],
['Bar', 5, 8, 10],
['Baz', 0, 2, 6],
['Bat', 1, 2, 4]
]);
var view = new google.visualization.DataView(data);
// duplicate 1 column as a dummy data series, and add intervals to it
view.setColumns([0, 1, {
id: 'min',
type: 'number',
role: 'interval',
calc: function (dt, row) {
return dt.getValue(row, 1);
}
}, {
id: 'avg',
type: 'number',
role: 'interval',
calc: function (dt, row) {
return dt.getValue(row, 2);
}
}, {
id: 'max',
type: 'number',
role: 'interval',
calc: function (dt, row) {
return dt.getValue(row, 3);
}
}, 1, 2, 3]);
var chart = new google.visualization.LineChart(document.querySelector('#chart_div'));
chart.draw(view, {
height: 400,
width: 600,
lineWidth: 0,
intervals: {
style: 'boxes'
},
legend: {
position: 'none'
},
series: {
0: {
// dummy data series, controls color of intervals
visibleInLegend: false,
color: 'blue',
enableInteractivity: false
},
1: {
// min series options
},
2: {
// average series options
},
3: {
// max series options
}
}
});
}
google.load('visualization', '1', {packages:['corechart'], callback: drawChart});
See working example: http://jsfiddle.net/asgallant/pvJpx/
If all you care about is how it looks visually, you can recreate this with a bit of finagling to have it look like this:
This is the code:
function drawVisualization() {
// Create and populate the data table.
var data = google.visualization.arrayToDataTable([
['label', 'filler', 'bot half', 'top half'],
['A', 3, 2, 2],
['B', 2, 4, 1],
['C', 4, 1, 3],
['D', 5, 1, 1],
['E', 1, 4, 4],
]);
// Create and draw the visualization.
var ac = new google.visualization.ColumnChart(document.getElementById('visualization'));
ac.draw(data, {
width: 600,
isStacked: true,
series: [{color:'transparent'},{color:'silver'},{color:'silver'}],
vAxis: {gridlines: {color: 'transparent'}, textPosition: 'none'},
focusTarget: 'category',
});
}
This is a dumb workaround, but here are the steps given a min value, a max value, and an avg value:
Create a dummy (transparent) series equal to min
Create a second series for the bottom half of the bar equal to avg - min
Create a third series for the top half of the bar equal to max - avg
Although it looks right, the issue is that interaction with the chart will be real funky, in the sense that it won't show you what you would expect from the chart (you would have separate values that aren't showing min, max, and average, but only two values for the size of points 2) and 3) above). You can get around this with creative use of focusTarget, but that will still get you odd stuff like this:
Now you could theoretically rename your series, and use the {v:, f:} trick to make it look nicer, and that may be a good workaround, but it is very kludgy depending on your application. If you finagle it all nice and right, you would get something like this:
This is done with the following code:
function drawVisualization() {
// Create and populate the data table.
var data = new google.visualization.DataTable();
data.addColumn('string', 'Series Name');
data.addColumn('number', 'Average');
data.addColumn('number', 'Minimum');
data.addColumn('number', 'Maximum');
data.addRows([
['A', {v:3, f:'5'}, {v:2, f:'3'}, {v:2, f:'7'}],
['B', {v:2, f:'6'}, {v:4, f:'2'}, {v:1, f:'7'}],
['C', {v:4, f:'5'}, {v:1, f:'4'}, {v:3, f:'8'}],
['D', {v:5, f:'6'}, {v:1, f:'5'}, {v:1, f:'8'}],
['E', {v:1, f:'5'}, {v:4, f:'1'}, {v:4, f:'9'}],
]);
// Create and draw the visualization.
var ac = new google.visualization.ColumnChart(document.getElementById('visualization'));
ac.draw(data, {
width: 600,
isStacked: true,
series: [{color:'transparent'},{color:'silver'},{color:'silver'}],
vAxis: {gridlines: {color: 'transparent'}, textPosition: 'none'},
focusTarget: 'category',
});
}
Again, this is kludgy and not perfect (see the grey box around the filler series, that can't be helped), but it will display the info, and it can be automated using some fancy javascript and/or formatters with dataviews depending on how often the charts need to be changed and what format you get your data in.
I can't figure out why, I've triple checked that I'm passing in the right values. When I hover over any of the bars it displays the right data, but every single one of them displays at 10x scale on the graph and I can't figure out why. Here's my code if it helps:
var dashboard2 = new google.visualization.Dashboard(
document.getElementById('dashboard'));
var control2 = new google.visualization.ControlWrapper({
'controlType': 'ChartRangeFilter',
'containerId': 'control2',
'options': {
// Filter by the date axis.
'filterColumnIndex': 0,
'ui': {
'chartType': 'LineChart',
'chartOptions': {
'chartArea': {'width': '80%'},
'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, 1, 14]
},
// 1 day in milliseconds = 24 * 60 * 60 * 1000 = 86,400,000
'minRangeSize': 259200000
}
},
// Initial range: 2012-02-09 to 2012-03-20.
'state': {'range': {'start': new Date(2012, 11, 7), 'end': new Date()}}
});
var chart2 = new google.visualization.ChartWrapper({
'chartType': 'ComboChart',
'containerId': 'chart2',
'options': {
// Use the same chart area width as the control for axis alignment.
'chartArea': {'height': '80%', 'width': '80%'},
'hAxis': {'slantedText': false},
'vAxis': {'viewWindow': {'min': 0, 'max': 400}},
'title': 'Sales Made by Affiliate Name',
'seriesType': "bars",
'series': {0: {type: "line"}, 13: {type: "line"}},
'isStacked': true
},
// 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, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
}
});
var jsonData2 = $.ajax({
url: "getData.php",
dataType:"json",
async: false
}).responseText;
// Create our data table out of JSON data loaded from server
var data2 = new google.visualization.DataTable(jsonData2);
dashboard2.bind(control2, chart2);
dashboard2.draw(data2);
Edit: Here's a small bit of the data at the very beginning, because I don't want to give out our data, but I suppose it might be necessary to get an idea for what is being passed in. I cut out the starting bracket for readability:
"cols":[ {"id":"","label":"Date","pattern":"","type":"date"}, {"id":"","label":"Total","pattern":"","type":"number"}, {"id":"","label":"andersce99","pattern":"","type":"number"}, {"id":"","label":"sojourn","pattern":"","type":"number"}, {"id":"","label":"warriorplus","pattern":"","type":"number"}, {"id":"","label":"potpie queen","pattern":"","type":"number"}, {"id":"","label":"60minuteaffiliate","pattern":"","type":"number"}, {"id":"","label":"bob voges","pattern":"","type":"number"}, {"id":"","label":"Grayth","pattern":"","type":"number"}, {"id":"","label":"TiffanyDow","pattern":"","type":"number"}, {"id":"","label":"AmandaT","pattern":"","type":"number"}, {"id":"","label":"Gaz Cooper","pattern":"","type":"number"}, {"id":"","label":"Sam England","pattern":"","type":"number"}, {"id":"","label":"Matthew Olson","pattern":"","type":"number"}, {"id":"","label":"Average Per Day Over Time","pattern":"","type":"number"} ],
"rows": [ {"c":[{"v":"Date(2012,11,7)","f":null},{"v":"387","f":null},{"v":"19","f":null},{"v":"275","f":null},{"v":"8","f":null},{"v":"0","f":null},{"v":"35","f":null},{"v":"3","f":null},{"v":"21","f":null},{"v":"0","f":null},{"v":"0","f":null},{"v":"0","f":null},{"v":"11","f":null},{"v":"6","f":null},{"v":"387","f":null}]},
{"c":[{"v":"Date(2012,11,8)","f":null},{"v":"98","f":null},{"v":"11","f":null},{"v":"39","f":null},{"v":"1","f":null},{"v":"0","f":null},{"v":"15","f":null},{"v":"0","f":null},{"v":"7","f":null},{"v":"9","f":null},{"v":"0","f":null},{"v":"0","f":null},{"v":"3","f":null},{"v":"6","f":null},{"v":"242.5","f":null}]},
{"c":[{"v":"Date(2012,11,9)","f":null},{"v":"58","f":null},{"v":"7","f":null},{"v":"16","f":null},{"v":"0","f":null},{"v":"0","f":null},{"v":"4","f":null},{"v":"0","f":null},{"v":"3","f":null},{"v":"10","f":null},{"v":"2","f":null},{"v":"9","f":null},{"v":"0","f":null},{"v":"2","f":null},{"v":"181","f":null}]},
{"c":[{"v":"Date(2012,11,10)","f":null},{"v":"196","f":null},{"v":"5","f":null},{"v":"8","f":null},{"v":"126","f":null},{"v":"0","f":null},{"v":"2","f":null},{"v":"35","f":null},{"v":"0","f":null},{"v":"7","f":null},{"v":"4","f":null},{"v":"3","f":null},{"v":"1","f":null},{"v":"0","f":null},{"v":"184.75","f":null}]},
{"c":[{"v":"Date(2012,11,11)","f":null},{"v":"76","f":null},{"v":"7","f":null},{"v":"5","f":null},{"v":"17","f":null},{"v":"30","f":null},{"v":"7","f":null},{"v":"1","f":null},{"v":"1","f":null},{"v":"2","f":null},{"v":"1","f":null},{"v":"4","f":null},{"v":"0","f":null},{"v":"0","f":null},{"v":"163","f":null}]},
{"c":[{"v":"Date(2012,11,12)","f":null},{"v":"48","f":null},{"v":"4","f":null},{"v":"5","f":null},{"v":"9","f":null},{"v":"20","f":null},{"v":"7","f":null},{"v":"1","f":null},{"v":"0","f":null},{"v":"0","f":null},{"v":"0","f":null},{"v":"0","f":null},{"v":"0","f":null},{"v":"0","f":null},{"v":"143.833333333","f":null}]},
{"c":[{"v":"Date(2012,11,13)","f":null},{"v":"21","f":null},{"v":"3","f":null},{"v":"2","f":null},{"v":"5","f":null},{"v":"4","f":null},{"v":"0","f":null},{"v":"0","f":null},{"v":"1","f":null},{"v":"2","f":null},{"v":"0","f":null},{"v":"1","f":null},{"v":"0","f":null},{"v":"0","f":null},{"v":"126.285714286","f":null}]},
{"c":[{"v":"Date(2012,11,14)","f":null},{"v":"12","f":null},{"v":"1","f":null},{"v":"1","f":null},{"v":"2","f":null},{"v":"4","f":null},{"v":"2","f":null},{"v":"0","f":null},{"v":"0","f":null},{"v":"0","f":null},{"v":"0","f":null},{"v":"0","f":null},{"v":"0","f":null},{"v":"0","f":null},{"v":"112","f":null}]},
{"c":[{"v":"Date(2012,11,15)","f":null},{"v":"8","f":null},{"v":"3","f":null},{"v":"0","f":null},{"v":"1","f":null},{"v":"2","f":null},{"v":"0","f":null},{"v":"0","f":null},{"v":"1","f":null},{"v":"0","f":null},{"v":"1","f":null},{"v":"0","f":null},{"v":"0","f":null},{"v":"0","f":null},{"v":"100.444444444","f":null}]}
Your data is formatted incorrectly: numbers need to be stored as numbers in the JSON, not as strings. As an example, this:
{"v":"387","f":null}
should be like this:
{"v":387,"f":null}
If you are using PHP's json_encode function to build the JSON, you can add JSON_NUMERIC_CHECK as an argument to the function call to output the numbers properly:
json_encode($myData, JSON_NUMERIC_CHECK);
Im getting some Google analytic data from the server and passing it to a Google chart as JSON. I cannot figure out how to get the chart to render as a date axis with lines. I now looks like this http://screencast.com/t/VdPNzW6JDlPQ and I need it to look like this http://screencast.com/t/yCzUdurhB.
This is the code
var Simple_data = new google.visualization.DataTable(Simple_setData(), 0.5);
visualization = new google.visualization.LineChart(document.getElementById('report_Simple'));
visualization.draw(Simple_data, Simple_options);
var Simple_options = { "title": "Test" };
function Simple_setData() {
var Simple_JsonTable = { cols: [{id: 'ga:date', label: 'date', type: 'string'}, {id: 'ga:visits', label: 'visits', type: 'number'}, {id: 'ga:newVisits', label: 'new visits', type: 'number'}], rows: [{c:[{v: '10/14/2013'}, {v: 333}, {v: 266}]}, {c:[{v: '10/18/2013'}, {v: 161}, {v: 109}]}, {c:[{v: '10/24/2013'}, {v: 224}, {v: 163}]}]};
return Simple_JsonTable;
}
Thanks in advance
I am going to assume that your Simple_setData function is a stand-in for the code that grabs data from Google Analytics, and that your data fetching function returns data in the exact same format. If you don't want to modify the source, you can use a DataView to convert the date strings to Date objects like this:
var view = new google.visualization.DataView(Simple_data);
view.setColumns([{
type: 'date',
label: Simple_data.getColumnLabel(0),
calc: function (dt, row) {
var dateArray = dt.getValue(row, 0).split('/');
var year = parseInt(dateArray[2]);
var month = parseInt(dateArray[0]) - 1; // subtract 1 to convert to javascript's 0-indexed months
var day = parseInt(dateArray[1]);
return new Date(year, month, day);
}
}, 1, 2]);
Use the DataView when drawing the chart instead of the DataTable:
visualization.draw(view, Simple_options);