{"id":32299730,"url":"https://github.com/rudi-q/cristalyse","last_synced_at":"2026-02-19T21:53:01.449Z","repository":{"id":297937445,"uuid":"998280760","full_name":"rudi-q/cristalyse","owner":"rudi-q","description":"High-performance data visualization library for Flutter with native rendering and cross-platform support","archived":false,"fork":false,"pushed_at":"2026-02-16T14:04:42.000Z","size":22160,"stargazers_count":63,"open_issues_count":6,"forks_count":6,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-02-16T21:44:34.913Z","etag":null,"topics":["bar-chart","business-intelligence","charts","dart","dashboard","data-visualization","dual-axis","flutter","ggplot2","grammar-of-graphics","heatmap","interactive-charts","line-chart","native-rendering","pie-chart","plotting","scatter-plot","stacked-bars"],"latest_commit_sha":null,"homepage":"https://docs.cristalyse.com","language":"Dart","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rudi-q.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"github":"rudi-q"}},"created_at":"2025-06-08T09:12:11.000Z","updated_at":"2026-02-10T11:01:53.000Z","dependencies_parsed_at":"2025-06-08T13:31:09.399Z","dependency_job_id":"f5126a1c-b2cd-4d3f-89cc-a9f491527419","html_url":"https://github.com/rudi-q/cristalyse","commit_stats":null,"previous_names":["rudi-q/cristalyse"],"tags_count":14,"template":false,"template_full_name":null,"purl":"pkg:github/rudi-q/cristalyse","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rudi-q%2Fcristalyse","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rudi-q%2Fcristalyse/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rudi-q%2Fcristalyse/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rudi-q%2Fcristalyse/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rudi-q","download_url":"https://codeload.github.com/rudi-q/cristalyse/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rudi-q%2Fcristalyse/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29634417,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-19T18:02:07.722Z","status":"ssl_error","status_checked_at":"2026-02-19T18:01:46.144Z","response_time":117,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bar-chart","business-intelligence","charts","dart","dashboard","data-visualization","dual-axis","flutter","ggplot2","grammar-of-graphics","heatmap","interactive-charts","line-chart","native-rendering","pie-chart","plotting","scatter-plot","stacked-bars"],"created_at":"2025-10-23T05:04:04.875Z","updated_at":"2026-02-19T21:53:01.443Z","avatar_url":"https://github.com/rudi-q.png","language":"Dart","funding_links":["https://github.com/sponsors/rudi-q"],"categories":[],"sub_categories":[],"readme":"\u003cp\u003e\n  \u003ca href=\"https://docs.cristalyse.com\"\u003e\n    \u003cimg src=\"doc/logo/logo.svg\" alt=\"Cristalyse\" width=\"400\"/\u003e\n  \u003c/a\u003e\n  \u003cspan\u003e\n    \u003ca href=\"https://github.com/sponsors/rudi-q\" style=\"float:right; margin-right: 300px\"\u003e\n      \u003cimg src=\"https://img.shields.io/badge/Sponsor_on-GitHub-2cacbf?style=for-the-badge\u0026logo=githubsponsors\u0026logoColor=white\u0026labelColor=145261\" alt=\"Sponsor on GitHub\" style=\"border-radius: 8px;\"/\u003e\n    \u003c/a\u003e\n  \u003c/span\u003e\n\n**The grammar of graphics visualization library that Flutter developers have been waiting for.**\n\u003c/p\u003e\n\n\n[![Flutter support](https://img.shields.io/badge/Flutter-3.13%2B-2cacbf?logo=flutter\u0026logoColor=white\u0026labelColor=145261)](https://flutter.dev/)\n[![Dart support](https://img.shields.io/badge/Dart-3.3.0%2B-2cacbf?logo=dart\u0026logoColor=white\u0026labelColor=145261)](https://dart.dev/)\n[![pub package](https://img.shields.io/pub/v/cristalyse.svg?color=2cacbf\u0026labelColor=145261)](https://pub.dev/packages/cristalyse)\n[![pub points](https://img.shields.io/pub/points/cristalyse?color=2cacbf\u0026labelColor=145261)](https://pub.dev/packages/cristalyse/score)\n[![likes](https://img.shields.io/pub/likes/cristalyse?color=2cacbf\u0026labelColor=145261)](https://pub.dev/packages/cristalyse/score)\n[![Pub Downloads](https://img.shields.io/pub/dm/cristalyse?color=2cacbf\u0026labelColor=145261)](https://pub.dev/packages/cristalyse/score)\n[![License: MIT](https://img.shields.io/badge/License-MIT-2cacbf.svg?labelColor=145261)](https://opensource.org/licenses/MIT)\n\n[![Web](https://img.shields.io/badge/Web-145261?logo=google-chrome\u0026logoColor=white)](https://flutter.dev/)\n[![WASM](https://img.shields.io/badge/Web_Assembly_(WASM)-145261?logo=webassembly\u0026logoColor=white)](https://flutter.dev/)\n[![Windows](https://img.shields.io/badge/Windows-145261?logo=Windows\u0026logoColor=white)](https://flutter.dev/)\n[![macOS](https://img.shields.io/badge/macOS-145261?logo=apple\u0026logoColor=white)](https://flutter.dev/)\n[![Linux](https://img.shields.io/badge/Linux-145261?logo=linux\u0026logoColor=white)](https://flutter.dev/)\n[![Android](https://img.shields.io/badge/Android-145261?logo=android\u0026logoColor=white)](https://flutter.dev/)\n[![iOS](https://img.shields.io/badge/iOS-145261?logo=ios\u0026logoStyle=bold\u0026logoColor=white)](https://flutter.dev/)\n\n[![Claude Code support](https://img.shields.io/badge/Claude-MCP_Client-2cacbf?logo=claude\u0026logoColor=white\u0026labelColor=145261)](https://docs.cristalyse.com/cristalyse-mcp-server#claude-code-cli)\n[![Windsurf support](https://img.shields.io/badge/Windsurf-MCP_Client-2cacbf?logo=windsurf\u0026logoColor=white\u0026labelColor=145261)](https://docs.cristalyse.com/cristalyse-mcp-server#ai-code-editor-cursor%2C-windsurf%2C-warp)\n[![CoPilot support](https://img.shields.io/badge/Co_Pilot-MCP_Client-2cacbf?logo=githubcopilot\u0026logoColor=white\u0026labelColor=145261)](https://docs.cristalyse.com/cristalyse-mcp-server#ai-code-editor-cursor%2C-windsurf%2C-warp)\n[![Warp support](https://img.shields.io/badge/Warp-MCP_Client-2cacbf?logo=warp\u0026logoColor=white\u0026labelColor=145261)](https://docs.cristalyse.com/cristalyse-mcp-server#ai-code-editor-cursor%2C-windsurf%2C-warp)\n\n\u003e Finally, create beautiful data visualizations in Flutter without fighting against chart widgets or settling for web-based solutions.\n\n---\n\n\u003ctable\u003e\n\u003ctr\u003e\n\u003ctd width=\"45%\"\u003e\n\n\u003cp align=\"center\" style=\"padding-left: 5em;\"\u003e\n  \u003ca href=\"https://docs.cristalyse.com\"\u003e\n    \u003cimg src=\"doc/logo/dark.svg\" alt=\"Cristalyse Documentation\" width=\"400\"/\u003e\n  \u003c/a\u003e\n\u003c/p\u003e\n\n\u003cp\u003e\n  \u003cstrong\u003eVisit our complete documentation for step-by-step guides, interactive examples,\u003cbr/\u003eand everything you need to master data visualization in Flutter.\u003c/strong\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://docs.cristalyse.com\"\u003e\n    \u003cimg src=\"https://img.shields.io/badge/Read_Docs-2D3748?style=for-the-badge\u0026logo=mintlify\u0026logoColor=white\u0026labelColor=2D3748\" alt=\"Read Documentation\"/\u003e\n  \u003c/a\u003e\n  \u0026nbsp;\u0026nbsp;\n  \u003ca href=\"https://docs.cristalyse.com/quickstart\"\u003e\n    \u003cimg src=\"https://img.shields.io/badge/Quick_Start-4A5568?style=for-the-badge\u0026logo=gnometerminal\u0026logoColor=white\u0026labelColor=4A5568\" alt=\"Quick Start Guide\"/\u003e\n  \u003c/a\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://docs.cristalyse.com/examples\"\u003e\n    \u003cimg src=\"https://img.shields.io/badge/Examples-718096?style=for-the-badge\u0026logo=vercel\u0026logoColor=white\u0026labelColor=718096\" alt=\"View Examples\"/\u003e\n  \u003c/a\u003e\n  \u0026nbsp;\u0026nbsp;\n  \u003ca href=\"https://github.com/rudi-q/cristalyse\"\u003e\n    \u003cimg src=\"https://img.shields.io/badge/View_Source-8B9DC3?style=for-the-badge\u0026logo=refinedgithub\u0026logoColor=white\u0026labelColor=8B9DC3\" alt=\"View Source Code\"/\u003e\n  \u003c/a\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://cristalyse.com\"\u003e\n    \u003cimg src=\"https://img.shields.io/badge/Visit_Website-A0AEC0?style=for-the-badge\u0026logo=astro\u0026logoColor=white\u0026labelColor=A0AEC0\" alt=\"Visit Website\"/\u003e\n  \u003c/a\u003e\n\u003c/p\u003e\n\n\u003c/td\u003e\n\u003ctd width=\"55%\"\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://docs.cristalyse.com\"\u003e\n    \u003cimg src=\"doc/images/documentation.png\" alt=\"Cristalyse Documentation Screenshot\" width=\"70%\"/\u003e\n  \u003c/a\u003e\n  \u003cbr/\u003e\n  \u003cem\u003eComprehensive guides, examples, and API reference\u003c/em\u003e\n\u003c/p\u003e\n\n\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/table\u003e\n\n---\n\n## 🤖 AI-Powered Development\n\n**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.\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://docs.cristalyse.com/cristalyse-mcp-server\"\u003e\n    \u003cimg src=\"https://img.shields.io/badge/Cristalyse_MCP-Setup_Guide-2cacbf?style=for-the-badge\u0026logo=modelcontextprotocol\u0026logoColor=white\u0026labelColor=145261\" alt=\"Cristalyse MCP Setup Guide\" style=\"border-radius: 8px;\"/\u003e\n  \u003c/a\u003e\n\u003c/p\u003e\n\n---\n\n## ✨ Why Cristalyse?\n\n**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.\n\n- 🎨 **Grammar of Graphics API** - Familiar syntax if you've used ggplot2 or plotly\n- 🚀 **Native 60fps Animations** - Leverages Flutter's rendering engine, not DOM manipulation\n- 📱 **True Cross-Platform** - One codebase → Mobile, Web, Desktop, all looking identical\n- ⚡ **GPU-Accelerated Performance** - Handle large datasets without breaking a sweat\n- 🎯 **Flutter-First Design** - Seamlessly integrates with your existing Flutter apps\n- 📊 **Dual Y-Axis Support** - Professional business dashboards with independent left/right scales\n- 📈 **Advanced Bar Charts** - Grouped, stacked, and horizontal variations with smooth animations\n- 🫧 **Bubble Charts** - Multi-dimensional data visualization with size, color, and position encoding\n- 👆 **Interactive Charts** - Engage users with tooltips, hover effects, and click events.\n\n### See What You Can Build\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"example/screenshots/cristalyse_scatter_plot.gif\" alt=\"Animated Scatter Plot\" width=\"600\"/\u003e\n  \u003cbr/\u003e\n  \u003cem\u003eInteractive scatter plots with smooth animations and multi-dimensional data mapping\u003c/em\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"example/screenshots/cristalyse_line_chart.gif\" alt=\"Progressive Line Chart\" width=\"600\"/\u003e\n  \u003cbr/\u003e\n  \u003cem\u003eProgressive line drawing with customizable themes and multi-series support\u003c/em\u003e\n\u003c/p\u003e\n\n\u003ctable\u003e\n\u003ctr\u003e\n\u003ctd width=\"50%\"\u003e\n\n## 🎯 Perfect For\n\n- **Flutter developers** building data-driven apps who need more than basic chart widgets\n- **Data scientists** who want to deploy interactive visualizations to mobile without learning Swift/Kotlin\n- **Enterprise teams** building dashboards that need consistent UX across all platforms\n- **Business analysts** creating professional reports with dual Y-axis charts and advanced visualizations\n- **Product managers** tracking performance metrics across multiple dimensions with bubble charts\n\n\u003c/td\u003e\n\u003ctd width=\"50%\"\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"doc/images/hero-dark.png\" alt=\"Cristalyse Chart Showcase\" width=\"400\"/\u003e\n  \u003cbr/\u003e\n  \u003cem\u003eBuild stunning, interactive charts with the power of grammar of graphics\u003c/em\u003e\n\u003c/p\u003e\n\n\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/table\u003e\n\n## 🚀 Quick Start\n\n### Installation\n\n```bash\nflutter pub add cristalyse\n```\n\nThat's it! No complex setup, no additional configuration.\n\n### Your First Chart (30 seconds)\n\n```dart\nimport 'package:cristalyse/cristalyse.dart';\nimport 'package:flutter/material.dart';\n\nclass MyChart extends StatelessWidget {\n  @override\n  Widget build(BuildContext context) {\n    final data = [\n      {'x': 1, 'y': 2, 'category': 'A'},\n      {'x': 2, 'y': 3, 'category': 'B'},\n      {'x': 3, 'y': 1, 'category': 'A'},\n      {'x': 4, 'y': 4, 'category': 'C'},\n    ];\n\n    return CristalyseChart()\n      .data(data)\n      .mapping(x: 'x', y: 'y', color: 'category')\n      .geomPoint(\n        size: 8.0, // Made points a bit larger to see border clearly\n        alpha: 0.8,\n        shape: PointShape.triangle, // Example: use triangles\n        borderWidth: 1.5,           // Example: add a border to points\n      )\n      .scaleXContinuous()\n      .scaleYContinuous()\n      .theme(ChartTheme.defaultTheme())\n      .build();\n  }\n}\n```\n\n**Result:** A beautiful, animated scatter plot that works identically on iOS, Android, Web, and Desktop.\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"example/screenshots/cristalyse_scatter_plot.png\" alt=\"Simple Scatter Plot\" width=\"600\"/\u003e\n  \u003cbr/\u003e\n  \u003cem\u003eYour first chart - clean, responsive, and cross-platform\u003c/em\u003e\n\u003c/p\u003e\n\n## 💡 Interactive Charts\n\n### Enhanced Panning Behavior\n\n**Real-time data streaming and interactive exploration** with advanced pan controls and coordinate transformation.\n\n```dart\n// Basic panning with range callbacks\nCristalyseChart()\n  .data(timeSeriesData)\n  .mapping(x: 'timestamp', y: 'value')\n  .geomLine()\n  .interaction(\n    pan: PanConfig(\n      enabled: true,\n      onPanUpdate: (info) {\n        // Handle real-time updates based on visible X range\n        print('Visible X range: ${info.visibleMinX} - ${info.visibleMaxX}');\n        \n        // Load more data when approaching boundaries\n        if (info.visibleMaxX! \u003e maxDataTimestamp - bufferTime) {\n          loadMoreRecentData();\n        }\n      },\n      throttle: Duration(milliseconds: 100), // Prevent overwhelming callbacks\n    ),\n  )\n  .build();\n\n// Advanced panning with state management\nclass PanningChartState extends State\u003cPanningChart\u003e {\n  DateTime? visibleStart;\n  DateTime? visibleEnd;\n  \n  @override\n  Widget build(BuildContext context) {\n    return Column([\n      // Range display header\n      Container(\n        padding: EdgeInsets.all(8),\n        child: Text(\n          visibleStart != null \n            ? 'Range: ${DateFormat('MMM d').format(visibleStart!)} - ${DateFormat('MMM d').format(visibleEnd!)}'\n            : 'Loading...',\n        ),\n      ),\n      \n      // Interactive chart\n      Expanded(\n        child: CristalyseChart()\n          .data(chartData)\n          .mapping(x: 'date', y: 'revenue')\n          .geomLine()\n          .onPan((info) {\n            setState(() {\n              visibleStart = DateTime.fromMillisecondsSinceEpoch(\n                (info.visibleMinX! * 1000).round()\n              );\n              visibleEnd = DateTime.fromMillisecondsSinceEpoch(\n                (info.visibleMaxX! * 1000).round()\n              );\n            });\n            \n            // Fetch data for new range\n            fetchDataForDateRange(visibleStart!, visibleEnd!);\n          })\n          .build(),\n      ),\n    ]);\n  }\n}\n```\n\n**Panning Features:**\n- ✅ **Coordinate Transformation** - Screen pixels to data values automatically\n- ✅ **Throttled Callbacks** - Configurable update frequency for performance\n- ✅ **Range State Persistence** - Maintains pan position across interactions\n- ✅ **Real-time Data Loading** - Perfect for streaming and large datasets\n- ✅ **Multi-axis Support** - Independent X and Y panning controls\n- ✅ **Touch \u0026 Mouse Compatible** - Works on all platforms\n\nBring 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.\n\n```dart\n// Add tooltips and click handlers\nCristalyseChart()\n  .data(salesData)\n  .mapping(x: 'week', y: 'revenue', color: 'rep')\n  .geomPoint(size: 8.0)\n  .interaction(\n    tooltip: TooltipConfig(\n      builder: (point) {\n        // Build a custom widget for the tooltip\n        final category = point.getDisplayValue('rep');\n        final value = point.getDisplayValue('revenue');\n        return Container(\n          padding: const EdgeInsets.all(8),\n          decoration: BoxDecoration(\n            color: Colors.black.withOpacity(0.8),\n            borderRadius: BorderRadius.circular(4),\n          ),\n          child: Text(\n            '$category: \\$$value k',\n            style: const TextStyle(color: Colors.white, fontSize: 12),\n          ),\n        );\n      },\n    ),\n    click: ClickConfig(\n      onTap: (point) {\n        // Handle tap event, e.g., show a dialog\n        print('Tapped on: ${point.data}');\n      },\n    ),\n  )\n  .build();\n```\n\n## 🎬 See It In Action\n\n### Animated Scatter Plot\n```dart\nCristalyseChart()\n  .data(salesData)\n  .mapping(x: 'date', y: 'revenue', color: 'region', size: 'deals')\n  .geomPoint(alpha: 0.7)\n  .animate(duration: Duration(milliseconds: 800), curve: Curves.elasticOut)\n  .theme(ChartTheme.defaultTheme())\n  .build()\n```\n\n### Multi-Series Line Chart\n```dart\nCristalyseChart()\n  .data(timeSeriesData)\n  .mapping(x: 'month', y: 'users', color: 'platform')\n  .geomLine(strokeWidth: 3.0)\n  .geomPoint(size: 4.0)\n  .animate(duration: Duration(milliseconds: 1200))\n  .theme(ChartTheme.darkTheme())\n  .build()\n```\n\n### Combined Visualizations\n```dart\nCristalyseChart()\n  .data(analyticsData)\n  .mapping(x: 'week', y: 'engagement')\n  .geomLine(strokeWidth: 2.0, alpha: 0.8)      // Trend line\n  .geomPoint(size: 5.0, alpha: 0.9)            // Data points\n  .animate(duration: Duration(milliseconds: 1000), curve: Curves.easeInOutCubic)\n  .build()\n```\n\n## 📊 Advanced Bar Charts\n\n\u003cdiv align=\"center\"\u003e\n  \u003cimg src=\"example/screenshots/cristalyse_bar_chart.gif\" alt=\"Animated Bar Chart\" width=\"400\"/\u003e\n  \u003cimg src=\"example/screenshots/cristalyse_horizontal_bar_chart.gif\" alt=\"Horizontal Bar Chart\" width=\"400\"/\u003e\n  \u003cbr/\u003e\n  \u003cem\u003eVertical and horizontal bar charts with staggered animations\u003c/em\u003e\n\u003c/div\u003e\n\n### Stacked Bar Charts\n```dart\n// Perfect for budget breakdowns and composition analysis\nCristalyseChart()\n  .data(revenueData)\n  .mapping(x: 'quarter', y: 'revenue', color: 'category')\n  .geomBar(\n    style: BarStyle.stacked,     // Stack segments on top of each other\n    width: 0.8,\n    alpha: 0.9,\n  )\n  .scaleXOrdinal()\n  .scaleYContinuous(min: 0)\n  .theme(ChartTheme.defaultTheme())\n  .animate(duration: Duration(milliseconds: 1400))\n  .build()\n```\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"example/screenshots/cristalyse_stacked_bar_chart.gif\" alt=\"Stacked Bar Chart\" width=\"600\"/\u003e\n  \u003cbr/\u003e\n  \u003cem\u003eStacked bars with segment-by-segment progressive animation\u003c/em\u003e\n\u003c/p\u003e\n\n### Grouped Bar Charts\n```dart\n// Compare multiple series side-by-side\nCristalyseChart()\n  .data(productData)\n  .mapping(x: 'quarter', y: 'revenue', color: 'product')\n  .geomBar(\n    style: BarStyle.grouped,     // Place bars side-by-side\n    width: 0.8,\n    alpha: 0.9,\n  )\n  .scaleXOrdinal()\n  .scaleYContinuous(min: 0)\n  .theme(ChartTheme.defaultTheme())\n  .build()\n```\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"example/screenshots/cristalyse_grouped_bar_chart.gif\" alt=\"Grouped Bar Chart\" width=\"600\"/\u003e\n  \u003cbr/\u003e\n  \u003cem\u003eGrouped bar charts for comparing multiple series side-by-side\u003c/em\u003e\n\u003c/p\u003e\n\n### Horizontal Bar Charts \u0026 Coordinate Flipping\n**Transform any vertical chart into horizontal** with coordinate system flipping.\n\n```dart\n// Horizontal bars - perfect for long category names and rankings\nfinal departmentData = [\n  {'department': 'Engineering', 'headcount': 45},\n  {'department': 'Product Management', 'headcount': 25},\n  {'department': 'Sales \u0026 Marketing', 'headcount': 35},\n  {'department': 'Customer Success', 'headcount': 20},\n  {'department': 'Human Resources', 'headcount': 15},\n];\n\nCristalyseChart()\n  .data(departmentData)\n  .mapping(x: 'department', y: 'headcount')\n  .geomBar(\n    borderRadius: BorderRadius.circular(4), // Rounded corners\n    borderWidth: 1.0,                       // Add borders\n    alpha: 0.8,\n  )\n  .coordFlip()                              // ✨ Flip to horizontal\n  .scaleXOrdinal()\n  .scaleYContinuous(min: 0)\n  .theme(ChartTheme.defaultTheme())\n  .build()\n\n// Horizontal grouped bars for comparison\nCristalyseChart()\n  .data(quarterlyData)\n  .mapping(x: 'quarter', y: 'revenue', color: 'region')\n  .geomBar(style: BarStyle.grouped)\n  .coordFlip()  // Makes grouped bars horizontal\n  .legend(position: LegendPosition.bottomRight)\n  .build()\n\n// Horizontal stacked bars for composition\nCristalyseChart()\n  .data(budgetData)\n  .mapping(x: 'category', y: 'amount', color: 'subcategory')\n  .geomBar(style: BarStyle.stacked)\n  .coordFlip()  // Horizontal stacked bars\n  .scaleYContinuous(\n    labels: NumberFormat.simpleCurrency().format,\n  )\n  .build()\n\n// Horizontal scatter plot - useful for rank vs performance\nCristalyseChart()\n  .data(performanceData)\n  .mapping(x: 'employee_name', y: 'performance_score', size: 'years_experience')\n  .geomPoint()\n  .coordFlip()  // Names on Y-axis, scores on X-axis\n  .build()\n```\n\n**Coordinate Flipping Features:**\n- ✅ **Universal Transformation** - Works with all chart types (bars, points, lines)\n- ✅ **Automatic Axis Swapping** - X becomes Y, Y becomes X seamlessly  \n- ✅ **Label Readability** - Perfect for long category names\n- ✅ **Ranking Visualizations** - Natural top-to-bottom ranking display\n- ✅ **Legend Compatibility** - Legends work perfectly with flipped coordinates\n- ✅ **Animation Support** - Smooth animations work in both orientations\n\n## 🏷️ Legends\n**Automatic legend generation** from your color mappings with flexible positioning and styling.\n\n```dart\n// Automatic legend from color mapping\nCristalyseChart()\n  .data(salesData)\n  .mapping(x: 'month', y: 'revenue', color: 'product') // Color mapping required\n  .geomBar()\n  .legend() // ✨ Auto-generates legend from 'product' categories\n  .build();\n\n// Positioned legend with custom styling\nCristalyseChart()\n  .data(revenueData)\n  .mapping(x: 'quarter', y: 'amount', color: 'category')\n  .geomBar(style: BarStyle.stacked)\n  .legend(\n    position: LegendPosition.right,\n    orientation: LegendOrientation.vertical,\n    backgroundColor: Colors.white.withOpacity(0.9),\n    textStyle: TextStyle(fontSize: 12, fontWeight: FontWeight.w500),\n    padding: EdgeInsets.all(12),\n  )\n  .build();\n\n// Top horizontal legend for grouped bars\nCristalyseChart()\n  .data(productData)\n  .mapping(x: 'quarter', y: 'revenue', color: 'product')\n  .geomBar(style: BarStyle.grouped)\n  .legend(\n    position: LegendPosition.topRight,\n    orientation: LegendOrientation.horizontal,\n    spacing: 16.0,\n    itemSpacing: 8.0,\n  )\n  .build();\n```\n\n**Legend Features:**\n- ✅ **Auto-Generation** - Automatically creates legends from color mappings\n- ✅ **Flexible Positioning** - Top, bottom, left, right, and corner positions\n- ✅ **Custom Styling** - Background, text style, padding, and spacing control\n- ✅ **Smart Layouts** - Automatic horizontal/vertical orientation based on position\n- ✅ **Multi-Chart Support** - Works with all chart types that use color mapping\n- ✅ **Responsive Design** - Adapts to container constraints\n\n### Legend Positions\n```dart\n// Available positions\nLegendPosition.top\nLegendPosition.bottom  \nLegendPosition.left\nLegendPosition.right\nLegendPosition.topLeft\nLegendPosition.topRight\nLegendPosition.bottomLeft\nLegendPosition.bottomRight\n```\n\n## 🥧 Pie Charts and Donut Charts\n\n**Perfect for part-to-whole relationships** - visualize market share, revenue distribution, user demographics, and any categorical data where proportions matter.\n\n### Basic Pie Chart\n```dart\n// Revenue Distribution by Platform\nCristalyseChart()\n  .data([\n    {'category': 'Mobile', 'revenue': 45.2},\n    {'category': 'Desktop', 'revenue': 32.8},\n    {'category': 'Tablet', 'revenue': 22.0},\n  ])\n  .mappingPie(value: 'revenue', category: 'category')\n  .geomPie(\n    outerRadius: 120.0,\n    strokeWidth: 2.0,\n    strokeColor: Colors.white,\n    showLabels: true,\n    showPercentages: true,\n  )\n  .theme(ChartTheme.defaultTheme())\n  .animate(\n    duration: Duration(milliseconds: 1200),\n    curve: Curves.elasticOut,\n  )\n  .build()\n```\n\n### Donut Charts\n```dart\n// User Analytics with Donut Visualization\nCristalyseChart()\n  .data(userPlatformData)\n  .mappingPie(value: 'users', category: 'platform')\n  .geomPie(\n    innerRadius: 60.0,        // Creates donut hole\n    outerRadius: 120.0,\n    strokeWidth: 3.0,\n    strokeColor: Colors.white,\n    showLabels: true,\n    showPercentages: false,   // Show actual values\n  )\n  .theme(ChartTheme.darkTheme())\n  .animate(\n    duration: Duration(milliseconds: 1500),\n    curve: Curves.easeOutBack,\n  )\n  .build()\n```\n\n### Advanced Pie Charts with Custom Styling\n```dart\n// Market Share Analysis with Exploded Slices\nCristalyseChart()\n  .data(marketShareData)\n  .mappingPie(value: 'market_share', category: 'product')\n  .geomPie(\n    outerRadius: 150.0,\n    strokeWidth: 2.0,\n    strokeColor: Colors.white,\n    showLabels: true,\n    showPercentages: true,\n    explodeSlices: true,      // Explode slices for emphasis\n    explodeDistance: 15.0,\n    labelRadius: 180.0,       // Position labels further out\n    labelStyle: TextStyle(\n      fontSize: 12,\n      fontWeight: FontWeight.bold,\n      color: Colors.black87,\n    ),\n  )\n  .theme(ChartTheme.solarizedLightTheme())\n  .build()\n}\n```\n\n## 🔥 Heat Map Charts\n\n**Perfect for 2D data visualization** - visualize correlations, performance matrices, time-based patterns, and any data with two categorical dimensions and a continuous value.\n\n### Business Performance Heat Map\n```dart\n// Sales Performance by Region and Month\nCristalyseChart()\n  .data([\n    {'month': 'Jan', 'region': 'North', 'sales': 85},\n    {'month': 'Jan', 'region': 'South', 'sales': 62},\n    {'month': 'Feb', 'region': 'North', 'sales': 93},\n    {'month': 'Feb', 'region': 'South', 'sales': 78},\n    // ... more data\n  ])\n  .mappingHeatMap(x: 'month', y: 'region', value: 'sales')\n  .geomHeatMap(\n    cellSpacing: 2.0,\n    cellBorderRadius: BorderRadius.circular(4),\n    colorGradient: [Colors.red, Colors.yellow, Colors.green],\n    interpolateColors: true,\n    showValues: true,\n    valueFormatter: (value) =\u003e '${value.toInt()}%',\n  )\n  .theme(ChartTheme.defaultTheme())\n  .animate(duration: Duration(milliseconds: 1500))\n  .build()\n```\n\n### System Monitoring Heat Map\n```dart\n// Server Response Times by Hour and Service\nCristalyseChart()\n  .data(metricsData)\n  .mappingHeatMap(x: 'hour', y: 'service', value: 'response_time')\n  .geomHeatMap(\n    minValue: 0,\n    maxValue: 100,\n    nullValueColor: Colors.grey.shade200,\n    cellAspectRatio: 1.0,\n    showValues: true,\n    valueTextStyle: TextStyle(\n      fontSize: 10, \n      fontWeight: FontWeight.bold,\n    ),\n  )\n  .theme(ChartTheme.darkTheme())\n  .build()\n```\n\n### Correlation Matrix\n```dart\n// Feature Correlation Analysis\nCristalyseChart()\n  .data(correlationData)\n  .mappingHeatMap(x: 'variable1', y: 'variable2', value: 'correlation')\n  .geomHeatMap(\n    minValue: -1.0,\n    maxValue: 1.0,\n    colorGradient: [\n      Colors.blue.shade800,   // Strong negative correlation\n      Colors.white,           // No correlation  \n      Colors.red.shade800,    // Strong positive correlation\n    ],\n    interpolateColors: true,\n    cellSpacing: 1.0,\n    showValues: true,\n    valueFormatter: (value) =\u003e value.toStringAsFixed(2),\n  )\n  .build()\n```\n\n## 🎯 Dual Y-Axis Charts\n**Perfect for business dashboards** - correlate volume metrics with efficiency metrics on independent scales.\n\n```dart\n// Revenue vs Conversion Rate - The Classic Business Dashboard\nCristalyseChart()\n  .data(businessData)\n  .mapping(x: 'month', y: 'revenue')        // Primary Y-axis (left)\n  .mappingY2('conversion_rate')             // Secondary Y-axis (right)\n  .geomBar(\n    yAxis: YAxis.primary,                   // Revenue bars use left axis\n    alpha: 0.7,\n  )\n  .geomLine(\n    yAxis: YAxis.secondary,                 // Conversion line uses right axis\n    strokeWidth: 3.0,\n    color: Colors.orange,\n  )\n  .geomPoint(\n    yAxis: YAxis.secondary,                 // Points on conversion line\n    size: 8.0,\n    color: Colors.orange,\n  )\n  .scaleXOrdinal()\n  .scaleYContinuous(min: 0)                 // Left axis: Revenue ($k)\n  .scaleY2Continuous(min: 0, max: 100)      // Right axis: Percentage (%)\n  .theme(ChartTheme.defaultTheme())\n  .build()\n```\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"example/screenshots/cristalyse_dual_axis_chart.gif\" alt=\"Dual Axis Chart\" width=\"600\"/\u003e\n  \u003cbr/\u003e\n  \u003cem\u003eDual axis charts for correlating two different metrics on independent scales\u003c/em\u003e\n\u003c/p\u003e\n\n### More Dual Y-Axis Examples\n\n```dart\n// Sales Volume vs Customer Satisfaction\nCristalyseChart()\n  .data(salesData)\n  .mapping(x: 'week', y: 'sales_volume')\n  .mappingY2('satisfaction_score')\n  .geomBar(yAxis: YAxis.primary)            // Volume bars\n  .geomLine(yAxis: YAxis.secondary)         // Satisfaction trend\n  .scaleY2Continuous(min: 1, max: 5)        // Rating scale\n  .build();\n\n// Website Traffic vs Bounce Rate\nCristalyseChart()\n  .data(analyticsData)\n  .mapping(x: 'date', y: 'page_views')\n  .mappingY2('bounce_rate')\n  .geomArea(yAxis: YAxis.primary, alpha: 0.3)    // Traffic area\n  .geomLine(yAxis: YAxis.secondary, strokeWidth: 2.0) // Bounce rate line\n  .scaleY2Continuous(min: 0, max: 100)      // Percentage scale\n  .build();\n```\n\n\n## 🫧 Bubble Charts\n**Perfect for market analysis and multi-dimensional data** - visualize three variables simultaneously with position and size encoding.\n\n```dart\n// Market Performance Analysis\nCristalyseChart()\n  .data([\n    {'company': 'TechCorp', 'revenue': 250, 'customers': 180, 'marketShare': 28},\n    {'company': 'StartupX', 'revenue': 85, 'customers': 120, 'marketShare': 12},\n    {'company': 'MidSize', 'revenue': 150, 'customers': 160, 'marketShare': 18},\n  ])\n  .mapping(\n    x: 'revenue',        // Revenue on X-axis\n    y: 'customers',      // Customer count on Y-axis\n    size: 'marketShare', // Market share determines bubble size\n    color: 'category'    // Color by company category\n  )\n  .geomBubble(\n    minSize: 8.0,        // Minimum bubble radius\n    maxSize: 25.0,       // Maximum bubble radius\n    alpha: 0.7,          // Semi-transparent bubbles\n    borderWidth: 2.0,    // Border for definition\n    showLabels: true,    // Show value labels\n    labelFormatter: (value) =\u003e '${value}%', // Custom label format\n  )\n  .scaleXContinuous()\n  .scaleYContinuous()\n  .theme(ChartTheme.defaultTheme())\n  .animate(duration: Duration(milliseconds: 1200))\n  .build()\n```\n\n\u003cp align=\"center\"\u003e\n  \u003cem\u003ePerfect for analyzing relationships between three continuous variables\u003c/em\u003e\n\u003c/p\u003e\n\n### Bubble Chart Features\n- ✅ **Size Encoding** - Third dimension mapped to bubble radius\n- ✅ **Color Grouping** - Categorical data with distinct colors  \n- ✅ **Custom Labels** - Show formatted values on bubbles\n- ✅ **Interactive Tooltips** - Rich hover information\n- ✅ **Dual Y-Axis Support** - Use with secondary scales\n- ✅ **Animation Support** - Smooth entrance effects\n\n## 🔥 Current Features\n\n### ✅ Chart Types\n- **Scatter plots** with size and color mapping\n- **Line charts** with multi-series support and progressive drawing\n- **Area charts** with smooth fills and multi-series transparency\n- **Bar charts** (vertical, horizontal, grouped, stacked) with smooth animations\n- **Pie charts and donut charts** with exploded slices and smart label positioning\n- **Heat map charts** with customizable color gradients and 2D data visualization\n- **Bubble charts** with 3D data visualization and size encoding\n- **Dual Y-axis charts** for professional business dashboards\n- **Combined visualizations** (bars + lines, points + lines, etc.)\n\n### ✅ Advanced Features\n- **Grammar of Graphics API** - Familiar ggplot2-style syntax\n- **Smooth 60fps animations** with customizable timing and curves\n- **Dual Y-axis support** with independent scales and data routing\n- **Multiple built-in themes** (Light, Dark, Solarized Light/Dark)\n- **Custom color palettes** for brand-specific category mapping\n- **Automatic legend generation** with flexible positioning and styling\n- **Advanced label formatting** with NumberFormat integration\n- **Interactive panning** with real-time data streaming support\n- **Responsive scaling** for all screen sizes\n- **High-DPI support** for crisp visuals\n\n### ✅ Data Handling\n- **Flexible data formats** - List\u003cMap\u003cString, dynamic\u003e\u003e\n- **Mixed data types** - Automatic type detection and conversion\n- **Missing value handling** - Graceful degradation for null/invalid data\n- **Large dataset support** - Optimized for 1000+ data points\n- **Real-time updates** - Smooth transitions when data changes\n- **Multi-dimensional mapping** - X, Y, size, color encoding simultaneously\n\n## 📸 Chart Export\n\n**Export your charts as professional-quality SVG vector graphics** for reports, presentations, and documentation.\n\n```dart\n// Simple SVG export\nfinal result = await chart.exportAsSvg(\n  width: 1200,\n  height: 800,\n  filename: 'sales_report',\n);\nprint('Chart saved to: ${result.filePath}');\n\n// Advanced configuration\nfinal config = ExportConfig(\n  width: 1920,\n  height: 1080,\n  format: ExportFormat.svg,\n  filename: 'high_res_dashboard',\n);\nfinal result = await chart.export(config);\n```\n\n**SVG Export Features:**\n- ✅ **Scalable Vector Graphics** - Infinite zoom without quality loss\n- ✅ **Professional Quality** - Perfect for presentations and reports\n- ✅ **Small File Sizes** - Efficient for web and print\n- ✅ **Design Software Compatible** - Editable in Figma, Adobe Illustrator, etc.\n- ✅ **Cross-Platform Reliable** - Works consistently on all platforms\n- ✅ **Automatic File Management** - Saves to Documents directory with timestamp\n\n## 🎯 Real-World Examples\n\n### Sales Dashboard\n```dart\nWidget buildRevenueTrend() {\n  return CristalyseChart()\n      .data(monthlyRevenue)\n      .mapping(x: 'month', y: 'revenue', color: 'product_line')\n      .geomLine(strokeWidth: 3.0)\n      .geomPoint(size: 5.0)\n      .scaleXContinuous()\n      .scaleYContinuous(min: 0)\n      .theme(ChartTheme.solarizedDarkTheme()) // Use Solarized Dark theme\n      .animate(duration: Duration(milliseconds: 1500))\n      .build();\n}\n```\n\n### User Analytics\n```dart\nWidget buildEngagementScatter() {\n  return CristalyseChart()\n      .data(userMetrics)\n      .mapping(x: 'session_length', y: 'pages_viewed',\n      color: 'user_type', size: 'revenue')\n      .geomPoint(alpha: 0.6)\n      .scaleXContinuous()\n      .scaleYContinuous()\n      .theme(isDarkMode ? ChartTheme.darkTheme() : ChartTheme.defaultTheme())\n      .animate(duration: Duration(milliseconds: 800), curve: Curves.elasticOut)\n      .build();\n}\n```\n\n### Market Share Analysis\n```dart\nWidget buildMarketSharePie() {\n  return CristalyseChart()\n      .data(marketData)\n      .mappingPie(value: 'market_share', category: 'product')\n      .geomPie(\n        outerRadius: 140.0,\n        strokeWidth: 3.0,\n        strokeColor: Colors.white,\n        showLabels: true,\n        showPercentages: true,\n        explodeSlices: true,                  // Emphasize key segments\n        explodeDistance: 12.0,\n        labelStyle: TextStyle(\n          fontSize: 11,\n          fontWeight: FontWeight.w600,\n        ),\n      )\n      .theme(ChartTheme.defaultTheme())\n      .animate(duration: Duration(milliseconds: 1200), curve: Curves.elasticOut)\n      .build();\n}\n```\n\n### Business Intelligence Dashboard\n```dart\n// Revenue bars + profit margin line on dual Y-axis\nCristalyseChart()\n  .data(kpiData)\n  .mapping(x: 'quarter', y: 'revenue')\n  .mappingY2('profit_margin')\n  .geomBar(yAxis: YAxis.primary, style: BarStyle.stacked)\n  .geomLine(yAxis: YAxis.secondary, color: Colors.green)\n  .scaleYContinuous(labels: NumberFormat.simpleCurrency().format)\n  .scaleY2Continuous(labels: (v) =\u003e '${v.toStringAsFixed(1)}%')\n  .legend()\n  .build();\n```\n\n### Advanced Multi-Geometry Dashboard\n```dart\n// Combined area + line + bubbles with dual Y-axis\nCristalyseChart()\n  .data(performanceData)\n  .mapping(x: 'month', y: 'revenue', size: 'team_size', color: 'department')\n  .mappingY2('efficiency')\n  .geomArea(yAxis: YAxis.primary, alpha: 0.2)\n  .geomLine(yAxis: YAxis.primary, strokeWidth: 3.0)\n  .geomBubble(yAxis: YAxis.primary, minSize: 5.0, maxSize: 15.0)\n  .geomLine(yAxis: YAxis.secondary, color: Colors.orange)\n  .scaleYContinuous(labels: NumberFormat.compact().format)\n  .scaleY2Continuous(labels: (v) =\u003e '${v.round()}%')\n  .legend()\n  .interaction(pan: PanConfig(enabled: true))\n  .build();\n```\n\n## 💡 Why Not Just Use...?\n\n| Alternative | Why Cristalyse is Better |\n|-------------|---------------------------|\n| **fl_chart** | Grammar of graphics API vs basic chart widgets. Dual Y-axis support vs single axis limitation. |\n| **charts_flutter** | Active development vs deprecated. Stacked bars and advanced features vs basic charts. |\n| **Web charts (plotly.js)** | Native performance vs DOM rendering. True mobile deployment vs responsive web. |\n| **Platform-specific charts** | Write once vs write 3x for iOS/Android/Web. Consistent UX vs platform differences. |\n| **Business tools (Tableau)** | Embedded in your app vs separate tools. Full customization vs template limitations. |\n\n## 🛠 Advanced Configuration\n\n\n### Animation Control\n```dart\nchart.animate(\n  duration: Duration(milliseconds: 1200),\n  curve: Curves.elasticOut,  // Try different curves!\n)\n```\n\n### Custom Themes\n\n**Complete visual control** with built-in themes and full customization options.\n\n```dart\n// Built-in themes\nCristalyseChart()\n  .data(data)\n  .mapping(x: 'month', y: 'revenue')\n  .geomLine()\n  .theme(ChartTheme.darkTheme()) // or .defaultTheme(), .solarizedLightTheme()\n  .build();\n\n// Custom branded theme\nfinal brandedTheme = ChartTheme(\n  primaryColor: const Color(0xFF007BFF), // Brand primary\n  colorPalette: [Colors.blue, Colors.green, Colors.red],\n  axisTextStyle: const TextStyle(fontSize: 12, fontWeight: FontWeight.w500),\n);\n\nCristalyseChart()\n  .theme(brandedTheme)\n  .build();\n```\n\n**Theme Features:**\n- ✅ **Built-in Themes** - Light, dark, and Solarized variants ready to use\n- ✅ **Brand Customization** - Match your organization's visual identity\n- ✅ **Responsive Design** - Adapt themes based on screen size\n- ✅ **Color Palettes** - Comprehensive color schemes for multi-series charts\n- ✅ **Typography Control** - Custom fonts, sizes, and weights\n- ✅ **Layout Options** - Padding, spacing, and dimension control\n\n### Custom Color Palettes\n\n**Brand-specific colors for categories** with semantic meaning and consistent visual identity.\n\n```dart\n// Platform-specific colors\nfinal platformColors = {\n  'iOS': const Color(0xFF007AFF),\n  'Android': const Color(0xFF3DDC84),\n  'Web': const Color(0xFFFF6B35),\n};\n\nCristalyseChart()\n  .data(appAnalyticsData)\n  .mapping(x: 'month', y: 'users', color: 'platform')\n  .geomLine()\n  .customPalette(categoryColors: platformColors)\n  .build();\n```\n\n**Custom Palette Features:**\n- ✅ **Brand Consistency** - Use your organization's exact brand colors\n- ✅ **Semantic Colors** - Map status, priority, or meaning to colors\n- ✅ **Category Override** - Specific colors for individual categories\n- ✅ **Fallback Support** - Unmapped categories use theme colors\n- ✅ **Legend Integration** - Custom colors appear in auto-generated legends\n\n### Advanced Label Formatting\n\n**Professional number formatting** with NumberFormat integration and custom callbacks.\n\n```dart\nimport 'package:intl/intl.dart';\n\n// Currency formatting\n.scaleYContinuous(labels: NumberFormat.simpleCurrency().format) // $1,234.56\n\n// Compact notation\n.scaleYContinuous(labels: NumberFormat.compact().format) // 1.2M, 5.6K\n\n// Custom formatting\n.scaleYContinuous(labels: (value) =\u003e '${value.toStringAsFixed(1)}°C') // 23.5°C\n```\n\n**Label Formatting Features:**\n- ✅ **NumberFormat Integration** - Built-in currency, percentage, and compact formatting\n- ✅ **Custom Callbacks** - Full control over label appearance and logic\n- ✅ **Locale Support** - Automatic localization based on device settings\n- ✅ **Multi-Chart Support** - Works with all chart types (axes, pie slices, bubbles)\n- ✅ **Performance Optimized** - Efficient formatting without UI blocking\n- ✅ **Unit Flexibility** - Easy addition of units, symbols, and custom text\n\n### Advanced Data Mapping\n```dart\n// Map any data structure\nchart\n    .data(complexData)\n    .mapping(\n      x: 'timestamp',           // Time series\n      y: 'metric_value',        // Numeric values  \n      color: 'category',        // Color grouping\n      size: 'importance'        // Size encoding\n    )\n    .mappingY2('efficiency')    // Secondary Y-axis for dual charts\n```\n\n### Stacked Bar Configuration\n```dart\nchart\n    .data(budgetData)\n    .mapping(x: 'department', y: 'amount', color: 'category')\n    .geomBar(\n      style: BarStyle.stacked,        // Stack segments\n      width: 0.8,                     // Bar width\n      borderRadius: BorderRadius.circular(4), // Rounded corners\n      alpha: 0.9,                     // Transparency\n    )\n    .scaleXOrdinal()\n    .scaleYContinuous(min: 0)\n```\n\n## 📱 Platform Support\n\n- ✅ **iOS 12+**\n- ✅ **Android API 21+**\n- ✅ **Web (Chrome 80+, Firefox, Safari)**\n- ✅ **Windows 10+**\n- ✅ **macOS 10.14+**\n- ✅ **Linux (Ubuntu 18.04+)**\n\n## 🧪 Development Status\n\n**Current Version: 1.17.4** - Production ready with fixed tooltips for interactive legends, bar chart positive/negative value styling, integer-only ticks, pinch/scroll wheel/button-based zoom, tick configuration, optional Y-axis titles in legends, boundary clamping, programmatic pan controller, interactive floating legends, and intelligent axis bounds\n\nWe're shipping progressively! Each release adds new visualization types while maintaining backward compatibility.\n\n- ✅ **v0.1.0** - Scatter plots and basic theming\n- ✅ **v0.2.0** - Line charts and animations\n- ✅ **v0.3.0** - Bar charts (including horizontal) and areas\n- ✅ **v0.4.0** - Enhanced theming with custom colors and text styles, stacked bars\n- ✅ **v0.5.0** - **Dual Y-axis support** and advanced bar chart variations\n- ✅ **v0.6.0** - Interactive tooltips\n- ✅ **v0.7.0** - Interactive panning\n- ✅ **v0.8.0** - **Area chart support** with animations and multi-series capabilities\n- ✅ **v0.9.0** - **Enhanced dual Y-axis SVG export** with comprehensive scale support\n- ✅ **v1.0.0** - **Pie charts and donut charts** with exploded slices and smart label positioning\n- ✅ **v1.1.0** - **Advanced label formatting system** with NumberFormat integration (by [@davidlrichmond](https://github.com/davidlrichmond))\n- ✅ **v1.2.0** - **Heat map charts** with 2D data visualization and customizable color gradients\n- ✅ **v1.3.0** - **Bubble charts** with 3D data visualization and professional size encoding\n- ✅ **v1.4.0** - **Custom color palettes** for brand-specific category mapping\n- ✅ **v1.5.0** - **Automatic legend generation** with flexible positioning and styling\n- ✅ **v1.6.0** - **Experimental gradient color support** for customPalette with Linear, Radial, and Sweep gradients\n- ✅ **v1.7.0** - **Progress bar charts** with horizontal, vertical, circular, stacked, grouped, gauge, and concentric styles + comprehensive documentation improvements\n- ✅ **v1.8.0** - **Intelligent axis bounds \u0026 labeling** with Wilkinson Extended algorithm (by [@davidlrichmond](https://github.com/davidlrichmond)) - professional round-number ticks, geometry-aware defaults, comprehensive testing\n- ✅ **v1.9.0** - **Interactive \u0026 floating legends** with click-to-toggle visibility, custom positioning with offsets, color consistency preservation, and overflow rendering support\n- ✅ **v1.10.0** - **Axis titles \u0026 bubble size guide** with optional titles for all axes, visual bubble size legends, smart spacing calculations, and bubble legend validation fixes (by [@davidlrichmond](https://github.com/davidlrichmond))\n- ✅ **v1.11.0** - **Programmatic pan controller** for external chart panning control via PanController with panTo() and panReset() methods (by [@jbbjarnason](https://github.com/jbbjarnason))\n- ✅ **v1.12.0** - **Boundary clamping for pan operations** with optional boundaryClampingX and boundaryClampingY to prevent infinite panning beyond data boundaries (by [@jbbjarnason](https://github.com/jbbjarnason))\n- ✅ **v1.13.0** - **Optional Y-axis titles in legends** for improved multi-axis chart readability (by [@jbbjarnason](https://github.com/jbbjarnason))\n- ✅ **v1.14.0** - **Tick configuration for scales** with explicit tick positions and simple linear spacing options (by [@jbbjarnason](https://github.com/jbbjarnason))\n- ✅ **v1.15.0** - **Zoom \u0026 pan interactions** with pinch gestures, scroll wheel support, and floating zoom buttons for multi-touch and desktop platforms\n- ✅ **v1.16.0** - **Integer-only ticks** for continuous scales, ensuring clean integer values for count data\n- ✅ **v1.17.0** - **Bar chart positive/negative value styling** with smart rounded corners (`roundOutwardEdges`) and conditional colors (`positiveColor`/`negativeColor`) for financial charts and variance analysis\n\n## Support This Project\n\n**Love Cristalyse?** Your support helps me dedicate more time to building the Flutter charting library you deserve!\n\n\u003cp\u003e\n  \u003ca href=\"https://github.com/sponsors/rudi-q\"\u003e\n    \u003cimg src=\"https://img.shields.io/badge/Sponsor_on-GitHub-2cacbf?style=for-the-badge\u0026logo=githubsponsors\u0026logoColor=white\u0026labelColor=145261\" alt=\"Sponsor on GitHub\" style=\"border-radius: 8px;\"/\u003e\n  \u003c/a\u003e\n\u003c/p\u003e\n\n### Why Sponsor?\n\n- **Faster Development** - More features, bug fixes, and improvements\n- **Better Documentation** - Comprehensive guides and examples\n- **Priority Support** - Get your issues and feature requests prioritized\n- **New Chart Types** - Help fund development of advanced visualizations\n- **Platform Support** - Ensure continued cross-platform compatibility\n\n### What Your Support Enables\n\n**Active Development** - Cristalyse is passion project that requires significant time investment  \n**Advanced Features** - Complex chart types like treemaps, sankey diagrams, and statistical overlays  \n**Bug Fixes \u0026 Performance** - Rapid responses to issues and continuous optimization  \n**Documentation \u0026 Examples** - Real-world examples and comprehensive tutorials  \n**Community Building** - Discord server, workshops, and educational content  \n\n\u003cp align=\"center\"\u003e\n  \u003cstrong\u003eEvery contribution, no matter the size, makes a real difference!\u003c/strong\u003e\n\u003c/p\u003e\n\n---\n\n## 🤝 Contributing\n\nWe'd love your help! Check out our [contributing guide](CONTRIBUTING.md) and:\n\n- 🐛 Report bugs\n- 💡 Suggest features\n- 📝 Improve documentation\n- 🔧 Submit pull requests\n\n## 📄 License\n\nMIT License - build whatever you want, commercially or otherwise.\n\n## 🔗 Links\n\n- 📦 [pub.dev package](https://pub.dev/packages/cristalyse)\n- 📖 [Full documentation](https://github.com/rudi-q/cristalyse#readme)\n- 🐛 [Issue tracker](https://github.com/rudi-q/cristalyse/issues)\n- 💬 [Discussions](https://github.com/rudi-q/cristalyse/discussions)\n\n---\n\n**Ready to create stunning visualizations?** `flutter pub add cristalyse` and start building! 🚀\n\n*Cristalyse: Finally, the grammar of graphics library Flutter developers deserve.*","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frudi-q%2Fcristalyse","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frudi-q%2Fcristalyse","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frudi-q%2Fcristalyse/lists"}