braven_charts 0.5.0 copy "braven_charts: ^0.5.0" to clipboard
braven_charts: ^0.5.0 copied to clipboard

Pure Dart Flutter line, area, bar, scatter, Pie, and Donut charts with custom rendering, multi-axis interaction, streaming, annotations, tables, and artifacts.

Braven Charts #

Pub version Flutter License: MIT

Braven Charts is a pure Dart charting library for Flutter applications. Chart rendering and interaction use a custom RenderBox and Flutter Canvas; the package does not embed a JavaScript charting engine.

BravenChartPlus supports line, area, bar, scatter, mixed Cartesian series, and single-series Pie and Donut charts; multiple independent axes and normalization; zoom, pan, scrollbars, tracking, tooltips, and editable annotations; frame-coalesced live data; configurable themes and state views; chart/table display modes; and portable chart artifacts. Rendering, input handling, and streaming updates remain inside the Flutter rendering pipeline.

For update-heavy charts, the implementation uses cached series layers, a spatial hit-test index, frame-coalesced point delivery, and a direct render-box streaming path so each sample does not require a widget-tree rebuild.

Live showcase and runnable examples

Rendered examples #

Multi-axis training profile Dark baseline fill, glow, and sections
Power area and heart-rate response with two axes, stage bands, a target threshold, tracking, and a peak marker Power-duration chart with six curves, positive and negative baseline fill, glow, annotations, and a scrollbar

Core chart types #

Line, area, scatter, bar, Pie, and Donut charts share the same native Flutter rendering pipeline while retaining independent series and theme treatments.

Line, area, scatter, bar, Pie, and Donut charts rendered by Braven Charts

Multi-axis interaction #

The animated example combines independently scaled axes, normalization, annotations, tracking, pointer zoom, drag-to-pan, and a synchronized scrollbar:

Four-axis chart with annotations, tracking, zoom, pan, and a synchronized scrollbar

Live-stream buffering #

LiveStreamController sends frame-coalesced point updates directly to the rendering layer. The viewport can follow the latest sample, pause while the bounded buffer continues receiving data, and resume with buffered catch-up.

Live chart data buffering and catching up

The Gallery combines curated and full-catalog views across Pie, Donut, line, area, bar, scatter, and mixed compositions. It covers light and dark Pie treatments, inside and collision-aware outside labels, dense categories, rounded and elevated slices, solid and gradient fills, baseline fills, live data, independent axes, annotations, interpolation, thresholds, and domain-shaped dashboards.

These PNGs are exported by BravenChartController.capturePreview(), the same native image path available to package consumers:

Collision-managed outside labels Gradient, elevation, and positioned legend
Pie contribution chart with outside category and percentage labels Pie allocation chart with gradients, rounded slices, elevation, and a positioned legend

Three product-shaped Donut compositions with center content, a partial sweep, and variable radii

Subscription MRR Release readiness Channel efficiency
Subscription MRR Donut with a selection-aware center value Dark release-readiness Donut with a partial sweep and compact labels Variable-radius Donut encoding orders and audience reach

Bar targets and interaction #

Grouped Bar series support keyed data-update animation, durable point selection, gradients, per-category benchmark markers, and absolute uncertainty intervals with styled stems and caps.

Grouped Bar chart with gradients, target markers, uncertainty intervals, and a tracking tooltip

The wider Cartesian catalog remains available in the current Gallery mosaic:

Varied Braven Charts compositions from the current Gallery

Feature coverage #

Area API and behavior
Rendering Pure Dart on Flutter's RenderBox/Canvas pipeline, cached series layers, and no embedded JavaScript chart engine
Interaction Pointer and touch zoom, pan, X/Y scrollbars, hover tooltips, crosshairs, and tracking panels
Data series Line, area, bar, scatter, mixed Cartesian series, and category-based Pie and Donut charts with labels, positioned legends, solid/gradient fills, three corner treatments, variable radii, center content, partial sweeps, elevation, selection, and animation
Axes Configurable X axis, multiple independent Y axes, shared axes, automatic or per-series normalization, and visible-axis slots
Annotations Point, range, text, threshold, trend, chord, pin, and legend annotations with interactive editing
Live data Frame-coalesced point ingestion, bounded buffers, follow-latest viewports, pause/resume, and buffered catch-up
Display Light/dark and custom themes, legends, labels, package-owned Chart/Data/Split workbenches, loading skeletons, progress indicators, and empty states
Application control Controllers, callbacks, runtime series selection, annotation management, axis-slot state, and serializable chart configuration
Portable artifacts Capture effective chart state, persist canonical JSON, render exact-X or category/share data tables with native copy/CSV actions, attach previews, and hydrate fresh interactive charts
Document comparison Explicit semantic series mapping, exact-X or timestamp alignment, safe units, missing values, deltas, and source-preserving CSV export

The live showcase provides runnable examples and configuration controls for these APIs. See the showcase guide for the feature-to-page map and local run instructions. Open Chart Workbench directly to try the package-owned Chart/Data/Split workflow, linked point selection, artifact capture, deliberate table freshness, and document comparison. Open Pie Charts directly to try category datasets, inside/outside labels, slice selection, native data tables, artifact capture, previews, and restored charts. Open Donut Charts directly to try full and partial rings, variable outer radii, selection-aware center content, Chart/Data/Split views, native tables, and portable restoration.

Install #

Add the package to your app:

dependencies:
  braven_charts: ^0.5.0

Then fetch dependencies:

flutter pub get

Braven Charts 0.5.0 requires Dart 3.9 or later and Flutter 3.35 or later.

Quick start #

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

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

  @override
  Widget build(BuildContext context) {
    return BravenChartPlus(
      title: 'Revenue',
      subtitle: 'Last 6 months',
      series: const [
        LineChartSeries(
          id: 'revenue',
          name: 'Revenue',
          unit: 'USD',
          color: Color(0xFF0F766E),
          interpolation: LineInterpolation.bezier,
          showDataPointMarkers: true,
          points: [
            ChartDataPoint(x: 1, y: 45000),
            ChartDataPoint(x: 2, y: 52000),
            ChartDataPoint(x: 3, y: 49000),
            ChartDataPoint(x: 4, y: 63000),
            ChartDataPoint(x: 5, y: 71000),
            ChartDataPoint(x: 6, y: 68000),
          ],
        ),
      ],
      xAxisConfig: const XAxisConfig(label: 'Month'),
      yAxis: const YAxisConfig(label: 'Revenue', unit: 'USD'),
      interactionConfig: const InteractionConfig(
        crosshair: CrosshairConfig(
          enabled: true,
          mode: CrosshairMode.both,
          snapToDataPoint: true,
          displayMode: CrosshairDisplayMode.tracking,
        ),
        tooltip: TooltipConfig(enabled: true),
      ),
    );
  }
}

Multi-axis and normalization #

Attach a YAxisConfig directly to each series when measurements use different units or scales. Braven Charts can normalize each series for a shared plot while keeping labels, tracking values, and tooltips in their original units.

BravenChartPlus(
  normalizationMode: NormalizationMode.perSeries,
  series: [
    LineChartSeries(
      id: 'power',
      name: 'Power',
      unit: 'W',
      points: powerPoints,
      yAxisConfig: const YAxisConfig(
        label: 'Power',
        unit: 'W',
        position: YAxisPosition.left,
      ),
    ),
    LineChartSeries(
      id: 'heart-rate',
      name: 'Heart rate',
      unit: 'bpm',
      points: heartRatePoints,
      yAxisConfig: const YAxisConfig(
        label: 'Heart rate',
        unit: 'bpm',
        position: YAxisPosition.right,
      ),
    ),
  ],
)

Pie charts #

Pie charts use one PieChartSeries; they do not mix with Cartesian series or use axes, crosshairs, pan, or zoom. Map insertion order becomes stable slice order, while the category string becomes the visible and accessible label.

BravenChartPlus(
  title: 'Revenue contribution',
  series: [
    PieChartSeries.fromMap(
      id: 'revenue-share',
      name: 'Revenue share',
      unit: 'USD',
      values: const {
        'Subscriptions': 42,
        'Services': 31,
        'Hardware': 27,
      },
      // Optional: provide one second-metric value per category.
      radiusValues: const {
        'Subscriptions': 120,
        'Services': 90,
        'Hardware': 65,
      },
      sliceRadiusConfig: const PieSliceRadiusConfig(
        label: 'Market size',
        unit: 'k users',
      ),
      pieStyle: const PieChartStyle(
        gradient: PieGradientStyle(type: PieGradientType.radial),
      ),
      dataLabels: const PieDataLabelConfig(
        position: PieDataLabelPosition.outside,
        content: PieDataLabelContent.categoryAndPercentage,
      ),
    ),
  ],
  interactionConfig: const InteractionConfig(
    tooltip: TooltipConfig(enabled: true),
  ),
)

Pie values must be finite and non-negative. Zero values remain portable and appear in the native table but do not paint a slice; an all-zero dataset uses the configured empty state. Optional radius values must be complete, finite, and non-negative; they appear in tooltips, the table, CSV, AI input, and portable artifacts. See the Pie chart guide for fills, labels, selection, tables, artifacts, validation, and accessibility.

Donut charts #

Donut uses the same ordered category contract as Pie, with a required shared center opening and optional portable center text. The center can show the total, the selected category value, a selected-or-total fallback, or custom status text.

BravenChartPlus(
  series: [
    DonutChartSeries.fromMap(
      id: 'revenue-share',
      unit: 'USD',
      values: const {
        'Subscriptions': 42,
        'Services': 31,
        'Hardware': 27,
      },
      donutStyle: const DonutChartStyle(
        innerRadiusFactor: 0.58,
        sliceGap: 2,
        cornerRadius: 8,
      ),
      centerContent: const DonutCenterContent(
        label: 'Revenue',
        valueMode: DonutCenterValueMode.selectedOrTotal,
      ),
    ),
  ],
)

Slice, legend, table, keyboard, and controller selection share one ChartPointRef, so the center follows selection no matter where it begins. The complete Donut document—including center content and optional variable-radius values—round-trips through canonical JSON and PNG previews. See the Donut chart guide.

Loading and empty states #

isLoading replaces the plot viewport without changing the surrounding layout. The default is an animated, theme-aware chart skeleton with reduced-motion support and soft edge fades. Circular, linear, determinate, and fully custom states are also available.

BravenChartPlus(
  series: series,
  isLoading: isLoading,
  loadingConfig: const ChartLoadingConfig.skeleton(),
  emptyStateConfig: const ChartEmptyStateConfig(
    title: 'No workout samples',
    message: 'Import a workout or change the selected date range.',
  ),
)

Customize only the skeleton characteristics your product needs:

loadingConfig: const ChartLoadingConfig.skeleton(
  skeletonStyle: ChartLoadingSkeletonStyle(
    seriesColor: Color(0xFF6D28D9),
    secondarySeriesColor: Color(0xFFEC4899),
    animationDuration: Duration(milliseconds: 1800),
    motionIntensity: 0.8,
    edgeFadeFraction: 0.16,
  ),
),

Live data #

LiveStreamController accepts individual or batched points without rebuilding the chart widget for every sample. It exposes pause/resume state, buffered point counts, bounds, the latest point, and a snapshot of the active buffer.

final liveController = LiveStreamController(
  seriesId: 'sensor',
  maxPoints: 1000,
);

liveController.addPoint(
  ChartDataPoint(
    x: DateTime.now().millisecondsSinceEpoch.toDouble(),
    y: sensorReading,
  ),
);

BravenChartPlus(
  series: const [
    LineChartSeries(
      id: 'sensor',
      name: 'Sensor',
      points: [],
    ),
  ],
  liveStreamController: liveController,
)

Dispose controllers you create when the owning widget is disposed.

Programmatic control #

The package provides focused controller APIs rather than requiring access to rendering internals:

  • BravenChartController selects series and exposes visible/overflow Y-axis slots.
  • ChartController manages runtime point collections and annotations.
  • AnnotationController coordinates interactive annotation workflows.
  • StreamingController and LiveStreamController control viewport and live ingestion state.
  • ChartConfigBuilder and the agent interface support serializable, tool-driven chart construction.

See Public API overview for the exported surface and the API documentation generated by pub.dev for member-level reference.

Portable chart artifacts #

For a reusable product surface, wrap a chart in BravenChartWorkbench. It keeps one chart runtime mounted while users switch between Chart, Data, and responsive Split modes, and gives host actions a stable handle for refresh and artifact capture:

BravenChartWorkbench(
  initialDisplayMode: ChartDisplayMode.split,
  tableRefreshPolicy: ChartTableRefreshPolicy.onDocumentRevision,
  chartBuilder: (context, controller) => BravenChartPlus(
    bravenChartController: controller,
    series: series,
  ),
  actionsBuilder: (context, handle) => [
    FilledButton(
      onPressed: handle.isExtractingArtifact
          ? null
          : () => addToReport(handle),
      child: const Text('Add to report'),
    ),
  ],
)

The package manages chart/table lifecycle and structured extraction state; the workbench also links table focus and activation to revision-safe chart point focus/selection by default. Wide rows target every populated series at their exact X value, and a successful linked selection rebases the table snapshot so the next row remains usable. The host owns action policy, artifact IDs, persistence, and navigation. Initial and refresh failures retain explicit recovery actions, and manual refresh is the recommended policy when a bounded live stream should not rewrite a visible table at sample cadence. See the Chart Workbench guide for refresh policies, point identity, responsive semantics, status, and controller ownership.

For two or more saved documents, ChartComparisonBuilder provides explicit series mapping, exact-X or timestamp alignment, missing-value state, safe unit conversion, optional deltas, and source-preserving CSV export. It never infers identity from display names or owns a comparison repository/screen. See the Chart Document Comparison guide.

Capture and transport #

Capture a mounted chart once and reuse the same effective state for storage, sharing, previews, data tables, or a restored interactive copy. Artifacts are validated, deterministic, schema-versioned, and safe by construction: JSON contains descriptors rather than executable callbacks or class names.

final result = await chartController.extractArtifact(
  const ChartArtifactExtractOptions(
    includePreview: true,
    documentOptions: ChartDocumentExtractOptions(
      dataStorage: ChartDataStorage.inlineColumns,
    ),
  ),
);

if (result case ChartArtifactSuccess<ChartArtifact>()) {
  final json = ChartArtifactJsonCodec.encode(result.value);
  // Persist json.value when encoding succeeds; inspect warnings as needed.
}

ChartDataTable includes bounded whole-dataset clipboard copy, per-row copy, and raw-value CSV export. Web builds download CSV directly; non-web hosts can provide delivery callbacks for their file or share-sheet workflow.

For the complete capture, table, transport, hydration, resolver, migration, and runtime-binding contracts, read the portable chart artifact guide.

Run the showcase #

Open the hosted showcase, or run the same application locally:

cd example
flutter pub get
flutter run -d chrome

The showcase is responsive: desktop uses a persistent feature rail, while smaller screens use a navigation drawer. It includes gallery-ready examples and focused pages for chart types, Pie and Donut charts, interaction, tracking, annotations, streaming, theming, performance, multi-axis layouts, scientific data, baseline fills, and state UX.

Documentation #

Pub.dev generates and hosts member-level API documentation from the package's /// documentation comments for every published version.

License #

Braven Charts is available under the MIT License.

2
likes
0
points
2.79k
downloads

Documentation

Documentation

Publisher

unverified uploader

Weekly Downloads

Pure Dart Flutter line, area, bar, scatter, Pie, and Donut charts with custom rendering, multi-axis interaction, streaming, annotations, tables, and artifacts.

Homepage
Repository (GitHub)
View/report issues

Topics

#chart #data-visualization #flutter-widgets #annotations #streaming

License

unknown (license)

Dependencies

crypto, fleather, flex_color_picker, flutter, parchment, web

More

Packages that depend on braven_charts