A Blazor chart library, based on G2Plot
English | 简体中文
-
Go to the project folder of the application and install the Nuget package reference
$ dotnet add package AntDesign.Charts
- Add namespace in
_Imports.razor
@using AntDesign.Charts
- Add namespace in
-
Finally, it can be referenced in the `.razor' component!
<Line Data="data" Config="config" /> @code { object[] data = new object[] { new { year = "1991", value = 3 }, new { year = "1992", value = 4 }, new { year = "1993", value = 3.5 }, new { year = "1994", value = 5 }, new { year = "1995", value = 4.9 }, new { year = "1996", value = 6 }, new { year = "1997", value = 7 }, new { year = "1998", value = 9 }, new { year = "1999", value = 13 }, }; LineConfig config = new LineConfig() { Padding = "auto", XField = "year", YField = "value", Smooth = true, }; }
When configuring charts, you can define JavaScript functions for properties like formatter
or properties ending with Func
. These functions will be properly converted from string representations to actual JavaScript functions.
The following JavaScript function syntaxes are supported:
-
Standard function declarations:
config.Tooltip.Formatter = "function(datum) { return { name: datum.year, value: '$' + datum.value.toFixed(2) }; }";
-
Arrow functions:
config.Tooltip.Formatter = "(datum) => { return { name: datum.year, value: '$' + datum.value.toFixed(2) }; }";
-
Concise arrow functions (implicit return):
config.Tooltip.Formatter = "datum => '$' + datum.value.toFixed(2)";
-
Simple expressions:
config.Meta.Value.Formatter = "'$' + datum * 100";
JavaScript functions can also be defined within objects inside arrays:
config.Annotations = new[]
{
new
{
type = "text",
position = new[] { "min", "median" },
content = "Middle point",
formatter = "function(item) { return item.value.toFixed(2); }"
}
};
Charts support various events that you can handle in your Blazor code. You can use the On<T>
and Once<T>
methods to subscribe to chart events.
<Line @ref="chartRef" Data="data" Config="config" />
@code {
IChartComponent chartRef;
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
// Using JsonElement directly
chartRef.On("plot:click", (JsonElement data) =>
{
Console.WriteLine($"Raw click data: {data}");
});
// Using strongly typed model
chartRef.On<PlotEvent>("plot:click", (data) =>
{
Console.WriteLine($"Clicked at x: {data.X}, y: {data.Y}");
});
}
}
class PlotEvent
{
public double X { get; set; }
public double Y { get; set; }
public object Data { get; set; }
}
}
Common chart events include:
plot:click
- Triggered when clicking on the chartplot:dblclick
- Triggered when double-clicking on the chartplot:mousemove
- Triggered when moving the mouse over the chartplot:mouseenter
- Triggered when the mouse enters the chart areaplot:mouseleave
- Triggered when the mouse leaves the chart areaelement:click
- Triggered when clicking on a chart element (e.g., line, bar)legend-item:click
- Triggered when clicking on a legend item
Use Once<T>
to subscribe to an event that should only be handled once:
await chartRef.Once<PlotEvent>("plot:click", (data) =>
{
// This handler will only be called once
Console.WriteLine($"First click at x: {data.X}, y: {data.Y}");
});
The event data is passed as System.Text.Json.JsonElement
by default, which you can handle directly or deserialize into a specific type using the generic methods. The actual structure of the event data depends on the event type and chart type.
A typical event data structure looks like this:
public class ChartEventData
{
public MappingData MappingData { get; set; }
public ChartData Data { get; set; }
public double X { get; set; }
public double Y { get; set; }
public string Color { get; set; }
public bool IsInCircle { get; set; }
public string Shape { get; set; }
public Style DefaultStyle { get; set; }
public Point[] Points { get; set; }
public Point[] NextPoints { get; set; }
}
public class MappingData
{
public ChartData Origin { get; set; }
public Point[] Points { get; set; }
public Point[] NextPoints { get; set; }
public double X { get; set; }
public double Y { get; set; }
public string Color { get; set; }
}
public class ChartData
{
public string Type { get; set; }
public int Sales { get; set; }
}
public class Point
{
public double X { get; set; }
public double Y { get; set; }
}
public class Style
{
public string Fill { get; set; }
public double FillOpacity { get; set; }
}
Example of handling event data:
chartRef.On<ChartEventData>("element:click", (data) =>
{
Console.WriteLine($"Clicked element: Type={data.Data.Type}, Sales={data.Data.Sales}");
Console.WriteLine($"Position: X={data.X}, Y={data.Y}");
Console.WriteLine($"Style: Color={data.Color}, Shape={data.Shape}");
});
You can unsubscribe from events using the Off
method. There are two ways to use it:
- Unsubscribe from a specific event handler:
@code {
IChartComponent chartRef;
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
// Subscribe to the event with a method
chartRef.On("plot:click", HandleChartClick);
// Later, unsubscribe this specific handler
chartRef.Off("plot:click", HandleChartClick);
}
}
private void HandleChartClick(JsonElement data)
{
Console.WriteLine($"Clicked: {data}");
}
}
- Unsubscribe from all handlers of a specific event or all events:
// Unsubscribe from all handlers of a specific event
await chartRef.Off("plot:click");
// Unsubscribe from all event handlers
await chartRef.Off();
It's good practice to unsubscribe from events when they are no longer needed or when the component is being disposed:
@implements IDisposable
@code {
IChartComponent chartRef;
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
// Subscribe to multiple events
chartRef.On("plot:click", HandleChartClick);
chartRef.On("element:click", HandleElementClick);
}
}
private void HandleChartClick(JsonElement data)
{
Console.WriteLine($"Chart clicked: {data}");
}
private void HandleElementClick(JsonElement data)
{
Console.WriteLine($"Element clicked: {data}");
}
public async void Dispose()
{
// Unsubscribe from all events when the component is disposed
if (chartRef != null)
{
await chartRef.Off();
}
}
}
If you would like to contribute, feel free to create a Pull Request, or give us Bug Report.
This project is an MIT-licensed open source project. In order to achieve better and sustainable development of the project, we expect to gain more backers. We will use the proceeds for community operations and promotion. You can support us in any of the following ways:
We will put the detailed donation records on the backer list.
If you encounter any problems in the process, feel free to ask for help via following channels. We also encourage experienced users to help newcomers.