Using Google Visualization, why is DataView conten

2019-02-27 00:51发布

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:

LineChart not showing DataView content while ChartRangeFilter does

Thanks!

1条回答
Bombasti
2楼-- · 2019-02-27 01:40

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>

查看更多
登录 后发表回答