chartificial 0.0.2
chartificial: ^0.0.2 copied to clipboard
Cartesian charts for Flutter on the two-dimensional viewport: lazy paged loading, recycled widget axis labels, scrolling time axes, pluggable series.
import 'package:flutter/material.dart';
import 'pages/aqi_gradient_page.dart';
import 'pages/bar_chart_page.dart';
import 'pages/custom_decoration_page.dart';
import 'pages/custom_series_page.dart';
import 'pages/fixed_chart_page.dart';
import 'pages/line_styles_page.dart';
import 'pages/live_chart_page.dart';
import 'pages/log_axis_page.dart';
import 'pages/scrolling_bars_page.dart';
import 'pages/scrolling_time_chart_page.dart';
import 'pages/stacked_bars_page.dart';
import 'pages/visible_range_page.dart';
void main() => runApp(const ChartificialExampleApp());
class ChartificialExampleApp extends StatelessWidget {
const ChartificialExampleApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'chartificial demos',
theme: ThemeData(colorSchemeSeed: Colors.teal, useMaterial3: true),
home: const DemoListPage(),
);
}
}
class DemoListPage extends StatelessWidget {
const DemoListPage({super.key});
@override
Widget build(BuildContext context) {
final demos = <(String, String, WidgetBuilder)>[
(
'Infinite past + lazy loading',
'Newest at the right, scroll into the past; pages load ahead of the scroll.',
(_) => const ScrollingTimeChartPage(),
),
(
'Live values + followLatest',
'A point per second; the chart stays pinned to "now" until you scroll away.',
(_) => const LiveChartPage(),
),
(
'AQI gradient line',
'Stroke colored by value bands, band backgrounds as a custom layer.',
(_) => const AqiGradientPage(),
),
(
'Line styles',
'Curves, dashes, area fill, gradient stroke, end badge, opposed axis.',
(_) => const LineStylesPage(),
),
(
'Bar chart: daily range',
'Floating min–max pill bars on a background track, colored by band.',
(_) => const BarChartPage(),
),
(
'Stacked + grouped bars',
'Pollutant mix stacked per bar; indoor and outdoor clustered per day.',
(_) => const StackedBarsPage(),
),
(
'Scrolling time bars',
'Hourly bars + average line; proportional widths, stable at the edges.',
(_) => const ScrollingBarsPage(),
),
(
'Custom grid + edge markers',
'Replaces the grid and rings the values where the line crosses the edges.',
(_) => const CustomDecorationPage(),
),
(
'Custom lollipop series',
'A series defined by the app, not the package — the ChartSeries seam.',
(_) => const CustomSeriesPage(),
),
(
'Fixed axes + callbacks',
'Non-scrollable chart with gaps, markers, and raw hit callbacks.',
(_) => const FixedChartPage(),
),
(
'Logarithmic axis',
'Four decades of particle counts with decade ticks.',
(_) => const LogAxisPage(),
),
(
'Visible-window y range',
'The y axis follows what is on screen; scroll into the spike to see it rescale.',
(_) => const VisibleRangePage(),
),
];
return Scaffold(
appBar: AppBar(title: const Text('chartificial demos')),
body: ListView.separated(
itemCount: demos.length,
separatorBuilder: (_, _) => const Divider(height: 1),
itemBuilder: (context, index) {
final (title, subtitle, builder) = demos[index];
return ListTile(
title: Text(title),
subtitle: Text(subtitle),
trailing: const Icon(Icons.chevron_right),
onTap: () => Navigator.of(
context,
).push(MaterialPageRoute<void>(builder: builder)),
);
},
),
);
}
}