Overview

Cristalyse provides built-in legend support that automatically generates beautiful legends from your chart’s color mapping data. With just .legend(), you get intelligent symbol generation, smart positioning, and full dark mode compatibility.
New in v1.5.0: Built-in legend support with zero configuration required!

Quick Start

Add a legend to any chart with color mapping in just one line:
CristalyseChart()
  .data(salesData)
  .mapping(x: 'quarter', y: 'revenue', color: 'product')
  .geomBar(style: BarStyle.grouped)
  .legend() // ✨ That's it! Auto-positioned legend with product categories
  .build();

Key Features

Zero Configuration

Works automatically with smart defaults - just add .legend()

8 Positioning Options

Flexible positioning: corners, edges, with auto-orientation

Smart Symbol Detection

Automatically matches your chart type: squares, circles, lines

Dark Mode Ready

Legend text adapts automatically to light and dark themes

Positioning

Basic Positioning

Control legend placement with the position parameter:
// Bottom legend (horizontal layout)
.legend(position: LegendPosition.bottom)

// Right side legend (vertical layout)  
.legend(position: LegendPosition.right)

// Top-right corner (default)
.legend(position: LegendPosition.topRight)

All Position Options

Corner Positions

  • LegendPosition.topLeft
  • LegendPosition.topRight (default)
  • LegendPosition.bottomLeft
  • LegendPosition.bottomRight

Edge Positions

  • LegendPosition.top
  • LegendPosition.bottom
  • LegendPosition.left
  • LegendPosition.right

Visual Examples

CristalyseChart()
  .data(data)
  .mapping(x: 'month', y: 'sales', color: 'region')
  .geomBar()
  .legend() // Default: topRight position
  .build();
Legend appears in the top-right corner with vertical layout.

Symbol Generation

Legends automatically choose appropriate symbols based on your chart type:
Chart TypeSymbolDescription
Bar Charts◼ SquareSolid colored squares for categorical bars
Line Charts━ LineHorizontal line segments matching chart lines
Scatter Plots● CircleCircular symbols for point data
Area Charts━ LineLine symbols representing area boundaries
Bubble Charts● CircleCircular symbols for bubble data
Symbol selection is automatic but can be overridden with custom styling if needed.

Dark Mode Support

Legend text automatically adapts to your chart theme:
CristalyseChart()
  .data(data)
  .mapping(x: 'month', y: 'sales', color: 'product')
  .geomBar()
  .theme(ChartTheme.defaultTheme()) // Light theme
  .legend() // Dark text on light background
  .build();
Theme Inheritance: Legend text uses theme.axisColor for perfect contrast in any theme.

Custom Styling

Background and Appearance

Add custom styling for professional dashboards:
CristalyseChart()
  .data(data)
  .mapping(x: 'quarter', y: 'revenue', color: 'product')
  .geomBar()
  .legend(
    position: LegendPosition.right,
    backgroundColor: Colors.white.withValues(alpha: 0.95),
    borderRadius: 8.0,
    symbolSize: 14.0,
    itemSpacing: 12.0,
  )
  .build();

Text Styling

Customize legend text while preserving theme colors:
.legend(
  textStyle: TextStyle(
    fontSize: 13,
    fontWeight: FontWeight.w600,
    // Color automatically inherits from theme
  ),
  symbolSize: 16.0,
)
Theme Colors: Avoid hardcoding text colors. Let the legend inherit from your theme for proper dark mode support.

All Styling Options

ParameterTypeDefaultDescription
positionLegendPositiontopRightLegend placement
backgroundColorColor?nullLegend background color
textStyleTextStyle?nullText styling (inherits color from theme)
symbolSizedouble12.0Size of legend symbols
itemSpacingdouble8.0Space between legend items
spacingdouble12.0Space between legend and chart
borderRadiusdouble4.0Background border radius

Real-World Examples

Dashboard Analytics

Perfect for executive dashboards with multiple data series:
CristalyseChart()
  .data(regionalSales)
  .mapping(x: 'month', y: 'revenue', color: 'region')
  .geomLine(strokeWidth: 3.0)
  .geomPoint(size: 6.0)
  .legend(
    position: LegendPosition.bottom,
    backgroundColor: Colors.grey.shade50,
    borderRadius: 12.0,
  )
  .build();

Mobile-Optimized

Bottom legends work great on mobile devices:
CristalyseChart()
  .data(performanceData)
  .mapping(x: 'date', y: 'value', color: 'metric')
  .geomArea(alpha: 0.7)
  .legend(position: LegendPosition.bottom) // Mobile-friendly
  .build();

Dark Theme Dashboard

Professional dark mode with custom styling:
CristalyseChart()
  .data(analyticsData)
  .mapping(x: 'week', y: 'users', color: 'platform')
  .geomBar(style: BarStyle.grouped)
  .theme(ChartTheme.darkTheme())
  .legend(
    position: LegendPosition.topRight,
    backgroundColor: Colors.black.withValues(alpha: 0.7),
    borderRadius: 8.0,
    symbolSize: 14.0,
  )
  .build();

Best Practices

Advanced Usage

Multi-Series Line Charts

Perfect for time-series data with multiple metrics:
CristalyseChart()
  .data(timeSeriesData)
  .mapping(x: 'date', y: 'value', color: 'metric')
  .geomLine(strokeWidth: 2.5)
  .scaleXContinuous()
  .scaleYContinuous(
    labels: (value) => '${value.toStringAsFixed(1)}K',
  )
  .legend(position: LegendPosition.topLeft)
  .build();

Grouped Bar Charts with Custom Colors

Combine custom palettes with legends:
final brandColors = {
  'iOS': const Color(0xFF007ACC),
  'Android': const Color(0xFF3DDC84),
  'Web': const Color(0xFFFF6B35),
};

CristalyseChart()
  .data(platformData)
  .mapping(x: 'quarter', y: 'users', color: 'platform')
  .geomBar(style: BarStyle.grouped)
  .customPalette(categoryColors: brandColors)
  .legend(position: LegendPosition.right)
  .build();

Requirements

Color Mapping Required: Legends only work when you have a color parameter in your .mapping() call.
// <Icon icon="check" /> Works - has color mapping
.mapping(x: 'month', y: 'sales', color: 'product')
.legend()

// <Icon icon="x" /> Won't show - no color mapping
.mapping(x: 'month', y: 'sales')
.legend() // Legend will be empty

Migration Guide

From Manual Legends

If you were manually creating legends, you can now use the built-in functionality:
// Manual legend creation with custom widgets
Column(
  children: [
    Row(
      children: [
        Container(width: 12, height: 12, color: Colors.blue),
        SizedBox(width: 8),
        Text('Product A'),
      ],
    ),
    // ... more manual legend items
    Expanded(child: CristalyseChart()...),
  ],
)

Troubleshooting

What’s Next?

  • Learn about Custom Themes to create branded chart experiences
  • Explore Interactions to add tooltips and hover effects
  • Check out Export to save charts with legends as SVG files
Pro Tip: Legends work seamlessly with all chart types and export formats. Your exported SVGs will include the positioned legends automatically!