Using Chart.js with Blazor

Microsoft Blazor wallpaper

In this post, I want to show you how using Chart.js with Blazor Server or Blazor Web Assembly. I won’t use any external components like ChartJs.Blazor a popular component you can find on GitHub.

What is Chart.js?

Chart.js is a an open source library written in JavaScript that helps you to create beautiful graphs such as bar, line, pie charts, animated charts and so on. Have a look to the website to understand what this library can do for you.

Home page of Chart.js - Using Chart.js with Blazor
Home page of Chart.js

Because this library is very popular and the graphs are very nice, I wanted to use it in my Blazor projects. Unfortunately, I tried some wraps of this library for Blazor but none of them are working properly. There are some commercial libraries but I don’t want to spend money. Where is the fun?

So, I want to find a way to create my own implementation.

Adding Chart.js to the project

First step is to add the library in your Blazor project. So, my project is a Blazor Web Assembly and in my case I have to add the Chart.js in the index.html. This is the script I have to add

<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>

So, the application reads the script from the CDN. Generally speaking, I prefer to have all the libraries under my control and for this reason I prefer to add a Client-Side Library. For that, in Visual Studio right-click on your project and select Add and then Client-Side Library.

Add Client-Side Library in Visual Studio 2019 - Using Chart.js with Blazor
Add Client-Side Library in Visual Studio 2019

Then, in the Add Client-Side Library window, in the Library textbox, start to type chart.js. When you start to type, you see a dropdown list with all the libraries you can select.

Add Client-Side Library window - Using Chart.js with Blazor
Add Client-Side Library window

Now, click on the library and select the Target Location. You have to save the library under wwwroot. To separate my JavaScript for external libraries, I save the external libraries in a lib folder.

 Add Client-Side Library window - Select chart.js - Using Chart.js with Blazor
Add Client-Side Library window – Select chart.js

So, in the index.html I can add the library from my project

<script src="lib/Chart.js/chart.js"></script>

Creating a Chart Blazor component

So, first step is creating a new Blazor component. Under Shared folder, I created a new Components folder and here I’m going to create a new Razor component and its name is Chart. Now, remember to add the reference in _Imports,razor like

@using yourproject.Shared.Components 

The component will receive all the data from the parent and pass it down to the Chart.js library via Javascript interop. It will have the following properties: Id, Type, Data, BackgroundColor and Labels. For example:

<Chart Id="pie1" Type="@Chart.ChartType.Pie" 
        Data="@(new[] { "1", "2" })" BackgroundColor="@(new[] { "blue","green" })" 
        Labels="@(new[] { "Fail","Ok" })">
</Chart>

Since we have to have the canvas html element rendered in the page before invoking the library we use OnAfterRenderAsync to do our logic and call the js library.

@inject IJSRuntime JSRuntime

<canvas id="@Id"></canvas>

@code {
    public enum ChartType
    {
        Pie,
        Bar
    }

    [Parameter]
    public string Id { get; set; }

    [Parameter]
    public ChartType Type { get; set; }

    [Parameter]
    public string[] Data { get; set; }

    [Parameter]
    public string[] BackgroundColor { get; set; }

    [Parameter]
    public string[] Labels { get; set; }

    protected override async Task OnAfterRenderAsync(bool firstRender) 
    {
        // Here we create an anonymous type with all the options 
        // that need to be sent to Chart.js
        var config = new
        {
            Type = Type.ToString().ToLower(),
            Options = new
            {
                Responsive = true,
                Scales = new
                {
                    YAxes = new[]
                    {
                        new { Ticks = new {
                            BeginAtZero=true
                        } }
                    }
                }
            },
            Data = new
            {
                Datasets = new[]
                {
                    new { Data = Data, BackgroundColor = BackgroundColor}
                },
                Labels = Labels
            }
        };

        await JSRuntime.InvokeVoidAsync("setup", Id, config);
    }
}

Calling Setup

We create a new javascript file called chart.js which initializes our Chart js component in a function called setup(). It receives the canvas Id and the config options from the blazor component.

window.setup = (id,config) => {
    var ctx = document.getElementById(id).getContext('2d');
    new Chart(ctx, config);
}

Then, in the index.html I have to add this script

<script src="chart.js"></script>

Using the new component

Now we have our <Chart> component ready to be used. Simply add the tag to a new page/component like

<Chart Id="pie1" Type="@Chart.ChartType.Pie"
       Data="@(new[] { "1", "2" })"
       BackgroundColor="@(new[] { "blue","green" })"
       Labels="@(new[] { "Fail","Ok" })">
</Chart>

and the result of it is this graph.

Pie Chart with the Blazor component
Pie Chart with the Blazor component

For a bar chart you can use this code

<Chart Id="bar1" Type="@Chart.ChartType.Bar" 
       Data="@(new[] { "10", "9" })" 
       BackgroundColor="@(new[] { "yellow","red"})" 
       Labels="@(new[] { "Fail","Ok" })">
</Chart>

and the result is the following image

Bar chart with the Blazor component
Bar chart with the Blazor component

This is a bare bone implementation that can be used as a blueprint if you want to extend it. Chart.js offers many different options to render the charts and they just need to be mapped in our anonymous class. E.g. If we want to create a property that holds the dataset label (and remove undefined from our rendered object) we would have something like this

var config = new
{
    Type = Type.ToString().ToLower(),
    Options = new
    {
        Responsive = true,
        Scales = new
        {
            YAxes = new[]
            {
                new { Ticks = new {
                    BeginAtZero=true
                } }
            }
        }
    },
    Data = new
    {
        Datasets = new[]
        {
            new { Data = Data, 
                    BackgroundColor = BackgroundColor, 
                    Label=YourNewLabelProperty}
        },
        Labels = Labels
    }
};

Wrap up

so, in this post Using Chart.js with Blazor I created a simple component to show bar and pie graphs using Chart.js in Blazor. This is quite simple but it is a start. Please you comment below or in the Forum.

Happy coding!

3 thoughts on “Using Chart.js with Blazor

  1. This is exactly what I was after, any chance you can guide me on how I can handle chart onclick event for further drill down?

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.