diff --git a/.theme-schema.json b/.theme-schema.json index 3875aa20ff..3d6968989f 100644 --- a/.theme-schema.json +++ b/.theme-schema.json @@ -181,6 +181,10 @@ "description": "Bearish color for candlestick charts (downward price movement).", "type": ["string", "null"] }, + "chart.grid": { + "description": "Chart grid line color.", + "type": ["string", "null"] + }, "danger.background": { "description": "Danger background color.", "type": ["string", "null"] diff --git a/crates/component/src/chart/bar_chart.rs b/crates/component/src/chart/bar_chart.rs index 8e76650f02..8efcda6e82 100644 --- a/crates/component/src/chart/bar_chart.rs +++ b/crates/component/src/chart/bar_chart.rs @@ -850,7 +850,7 @@ where // Draw grid, excluding the line at the baseline. if self.grid { - let grid = Grid::new().stroke(cx.theme().border); + let grid = Grid::new().stroke(cx.theme().chart_grid); let grid = if self.grid_dashed { grid.dash_array(&[px(4.), px(2.)]) } else { diff --git a/crates/component/src/chart/mod.rs b/crates/component/src/chart/mod.rs index 4bd8185ef5..98e8ffe82e 100644 --- a/crates/component/src/chart/mod.rs +++ b/crates/component/src/chart/mod.rs @@ -408,7 +408,7 @@ impl PointAxes { let columns: Vec = (0..self.grid_columns) .map(|i| width * i as f32 / self.grid_columns as f32) .collect(); - let grid = Grid::new().y(rows).x(columns).stroke(cx.theme().border); + let grid = Grid::new().y(rows).x(columns).stroke(cx.theme().chart_grid); let grid = if self.grid_dashed { grid.dash_array(&[px(4.), px(2.)]) } else { diff --git a/crates/component/src/chart/radar_chart.rs b/crates/component/src/chart/radar_chart.rs index cbae0c0e95..894cd87298 100644 --- a/crates/component/src/chart/radar_chart.rs +++ b/crates/component/src/chart/radar_chart.rs @@ -482,7 +482,7 @@ where // Draw grid rings and spokes if self.grid { - let stroke = cx.theme().border; + let stroke = cx.theme().chart_grid; for level in 1..=self.grid_levels { let radius = outer_radius * level as f32 / self.grid_levels as f32; diff --git a/crates/component/src/theme/default-theme.json b/crates/component/src/theme/default-theme.json index 0273713ddc..aadcbdfddf 100644 --- a/crates/component/src/theme/default-theme.json +++ b/crates/component/src/theme/default-theme.json @@ -25,6 +25,7 @@ "chart.5": "#1e40af", "chart.bullish": "green-600", "chart.bearish": "red-600", + "chart.grid": "neutral-200/60", "danger.background": "red-500", "danger.foreground": "neutral-50", "description_list_label.foreground": "#171717", @@ -230,6 +231,7 @@ "chart.5": "#1e40af", "chart.bullish": "green-600", "chart.bearish": "red-600", + "chart.grid": "neutral-800/60", "danger.background": "red-400", "danger.foreground": "red-600", "description_list_label.background": "#171717", diff --git a/crates/component/src/theme/schema.rs b/crates/component/src/theme/schema.rs index ac5b6af031..1e0edbcd50 100644 --- a/crates/component/src/theme/schema.rs +++ b/crates/component/src/theme/schema.rs @@ -383,6 +383,9 @@ pub struct ThemeConfigColors { /// Bearish color for candlestick charts (downward price movement). #[serde(rename = "chart.bearish")] pub chart_bearish: Option, + /// Chart grid line color. + #[serde(rename = "chart.grid")] + pub chart_grid: Option, /// Danger background color. #[serde(rename = "danger.background")] pub danger: Option, @@ -922,6 +925,7 @@ impl ThemeColor { apply_color!(chart_5, fallback = self.blue.darken(0.4)); apply_color!(chart_bullish, fallback = self.green); apply_color!(chart_bearish, fallback = self.red); + apply_color!(chart_grid, fallback = self.border.opacity(0.6)); apply_background_color!(danger, fallback = self.red); apply_background_color!(danger_active, fallback = self.danger.darken(active_darken)); apply_color!(danger_foreground, fallback = self.primary_foreground); @@ -1197,7 +1201,8 @@ mod tests { "chart.2": "not a color", "chart.3": "#333333", "chart.bullish": "#00ff00", - "chart.bearish": "#ff0000" + "chart.bearish": "#ff0000", + "chart.grid": "#eeeeee" } })) .unwrap(); @@ -1215,6 +1220,10 @@ mod tests { assert_eq!(theme.tokens.chart_3.color, theme.chart_3); assert_eq!(theme.chart_bullish, try_parse_color("#00ff00").unwrap()); assert_eq!(theme.chart_bearish, try_parse_color("#ff0000").unwrap()); + assert_eq!(theme.chart_grid, try_parse_color("#eeeeee").unwrap()); + + theme.apply_config(&std::rc::Rc::new(ThemeConfig::default())); + assert_eq!(theme.chart_grid, theme.border.opacity(0.6)); } #[test] diff --git a/crates/component/src/theme/theme_color.rs b/crates/component/src/theme/theme_color.rs index e9f665ccb3..76c0961079 100644 --- a/crates/component/src/theme/theme_color.rs +++ b/crates/component/src/theme/theme_color.rs @@ -143,6 +143,8 @@ pub struct ThemeColor { pub chart_bullish: Hsla, /// Bearish color for candlestick charts (downward price movement). pub chart_bearish: Hsla, + /// Chart grid line color. + pub chart_grid: Hsla, /// Danger background color. pub danger: Hsla, /// Danger active background color. @@ -444,6 +446,7 @@ define_theme_tokens! { chart_5, chart_bullish, chart_bearish, + chart_grid, danger, danger_active, danger_foreground, diff --git a/crates/story/src/stories/theme_story/mapper.rs b/crates/story/src/stories/theme_story/mapper.rs index 83f28861b1..6f97dd7a41 100644 --- a/crates/story/src/stories/theme_story/mapper.rs +++ b/crates/story/src/stories/theme_story/mapper.rs @@ -144,6 +144,7 @@ pub fn parse_theme_key(key: &str) -> ParsedKey { "chart_5" => ("Chart", "Color 5", "chart.5"), "chart_bullish" => ("Chart", "Bullish", "chart.bullish"), "chart_bearish" => ("Chart", "Bearish", "chart.bearish"), + "chart_grid" => ("Chart", "Grid", "chart.grid"), // Danger / Success / Warning / Info "danger" => ("Danger", "Background", "danger.background"), diff --git a/website/component/chart.md b/website/component/chart.md index 9d8abd0ea0..6847d0d307 100644 --- a/website/component/chart.md +++ b/website/component/chart.md @@ -1161,7 +1161,7 @@ div() Charts automatically include: -- Grid lines with dashed appearance +- Grid lines with dashed appearance, in the theme's `chart.grid` color (a translucent `border` when a theme leaves it unset) - X-axis labels with smart positioning - Y-axis scaling starting from zero - Responsive tick spacing based on `tick_margin` diff --git a/website/zh-CN/component/chart.md b/website/zh-CN/component/chart.md index 9ee52b608f..010c267fac 100644 --- a/website/zh-CN/component/chart.md +++ b/website/zh-CN/component/chart.md @@ -1125,7 +1125,7 @@ div() 图表默认会自动包含: -- 虚线网格 +- 虚线网格,颜色取主题的 `chart.grid`(主题未设置时为半透明的 `border`) - 自动定位的 X 轴标签 - 从 0 开始的 Y 轴刻度 - 基于 `tick_margin` 的刻度稀疏控制