[Chartjs]-I am using chart.js in my Blazor app with JSInterop. How can I update my chart when there is a new data in the data set?

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();
    }
}

Leave a comment