Панель визуализации Google с фильтром и DataView

1

У меня есть 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 |
  ...       ...       ...

Я хочу отобразить Google Visualization с одним ChartWrapper и одним ControlWrapper.

ChartWrapper отобразит таблицу, но я хочу, чтобы эта таблица показывала последний месяц. Для этого я использую .setView() в ChartWrapper.

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
});
Теги:
charts
dashboard
google-visualization

1 ответ

1
Лучший ответ

при использовании Dashboard управления Dashboard,
ChartWrapper и ControlWrapper должны быть синхронизированы и используют один и тот же набор данных,

как вы нашли, установив свойство 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>
  • 0
    К сожалению, это решает одну проблему, но создает другую, но я думаю, что я найду новое решение другой проблемы :) Причина, по которой у меня в первую очередь другие месяцы, заключается в том, что в другом месте на панели инструментов я показываю линейный график исторического ценности. После фильтрации по заданному имени (который показывает только одну строку в таблице для «текущего» дохода), я хочу, чтобы линейный график также был отфильтрован, чтобы показать исторические значения для этого имени. Таким образом, таблица должна показывать подпредставление представления, созданного фильтром.
  • 0
    используйте панель инструментов для всего, кроме таблицы, затем используйте второй вариант выше, чтобы нарисовать таблицу ...

Ещё вопросы

Сообщество Overcoder
Наверх
Меню