Skip to main content

Overview

Custom themes in Cristalyse offer complete flexibility to express your brand’s unique style. Design themes with specific colors, typography, spacing, and other visual elements to ensure consistency across all charts.

Designing a Custom Theme

Theme Properties

Customize various properties:
  • Colors: Define primary, secondary, background, and accent colors.
  • Typography: Adjust fonts, sizes, and weights.
  • Dimensions: Set padding, margins, and element sizes.

Creating Themes

Design a theme matching your brand:
final customTheme = ChartTheme(
  backgroundColor: const Color(0xFFF0F0F0),
  plotBackgroundColor: Colors.white,
  primaryColor: const Color(0xFF0050AC), // Brand primary
  borderColor: const Color(0xFFCCCCCC),
  gridColor: const Color(0xFFE0E0E0),
  axisColor: const Color(0xFF333333),
  gridWidth: 1.0,
  axisWidth: 1.5,
  pointSizeDefault: 6.0,
  colorPalette: [
    const Color(0xFF0050AC), // Primary
    const Color(0xFFFF9500), // Accent
    const Color(0xFF5A2EA6), // Secondary
    const Color(0xFF34C759), // Success
  ],
  padding: const EdgeInsets.all(20),
  axisTextStyle: const TextStyle(
    fontSize: 12,
    color: Color(0xFF333333),
    fontWeight: FontWeight.w400,
  ),
);

Applying Themes

Apply themes in charts:
CristalyseChart()
  .data(chartData)
  .mapping(x: 'month', y: 'visitors')
  .geomBar()
  .theme(customTheme)
  .build()

Theme Variants

Light and Dark Modes

Create matching themes for light and dark modes:
final lightTheme = ChartTheme.defaultTheme();
final darkTheme = ChartTheme.darkTheme();

CristalyseChart()
  .data(data)
  .mapping(x: 'category', y: 'count')
  .geomBar()
  .theme(isDarkMode ? darkTheme : lightTheme)
  .build();

Responsive Themes

Adjust theme properties based on screen size:
ChartTheme responsiveTheme(BuildContext context) {
  final width = MediaQuery.of(context).size.width;
  if (width > 1200) { // Desktop
    return ChartTheme.defaultTheme().copyWith(
      padding: const EdgeInsets.all(32),
      axisTextStyle: const TextStyle(fontSize: 14),
    );
  } else if (width > 800) { // Tablet
    return ChartTheme.defaultTheme().copyWith(
      padding: const EdgeInsets.all(24),
    );
  } else { // Mobile
    return ChartTheme.defaultTheme().copyWith(
      padding: const EdgeInsets.all(16),
      axisTextStyle: const TextStyle(fontSize: 10),
    );
  }
}

Gradient Themes (Experimental)

New Experimental Feature in v1.6.0:Create stunning gradient effects for your charts with category-specific gradient mapping.Not advisable for Production use as of v1.6.0.

Creating Gradient Themes

Define gradients for specific categories in your data:
// Create gradients map for use with .customPalette()
final productGradients = {
  // Linear gradients for different product tiers
  'Enterprise': const LinearGradient(
    colors: [Color(0xFF8B5CF6), Color(0xFFA78BFA)],
    begin: Alignment.bottomLeft,
    end: Alignment.topRight,
    stops: [0.0, 1.0],
  ),
  'Professional': const LinearGradient(
    colors: [Color(0xFF3B82F6), Color(0xFF60A5FA)],
    begin: Alignment.bottomCenter,
    end: Alignment.topCenter,
  ),
  // Radial gradient for special categories
  'Premium': const RadialGradient(
    colors: [Color(0xFFDC2626), Color(0xFFEF4444), Color(0xFFFCA5A5)],
    center: Alignment.center,
    radius: 1.2,
    stops: [0.0, 0.7, 1.0],
  ),
  // Sweep gradient for dynamic effects
  'Special': const SweepGradient(
    colors: [
      Color(0xFFEAB308),
      Color(0xFFF59E0B),
      Color(0xFFDC2626),
      Color(0xFFEAB308),
    ],
    center: Alignment.center,
    startAngle: 0.0,
    endAngle: 2 * math.pi,
  ),
};

Gradient Types

Linear Gradients

Smooth color transitions along a line:
const LinearGradient(
  colors: [Color(0xFF4F46E5), Color(0xFF7C3AED)],
  begin: Alignment.bottomCenter, // Start point
  end: Alignment.topCenter,      // End point
  stops: [0.0, 1.0],            // Optional color stops
)

Radial Gradients

Circular color transitions from center outward:
const RadialGradient(
  colors: [Color(0xFF059669), Color(0xFF10B981)],
  center: Alignment.center,    // Center point
  radius: 0.8,                // Radius (0.0 to 1.0+)
  focal: Alignment.center,     // Optional focal point
  focalRadius: 0.1,           // Optional focal radius
)

Sweep Gradients

Angular color transitions around a center point:
const SweepGradient(
  colors: [Color(0xFFEAB308), Color(0xFFF59E0B), Color(0xFFEAB308)],
  center: Alignment.center,     // Center point
  startAngle: 0.0,             // Start angle in radians
  endAngle: 2 * math.pi,       // End angle in radians
)

Applying Gradient Themes

Use gradient themes with color mapping:
CristalyseChart()
  .data(productData)
  .mapping(x: 'month', y: 'sales', color: 'tier') // Color mapping required
  .geomBar()
  .customPalette(categoryGradients: productGradients)
  .build()
Important: Gradients only work when you specify color mapping in your chart. Without color: 'columnName', charts will use solid colors from the color palette.

Supported Chart Types

Gradient themes currently support:
  • Bar Charts - Full gradient support with alpha blending
  • Point/Scatter Charts - Gradient fills for data points
  • Line Charts - Not yet supported (solid colors only)
  • Area Charts - Not yet supported (solid colors only)
  • Bubble Charts - Not yet supported (solid colors only)

Advanced Customization

Theme Extensions

Add additional properties using extensions:
extension ChartThemeExtras on ChartTheme {
  ChartTheme get withCustomColors => copyWith(
    primaryColor: Colors.teal,
    colorPalette: [Colors.teal, Colors.amber, Colors.purple],
  );
}

final extendedTheme = ChartTheme.defaultTheme().withCustomColors;

Dynamic Themes

Change themes in response to user actions and preferences:
class ThemeSwitcher extends StatefulWidget {
  final ChartTheme lightTheme;
  final ChartTheme darkTheme;
  final List<Map<String, dynamic>> data;

  const ThemeSwitcher({
    required this.lightTheme,
    required this.darkTheme,
    required this.data,
    super.key,
  });

  @override
  _ThemeSwitcherState createState() => _ThemeSwitcherState();
}

class _ThemeSwitcherState extends State<ThemeSwitcher> {
  bool isDark = false;

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        Switch(
          value: isDark,
          onChanged: (value) {
            setState(() {
              isDark = value;
            });
          },
        ),
        Expanded(
          child: CristalyseChart()
            .data(widget.data)
            .mapping(x: 'time', y: 'value')
            .geomLine()
            .theme(isDark ? widget.darkTheme : widget.lightTheme)
            .build(),
        ),
      ],
    );
  }
}

Corporate Branding

Match your organization’s color scheme and brand identity.

Responsive Design

Automatic adjustments for different device sizes and resolutions.

Theme Persistence

Save and restore user preferences for consistent experiences.

Interactive Theming

Real-time adjustments and theme switching based on user actions.

Next Steps

Conclusion

Utilize custom themes to ensure charts are a seamless part of your application’s visual identity. By leveraging Cristalyse’s flexible theming capabilities, create charts that not only convey data but also resonate with your brand’s aesthetics.
I