Google可视化仪表板-过滤后如何获取新数据集

最后发布: 2014-04-22 13:45:04


问题

我正在创建一个Google可视化仪表板,其中包含多个过滤器,滑块,表格和柱形图。 该表在状态列(列0)中有重复的行,因此我有一个视图计算逻辑来获取每个状态的计数。 所有这些都很好。 为了隐藏不想看到的行(基本上是重复的),我使用了view.rows并传入了我想显示的行号数组。

当我第一次加载HTML时,一切正常。 如果我使用“订单”优先级滑块(rangeSlider)并将最大值从5滑到4,我的表将相应更改,现在我只有5行数据,而不是6行。此时,view.rows仍在查找在最初的6行中,我收到一条错误消息:“无效的行索引5。应在[0-4]范围内”。

如果我没有view.rows数组,它可以正常工作,但我的柱形图也显示所有重复的行。

任何帮助将不胜感激! 谢谢!!

这是我的代码:

<html><head>
<script type='text/javascript' src='https://www.google.com/jsapi'></script>
<script type='text/javascript'>

google.load('visualization', '1.1', {'packages':['controls']});

var rows = 0;
function drawDashboard() {

var data = google.visualization.arrayToDataTable([
    ['Status','Priority','Order No.','Description','Func. Loc.','Type','Start Dt','Fin Date'],
    ['RSCH',2,500400,'Hard disk problem (SAP01)','1171-ADMI-0001 ','SM01',new Date(2005, 0, 1),new Date(2009, 0, 2)],
    ['INIT',1,501300,'','','SM02',new Date(2007, 0, 1),new Date(2009, 11, 2)],
    ['RSCH',1,500400,'Hard disk problem (SAP01)','1171-ADMI-0001 ','SM01',new Date(2005, 0, 1),new Date(2009, 0, 2)],
    ['INIT',2,501300,'','','SM02',new Date(2007, 0, 1),new Date(2009, 11, 2)],
    ['RSCH',5,500400,'Hard disk problem (SAP01)','1171-ADMI-0001 ','SM01',new Date(2005, 0, 1),new Date(2009, 0, 2)],
    ['RDSP',4,501300,'','','SM02',new Date(2007, 0, 1),new Date(2009, 11, 2)]
]);


// Create a dashboard.
 dashboard = new google.visualization.Dashboard(
 document.getElementById('dashboard_div'));
// Create a range slider, passing some options
 var rangeSlider = new google.visualization.ControlWrapper({
    'controlType': 'NumberRangeFilter','containerId': 'slider_div',
    'options': {'filterColumnLabel': 'Priority','ui': {'label':'Order Priority Level:'}}});
// Create a range slider, passing some options
 var dateRangeSlider = new google.visualization.ControlWrapper({
    'controlType': 'DateRangeFilter','containerId': 'dateSlider_div',
    'options': {'filterColumnLabel':'Start Dt','ui': {'label':'Start Date :'}}});
// Create a range slider, passing some options
 var dateRangeSliderFin = new google.visualization.ControlWrapper({
    'controlType': 'DateRangeFilter','containerId': 'dateSliderFin_div',
    'options': {'filterColumnLabel':'Fin Date','ui': {'label':'Finish Date:'}}});
// Define category filters
var FlocFilter = new google.visualization.ControlWrapper({
     'controlType': 'CategoryFilter', 'containerId': 'FLfilter_div',
     'options': {'filterColumnLabel': 'Func. Loc.','ui': { 'labelStacking': 'vertical','allowTyping': false,'allowMultiple': false}}});
var StatFilter = new google.visualization.ControlWrapper({
     'controlType': 'CategoryFilter', 'containerId': 'Statfilter_div',
     'options': {'filterColumnLabel': 'Status','ui': { 'labelStacking': 'vertical','allowTyping': true,'allowMultiple': true}}});
var TypeFilter = new google.visualization.ControlWrapper({
     'controlType': 'CategoryFilter', 'containerId': 'Typefilter_div',
     'options': {'filterColumnLabel': 'Type','ui': { 'labelStacking': 'vertical','allowTyping': true,'allowMultiple': true}}});


// Define a table
var table = new google.visualization.ChartWrapper({
    chartType: 'Table',
    dataTable:data,
    containerId: 'table_div',
    options: {'width': '800px'}
});

    rows = data.getNumberOfRows();
    distinct_values = data.getDistinctValues(0);

    arRows = [];
    for (var ii=0; ii<distinct_values.length; ii++){
        for (var jj=0; jj<rows; jj++){
            var curr_stat = data.getValue(jj,0);
            if (curr_stat == distinct_values[ii]){
                arRows.push(jj);
                break;
            }
        }
    }

// Draw a column chart
var columnChart = new google.visualization.ChartWrapper({
    chartType: 'ColumnChart',
    options: {'title': 'Status vs. Order Count'},
    containerId: 'columnChart_div',
    view: {'columns': [0,{calc:testfunc, type:'number', label:'Count..'}],'rows':arRows}
});



function testfunc(dataTable, rowNum){   
    var curr_stat = dataTable.getValue(rowNum,0);
    var distinct_values = dataTable.getDistinctValues(0);
    var count = 0;

    for (var ii=0; ii<dataTable.getNumberOfRows(); ii++){
        stat = dataTable.getValue(ii,0);
        if (stat == curr_stat){
            count++;
        }
    }
    return count;
}




// Establish dependencies
dashboard.bind(rangeSlider,dateRangeSlider);
dashboard.bind(rangeSlider,dateRangeSliderFin);
dashboard.bind(rangeSlider,FlocFilter);
dashboard.bind(rangeSlider,StatFilter);
dashboard.bind(rangeSlider,TypeFilter);

dashboard.bind(dateRangeSlider,dateRangeSliderFin);
dashboard.bind(dateRangeSlider,FlocFilter);
dashboard.bind(dateRangeSlider,StatFilter);
dashboard.bind(dateRangeSlider,TypeFilter);

dashboard.bind(dateRangeSliderFin,FlocFilter);
dashboard.bind(dateRangeSliderFin,StatFilter);
dashboard.bind(dateRangeSliderFin,TypeFilter);

dashboard.bind(FlocFilter,StatFilter);
dashboard.bind(FlocFilter,TypeFilter);

dashboard.bind(StatFilter,TypeFilter);

dashboard.bind([rangeSlider,dateRangeSlider,dateRangeSliderFin,FlocFilter,StatFilter,TypeFilter],[table,columnChart]);

// Draw the dashboard.  
dashboard.draw(data);

}

google.setOnLoadCallback(drawDashboard);

</script></head>
<body style='font-family: Arial;border: 0 none;'>
<div id='dashboard_div'>
<h3>PM Work Orders</h3>
<table>
     <tr style='vertical-align: top'>
        <td style='width: 600px; font-size: 0.8em;'>
            <div id='slider_div' style='width:500px;'></div></br></br>
            <div id='dateSlider_div' style='width:500px;'></div></br></br>
            <div id='dateSliderFin_div' style='width:500px;'></div></br></br></br>
            <div id='columnChart_div' style='width:500px;'></div></br></br>
        </td>   
        <td style='width: 300px; font-size: 0.8em;'>
            <div id='FLfilter_div' style='width:300px;'></div></br>
            <div id='Statfilter_div' style='width:300px;'></div></br>
            <div id='Typefilter_div' style='width:300px;'></div></br>
        </td>
        <td style='width: 1500px'>
             <div id='table_div'></div>

         </td>
    </tr>
 </table>
</div>
</body>

google-visualization dashboard google-chartwrapper
回答

我认为您可以通过链接它们来极大地简化控件,这也将使其余部分变得更加容易。 使用以下命令替换您的dashboard.bind调用:

dashboard.bind([rangeSlider], [dateRangeSlider]);
dashboard.bind([dateRangeSlider], [dateRangeSliderFin]);
dashboard.bind([dateRangeSliderFin], [FlocFilter]);
dashboard.bind([FlocFilter], [StatFilter]);
dashboard.bind([StatFilter], [TypeFilter]);
dashboard.bind([TypeFilter], [table, columnChart]);

然后将计算arRows的代码移至一个函数(进行一些小的修改):

function setChartRows () {
    var dt = columnChart.getDataTable();
    var rows = dt.getNumberOfRows();
    var distinct_values = dt.getDistinctValues(0);

    var arRows = [];
    for (var ii=0; ii<distinct_values.length; ii++){
        for (var jj=0; jj<rows; jj++){
            var curr_stat = dt.getValue(jj,0);
            if (curr_stat == distinct_values[ii]){
                arRows.push(jj);
                break;
            }
        }
    }
    var view = columnChart.getView();
    view.rows = arRows;
    columnChart.setView(view);
    columnChart.draw();
}

然后为表的'ready'事件设置事件处理程序

google.visualization.events.addListener(table, 'ready', setChartRows);

每次更新表时,图表都会重新计算其行,并使用新的行集进行重绘。

工作示例: http : //jsfiddle.net/asgallant/bLQ2D/