Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 30 additions & 1 deletion .github/skills/syncfusion-blazor-toolkit-charts/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -581,12 +581,41 @@ Here's a minimal example to create a column chart with data:
### Chart Component (`SfChart`)
- `Title` - Chart title text
- `Width` / `Height` - Chart dimensions (accepts px or %, default: "100%")
- `Theme` - Visual theme (see Theme enum in API reference)
- `Theme` - Visual theme. One of `Theme.Fluent` (default), `Theme.FluentDark`, `Theme.HighContrast`. See the **Themes** section below.
- `Background` - Chart background color
- `EnableAnimation` - Enable/disable animation (default: true)
- `SelectionMode` - Selection mode (None, Series, Point, Cluster, DragXY, DragX, DragY, Lasso)
- `HighlightMode` - Highlight mode (None, Series, Point, Cluster)

### Themes

The chart's `Theme` parameter is bound to `Syncfusion.Blazor.Toolkit.Theme`:

| Enum value | Background | Text | Focus / Selection | Use case |
|---|---|---|---|---|
| `Theme.Fluent` (default) | `#FFFFFF` | `#242424` | `#0F6CBD` | Light mode interfaces. |
| `Theme.FluentDark` | `#1C1B1F` | `#FFFFFF` | `#115EA3` | Dark mode interfaces. |
| `Theme.HighContrast` | `#000000` | `#FFFFFF` | `#FFFF00` | Accessibility scenarios; matches Microsoft High Contrast. |

The theme flows into:
- `ChartHelper.GetChartThemeStyle(...)` — tokens for axis lines, labels, grid lines, titles, legend, tooltips, crosshair, selection rectangles, error bars, stripline text, tooltip fill, and the scrollbar (`ChartHelper.GetScrollbarThemeColor`).
- `ChartHelper.GetSeriesColor(...)` — the default series palette when `Palettes` is not supplied. The high-contrast palette uses fully saturated, easily distinguishable colors: `#FFFF00`, `#00FFFF`, `#FF00FF`, `#00FF00`, `#FF8000`, `#80FF00`, `#00FF80`, `#FF0080`, `#FFFFFF`, `#80FFFF`.
- `ZoomToolkit` — the zoom toolbar icon colors and rectangle fill re-skin to match the active theme.

**Example — High Contrast:**

```razor
@using Syncfusion.Blazor.Toolkit.Charts
<SfChart Theme="Theme.HighContrast" Title="Sales Data">
<ChartPrimaryXAxis ValueType="Syncfusion.Blazor.Toolkit.ValueType.Category" />
<ChartSeries DataSource="@SalesData" XName="Month" YName="Revenue"
Type="ChartSeriesType.Column" />
</SfChart>
```

> The high-contrast theme provides maximum contrast and is recommended for users who have Windows High Contrast Mode (or an equivalent OS-level accessibility setting) enabled. When a custom `Background` or `Palettes` is supplied, those values always win over the theme defaults.
### Primary Axes (`ChartPrimaryXAxis`, `ChartPrimaryYAxis`)
- `ValueType` - Axis type: `Syncfusion.Blazor.Toolkit.ValueType.Category`, `ValueType.Double`, `ValueType.DateTime`, `ValueType.Logarithmic`, `ValueType.DateTimeCategory`
- `Title` - Axis title
Expand Down
12 changes: 11 additions & 1 deletion src/Base/Enumeration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1362,7 +1362,17 @@ public enum Theme
/// <remarks>
/// The Fluent dark theme is designed for dark mode interfaces.
/// </remarks>
FluentDark
FluentDark,
/// <summary>
/// Applies the High Contrast theme to the chart, rendering with maximum-contrast colors for users who require stronger visual differentiation.
/// </summary>
/// <remarks>
/// The High Contrast theme uses a black background (<b>#000000</b>), white text (<b>#FFFFFF</b>),
/// a soft accessibility-yellow focus / selection color (<b>#FFD939</b>), and a high-contrast accent palette
/// (axis labels and grid lines in neutral grays <b>#969696</b> / <b>#BFBFBF</b>).
/// It is designed for accessibility scenarios and environments where Windows High Contrast Mode (or an equivalent OS-level accessibility setting) is enabled.
/// </remarks>
HighContrast
}

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,15 @@ public class ZoomToolkit : ComponentBase
protected override void OnInitialized()
{
_elementId = Chart?.ID;
_selectionColor = Chart?.Theme != Theme.FluentDark ? "#424242" : "#D6D6D6";
_fillColor = Chart?.Theme != Theme.FluentDark ? "#424242" : "#D6D6D6";
_iconRectOverFill = Chart?.Theme != Theme.FluentDark ? "#EBEBEB" : "#383838";
_iconRectSelectionFill = Chart?.Theme != Theme.FluentDark ? "#EBEBEB" : "#383838";
_iconRect = Chart?.Theme != Theme.FluentDark ? new Rect(-7, -8, 32, 32) : new Rect(0, 0, 16, 16);
// Resolve theme-aware color tokens for the zoom toolkit. High Contrast is treated as a third branch.
// The soft accessibility yellow (#FFD939) matches the selectionCircleStroke / tabColor tokens in ChartHelper.GetThemeStyle("HighContrast").
bool isHighContrast = Chart?.Theme == Theme.HighContrast;
bool isDark = Chart?.Theme == Theme.FluentDark;
_selectionColor = isHighContrast ? "#FFD939" : (isDark ? "#D6D6D6" : "#424242");
_fillColor = isHighContrast ? "#FFD939" : (isDark ? "#D6D6D6" : "#424242");
_iconRectOverFill = isHighContrast ? "#000000" : (isDark ? "#383838" : "#EBEBEB");
_iconRectSelectionFill = isHighContrast ? "#000000" : (isDark ? "#383838" : "#EBEBEB");
_iconRect = isHighContrast ? new Rect(0, 0, 16, 16) : (isDark ? new Rect(0, 0, 16, 16) : new Rect(-7, -8, 32, 32));
_zoomkitOpacity = 1;
}

Expand Down Expand Up @@ -124,7 +128,7 @@ private void ShowZoomingToolkit(RenderTreeBuilder builder)
}

toolboxItems = IsDevice() ? [ToolbarItems.Reset] : toolboxItems;
RectOptions rectOptions = new(_elementId + "_Zooming_Rect", 0, 0, width, height + (SPACING * 2), 1, Constants.Transparent, Chart?.Theme != Theme.FluentDark ? "#fafafa" : "#1C1B1F", 4, 4, 1);
RectOptions rectOptions = new(_elementId + "_Zooming_Rect", 0, 0, width, height + (SPACING * 2), 1, Constants.Transparent, Chart?.Theme == Theme.HighContrast ? "#000000" : (Chart?.Theme != Theme.FluentDark ? "#fafafa" : "#1C1B1F"), 4, 4, 1);
RenderZoomKit(builder, transX, transY, rectOptions, length, toolboxItems, iconSize);
}

Expand Down Expand Up @@ -361,7 +365,7 @@ private void RenderResetButtonAsText(SvgRendering render, RenderTreeBuilder buil
Transform = "rotate(0," + 0 + ',' + 0 + ')',
DominantBaseline = "middle",
FontSize = "12px",
Fill = Chart?.Theme != Theme.FluentDark ? "black" : "white"
Fill = Chart?.Theme == Theme.HighContrast ? "#FFD939" : (Chart?.Theme != Theme.FluentDark ? "black" : "white")
});
}

Expand Down
37 changes: 23 additions & 14 deletions src/Components/Charts/Common/ChartUtils/ChartHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1252,16 +1252,21 @@ internal static string FindThemeColor(string actualColor, string themeColor)
/// <returns>The theme style configuration.</returns>
internal static ChartThemeStyle GetChartThemeStyle(string theme)
{
if(theme != "FluentDark")
{
return GetThemeStyle("#616161", "#242424", "#D2D0CE", "#EDEBE9", "#EDEBE9", "#D2D0CE", "#D2DOCE", "#242424", "#242424", "#FFFFFF", "#EDEBE9", "#A19F9D", "#A19F9D", "rgba(138, 136, 134, 0.1)", "#FFFFFF", "#242424", "#FFFFFF", "#242424", "#242424", "#D2D0CE", null!, "rgba(180, 214, 250, 0.1)", "#0F6CBD", "#0F6CBD", "#424242", "#A19F9D",
"14px", "600", "Segoe UI", "12px", "400", "Segoe UI", "12px", "Segoe UI", "400", "12px", "Segoe UI", "700", "12px", "Segoe UI", "400", "12px", "Segoe UI", "600", "#616161", "12px", "Segoe UI", "600", "#616161", "Segoe UI", "12px", "400", "#E7910F", "#0076E5", "12px", "Segoe UI", "600");
}
else
if (theme == "FluentDark")
{
return GetThemeStyle("#ADADAD", "#FFFFFF", "#3B3A39", "#292827", "#292827", "#3B3A39", "#3B3A39", "#FFFFFF", "#FFFFFF", "#1c1b1f", "#292827", "#8A8886", "#8A8886", "rgba(138, 136, 134, 0.1)", "#292929", "#FFFFFF", "#292929", "#FFFFFF", "#FFFFFF", "#3B3A39", null!, "rgba(14, 71, 117, 0.1)", "#115EA3", "#115EA3", "#D6D6D6", "#8A8886",
"14px", "600", "Segoe UI", "12px", "400", "Segoe UI", "12px", "Segoe UI", "400", "12px", "Segoe UI", "700", "12px", "Segoe UI", "400", "12px", "Segoe UI", "600", "#ADADAD", "12px", "Segoe UI", "600", "#ADADAD", "Segoe UI", "12px", "400", "#584EC6", "#43B786", "12px", "Segoe UI", "600");
}
if (theme == "HighContrast")
{
// High Contrast theme: black background, light-gray axis labels, white chart title.
// Yellow (#FFD939) is used for focus/selection accents to remain visible on black.
return GetThemeStyle("#969696", "#FFFFFF", "#ffffff", "#BFBFBF", "#969696", "#BFBFBF", "#969696", "#FFFFFF", "#969696", "#000000", "#ffffff", "#ffffff", "#ffffff", "rgba(255, 255, 255, 0.1)", "#FFFFFF", "#000000", "#ffffff", "#000000", "#000000", "#969696", "#BFBFBF", "rgba(255, 217, 57, 0.3)", "#ffffff", "#FFD939", "#FFD939", "#ffffff",
"16px", "600", "Segoe UI", "12px", "400", "Segoe UI", "14px", "Segoe UI", "400", "12px", "Segoe UI", "400", "12px", "Segoe UI", "400", "14px", "Segoe UI", "600", "#FFFFFF", "14px", "Segoe UI", "400", "#969696", "Segoe UI");
}
// Fluent (light) — default.
return GetThemeStyle("#616161", "#242424", "#D2D0CE", "#EDEBE9", "#EDEBE9", "#D2D0CE", "#D2DOCE", "#242424", "#242424", "#FFFFFF", "#EDEBE9", "#A19F9D", "#A19F9D", "rgba(138, 136, 134, 0.1)", "#FFFFFF", "#242424", "#FFFFFF", "#242424", "#242424", "#D2D0CE", null!, "rgba(180, 214, 250, 0.1)", "#0F6CBD", "#0F6CBD", "#424242", "#A19F9D",
"14px", "600", "Segoe UI", "12px", "400", "Segoe UI", "12px", "Segoe UI", "400", "12px", "Segoe UI", "700", "12px", "Segoe UI", "400", "12px", "Segoe UI", "600", "#616161", "12px", "Segoe UI", "600", "#616161", "Segoe UI", "12px", "400", "#E7910F", "#0076E5", "12px", "Segoe UI", "600");
}

/// <summary>
Expand All @@ -1270,14 +1275,16 @@ internal static ChartThemeStyle GetChartThemeStyle(string theme)
/// <returns>An array of color strings for the series.</returns>
internal static string[] GetSeriesColor(string theme)
{
if(theme != "FluentDark")
if (theme == "FluentDark")
{
return new string[] { "#6200EE", "#09AF74", "#0076E5", "#CB3587", "#E7910F", "#0364DE", "#66CD15", "#F3A93C", "#107C10", "#C19C00" };
return new string[] { "#9BB449", "#2A72D5", "#43B786", "#3F579A", "#584EC6", "#E85F9C", "#6E7A89", "#EA6266", "#0B6A0B", "#C19C00" };
}
else
if (theme == "HighContrast")
{
return new string[] { "#9BB449", "#2A72D5", "#43B786", "#3F579A", "#584EC6", "#E85F9C", "#6E7A89", "#EA6266", "#0B6A0B", "#C19C00" };
return new string[] { "#79ECE4", "#E98272", "#DFE6B6", "#C6E773", "#BA98FF", "#FA83C3", "#00C27A", "#43ACEF", "#D681EF", "#D8BC6E" };
}
// Fluent (light) — default.
return new string[] { "#6200EE", "#09AF74", "#0076E5", "#CB3587", "#E7910F", "#0364DE", "#66CD15", "#F3A93C", "#107C10", "#C19C00" };
}

/// <summary>
Expand Down Expand Up @@ -1966,14 +1973,16 @@ internal static Rect GetTransform(Rect xAxisRect, Rect yAxisRect, bool invertedA
/// <returns>The scrollbar theme style.</returns>
internal static ScrollbarThemeStyle GetScrollbarThemeColor(string theme)
{
if(theme != "FluentDark")
if (theme == "FluentDark")
{
return GetScrollbarStyle("#F5F5F5", "#F0F0F0", "#FAFAFA", "#FAFAFA", "#424242", "#424242");
return GetScrollbarStyle("#0A0A0A", "#141414", "#1F1F1F", "#1F1F1F", "#D6D6D6", "#D6D6D6");
}
else
if (theme == "HighContrast")
{
return GetScrollbarStyle("#0A0A0A", "#141414", "#1F1F1F", "#1F1F1F", "#D6D6D6", "#D6D6D6");
return GetScrollbarStyle("#000000", "#000000", "#000000", "#000000", "#FFFF00", "#FFFF00");
}
// Fluent (light) — default.
return GetScrollbarStyle("#F5F5F5", "#F0F0F0", "#FAFAFA", "#FAFAFA", "#424242", "#424242");
}

/// <summary>
Expand Down
Loading