使用 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