谷歌可视化仪表板配有筛选器和数据视图

3

我有一个类似下面这样的DataTable:

+-------+---------+--------+
| month |  name   | income |
+-------+---------+--------+
| Jan   | Alice   | $5,000 |
| Feb   | Alice   | $3,000 |
| Mar   | Alice   | $4,500 |
| Jan   | Bob     | $2,750 |
| Feb   | Bob     | $8,000 |
| Mar   | Bob     | $1,000 |
| Jan   | Charlie | $3,500 |
| Feb   | Charlie | $4,100 |
| Mar   | Charlie | $3,900 |
  ...       ...       ...

我希望使用一个ChartWrapper和一个ControlWrapper来展示谷歌可视化。

ChartWrapper将显示一个表格,但我只想显示最近一个月的数据。为此,我在ChartWrapper上使用了.setView()方法。

ControlWrapper将在名称列上包装一个CategoryFilter。

我遇到的问题是,当我尝试选择一个名称时,它会抛出一个错误:Invalid row index ... Should be in range [0-...]

我认为我遇到这个问题是因为setView接受一个静态的行数组来显示,但如果表格被过滤,则要显示的行将不同。我像下面这样调用setView

var recentRows = dataTable.getFilteredRows([
    {
        "column": 2,
        "minValue": dataTable.getColumnRange(2).max
    }
]);
chartWrapper.setView({
    "rows": recentRows
});
1个回答

3
使用Dashboard控件时,ChartWrapperControlWrapper需要保持同步并使用相同的数据集。
正如您所发现的那样,仅在图表上设置view属性会导致此问题。
为了纠正这个问题,使用DataView来绘制仪表板,如下面的工作示例所示...

google.charts.load('current', {
  callback: drawChart,
  packages: ['controls']
});

function drawChart() {
  var data = google.visualization.arrayToDataTable([
    ['month', 'name', 'income'],
    [0, 'Alice', 5000],
    [1, 'Alice', 3000],
    [2, 'Alice', 4500],
    [0, 'Bob', 2750],
    [1, 'Bob', 8000],
    [2, 'Bob', 1000],
    [0, 'Charlie', 3500],
    [1, 'Charlie', 4100],
    [2, 'Charlie', 3900]
  ]);

  var control = new google.visualization.ControlWrapper({
    controlType: 'CategoryFilter',
    containerId: 'control',
    options: {
      filterColumnLabel: 'name',
      ui: {
        allowTyping: false,
        allowMultiple: true
      }
    }
  });

  var chart = new google.visualization.ChartWrapper({
    chartType: 'Table',
    containerId: 'chart'
  });

  var view = new google.visualization.DataView(data);
  view.setRows(data.getFilteredRows([{
    column: 0,
    minValue: data.getColumnRange(0).max
  }]));

  var dashboard = new google.visualization.Dashboard(
    document.getElementById('dashboard')
  );
  dashboard.bind(control, chart);
  dashboard.draw(view);
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="control"></div>
<div id="chart"></div>


另一种选择是不使用仪表板
独立绘制每个包装器,
然后在控件上侦听statechange事件,
并相应地绘制表格

请参见以下工作片段...

google.charts.load('current', {
  callback: drawChart,
  packages: ['controls']
});

function drawChart() {
  var data = google.visualization.arrayToDataTable([
    ['month', 'name', 'income'],
    [0, 'Alice', 5000],
    [1, 'Alice', 3000],
    [2, 'Alice', 4500],
    [0, 'Bob', 2750],
    [1, 'Bob', 8000],
    [2, 'Bob', 1000],
    [0, 'Charlie', 3500],
    [1, 'Charlie', 4100],
    [2, 'Charlie', 3900]
  ]);

  var control = new google.visualization.ControlWrapper({
    controlType: 'CategoryFilter',
    containerId: 'control',
    dataTable: data,
    options: {
      filterColumnLabel: 'name',
      ui: {
        allowTyping: false,
        allowMultiple: true
      }
    }
  });
  control.draw();

  var chart = new google.visualization.ChartWrapper({
    chartType: 'Table',
    containerId: 'chart',
    dataTable: data
  });

  google.visualization.events.addListener(control, 'ready', drawTable);
  google.visualization.events.addListener(control, 'statechange', drawTable);
  drawTable();

  function drawTable() {
    var filters = [{
      column: 0,
      minValue: data.getColumnRange(0).max
    }];

    var selectedNames = control.getState().selectedValues;
    if (selectedNames.length > 0) {
      filters.push({
        column: 1,
        test: function (value, row, column, table) {
          return (selectedNames.indexOf(table.getValue(row, column)) > -1);
        }
      });
    }

    chart.setView({
      rows: data.getFilteredRows(filters)
    });
    chart.draw();
  }
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="control"></div>
<div id="chart"></div>


不幸的是,这解决了一个问题,但又引发了另一个问题,但我想我会找到另一个问题的新解决方案 :) 我之所以有其他月份,是因为在仪表板的其他地方,我显示了历史值的折线图。在过滤给定名称(仅在“当前”收入的表中显示单个行)时,我希望该折线图被过滤以显示该名称的历史值。因此,实际上,该表需要显示由过滤器创建的视图的子视图。 - stevendesu
使用仪表板来处理除表格以外的所有内容,然后使用上面的第二个选项来绘制表格... - WhiteHat

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接