Using Google Visualization, why is DataView content showing in ChartRangeFilter but not in its associated LineChart?

泪湿孤枕 提交于 2019-12-02 04:28:44

问题


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!


回答1:


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!