It’s not just that the Chart component in Telerik UI for Blazor makes it easy to create charts – it’s that the Chart component makes it easy for you to let the user have the chart they want.
You can produce whatever report or chart you want but, if it’s used by more than one person, you can be pretty much guaranteed that your chart won’t be “right” for more than one of them. For all the rest of your users, your chart won’t be in the “right” format, it won’t combine the “right” data, and so on. Even if you have an audience of one that you can tailor your chart for, you’re guaranteed that when that person moves on to a new job, the replacement will want significant changes to the chart.
This is, of course, one of the reasons that dashboards are popular: They allow users to configure the various widgets on the page to meet each user’s particular wants/needs. The Chart component in Telerik UI for Blazor supports that same kind of flexibility through its ability to be dynamically reconfigured at runtime. In other words, you can not only deliver a chart to the user, you can also give users the ability to customize the chart to get the view they want.
In a previous post, Creating Charts with the Telerik Chart Component for Blazor, I showed how the Chart’s Independent Series binding mechanism let me massage an incoming set of data into the data points that the user wanted. The markup and code to make that work looked like this:
<TelerikChart>
<ChartSeriesItems>
<ChartSeries Type="@selectedType" Data="@quantitiesSold">
</ChartSeries>
</ChartSeriesItems>
<ChartCategoryAxes>
<ChartCategoryAxis Categories="@months"></ChartCategoryAxis>
</ChartCategoryAxes>*@
</TelerikChart>
@code {
private IEnumerable<object> quantitiesSold;
private string[] months;
In this example, I’m using what Telerik calls “Independent Series” binding. Independent Series binding requires two collections: One to hold the “data to be graphed” or Y-axis data (quantitiesSold, in my case), and one to hold the labels for that data or the X-axis data (months, in this code). I built both collections in my component’s OnInitializedAsync method from an initial collection of SalesDTO objects.
But now that I’ve created that initial chart, I can start giving the user the ability to customize it. To begin with, I’ll let the user select the year for the data so the user can look at previous years.
My first step in letting the user pick the year to display is to declare two fields: one to hold the list of years retrieved from my collection of SaleDTOs, and one to hold the year that my user has selected. Those two fields look like this:
@code {
private List<string> years;
private string selectedYear;
In my OnInitializedAsync method, after retrieving my data and loading my months field, I’ll load my years field with the available years in the SalesDTO collection using code like this:
years = (from s in graphSales
orderby s.Year
select s.Year).Distinct().ToList();
Finally, in my markup, I’ll generate a dropdown list with options for each of the years. I’ll bind that dropdown list to my selectedYear field so that the field is automatically updated whenever the user selects a year:
Year: <select @bind="selectedYear">
<option>Pick a Year</option>
@foreach (string year in years)
{
<option>@year</option>
}
</select>
My last step in letting the user select which data to use is to update the statement that loads the quantitiesSold field that, in turn, drives my chart. Instead of hardcoding in the current year as I did originally, I’ll have the LINQ query that fills the field use my selectedYear field (Blazor will take care of regenerating the collection each time selectedYear changes):
quantitiesSold = (from s in graphSales
where s.Year == selectedYear
orderby s.MonthOrder
select (object)s.QuantitySold);
That works great for my ChartSeries… but is less successful for my ChartAxis. While I can use my selectedYear field in the query that generates my list of month names, that query isn’t regenerated when the user selects a new year.
The solution is relatively simple, though. First, I convert my selectedYear field into a fully written out property. Then I regenerate my months list in the property’s setter, instead of doing it in my OnInitializedAsync method. Here’s the new version of the selectedYear “property that used to be a field” that will refill the months field every time the user selects a new year:
string selectedyear = "Pick a Year";
private string selectedYear
{
get
{
return selectedyear;
}
set
{
selectedyear = value;
months = (from s in graphSales
where s.Year == selectedyear
orderby s.MonthOrder
select s.Month).Distinct().ToArray();
}
}
You could make a very good case that I should move the code that fills my quantitiesSold field to this setter also. However, the code is working in the OnInitializedAsync method, and Vogel’s first law of programming is, “You don’t screw with working code,” – so I’ll leave it in place.
That’s cool, but it’s considerably sexier to let the user change the chart type. With the Chart component, I can do that, too.
First, I need another field, this time to hold my chart type. I’ll initialize this field to the type I think that the user is most likely to want (if I don’t initialize this field, my Chart will default to Area, which, while not the worst choice in the world, is less likely to be my user’s favorite than, for example, a line chart). Here’s that field:
private ChartSeriesType selectedChartType = ChartSeriesType.Line;
I’ll then provide the user with another dropdown list that lets the user select their chart type. I’ll bind the dropdown list to my selectedChartType field. That dropdown list looks like this:
Type: <select @bind="selectedChartType">
<option value="@ChartSeriesType.Line">Line</option>
<option value="@ChartSeriesType.Bar">Bar</option>
<option value="@ChartSeriesType.Column">Column</option>
<option value="@ChartSeriesType.Area">Area</option>
</select>
The last step is, in the TelerikChart element, to bind the ChartSeries’ Type attribute to my selectedChartType field. That change gives me this:
<ChartSeries Type="@selectedChartType" Data="@quantitiesSold">
</ChartSeries>
And now I have the display in Figure 2 below:
My user may still not have, initially, the display they want. But I’ve given them some options to customize that display to get to what they do want. In other words, I may not be able to make them happy, but I can keep them busy.
To learn more about Telerik UI for Blazor components and what they can do, check out the Blazor demo page or download a trial to start developing right away.
Peter Vogel is a system architect and principal in PH&V Information Services. PH&V provides full-stack consulting from UX design through object modeling to database design. Peter also writes courses and teaches for Learning Tree International.