Skip to main content

Updates & Changelog

Stay informed about the latest features, improvements, and fixes in Cristalyse.
November 2, 2025
v1.13.0

🎨 Legend Enhancements

Authored by @jbbjarnason - Thank you for this contribution!Optional Y-Axis Titles in Legends!Legend Enhancements:
  • New showTitles option to display Y-axis titles alongside legend entries
  • Improves chart legend readability when multiple Y-axes are present
  • Optional feature - legends work as before by default
  • Seamless integration with existing legend styling and layout
Use Cases:
  • Multi-axis charts with clearer data context
  • Better legend readability for complex visualizations
  • Maintain visual hierarchy with optional titles
Technical Implementation:
  • Extended LegendWidget to support optional Y-axis title rendering
  • Enhanced legend.dart core logic to handle title display
  • Updated chart configuration to expose new option
  • Comprehensive test coverage included
Quality Assurance:
  • All existing tests continue to pass
  • Zero breaking changes - fully backward compatible
  • New feature is opt-in
  • Production ready
November 2, 2025
v1.12.1

🐛 Right Padding & Secondary Y-Axis Fixes

Fixed excessive right padding and layout misalignment
  • Removed hardcoded 80px padding applied unconditionally for secondary y-axis
  • Charts without secondary y-axis now use only theme padding (no waste)
  • Widget layout uses conservative estimate only when y2Scale exists
  • Painter performs precise calculation at paint time with full scale information
  • Eliminates divergence between layout and rendering phases
  • Added proper null checking for y2Scale to prevent unnecessary padding
Benefits:
  • Better space utilization on single-axis charts
  • Proper secondary y-axis spacing based on actual label widths
  • Ensures hit-testing alignment for interactions (hover, click, pan)
  • Consistent plot area between layout and render phases
Quality Assurance:
  • Zero breaking changes - fully backward compatible
  • Improved interaction reliability with secondary y-axis charts
  • Maintains consistent dimensions during pan/zoom operations
November 1, 2025
v1.12.0

🏔️ Boundary Clamping for Pan Operations

Authored by @jbbjarnason - Thank you for this contribution!Control infinite panning with boundary clamping!Boundary Clamping:
  • New boundaryClampingX and boundaryClampingY options in PanConfig
  • Prevents panning beyond data boundaries when enabled
  • Maintains intuitive pan behavior within configured domain limits
  • Perfect for constrained data exploration and guided navigation
Use Cases:
  • Prevent users from panning too far from relevant data
  • Create bounded exploration areas for large datasets
  • Maintain data context during navigation
  • Improve UX for time-series and scientific visualizations
CristalyseChart()
  .data(timeSeriesData)
  .mapping(x: 'time', y: 'value')
  .geomLine()
  .interaction(
    pan: PanConfig(
      enabled: true,
      boundaryClampingX: true,  // Clamp X-axis panning
      boundaryClampingY: true,  // Clamp Y-axis panning
    ),
  )
  .build()
Technical Implementation:
  • Scale boundaries tracked via valuesBoundaries in LinearScale
  • Pan domain clamping applied during interaction handling
  • Seamless integration with existing pan callbacks and pan controller
  • No changes to default behavior - opt-in feature
Quality Assurance:
  • Zero breaking changes - fully backward compatible
  • Default clamping disabled (infinite panning by default)
  • Tested with pan controller and manual pan interactions
  • Production ready
October 24, 2025
v1.11.1

🐛 Y-axis Bounds Fix During Panning

Authored by @jbbjarnason - Thank you for this fix!Fixed Y-axis getting stuck during X-axis pan operations
  • Y-axis bounds now correctly update when configured with updateYDomain: false
  • Previously remained locked to original panYDomain bounds during X-axis panning
  • Enables proper dynamic Y-axis scaling while panning horizontally
Quality Assurance:
  • Zero breaking changes - fully backward compatible
  • Patch bump release
October 24, 2025
v1.11.0

🎯 Programmatic Pan Controller

Code authored by @jbbjarnason - Thank you for this contribution!New PanController Class:
  • External control of chart panning via new PanController class
  • panTo(PanInfo) method for programmatic pan operations
  • panReset() method to restore original chart view
  • ChangeNotifier-based architecture for reactive updates
  • Optional controller parameter in PanConfig
Enhanced Pan Configuration:
  • Widget lifecycle management (initState, didUpdateWidget, dispose)
  • Automatic listener registration and cleanup
  • Full integration with existing pan callbacks
final panController = PanController();

CristalyseChart()
  .data(data)
  .mapping(x: 'x', y: 'y')
  .geomLine()
  .interaction(
    pan: PanConfig(
      enabled: true,
      controller: panController,
    ),
  )
  .build();

// Pan to specific range
panController.panTo(PanInfo(
  visibleMinX: 500,
  visibleMaxX: 1500,
  state: PanState.update,
));

// Reset to original view
panController.panReset();
Use Cases:
  • Programmatic zoom controls with buttons/sliders
  • Reset to original view functionality
  • Coordinated panning across multiple charts
  • External UI controls for chart navigation
  • Jump to specific data ranges programmatically
Quality Assurance:
  • Zero breaking changes - fully backward compatible
  • Optional controller parameter (defaults to null)
  • Proper lifecycle management with listener cleanup
  • Example integration in pan_example.dart
October 23, 2025
v1.10.3

🐛 Scale Padding Fix

Authored by @jbbjarnason - Thank you for this fix!Fixed chart shrinking when panning
  • Scale padding now initialized before painting charts
  • Prevents setupYScale from changing padding during panning
  • Chart maintains consistent size during all pan operations
  • Smooth user experience without unintended resize behavior
Quality Assurance:
  • All existing tests continue to pass
  • Zero breaking changes - fully backward compatible
October 21, 2025
v1.10.2

🎨 Heat Map Unification & Bounds Validation

Authored by @davidlrichmond - Thank you for this contribution!Heat Map Color System Unification:
  • Unified heat maps to use GradientColorScale for consistent color handling
  • Eliminates duplicate color logic between heat maps and other chart types
  • Improves code maintainability and reduces technical debt
  • Heat map colors now follow the same scaling principles as other geometries
Bounds Edge Cases & Validation:
  • Fixed guard condition for corner case where min > max in bounds calculations
  • Prevents invalid scale configurations that could crash rendering
  • Added comprehensive test coverage for edge cases
  • Improved documentation for bounds behavior with notes on invalid configurations
Code Quality:
  • Addressed code review feedback on refactored code
  • Fixed deprecated int RGB getters for Flutter compatibility
  • Applied code formatting linter fixes
Quality Assurance:
  • Added 34 new test cases for bounds edge cases
  • Added 106 lines of tests for GradientColorScale functionality
  • All existing tests continue to pass
  • Zero breaking changes - fully backward compatible
October 21, 2025
v1.10.1

🐛 Wilkinson Labeling Precision

Authored by @jbbjarnason - Thank you for this fix!Fixed floating-point rounding in epoch millisecond label calculations
  • Replaced round() with roundToDouble() for proper double precision handling
  • Resolves issues with large number labeling (e.g., epoch timestamps)
  • Added comprehensive test case for epoch millisecond labeling
  • Test validates correct tick generation: [1760527000000.0, 1760528000000.0, 1760529000000.0, 1760530000000.0]
Technical Details:
  • _cleanNumber() method in WilkinsonLabeling class now uses roundToDouble() instead of round()
  • Fixes edge case with very large timestamp values (>1.7 trillion milliseconds)
  • Maintains precision in float arithmetic for astronomical numbers
Quality Assurance:
  • All 286 tests passing (285 existing + 1 new test)
  • Zero breaking changes - fully backward compatible
October 7, 2025
v1.10.0

🎨 Axis Titles & Bubble Size Guide

Descriptive axis titles and visual bubble size legends!Axis Titles:
  • Add titles to X, Y, and Y2 axes with optional title parameter
  • Smart positioning with automatic spacing calculations
  • Vertical axes display rotated titles (-90° for Y, +90° for Y2)
  • Theme-aware styling with customizable fonts
Bubble Size Guide:
  • Visual legend shows min, mid, and max bubble sizes
  • Automatically appears when title provided on geomBubble()
  • Horizontal and vertical layout support
  • Seamlessly integrates with existing legend system
// Axis titles for clearer data context
CristalyseChart()
  .data(timeSeriesData)
  .mapping(x: 'time', y: 'value')
  .geomLine()
  .scaleXContinuous(title: 'Time (seconds)')
  .scaleYContinuous(title: 'Temperature (°C)')
  .build()

// Dual axis with titles
CristalyseChart()
  .data(businessData)
  .mapping(x: 'month', y: 'revenue')
  .mappingY2('conversion')
  .geomBar(yAxis: YAxis.primary)
  .geomLine(yAxis: YAxis.secondary)
  .scaleXOrdinal(title: 'Month')
  .scaleYContinuous(title: 'Revenue ($K)')
  .scaleY2Continuous(title: 'Conversion Rate (%)')
  .build()

// Bubble size guide in legend
CristalyseChart()
  .data(companyData)
  .mapping(x: 'revenue', y: 'customers', size: 'marketShare')
  .geomBubble(
    title: 'Market Share (%)',  // Enables size guide
    minSize: 8.0,
    maxSize: 25.0,
  )
  .legend()  // Shows both category colors and size guide
  .build()
Bug Fixes:
  • Fixed edge case where zero/negative bubble sizes could cause rendering errors
  • Added validation to ensure bubble legend sizes are always positive
  • Clamps invalid values to safe minimum (1.0px radius)
  • Prevents Container dimension errors with edge-case data
Technical Improvements:
  • Precise spacing calculations for axis labels and titles
  • Pre-calculated label dimensions for optimal layout
  • Consistent spacing constants across all axes
  • Validated bubble sizes in legend rendering
  • 8 new edge case tests for bubble validation
Quality Assurance:
  • All 285 tests passing (20 new tests added)
  • Zero breaking changes - fully backward compatible
  • Titles optional and render only when provided
  • Production ready
October 6, 2025
v1.9.0

🎯 Interactive & Floating Legends

Authored by @davidlrichmond - Valuable contribution!Transform your charts with interactive legend controls and advanced positioning!Interactive Legend Toggle:
  • Click-to-hide/show data points with visual feedback
  • Simple .legend(interactive: true) to enable
  • Toggled items show reduced opacity + strikethrough styling
  • Smooth chart updates with preserved color consistency
  • Both auto-managed and external state control
Floating Legend Positioning:
  • New LegendPosition.floating with custom offsets
  • Negative offsets supported (legends outside chart bounds!)
  • clipBehavior: Clip.none enables overflow rendering
  • Full creative control over placement
// Interactive Legend (Auto-Managed)
CristalyseChart()
  .data(salesData)
  .mapping(x: 'quarter', y: 'revenue', color: 'product')
  .geomBar(style: BarStyle.grouped)
  .legend(interactive: true) // Click to toggle!
  .build()

// Floating Legend with Custom Position
CristalyseChart()
  .data(data)
  .mapping(x: 'x', y: 'y', color: 'category')
  .geomPoint()
  .legend(
    position: LegendPosition.floating,
    floatingOffset: Offset(20, 20), // Custom position
  )
  .build()

// Interactive + Floating + External State
CristalyseChart()
  .data(data)
  .mapping(x: 'x', y: 'y', color: 'category')
  .geomLine()
  .legend(
    interactive: true,
    position: LegendPosition.floating,
    floatingOffset: Offset(-10, 30), // Can overflow!
    hiddenCategories: myHiddenSet,
    onToggle: (category, visible) => handleToggle(category, visible),
  )
  .build()
Enhanced API:
  • interactive: Enable click-to-toggle functionality
  • hiddenCategories: External state management
  • onToggle: Custom toggle callbacks
  • floatingOffset: Precise Offset positioning
Color Consistency Fixed:
  • Original ColorScale preserved when filtering
  • No color shifting when toggling categories
  • Chart painter respects provided ColorScale
Theme-Aware Backgrounds:
  • Legend backgrounds adapt to theme colors
  • Automatic contrast for light/dark modes
  • No hardcoded white backgrounds
Quality Assurance:
  • All 268 tests passing
  • Zero breaking changes
  • Production ready
View legend documentation
October 4, 2025
v1.8.1

🔗 Enhanced Developer Experience

Seamless navigation between documentation and live examples!
  • Bidirectional Links: Jump between docs and example app instantly
  • View Docs Button: All 19 example app screens link to documentation
  • View Live Example Cards: 9 chart docs pages link to interactive examples
  • Better Learning Flow: Quickly switch from reading to seeing live code
Documentation Navigation:
  • Scatter plots, line charts, bar charts, area charts
  • Bubble charts, pie charts, dual-axis charts
  • Heat maps, progress bars
  • Opens in appropriate context (external browser for app, new tab for docs)
Technical Improvements:
  • Clean architecture with single source of truth for URL mappings
  • Type-safe implementation with proper null checks
  • Consistent UI patterns across both navigation methods
  • Added url_launcher package for external link handling
// Example app now has "View Docs" button on each chart
// Documentation now has "View Live Example" cards
// Perfect for learning and exploring!
Quality Assurance:
  • All Flutter analyze checks passing
  • Zero breaking changes
  • Backward compatible
October 1, 2025
v1.8.0

🎯 Intelligent Axis Bounds & Labeling

Authored by @davidlrichmond - Exceptional contribution!Wilkinson Extended Algorithm for professional axis labels:
  • Based on IEEE paper by Talbot, Lin, and Hanrahan (2010)
  • Generates “nice” round numbers: 0, 5, 10, 50, 100
  • Optimizes simplicity, coverage, density, and legibility
  • Smart pruning for performance
Geometry-Aware Bounds:
  • Bar/area charts: Zero baseline for quantity comparison
  • Line/scatter charts: Data-driven bounds for trend analysis
  • Automatic appropriate defaults based on chart type
// Prettier axis labels automatically!
// Before: 0.47, 5.23, 10.88, 15.91, 21.07
// After:  0, 5, 10, 15, 20

CristalyseChart()
  .data(data)
  .mapping(x: 'time', y: 'value')
  .geomLine()
  .scaleYContinuous()  // Smart bounds automatically!
  .build()

// New bubble size limits
chart.geomBubble(
  minSize: 8.0,
  maxSize: 25.0,
  limits: (1000, 50000),  // Scale domain control
)
Testing & Quality:
  • 803 lines of new tests added
  • All 263 tests passing
  • Zero breaking changes
  • Production ready
View axis bounds documentation
September 30, 2025
v1.7.0

📊 Progress Bar Charts

Professional progress visualization with multiple styles!
  • Multiple Orientations: Horizontal, vertical, and circular progress bars
  • Advanced Styles: Stacked, grouped, gauge, and concentric layouts
  • Theme-Responsive: Full dark mode and custom palette support
  • Robust Validation: Comprehensive input validation and error handling
// Stacked Progress Bar
CristalyseChart()
  .data([
    {'project': 'App', 'stage': 'Design', 'progress': 30.0},
    {'project': 'App', 'stage': 'Development', 'progress': 50.0},
    {'project': 'App', 'stage': 'Testing', 'progress': 20.0},
  ])
  .mappingProgress(category: 'project', value: 'progress', group: 'stage')
  .geomProgress(
    style: ProgressStyle.stacked,
    orientation: ProgressOrientation.horizontal,
  )
  .build()
Documentation Improvements:
  • Enhanced SEO with comprehensive metadata
  • Custom 404 page with helpful navigation
  • Subscribable RSS feed for updates
  • Fixed all broken links
  • Improved contextual menu copy
September 8, 2025
v1.6.1

🤖 MCP Server Integration

Cristalyse now integrates with AI coding assistants!
  • New documentation guide for connecting Cristalyse docs to AI coding assistants (Cursor, Windsurf, Warp, Claude)
  • Enable AI assistants to access complete documentation, examples, and best practices directly in your IDE
  • Setup instructions: Add "cristalyse_docs": {"url": "https://docs.cristalyse.com/mcp"} to MCP settings
Learn more about MCP Server
September 7, 2025
v1.6.0

🌈 Gradient Color Support (Experimental)

Transform your charts with stunning gradient effects!
  • Category-specific gradients with categoryGradients property
  • Support for Linear, Radial, and Sweep gradients
  • Advanced alpha blending that respects animation transparency
  • Works with bar charts and scatter plots
CristalyseChart()
  .data(data)
  .mapping(x: 'quarter', y: 'revenue', color: 'quarter')
  .geomBar()
  .customPalette(categoryGradients: {
    'Q1': LinearGradient(colors: [Colors.blue, Colors.cyan]),
    'Q2': RadialGradient(colors: [Colors.red, Colors.orange]),
  })
  .build()
⚠️ Note: Not advisable for production use as of v1.6.0
September 5, 2025
v1.5.0

🔥 Built-In Legend Support

Professional legends with zero configuration!
  • Simple .legend() method with smart defaults
  • 8 flexible positioning options (topLeft, topRight, bottom, etc.)
  • Automatic symbol generation based on chart type
  • Full dark mode support with theme-aware text colors
CristalyseChart()
  .data(salesData)
  .mapping(x: 'quarter', y: 'revenue', color: 'product')
  .geomBar(style: BarStyle.grouped)
  .legend() // That's it! ✨
  .build()
View legend documentation
September 3, 2025
v1.4.0

🎨 Custom Category Colors

Brand-consistent charts with custom color palettes!
  • New customPalette() method for category-specific colors
  • Smart fallback system for unmapped categories
  • Perfect for corporate dashboards and brand consistency
final platformColors = {
  'iOS': const Color(0xFF007ACC),      // Apple Blue
  'Android': const Color(0xFF3DDC84),  // Android Green
  'Web': const Color(0xFFFF6B35),      // Web Orange
};

CristalyseChart()
  .customPalette(categoryColors: platformColors)
  .build()
September 3, 2025
v1.3.1

🐛 Multi-Series Line Chart Fixes

  • Fixed critical rendering issues with multi-series line charts
  • Resolved missing data points on multi-series visualizations
  • Fixed overlapping series lines for better visual separation
September 2, 2025
v1.3.0

🫧 Bubble Chart Support

Three-dimensional data visualization is here!
  • Full bubble chart implementation with size mapping
  • Advanced SizeScale class for proportional bubble sizing
  • Interactive tooltips with rich hover information
  • New geomBubble() API following grammar of graphics
CristalyseChart()
  .data(companyData)
  .mapping(
    x: 'revenue',
    y: 'customers',
    size: 'marketShare',
    color: 'category',
  )
  .geomBubble(
    minSize: 8.0,
    maxSize: 25.0,
    alpha: 0.75,
  )
  .build()
View bubble chart documentation
August 30, 2025
v1.2.4

Bug Fixes & Improvements

  • Fixed heatmap cell ordering to match axis labels
  • Fixed horizontal grouped bar charts crash
  • Fixed heatmap alpha calculation overflow
  • Improved code quality with comprehensive docstrings
August 24, 2025
v1.2.2

🎨 Enhanced HeatMap Text Readability

  • Improved text visibility for low-value cells
  • Values < 15% now display with black text for guaranteed readability
  • Values ≥ 15% use smart brightness-based contrast
  • Zero breaking changes - fully backward compatible
August 18, 2025
v1.2.0

🔥 Heat Map Chart Support

Visualize 2D data patterns with professional heat maps!
  • Comprehensive heat map implementation with customizable styling
  • Advanced color mapping with smooth gradients
  • Wave-effect animations with staggered cell appearance
  • Smart value visualization with automatic contrast detection
CristalyseChart()
  .data(salesData)
  .mappingHeatMap(x: 'month', y: 'region', value: 'revenue')
  .geomHeatMap(
    cellSpacing: 2.0,
    colorGradient: [Colors.red, Colors.yellow, Colors.green],
    showValues: true,
  )
  .build()
View heat map documentation
August 5, 2025
v1.1.0

🎯 Advanced Label Formatting

Professional data visualization with NumberFormat integration!
  • Full callback-based label formatting system
  • Seamless integration with Flutter’s intl package
  • Currency, percentages, compact notation support
CristalyseChart()
  .scaleYContinuous(
    labels: NumberFormat.simpleCurrency().format  // $1,234.56
  )
  .build()
🙏 Feature authored by @davidlrichmond
July 31, 2025
v1.0.1

Fixed

  • Grouped Bar Chart Alignment: Fixed positioning of grouped bars on ordinal scales
  • Bars now center properly on tick marks
  • Thanks @davidlrichmond!
July 10, 2025
v1.0.0

🥧 Pie & Donut Charts

Major v1.0 release with comprehensive pie chart support!
  • Full pie chart and donut chart implementation
  • Smooth slice animations with staggered timing
  • Smart label positioning with percentage display
  • Exploded slice functionality for emphasis
  • New .mappingPie() and .geomPie() API
CristalyseChart()
  .mappingPie(value: 'revenue', category: 'department')
  .geomPie(
    outerRadius: 120.0,
    innerRadius: 60.0,  // Creates donut
    showLabels: true,
  )
  .build()
View pie chart documentation
July 4, 2025
v0.9.4 - v0.9.3

📖 Documentation Site Launch

  • docs.cristalyse.com is now live!
  • Comprehensive guides, examples, and API reference
  • Improved web WASM compatibility
July 3, 2025
v0.9.2

Advanced Pan Control System

  • Fixed chart position reset bug
  • Infinite panning capability in any direction
  • Visual clipping implementation for clean boundaries
  • Selective axis panning with updateXDomain and updateYDomain
Perfect for exploring large datasets!
July 2, 2025
v0.9.0

Enhanced SVG Export

  • Professional-quality vector graphics output
  • Support for all chart types
  • Perfect for presentations and reports
  • Editable in Figma, Adobe Illustrator, etc.
July 2, 2025
v0.8.0

🎨 Area Chart Support

Visualize volume and trends with area charts!
  • Comprehensive AreaGeometry with customizable styling
  • Progressive area animations
  • Multi-series support with transparency
  • Dual Y-axis compatibility
CristalyseChart()
  .geomArea(
    strokeWidth: 2.0,
    alpha: 0.3,
    fillArea: true,
  )
  .build()
View area chart documentation
June 30, 2025
v0.7.0

Interactive Panning System

  • Persistent pan state across gestures
  • Real-time visible range synchronization
  • Comprehensive PanConfig API with callbacks
  • Perfect for time series data exploration
June 21, 2025
v0.6.0

🎯 Interactive Chart Layer

Tooltips, hover, and click interactions!
  • New interaction system for user engagement
  • Flexible tooltip system with TooltipConfig
  • onHover, onExit, and onTap callbacks
CristalyseChart()
  .interaction(
    tooltip: TooltipConfig(
      builder: (point) => MyCustomTooltip(point: point),
    ),
    click: ClickConfig(
      onTap: (point) => showDetails(point),
    ),
  )
  .build()
View interaction documentation
June 14, 2025
v0.5.0

🚀 Dual Y-Axis Support

Professional business dashboards unlocked!
  • Independent left and right Y-axes
  • New .mappingY2() and .scaleY2Continuous() methods
  • Perfect for Revenue vs Conversion Rate charts
  • Fixed ordinal scale support for lines and points
CristalyseChart()
  .mapping(x: 'month', y: 'revenue')
  .mappingY2('conversion_rate')
  .geomBar(yAxis: YAxis.primary)
  .geomLine(yAxis: YAxis.secondary)
  .scaleY2Continuous(min: 0, max: 100)
  .build()
View dual axis documentation
June 12, 2025
v0.4.4 - v0.4.0

Bar Charts & Theming

  • Stacked Bar Charts: Full support with progressive animations
  • Enhanced Theming: Solarized Light/Dark themes
  • Color Palettes: Warm, cool, and pastel options
  • Horizontal Bars: Via coordFlip() method
June 8, 2025
v0.2.0

Line Charts & Animations

  • Line chart support with geomLine()
  • Configurable animations with curves
  • Multi-series support with color grouping
  • Progressive line drawing animations
  • Dark theme support
June 8, 2025
v0.1.0

🎉 Initial Release

Cristalyse is born!
  • Basic scatter plot support
  • Grammar of graphics API
  • Linear scales for continuous data
  • Light and dark themes
  • Cross-platform Flutter support