Сортировка PaginatedDataTable с динамическими данными в строках и столбцах - PullRequest
0 голосов
/ 02 ноября 2019

Я использую PaginatedDataTable, чтобы показать мои данные. Данные поступают из JSON. Я могу показать данные и использовать нумерацию страниц. Но сортировка не работает в моем коде.

Я использую этот код в качестве ссылки. Сортировка отлично работает в ссылке. но в этом коде только строки являются динамическими.

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

Это мой DataGrid, гдеЯ определяю PaginatedDataTable:

import 'dart:async';

import 'package:boshloo/Dashboard/ChartInfo.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';

class Result {
  List<DataCell> cells;
  List<DataColumn> columns;

  Result({this.cells, this.columns});

  bool selected = false;
}

class ResultsDataSource extends DataTableSource {
  final List<Result> _results;
  ResultsDataSource(this._results);

  void _sort<T>(Comparable<T> getField(Result d), bool ascending) {
    _results.sort((Result a, Result b) {
      if (!ascending) {
        final Result c = a;
        a = b;
        b = c;
      }
      final Comparable<T> aValue = getField(a);
      final Comparable<T> bValue = getField(b);
      return Comparable.compare(aValue, bValue);
    });
    notifyListeners();
  }

  int _selectedCount = 0;

  @override
  DataRow getRow(int index) {
    assert(index >= 0);
    if (index >= _results.length) return null;
    final Result result = _results[index];
    return DataRow.byIndex(
        index: index,
        selected: result.selected,
        onSelectChanged: (bool value) {
          if (result.selected != value) {
            _selectedCount += value ? 1 : -1;
            assert(_selectedCount >= 0);
            result.selected = value;
            notifyListeners();
          }
        },
        cells: result.cells);
  }

  @override
  int get rowCount => _results.length;

  @override
  bool get isRowCountApproximate => false;

  @override
  int get selectedRowCount => _selectedCount;

  void _selectAll(bool checked) {
    for (Result result in _results) result.selected = checked;
    _selectedCount = checked ? _results.length : 0;
    notifyListeners();
  }
}

class DataGrid extends StatefulWidget {
  final ChartInfo chartsInfo;
  ResultsDataSource _resultsDataSource = ResultsDataSource([]);
  bool isLoaded = false;

  DataGrid({Key key, this.chartsInfo}) : super(key: key);

  @override
  _DataGridState createState() => _DataGridState();
}

class _DataGridState extends State<DataGrid> {
  ResultsDataSource _resultsDataSource = ResultsDataSource([]);
  bool isLoaded = false;
  int _rowsPerPage = 10;
  int _sortColumnIndex;
  bool _sortAscending = true;

  void _sort<T>(
      Comparable<T> getField(Result d), int columnIndex, bool ascending) {
    _resultsDataSource._sort<T>(getField, ascending);
    setState(() {
      _sortColumnIndex = columnIndex;
      _sortAscending = ascending;
    });
  }

  Future<void> getData() async {
    List<Result> results = List();
    for (var i = 0; i < dataRows.length; i++) {
      results.add(Result(
        cells: dataRows[i].cells,
      ));
    }
    if (!isLoaded) {
      setState(() {
        _resultsDataSource = ResultsDataSource(results);
        isLoaded = true;
      });
    }
  }

  List<DataColumn> dataColumns = List();
  List<DataRow> dataRows = List();
  void _setDataColumnsRows() {
    //print('widget.chartsInfo.gridData = ' + widget.chartsInfo.gridData[0].values.toList()[0].toString());
    for (var i = 0; i < widget.chartsInfo.gridFields.length; i++) {
      dataColumns.add(
        DataColumn(
          label: Text(widget.chartsInfo.gridFields.keys.toList()[i]),
          //numeric: false,
          onSort: (int columnIndex, bool ascending) {
            _sort<String>((Result d) {

              return widget.chartsInfo.gridFields.keys.toList()[i];
            }, columnIndex, ascending);
          },
        ),
      );
    }
    //print('DataCoumns length = ' + dataColumns.length.toString());

    for (var i = 0; i < widget.chartsInfo.gridData.length; i++) {
      List<DataCell> cells = List();
      //print('DataRow[ ');
      for (var j = 0; j < widget.chartsInfo.gridData[i].length; j++) {
        //print('Cell $j = ' + widget.chartsInfo.gridData[i].values.toList()[j].toString());
        cells.add(DataCell(
            Text(widget.chartsInfo.gridData[i].values.toList()[j].toString())));
      }
      //print('cells length = ' + cells.length.toString());
      dataRows.add(DataRow(cells: cells));
      //print(' ]');
    }
  }

  @override
  void initState() {
    super.initState();
    _setDataColumnsRows();
    getData();
  }

  @override
  Widget build(BuildContext context) {
    return SingleChildScrollView(
      scrollDirection: Axis.horizontal,
      child: Container(
        width: MediaQuery.of(context).size.width,
        child: PaginatedDataTable(
            header: Text(widget.chartsInfo.title),
            rowsPerPage: _rowsPerPage,
            onRowsPerPageChanged: (int value) {
              setState(() {
                _rowsPerPage = value;
              });
            },
            sortColumnIndex: _sortColumnIndex,
            sortAscending: _sortAscending,
            onSelectAll: _resultsDataSource._selectAll,
            columns: dataColumns,
            source: _resultsDataSource),
      ),
    );
  }
}

И это панель инструментов, где я получаю json и показываю DataGrid:

import 'dart:convert';

import 'package:boshloo/Dashboard/ChartInfo.dart';
import 'package:flutter/material.dart';

import 'BarChart.dart';
import 'DataGrid.dart';
import 'GaugeChart.dart';
import 'LineChart.dart';
import 'PieChart.dart';
import 'package:http/http.dart' as http;

class Dashboard extends StatefulWidget {
  @override
  _DashboardState createState() => _DashboardState();
}

class _DashboardState extends State<Dashboard> {
  List<ChartInfo> charts = List();
  bool isLoaded = false;
  @override
  void initState() {
    super.initState();
    _getCharts().then((ch) {
      setState(() {
        charts = ch;
        isLoaded = true;
      });
    });
  }

  Future<List<ChartInfo>> _getCharts() async {
    List<ChartInfo> charts = List();
    String url =
        'http://ls.arian.co.ir:8081/api/1.0/arian/mobiledashboard/dashlet-list/71';
    //print('body = ' + body);

    http.Response response = http.Response('{}', 200);
    response = await http.get(url);
    //print('respons body = ' + response.body);
    try {} catch (e) {
      print('failed' + e.toString());
      return null;
    }

    List<dynamic> json = jsonDecode(response.body);
    for (var i = 0; i < json.length; i++) {
      //print('json[i]["domain-title"] = ' + json[i]['domain-title'][0]);
      ChartInfo chart;
      if (json[i]['title'] == 'تست گرید ') {
        chart = ChartInfo(
          title: json[i]['title'],
          type: 'grid',
          domainTitle: json[i]['domain-title'],
          measureTitle: json[i]['measure-title'],
          measures: json[i]['measure'],
          gridFields: json[i]['fields'],
          gridData: json[i]['data'],
        );
      } else {
        chart = ChartInfo(
          title: json[i]['title'],
          type: json[i]['type'],
          domainTitle: json[i]['domain-title'],
          measureTitle: json[i]['measure-title'],
          measures: json[i]['measure'],
        );
      }
      //print('title' + chart.title);
      //print('chart measure = ' + chart.measures.values.toList()[0].toString());

      charts.add(chart);

      //print('measures ' + chart.measures[0][1].toString());
    }
    return charts;
  }

  @override
  Widget build(BuildContext context) {
    List<Widget> _getChartsWidget() {
      List<Widget> chartList = List();
      for (var i = 0; i < charts.length; i++) {
        if (charts[i].type == 'bar' || charts[i].type == 'column') {
          //chartList.add(BarChart(chartsInfo: charts[i]));
        } else if (charts[i].type == 'pie') {
          //chartList.add(PieChart(chartsInfo: charts[i],));
        } else if (charts[i].type == 'line') {
          //chartList.add(LineChart(chartsInfo: charts[i]));
        } else if (charts[i].type == 'grid'){
          chartList.add(DataGrid(chartsInfo: charts[i]));
        }
      }
      chartList.add(GaugeChart());
      return chartList;
    }

    return Scaffold(
      body: isLoaded
          ? Container(
              child: ListView(
                children: _getChartsWidget(),
              ),
            )
          : Container(),
    );
  }
}

И Json Link , (Третий вмассив (индекс # 2) - это данные, которые должны быть показаны в таблице.

«поля» (только ключ, значение не используется) - это мои столбцы, а «данные» - мои строки

(Я не думаю, что вам понадобится файл json, который я включил, хотя).

Любая помощь будет оценена.

...