2👍
✅
Normally you use JSRuntime’s InvokeAsnyc
or InvokeVoidAsync
methods as for all other JS interop calls. Here is a simple example.
JavaScript part:
window.setupChart = (id, config) => {
var ctx = document.getElementById(id).getContext('2d');
new Chart(ctx, config);
}
Blazor C# part:
[Inject]
public IJSRuntime JSRunTime { get; set; }
public string id = "chartCanvas"; // ID for canvas: <canvas id="@Id"></canvas>
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
var config = new
{
Type = "line",
Options = new { ... },
Data = new { ... }
}
await JSRuntime.InvokeVoidAsync("setupChart", id, config);
}
}
It works perfectly, but you can’t update the chart or cannot add anything to it.
The solution is IJSObjectReference
in Blazor. This is exactly what this function is for.
You need to change the previous code to the followings:
JavaScript part:
window.setupChart = (id, config) => {
var ctx = document.getElementById(id).getContext('2d');
return new Chart(ctx, config);
},
window.updateChart = (chartRef, visible) => {
// Example: make visible/hidden the 4th dataset in the chart
chartRef.data.datasets[3].hidden = visible;
chartRef.update();
}
Blazor C# part:
[Inject]
public IJSRuntime JSRunTime { get; set; }
private IJSObjectReference? chartInstance;
public string id = "chartCanvas";
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
var config = new
{
Type = "line",
Options = new { ... },
Data = new { ... }
}
chartInstance = await JSRuntime.InvokeAsync<IJSObjectReference>("setupChart", id, config);
}
}
public async Task UpdateChart()
{
await JSRuntime.InvokeVoidAsync("updateChart", chartInstance, false);
}
And that’s it, you can update your existing chart.
And don’t forget to implement @implements IAsyncDisposable
in your razor component, as well as to dispose it:
async ValueTask IAsyncDisposable.DisposeAsync()
{
if (chartInstance is not null)
{
await chartInstance.DisposeAsync();
}
}
Source:stackexchange.com