ASP.NET Core MVC TagHelper实践HighchartsNET快速图表控件-开源

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:" + 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-width:400px;");
            if (Width > 0)
                style.Append($"width:{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());
        }
    }
View Code

 

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

 

如果你觉得本文对你有帮助,请点击“推荐”,谢谢。

posted @ 2016-10-19 11:21  LineZero  阅读(5610)  评论(10编辑  收藏  举报