The code below should populate a DataView from a CSV file. The DataView is then fed to a DashBoard which inludes a LineChart and a ChartRangeFilter bound together. My problem is that while the ChartRangeFilter shows a proper chart preview and allows me to select the range the LineChart shows only an empty data set but with the right data type and axis labels. My assumption is that the DataView content is OK since the ChartRangeFilter is capable of showing it. Why then can't the LineChart do the same?
google.load('visualization', '1', {packages: ['controls', 'charteditor']});
google.setOnLoadCallback(drawChart);
function drawChart() {
// Create CSV string
csvString = 'TIME,TEMP0,HUM0\n13:00:04,24.7,50\n13:01:05,26.7,60\n13:02:04,22.7,52\n13:03:05,14.7,40\n13:04:04,34.7,80\n13:05:05,24.7,50';
// Parse string into an Array
var arrayData = $.csv.toArrays(csvString, {onParseValue: $.csv.hooks.castToScalar});
// Convert Array into a DataTable
var data = new google.visualization.arrayToDataTable(arrayData);
// Create DataView from DataTable
var view = new google.visualization.DataView(data);
// Convert string times in first column to timeofday (thanks to WhiteHat!)
var columns = [];
for (var i = 0; i < data.getNumberOfColumns(); i++) {
columns.push(i);
}
columns[0] = {
calc: function(dt, row) {
var thisDate = new Date('1/1/2016 ' + dt.getValue(row, 0));
return [thisDate.getHours(), thisDate.getMinutes(), thisDate.getSeconds(), thisDate.getMilliseconds()];
},
label: arrayData[0][0],
type: 'timeofday'
};
// Determine which columns should be visible
view.setColumns(columns);
// Create Dashboard
var dash = new google.visualization.Dashboard(document.getElementById('dashboard'));
// Range filter control wrapper
var control = new google.visualization.ControlWrapper({
controlType: 'ChartRangeFilter',
containerId: 'control_div',
options: {
filterColumnIndex: 0,
ui: {
chartOptions: {
height: 50,
width: 1000,
},
chartView: {
columns: [0, 1,2]
}
}
}
});
// Line chart wrapper
var chart = new google.visualization.ChartWrapper({
chartType: 'LineChart',
containerId: 'chart_div',
dataTable: view,
options:{
title: 'Home Automation - Environment Sensor Log',
width: 1000,
height: 400
}
});
// Bind control and chart in Dashboard
dash.bind([control], [chart]);
// Draw dashboard using Dataview as source
dash.draw(view);
}
This is the current end result:
Thanks!
tried a number of things to get the chart to work with 'timeofday'
, but no luck
however, using a 'date'
column, formatted as 'HH:mm:ss'
seems to work fine
see following working snippet.
changes include:
1) using loader.js
vs. jsapi
2) changed calc
function to return date formatted as time
3) added hAxis.ticks
to both chart
and control
4) used getColumnRange
to set the vAxis.viewWindow
on the chart
google.charts.load('current', {
callback: function () {
// Create CSV string
csvString = 'TIME,TEMP0,HUM0\n13:00:04,24.7,50\n13:01:05,26.7,60\n13:02:04,22.7,52\n13:03:05,14.7,40\n13:04:04,34.7,80\n13:05:05,24.7,50';
// Parse string into an Array
var arrayData = $.csv.toArrays(csvString, {onParseValue: $.csv.hooks.castToScalar});
// Convert Array into a DataTable
var data = new google.visualization.arrayToDataTable(arrayData);
// Create DataView from DataTable
var view = new google.visualization.DataView(data);
// Convert string times in first column to timeofday (thanks to WhiteHat!)
var columns = [];
for (var i = 0; i < data.getNumberOfColumns(); i++) {
columns.push(i);
}
var formatter = new google.visualization.DateFormat({pattern: 'HH:mm:ss'});
columns[0] = {
calc: function(dt, row) {
var dateValue = new Date('1/1/2016 ' + dt.getValue(row, 0));
return {
v: dateValue,
f: formatter.formatValue(dateValue)
};
},
label: arrayData[0][0],
type: 'date'
};
// Determine which columns should be visible
view.setColumns(columns);
var tickMarks = [];
for (var i = 0; i < view.getNumberOfRows(); i++) {
tickMarks.push(view.getValue(i, 0));
}
// Create Dashboard
var dash = new google.visualization.Dashboard(document.getElementById('dashboard'));
// Get column range min & max
var yRange1 = view.getColumnRange(1);
var yRange2 = view.getColumnRange(2);
var control = new google.visualization.ControlWrapper({
controlType: 'ChartRangeFilter',
containerId: 'control_div',
options: {
filterColumnIndex: 0,
ui: {
chartOptions: {
height: 50,
width: 1000,
hAxis: {
ticks: tickMarks,
format: 'HH:mm:ss'
}
}
}
}
});
// Line chart wrapper
var chart = new google.visualization.ChartWrapper({
chartType: 'LineChart',
containerId: 'chart_div',
options:{
pointSize: 8,
title: 'Home Automation - Environment Sensor Log',
width: 1000,
height: 400,
hAxis: {
ticks: tickMarks,
format: 'HH:mm:ss'
},
vAxis: {
viewWindow: {
min: Math.min(yRange1.min, yRange2.min),
max: Math.max(yRange1.max, yRange2.max)
}
}
}
});
// Bind control and chart in Dashboard
dash.bind(control, chart);
// Draw dashboard using Dataview as source
dash.draw(view);
},
packages: ['controls', 'corechart']
});
<script src="https://www.gstatic.com/charts/loader.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-csv/0.71/jquery.csv-0.71.min.js"></script>
<div id="dashboard">
<div id="chart_div"></div>
<div id="control_div"></div>
</div>
来源:https://stackoverflow.com/questions/38571802/using-google-visualization-why-is-dataview-content-showing-in-chartrangefilter