pax.BlazorChartJs
0.9.0-preview
See the version list below for details.
dotnet add package pax.BlazorChartJs --version 0.9.0-preview
NuGet\Install-Package pax.BlazorChartJs -Version 0.9.0-preview
<PackageReference Include="pax.BlazorChartJs" Version="0.9.0-preview" />
<PackageVersion Include="pax.BlazorChartJs" Version="0.9.0-preview" />
<PackageReference Include="pax.BlazorChartJs" />
paket add pax.BlazorChartJs --version 0.9.0-preview
#r "nuget: pax.BlazorChartJs, 0.9.0-preview"
#:package pax.BlazorChartJs@0.9.0-preview
#addin nuget:?package=pax.BlazorChartJs&version=0.9.0-preview&prerelease
#tool nuget:?package=pax.BlazorChartJs&version=0.9.0-preview&prerelease
Blazor dotnet wrapper library for ChartJs
The current release is compatible with the following ChartJs versions Release | ChartJs | Tests ---|---|--- >= 0.5.0 | 4.x | 4.5.1
Getting started
This library is using JavaScript isolation. JS isolation provides the following benefits:
- Imported JS no longer pollutes the global namespace.
- Consumers of a library and components aren't required to import the related JS.
Installation
dotnet add package pax.BlazorChartJs
Program.cs:
builder.Services.AddChartJs(options =>
{
// default
options.ChartJsLocation = "https://cdn.jsdelivr.net/npm/chart.js";
options.ChartJsPluginDatalabelsLocation = "https://cdn.jsdelivr.net/npm/chartjs-plugin-datalabels@2";
});
If you want to serve Chart.js locally, you can provide your own URLs:
builder.Services.AddChartJs(options =>
{
var version = "4.5.1";
options.ChartJsLocation = $"/_content/dsstats.weblib/js/chart.umd.min.js?v={version}";
options.ChartJsPluginDatalabelsLocation = "/_content/dsstats.weblib/js/chartjs-plugin-datalabels.min.js";
});
Usage
Sample Project pax.BlazorChartJs.samplelib with Sample Chart
@using pax.BlazorChartJs
<div class="btn-group">
<button type="button" class="btn btn-primary" @onclick="Randomize">Randomize</button>
</div>
<div class="chart-container w-75">
<ChartComponent @ref="chartComponent"
ChartJsConfig="chartJsConfig"
OnEventTriggered="ChartEventTriggered">
</ChartComponent>
</div>
@code {
ChartJsConfig chartJsConfig = null!;
ChartComponent? chartComponent;
private bool chartReady;
protected override void OnInitialized()
{
chartJsConfig = new ChartJsConfig()
{
Type = ChartType.bar,
Data = new ChartJsData()
{
Labels = ["Jan", "Feb", "Mar"],
Datasets = new List<ChartJsDataset>()
{
new BarDataset()
{
Label = "Dataset 1",
Data = [ 1, 2, 3 ]
}
}
}
};
base.OnInitialized();
}
private void ChartEventTriggered(ChartJsEvent chartJsEvent)
{
if (chartJsEvent is ChartJsInitEvent initEvent)
{
chartReady = true;
}
}
private void Randomize()
{
if (!chartReady)
{
return;
}
Dictionary<string, IList<object>> dataByDatasetId = [];
foreach (var dataset in chartJsConfig.Data.Datasets)
{
if (dataset is BarDataset barDataset)
{
List<object> newData = new();
foreach (var data in barDataset.Data)
{
newData.Add(Random.Shared.Next(1, 10));
}
dataByDatasetId[barDataset.Id] = newData;
}
}
chartJsConfig.UpdateDatasetsDataSmooth(dataByDatasetId);
}
}
Update Chart
- To update the chart with the current ChartJsConfig call
ChartJsConfig.ReinitializeChart() - To update the chart with smooth animations there are several helper functions available, e.g.:
ChartJsConfig.SetLabels(...)ChartJsConfig.AddData(...)ChartJsConfig.AddDatasetSmooth(...)ChartJsConfig.SetData(...)ChartJsConfig.SetDatasetsSmooth(...)
- use
ChartJsConfig.UpdateChartOptions()to update the chart options, only (e.g. StepSize) - use
ChartJsConfig.SetDatasetsSmooth(...)to add, update, remove, and reorder datasets by id in one batched smooth update. Optional labels and current chart options can be applied in the same chart update:
chartJsConfig.Options ??= new ChartJsOptions();
chartJsConfig.Options.Responsive = false;
chartJsConfig.SetDatasetsSmooth(
datasets:
[
new BarDataset
{
Id = "dataset-2",
Label = "Dataset 2",
Data = [ 4, 5, 6 ]
},
new BarDataset
{
Id = "dataset-1",
Label = "Dataset 1",
Data = [ 3, 2, 1 ]
}
],
labels: ["Apr", "May", "Jun"],
updateOptions: true);
Chart Events
Several chart events are available, by default only the Init event is fired. The others can be activated in the ChartJsConfig.Options Sample
- click
- hover
- leave
- progress
- complete
- resize
ChartJsFunction Callbacks
ChartJsFunction.FromName(...) can be used to reference JavaScript callbacks from C# chart configuration without serializing raw JavaScript into the config. Configure a callback module that exports a chartJsCallbacks object:
builder.Services.AddChartJs(options =>
{
options.ChartJsCallbacksModuleLocation = $"{builder.HostEnvironment.BaseAddress}_content/pax.BlazorChartJs.samplelib/chartJsCallbacks.js";
});
Then reference registered callback names from chart options or datasets:
new BarDataset()
{
Label = "Dataset 1",
Data = new List<object>() { 1, 2, 3 },
BackgroundColor = ChartJsFunction.FromName("createRepeatFillPattern")
}
new Legend()
{
Labels = new Labels()
{
Filter = ChartJsFunction.FromName("showLegendItem")
}
}
new LinearAxisTick()
{
Callback = ChartJsFunction.FromName("formatCurrency")
}
Callback names are validated and resolved from the configured module, which avoids raw JavaScript serialization in the chart config. See the full ChartJsFunction callback sample.
Additional AddChartJs options
Beyond the basic script locations shown in the installation section, AddChartJs(...) can configure callback modules and app-wide Chart.js defaults.
builder.Services.AddChartJs(options =>
{
options.ChartJsCallbacksModuleLocation = $"{builder.HostEnvironment.BaseAddress}_content/my-app/chartJsCallbacks.js";
options.Defaults = new ChartJsDefaultsOptions()
{
Color = "#1f2937",
BorderColor = "#d1d5db",
Font = new Font()
{
Family = "Inter, system-ui, sans-serif",
Size = 12
},
Datasets = new ChartJsOptionsDatasets()
{
Bar = new
{
barPercentage = 0.8,
categoryPercentage = 0.9
},
Line = new
{
tension = 0.25
}
},
OnClick = ChartJsFunction.FromName("globalChartClick")
};
});
Defaults maps to Chart.defaults and is applied after Chart.js is loaded and before the first chart is constructed. Per-chart ChartJsConfig.Options still override the global defaults. ChartJsFunction values in defaults use the same callback registry configured by ChartJsCallbacksModuleLocation.
Supported Plugins
- chartjs-plugin-datalabels
- ArbitraryLines (YouTube)
- Custom Plugins Sample
ChartComponent
Several chart functions are available in the ChartComponent, e.g.:
ChartComponent.ResizeChart(...)ChartComponent.GetChartImage(...)ChartComponent.ToggleDataVisibility(...)
Contributing
We really like people helping us with the project. Nevertheless, take your time to read our contributing guidelines here.
Changelog
<details open="open"><summary>v0.9.0-preview</summary>
- Added
ChartJsFunctionto reference registered JavaScript callbacks from C# chart configuration without serializing raw JavaScript.- Added callback module configuration and marker revival for chart initialization, option updates, and dataset add/update/set interop calls.
- Added scriptable callback support for datalabel formatters, axis ticks, tooltip callbacks, legend callbacks, and indexable color options.
- Expanded
IndexableOption<T>to support single values, indexed values, andChartJsFunctioncallback values.- Expanded
Paddingto support Chart.js numeric padding,{x, y}shorthand padding, and scriptable padding callbacks while preserving existingPadding?property types.- Added a scriptable padding sample with a sample-only
Latestlabel plugin.- Hardened callback resolution with flat JavaScript identifier validation and reserved-name checks.
- Updated sample callback charts to use a shared
chartJsCallbacks.jscallback registry.- Added missing global/core Chart.js options to
ChartJsOptions:BackgroundColor,BorderColor,Clip,Color,Datasets,Font,Hover,HoverBackgroundColor,HoverBorderColor,Normalized,OnClick,OnHover, andOnResize.- Added
ChartJsSetupOptions.Defaults/ChartJsDefaultsOptionsto configure app-wideChart.defaultsvalues throughAddChartJs(...).- Added
ChartJsOptionsDatasetsforoptions.datasetsandChart.defaults.datasetschart-type defaults.- Chart.js native
OnClick,OnHover, andOnResizecallbacks are preserved when the Blazor/C# event bridge flags are enabled.- Added
ChartJsConfig.SetDatasetsSmooth(...)to add, update, remove, and reorder datasets by id in one smooth batched chart update, with optional labels and current options update.
</details>
<details><summary>v0.8.8</summary>
- Dataset interop calls are ignored safely when the target chart was already disposed.
- Reduced allocation and lookup work while resolving and disposing Chart.js instances.
- Refactored library and sample code for .NET 11 analyzer/style guidance.
</details>
<details><summary>v0.8.7</summary>
- Hardened chart initialization to better handle rapid reinitialization and existing Chart.js instances for the same canvas.
- Resize events now include browser viewport dimensions via
WindowWidthandWindowHeight.ChartJsResizeEvent.WidthandHeightremain chart/container dimensions; useWindowWidthandWindowHeightfor viewport breakpoint logic.ChartJsInitEventnow includes initial chart and viewport dimensions viaWidth,Height,WindowWidth, andWindowHeight.- Dataset updates now match by dataset id across all chart datasets, including hidden datasets.
- Update Microsoft.TypeScript.MSBuild to v6.0.3
</details>
<details><summary>v0.8.6</summary>
- Updated to .NET 10
- Full JavaScript generation from TypeScript
- Chart.js v4.5.1 test coverage
- Improved JSON serialization to be more AOT‑friendly
</details>
<details><summary>v0.8.5</summary>
- Microsoft.AspNetCore.Components.Web v8.0.*
- ChartJs v4.4.5 tests
- Test/Sample projects update to dotnet v8.0.10
</details>
<details><summary>v0.8.4</summary>
- Microsoft.AspNetCore.Components.Web v8.0.8
- ChartJs v4.4.4 tests
</details>
<details><summary>v0.8.3</summary>
- Microsoft.AspNetCore.Components.Web v8.0.2
- Added ChartJsConfig.UpdateDatasetsSmooth updates the ChartJs dataset(s), instead of replacing.
- Added BlazorLegendBase that can be used for a ChartJs Html Legend - [Sample][https://ipax77.github.io/pax.BlazorChartJs/htmllegendchart]
- Added ChartComponent.GetLegendItems()
- Added ChartComponent.IsDatasetVisible(int datasetIndex)
- Added ChartComponent.SetDatasetPointsActive(int datasetIndex)
- BarDataset.BarPercentage changed from int? to double?
- Renamed Layout to ChartJsLayout (CA1724)
IndexableOptionnow supports Collection Expressions e.g.
BorderColor = ["rgba(255, 99, 132, 1)", "rgba(54, 162, 235, 1)"],
BorderWidth = [1, 2]
- ChartJs v4.4.2 Tests
- Blazor App sample
</details>
<details><summary>v0.8.2</summary>
- ChartJs v4.4.1 tests
- Catching (more) dispose exeptions when switching from SSR to CSR (rendermode auto - AggregateException, JSDisconnectedException)
</details>
<details><summary>v0.8.1</summary>
- dotnet 8 Breaking Change
- Added missing pie/doughnut dataset options (Cutout, Radius, Animation)
- The
IndexableOptionnow supports implicit operators, allowing a more concise syntax for initialization.
New Syntax:
BorderColor = new List<string>()
{
"rgba(255, 99, 132, 1)",
"rgba(54, 162, 235, 1)"
},
BorderWidth = 1
Old Syntax (still possible):
BorderColor = new IndexableOption<string>(new List<string>()
{
"rgba(255, 99, 132, 1)",
"rgba(54, 162, 235, 1)"
}),
BorderWidth = new IndexableOption<double>(1)
</details>
<details><summary>v0.6.3</summary>
- Reverted Microsoft.TypeScript.MSBuild to v5.2.2 Microsoft.TypeScript.MSBuild v5.3.2 not working for Blazor projects (only working for wasm)
</details>
<details><summary>v0.6.2</summary>
- Microsoft.AspNetCore.Components.Web upgrade to v6.0.25
- Added missing pie/doughnut dataset options (Cutout, Radius, Animation)
- The
IndexableOptionnow supports implicit operators, allowing a more concise syntax for initialization.
New Syntax:
BorderColor = new List<string>()
{
"rgba(255, 99, 132, 1)",
"rgba(54, 162, 235, 1)"
},
BorderWidth = 1
Old Syntax (still possible):
BorderColor = new IndexableOption<string>(new List<string>()
{
"rgba(255, 99, 132, 1)",
"rgba(54, 162, 235, 1)"
}),
BorderWidth = new IndexableOption<double>(1)
</details>
<details><summary>v0.6.1</summary>
- ChartJsLabelClickEvent and ChartJsLabelHoverEvent with 'nearest' DatasetLabel and DatasetIndex
- Microsoft.AspNetCore.Components.Web upgrade to v6.0.21
</details>
<details><summary>v0.6.0</summary>
- Fix typo for AngleLines in LinearRadialAxis Breaking Change
</details>
<details><summary>v0.5.2</summary>
- Datalabels per dataset contributed by pjvinson
- ChartJs v4.4.0 tests
</details>
<details><summary>v0.5.1</summary>
- Marked ChartJsGrid border options as obsolete for v4.x - use ChartJsAxisBorder instead.
- TimeSeriesAxis Min, Max, SuggestedMin and SuggestedMax are of type
StringOrDoubleValue, now.- Microsoft.AspNetCore.Components.Web upgrade to v6.0.16
- ChartJs v4.3.0 tests
- ChartJs v4.3.1 tests
- ChartJs v4.3.3 tests
</details>
<details><summary>v0.5.0</summary>
- Breaking Changes
- Update to ChartJs v4.x
- Removed ChartJs javascript files - defaults to cdn links, now. Use
options.ChartJsLocation = "mychart.js"to use a custom/local ChartJs version.- Removed chartjs-plugin-labels (you can still register it as custom plugin)
- Microsoft.AspNetCore.Components.Web upgrade to v6.0.13
- Added ScaleAxis X1 and Y1 (override ChartJsOptionsScales for other names)
ChartJsConfig.UpdateChartOptions()(will replaceChartComponent.UpdateChartOptions)ChartJsConfig.ReinitializeChart()(will replaceChartComponent.DrawChart)
</details>
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- Microsoft.AspNetCore.Components.Web (>= 10.0.8)
NuGet packages (1)
Showing the top 1 NuGet packages that depend on pax.BlazorChartJs:
| Package | Downloads |
|---|---|
|
NarcRazor
Generic, accessible and themeable Razor components for Blazor applications. |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated | |
|---|---|---|---|
| 0.9.1 | 402 | 6/13/2026 | |
| 0.9.0 | 313 | 5/27/2026 | |
| 0.9.0-preview2 | 113 | 5/22/2026 | |
| 0.9.0-preview | 104 | 5/21/2026 | |
| 0.8.8 | 212 | 5/18/2026 | |
| 0.8.7 | 450 | 5/3/2026 | |
| 0.8.6 | 697 | 3/21/2026 | |
| 0.8.6-rc2 | 351 | 10/23/2025 | |
| 0.8.6-rc1 | 272 | 9/23/2025 | |
| 0.8.5 | 19,816 | 10/19/2024 | |
| 0.8.4 | 1,618 | 8/24/2024 | |
| 0.8.3 | 2,215 | 3/4/2024 | |
| 0.8.3-rc1 | 175 | 2/29/2024 | |
| 0.8.2 | 1,322 | 12/6/2023 | |
| 0.8.1 | 312 | 11/28/2023 | |
| 0.8.0 | 258 | 11/28/2023 | |
| 0.8.0-rc2.0 | 171 | 11/15/2023 | |
| 0.8.0-rc1.0 | 179 | 10/17/2023 | |
| 0.6.3 | 450 | 11/28/2023 | |
| 0.6.2 | 254 | 11/28/2023 |