The grammar of graphics visualization library that Flutter developers have been waiting for.
Finally, create beautiful data visualizations in Flutter without fighting against chart widgets or settling for web-based solutions.
Visit our complete documentation for step-by-step guides, interactive examples, |
π€ AI-Powered Development
Cristalyse Docs now has MCP server which you can connect to your AI coding assistant (Cursor, Windsurf, Warp, Claude) for instant access to documentation while you code.
β¨ Why Cristalyse?
Stop wrestling with limited chart libraries. Cristalyse brings the power of grammar of graphics (think ggplot2) to Flutter with buttery-smooth 60fps animations and true cross-platform deployment.
- π¨ Grammar of Graphics API - Familiar syntax if you've used ggplot2 or plotly
- π Native 60fps Animations - Leverages Flutter's rendering engine, not DOM manipulation
- π± True Cross-Platform - One codebase β Mobile, Web, Desktop, all looking identical
- β‘ GPU-Accelerated Performance - Handle large datasets without breaking a sweat
- π― Flutter-First Design - Seamlessly integrates with your existing Flutter apps
- π Dual Y-Axis Support - Professional business dashboards with independent left/right scales
- π Advanced Bar Charts - Grouped, stacked, and horizontal variations with smooth animations
- π«§ Bubble Charts - Multi-dimensional data visualization with size, color, and position encoding
- π Interactive Charts - Engage users with tooltips, hover effects, and click events.
See What You Can Build
Interactive scatter plots with smooth animations and multi-dimensional data mapping
Progressive line drawing with customizable themes and multi-series support
π― Perfect For
|
|
π Quick Start
Installation
flutter pub add cristalyse
That's it! No complex setup, no additional configuration.
Your First Chart (30 seconds)
import 'package:cristalyse/cristalyse.dart';
import 'package:flutter/material.dart';
class MyChart extends StatelessWidget {
@override
Widget build(BuildContext context) {
final data = [
{'x': 1, 'y': 2, 'category': 'A'},
{'x': 2, 'y': 3, 'category': 'B'},
{'x': 3, 'y': 1, 'category': 'A'},
{'x': 4, 'y': 4, 'category': 'C'},
];
return CristalyseChart()
.data(data)
.mapping(x: 'x', y: 'y', color: 'category')
.geomPoint(
size: 8.0, // Made points a bit larger to see border clearly
alpha: 0.8,
shape: PointShape.triangle, // Example: use triangles
borderWidth: 1.5, // Example: add a border to points
)
.scaleXContinuous()
.scaleYContinuous()
.theme(ChartTheme.defaultTheme())
.build();
}
}
Result: A beautiful, animated scatter plot that works identically on iOS, Android, Web, and Desktop.
Your first chart - clean, responsive, and cross-platform
π‘ Interactive Charts
Enhanced Panning Behavior
Real-time data streaming and interactive exploration with advanced pan controls and coordinate transformation.
// Basic panning with range callbacks
CristalyseChart()
.data(timeSeriesData)
.mapping(x: 'timestamp', y: 'value')
.geomLine()
.interaction(
pan: PanConfig(
enabled: true,
onPanUpdate: (info) {
// Handle real-time updates based on visible X range
print('Visible X range: ${info.visibleMinX} - ${info.visibleMaxX}');
// Load more data when approaching boundaries
if (info.visibleMaxX! > maxDataTimestamp - bufferTime) {
loadMoreRecentData();
}
},
throttle: Duration(milliseconds: 100), // Prevent overwhelming callbacks
),
)
.build();
// Advanced panning with state management
class PanningChartState extends State<PanningChart> {
DateTime? visibleStart;
DateTime? visibleEnd;
@override
Widget build(BuildContext context) {
return Column([
// Range display header
Container(
padding: EdgeInsets.all(8),
child: Text(
visibleStart != null
? 'Range: ${DateFormat('MMM d').format(visibleStart!)} - ${DateFormat('MMM d').format(visibleEnd!)}'
: 'Loading...',
),
),
// Interactive chart
Expanded(
child: CristalyseChart()
.data(chartData)
.mapping(x: 'date', y: 'revenue')
.geomLine()
.onPan((info) {
setState(() {
visibleStart = DateTime.fromMillisecondsSinceEpoch(
(info.visibleMinX! * 1000).round()
);
visibleEnd = DateTime.fromMillisecondsSinceEpoch(
(info.visibleMaxX! * 1000).round()
);
});
// Fetch data for new range
fetchDataForDateRange(visibleStart!, visibleEnd!);
})
.build(),
),
]);
}
}
Panning Features:
- β Coordinate Transformation - Screen pixels to data values automatically
- β Throttled Callbacks - Configurable update frequency for performance
- β Range State Persistence - Maintains pan position across interactions
- β Real-time Data Loading - Perfect for streaming and large datasets
- β Multi-axis Support - Independent X and Y panning controls
- β Touch & Mouse Compatible - Works on all platforms
Bring your data to life with a fully interactive layer. Add rich tooltips, hover effects, and click/tap events to give users a more engaging experience.
// Add tooltips and click handlers
CristalyseChart()
.data(salesData)
.mapping(x: 'week', y: 'revenue', color: 'rep')
.geomPoint(size: 8.0)
.interaction(
tooltip: TooltipConfig(
builder: (point) {
// Build a custom widget for the tooltip
final category = point.getDisplayValue('rep');
final value = point.getDisplayValue('revenue');
return Container(
padding: const EdgeInsets.all(8),
decoration: BoxDecoration(
color: Colors.black.withOpacity(0.8),
borderRadius: BorderRadius.circular(4),
),
child: Text(
'$category: \$$value k',
style: const TextStyle(color: Colors.white, fontSize: 12),
),
);
},
),
click: ClickConfig(
onTap: (point) {
// Handle tap event, e.g., show a dialog
print('Tapped on: ${point.data}');
},
),
)
.build();
π¬ See It In Action
Animated Scatter Plot
CristalyseChart()
.data(salesData)
.mapping(x: 'date', y: 'revenue', color: 'region', size: 'deals')
.geomPoint(alpha: 0.7)
.animate(duration: Duration(milliseconds: 800), curve: Curves.elasticOut)
.theme(ChartTheme.defaultTheme())
.build()
Multi-Series Line Chart
CristalyseChart()
.data(timeSeriesData)
.mapping(x: 'month', y: 'users', color: 'platform')
.geomLine(strokeWidth: 3.0)
.geomPoint(size: 4.0)
.animate(duration: Duration(milliseconds: 1200))
.theme(ChartTheme.darkTheme())
.build()
Combined Visualizations
CristalyseChart()
.data(analyticsData)
.mapping(x: 'week', y: 'engagement')
.geomLine(strokeWidth: 2.0, alpha: 0.8) // Trend line
.geomPoint(size: 5.0, alpha: 0.9) // Data points
.animate(duration: Duration(milliseconds: 1000), curve: Curves.easeInOutCubic)
.build()
π Advanced Bar Charts


Vertical and horizontal bar charts with staggered animations
Stacked Bar Charts
// Perfect for budget breakdowns and composition analysis
CristalyseChart()
.data(revenueData)
.mapping(x: 'quarter', y: 'revenue', color: 'category')
.geomBar(
style: BarStyle.stacked, // Stack segments on top of each other
width: 0.8,
alpha: 0.9,
)
.scaleXOrdinal()
.scaleYContinuous(min: 0)
.theme(ChartTheme.defaultTheme())
.animate(duration: Duration(milliseconds: 1400))
.build()
Stacked bars with segment-by-segment progressive animation
Grouped Bar Charts
// Compare multiple series side-by-side
CristalyseChart()
.data(productData)
.mapping(x: 'quarter', y: 'revenue', color: 'product')
.geomBar(
style: BarStyle.grouped, // Place bars side-by-side
width: 0.8,
alpha: 0.9,
)
.scaleXOrdinal()
.scaleYContinuous(min: 0)
.theme(ChartTheme.defaultTheme())
.build()
Grouped bar charts for comparing multiple series side-by-side
Horizontal Bar Charts & Coordinate Flipping
Transform any vertical chart into horizontal with coordinate system flipping.
// Horizontal bars - perfect for long category names and rankings
final departmentData = [
{'department': 'Engineering', 'headcount': 45},
{'department': 'Product Management', 'headcount': 25},
{'department': 'Sales & Marketing', 'headcount': 35},
{'department': 'Customer Success', 'headcount': 20},
{'department': 'Human Resources', 'headcount': 15},
];
CristalyseChart()
.data(departmentData)
.mapping(x: 'department', y: 'headcount')
.geomBar(
borderRadius: BorderRadius.circular(4), // Rounded corners
borderWidth: 1.0, // Add borders
alpha: 0.8,
)
.coordFlip() // β¨ Flip to horizontal
.scaleXOrdinal()
.scaleYContinuous(min: 0)
.theme(ChartTheme.defaultTheme())
.build()
// Horizontal grouped bars for comparison
CristalyseChart()
.data(quarterlyData)
.mapping(x: 'quarter', y: 'revenue', color: 'region')
.geomBar(style: BarStyle.grouped)
.coordFlip() // Makes grouped bars horizontal
.legend(position: LegendPosition.bottomRight)
.build()
// Horizontal stacked bars for composition
CristalyseChart()
.data(budgetData)
.mapping(x: 'category', y: 'amount', color: 'subcategory')
.geomBar(style: BarStyle.stacked)
.coordFlip() // Horizontal stacked bars
.scaleYContinuous(
labels: NumberFormat.simpleCurrency().format,
)
.build()
// Horizontal scatter plot - useful for rank vs performance
CristalyseChart()
.data(performanceData)
.mapping(x: 'employee_name', y: 'performance_score', size: 'years_experience')
.geomPoint()
.coordFlip() // Names on Y-axis, scores on X-axis
.build()
Coordinate Flipping Features:
- β Universal Transformation - Works with all chart types (bars, points, lines)
- β Automatic Axis Swapping - X becomes Y, Y becomes X seamlessly
- β Label Readability - Perfect for long category names
- β Ranking Visualizations - Natural top-to-bottom ranking display
- β Legend Compatibility - Legends work perfectly with flipped coordinates
- β Animation Support - Smooth animations work in both orientations
π·οΈ Legends
Automatic legend generation from your color mappings with flexible positioning and styling.
// Automatic legend from color mapping
CristalyseChart()
.data(salesData)
.mapping(x: 'month', y: 'revenue', color: 'product') // Color mapping required
.geomBar()
.legend() // β¨ Auto-generates legend from 'product' categories
.build();
// Positioned legend with custom styling
CristalyseChart()
.data(revenueData)
.mapping(x: 'quarter', y: 'amount', color: 'category')
.geomBar(style: BarStyle.stacked)
.legend(
position: LegendPosition.right,
orientation: LegendOrientation.vertical,
backgroundColor: Colors.white.withOpacity(0.9),
textStyle: TextStyle(fontSize: 12, fontWeight: FontWeight.w500),
padding: EdgeInsets.all(12),
)
.build();
// Top horizontal legend for grouped bars
CristalyseChart()
.data(productData)
.mapping(x: 'quarter', y: 'revenue', color: 'product')
.geomBar(style: BarStyle.grouped)
.legend(
position: LegendPosition.topRight,
orientation: LegendOrientation.horizontal,
spacing: 16.0,
itemSpacing: 8.0,
)
.build();
Legend Features:
- β Auto-Generation - Automatically creates legends from color mappings
- β Flexible Positioning - Top, bottom, left, right, and corner positions
- β Custom Styling - Background, text style, padding, and spacing control
- β Smart Layouts - Automatic horizontal/vertical orientation based on position
- β Multi-Chart Support - Works with all chart types that use color mapping
- β Responsive Design - Adapts to container constraints
Legend Positions
// Available positions
LegendPosition.top
LegendPosition.bottom
LegendPosition.left
LegendPosition.right
LegendPosition.topLeft
LegendPosition.topRight
LegendPosition.bottomLeft
LegendPosition.bottomRight
π₯§ Pie Charts and Donut Charts
Perfect for part-to-whole relationships - visualize market share, revenue distribution, user demographics, and any categorical data where proportions matter.
Basic Pie Chart
// Revenue Distribution by Platform
CristalyseChart()
.data([
{'category': 'Mobile', 'revenue': 45.2},
{'category': 'Desktop', 'revenue': 32.8},
{'category': 'Tablet', 'revenue': 22.0},
])
.mappingPie(value: 'revenue', category: 'category')
.geomPie(
outerRadius: 120.0,
strokeWidth: 2.0,
strokeColor: Colors.white,
showLabels: true,
showPercentages: true,
)
.theme(ChartTheme.defaultTheme())
.animate(
duration: Duration(milliseconds: 1200),
curve: Curves.elasticOut,
)
.build()
Donut Charts
// User Analytics with Donut Visualization
CristalyseChart()
.data(userPlatformData)
.mappingPie(value: 'users', category: 'platform')
.geomPie(
innerRadius: 60.0, // Creates donut hole
outerRadius: 120.0,
strokeWidth: 3.0,
strokeColor: Colors.white,
showLabels: true,
showPercentages: false, // Show actual values
)
.theme(ChartTheme.darkTheme())
.animate(
duration: Duration(milliseconds: 1500),
curve: Curves.easeOutBack,
)
.build()
Advanced Pie Charts with Custom Styling
// Market Share Analysis with Exploded Slices
CristalyseChart()
.data(marketShareData)
.mappingPie(value: 'market_share', category: 'product')
.geomPie(
outerRadius: 150.0,
strokeWidth: 2.0,
strokeColor: Colors.white,
showLabels: true,
showPercentages: true,
explodeSlices: true, // Explode slices for emphasis
explodeDistance: 15.0,
labelRadius: 180.0, // Position labels further out
labelStyle: TextStyle(
fontSize: 12,
fontWeight: FontWeight.bold,
color: Colors.black87,
),
)
.theme(ChartTheme.solarizedLightTheme())
.build()
}
π₯ Heat Map Charts
Perfect for 2D data visualization - visualize correlations, performance matrices, time-based patterns, and any data with two categorical dimensions and a continuous value.
Business Performance Heat Map
// Sales Performance by Region and Month
CristalyseChart()
.data([
{'month': 'Jan', 'region': 'North', 'sales': 85},
{'month': 'Jan', 'region': 'South', 'sales': 62},
{'month': 'Feb', 'region': 'North', 'sales': 93},
{'month': 'Feb', 'region': 'South', 'sales': 78},
// ... more data
])
.mappingHeatMap(x: 'month', y: 'region', value: 'sales')
.geomHeatMap(
cellSpacing: 2.0,
cellBorderRadius: BorderRadius.circular(4),
colorGradient: [Colors.red, Colors.yellow, Colors.green],
interpolateColors: true,
showValues: true,
valueFormatter: (value) => '${value.toInt()}%',
)
.theme(ChartTheme.defaultTheme())
.animate(duration: Duration(milliseconds: 1500))
.build()
System Monitoring Heat Map
// Server Response Times by Hour and Service
CristalyseChart()
.data(metricsData)
.mappingHeatMap(x: 'hour', y: 'service', value: 'response_time')
.geomHeatMap(
minValue: 0,
maxValue: 100,
nullValueColor: Colors.grey.shade200,
cellAspectRatio: 1.0,
showValues: true,
valueTextStyle: TextStyle(
fontSize: 10,
fontWeight: FontWeight.bold,
),
)
.theme(ChartTheme.darkTheme())
.build()
Correlation Matrix
// Feature Correlation Analysis
CristalyseChart()
.data(correlationData)
.mappingHeatMap(x: 'variable1', y: 'variable2', value: 'correlation')
.geomHeatMap(
minValue: -1.0,
maxValue: 1.0,
colorGradient: [
Colors.blue.shade800, // Strong negative correlation
Colors.white, // No correlation
Colors.red.shade800, // Strong positive correlation
],
interpolateColors: true,
cellSpacing: 1.0,
showValues: true,
valueFormatter: (value) => value.toStringAsFixed(2),
)
.build()
π― Dual Y-Axis Charts
Perfect for business dashboards - correlate volume metrics with efficiency metrics on independent scales.
// Revenue vs Conversion Rate - The Classic Business Dashboard
CristalyseChart()
.data(businessData)
.mapping(x: 'month', y: 'revenue') // Primary Y-axis (left)
.mappingY2('conversion_rate') // Secondary Y-axis (right)
.geomBar(
yAxis: YAxis.primary, // Revenue bars use left axis
alpha: 0.7,
)
.geomLine(
yAxis: YAxis.secondary, // Conversion line uses right axis
strokeWidth: 3.0,
color: Colors.orange,
)
.geomPoint(
yAxis: YAxis.secondary, // Points on conversion line
size: 8.0,
color: Colors.orange,
)
.scaleXOrdinal()
.scaleYContinuous(min: 0) // Left axis: Revenue ($k)
.scaleY2Continuous(min: 0, max: 100) // Right axis: Percentage (%)
.theme(ChartTheme.defaultTheme())
.build()
Dual axis charts for correlating two different metrics on independent scales
More Dual Y-Axis Examples
// Sales Volume vs Customer Satisfaction
CristalyseChart()
.data(salesData)
.mapping(x: 'week', y: 'sales_volume')
.mappingY2('satisfaction_score')
.geomBar(yAxis: YAxis.primary) // Volume bars
.geomLine(yAxis: YAxis.secondary) // Satisfaction trend
.scaleY2Continuous(min: 1, max: 5) // Rating scale
.build();
// Website Traffic vs Bounce Rate
CristalyseChart()
.data(analyticsData)
.mapping(x: 'date', y: 'page_views')
.mappingY2('bounce_rate')
.geomArea(yAxis: YAxis.primary, alpha: 0.3) // Traffic area
.geomLine(yAxis: YAxis.secondary, strokeWidth: 2.0) // Bounce rate line
.scaleY2Continuous(min: 0, max: 100) // Percentage scale
.build();
π«§ Bubble Charts
Perfect for market analysis and multi-dimensional data - visualize three variables simultaneously with position and size encoding.
// Market Performance Analysis
CristalyseChart()
.data([
{'company': 'TechCorp', 'revenue': 250, 'customers': 180, 'marketShare': 28},
{'company': 'StartupX', 'revenue': 85, 'customers': 120, 'marketShare': 12},
{'company': 'MidSize', 'revenue': 150, 'customers': 160, 'marketShare': 18},
])
.mapping(
x: 'revenue', // Revenue on X-axis
y: 'customers', // Customer count on Y-axis
size: 'marketShare', // Market share determines bubble size
color: 'category' // Color by company category
)
.geomBubble(
minSize: 8.0, // Minimum bubble radius
maxSize: 25.0, // Maximum bubble radius
alpha: 0.7, // Semi-transparent bubbles
borderWidth: 2.0, // Border for definition
showLabels: true, // Show value labels
labelFormatter: (value) => '${value}%', // Custom label format
)
.scaleXContinuous()
.scaleYContinuous()
.theme(ChartTheme.defaultTheme())
.animate(duration: Duration(milliseconds: 1200))
.build()
Perfect for analyzing relationships between three continuous variables
Bubble Chart Features
- β Size Encoding - Third dimension mapped to bubble radius
- β Color Grouping - Categorical data with distinct colors
- β Custom Labels - Show formatted values on bubbles
- β Interactive Tooltips - Rich hover information
- β Dual Y-Axis Support - Use with secondary scales
- β Animation Support - Smooth entrance effects
π₯ Current Features
β Chart Types
- Scatter plots with size and color mapping
- Line charts with multi-series support and progressive drawing
- Area charts with smooth fills and multi-series transparency
- Bar charts (vertical, horizontal, grouped, stacked) with smooth animations
- Pie charts and donut charts with exploded slices and smart label positioning
- Heat map charts with customizable color gradients and 2D data visualization
- Bubble charts with 3D data visualization and size encoding
- Dual Y-axis charts for professional business dashboards
- Combined visualizations (bars + lines, points + lines, etc.)
β Advanced Features
- Grammar of Graphics API - Familiar ggplot2-style syntax
- Smooth 60fps animations with customizable timing and curves
- Dual Y-axis support with independent scales and data routing
- Multiple built-in themes (Light, Dark, Solarized Light/Dark)
- Custom color palettes for brand-specific category mapping
- Automatic legend generation with flexible positioning and styling
- Advanced label formatting with NumberFormat integration
- Interactive panning with real-time data streaming support
- Responsive scaling for all screen sizes
- High-DPI support for crisp visuals
β Data Handling
- Flexible data formats - List<Map<String, dynamic>>
- Mixed data types - Automatic type detection and conversion
- Missing value handling - Graceful degradation for null/invalid data
- Large dataset support - Optimized for 1000+ data points
- Real-time updates - Smooth transitions when data changes
- Multi-dimensional mapping - X, Y, size, color encoding simultaneously
πΈ Chart Export
Export your charts as professional-quality SVG vector graphics for reports, presentations, and documentation.
// Simple SVG export
final result = await chart.exportAsSvg(
width: 1200,
height: 800,
filename: 'sales_report',
);
print('Chart saved to: ${result.filePath}');
// Advanced configuration
final config = ExportConfig(
width: 1920,
height: 1080,
format: ExportFormat.svg,
filename: 'high_res_dashboard',
);
final result = await chart.export(config);
SVG Export Features:
- β Scalable Vector Graphics - Infinite zoom without quality loss
- β Professional Quality - Perfect for presentations and reports
- β Small File Sizes - Efficient for web and print
- β Design Software Compatible - Editable in Figma, Adobe Illustrator, etc.
- β Cross-Platform Reliable - Works consistently on all platforms
- β Automatic File Management - Saves to Documents directory with timestamp
π― Real-World Examples
Sales Dashboard
Widget buildRevenueTrend() {
return CristalyseChart()
.data(monthlyRevenue)
.mapping(x: 'month', y: 'revenue', color: 'product_line')
.geomLine(strokeWidth: 3.0)
.geomPoint(size: 5.0)
.scaleXContinuous()
.scaleYContinuous(min: 0)
.theme(ChartTheme.solarizedDarkTheme()) // Use Solarized Dark theme
.animate(duration: Duration(milliseconds: 1500))
.build();
}
User Analytics
Widget buildEngagementScatter() {
return CristalyseChart()
.data(userMetrics)
.mapping(x: 'session_length', y: 'pages_viewed',
color: 'user_type', size: 'revenue')
.geomPoint(alpha: 0.6)
.scaleXContinuous()
.scaleYContinuous()
.theme(isDarkMode ? ChartTheme.darkTheme() : ChartTheme.defaultTheme())
.animate(duration: Duration(milliseconds: 800), curve: Curves.elasticOut)
.build();
}
Market Share Analysis
Widget buildMarketSharePie() {
return CristalyseChart()
.data(marketData)
.mappingPie(value: 'market_share', category: 'product')
.geomPie(
outerRadius: 140.0,
strokeWidth: 3.0,
strokeColor: Colors.white,
showLabels: true,
showPercentages: true,
explodeSlices: true, // Emphasize key segments
explodeDistance: 12.0,
labelStyle: TextStyle(
fontSize: 11,
fontWeight: FontWeight.w600,
),
)
.theme(ChartTheme.defaultTheme())
.animate(duration: Duration(milliseconds: 1200), curve: Curves.elasticOut)
.build();
}
Business Intelligence Dashboard
// Revenue bars + profit margin line on dual Y-axis
CristalyseChart()
.data(kpiData)
.mapping(x: 'quarter', y: 'revenue')
.mappingY2('profit_margin')
.geomBar(yAxis: YAxis.primary, style: BarStyle.stacked)
.geomLine(yAxis: YAxis.secondary, color: Colors.green)
.scaleYContinuous(labels: NumberFormat.simpleCurrency().format)
.scaleY2Continuous(labels: (v) => '${v.toStringAsFixed(1)}%')
.legend()
.build();
Advanced Multi-Geometry Dashboard
// Combined area + line + bubbles with dual Y-axis
CristalyseChart()
.data(performanceData)
.mapping(x: 'month', y: 'revenue', size: 'team_size', color: 'department')
.mappingY2('efficiency')
.geomArea(yAxis: YAxis.primary, alpha: 0.2)
.geomLine(yAxis: YAxis.primary, strokeWidth: 3.0)
.geomBubble(yAxis: YAxis.primary, minSize: 5.0, maxSize: 15.0)
.geomLine(yAxis: YAxis.secondary, color: Colors.orange)
.scaleYContinuous(labels: NumberFormat.compact().format)
.scaleY2Continuous(labels: (v) => '${v.round()}%')
.legend()
.interaction(pan: PanConfig(enabled: true))
.build();
π‘ Why Not Just Use...?
Alternative | Why Cristalyse is Better |
---|---|
fl_chart | Grammar of graphics API vs basic chart widgets. Dual Y-axis support vs single axis limitation. |
charts_flutter | Active development vs deprecated. Stacked bars and advanced features vs basic charts. |
Web charts (plotly.js) | Native performance vs DOM rendering. True mobile deployment vs responsive web. |
Platform-specific charts | Write once vs write 3x for iOS/Android/Web. Consistent UX vs platform differences. |
Business tools (Tableau) | Embedded in your app vs separate tools. Full customization vs template limitations. |
π Advanced Configuration
Animation Control
chart.animate(
duration: Duration(milliseconds: 1200),
curve: Curves.elasticOut, // Try different curves!
)
Custom Themes
Complete visual control with built-in themes and full customization options.
// Built-in themes
CristalyseChart()
.data(data)
.mapping(x: 'month', y: 'revenue')
.geomLine()
.theme(ChartTheme.darkTheme()) // or .defaultTheme(), .solarizedLightTheme()
.build();
// Custom branded theme
final brandedTheme = ChartTheme(
primaryColor: const Color(0xFF007BFF), // Brand primary
colorPalette: [Colors.blue, Colors.green, Colors.red],
axisTextStyle: const TextStyle(fontSize: 12, fontWeight: FontWeight.w500),
);
CristalyseChart()
.theme(brandedTheme)
.build();
Theme Features:
- β Built-in Themes - Light, dark, and Solarized variants ready to use
- β Brand Customization - Match your organization's visual identity
- β Responsive Design - Adapt themes based on screen size
- β Color Palettes - Comprehensive color schemes for multi-series charts
- β Typography Control - Custom fonts, sizes, and weights
- β Layout Options - Padding, spacing, and dimension control
Custom Color Palettes
Brand-specific colors for categories with semantic meaning and consistent visual identity.
// Platform-specific colors
final platformColors = {
'iOS': const Color(0xFF007AFF),
'Android': const Color(0xFF3DDC84),
'Web': const Color(0xFFFF6B35),
};
CristalyseChart()
.data(appAnalyticsData)
.mapping(x: 'month', y: 'users', color: 'platform')
.geomLine()
.customPalette(categoryColors: platformColors)
.build();
Custom Palette Features:
- β Brand Consistency - Use your organization's exact brand colors
- β Semantic Colors - Map status, priority, or meaning to colors
- β Category Override - Specific colors for individual categories
- β Fallback Support - Unmapped categories use theme colors
- β Legend Integration - Custom colors appear in auto-generated legends
Advanced Label Formatting
Professional number formatting with NumberFormat integration and custom callbacks.
import 'package:intl/intl.dart';
// Currency formatting
.scaleYContinuous(labels: NumberFormat.simpleCurrency().format) // $1,234.56
// Compact notation
.scaleYContinuous(labels: NumberFormat.compact().format) // 1.2M, 5.6K
// Custom formatting
.scaleYContinuous(labels: (value) => '${value.toStringAsFixed(1)}Β°C') // 23.5Β°C
Label Formatting Features:
- β NumberFormat Integration - Built-in currency, percentage, and compact formatting
- β Custom Callbacks - Full control over label appearance and logic
- β Locale Support - Automatic localization based on device settings
- β Multi-Chart Support - Works with all chart types (axes, pie slices, bubbles)
- β Performance Optimized - Efficient formatting without UI blocking
- β Unit Flexibility - Easy addition of units, symbols, and custom text
Advanced Data Mapping
// Map any data structure
chart
.data(complexData)
.mapping(
x: 'timestamp', // Time series
y: 'metric_value', // Numeric values
color: 'category', // Color grouping
size: 'importance' // Size encoding
)
.mappingY2('efficiency') // Secondary Y-axis for dual charts
Stacked Bar Configuration
chart
.data(budgetData)
.mapping(x: 'department', y: 'amount', color: 'category')
.geomBar(
style: BarStyle.stacked, // Stack segments
width: 0.8, // Bar width
borderRadius: BorderRadius.circular(4), // Rounded corners
alpha: 0.9, // Transparency
)
.scaleXOrdinal()
.scaleYContinuous(min: 0)
π± Platform Support
- β iOS 12+
- β Android API 21+
- β Web (Chrome 80+, Firefox, Safari)
- β Windows 10+
- β macOS 10.14+
- β Linux (Ubuntu 18.04+)
π§ͺ Development Status
Current Version: 1.8.0 - Production ready with intelligent axis bounds & labeling, automatic legend generation, and professional styling
We're shipping progressively! Each release adds new visualization types while maintaining backward compatibility.
- β v0.1.0 - Scatter plots and basic theming
- β v0.2.0 - Line charts and animations
- β v0.3.0 - Bar charts (including horizontal) and areas
- β v0.4.0 - Enhanced theming with custom colors and text styles, stacked bars
- β v0.5.0 - Dual Y-axis support and advanced bar chart variations
- β v0.6.0 - Interactive tooltips
- β v0.7.0 - Interactive panning
- β v0.8.0 - Area chart support with animations and multi-series capabilities
- β v0.9.0 - Enhanced dual Y-axis SVG export with comprehensive scale support
- β v1.0.0 - Pie charts and donut charts with exploded slices and smart label positioning
- β v1.1.0 - Advanced label formatting system with NumberFormat integration (by @davidlrichmond)
- β v1.2.0 - Heat map charts with 2D data visualization and customizable color gradients
- β v1.3.0 - Bubble charts with 3D data visualization and professional size encoding
- β v1.4.0 - Custom color palettes for brand-specific category mapping
- β v1.5.0 - Automatic legend generation with flexible positioning and styling
- β v1.6.0 - Experimental gradient color support for customPalette with Linear, Radial, and Sweep gradients
- β v1.7.0 - Progress bar charts with horizontal, vertical, circular, stacked, grouped, gauge, and concentric styles + comprehensive documentation improvements
- β v1.8.0 - Intelligent axis bounds & labeling with Wilkinson Extended algorithm (by @davidlrichmond) - professional round-number ticks, geometry-aware defaults, comprehensive testing
Support This Project
Love Cristalyse? Your support helps me dedicate more time to building the Flutter charting library you deserve!
Why Sponsor?
- Faster Development - More features, bug fixes, and improvements
- Better Documentation - Comprehensive guides and examples
- Priority Support - Get your issues and feature requests prioritized
- New Chart Types - Help fund development of advanced visualizations
- Platform Support - Ensure continued cross-platform compatibility
What Your Support Enables
Active Development - Cristalyse is passion project that requires significant time investment
Advanced Features - Complex chart types like treemaps, sankey diagrams, and statistical overlays
Bug Fixes & Performance - Rapid responses to issues and continuous optimization
Documentation & Examples - Real-world examples and comprehensive tutorials
Community Building - Discord server, workshops, and educational content
Every contribution, no matter the size, makes a real difference!
π€ Contributing
We'd love your help! Check out our contributing guide and:
- π Report bugs
- π‘ Suggest features
- π Improve documentation
- π§ Submit pull requests
π License
MIT License - build whatever you want, commercially or otherwise.
π Links
- π¦ pub.flutter-io.cn package
- π Full documentation
- π Issue tracker
- π¬ Discussions
Ready to create stunning visualizations? flutter pub add cristalyse
and start building! π
Cristalyse: Finally, the grammar of graphics library Flutter developers deserve.