Draw Dynamic ASP.NET Core Blazor Bubble Chart Using Canvas Extensions

Draw Dynamic ASP.NET Core Blazor Bubble Chart Using Canvas Extensions 
 
Here we have planned to write a series of articles. In each article we will explain in detail about how to draw our own chart for ASP.NET Core Blazor Web Application using HTML5 Canvas Blazor Extensions.
 
Today in this article we will see on how to draw our own bubble chart using ASP.NET Core Blazor Web Application using HTML5 Canvas.

In this series we will see one by one in detail starting from,
  1. Dynamic Bar Chart using Blazor Canvas Extentoins
  2. Dynamic Bubble Chart using Blazor Canvas Extentoins
  3. Dynamic Line Chart using Blazor Canvas Extentoins
  4. Dynamic Bar & Line Chart using Blazor Canvas Extentoins
Prerequisites

Create ASP.NET Core Blazor Server Application

 
After installing all the prerequisites listed above, click Start >> Programs >> Visual Studio 2019 >> Visual Studio 2019 on your desktop. Click New >> Project. 
 
Draw Dynamic ASP.NET Core Blazor Bubble Chart Using Canvas Extensions 
 
Select Blazor App and click Next button.
 
Draw Dynamic ASP.NET Core Blazor Bubble Chart Using Canvas Extensions 
 
Select your project folder and enter your project name and then click Create button.
 
Draw Dynamic ASP.NET Core Blazor Bubble Chart Using Canvas Extensions 
 
Select Blazor Server App
 
Draw Dynamic ASP.NET Core Blazor Bubble Chart Using Canvas Extensions 
 
After creating ASP.NET Core Blazor Server Application, wait for a few seconds. You will see the below structure in Solution Explorer.
 
Draw Dynamic ASP.NET Core Blazor Bubble Chart Using Canvas Extensions 
 
In the Data folder we can add all our Model, DBContext Class, Services and Controller. We will see that in this article.
 
In the Pages folder we can add all our component files. Component files all should have the .razor extension with the file name.
 
In the Shared folder we can add all left menus from NavMenu.razor file and change the main content from the MainLayout.razor file.
 
In the _Imports.razor file we can see all sets of imports have been added  to use in all component pages.
 
In the App.razor file we will add our main component to be displayed by default when run in browser. Appsertings.json can be used to add the connection string.
 
Startup.cs file is important file where we add all our endpoints for example like Controller end points, HTTP Client, add services and dbcontext to be used in startup Configuration method.
 
Run to test the application
 
When we run the application, we can see that the left side has navigation and the right side contains the data. We can see as the default sample pages and menus will be displayed in our Blazor web site. We can use the pages or remove it and start with our own page.
 
Draw Dynamic ASP.NET Core Blazor Bubble Chart Using Canvas Extensions 
 
Step 2 Install the Packages
 
To use the Blazor Canvas Extension in our Blazor Application we need to install the below packages
 
Blazor.Extensions.Canvas
 
Right click the solution and click on the Manage Nuget package. Search for all the packages and install all the needed packages like the below image.
 
Draw Dynamic ASP.NET Core Blazor Bubble Chart Using Canvas Extensions 
 
After installing the package, we can confirm it from Dependencies Packages.
 
Draw Dynamic ASP.NET Core Blazor Bubble Chart Using Canvas Extensions 
 
Note
Add the blazor.extensions.canvas.js File.
 
Open the _Host.cshtml file and add the below code inside the head tag.
  1. <script src="_content/Blazor.Extensions.Canvas/blazor.extensions.canvas.js"></script>  
Draw Dynamic ASP.NET Core Blazor Bubble Chart Using Canvas Extensions 
 
Step 3 Create Model Class
 
Next, we need to create the Model class for using in our application for binding the Item name and Item count in the Bar Chart.
 
Right Click the Data Folder and create new class file as “ItemMaster.cs”
 
Draw Dynamic ASP.NET Core Blazor Bubble Chart Using Canvas Extensions 
 
In the class we add the property field name same as in the below code.
  1. public String ItemName { getset; }  
  2.    public int SaleCount { getset; }  

Creating Service Class

 
Next we create the ItemMasterService class in order to bind the result in chart with sample Item details with the Item Name and Sale Count per each item. For this we right click on the Data folder and click on Add New Item to add our ItemMasterService class.
 
Draw Dynamic ASP.NET Core Blazor Bubble Chart Using Canvas Extensions 
 
In this class we create a method to get the ItemMaster details with a sample 5 records of items with item name and sale count per each item as random values.
  1. public class ItemMasterService  
  2.     {  
  3.         public Task<ItemMaster[]> GetItemMasters()  
  4.         {  
  5.             var rng = new Random();  
  6.             int ivale = 0;  
  7.             return Task.FromResult(Enumerable.Range(1, 5).Select(index => new ItemMaster  
  8.             {  
  9.                 ItemName = "itm" + rng.Next(1, 100),  
  10.                 SaleCount = rng.Next(20, 100),  
  11.             }).ToArray()); ;  
  12.         }  
  13.     }  
Step 4 - Add the Service to the Startup.cs
 
We need to add the services created by us to the Startup.cs ConfigureServices method.
 
services.AddSingleton<ItemMasterService>();
 
Step 5 - Working with Client Project
 
First, we need to add the Razor Component page
 

Add Razor Component

 
To add the Razor Component page right click the Pages folder from the Client project. Click on Add >> New Item >> Select Razor Component >> Enter your component name. Here we have given the name as DrawingSample.razor.
 
Note all the component files need to have the extensions as .razor.
 
Draw Dynamic ASP.NET Core Blazor Bubble Chart Using Canvas Extensions 
 
In Razor Component Page we have 3 parts of code. First is the Import part where we import all the references and models for using in the component, HTML design and data binding part and finally we have the function part to call all the web API to bind in our HTML page and also to perform client-side business logic to be displayed in component page.
 
Import part
 
First, we import all the needed support files and references in our Razor View page. Here we have first imported our Model class to be used in our view and also imported Blazor Canvas Extension for drawing our own chart control for Blazor applications.
  1. @page "/drawingsample"  
  2. @using Blazor.Extensions.Canvas  
  3. @using Blazor.Extensions;  
  4. @using Blazor.Extensions.Canvas.Canvas2D;  
  5. @using ClazorCharts.Data  
  6. @inject ItemMasterService MasterService  
HTML design and data binding part
 
Next, we design our DrawingSample details page to display the Bar Chart with item name and sales count per each item. Here we have added the Blazor Extension Canvas HTML5 canvas in our Blazor HTML design part for drawing the bar chart.
  1. <h3>Shanu - Draw Bar Chart using Blazor Canvas Extensions</h3>  
  2. <hr />    
  3. <BECanvas Width="500" Height="500" @ref="_canvasReference"></BECanvas>   
Function Part
 
Function part is to get the Service result and bind the result in array and to draw and plot the values for displaying the bar chart.
 
Here first we declare the ItemsArray to get bind the result of Item Master in BarChart.
 
Next, we create a string array as pirChartColor to draw each bar with different color from the array.
In OnInitializedAsync we get the ItemMasterService result and bind the result in the ItemsArrys.
 
In OnAfterRenderAsync Method we draw the Bar Chart using C# draw objects to the Canvas. we get all item names and values using foreach of Item Array and here we plot all values and draw Bubble charts using the Array values. Using the value, we will draw our Bubble chart on canvas tag from this method.
 

Bubble Chart

 
Bubble chart usually has a minimum of 3 variables,  as one is the Bubble Size and X plot value and y plot value. Here in our example the Bubble size is our SaleCount values and x and y values to draw the bubble inside our chart.
  1. @code {  
  2.     private Canvas2DContext _context;  
  3.     protected BECanvasComponent _canvasReference;  
  4.     ItemMaster[] itemsArrys;  
  5.     private static readonly string[] pirChartColor = new [] {  
  6.         "#3090C7",  
  7.         "#BDEDFF",  
  8.         "#F9B7FF",  
  9.         "#736AFF",  
  10.         "#78C7C7",  
  11.         "#B048B5",  
  12.         "#4E387E",  
  13.         "#7FFFD4",  
  14.         "#3EA99F",  
  15.         "#EBF4FA",  
  16.         "#F9B7FF",  
  17.         "#8BB381",  
  18.         //"#6CBB3C", "#F87217", "#EAC117", "#EDDA74", "#CD7F32", "#CCFB5D", "#FDD017", "#9DC209", "#E67451", "#728C00","#617C58", "#64E986"  
  19.     };  
  20.     protected override async Task OnInitializedAsync() {  
  21.         itemsArrys = await MasterService.GetItemMasters();  
  22.     }  
  23.     protected override async Task OnAfterRenderAsync(bool firstRender) {  
  24.         lastend = 0;  
  25.         xSpace = 10;  
  26.         XvalPosition = xSpace;  
  27.         maxDataVal = itemsArrys.Max(row => row.SaleCount);  
  28.         noOfPlots = itemsArrys.Length;  
  29.         chartWidth = Convert.ToInt32(_canvasReference.Width);  
  30.         chartHeight = Convert.ToInt32(_canvasReference.Height);  
  31.         int widthcalculation = (Convert.ToInt32(_canvasReference.Width) - 100) / itemsArrys.Length;  
  32.         chartHeight = Convert.ToInt32(_canvasReference.Height) - 40;  
  33.         this._context = await this._canvasReference.CreateCanvas2DAsync();  
  34.         int colorval = 0;  
  35.         // Draw the axises  
  36.         await this._context.BeginPathAsync();  
  37.         await this._context.MoveToAsync(xSpace, xSpace);  
  38.         // first Draw Y Axis  
  39.         await this._context.LineToAsync(xSpace, chartHeight);  
  40.         // Next draw the X-Axis  
  41.         await this._context.LineToAsync(Convert.ToInt32(_canvasReference.Width) - 10, chartHeight);  
  42.         await this._context.StrokeAsync();  
  43.         int varbubbleSize = 30;  
  44.         int ival = 1;  
  45.         @foreach(var itemsArry in itemsArrys) {  
  46.             // Draw Xaxis Plots Line and Text   ***********  
  47.             XvalPosition = XvalPosition + widthcalculation;  
  48.             await this._context.MoveToAsync(XvalPosition, chartHeight);  
  49.             await this._context.LineToAsync(XvalPosition, chartHeight + 15);  
  50.             await this._context.StrokeAsync();  
  51.             await this._context.SetFillStyleAsync("#034560");  
  52.             await this._context.SetStrokeStyleAsync("#034560");  
  53.             await this._context.SetFontAsync("12pt Calibri");  
  54.             await this._context.StrokeTextAsync(itemsArry.ItemName, XvalPosition - 40, chartHeight + 24);  
  55.             //  EndXval Plotting  ************  
  56.             ////Draw Bar Graph  **************==================********************  
  57.             await this._context.SetFillStyleAsync(pirChartColor[colorval]);  
  58.             await this._context.SetStrokeStyleAsync(pirChartColor[colorval]);  
  59.             await this._context.BeginPathAsync();  
  60.             varbubbleSize = itemsArry.SaleCount;  
  61.             if (itemsArry.SaleCount > 70) {  
  62.                 varbubbleSize = itemsArry.SaleCount - 10;  
  63.             }  
  64.             await this._context.ArcAsync(getXPlotvalue(ival) - 6, getYPlotVale(varbubbleSize - 10), varbubbleSize, varbubbleSize, Math.PI * 2, true);  
  65.             await this._context.FillAsync();  
  66.             await this._context.StrokeAsync();  
  67.             await this._context.SetFillStyleAsync("#034560");  
  68.             await this._context.SetStrokeStyleAsync("#034560");  
  69.             await this._context.SetFontAsync("12pt Calibri");  
  70.             await this._context.StrokeTextAsync(itemsArry.SaleCount.ToString(), getXPlotvalue(ival) - 12, getYPlotVale(itemsArry.SaleCount) + 46);  
  71.             await this._context.SetStrokeStyleAsync("#C0C0C0");  
  72.             colorval = colorval + 1;  
  73.             ival = ival + 1;  
  74.         }  
  75.     }  
Method to get X plot and Y Plot Value
 
Here we calculate drawing our Chart item in the X and in Y Axis.
  1.     // to return the x-Value    
  2. private double getXPlotvalue(int val) {    
  3.   
  4. return Convert.ToDouble((chartWidth-40) / noOfPlots) * val + (xSpace * 1.5) - 20;   
  5. }    
  6.     
  7. // Return the y value    
  8. private double  getYPlotVale(int val) {    
  9.    return chartHeight - (((chartHeight - xSpace) / maxDataVal) * val);    
  10.     
  11. }  }  
Navigation Menu
 
Now we need to add this newly added DrawingSample Razor page to our left Navigation. For adding this, open the Shared Folder and open the NavMenu.cshtml page and add the menu.
  1. <li class="nav-item px-3">  
  2.             <NavLink class="nav-link" href="DrawingSample">  
  3.                 <span class="oi oi-list-rich" aria-hidden="true"></span> Bar Chart  
  4.             </NavLink>  
  5.         </li>  
Build and Run the Application
 
Draw Dynamic ASP.NET Core Blazor Bubble Chart Using Canvas Extensions 
 

Conclusion

 
In this sample we have used a simple method to display the Bubble Chart within 0 to 100 range values. In order to use this for many scales, we can extend this chart to draw the Legend and other details. As this is our own Chart we can add any functions as per our need. In the next article we will see in detail on making our own chart using ASP.NET Blazor.