65.9K
CodeProject 正在变化。 阅读更多。
Home

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

starIconstarIconstarIconstarIconstarIcon

5.00/5 (2投票s)

2020 年 3 月 6 日

CPOL

6分钟阅读

viewsIcon

16159

downloadIcon

167

如何使用 HTML5 Canvas 和 ASP.NET Core Blazor Web 应用程序绘制自己的气泡图

引言

在本系列中,我们将一一详细介绍,从

  1. 使用 Blazor Canvas 扩展绘制动态条形图
  2. 使用 Blazor Canvas 扩展绘制动态气泡图 (当前)
  3. 使用 Blazor Canvas 扩展绘制动态折线图
  4. 使用 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.csConfigureServices方法中。

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值决定,并使用xvaluey值在图表中绘制气泡。

@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
© . All rights reserved.