Skip to content

rudi-q/cristalyse

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

50 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Cristalyse

The grammar of graphics visualization library that Flutter developers have been waiting for.

pub package pub points likes Platform Flutter support Dart support License: MIT

Finally, create beautiful data visualizations in Flutter without fighting against chart widgets or settling for web-based solutions.


Cristalyse Documentation

Visit our complete documentation for step-by-step guides, interactive examples,
and everything you need to master data visualization in Flutter.

Read Documentation Β Β  Quick Start Guide

View Examples Β Β  View Source Code

Visit Website

Cristalyse Documentation Screenshot
Comprehensive guides, examples, and API reference


✨ 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
  • πŸ‘† Interactive Charts - Engage users with tooltips, hover effects, and click events.

See What You Can Build

Animated Scatter Plot
Interactive scatter plots with smooth animations and multi-dimensional data mapping

Progressive Line Chart
Progressive line drawing with customizable themes and multi-series support

🎯 Perfect For

  • Flutter developers building data-driven apps who need more than basic chart widgets
  • Data scientists who want to deploy interactive visualizations to mobile without learning Swift/Kotlin
  • Enterprise teams building dashboards that need consistent UX across all platforms
  • Business analysts creating professional reports with dual Y-axis charts and advanced visualizations

Cristalyse Chart Showcase
Build stunning, interactive charts with the power of grammar of graphics

πŸš€ 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.

Simple Scatter Plot
Your first chart - clean, responsive, and cross-platform

πŸ’‘ Interactive Charts

New: Enhanced Panning Behavior

Add real-time panning capabilities to your charts with seamless range updates and smooth interaction.

CristalyseChart()
  .data(myData)
  .mapping(x: 'x', y: 'y')
  .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}');
      },
    ),
  )
  .build();

Features:

  • Maintains pan state across interactions
  • Synchronizes displayed range between header and chart axis
  • Enhanced UI for range display card

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

Animated Bar Chart Horizontal Bar Chart
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 Bar Chart
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 Chart
Grouped bar charts for comparing multiple series side-by-side

Horizontal Bar Charts

// Great for ranking and long category names
CristalyseChart()
  .data(departmentData)
  .mapping(x: 'department', y: 'headcount')
  .geomBar(
    borderRadius: BorderRadius.circular(4), // Rounded corners
    borderWidth: 1.0,                       // Add borders
  )
  .coordFlip()                              // Flip to horizontal
  .scaleXOrdinal()
  .scaleYContinuous(min: 0)
  .theme(ChartTheme.defaultTheme())
  .build()

πŸ₯§ 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()

🎯 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 Chart
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();

πŸ”₯ 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
  • 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
  • Coordinate flipping for horizontal charts
  • Multiple themes (Light, Dark, Solarized Light/Dark)
  • Custom color palettes and styling options
  • 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

πŸ“Έ 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

🚧 Coming Soon (Next Releases)

  • Statistical overlays (regression lines, confidence intervals)
  • Interactive zoom capabilities with scale persistence
  • Faceting for small multiples and grid layouts
  • Enhanced SVG export with full chart rendering

🎯 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

Widget buildKPIDashboard() {
  return CristalyseChart()
      .data(kpiData)
      .mapping(x: 'quarter', y: 'revenue')
      .mappingY2('profit_margin')             // Dual Y-axis for percentage
      .geomBar(
        yAxis: YAxis.primary,
        style: BarStyle.stacked,              // Stack revenue components
        color: 'revenue_source',
      )
      .geomLine(
        yAxis: YAxis.secondary,               // Profit margin trend
        strokeWidth: 4.0,
        color: Colors.green,
      )
      .scaleXOrdinal()
      .scaleYContinuous(min: 0)               // Revenue scale
      .scaleY2Continuous(min: 0, max: 50)     // Percentage scale
      .theme(ChartTheme.defaultTheme())
      .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

Custom Themes

final customTheme = ChartTheme(
  backgroundColor: Colors.grey[50]!,
  primaryColor: Colors.deepPurple,
  colorPalette: [Colors.blue, Colors.red, Colors.green],
  gridColor: Colors.grey[300]!,
  axisTextStyle: TextStyle(fontSize: 14, color: Colors.black87),
  padding: EdgeInsets.all(40),
);

chart.theme(customTheme)

Animation Control

chart.animate(
  duration: Duration(milliseconds: 1200),
  curve: Curves.elasticOut,  // Try different curves!
)

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.0.0 - Production ready with enhanced dual Y-axis SVG export and comprehensive interactive capabilities

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

🀝 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


Ready to create stunning visualizations? flutter pub add cristalyse and start building! πŸš€

Cristalyse: Finally, the grammar of graphics library Flutter developers deserve.