Shapes in Flutter Maps (SfMaps)
2 Nov 202119 minutes to read
This section explains about shapes and how to apply colors to the shapes based on specific values in the Flutter maps.
Loading progress indicator
You can notify the user that the map is being loaded using the MapShapeLayer.loadingBuilder
. It returns the widget which will be visible till the maps is loaded.
late MapShapeSource dataSource;
@override
void initState() {
dataSource = MapShapeSource.asset(
'assets/world_map.json',
shapeDataField: 'continent',
);
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Padding(
padding: EdgeInsets.all(15),
child: SfMaps(
layers: <MapLayer>[
MapShapeLayer(
source: dataSource,
loadingBuilder: (BuildContext context) {
return Container(
height: 25,
width: 25,
child: const CircularProgressIndicator(
strokeWidth: 3,
),
);
},
),
],
),
),
);
}
Shape color
You can apply color, stroke color and stroke width to the shapes using the MapShapeLayer.color
, MapShapeLayer.strokeColor
and MapShapeLayer.strokeWidth
properties respectively.
late MapShapeSource dataSource;
@override
void initState() {
dataSource = MapShapeSource.asset(
'assets/world_map.json',
shapeDataField: 'continent',
);
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Padding(
padding: EdgeInsets.all(15),
child: SfMaps(
layers: <MapLayer>[
MapShapeLayer(
source: dataSource,
color: Colors.blue[100],
strokeColor: Colors.blue,
strokeWidth: 2,
),
],
),
),
);
}
Using SfMapsTheme
You can also customize the below appearance of the shape using SfMapsTheme
.
-
Color - Change the color of the shapes using the
SfMapsThemeData.layerColor
property. -
Stroke color - Change the stroke color of the shapes using the
SfMapsThemeData.layerStrokeColor
property. -
Stroke width - Change the stroke width of the shapes using the
SfMapsThemeData.layerStrokeWidth
property.
NOTE
You must import the
theme.dart
library from theCore
package to useSfMapsTheme
.
late MapShapeSource dataSource;
@override
void initState() {
dataSource = MapShapeSource.asset(
'assets/world_map.json',
shapeDataField: 'continent',
);
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Padding(
padding: EdgeInsets.all(15),
child: SfMapsTheme(
data: SfMapsThemeData(
layerColor: Colors.blue[100],
layerStrokeColor: Colors.blue,
layerStrokeWidth: 2,
),
child: SfMaps(
layers: <MapLayer>[
MapShapeLayer(
source: dataSource,
),
],
),
),
),
);
}
Hover color
You can apply hover color, stroke color and stroke width to the shapes in the web platform using the SfMapsThemeData.shapeHoverColor
, SfMapsThemeData.shapeHoverStrokeColor
and SfMapsThemeData.shapeHoverStrokeWidth
properties respectively.
NOTE
You must import the
theme.dart
library from theCore
package to useSfMapsTheme
.
late MapShapeSource dataSource;
@override
void initState() {
dataSource = MapShapeSource.asset(
'assets/world_map.json',
shapeDataField: 'continent',
);
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Padding(
padding: EdgeInsets.all(15),
child: SfMapsTheme(
data: SfMapsThemeData(
shapeHoverColor: Colors.red[800],
shapeHoverStrokeColor: Colors.black,
shapeHoverStrokeWidth: 2,
),
child: SfMaps(
layers: <MapLayer>[
MapShapeLayer(
source: dataSource,
),
],
),
),
),
);
}
Applying colors based on the data
If you return a color from the shapeColorValueMapper
, then the color will be applied to the respective shape straightaway.
If you return a value of different type other than the color from the shapeColorValueMapper
, then you must set the MapShapeSource.shapeColorMappers
property which is a collection of MapColorMapper
to apply colors for the respective shapes.
NOTE
You can show legend using the
MapShapeLayer.legend
property. The icons color of the legend is applied based on the colors returned in theMapShapeSource.shapeColorValueMapper
property and the text will be taken from theprimaryValueMapper
. It is possible to customize the legend icons color and text using theMapShapeSource.shapeColorMappers
property.
late List<Model> data;
late MapShapeSource dataSource;
@override
void initState() {
data = const <Model>[
Model('Asia', Color.fromRGBO(60, 120, 255, 0.8)),
Model('Africa', Color.fromRGBO(51, 102, 255, 0.8)),
Model('Europe', Color.fromRGBO(0, 57, 230, 0.8)),
Model('South America', Color.fromRGBO(0, 51, 204, 0.8)),
Model('Australia', Color.fromRGBO(0, 45, 179, 0.8)),
Model('North America', Color.fromRGBO(0, 38, 153, 0.8))
];
dataSource = MapShapeSource.asset(
'assets/world_map.json',
shapeDataField: 'continent',
dataCount: data.length,
primaryValueMapper: (int index) => data[index].country,
shapeColorValueMapper: (int index) => data[index].color,
);
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Container(
height: 350,
child: Padding(
padding: EdgeInsets.only(left: 15, right: 15),
child: SfMaps(
layers: <MapLayer>[
MapShapeLayer(
source: dataSource,
),
],
),
),
)),
);
}
class Model {
const Model(this.country, this.color);
final String country;
final Color color;
}
Equal color mapping
You can apply color to the shape by comparing a value that returns from the shapeColorValueMapper
with the MapColorMapper.value
. For the matched values, the MapColorMapper.color
will be applied to the respective shapes.
late List<Model> data;
late MapShapeSource dataSource;
@override
void initState() {
data = <Model>[
Model('India', "Low"),
Model('United States of America', "High"),
Model('Pakistan', "Low"),
];
dataSource = MapShapeSource.asset(
"assets/world_map.json",
shapeDataField: "name",
dataCount: data.length,
primaryValueMapper: (int index) {
return data[index].country;
},
shapeColorValueMapper: (int index) {
return data[index].storage;
},
shapeColorMappers: [
MapColorMapper(value: "Low", color: Colors.red),
MapColorMapper(value: "High", color: Colors.green)
],
);
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Padding(
padding: EdgeInsets.only(left: 15, right: 15),
child: SfMaps(
layers: <MapShapeLayer>[
MapShapeLayer(source: dataSource),
],
),
),
);
}
class Model {
const Model(this.country, this.storage);
final String country;
final String storage;
}
Range color mapping
You can apply color to the shape based on whether the value returned from shapeColorValueMapper
falls within the MapColorMapper.from
and MapColorMapper.to
. Then, the MapColorMapper.color
will be applied to the respective shapes.
late List<Model> data;
late MapShapeSource dataSource;
@override
void initState() {
data = <Model>[
Model('India', 280),
Model('United States of America', 190),
Model('Kazakhstan', 37),
];
dataSource = MapShapeSource.asset(
"assets/world_map.json",
shapeDataField: "name",
dataCount: data.length,
primaryValueMapper: (int index) => data[index].country,
shapeColorValueMapper: (int index) => data[index].count,
shapeColorMappers: [
MapColorMapper(from: 0, to: 100, color: Colors.red),
MapColorMapper(from: 101, to: 300, color: Colors.green)
],
);
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Padding(
padding: EdgeInsets.only(left: 15, right: 15),
child: SfMaps(
layers: [
MapShapeLayer(source: dataSource),
],
),
),
);
}
class Model {
const Model(this.country, this.count);
final String country;
final double count;
}
Opacity
You can apply the maximum and minimum opacity to the shape or bubbles
while using MapColorMapper.from
and MapColorMapper.to
properties.
The shapes or bubbles with lowest value which is from
will be applied a minOpacity
and the shapes or bubbles with highest value which is to
will be applied a maxOpacity
. The shapes or bubbles with values in-between the range will get a opacity based on their respective value.
late List<Model> data;
late MapShapeSource dataSource;
@override
void initState() {
data = <Model>[
Model('India', 280),
Model('United States of America', 190),
Model('Kazakhstan', 37),
];
dataSource = MapShapeSource.asset(
"assets/world_map.json",
shapeDataField: "name",
dataCount: data.length,
primaryValueMapper: (int index) => data[index].country,
shapeColorValueMapper: (int index) => data[index].count,
shapeColorMappers: [
MapColorMapper(
from: 0,
to: 100,
color: Colors.red,
minOpacity: 0.2,
maxOpacity: 0.4,
),
MapColorMapper(
from: 101,
to: 300,
color: Colors.green,
minOpacity: 0.4,
maxOpacity: 0.6,
),
],
);
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Padding(
padding: EdgeInsets.only(left: 15, right: 15),
child: SfMaps(
layers: [
MapShapeLayer(source: dataSource),
],
),
),
);
}
class Model {
const Model(this.country, this.count);
final String country;
final double count;
}
NOTE
- Refer the
MapShapeSource.bubbleColorMappers
, for setting the bubble colors based on the specific value. You can refer to our Flutter Maps feature tour page for its groundbreaking feature representations. You can also explore our Flutter Maps Shapes example that shows how to configure a Maps in Flutter.