Preformu / config /chart_styles.py
Kevinshh's picture
Upload chart_styles.py
aed6f5c verified
"""
Chart Styles Configuration - Standardized Plotly Styling
This module defines standard colors, fonts, and styles for all charts
to ensure visual consistency across the platform.
"""
# =============================================================================
# Color Palette (Pharma-appropriate colors)
# =============================================================================
COLORS = {
# Primary data colors
"data_primary": "#003366", # Deep blue - measured data
"data_secondary": "#0066cc", # Medium blue - secondary data
# Prediction colors
"prediction_line": "#28a745", # Green - prediction lines
"prediction_ci": "rgba(40, 167, 69, 0.2)", # Semi-transparent green - CI band
# Limit colors
"specification_limit": "#dc3545", # Red - specification limit
"warning_limit": "#ffc107", # Yellow/amber - warning threshold
# Status colors
"compliant": "#28a745", # Green - compliant/pass
"marginal": "#ffc107", # Yellow - marginal/warning
"non_compliant": "#dc3545", # Red - non-compliant/fail
# Background/grid
"grid": "#e0e0e0",
"background": "#ffffff",
"paper": "#fafafa",
# Batch comparison palette
"batch_palette": [
"#1f77b4", # Blue
"#ff7f0e", # Orange
"#2ca02c", # Green
"#d62728", # Red
"#9467bd", # Purple
"#8c564b", # Brown
"#e377c2", # Pink
"#7f7f7f", # Gray
]
}
# =============================================================================
# Font Configuration
# =============================================================================
FONTS = {
"family": "'Segoe UI', 'Roboto', 'Helvetica Neue', Arial, sans-serif",
"family_cn": "'Microsoft YaHei', 'PingFang SC', 'Hiragino Sans GB', sans-serif",
"size_title": 16,
"size_axis": 12,
"size_tick": 10,
"size_annotation": 11,
}
# =============================================================================
# Chart Templates
# =============================================================================
def get_prediction_chart_layout() -> dict:
"""Get standard layout for prediction charts."""
return {
"template": "plotly_white",
"font": {
"family": FONTS["family"],
"size": FONTS["size_axis"]
},
"title": {
"font": {"size": FONTS["size_title"], "color": COLORS["data_primary"]}
},
"xaxis": {
"title": {"text": "时间 (月)", "font": {"size": FONTS["size_axis"]}},
"gridcolor": COLORS["grid"],
"zeroline": False
},
"yaxis": {
"title": {"text": "含量 (%)", "font": {"size": FONTS["size_axis"]}},
"gridcolor": COLORS["grid"],
"zeroline": False
},
"legend": {
"orientation": "h",
"yanchor": "bottom",
"y": 1.02,
"xanchor": "right",
"x": 1
},
"margin": {"l": 60, "r": 30, "t": 60, "b": 50},
"plot_bgcolor": COLORS["background"],
"paper_bgcolor": COLORS["paper"],
}
def get_comparison_chart_layout() -> dict:
"""Get standard layout for batch comparison charts."""
return {
"template": "plotly_white",
"font": {
"family": FONTS["family"],
"size": FONTS["size_axis"]
},
"title": {
"font": {"size": FONTS["size_title"], "color": COLORS["data_primary"]}
},
"xaxis": {
"title": {"text": "批次", "font": {"size": FONTS["size_axis"]}},
},
"yaxis": {
"title": {"text": "评分", "font": {"size": FONTS["size_axis"]}},
"range": [0, 105]
},
"margin": {"l": 50, "r": 30, "t": 60, "b": 50},
"plot_bgcolor": COLORS["background"],
"paper_bgcolor": COLORS["paper"],
}
def get_score_color(score: float) -> str:
"""Get color based on score value."""
if score >= 80:
return COLORS["compliant"]
elif score >= 60:
return COLORS["marginal"]
else:
return COLORS["non_compliant"]
def get_risk_color(risk_level: str) -> str:
"""Get color based on risk level string."""
risk_lower = risk_level.lower()
if "compliant" in risk_lower or "合格" in risk_lower or "low" in risk_lower:
return COLORS["compliant"]
elif "marginal" in risk_lower or "临界" in risk_lower or "medium" in risk_lower:
return COLORS["marginal"]
else:
return COLORS["non_compliant"]