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





5.00/5 (6投票s)
本文提供了一个分步教程,介绍如何使用 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 所示的输出。
使用数据数组
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 所示的结果。
使用 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 所示的结果。
实时图表
实时图表有广泛的应用,例如金融领域的股票图表和天气预报中的温度变化。在这里,我将向您展示如何使用 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 所示。
在此,我详细介绍了如何使用 ASP.NET Core MVC 和客户端图表库 – Google Charts API 来创建跨平台图表的详细过程。