我有一个看起来像这样的数据表:

+-------+---------+--------+
| 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的Google Visualization。

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

最佳答案

使用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>

09-11 15:43