📌 Steps to Achieve:
-
Store data in a list (with
category
,sub_category
,item
, andamount
). -
Group data by
category
andsub_category
. -
Calculate totals for each
sub_category
andcategory
. -
Compute the grand total.
-
Display everything in a table format.
📌 Expected Output:
Category | Sub-Category | Item | Amount |
---|---|---|---|
Fruits | Citrus | Orange | 10 |
Lemon | 5 | ||
Subtotal | 15 | ||
Berries | Strawberry | 8 | |
Blueberry | 12 | ||
Subtotal | 20 | ||
Total for Fruits | 35 | ||
Vegetables | Leafy | Spinach | 7 |
Lettuce | 6 | ||
Subtotal | 13 | ||
Root | Carrot | 9 | |
Potato | 11 | ||
Subtotal | 20 | ||
Total for Vegetables | 33 | ||
Grand Total | 68 |
🔹 Example Implementation
dartimport 'package:flutter/material.dart'; class GroupedTableScreen extends StatefulWidget { @override _GroupedTableScreenState createState() => _GroupedTableScreenState(); } class _GroupedTableScreenState extends State<GroupedTableScreen> { // Sample data: category, sub_category, item, amount final List<Map<String, dynamic>> items = [ {'category': 'Fruits', 'sub_category': 'Citrus', 'item': 'Orange', 'amount': 10}, {'category': 'Fruits', 'sub_category': 'Citrus', 'item': 'Lemon', 'amount': 5}, {'category': 'Fruits', 'sub_category': 'Berries', 'item': 'Strawberry', 'amount': 8}, {'category': 'Fruits', 'sub_category': 'Berries', 'item': 'Blueberry', 'amount': 12}, {'category': 'Vegetables', 'sub_category': 'Leafy', 'item': 'Spinach', 'amount': 7}, {'category': 'Vegetables', 'sub_category': 'Leafy', 'item': 'Lettuce', 'amount': 6}, {'category': 'Vegetables', 'sub_category': 'Root', 'item': 'Carrot', 'amount': 9}, {'category': 'Vegetables', 'sub_category': 'Root', 'item': 'Potato', 'amount': 11}, ]; // Method to group and calculate totals Map<String, Map<String, dynamic>> groupData() { Map<String, Map<String, dynamic>> groupedData = {}; for (var item in items) { String category = item['category']; String subCategory = item['sub_category']; int amount = item['amount']; // Initialize category if (!groupedData.containsKey(category)) { groupedData[category] = {'sub_categories': {}, 'total': 0}; } // Initialize sub-category if (!groupedData[category]!['sub_categories'].containsKey(subCategory)) { groupedData[category]!['sub_categories'][subCategory] = {'items': [], 'total': 0}; } // Add item to sub-category groupedData[category]!['sub_categories'][subCategory]['items'].add(item); groupedData[category]!['sub_categories'][subCategory]['total'] += amount; groupedData[category]!['total'] += amount; // Update category total } return groupedData; } @override Widget build(BuildContext context) { Map<String, Map<String, dynamic>> groupedData = groupData(); int grandTotal = groupedData.values.fold(0, (sum, cat) => sum + (cat['total'] as num).toInt()); return Scaffold( appBar: AppBar(title: Text('Grouped Data Table')), body: SingleChildScrollView( scrollDirection: Axis.horizontal, child: DataTable( columns: [ DataColumn(label: Text('Category')), DataColumn(label: Text('Sub-Category')), DataColumn(label: Text('Item')), DataColumn(label: Text('Amount')), ], rows: _buildRows(groupedData, grandTotal), ), ), ); } // Method to build rows dynamically List<DataRow> _buildRows(Map<String, Map<String, dynamic>> groupedData, int grandTotal) { List<DataRow> rows = []; groupedData.forEach((category, catData) { bool firstCategoryRow = true; catData['sub_categories'].forEach((subCategory, subData) { bool firstSubCategoryRow = true; for (var item in subData['items']) { rows.add(DataRow(cells: [ DataCell(firstCategoryRow ? Text(category, style: TextStyle(fontWeight: FontWeight.bold)) : Text('')), DataCell(firstSubCategoryRow ? Text(subCategory, style: TextStyle(fontWeight: FontWeight.w600)) : Text('')), DataCell(Text(item['item'])), DataCell(Text('${item['amount']}')), ])); firstCategoryRow = false; firstSubCategoryRow = false; } // Sub-category total row rows.add(DataRow(cells: [ DataCell(Text('')), DataCell(Text('Subtotal:', style: TextStyle(fontWeight: FontWeight.bold))), DataCell(Text('')), DataCell(Text('${subData['total']}', style: TextStyle(fontWeight: FontWeight.bold))), ])); }); // Category total row rows.add(DataRow(cells: [ DataCell(Text('Total for $category', style: TextStyle(fontWeight: FontWeight.bold))), DataCell(Text('')), DataCell(Text('')), DataCell(Text('${catData['total']}', style: TextStyle(fontWeight: FontWeight.bold))), ])); }); // Grand total row rows.add(DataRow(cells: [ DataCell(Text('Grand Total', style: TextStyle(fontWeight: FontWeight.bold, fontSize: 16))), DataCell(Text('')), DataCell(Text('')), DataCell(Text('$grandTotal', style: TextStyle(fontWeight: FontWeight.bold, fontSize: 16))), ])); return rows; } }