ASP.NET Core: Building Charts with Razor Pages

August 21st, 2020

In this post, we revisit the previous charting project and refactor the code to use ASP.NET Core with Razor Pages.

After ASP.NET MVC, Core introduced ASP.NET Razor Pages. ASP.NET Razor Pages takes the simplicity of ASP.NET MVC and eases developers into a page-specific model. This gives developers a transition into the latest version of Microsoft's web development approach.

Back in April, the post titled Creating Charts with ASP.NET Core triggered some comments, questions, and emails about how to achieve charting using Razor pages.

Before we start, I also want to mention the awesome parts of ASP.NET.

While the concepts from our previous charting demo are in ASP.NET Core MVC, our core codebase is merely shuffled to the shiny and new parts of Razor pages.

Preliminary Setup

In our previous charting example, we required some packages and initial setup before writing code.

Create the Application

First, create your project using File / New Project.

Create an ASP.NET Core Web Application, fill out the Location details, and select ASP.NET MVC "Web Application" (NOT "Web Application (Model-View-Controller)"). As a hint, it will say "Razor Pages" near the end of the description.

Manage Client-side libraries

Once you have your project created and Visual Studio has settled down, right-click on your project (not solution), and select "Manage client-side libraries."

Add the ChartJs library (currently 2.9.3) using the following libman.js file.

{
  "version": "1.0",
  "defaultProvider": "cdnjs",
  "libraries": [
    {
      "library": "Chart.js@2.9.3",
      "destination": "wwwroot/lib/chartjs"
    }
  ]
}

Hit Ctrl-S to save and Visual Studio will download the package to your destination folder (wwwroot/lib/chartjs in this case).

Newtonsoft.Json

Install the latest version of Newtonsoft.Json from NuGet.

Building the Chart

With the preliminary setup out of the way, we can now focus on the ChartJs model. The ChartJs model is exactly the same as the previous example.

The ChartJs model contains too many classes to place into this post so I recommend you download (or clone) the models from the previous project located here: https://github.com/jdanylko/Chart-ASPNETCore/tree/master/ChartExample/Models/Chart.

Once you have your models in a folder in your project, the next step is to add the JavaScript and CSS to the _Layout.cshtml (found in the Pages/Shared folder).

Next, open your Index.cshtml file.

If you notice, there is a .cshtml and a .cs file. Our .cshtml file will look like this:

/Pages/Index.cshtml

<div class="chart-container" width="600" height="400">
    <canvas id="myChart"></canvas>
</div>

<script>
    document.addEventListener('DOMContentLoaded', (event) => {

       var ctx = document.getElementById('myChart');
        var myChart = new Chart(ctx, @Html.Raw(Model.ChartJson) );

   });
</script>

If you've seen the previous chart project, this HTML should look extremely familiar to you. ;-)

The DOMContentLoaded event in the script gives the browser enough time to load the entire page before kicking off the script.

To finish this project, we need to write the "code-behind" for the OnGet method.

/Pages/Index.cshtml.cs

public class IndexModel : PageModel
{
    public ChartJs Chart { get; set; }
    public string ChartJson { get; set; }

   private readonly ILogger<IndexModel> _logger;

   public IndexModel(ILogger<IndexModel> logger)
    {
        _logger = logger;
    }

   public void OnGet()
    {
        // Ref: https://www.chartjs.org/docs/latest/
        var chartData = @"
        {
            type: 'bar',
            responsive: true,
            data:
            {
                labels: ['Red', 'Blue', 'Yellow', 'Green', 'Purple', 'Orange'],
                datasets: [{
                    label: '# of Votes',
                    data: [12, 19, 3, 5, 2, 3],
                    backgroundColor: [
                    'rgba(255, 99, 132, 0.2)',
                    'rgba(54, 162, 235, 0.2)',
                    'rgba(255, 206, 86, 0.2)',
                    'rgba(75, 192, 192, 0.2)',
                    'rgba(153, 102, 255, 0.2)',
                    'rgba(255, 159, 64, 0.2)'
                        ],
                    borderColor: [
                    'rgba(255, 99, 132, 1)',
                    'rgba(54, 162, 235, 1)',
                    'rgba(255, 206, 86, 1)',
                    'rgba(75, 192, 192, 1)',
                    'rgba(153, 102, 255, 1)',
                    'rgba(255, 159, 64, 1)'
                        ],
                    borderWidth: 1
                }]
            },
            options:
            {
                scales:
                {
                    yAxes: [{
                        ticks:
                        {
                            beginAtZero: true
                        }
                    }]
                }
            }
        }"
;

       Chart = JsonConvert.DeserializeObject<ChartJs>(chartData);
        ChartJson = JsonConvert.SerializeObject(Chart, new JsonSerializerSettings
        {
            NullValueHandling = NullValueHandling.Ignore,
        });
    }
}

In our previous chart example in ASP.NET Core MVC, we required a ViewModel (ChartJsViewModel to be exact). With Razor pages, we don't need a ViewModel at all. We only needed to include the members at the top of the class. They're automatically added to a Model and passed into the View.

Run the example and you should have the same display from our previous project.

If you want to try it yourself, check out the GitHub repository.

Conclusion

In this post, we revisit the previous ASP.NET Core MVC charting project and refactor it to use ASP.NET Core with Razor Pages.

As I mentioned before, you can use any type of JavaScript charting library using this technique. With these two examples, each one can be extended to use the full charting library. It depends on how far you take it.

Do you have a favorite charting library? Did you build your own? Post your comments below and let's discuss.