使用 Canvas 扩展绘制动态 ASP.NET Core Blazor 气泡图





5.00/5 (2投票s)
如何使用 HTML5 Canvas 和 ASP.NET Core Blazor Web 应用程序绘制自己的气泡图
引言

在本系列中,我们将一一详细介绍,从
- 使用 Blazor Canvas 扩展绘制动态条形图
- 使用 Blazor Canvas 扩展绘制动态气泡图 (当前)
- 使用 Blazor Canvas 扩展绘制动态折线图
- 使用 Blazor Canvas 扩展绘制动态条形图和折线图
在今天的文章中,我们将使用 HTML5 Canvas 和 ASP.NET Core Blazor Web 应用程序来学习如何绘制自己的气泡图。
背景
Using the Code
步骤 1:创建 ASP.NET Core Blazor Server 应用程序
安装完上述所有先决条件后,在桌面上点击开始 >> 程序 >> Visual Studio 2019 >> Visual Studio 2019。点击新建 >> 项目。

选择 Blazor 应用 并点击 下一步 按钮。

选择您的项目文件夹并输入您的项目名称,然后点击 创建 按钮。

选择 Blazor 服务器应用。

创建 ASP.NET Core Blazor Server 应用程序后,请等待几秒钟。您将在解决方案资源管理器中看到如下结构。

在Data文件夹中,我们可以添加所有模型、DBContext类、服务和控制器,我们将在本文中介绍。
在Pages文件夹中,我们可以添加所有组件*文件。组件文件都应具有* .razor*扩展名。
在Shared文件夹中,我们可以添加所有左侧菜单,例如NavMenu.razor文件,并从MainLayout.razor文件中更改主内容。
在_Imports.razor文件中,我们可以看到已添加所有导入集,以便在所有组件页面中使用。
在 App.razor 文件中,我们将添加在浏览器中运行应用程序时默认显示的主组件。Appsertings.json 可用于添加连接字符串。
Startup.cs文件是一个重要文件,我们在此文件中添加所有端点,例如控制器端点、HTTP 客户端、添加要在启动Configuration方法中使用的服务和dbcontext。
运行以测试应用程序
当我们运行应用程序时,我们可以看到左侧有导航,右侧包含数据。我们可以看到 Blazor 网站中将显示默认的示例页面和菜单。我们可以使用这些页面,也可以删除它们并开始创建自己的页面。

步骤 2:安装包
要在我们的 Blazor 应用程序中使用 Blazor Canvas 扩展,我们需要安装以下包
- Blazor.Extensions.Canvas
右键单击解决方案,然后点击管理 Nuget 包。搜索所有包并安装所有需要的包,如下图所示

安装包后,我们可以在依赖项包中进行确认。

注意:添加* blazor.extensions.canvas.js*文件。
打开* _Host.cshtml*文件,并在head标签内添加以下代码。
    <script src="_content/Blazor.Extensions.Canvas/blazor.extensions.canvas.js"></script>

步骤 3:创建模型类
接下来,我们需要创建Model类,以便在我们的应用程序中使用,用于在条形图中绑定项目名称和项目数量。
右键单击Data文件夹,然后创建一个新的类文件,名为“ItemMaster.cs”。

在该类中,我们添加与下面代码相同的属性字段名称
     public String ItemName { get; set; }
     public int SaleCount { get; set; }
创建服务类
接下来,我们创建ItemMasterService类,以便使用示例项目详细信息(包括项目名称和每个项目的销售数量)将结果绑定到图表中。为此,我们右键单击Data文件夹,然后点击添加新项来添加我们的ItemMasterService类。

在此类中,我们创建一个方法来获取ItemMaster详细信息,其中包含 5 条示例记录,每个项目的名称和销售数量为随机值。
public class ItemMasterService
    {
        public Task<ItemMaster[]> GetItemMasters()
        {
            var rng = new Random();
            int ivale = 0;
            return Task.FromResult(Enumerable.Range(1, 5).Select(index => new ItemMaster
            {
                ItemName = "itm" + rng.Next(1, 100),
                SaleCount = rng.Next(20, 100),
            }).ToArray()); 
        }
    }
步骤 4:将服务添加到 Startup.cs
我们需要将我们创建的服务添加到Startup.cs的ConfigureServices方法中。
services.AddSingleton<ItemMasterService>();
步骤 5:使用客户端项目
首先,我们需要添加 Razor 组件页面。
添加 Razor 组件
要添加 Razor 组件页面,请右键单击Client项目中的Pages文件夹。点击添加 >> 新项 >> 选择 Razor 组件 >> 输入您的组件名称。这里,我们将名称设为*DrawingSample.razor*。
注意:所有组件文件都需要以* .razor*为扩展名。

在 Razor 组件页面中,代码有三个部分:第一个是Import部分,我们在其中导入所有需要的引用和模型以在组件中使用;第二个是 HTML 设计和数据绑定部分;最后是函数部分,用于调用所有 Web API 以绑定到我们的 HTML 页面,并执行客户端业务逻辑以显示在组件页面上。
导入部分
首先,我们在 Razor 视图页面中导入所有必需的支持文件和引用。这里,我们首先导入了将在视图中使用的Model类,并且还导入了 Blazor Canvas 扩展,用于为 Blazor 应用程序绘制我们自己的图表控件。
@page "/drawingsample"
@using Blazor.Extensions.Canvas
@using Blazor.Extensions;
@using Blazor.Extensions.Canvas.Canvas2D;
@using ClazorCharts.Data
@inject ItemMasterService MasterService
HTML 设计和数据绑定部分
接下来,我们设计DrawingSample详细信息页面,以显示带有项目名称和每个项目销售数量的条形图。这里,我们在 Blazor HTML 设计部分添加了 Blazor Extension HTML5 canvas,用于绘制条形图。
<h3>Shanu - Draw Bar Chart using Blazor Canvas Extensions</h3>
<hr />  
<BECanvas Width="500" Height="500" @ref="_canvasReference"></BECanvas> 
函数部分
函数部分用于获取服务结果并将结果绑定到数组,然后绘制和绘制值以显示条形图。
在这里,我们首先声明ItemsArray,用于将 Item Master 的结果绑定到BarChart。
接下来,我们创建一个string数组pirChartColor,用于为每个条形图绘制不同的颜色。
在OnInitializedAsync中,我们获取ItemMasterService结果并将结果绑定到ItemsArrys。
在OnAfterRenderAsync方法中,我们使用 C# 绘图对象在Canvas上绘制条形图。我们使用foreach遍历 Item Array 来获取所有项目名称和值,并在此处绘制所有值,并使用数组值绘制气泡图。使用这些值,我们将在此方法中绘制气泡图到 canvas 标签上。
气泡图
气泡图通常至少有 3 个变量:一个用于气泡大小,一个用于 X 轴值,一个用于 Y 轴值。在我们的示例中,气泡大小由SaleCount值决定,并使用xvalue和y值在图表中绘制气泡。
@code {
    private Canvas2DContext _context;
    protected BECanvasComponent _canvasReference;
    ItemMaster[] itemsArrys;
    private static readonly string[] pirChartColor = new[]
      {
      "#3090C7", "#BDEDFF", "#F9B7FF", "#736AFF", "#78C7C7", 
      "#B048B5", "#4E387E","#7FFFD4", "#3EA99F", "#EBF4FA", "#F9B7FF", "#8BB381",
          //"#6CBB3C", "#F87217", "#EAC117", "#EDDA74", "#CD7F32", 
          //"#CCFB5D", "#FDD017", "#9DC209", "#E67451", "#728C00","#617C58", "#64E986"
        };
    protected override async Task OnInitializedAsync()
    {
        itemsArrys = await MasterService.GetItemMasters();
    }
    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        lastend = 0;
        xSpace = 10;
        XvalPosition = xSpace;
        maxDataVal = itemsArrys.Max(row => row.SaleCount);
        noOfPlots = itemsArrys.Length;
        chartWidth = Convert.ToInt32(_canvasReference.Width);
        chartHeight = Convert.ToInt32(_canvasReference.Height);
        int widthcalculation = 
            (Convert.ToInt32(_canvasReference.Width) - 100) / itemsArrys.Length;
        chartHeight = Convert.ToInt32(_canvasReference.Height) - 40;
        this._context = await this._canvasReference.CreateCanvas2DAsync();
        int colorval = 0;
        // Draw the axises
        await this._context.BeginPathAsync();
        await this._context.MoveToAsync(xSpace, xSpace);
        // first Draw Y Axis
        await this._context.LineToAsync(xSpace, chartHeight);
        // Next draw the X-Axis
        await this._context.LineToAsync
              (Convert.ToInt32(_canvasReference.Width) - 10, chartHeight);
        await this._context.StrokeAsync();
       
      int  varbubbleSize = 30;  
  
   int ival = 1; 
        @foreach (var itemsArry in itemsArrys)
        {
            // Draw Xaxis Plots Line and Text   ***********
            XvalPosition = XvalPosition + widthcalculation;
            await this._context.MoveToAsync(XvalPosition, chartHeight);
            await this._context.LineToAsync(XvalPosition, chartHeight + 15);
            await this._context.StrokeAsync();
            await this._context.SetFillStyleAsync("#034560");
            await this._context.SetStrokeStyleAsync("#034560");
            await this._context.SetFontAsync("12pt Calibri");
            await this._context.StrokeTextAsync
                  (itemsArry.ItemName, XvalPosition - 40, chartHeight + 24);
            //  EndXval Plotting  ************
            ////Draw Bar Graph  **************==================********************
            await this._context.SetFillStyleAsync(pirChartColor[colorval]);
            await this._context.SetStrokeStyleAsync(pirChartColor[colorval]);
            await this._context.BeginPathAsync();
            varbubbleSize = itemsArry.SaleCount;
            if(itemsArry.SaleCount>70)
            {
                varbubbleSize = itemsArry.SaleCount-10;
            }
            await this._context.ArcAsync(getXPlotvalue(ival)-6, 
            getYPlotVale(varbubbleSize-10), varbubbleSize, varbubbleSize, Math.PI * 2, true);
            await this._context.FillAsync();
            await this._context.StrokeAsync();
            await this._context.SetFillStyleAsync("#034560");
            await this._context.SetStrokeStyleAsync("#034560");
            await this._context.SetFontAsync("12pt Calibri");
            await this._context.StrokeTextAsync(itemsArry.SaleCount.ToString(), 
            getXPlotvalue(ival)-12, getYPlotVale(itemsArry.SaleCount)+46);
            await this._context.SetStrokeStyleAsync("#C0C0C0");             
            colorval = colorval + 1;
            ival = ival + 1;
        }
    }
获取 X 轴和 Y 轴值的方法:在这里,我们计算要在 X 轴和 Y 轴上绘制图表的项目。
// to return the x-Value  
private double getXPlotvalue(int val) {  
return Convert.ToDouble((chartWidth-40) / noOfPlots) * val + (xSpace * 1.5) - 20; 
}  
  
// Return the y value  
private double  getYPlotVale(int val) {  
   return chartHeight - (((chartHeight - xSpace) / maxDataVal) * val);  
  
}  }
导航菜单
现在我们需要将这个新添加的DrawingSample Razor 页面添加到我们的左侧导航中。为此,请打开 Shared 文件夹并打开*NavMenu.cshtml*页面,然后添加菜单项。
<li class="nav-item px-3">
            <NavLink class="nav-link" href="DrawingSample">
                <span class="oi oi-list-rich" aria-hidden="true"></span> Bar Chart
            </NavLink>
        </li>
构建并运行应用程序

关注点
在此示例中,我们使用了简单的方法来显示 0 到 100 范围内的气泡图。为了处理更大的范围,我们可以扩展此图表以绘制图例和其他详细信息。由于这是我们自己的图表,我们可以根据需要添加任何功能。在下一篇文章中,我们将详细介绍如何使用 ASP.NET Blazor 创建其他自定义图表。
历史
- 2020 年 3 月 6 日:BlazorChartSrc.zip


