heart_rate_chart 1.1.1 copy "heart_rate_chart: ^1.1.1" to clipboard
heart_rate_chart: ^1.1.1 copied to clipboard

A lightweight Flutter heart‑rate range chart (hour buckets + spikes) with rich customization.

example/lib/main.dart

import 'package:flutter/material.dart';
import 'package:heart_rate_chart/heart_rate_chart.dart';

void main() => runApp(const DemoApp());

class DemoApp extends StatelessWidget {
  const DemoApp({super.key});

  @override
  Widget build(BuildContext context) {
    final today = DateTime.now();
    final start = DateTime(today.year, today.month, today.day);

    final data = List.generate(24, (h) {
      final t = start.add(Duration(hours: h));
      final min = 55 + (h % 5) * 3;
      final max = min + 30 + (h % 3) * 10;
      return BucketWithSpikes(
        HeartRateBucket(
            time: t, minBpm: min, maxBpm: max, medianBpm: (min + max) ~/ 2),
        h % 6 == 0
            ? [HeartSpike(t.add(const Duration(minutes: 30)), max + 30)]
            : const [],
      );
    });

    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: const Text('Heart Rate Chart Example')),
        body: Center(
          child: SizedBox(
            height: 260,
            child: HeartRateChart(
              buckets: data,
              range: DateTimeRange(
                  start: start, end: start.add(const Duration(days: 1))),
              style: const HeartRateChartStyle(
                barWidthFactor: 0.55,
                spikeRadius: 5,
              ),
              config: HeartRateChartConfig(
                minY: 40,
                maxY: 200,
                showMedianLine: true,
                yTicks: const [40, 100, 160, 200],
                xTimeLabelFormatter: (t) =>
                    '${t.hour.toString().padLeft(2, '0')}:${t.minute.toString().padLeft(2, '0')}',
                tooltipFormatter: (d) =>
                    '${d.minBpm}–${d.maxBpm} bpm (median: ${d.medianBpm ?? '-'} )\n'
                    '${d.start.hour.toString().padLeft(2, '0')}:00 – '
                    '${d.end.hour.toString().padLeft(2, '0')}:00',
              ),
              onTapBucket: (b) {
                debugPrint(
                    'Tapped bucket @ ${b.time}: ${b.minBpm}–${b.maxBpm}');
              },
            ),
          ),
        ),
      ),
    );
  }
}

class _Comparison extends StatelessWidget {
  const _Comparison({super.key});

  @override
  Widget build(BuildContext context) {
    final today = DateTime.now();
    final start = DateTime(today.year, today.month, today.day);

    // Fake data for comparison (no health plugin required at runtime)
    final base = List.generate(24, (h) {
      final t = start.add(Duration(hours: h));
      final min = 55 + (h % 5) * 3;
      final max = min + 30 + (h % 3) * 10;
      return BucketWithSpikes(
        HeartRateBucket(
            time: t, minBpm: min, maxBpm: max, medianBpm: (min + max) ~/ 2),
        h % 6 == 0
            ? [HeartSpike(t.add(const Duration(minutes: 30)), max + 30)]
            : const [],
      );
    });

    // Two charts stacked: exclude spikes (default) vs include spikes
    return SingleChildScrollView(
      child: Padding(
        padding: const EdgeInsets.all(12),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.stretch,
          children: [
            const Text('Exclude spikes from bars (default)',
                style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold)),
            SizedBox(
              height: 220,
              child: HeartRateChart(
                buckets: base,
                range: DateTimeRange(
                    start: start, end: start.add(const Duration(days: 1))),
                style: const HeartRateChartStyle(barWidthFactor: 0.55),
                config: const HeartRateChartConfig(
                    minY: 40, maxY: 200, showMedianLine: true),
              ),
            ),
            const SizedBox(height: 16),
            const Text('Include spikes in bars',
                style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold)),
            SizedBox(
              height: 220,
              child: HeartRateChart(
                buckets: base
                    .map((b) => BucketWithSpikes(
                          HeartRateBucket(
                              time: b.bucket.time,
                              minBpm: b.bucket.minBpm,
                              maxBpm: b.bucket.maxBpm,
                              medianBpm: b.bucket.medianBpm),
                          b.spikes,
                        ))
                    .toList(),
                range: DateTimeRange(
                    start: start, end: start.add(const Duration(days: 1))),
                style: const HeartRateChartStyle(
                    barWidthFactor: 0.55, barColor: Color(0xffe91e63)),
                config: const HeartRateChartConfig(
                    minY: 40, maxY: 200, showMedianLine: true),
              ),
            ),
          ],
        ),
      ),
    );
  }
}
1
likes
150
points
13
downloads

Publisher

unverified uploader

Weekly Downloads

A lightweight Flutter heart‑rate range chart (hour buckets + spikes) with rich customization.

Repository (GitHub)
View/report issues

Topics

#chart #health #heart-rate

Documentation

API reference

License

MIT (license)

Dependencies

flutter

More

Packages that depend on heart_rate_chart