Overview

Scatter plots are perfect for exploring relationships between two continuous variables. Cristalyse’s scatter plots support multi-dimensional encoding through color, size, and shape mappings.


Basic Scatter Plot

The simplest scatter plot maps X and Y coordinates to data:

final data = [
  {'x': 1, 'y': 2},
  {'x': 2, 'y': 3},
  {'x': 3, 'y': 1},
  {'x': 4, 'y': 4},
];

CristalyseChart()
  .data(data)
  .mapping(x: 'x', y: 'y')
  .geomPoint()
  .scaleXContinuous()
  .scaleYContinuous()
  .build()

Color Mapping

Add categorical grouping with color:

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'},
];

CristalyseChart()
  .data(data)
  .mapping(x: 'x', y: 'y', color: 'category')
  .geomPoint(size: 8.0, alpha: 0.8)
  .scaleXContinuous()
  .scaleYContinuous()
  .theme(ChartTheme.defaultTheme())
  .build()

Size Mapping

Encode a third dimension with point size:

final salesData = [
  {'revenue': 100, 'deals': 25, 'region': 'North', 'team_size': 5},
  {'revenue': 150, 'deals': 30, 'region': 'South', 'team_size': 8},
  {'revenue': 80, 'deals': 20, 'region': 'East', 'team_size': 3},
  {'revenue': 200, 'deals': 35, 'region': 'West', 'team_size': 12},
];

CristalyseChart()
  .data(salesData)
  .mapping(
    x: 'revenue', 
    y: 'deals', 
    color: 'region', 
    size: 'team_size'
  )
  .geomPoint(alpha: 0.7)
  .scaleXContinuous(min: 0)
  .scaleYContinuous(min: 0)
  .build()

Point Styling

Shape Options

Customize point shapes for different data categories:

CristalyseChart()
  .data(data)
  .mapping(x: 'x', y: 'y')
  .geomPoint(
    size: 10.0,
    shape: PointShape.triangle,  // circle, square, triangle, diamond
    borderWidth: 2.0,
    alpha: 0.8,
  )
  .build()

Available shapes:

  • PointShape.circle (default)
  • PointShape.square
  • PointShape.triangle
  • PointShape.diamond

Advanced Styling

CristalyseChart()
  .data(data)
  .mapping(x: 'x', y: 'y', color: 'category')
  .geomPoint(
    size: 12.0,
    alpha: 0.8,
    shape: PointShape.circle,
    borderWidth: 1.5,        // Border thickness
    color: Colors.blue,      // Override color mapping
  )
  .build()

Multi-Dimensional Analysis

Business Intelligence Example

Analyze sales performance across multiple dimensions:

final performanceData = [
  {
    'revenue': 150000,
    'customer_satisfaction': 4.2,
    'region': 'North America',
    'deal_count': 45,
    'rep_experience': 3.5,
  },
  {
    'revenue': 120000,
    'customer_satisfaction': 3.8,
    'region': 'Europe',
    'deal_count': 38,
    'rep_experience': 2.1,
  },
  {
    'revenue': 180000,
    'customer_satisfaction': 4.6,
    'region': 'Asia Pacific',
    'deal_count': 52,
    'rep_experience': 5.2,
  },
];

CristalyseChart()
  .data(performanceData)
  .mapping(
    x: 'revenue',
    y: 'customer_satisfaction',
    color: 'region',
    size: 'deal_count',
  )
  .geomPoint(alpha: 0.7, borderWidth: 1.0)
  .scaleXContinuous(min: 0)
  .scaleYContinuous(min: 1, max: 5)
  .theme(ChartTheme.defaultTheme())
  .build()

Interactive Scatter Plots

Tooltips

Add rich hover information:

CristalyseChart()
  .data(performanceData)
  .mapping(x: 'revenue', y: 'customer_satisfaction', color: 'region')
  .geomPoint(size: 8.0)
  .interaction(
    tooltip: TooltipConfig(
      builder: (point) {
        final region = point.getDisplayValue('region');
        final revenue = point.getDisplayValue('revenue');
        final satisfaction = point.getDisplayValue('customer_satisfaction');
        
        return Container(
          padding: EdgeInsets.all(12),
          decoration: BoxDecoration(
            color: Colors.black87,
            borderRadius: BorderRadius.circular(8),
          ),
          child: Column(
            mainAxisSize: MainAxisSize.min,
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              Text(
                region,
                style: TextStyle(
                  color: Colors.white,
                  fontWeight: FontWeight.bold,
                ),
              ),
              SizedBox(height: 4),
              Text(
                'Revenue: \$${revenue}',
                style: TextStyle(color: Colors.white),
              ),
              Text(
                'Satisfaction: ${satisfaction}/5',
                style: TextStyle(color: Colors.white),
              ),
            ],
          ),
        );
      },
    ),
  )
  .build()

Click Handlers

React to point selection:

CristalyseChart()
  .data(data)
  .mapping(x: 'x', y: 'y', color: 'category')
  .geomPoint(size: 8.0)
  .interaction(
    click: ClickConfig(
      onTap: (point) {
        print('Selected point: ${point.data}');
        // Navigate to detail view
        // Show dialog
        // Update other charts
      },
    ),
  )
  .build()

Animation

Entrance Animation

Animate points appearing:

CristalyseChart()
  .data(data)
  .mapping(x: 'x', y: 'y', color: 'category')
  .geomPoint(size: 8.0, alpha: 0.8)
  .animate(
    duration: Duration(milliseconds: 800),
    curve: Curves.elasticOut,
  )
  .build()

Staggered Animation

Points appear in sequence:

CristalyseChart()
  .data(data)
  .mapping(x: 'x', y: 'y')
  .geomPoint(size: 10.0)
  .animate(
    duration: Duration(milliseconds: 1200),
    curve: Curves.easeInOutCubic,
  )
  .build()

Dual Y-Axis Support

Use scatter plots on secondary Y-axis:

final mixedData = [
  {'quarter': 'Q1', 'revenue': 120, 'efficiency': 85, 'satisfaction': 4.2},
  {'quarter': 'Q2', 'revenue': 150, 'efficiency': 92, 'satisfaction': 4.5},
  {'quarter': 'Q3', 'revenue': 110, 'efficiency': 78, 'satisfaction': 3.9},
];

CristalyseChart()
  .data(mixedData)
  .mapping(x: 'quarter', y: 'revenue')
  .mappingY2('satisfaction')
  .geomBar(yAxis: YAxis.primary)  // Revenue bars
  .geomPoint(                     // Satisfaction points
    yAxis: YAxis.secondary,
    size: 10.0,
    color: Colors.orange,
  )
  .scaleXOrdinal()
  .scaleYContinuous(min: 0)
  .scaleY2Continuous(min: 1, max: 5)
  .build()

Best Practices

Common Use Cases

Correlation Analysis

Explore relationships between variables

Outlier Detection

Identify unusual data points visually

Clustering

Discover natural groupings in data

Multi-variate Analysis

Analyze 3-4 dimensions simultaneously

Next Steps