use super::config::{
ChartType, ColorScheme, CustomVisualization, DashboardLayout, ExportFormat, ReportTemplate,
VisualizationConfig,
};
use super::data::{DashboardData, RealtimeMetrics, TimeSeriesData};
use crate::DeviceResult;
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use std::time::{Duration, SystemTime};
pub struct DashboardRenderer {
config: VisualizationConfig,
chart_generators: HashMap<ChartType, Box<dyn ChartGenerator + Send + Sync>>,
layout_manager: LayoutManager,
export_engine: ExportEngine,
theme_manager: ThemeManager,
}
pub trait ChartGenerator {
fn generate(&self, data: &ChartData, options: &ChartOptions) -> DeviceResult<Chart>;
fn supports_interactivity(&self) -> bool;
fn get_supported_formats(&self) -> Vec<ChartFormat>;
}
#[derive(Debug, Clone)]
pub struct ChartData {
pub data_type: ChartDataType,
pub series: Vec<DataSeries>,
pub metadata: ChartMetadata,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum ChartDataType {
TimeSeries,
Categorical,
Numerical,
Correlation,
Distribution,
Geospatial,
Custom(String),
}
#[derive(Debug, Clone)]
pub struct DataSeries {
pub name: String,
pub data_points: Vec<DataPoint>,
pub series_type: SeriesType,
pub styling: SeriesStyling,
}
#[derive(Debug, Clone)]
pub struct DataPoint {
pub x: DataValue,
pub y: DataValue,
pub z: Option<DataValue>, pub metadata: HashMap<String, String>,
}
#[derive(Debug, Clone)]
pub enum DataValue {
Number(f64),
Text(String),
Timestamp(SystemTime),
Boolean(bool),
Array(Vec<f64>),
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum SeriesType {
Line,
Bar,
Scatter,
Area,
Candlestick,
Bubble,
Custom(String),
}
#[derive(Debug, Clone)]
pub struct SeriesStyling {
pub color: String,
pub line_width: f64,
pub marker_size: f64,
pub opacity: f64,
pub fill_pattern: Option<String>,
pub custom_styles: HashMap<String, String>,
}
#[derive(Debug, Clone)]
pub struct ChartMetadata {
pub title: String,
pub subtitle: Option<String>,
pub x_axis_label: String,
pub y_axis_label: String,
pub data_source: String,
pub last_updated: SystemTime,
pub chart_id: String,
}
#[derive(Debug, Clone)]
pub struct ChartOptions {
pub width: u32,
pub height: u32,
pub interactive: bool,
pub animation: bool,
pub legend: LegendOptions,
pub axes: AxesOptions,
pub grid: GridOptions,
pub tooltip: TooltipOptions,
pub custom_options: HashMap<String, String>,
}
#[derive(Debug, Clone)]
pub struct LegendOptions {
pub show: bool,
pub position: LegendPosition,
pub orientation: LegendOrientation,
pub styling: HashMap<String, String>,
}
#[derive(Debug, Clone, PartialEq)]
pub enum LegendPosition {
Top,
Bottom,
Left,
Right,
TopLeft,
TopRight,
BottomLeft,
BottomRight,
Custom { x: f64, y: f64 },
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum LegendOrientation {
Horizontal,
Vertical,
}
#[derive(Debug, Clone)]
pub struct AxesOptions {
pub x_axis: AxisOptions,
pub y_axis: AxisOptions,
pub y2_axis: Option<AxisOptions>, }
#[derive(Debug, Clone)]
pub struct AxisOptions {
pub show: bool,
pub title: String,
pub min: Option<f64>,
pub max: Option<f64>,
pub tick_interval: Option<f64>,
pub tick_format: String,
pub logarithmic: bool,
pub grid_lines: bool,
}
#[derive(Debug, Clone)]
pub struct GridOptions {
pub show: bool,
pub major_lines: bool,
pub minor_lines: bool,
pub line_style: String,
pub color: String,
pub opacity: f64,
}
#[derive(Debug, Clone)]
pub struct TooltipOptions {
pub show: bool,
pub format: String,
pub background_color: String,
pub border_color: String,
pub follow_mouse: bool,
}
#[derive(Debug, Clone)]
pub struct Chart {
pub chart_id: String,
pub chart_type: ChartType,
pub format: ChartFormat,
pub content: ChartContent,
pub metadata: ChartMetadata,
pub interactive_features: Vec<InteractiveFeature>,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum ChartFormat {
SVG,
PNG,
JPEG,
HTML,
Canvas,
WebGL,
PDF,
Custom(String),
}
#[derive(Debug, Clone)]
pub enum ChartContent {
Image(Vec<u8>),
SVG(String),
HTML(String),
JSON(String),
Custom(String, Vec<u8>),
}
#[derive(Debug, Clone)]
pub enum InteractiveFeature {
Zoom,
Pan,
Hover,
Click,
Brush,
Crossfilter,
Animation,
Custom(String),
}
pub struct LayoutManager {
layout_type: DashboardLayout,
grid_config: GridConfiguration,
responsive_rules: Vec<ResponsiveRule>,
layout_cache: HashMap<String, LayoutResult>,
}
#[derive(Debug, Clone)]
pub struct GridConfiguration {
pub columns: usize,
pub rows: usize,
pub gap: f64,
pub padding: f64,
pub responsive_breakpoints: Vec<Breakpoint>,
}
#[derive(Debug, Clone)]
pub struct Breakpoint {
pub width: u32,
pub columns: usize,
pub chart_height: u32,
}
#[derive(Debug, Clone)]
pub struct ResponsiveRule {
pub condition: ResponsiveCondition,
pub action: ResponsiveAction,
}
#[derive(Debug, Clone)]
pub enum ResponsiveCondition {
ScreenWidth { min: Option<u32>, max: Option<u32> },
ScreenHeight { min: Option<u32>, max: Option<u32> },
DeviceType(DeviceType),
Custom(String),
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum DeviceType {
Desktop,
Tablet,
Mobile,
TV,
Custom(String),
}
#[derive(Debug, Clone)]
pub enum ResponsiveAction {
ChangeLayout(DashboardLayout),
AdjustChartSize { width: u32, height: u32 },
HideCharts(Vec<String>),
ReorderCharts(Vec<String>),
Custom(String),
}
#[derive(Debug, Clone)]
pub struct LayoutResult {
pub layout_type: DashboardLayout,
pub chart_positions: Vec<ChartPosition>,
pub total_width: u32,
pub total_height: u32,
pub responsive_applied: Vec<String>,
}
#[derive(Debug, Clone)]
pub struct ChartPosition {
pub chart_id: String,
pub x: u32,
pub y: u32,
pub width: u32,
pub height: u32,
pub z_index: i32,
}
pub struct ExportEngine {
export_formats: Vec<ExportFormat>,
template_engine: TemplateEngine,
format_converters: HashMap<ExportFormat, Box<dyn FormatConverter + Send + Sync>>,
}
pub trait FormatConverter {
fn convert(&self, content: &ExportContent, options: &ExportOptions) -> DeviceResult<Vec<u8>>;
fn get_mime_type(&self) -> String;
fn get_file_extension(&self) -> String;
}
#[derive(Debug, Clone)]
pub struct ExportContent {
pub charts: Vec<Chart>,
pub data_tables: Vec<DataTable>,
pub text_sections: Vec<TextSection>,
pub metadata: ExportMetadata,
}
#[derive(Debug, Clone)]
pub struct DataTable {
pub table_id: String,
pub title: String,
pub headers: Vec<String>,
pub rows: Vec<Vec<String>>,
pub formatting: TableFormatting,
}
#[derive(Debug, Clone)]
pub struct TableFormatting {
pub header_style: HashMap<String, String>,
pub row_style: HashMap<String, String>,
pub alternating_rows: bool,
pub borders: bool,
}
#[derive(Debug, Clone)]
pub struct TextSection {
pub section_id: String,
pub title: String,
pub content: String,
pub format_type: TextFormatType,
pub styling: HashMap<String, String>,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum TextFormatType {
PlainText,
Markdown,
HTML,
LaTeX,
Custom(String),
}
#[derive(Debug, Clone)]
pub struct ExportMetadata {
pub title: String,
pub author: String,
pub creation_date: SystemTime,
pub description: String,
pub version: String,
pub custom_fields: HashMap<String, String>,
}
#[derive(Debug, Clone)]
pub struct ExportOptions {
pub format: ExportFormat,
pub quality: ExportQuality,
pub compression: bool,
pub include_data: bool,
pub include_metadata: bool,
pub page_settings: PageSettings,
pub custom_options: HashMap<String, String>,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum ExportQuality {
Low,
Medium,
High,
Maximum,
Custom(u32),
}
#[derive(Debug, Clone)]
pub struct PageSettings {
pub page_size: PageSize,
pub orientation: PageOrientation,
pub margins: PageMargins,
pub header: Option<String>,
pub footer: Option<String>,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum PageSize {
A4,
A3,
Letter,
Legal,
Custom { width: u32, height: u32 },
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum PageOrientation {
Portrait,
Landscape,
}
#[derive(Debug, Clone)]
pub struct PageMargins {
pub top: u32,
pub bottom: u32,
pub left: u32,
pub right: u32,
}
pub struct TemplateEngine {
templates: HashMap<String, ReportTemplate>,
template_cache: HashMap<String, CompiledTemplate>,
variable_resolver: VariableResolver,
}
#[derive(Debug, Clone)]
pub struct CompiledTemplate {
pub template_id: String,
pub template_content: String,
pub variables: Vec<TemplateVariable>,
pub sections: Vec<TemplateSection>,
}
#[derive(Debug, Clone)]
pub struct TemplateVariable {
pub name: String,
pub variable_type: VariableType,
pub default_value: Option<String>,
pub required: bool,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum VariableType {
Text,
Number,
Date,
Chart,
Table,
Image,
Custom(String),
}
#[derive(Debug, Clone)]
pub struct TemplateSection {
pub section_id: String,
pub section_type: String,
pub content: String,
pub variables: Vec<String>,
pub conditional: Option<String>,
}
pub struct VariableResolver {
resolvers: HashMap<String, Box<dyn VariableProvider + Send + Sync>>,
}
pub trait VariableProvider {
fn resolve(&self, variable_name: &str, context: &ResolverContext) -> DeviceResult<String>;
fn get_supported_variables(&self) -> Vec<String>;
}
#[derive(Debug, Clone)]
pub struct ResolverContext {
pub dashboard_data: DashboardData,
pub export_options: ExportOptions,
pub user_variables: HashMap<String, String>,
}
pub struct ThemeManager {
current_theme: Theme,
available_themes: HashMap<String, Theme>,
custom_css: HashMap<String, String>,
}
#[derive(Debug, Clone)]
pub struct Theme {
pub theme_id: String,
pub theme_name: String,
pub color_palette: ColorPalette,
pub typography: Typography,
pub spacing: Spacing,
pub borders: BorderStyles,
pub shadows: ShadowStyles,
}
#[derive(Debug, Clone)]
pub struct ColorPalette {
pub primary: String,
pub secondary: String,
pub accent: String,
pub background: String,
pub surface: String,
pub text_primary: String,
pub text_secondary: String,
pub success: String,
pub warning: String,
pub error: String,
pub info: String,
pub chart_colors: Vec<String>,
}
#[derive(Debug, Clone)]
pub struct Typography {
pub font_family: String,
pub font_sizes: HashMap<String, u32>,
pub font_weights: HashMap<String, u32>,
pub line_heights: HashMap<String, f64>,
}
#[derive(Debug, Clone)]
pub struct Spacing {
pub base_unit: u32,
pub small: u32,
pub medium: u32,
pub large: u32,
pub extra_large: u32,
}
#[derive(Debug, Clone)]
pub struct BorderStyles {
pub width: HashMap<String, u32>,
pub style: HashMap<String, String>,
pub color: HashMap<String, String>,
pub radius: HashMap<String, u32>,
}
#[derive(Debug, Clone)]
pub struct ShadowStyles {
pub box_shadows: HashMap<String, String>,
pub text_shadows: HashMap<String, String>,
}
impl DashboardRenderer {
pub fn new(config: VisualizationConfig) -> Self {
let mut chart_generators: HashMap<ChartType, Box<dyn ChartGenerator + Send + Sync>> =
HashMap::new();
chart_generators.insert(ChartType::LineChart, Box::new(LineChartGenerator::new()));
chart_generators.insert(ChartType::BarChart, Box::new(BarChartGenerator::new()));
chart_generators.insert(ChartType::HeatMap, Box::new(HeatMapGenerator::new()));
Self {
config: config.clone(),
chart_generators,
layout_manager: LayoutManager::new(config.dashboard_layout.clone()),
export_engine: ExportEngine::new(),
theme_manager: ThemeManager::new(config.color_scheme),
}
}
pub async fn render_dashboard(&self, data: &DashboardData) -> DeviceResult<DashboardView> {
let mut charts = Vec::new();
for chart_type in &self.config.chart_types {
if let Some(generator) = self.chart_generators.get(chart_type) {
let chart_data = self.prepare_chart_data(data, chart_type)?;
let chart_options = self.create_chart_options(chart_type)?;
let chart = generator.generate(&chart_data, &chart_options)?;
charts.push(chart);
}
}
let layout = self.layout_manager.arrange_charts(&charts).await?;
Ok(DashboardView {
view_id: format!(
"dashboard-{}",
SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.unwrap_or_default()
.as_secs()
),
title: "Performance Analytics Dashboard".to_string(),
charts,
layout,
theme: self.theme_manager.get_current_theme().clone(),
last_updated: SystemTime::now(),
})
}
pub async fn export_dashboard(
&self,
data: &DashboardData,
export_options: &ExportOptions,
) -> DeviceResult<Vec<u8>> {
let export_content = self.prepare_export_content(data).await?;
self.export_engine
.export(&export_content, export_options)
.await
}
fn prepare_chart_data(
&self,
data: &DashboardData,
chart_type: &ChartType,
) -> DeviceResult<ChartData> {
match chart_type {
ChartType::LineChart => self.prepare_line_chart_data(data),
ChartType::BarChart => self.prepare_bar_chart_data(data),
ChartType::HeatMap => self.prepare_heatmap_data(data),
_ => Ok(ChartData::default()),
}
}
fn prepare_line_chart_data(&self, data: &DashboardData) -> DeviceResult<ChartData> {
let series = vec![DataSeries {
name: "Fidelity".to_string(),
data_points: vec![DataPoint {
x: DataValue::Timestamp(SystemTime::now()),
y: DataValue::Number(data.realtime_metrics.device_metrics.fidelity),
z: None,
metadata: HashMap::new(),
}],
series_type: SeriesType::Line,
styling: SeriesStyling::default(),
}];
Ok(ChartData {
data_type: ChartDataType::TimeSeries,
series,
metadata: ChartMetadata {
title: "Device Performance".to_string(),
subtitle: Some("Real-time metrics".to_string()),
x_axis_label: "Time".to_string(),
y_axis_label: "Value".to_string(),
data_source: "Performance Dashboard".to_string(),
last_updated: SystemTime::now(),
chart_id: "device-performance".to_string(),
},
})
}
fn prepare_bar_chart_data(&self, _data: &DashboardData) -> DeviceResult<ChartData> {
Ok(ChartData::default())
}
fn prepare_heatmap_data(&self, _data: &DashboardData) -> DeviceResult<ChartData> {
Ok(ChartData::default())
}
fn create_chart_options(&self, _chart_type: &ChartType) -> DeviceResult<ChartOptions> {
Ok(ChartOptions {
width: 800,
height: 400,
interactive: self.config.enable_interactive_charts,
animation: true,
legend: LegendOptions {
show: true,
position: LegendPosition::Right,
orientation: LegendOrientation::Vertical,
styling: HashMap::new(),
},
axes: AxesOptions {
x_axis: AxisOptions::default(),
y_axis: AxisOptions::default(),
y2_axis: None,
},
grid: GridOptions::default(),
tooltip: TooltipOptions::default(),
custom_options: HashMap::new(),
})
}
async fn prepare_export_content(&self, data: &DashboardData) -> DeviceResult<ExportContent> {
Ok(ExportContent {
charts: Vec::new(),
data_tables: Vec::new(),
text_sections: Vec::new(),
metadata: ExportMetadata {
title: "Performance Analytics Report".to_string(),
author: "QuantRS Dashboard".to_string(),
creation_date: SystemTime::now(),
description: "Automated performance report".to_string(),
version: "1.0".to_string(),
custom_fields: HashMap::new(),
},
})
}
}
#[derive(Debug, Clone)]
pub struct DashboardView {
pub view_id: String,
pub title: String,
pub charts: Vec<Chart>,
pub layout: LayoutResult,
pub theme: Theme,
pub last_updated: SystemTime,
}
struct LineChartGenerator;
struct BarChartGenerator;
struct HeatMapGenerator;
impl LineChartGenerator {
const fn new() -> Self {
Self
}
}
impl ChartGenerator for LineChartGenerator {
fn generate(&self, data: &ChartData, options: &ChartOptions) -> DeviceResult<Chart> {
Ok(Chart {
chart_id: data.metadata.chart_id.clone(),
chart_type: ChartType::LineChart,
format: ChartFormat::SVG,
content: ChartContent::SVG("<svg>Line Chart</svg>".to_string()),
metadata: data.metadata.clone(),
interactive_features: if options.interactive {
vec![
InteractiveFeature::Zoom,
InteractiveFeature::Pan,
InteractiveFeature::Hover,
]
} else {
Vec::new()
},
})
}
fn supports_interactivity(&self) -> bool {
true
}
fn get_supported_formats(&self) -> Vec<ChartFormat> {
vec![ChartFormat::SVG, ChartFormat::PNG, ChartFormat::HTML]
}
}
impl BarChartGenerator {
const fn new() -> Self {
Self
}
}
impl ChartGenerator for BarChartGenerator {
fn generate(&self, data: &ChartData, _options: &ChartOptions) -> DeviceResult<Chart> {
Ok(Chart {
chart_id: data.metadata.chart_id.clone(),
chart_type: ChartType::BarChart,
format: ChartFormat::SVG,
content: ChartContent::SVG("<svg>Bar Chart</svg>".to_string()),
metadata: data.metadata.clone(),
interactive_features: Vec::new(),
})
}
fn supports_interactivity(&self) -> bool {
true
}
fn get_supported_formats(&self) -> Vec<ChartFormat> {
vec![ChartFormat::SVG, ChartFormat::PNG]
}
}
impl HeatMapGenerator {
const fn new() -> Self {
Self
}
}
impl ChartGenerator for HeatMapGenerator {
fn generate(&self, data: &ChartData, _options: &ChartOptions) -> DeviceResult<Chart> {
Ok(Chart {
chart_id: data.metadata.chart_id.clone(),
chart_type: ChartType::HeatMap,
format: ChartFormat::SVG,
content: ChartContent::SVG("<svg>Heat Map</svg>".to_string()),
metadata: data.metadata.clone(),
interactive_features: Vec::new(),
})
}
fn supports_interactivity(&self) -> bool {
false
}
fn get_supported_formats(&self) -> Vec<ChartFormat> {
vec![ChartFormat::SVG, ChartFormat::PNG]
}
}
impl LayoutManager {
pub fn new(layout_type: DashboardLayout) -> Self {
Self {
layout_type,
grid_config: GridConfiguration::default(),
responsive_rules: Vec::new(),
layout_cache: HashMap::new(),
}
}
pub async fn arrange_charts(&self, charts: &[Chart]) -> DeviceResult<LayoutResult> {
let chart_positions = charts
.iter()
.enumerate()
.map(|(i, chart)| ChartPosition {
chart_id: chart.chart_id.clone(),
x: (i % 2) as u32 * 400,
y: (i / 2) as u32 * 300,
width: 400,
height: 300,
z_index: i as i32,
})
.collect();
Ok(LayoutResult {
layout_type: self.layout_type.clone(),
chart_positions,
total_width: 800,
total_height: 600,
responsive_applied: Vec::new(),
})
}
}
impl Default for ExportEngine {
fn default() -> Self {
Self::new()
}
}
impl ExportEngine {
pub fn new() -> Self {
Self {
export_formats: vec![ExportFormat::PDF, ExportFormat::PNG, ExportFormat::HTML],
template_engine: TemplateEngine::new(),
format_converters: HashMap::new(),
}
}
pub async fn export(
&self,
content: &ExportContent,
options: &ExportOptions,
) -> DeviceResult<Vec<u8>> {
Ok(b"Exported content".to_vec())
}
}
impl Default for TemplateEngine {
fn default() -> Self {
Self::new()
}
}
impl TemplateEngine {
pub fn new() -> Self {
Self {
templates: HashMap::new(),
template_cache: HashMap::new(),
variable_resolver: VariableResolver::new(),
}
}
}
impl Default for VariableResolver {
fn default() -> Self {
Self::new()
}
}
impl VariableResolver {
pub fn new() -> Self {
Self {
resolvers: HashMap::new(),
}
}
}
impl ThemeManager {
pub fn new(color_scheme: ColorScheme) -> Self {
let theme = Self::create_theme_from_scheme(color_scheme);
let mut available_themes = HashMap::new();
available_themes.insert(theme.theme_id.clone(), theme.clone());
Self {
current_theme: theme,
available_themes,
custom_css: HashMap::new(),
}
}
pub const fn get_current_theme(&self) -> &Theme {
&self.current_theme
}
fn create_theme_from_scheme(scheme: ColorScheme) -> Theme {
let (primary, background, text) = match scheme {
ColorScheme::Dark => (
"#BB86FC".to_string(),
"#121212".to_string(),
"#FFFFFF".to_string(),
),
ColorScheme::Light => (
"#6200EE".to_string(),
"#FFFFFF".to_string(),
"#000000".to_string(),
),
ColorScheme::Scientific => (
"#1976D2".to_string(),
"#F5F5F5".to_string(),
"#212121".to_string(),
),
_ => (
"#6200EE".to_string(),
"#FFFFFF".to_string(),
"#000000".to_string(),
),
};
Theme {
theme_id: format!("{scheme:?}").to_lowercase(),
theme_name: format!("{scheme:?} Theme"),
color_palette: ColorPalette {
primary,
secondary: "#03DAC6".to_string(),
accent: "#FF5722".to_string(),
background,
surface: "#FFFFFF".to_string(),
text_primary: text,
text_secondary: "#757575".to_string(),
success: "#4CAF50".to_string(),
warning: "#FF9800".to_string(),
error: "#F44336".to_string(),
info: "#2196F3".to_string(),
chart_colors: vec![
"#1976D2".to_string(),
"#388E3C".to_string(),
"#F57C00".to_string(),
"#7B1FA2".to_string(),
"#D32F2F".to_string(),
"#0097A7".to_string(),
],
},
typography: Typography::default(),
spacing: Spacing::default(),
borders: BorderStyles::default(),
shadows: ShadowStyles::default(),
}
}
}
impl Default for ChartData {
fn default() -> Self {
Self {
data_type: ChartDataType::TimeSeries,
series: Vec::new(),
metadata: ChartMetadata {
title: "Chart".to_string(),
subtitle: None,
x_axis_label: "X".to_string(),
y_axis_label: "Y".to_string(),
data_source: "Dashboard".to_string(),
last_updated: SystemTime::now(),
chart_id: "chart".to_string(),
},
}
}
}
impl Default for SeriesStyling {
fn default() -> Self {
Self {
color: "#1976D2".to_string(),
line_width: 2.0,
marker_size: 4.0,
opacity: 1.0,
fill_pattern: None,
custom_styles: HashMap::new(),
}
}
}
impl Default for AxisOptions {
fn default() -> Self {
Self {
show: true,
title: String::new(),
min: None,
max: None,
tick_interval: None,
tick_format: "auto".to_string(),
logarithmic: false,
grid_lines: true,
}
}
}
impl Default for GridOptions {
fn default() -> Self {
Self {
show: true,
major_lines: true,
minor_lines: false,
line_style: "solid".to_string(),
color: "#E0E0E0".to_string(),
opacity: 0.5,
}
}
}
impl Default for TooltipOptions {
fn default() -> Self {
Self {
show: true,
format: "auto".to_string(),
background_color: "#333333".to_string(),
border_color: "#666666".to_string(),
follow_mouse: true,
}
}
}
impl Default for GridConfiguration {
fn default() -> Self {
Self {
columns: 2,
rows: 2,
gap: 16.0,
padding: 16.0,
responsive_breakpoints: vec![
Breakpoint {
width: 768,
columns: 1,
chart_height: 300,
},
Breakpoint {
width: 1024,
columns: 2,
chart_height: 400,
},
],
}
}
}
impl Default for Typography {
fn default() -> Self {
Self {
font_family: "Roboto, sans-serif".to_string(),
font_sizes: [
("small".to_string(), 12),
("medium".to_string(), 14),
("large".to_string(), 16),
("title".to_string(), 20),
]
.iter()
.cloned()
.collect(),
font_weights: [("normal".to_string(), 400), ("bold".to_string(), 700)]
.iter()
.cloned()
.collect(),
line_heights: [("normal".to_string(), 1.4), ("tight".to_string(), 1.2)]
.iter()
.cloned()
.collect(),
}
}
}
impl Default for Spacing {
fn default() -> Self {
Self {
base_unit: 8,
small: 4,
medium: 8,
large: 16,
extra_large: 32,
}
}
}
impl Default for BorderStyles {
fn default() -> Self {
Self {
width: [("thin".to_string(), 1), ("medium".to_string(), 2)]
.iter()
.cloned()
.collect(),
style: [("solid".to_string(), "solid".to_string())]
.iter()
.cloned()
.collect(),
color: [("default".to_string(), "#E0E0E0".to_string())]
.iter()
.cloned()
.collect(),
radius: [("small".to_string(), 4), ("medium".to_string(), 8)]
.iter()
.cloned()
.collect(),
}
}
}
impl Default for ShadowStyles {
fn default() -> Self {
Self {
box_shadows: [
("small".to_string(), "0 2px 4px rgba(0,0,0,0.1)".to_string()),
(
"medium".to_string(),
"0 4px 8px rgba(0,0,0,0.1)".to_string(),
),
]
.iter()
.cloned()
.collect(),
text_shadows: HashMap::new(),
}
}
}