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

使用 ASP.NET Core MVC 创建跨平台图表

starIconstarIconstarIconstarIconstarIcon

5.00/5 (6投票s)

2018 年 5 月 11 日

CPOL

6分钟阅读

viewsIcon

37508

downloadIcon

1343

本文提供了一个分步教程,介绍如何使用 ASP.NET Core MVC 结合客户端或服务器端的数据来创建 Web 应用程序中的图表。

引言

.NET Core 的主要优势之一在于它可以在多个平台和架构上运行。因此,您可以在一个平台上构建应用程序,然后在 Windows、Linux、MacOS 以及 x86 和 ARM 等不同架构上运行它。在本文中,我将演示如何使用 ASP.NET Core (2.0) MVC 创建一个跨平台图表应用程序。

过去,在创建 WinForm 或 WPF 图表应用程序时,代码或库通常在服务器上运行。例如,Microsoft (MS) Chart Control 是为 Windows Forms 和 ASP.NET 应用程序开发的,并且在服务器端运行。在这里,我将向您展示如何使用客户端图表库 – Google Charts 来创建 ASP.NET Core 图表应用程序。

Google Charts API 提供了大量现成的图表类型。它提供了合理的默认外观,通常可以满足您的需求,但同时也提供了灵活的选项,可以在需要时进行自定义。与大多数其他免费使用的图表库相比,Google Charts 拥有 Google 提供的优秀文档。它使用可预测的 API,这意味着一旦您学会了如何使用它创建一种图表类型,就可以轻松地开始创建其他类型的图表。

使用 Google Charts 的一个缺点是,尽管它是免费的,但它不是开源的。Google 的许可不允许您将他们的库托管在自己的服务器上。这意味着您无法离线使用 Google Charts。如果您在大企业工作,并且有一些敏感数据,Google Charts 可能不是最佳选择。

使用 DataTable 创建图表

Google Charts API 使用 `DataTable` 将数据传入图表。所有图表都将数据存储在一个表中。数据存储在单元格中,通过 (, ) 引用,其中 是基于零的行索引, 是基于零的列索引或您可以指定的唯一 ID。

在这里,我将使用一个简单的示例向您展示如何直接使用 `DataTable` 创建图表。打开 Visual Studio 2017,从一个新的 ASP.NET Core (2.0) MVC 项目开始,并将其命名为 `NetCoreChart`。在 _Controllers_ 文件夹中添加一个名为 `ChartController` 的新控制器,并将以下代码添加到控制器中

public IActionResult UseDataTable()
{
   return View();
}

在 _Views_ 文件夹中添加一个名为 `Chart` 的新文件夹。在 _Chart_ 文件夹中添加一个名为 _UseDataTable.cshtml_ 的新视图,并用以下代码替换其内容

<div class="container">
    <div class="row">
        <div class="col-md-6">
            <h4 style="margin-left:200px">Simple Pie Chart</h4>
            <div id="chart1"></div>
        </div>

        .......

</div>

@section scripts{
    <script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
    <script>
        google.charts.load('current', { 'packages': ['corechart'] });
        google.charts.setOnLoadCallback(drawChart);

        function drawChart() {
            var data = new google.visualization.DataTable();
            data.addColumn('string', 'Tax Type');
            data.addColumn('number', 'Tax Percentage');
            data.addRows([
                ['Soc. Sec. Tax', { v: 30, f: '30%' }],
                ['Income Tax', { v: 35, f: '35%' }],
                ['Borrowing', { v: 15, f: '15%' }],
                ['Corp. Tax', { v: 12, f: '12%' }],
                ['Misc', { v: 8, f: '8%' }]
            ]);

            // Simple Pie Chart:
            var option = {
                title: 'Tax Structure in US',
                width: 500,
                height: 400
            };

            var chart = new google.visualization.PieChart(document.getElementById('chart1'));
            chart.draw(data, option);

            //3D Pie Chart:
            option.is3D = true;
            chart = new google.visualization.PieChart(document.getElementById('chart2'));
            chart.draw(data, option);

            // Exploded Pie Chart:
            option.is3D = false;
            option.slices = {
                1: { offset: 0.3 },
                3: { offset: 0.5 }
            };
            chart = new google.visualization.PieChart(document.getElementById('chart3'));
            chart.draw(data, option);

            // Exploded 3D Pie Chart:
            option.is3D = true;
            chart = new google.visualization.PieChart(document.getElementById('chart4'));
            chart.draw(data, option);
        }
    </script>
}

此代码首先使用 `google.chart.load` 方法加载 `corechart` API 的当前版本,并实现一个名为 `drawChart` 的函数。在这里,我们使用相同的数据创建四种不同的饼图:一个普通饼图、一个带有 3D 效果的饼图、一个爆炸式饼图和一个带有 3D 效果的爆炸式饼图。这些图表之间的区别是通过配置每种图表的 _option_ 来指定的。

运行项目将产生图 1 所示的输出。

图 1:使用 DataTable 创建的饼图

使用数据数组

Google Charts 提供了一个名为 `arrayToDataTable` 的辅助函数,可用于使用数据数组创建和填充 `DataTable`。我们将使用一个示例来演示如何使用数据数组创建图表。

将以下代码添加到 _ChartControl.cs_

 public IActionResult UseDataArray()
 {
    return View();
 }

在 _Views/Chart_ 文件夹中添加一个名为 _UseDataArray.cshtml_ 的新视图,并用以下代码替换其内容

<div class="container">
    <div class="row">
        <div class="col-md-6">
            <h4 style="margin-left:200px">Simple Pie Chart</h4>
            <div id="chart1"></div>
        </div>
        <div class="col-md-6">
            <h4 style="margin-left:200px">Line Chart</h4>
            <div id="chart2"></div>
        </div>
    </div>
</div>

@section scripts{
    <script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>

    <script>
        google.charts.load('current', { 'packages': ['corechart'] });
        google.charts.setOnLoadCallback(drawChart);

        function drawChart() {
            // Pie Chart with Data Array:
            var arr = [
                ['Tax Type', 'Tax Percentage'],
                ['Income Tax', { v: 35, f: '35%' }],
                ['Borrowing', { v: 15, f: '15%' }],
                ['Corp. Tax', { v: 12, f: '12%' }],
                ['Misc', { v: 8, f: '8%' }]
            ];
            var data = google.visualization.arrayToDataTable(arr, false);
            var option = {
                title: 'Tax Structure in US',
                width: 600,
                height: 500
            };
            var chart = new google.visualization.PieChart(document.getElementById('chart1'));
            chart.draw(data, option);

            // Line Chart:
            arr = [];
            arr.push(['x', 'sin(x)', 'cos(x)', 'sin(x)^2']);
            for (var i = 0; i < 70; i++) {
                var x = 0.1 * i;
                arr.push([x, Math.sin(x), Math.cos(x), Math.sin(x) * Math.sin(x)]);
            }
            data = google.visualization.arrayToDataTable(arr, false);
            chart = new google.visualization.LineChart(document.getElementById('chart2'));
            chart.draw(data, option);
        }
    </script>
}

此代码创建两个图表:一个饼图和一个折线图。在饼图中,我们手动定义了一个数组;而在折线图中,我们使用三个数学函数:`sin(x)`、`cos(x)` 和 `sin(x)^2` 来创建数据数组。然后调用 `arrayToDataTable` 函数来定义和填充 `DataTable`。

运行此示例将生成图 2 所示的结果。

图 2:使用数据数组创建的图表

使用 JSON 数据

您还可以将 JSON 数据传递到 `DataTable` 构造函数中。这在服务器端生成数据时会很有用。这种方法的主要优点是,与使用数据数组等其他方法相比,它处理大型表格的速度要快得多。而缺点是其复杂的语法格式,很难正确书写,并且容易出错,导致代码可读性不高。

将以下代码片段添加到 _ChartController.cs_

 public IActionResult UseJsonData()
 {
     return View();
 }

在 _Views/Chart_ 文件夹中添加一个名为 _UseJsonData.cshtml_ 的新视图,并用以下代码替换其内容

<div class="container">
    ......
</div>

@section scripts{
    <script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>

    <script>
        google.charts.load('current', { 'packages': ['corechart'] });
        google.charts.setOnLoadCallback(drawChart);

        function drawChart() {
            var json = {
                cols: [
                    { id: 'taxType', label: 'Tax Type', type: 'string' },
                    { id: 'percent', label: 'Tax Percentage', type: 'number' }
                ],
                rows: [
                    { c: [{ v: 'Soc. Sec. Tax' }, { v: 30, f: '30%' }] },
                    { c: [{ v: 'Income Tax' }, { v: 35 }] },
                    { c: [{ v: 'Borrowing' }, { v: 15 }] },
                    { c: [{ v: 'Corp. Tax' }, { v: 12 }] },
                    { c: [{ v: 'Misc' }, { v: 8 }] },
                ],
            };

            var data = new google.visualization.DataTable(json);           

            // Simple Pie Chart:
            var option = {
                title: 'Tax Structure in US',
                width: 500,
                height: 400
            };
            var chart = new google.visualization.PieChart(document.getElementById('chart1'));
            chart.draw(data, option);

            //3D Pie Chart:

           ......

        }
    </script>
}

此代码与我们在 `UseDataTable` 示例中使用的基本相同,只是我们使用 JSON `string` 对象来填充 `DataTable`。您可以看到,JSON 数据对象包含两个必需的顶级属性:`cols` 和 `rows`,以及其他可选的 `p` 属性(在此示例中未使用),它是一个任意值的映射。

然后,代码将 JSON 对象直接放入 `DataTable` 的构造函数中以填充表。运行此示例将产生与图 1 相同的效果。

使用来自服务器的数据

我们还可以使用服务器端的数据来创建图表。让我们考虑一个简单的例子,我们想创建一个带有来自服务器数据的折线图。

向 _Model_ 文件夹添加一个 _ModelHelper.cs_ 类。此类代码如下

using System.Collections.Generic;

namespace NetCoreChart.Models
{
    public static class ModelHelper
    {
       public static List<object> MultiLineData()
        {
            List<object> objs = new List<object>();
            objs.Add(new[] { "x", "sin(x)", "cos(x)", "sin(x)^2" });
            for(int i = 0; i < 70; i++)
            {
                double x = 0.1 * i;
                objs.Add(new[] { x, Math.Sin(x), Math.Cos(x), Math.Sin(x) * Math.Sin(x) });
            }
            return objs;
        }
    }
}

`MultiLineData` 方法生成一个数据列表,该列表将用于在客户端创建折线图。将以下代码片段添加到 _ChartController.cs_

        public IActionResult UseDataFromServer()
        {
            return View();
        }

        public JsonResult JsonData()
        {
            var data = ModelHelper.MultiLineData();
            return Json(data);
        }

`JsonData` 方法将数据列表转换为 JSON 对象。在 _Views/Chart_ 文件夹中添加一个名为 _UseDataFromServer.cshtml_ 的新视图,并用以下代码替换其内容

<div class="container">
    <div id="chart1"></div>
</div>

@section scripts{
    <script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>

    <script>
        google.charts.load('current', { 'packages': ['corechart'] });
        google.charts.setOnLoadCallback(drawChart);

        function drawChart() {           
            $.get('JsonData', function (jsonData) {
                data = google.visualization.arrayToDataTable(jsonData, false);
                var option = {
                    title: "Line Chart",
                    width: 800,
                    height: 600
                };
                chart = new google.visualization.LineChart(document.getElementById('chart1'));
                chart.draw(data, option);
            })            
        }
    </script>
}

此代码首先使用 AJAX `.get` 函数从服务器检索 JSON 数据,然后使用 `arrayToDataTable` 辅助函数将 JSON 数据转换为 `DataTable`。运行此示例将产生图 3 所示的结果。

图 3:使用来自服务器的数据创建的图表

实时图表

实时图表有广泛的应用,例如金融领域的股票图表和天气预报中的温度变化。在这里,我将向您展示如何使用 ASP.NET Core MVC 和 Google Charts API 创建实时图表。

在这里,我们假设数据源来自服务器端,模拟实时股票报价。在 _ChartController.cs_ 的末尾添加一个名为 `RealTimeData` 的新类

public class RealTimeData
{
    public DateTime TimeStamp { get; set; }
    public double DataValue { get; set; }
}

将以下两个方法添加到 _ChartController.cs_

        Random rdn = new Random();

        public IActionResult RealTimeChart()
        {
            return View();
        }

        public JsonResult GetRealTimeData()
        {
            RealTimeData data = new RealTimeData
            {
                TimeStamp = DateTime.Now,
                DataValue = rdn.Next(0, 11)
            };
            return Json(data);
        }

`GetRealTimeData` 方法将前面的 `RealTimeData` 对象转换为 JSON 对象。在这里,为了简单起见,我们创建带有时间戳和随机数的数据。在实际应用程序中,您应该将 `RealTimeData` 对象替换为实际的数据源。

在 _Views/Chart_ 文件夹中添加一个名为 _RealTimeChart.cshtml_ 的新视图,并用以下代码替换其内容

<div class="container">
    <div id="chart1"></div>
</div>

@section scripts{
    <script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
    <script src="~/lib/node_modules/moment/moment.min.js"></script>

    <script>
        google.charts.load('current', { 'packages': ['corechart'] });
        google.charts.setOnLoadCallback(callback);
        
        function callback() {
            var option = {
                title: "Real-Time Chart",
                width: 900,
                height: 650,
                legend: { position: 'none' },
                vAxis: { viewWindow: { min: -1, max: 11 }, baselineColor: 'transparent'  },
                chartArea: { height: '80%', width: '85%', left: 100, 
                             backgroundColor: { stroke: "gray", strokeWidth: 1 } },
                pointSize: 10
            };
            var chart = new google.visualization.LineChart(document.getElementById('chart1'));
            var data = new google.visualization.DataTable();
            data.addColumn('datetime', 'TimeStamp');
            data.addColumn('number', 'Value');

            drawChart();
            setInterval(drawChart, 1000);

            function drawChart() {
                $.get('GetRealTimeData', function (d) {
                    var timeStamp = new Date(d.timeStamp);
                    var time = { v: timeStamp, f: moment(timeStamp).format('HH:mm:ss') };
                    var val = d.dataValue;                    
                    data.addRow([time, val]);
                    if (data.getNumberOfRows() > 20) {
                        data.removeRow(0);
                    }
                    chart.draw(data, option);
                });
            }
        }
    </script>
}

此代码与 `UseDataFromServer` 示例中的代码基本相同,只是在这里我们使用 `setInterval(drawChart, 1000)` 方法每秒(1000 毫秒)更新一次图表。此外,我们在屏幕上只保留 20 个数据点。如果数据点超过 20 个,我们将使用 `removeRow` 方法删除最旧的数据点。

运行此示例将为您提供一个流畅的实时图表,如图 4 所示。

图 4:使用来自服务器的数据创建的实时图表

在此,我详细介绍了如何使用 ASP.NET Core MVC 和客户端图表库 – Google Charts API 来创建跨平台图表的详细过程。

© . All rights reserved.