Drilldown in Flutter Treemap (SfTreemap)
18 Nov 201824 minutes to read
The drilldown feature provides better visualization of a larger set of hierarchical-level data.
To learn more about the drilldown feature in Flutter Treemap, you can watch this video.
Enable drilldown
You can drill down the tiles by setting the enableDrilldown property to true. In the UI, you can only see one level tiles at a time. When you tap a tile, it expands to the size of the viewport and loads its descendant tiles with smoother animation.
The widget returned by the TreemapBreadcrumbs.builder will be added to the breadcrumbs item. While drilling down the tiles, it is called with the tapped tile details.
Selection for touch and mouse-enabled devices, and tooltip for touch devices, will work only for the tiles that don’t have descendants.
import 'package:flutter/material.dart';
import 'package:syncfusion_flutter_treemap/treemap.dart';
class TreemapDrilldownExample extends StatefulWidget {
const TreemapDrilldownExample({super.key});
@override
State<TreemapDrilldownExample> createState() =>
_TreemapDrilldownExampleState();
}
class _TreemapDrilldownExampleState extends State<TreemapDrilldownExample> {
late List<CarSale> _source;
late Map<String, Color> _colors;
@override
void initState() {
_source = <CarSale>[
const CarSale(carName: 'Hyundai', model: 'Elantra', totalScale: 198210),
const CarSale(carName: 'Hyundai', model: 'Sonata', totalScale: 131803),
const CarSale(carName: 'Hyundai', model: 'Tucson', totalScale: 114735),
const CarSale(carName: 'Hyundai', model: 'Santa Fe', totalScale: 133171),
const CarSale(carName: 'Hyundai', model: 'Accent', totalScale: 58955),
const CarSale(carName: 'Hyundai', model: 'Veloster', totalScale: 12658),
const CarSale(carName: 'Hyundai', model: 'loniq', totalScale: 11197),
const CarSale(carName: 'Hyundai', model: 'Azera', totalScale: 3060),
const CarSale(carName: 'Benz', model: 'C-Class', totalScale: 77447),
const CarSale(carName: 'Benz', model: 'GLE-Class', totalScale: 54595),
const CarSale(carName: 'Benz', model: 'E/CLS-Class', totalScale: 51312),
const CarSale(carName: 'Benz', model: 'GLC-Class', totalScale: 48643),
const CarSale(carName: 'Benz', model: 'GLS-Class', totalScale: 322548),
const CarSale(carName: 'Benz', model: 'Sprinter', totalScale: 27415),
const CarSale(carName: 'Benz', model: 'CLA-Class', totalScale: 20669),
const CarSale(carName: 'Benz', model: 'GLA-Class', totalScale: 24104),
const CarSale(carName: 'Benz', model: 'S-Class', totalScale: 15888),
const CarSale(carName: 'Benz', model: 'Metris', totalScale: 7579),
const CarSale(carName: 'BMW', model: '3-Series', totalScale: 59449),
const CarSale(carName: 'BMW', model: 'X5', totalScale: 50815),
const CarSale(carName: 'BMW', model: 'X3', totalScale: 40691),
const CarSale(carName: 'BMW', model: '5-Series', totalScale: 40658),
const CarSale(carName: 'BMW', model: '4-Series', totalScale: 39634),
const CarSale(carName: 'BMW', model: '2-Series', totalScale: 11737),
const CarSale(carName: 'BMW', model: '7-Series', totalScale: 9276),
const CarSale(carName: 'BMW', model: 'X1', totalScale: 30826),
const CarSale(carName: 'BMW', model: 'X6', totalScale: 6780),
const CarSale(carName: 'BMW', model: 'X4', totalScale: 5198),
const CarSale(carName: 'BMW', model: '6-Series', totalScale: 3355),
const CarSale(carName: 'Jeep', model: 'Grand Cherokee', totalScale: 240696),
const CarSale(carName: 'Jeep', model: 'Cherokee', totalScale: 169822),
const CarSale(carName: 'Jeep', model: 'Renegade', totalScale: 103434),
const CarSale(carName: 'Jeep', model: 'Wrangler', totalScale: 190522),
const CarSale(carName: 'Jeep', model: 'Compass', totalScale: 83523),
const CarSale(carName: 'Jeep', model: 'Patriot', totalScale: 10735),
const CarSale(carName: 'Nissan', model: 'Rogue', totalScale: 403465),
const CarSale(carName: 'Nissan', model: 'Sentra', totalScale: 218451),
const CarSale(carName: 'Nissan', model: 'Murano', totalScale: 76732),
const CarSale(carName: 'Nissan', model: 'Frontier', totalScale: 74360),
const CarSale(carName: 'Nissan', model: 'Altima', totalScale: 254996),
const CarSale(carName: 'Nissan', model: 'Versa', totalScale: 106772),
const CarSale(carName: 'Nissan', model: 'Pathfinder', totalScale: 81065),
const CarSale(carName: 'Nissan', model: 'Maxima', totalScale: 67627),
const CarSale(carName: 'Nissan', model: 'Titan', totalScale: 52924),
const CarSale(carName: 'Nissan', model: 'Armada', totalScale: 35667),
const CarSale(carName: 'Nissan', model: 'NV', totalScale: 17858),
const CarSale(carName: 'Nissan', model: 'NV200', totalScale: 18602),
const CarSale(carName: 'Nissan', model: 'Duke', totalScale: 10157),
const CarSale(carName: 'Honda', model: 'Rogue', totalScale: 403465),
const CarSale(carName: 'Honda', model: 'Sentra', totalScale: 218451),
const CarSale(carName: 'Honda', model: 'Murano', totalScale: 76732),
const CarSale(carName: 'Honda', model: 'Frontier', totalScale: 74360),
const CarSale(carName: 'Honda', model: 'Altima', totalScale: 254996),
const CarSale(carName: 'Honda', model: 'Versa', totalScale: 106772),
const CarSale(carName: 'Honda', model: 'Maxima', totalScale: 67627),
const CarSale(carName: 'Honda', model: 'Titan', totalScale: 52924),
const CarSale(carName: 'Honda', model: 'Armada', totalScale: 35667),
const CarSale(carName: 'Honda', model: 'NV', totalScale: 17858),
const CarSale(carName: 'Honda', model: 'NV200', totalScale: 18602),
const CarSale(carName: 'Honda', model: 'Duke', totalScale: 10157),
const CarSale(carName: 'Ford', model: 'F-Series', totalScale: 896764),
const CarSale(carName: 'Ford', model: 'Explorer', totalScale: 271134),
const CarSale(carName: 'Ford', model: 'Fusion', totalScale: 209623),
const CarSale(carName: 'Ford', model: 'Focus', totalScale: 158385),
const CarSale(carName: 'Ford', model: 'Edge', totalScale: 142603),
const CarSale(carName: 'Ford', model: 'Transit', totalScale: 127340),
const CarSale(carName: 'Ford', model: 'Mustang', totalScale: 81866),
const CarSale(carName: 'Ford', model: 'Escape', totalScale: 308286),
const CarSale(carName: 'Ford', model: 'E-Series', totalScale: 53304),
const CarSale(carName: 'Ford', model: 'Expedition', totalScale: 51833),
const CarSale(carName: 'Ford', model: 'Fiesta', totalScale: 46249),
const CarSale(carName: 'Ford', model: 'Taurus', totalScale: 41326),
const CarSale(carName: 'Ford', model: 'Flex', totalScale: 22389),
const CarSale(carName: 'Ford', model: 'Transit Connect', totalScale: 34473),
];
_colors = <String, Color>{
'Hyundai': const Color.fromRGBO(220, 103, 171, 1.0),
'BMW': const Color.fromRGBO(160, 220, 103, 1.0),
'Benz': const Color.fromRGBO(220, 210, 103, 1.0),
'Nissan': const Color.fromRGBO(163, 103, 220, 1.0),
'Jeep': const Color.fromRGBO(220, 105, 103, 1.0),
'Ford': const Color.fromRGBO(103, 183, 220, 1.0),
'Honda': const Color.fromRGBO(103, 220, 187, 1.0),
};
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Container(
height: 400,
width: 400,
child: SfTreemap(
dataCount: _source.length,
weightValueMapper: (int index) {
return _source[index].totalScale!;
},
enableDrilldown: true,
breadcrumbs: TreemapBreadcrumbs(
builder: (BuildContext context, TreemapTile tile, bool isCurrent) {
return Text(tile.group, style: const TextStyle(color: Colors.black));
},
),
levels: [
TreemapLevel(
groupMapper: (int index) => _source[index].carName,
labelBuilder: (BuildContext context, TreemapTile tile) {
return Padding(
padding: const EdgeInsets.only(left: 5.0, top: 5.0),
child: Text(
tile.group,
style: const TextStyle(color: Colors.black),
overflow: TextOverflow.ellipsis,
),
);
},
colorValueMapper: (TreemapTile tile) {
return _colors[_source[tile.indices[0]].carName];
},
),
TreemapLevel(
groupMapper: (int index) {
return _source[index].model;
},
colorValueMapper: (TreemapTile tile) {
return _colors[_source[tile.indices[0]].carName];
},
labelBuilder: (BuildContext context, TreemapTile tile) {
return Padding(
padding: const EdgeInsets.only(left: 5.0, top: 5.0),
child: Text(
tile.group,
style: const TextStyle(color: Colors.black),
overflow: TextOverflow.ellipsis,
),
);
},
),
],
),
),
),
);
}
}
class CarSale {
const CarSale({
required this.carName,
this.model,
this.version,
this.versionNumber,
this.totalScale,
});
final String carName;
final String? model;
final String? version;
final String? versionNumber;
final double? totalScale;
}
Breadcrumb customization
The breadcrumb is used to display information about the drilled item and provides an option to navigate back to the previous level. You can customize the breadcrumb items using the following properties:
-
Position - Positions the breadcrumbs either at the top or bottom of the Flutter Treemap. The default value of the
positionisTreemapBreadcrumbPosition.top. - Divider - Used to add a separator between two breadcrumbs.
import 'package:flutter/material.dart';
import 'package:syncfusion_flutter_treemap/treemap.dart';
class TreemapBreadcrumbCustomizationExample extends StatefulWidget {
const TreemapBreadcrumbCustomizationExample({super.key});
@override
State<TreemapBreadcrumbCustomizationExample> createState() =>
_TreemapBreadcrumbCustomizationExampleState();
}
class _TreemapBreadcrumbCustomizationExampleState
extends State<TreemapBreadcrumbCustomizationExample> {
late List<CarSale> _source;
late Map<String, Color> _colors;
@override
void initState() {
_source = <CarSale>[
const CarSale(carName: 'Hyundai', model: 'Elantra', totalScale: 198210),
const CarSale(carName: 'Hyundai', model: 'Sonata', totalScale: 131803),
const CarSale(carName: 'Hyundai', model: 'Tucson', totalScale: 114735),
const CarSale(carName: 'Hyundai', model: 'Santa Fe', totalScale: 133171),
const CarSale(carName: 'Hyundai', model: 'Accent', totalScale: 58955),
const CarSale(carName: 'Hyundai', model: 'Veloster', totalScale: 12658),
const CarSale(carName: 'Hyundai', model: 'loniq', totalScale: 11197),
const CarSale(carName: 'Hyundai', model: 'Azera', totalScale: 3060),
const CarSale(carName: 'Benz', model: 'C-Class', totalScale: 77447),
const CarSale(carName: 'Benz', model: 'GLE-Class', totalScale: 54595),
const CarSale(carName: 'Benz', model: 'E/CLS-Class', totalScale: 51312),
const CarSale(carName: 'Benz', model: 'GLC-Class', totalScale: 48643),
const CarSale(carName: 'Benz', model: 'GLS-Class', totalScale: 322548),
const CarSale(carName: 'Benz', model: 'Sprinter', totalScale: 27415),
const CarSale(carName: 'Benz', model: 'CLA-Class', totalScale: 20669),
const CarSale(carName: 'Benz', model: 'GLA-Class', totalScale: 24104),
const CarSale(carName: 'Benz', model: 'S-Class', totalScale: 15888),
const CarSale(carName: 'Benz', model: 'Metris', totalScale: 7579),
const CarSale(carName: 'BMW', model: '3-Series', totalScale: 59449),
const CarSale(carName: 'BMW', model: 'X5', totalScale: 50815),
const CarSale(carName: 'BMW', model: 'X3', totalScale: 40691),
const CarSale(carName: 'BMW', model: '5-Series', totalScale: 40658),
const CarSale(carName: 'BMW', model: '4-Series', totalScale: 39634),
const CarSale(carName: 'BMW', model: '2-Series', totalScale: 11737),
const CarSale(carName: 'BMW', model: '7-Series', totalScale: 9276),
const CarSale(carName: 'BMW', model: 'X1', totalScale: 30826),
const CarSale(carName: 'BMW', model: 'X6', totalScale: 6780),
const CarSale(carName: 'BMW', model: 'X4', totalScale: 5198),
const CarSale(carName: 'BMW', model: '6-Series', totalScale: 3355),
const CarSale(carName: 'Jeep', model: 'Grand Cherokee', totalScale: 240696),
const CarSale(carName: 'Jeep', model: 'Cherokee', totalScale: 169822),
const CarSale(carName: 'Jeep', model: 'Renegade', totalScale: 103434),
const CarSale(carName: 'Jeep', model: 'Wrangler', totalScale: 190522),
const CarSale(carName: 'Jeep', model: 'Compass', totalScale: 83523),
const CarSale(carName: 'Jeep', model: 'Patriot', totalScale: 10735),
const CarSale(carName: 'Nissan', model: 'Rogue', totalScale: 403465),
const CarSale(carName: 'Nissan', model: 'Sentra', totalScale: 218451),
const CarSale(carName: 'Nissan', model: 'Murano', totalScale: 76732),
const CarSale(carName: 'Nissan', model: 'Frontier', totalScale: 74360),
const CarSale(carName: 'Nissan', model: 'Altima', totalScale: 254996),
const CarSale(carName: 'Nissan', model: 'Versa', totalScale: 106772),
const CarSale(carName: 'Nissan', model: 'Pathfinder', totalScale: 81065),
const CarSale(carName: 'Nissan', model: 'Maxima', totalScale: 67627),
const CarSale(carName: 'Nissan', model: 'Titan', totalScale: 52924),
const CarSale(carName: 'Nissan', model: 'Armada', totalScale: 35667),
const CarSale(carName: 'Nissan', model: 'NV', totalScale: 17858),
const CarSale(carName: 'Nissan', model: 'NV200', totalScale: 18602),
const CarSale(carName: 'Nissan', model: 'Duke', totalScale: 10157),
const CarSale(carName: 'Honda', model: 'Rogue', totalScale: 403465),
const CarSale(carName: 'Honda', model: 'Sentra', totalScale: 218451),
const CarSale(carName: 'Honda', model: 'Murano', totalScale: 76732),
const CarSale(carName: 'Honda', model: 'Frontier', totalScale: 74360),
const CarSale(carName: 'Honda', model: 'Altima', totalScale: 254996),
const CarSale(carName: 'Honda', model: 'Versa', totalScale: 106772),
const CarSale(carName: 'Honda', model: 'Maxima', totalScale: 67627),
const CarSale(carName: 'Honda', model: 'Titan', totalScale: 52924),
const CarSale(carName: 'Honda', model: 'Armada', totalScale: 35667),
const CarSale(carName: 'Honda', model: 'NV', totalScale: 17858),
const CarSale(carName: 'Honda', model: 'NV200', totalScale: 18602),
const CarSale(carName: 'Honda', model: 'Duke', totalScale: 10157),
const CarSale(carName: 'Ford', model: 'F-Series', totalScale: 896764),
const CarSale(carName: 'Ford', model: 'Explorer', totalScale: 271134),
const CarSale(carName: 'Ford', model: 'Fusion', totalScale: 209623),
const CarSale(carName: 'Ford', model: 'Focus', totalScale: 158385),
const CarSale(carName: 'Ford', model: 'Edge', totalScale: 142603),
const CarSale(carName: 'Ford', model: 'Transit', totalScale: 127340),
const CarSale(carName: 'Ford', model: 'Mustang', totalScale: 81866),
const CarSale(carName: 'Ford', model: 'Escape', totalScale: 308286),
const CarSale(carName: 'Ford', model: 'E-Series', totalScale: 53304),
const CarSale(carName: 'Ford', model: 'Expedition', totalScale: 51833),
const CarSale(carName: 'Ford', model: 'Fiesta', totalScale: 46249),
const CarSale(carName: 'Ford', model: 'Taurus', totalScale: 41326),
const CarSale(carName: 'Ford', model: 'Flex', totalScale: 22389),
const CarSale(carName: 'Ford', model: 'Transit Connect', totalScale: 34473),
];
_colors = <String, Color>{
'Hyundai': const Color.fromRGBO(220, 103, 171, 1.0),
'BMW': const Color.fromRGBO(160, 220, 103, 1.0),
'Benz': const Color.fromRGBO(220, 210, 103, 1.0),
'Nissan': const Color.fromRGBO(163, 103, 220, 1.0),
'Jeep': const Color.fromRGBO(220, 105, 103, 1.0),
'Ford': const Color.fromRGBO(103, 183, 220, 1.0),
'Honda': const Color.fromRGBO(103, 220, 187, 1.0),
};
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Container(
height: 400,
width: 400,
child: SfTreemap(
dataCount: _source.length,
weightValueMapper: (int index) {
return _source[index].totalScale!;
},
enableDrilldown: true,
breadcrumbs: TreemapBreadcrumbs(
builder: (BuildContext context, TreemapTile tile, bool isCurrent) {
if (tile.group == 'Home') {
return const Icon(Icons.home, color: Colors.black);
}
return Text(
tile.group,
style: const TextStyle(color: Colors.black),
);
},
divider: const Icon(Icons.chevron_right, color: Colors.black),
position: TreemapBreadcrumbPosition.top,
),
levels: [
TreemapLevel(
groupMapper: (int index) => _source[index].carName,
labelBuilder: (BuildContext context, TreemapTile tile) {
return Padding(
padding: const EdgeInsets.only(left: 5.0, top: 5.0),
child: Text(
tile.group,
style: const TextStyle(color: Colors.black),
overflow: TextOverflow.ellipsis,
),
);
},
colorValueMapper: (TreemapTile tile) {
return _colors[_source[tile.indices[0]].carName];
},
),
TreemapLevel(
groupMapper: (int index) {
return _source[index].model;
},
colorValueMapper: (TreemapTile tile) {
return _colors[_source[tile.indices[0]].carName];
},
labelBuilder: (BuildContext context, TreemapTile tile) {
return Padding(
padding: const EdgeInsets.only(left: 5.0, top: 5.0),
child: Text(
tile.group,
style: const TextStyle(color: Colors.black),
overflow: TextOverflow.ellipsis,
),
);
},
),
],
),
),
),
);
}
}
class CarSale {
const CarSale({
required this.carName,
this.model,
this.version,
this.versionNumber,
this.totalScale,
});
final String carName;
final String? model;
final String? version;
final String? versionNumber;
final double? totalScale;
}