ASP.NET Core MVC TagHelper最佳实践HighchartsNET快速图表控件支持ASP.NET Core。
曾经在WebForms上写过 HighchartsNET快速图表控件-开源 Highcharts的ASP.NET Web自定义控件。
今天我就来改造它,将其使用最新的TagHelper 来实践,学习TagHelper 的使用也提供一个方便的图表控件在ASP.NET Core MVC中使用。
下面正式开始,使用之前的代码直接进行迁移升级。
GitHub:https://github.com/linezero/HighchartsNET
代码迁移升级
首先我们新建一个 .NET Core Class Library -> HighchartsNETCore
然后我们添加引用
Install-Package Microsoft.AspNetCore.Razor.Runtime
新建一个HighChartsTagHelper.cs然后将之前的 HighCharts.cs 的代码复制到其中,进行相关更改。
这里首先需要引用 using Microsoft.AspNetCore.Razor.TagHelpers; 然后继承 TagHelper 重写 Process。
在之前的属性上加上 HtmlAttributeName 特性,调整方法。
最终主要代码如下:
public class HighChartsTagHelper : TagHelper { /// <summary> /// 图表标题 /// </summary> [HtmlAttributeName("title")] public string Title { get; set; } /// <summary> /// 图表类型 /// </summary> [HtmlAttributeName("type")] public ChartType Type { get; set; } /// <summary> /// 图表2级标题 /// </summary> [HtmlAttributeName("subtitle")] public string SubTitle { get; set; } /// <summary> /// 数据对象 /// </summary> [HtmlAttributeName("series")] public ChartsSeries Series { get; set; } /// <summary> /// 一些附加选项 /// </summary> [HtmlAttributeName("plotoptions")] public string PlotOptions { get; set; } /// <summary> /// X轴选项 /// </summary> [HtmlAttributeName("xAxis")] public List<object> XAxis { get; set; } /// <summary> /// Y轴选项 默认可以只填名称 /// </summary> [HtmlAttributeName("yAxis")] public string YAxis { get; set; } /// <summary> /// 提示格式 /// </summary> [HtmlAttributeName("Tooltip")] public string Tooltip { get; set; } /// <summary> /// 图表层id(容器) /// </summary> [HtmlAttributeName("id")] public string Id { get; set; } /// <summary> /// 图标下方标识是否显示 默认不显示 /// </summary> [HtmlAttributeName("legend")] public bool Legend { get; set; } /// <summary> /// 高级功能,多个数据集,多条图表,饼图不需要。 /// </summary> [HtmlAttributeName("serieslist")] public List<ChartsSeries> SeriesList { get; set; } [HtmlAttributeName("width")] public int Width { get; set; } [HtmlAttributeName("height")] public int Height { get; set; } private void HighChartsJs(StringBuilder jscode) { jscode.Append("$(function(){$('#" + Id + "').highcharts({ "); jscode.Append("credits: { enabled: false },"); jscode.Append("chart:{ type: '" + Type.ToString().ToLower() + "'"); if (Width>0) jscode.Append("," + Width); if (Height>0) jscode.Append(",height:" + Height); jscode.Append("},"); if (!string.IsNullOrEmpty(Title)) jscode.Append("title: { text: '" + Title + "'},"); if (!string.IsNullOrEmpty(SubTitle)) jscode.Append("subtitle: { text: '" + SubTitle + "'},"); //判断类型及数据显示 if (XAxis != null && Type != ChartType.Pie) { XAxisToString(jscode, XAxis); } else if (Series.SeriesData != null && Type != ChartType.Pie) { XAxisToString(jscode, Series.SeriesData.Keys.ToList()); } else if (SeriesList != null && SeriesList.Count > 0) { XAxisToString(jscode, SeriesList[0].SeriesData.Keys.ToList()); } if (!string.IsNullOrEmpty(YAxis)) { if (YAxis.IndexOf("title") < 0) { jscode.Append("yAxis: { title:{ text:'" + YAxis + "'}},"); if(string.IsNullOrEmpty(Tooltip)) jscode.Append("tooltip: { valueSuffix:'" + YAxis + "' },"); } else { jscode.Append("yAxis: {" + YAxis + "},"); } } jscode.Append("legend: { enabled: "+Legend.ToString().ToLower()+" },"); if (!string.IsNullOrEmpty(Tooltip)) jscode.Append("tooltip: {" + Tooltip + "},"); if (!string.IsNullOrEmpty(PlotOptions)) jscode.Append("plotOptions:{" + PlotOptions + "},"); //数据处理方法 SeriesToString(jscode); jscode.Append(" }); });"); } private void SeriesToString(StringBuilder sb) { sb.Append("series: ["); string seriesdata = string.Empty; if (Series.SeriesData != null) { seriesdata = SeriesDataToString(Series); } if (SeriesList != null && SeriesList.Count != 0) { foreach (ChartsSeries ser in SeriesList) { seriesdata += SeriesDataToString(ser) + ","; } seriesdata = seriesdata.TrimEnd(','); } sb.Append(seriesdata); sb.Append("]"); } /// <summary> /// 数据部分转成js代码 /// </summary> /// <param name="series"></param> /// <returns></returns> private string SeriesDataToString(ChartsSeries series) { string seriesdata = "{ name: '" + series.SeriesName + "',data:["; foreach (var item in series.SeriesData) { seriesdata += "['" + item.Key + "'," + item.Value + "],"; } seriesdata = seriesdata.TrimEnd(','); seriesdata += "] }"; return seriesdata; } /// <summary> /// x轴上数据转换 /// </summary> /// <param name="sb"></param> /// <param name="xAxis"></param> private void XAxisToString(StringBuilder sb, List<object> xAxis) { sb.Append("xAxis: { categories: ["); string xaxis = string.Empty; foreach (var item in xAxis) { xaxis += "'" + item + "',"; } xaxis = xaxis.TrimEnd(','); sb.Append(xaxis); sb.Append("]},"); } public override void Process(TagHelperContext context, TagHelperOutput output) { if (Series == null) return; output.Attributes.SetAttribute("title", "HighchartsNET自动生成 By:LineZero"); output.Attributes.SetAttribute("id", Id); StringBuilder style = new StringBuilder("margin:0px auto;min-400px;"); if (Width > 0) style.Append($"{Width}px;"); if (Height > 0) style.Append($"heigth:{Height}px;"); output.Attributes.SetAttribute("style",style.ToString()); output.TagName = "div"; StringBuilder innerhtml = new StringBuilder(); innerhtml.Append("<script>"); HighChartsJs(innerhtml); innerhtml.Append("</script>"); output.PostElement.AppendHtml(innerhtml.ToString()); } }
TagHelper 使用
代码编写好以后,新建一个 ASP.NET Core Web Application 名为 HighchartsNETCoreWeb -> 选择Web应用程序-》不进行身份验证。
添加 HighchartsNETCore 引用。
然后打开 Views/_ViewImports.cshtml 文件添加:
@using HighchartsNETCoreWeb @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers @addTagHelper *,HighchartsNETCore
然后将 Home/Index.cshtml 替换为如下代码:
<script src="http://cdn.hcharts.cn/jquery/jquery-1.8.3.min.js"></script> <script src="http://cdn.hcharts.cn/highcharts/highcharts.js"></script> <div> <high-charts id="demoline" title="ASP.NET Core 线图" subtitle="http://www.cnblogs.com/linezero" type="Line" series="ViewBag.Series"></high-charts> <high-charts id="democolumn" title="ASP.NET Core柱图" subtitle="http://www.cnblogs.com/linezero" type="Column" series="ViewBag.Series"></high-charts> <high-charts id="demopie" title="ASP.NET Core饼图" subtitle="http://www.cnblogs.com/linezero" type="Pie" series="ViewBag.Series"></high-charts> </div>
在Index Action添加数据源
public IActionResult Index() { ChartsSeries series = new ChartsSeries(); Dictionary<object, object> dic = new Dictionary<object, object>(); Random r = new Random(); for (int i = 0; i < 12; i++) { dic.Add(DateTime.Now.AddDays(i).ToString("yyyyMMdd"), r.Next(20)); } series.SeriesName = "温度"; series.SeriesData = dic; ViewBag.Series = series; return View(); }
运行程序 http://localhost:5000/
更多使用示例可以参考以前的Web 文件夹。
将HighchartsNETCore 打包以后可以直接适用于任意ASP.NET Core MVC应用程序。
GitHub:https://github.com/linezero/HighchartsNET
另附NuGet包:HighchartsNETCore.1.0.0.zip
如果你觉得本文对你有帮助,请点击“推荐”,谢谢。