Визуализация Google - при сортировке таблицы событий сохранить конкретную строку в качестве первой видимой записи? - PullRequest
1 голос
/ 23 октября 2019

Когда пользователь щелкает заголовок для сортировки, я хочу, чтобы строка с пометкой «Общий итог» оставалась первой видимой строкой.

Я могу перехватить событие сортировки таблицы следующим образом:

google.visualization.events.addListener(table.getChart(), 'sort', function() {
      console.log('User clicked to sort.');
};

Но я не знаю, что делать, чтобы перенести итоговую строку обратно к первой записи.

Как мне этого добиться? Я ценю ваши подсказки.

Рабочий пример: (стартовый код)

google.charts.load('current', {
  'packages': ['corechart', 'table', 'gauge', 'controls', 'charteditor']
});

$(document).ready(function() {
  renderChart_onPageLoad();
});

function renderChart_onPageLoad() {
  google.charts.setOnLoadCallback(function() {
    drawDashboard();
  });
}

function drawDashboard() {

  var data = google.visualization.arrayToDataTable([
    ['Name', 'RoolNumber', 'Gender', 'Age', 'Donuts eaten'],
    ['Michael', 1, 'Male', 12, 5],
    ['Elisa', 2, 'Female', 20, 7],
    ['Robert', 3, 'Male', 7, 3],
    ['John', 4, 'Male', 54, 2],
    ['Jessica', 5, 'Female', 22, 6],
    ['Aaron', 6, 'Male', 3, 1],
    ['Margareth', 7, 'Female', 42, 8],
    ['Miranda', 8, 'Female', 33, 6]
  ]);

  var dashboard = new google.visualization.Dashboard(document.getElementById('dashboard'));

  var categoryPicker = new google.visualization.ControlWrapper({
    controlType: 'CategoryFilter',
    containerId: 'categoryPicker',
    options: {
      filterColumnLabel: 'Gender',
      ui: {
        labelStacking: 'vertical',
        allowTyping: false,
        allowMultiple: false
      }
    }
  });

  var proxyTable = new google.visualization.ChartWrapper({
    chartType: 'Table',
    containerId: 'proxyTable',
    options: {
      width: '500px'
    }
  });

  var table = new google.visualization.ChartWrapper({
    chartType: 'Table',
    containerId: 'table',
    options: {
      width: '500px'
    }
  });

  dashboard.bind([categoryPicker], [proxyTable]);
  dashboard.draw(data);

  google.visualization.events.addListener(dashboard, 'ready', function() {
    redrawChart();
  });

  function redrawChart() {

    var sourceData = proxyTable.getDataTable();
    var dataResults = sourceData.toDataTable().clone();

    var group = google.visualization.data.group(sourceData, [{
      // we need a key column to group on, but since we want all rows grouped into 1, 
      // then it needs a constant value
      column: 0,
      type: 'number',
      modifier: function() {
        return 1;
      }
    }], [{
      column: 1,
      id: 'SumRool',
      label: 'SumRool',
      type: 'number',
      aggregation: google.visualization.data.sum
    }, {
      column: 3,
      id: 'SumAge',
      label: 'SumAge',
      type: 'number',
      aggregation: google.visualization.data.sum
    }, {
      // get the average age
      column: 4,
      id: 'SumEaten',
      label: 'SumEaten',
      type: 'number',
      aggregation: google.visualization.data.sum
    }]);

    dataResults.insertRows(0, [
      ['Grand Total', group.getValue(0, 1), null, group.getValue(0, 2), group.getValue(0, 3)],
    ]);

    //Set dataTable
    table.setDataTable(dataResults);
    table.draw();

    // table sort event
    google.visualization.events.addListener(table.getChart(), 'sort', function() {
      console.log('User clicked header to sort.');

      //When a user clicks the header and resorts the table I want the row labeled "Grand Total" to stay as the first row visible.


    });
  }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<script src="https://www.gstatic.com/charts/loader.js"></script>

<div id="dashboard">
  <div id="categoryPicker"></div><br />
  <div id="proxyTable" style='display:none;'></div>
  <div id="table"></div><br /><br />
</div>

1 Ответ

0 голосов
/ 24 октября 2019

, чтобы выполнить, нам нужно будет вручную управлять порядком сортировки.

сначала установите параметр сортировки на графике таблицы.

var table = new google.visualization.ChartWrapper({
  chartType: 'Table',
  containerId: 'table',
  options: {
    sort: 'event',  // <-- set sort to 'event'
    width: '500px'
  }
});

далее нам нужно назначить прослушиватели событий до построения графика.
сначала мы должны дождаться готовности оболочки,
затем назначитьсобытие сортировки на диаграмму.
, но мы хотим сделать это только один раз, поэтому -> addOneTimeListener

google.visualization.events.addOneTimeListener(table, 'ready', function() {
  google.visualization.events.addListener(table.getChart(), 'sort', function(sender) {

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

// table sort event
google.visualization.events.addOneTimeListener(table, 'ready', function() {
  google.visualization.events.addListener(table.getChart(), 'sort', function(sender) {
    // sort data table according to sort properties
    var tableData = table.getDataTable();
    var sortIndexes = tableData.getSortedRows({column: sender.column, desc: !sender.ascending});

    // find grand total row
    var grandTotal = tableData.getFilteredRows([{
      column: 0,
      value: 'Grand Total'
    }]);
    if (grandTotal.length > 0) {
      // find grand total in sort
      var grandTotalSort = sortIndexes.indexOf(grandTotal[0]);

      // remove grand total from sort
      sortIndexes.splice(grandTotalSort, 1);

      // add grand total as first index
      sortIndexes.unshift(grandTotal[0]);

      // set table sort arrow
      table.setOption('sortAscending', sender.ascending);
      table.setOption('sortColumn', sender.column);

      // set table view
      table.setView({rows: sortIndexes});

      // re-draw table
      table.draw();
    }
  });
});

см. Следующий рабочий фрагмент ...

google.charts.load('current', {
  'packages': ['corechart', 'table', 'gauge', 'controls', 'charteditor']
});

$(document).ready(function() {
  renderChart_onPageLoad();
});

function renderChart_onPageLoad() {
  google.charts.setOnLoadCallback(function() {
    drawDashboard();
  });
}

function drawDashboard() {
  var data = google.visualization.arrayToDataTable([
    ['Name', 'RoolNumber', 'Gender', 'Age', 'Donuts eaten'],
    ['Michael', 1, 'Male', 12, 5],
    ['Elisa', 2, 'Female', 20, 7],
    ['Robert', 3, 'Male', 7, 3],
    ['John', 4, 'Male', 54, 2],
    ['Jessica', 5, 'Female', 22, 6],
    ['Aaron', 6, 'Male', 3, 1],
    ['Margareth', 7, 'Female', 42, 8],
    ['Miranda', 8, 'Female', 33, 6]
  ]);

  var dashboard = new google.visualization.Dashboard(document.getElementById('dashboard'));

  var categoryPicker = new google.visualization.ControlWrapper({
    controlType: 'CategoryFilter',
    containerId: 'categoryPicker',
    options: {
      filterColumnLabel: 'Gender',
      ui: {
        labelStacking: 'vertical',
        allowTyping: false,
        allowMultiple: false
      }
    }
  });

  var proxyTable = new google.visualization.ChartWrapper({
    chartType: 'Table',
    containerId: 'proxyTable',
    options: {
      width: '500px'
    }
  });

  var table = new google.visualization.ChartWrapper({
    chartType: 'Table',
    containerId: 'table',
    options: {
      sort: 'event',
      width: '500px'
    }
  });

  dashboard.bind([categoryPicker], [proxyTable]);
  dashboard.draw(data);

  google.visualization.events.addListener(dashboard, 'ready', function() {
    redrawChart();
  });

  function redrawChart() {
    var sourceData = proxyTable.getDataTable();
    var dataResults = sourceData.toDataTable().clone();

    var group = google.visualization.data.group(sourceData, [{
      // we need a key column to group on, but since we want all rows grouped into 1,
      // then it needs a constant value
      column: 0,
      type: 'number',
      modifier: function() {
        return 1;
      }
    }], [{
      column: 1,
      id: 'SumRool',
      label: 'SumRool',
      type: 'number',
      aggregation: google.visualization.data.sum
    }, {
      column: 3,
      id: 'SumAge',
      label: 'SumAge',
      type: 'number',
      aggregation: google.visualization.data.sum
    }, {
      // get the average age
      column: 4,
      id: 'SumEaten',
      label: 'SumEaten',
      type: 'number',
      aggregation: google.visualization.data.sum
    }]);

    dataResults.insertRows(0, [
      ['Grand Total', group.getValue(0, 1), null, group.getValue(0, 2), group.getValue(0, 3)],
    ]);

    // table sort event
    google.visualization.events.addOneTimeListener(table, 'ready', function() {
      google.visualization.events.addListener(table.getChart(), 'sort', function(sender) {
        // sort data table according to sort properties
        var tableData = table.getDataTable();
        var sortIndexes = tableData.getSortedRows({column: sender.column, desc: !sender.ascending});

        // find grand total row
        var grandTotal = tableData.getFilteredRows([{
          column: 0,
          value: 'Grand Total'
        }]);
        if (grandTotal.length > 0) {
          // find grand total in sort
          var grandTotalSort = sortIndexes.indexOf(grandTotal[0]);

          // remove grand total from sort
          sortIndexes.splice(grandTotalSort, 1);

          // add grand total as first index
          sortIndexes.unshift(grandTotal[0]);

          // set table sort arrow
          table.setOption('sortAscending', sender.ascending);
          table.setOption('sortColumn', sender.column);

          // set table view
          table.setView({rows: sortIndexes});

          // re-draw table
          table.draw();
        }
      });
    });

    //Set dataTable
    table.setDataTable(dataResults);
    table.draw();
  }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<script src="https://www.gstatic.com/charts/loader.js"></script>

<div id="dashboard">
  <div id="categoryPicker"></div><br />
  <div id="proxyTable" style='display:none;'></div>
  <div id="table"></div><br /><br />
</div>
...