bodyheatmap 1.0.0
bodyheatmap: ^1.0.0 copied to clipboard
Interactive human body heatmap widget for Flutter. Perfect for fitness, health, and medical apps to track body parts with customizable intensity visualization.
Body Heatmap #
An interactive Flutter widget that displays a human body diagram with customizable heatmap visualization. Perfect for fitness apps, health tracking applications, pain tracking tools, or any app that needs body part selection and intensity visualization.
Features #
- π― Interactive Body Diagram - Front and back view of human body with clickable regions
- π‘οΈ Heatmap Visualization - Display intensity levels with customizable colors and opacity
- π Touch & Hover Support - Responsive interactions with visual feedback
- π¨ Fully Customizable - Colors, intensity levels, legend display, and more
- π± Responsive Design - Scales to any screen size while maintaining proportions
- π Detailed Body Parts - 60+ distinct body regions including head, neck, shoulders, arms, chest, abs, legs, and feet, knees
Use Cases #
- Fitness Apps - Track muscle soreness or workout intensity by body part
- Health Apps - Monitor pain levels or symptoms across different body regions
- Physical Therapy - Document patient progress and problem areas
- Medical Apps - Record injury locations or treatment areas
- Wellness Apps - Track massage therapy sessions or acupuncture points
Getting Started #
Add this to your package's pubspec.yaml file:
dependencies:
bodyheatmap: ^1.0.0
Then run:
flutter pub get
Usage #
Basic Example #
import 'package:flutter/material.dart';
import 'package:bodyheatmap/bodyheatmap.dart';
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: Text('Body Heatmap Example')),
body: Center(
child: BodyHeatmap(
selectedParts: const {
'front-head': 3,
'front-chest-left': 2,
'front-chest-right': 2,
'front-arm-left': 1,
},
baseColor: Colors.red,
width: 300,
showLegend: true,
onPartTap: (part) {
print('Tapped: $part');
},
),
),
),
);
}
}
Interactive Example with State Management #
class InteractiveBodyHeatmap extends StatefulWidget {
@override
_InteractiveBodyHeatmapState createState() => _InteractiveBodyHeatmapState();
}
class _InteractiveBodyHeatmapState extends State<InteractiveBodyHeatmap> {
Map<String, int> selectedParts = {};
void _handlePartTap(String part) {
setState(() {
if (selectedParts.containsKey(part)) {
// Cycle through intensity levels: 1 -> 2 -> 3 -> remove
if (selectedParts[part]! >= 3) {
selectedParts.remove(part);
} else {
selectedParts[part] = selectedParts[part]! + 1;
}
} else {
selectedParts[part] = 1;
}
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Pain Tracker')),
body: Column(
children: [
Expanded(
child: Center(
child: BodyHeatmap(
selectedParts: selectedParts,
baseColor: Colors.orange,
unselectedColor: Colors.grey[300]!,
width: 300,
showLegend: true,
intensityLevels: 3,
legendTextStyle: TextStyle(fontSize: 12),
onPartTap: _handlePartTap,
),
),
),
Padding(
padding: EdgeInsets.all(16),
child: Text(
'Tap body parts to track pain levels (1-3)',
style: TextStyle(fontSize: 16),
),
),
],
),
);
}
}
Parameters #
| Parameter | Type | Default | Description |
|---|---|---|---|
selectedParts |
Map<String, int> |
required | Map of body part IDs to intensity values (1-10) |
baseColor |
Color |
required | Base color for the heatmap visualization |
unselectedColor |
Color |
Color(0xFFCCCCCC) |
Color for unselected body parts |
width |
double |
300 |
Width of the widget (height scales proportionally) |
showLegend |
bool |
false |
Whether to display the intensity legend |
legendTextStyle |
TextStyle |
TextStyle(fontSize: 14) |
Style for legend text |
legendAlignment |
MainAxisAlignment |
MainAxisAlignment.center |
Alignment of the legend |
intensityLevels |
int |
3 |
Number of intensity levels (affects opacity steps) |
onPartTap |
Function(String)? |
null |
Callback when a body part is tapped |
Available Body Parts #
The widget recognizes 60+ body part identifiers:
Front View:
front-head,front-neck-left,front-neck-rightfront-shoulder-left,front-shoulder-rightfront-chest-left,front-chest-rightfront-arm-left,front-arm-rightfront-palm-left,front-palm-rightfront-abs,front-hip-left,front-hip-rightfront-leg-left,front-leg-rightfront-knee-left,front-knee-rightfront-foot-left,front-foot-right
Back View:
back-head,back-neck-left,back-neck-rightback-shoulder-left,back-shoulder-rightback-upper-left,back-upper-rightback-mid-left,back-mid-rightback-arm-left,back-arm-rightback-hand-left,back-hand-rightback-butt-left,back-butt-rightback-leg-left,back-leg-right
Customization Examples #
Fitness App - Muscle Soreness Tracker #
BodyHeatmap(
selectedParts: {
'front-chest-left': 5,
'front-chest-right': 5,
'front-arm-left': 3,
'front-leg-left': 2,
},
baseColor: Colors.deepOrange,
width: 350,
showLegend: true,
intensityLevels: 5,
onPartTap: (part) => _recordSoreness(part),
)
Medical App - Pain Assessment #
BodyHeatmap(
selectedParts: painData,
baseColor: Colors.red,
unselectedColor: Colors.grey[200]!,
width: 280,
showLegend: true,
legendTextStyle: TextStyle(
fontSize: 14,
fontWeight: FontWeight.w500,
),
intensityLevels: 10,
onPartTap: (part) => _assessPain(part),
)
Wellness App - Massage Therapy #
BodyHeatmap(
selectedParts: treatmentAreas,
baseColor: Colors.blue,
width: 300,
showLegend: false,
onPartTap: (part) => _markTreatmentArea(part),
)
How It Works #
The widget uses SVG path data to render an accurate human body diagram. Each body part is a clickable region that:
- Responds to hover events (on supported platforms)
- Provides visual feedback on tap
- Calculates opacity based on intensity values
- Normalizes intensity across all selected parts for consistent visualization
The heatmap automatically scales intensity values to create a gradient effect, making it easy to visualize relative differences between body parts.
Contributing #
Contributions are welcome! If you find a bug or want to add a feature:
- Open an issue describing the bug or feature
- Fork the repository
- Create a pull request with your changes
License #
This project is licensed under the MIT License - see the LICENSE file for details.
Support #
For issues, questions, or suggestions, please file an issue on the GitHub repository.