1

下面的代码应该从CSV文件填充DataView。然后将DataView提供给包含在一起的LineChart和ChartRangeFilter的DashBoard。我的问题是,虽然ChartRangeFilter显示一个适当的图表预览,并允许我选择范围LineChart只显示一个空的数据集,但具有正确的数据类型和轴标签。我的假设是DataView内容是OK的,因为ChartRangeFilter能够显示它。为什么LineChart不能这样做?使用Google Visualization,为什么DataView内容在ChartRangeFilter中显示,但不在其关联的LineChart中显示?

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); 
} 

这是当前的最终结果是:

LineChart not showing DataView content while ChartRangeFilter does

谢谢!

回答

1

尝试了一些事情让图表与'timeofday'工作,但没有运气

然而,使用'date'列,格式为'HH:mm:ss'似乎做工精细

看到下面的工作片段。

变化包括:

1)使用

loader.jsjsapi
2)改变 calc函数返回日期格式为时间
3)加入 hAxis.ticks两者 chartcontrol
4)用于 getColumnRange设置 vAxis.viewWindow上的 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>

+0

对不起,延迟!是的,它可以工作,但是当我使用从更大(1400 +行x 30列)的CSV文件导入的实际数据集时,重绘非常慢。我将不得不执行一些测试来查看造成这种情况的原因。我怀疑getColumnRange设置vAxis.viewWindow或每次移动范围过滤器轨迹条时重绘的大量刻度。 此外,我再也不能使用'view.setColumns([0,1,5,9,13,17,21,25,29]);''象我以前那样设置想要查看的列。当我这样做时,我得到了“过滤器不能在字符串类型的列上操作”错误消息... – tohox

+0

我在想这就是为什么上面的答案使用计算列代替'0' - 至于速度慢,这就是客户端处理的本质,更多的数据需要更多的时间...... – WhiteHat

+0

通过删除'vAxis''viewWindow'调整大小和关联'view.getColumnRange',能够大幅加速事物。我也摆脱了线图中的要点,因为它们的密度太高,掩盖了其余的一切。现在我只需要找到一种方法来选择我想要从原始CSV数据集中看到哪些列。谢谢WhiteHat! – tohox

相关问题