Thứ Hai, 6 tháng 7, 2015

Generate fusion chart from controller MVC

We all know FusionCharts is a javascript charting library which is used by many developer in the world. FusionCharts is very good, but it's licensing is too expensive. In this article, we see the way to generate fusion charts from controller mvc using free version of FusionCharts.
The first, let go to FusionCharts website and download free trial (it's free and no limit time to use). Here is example of one fusion chart (json)
{
    "chart": {
        "palette": "3",
        "caption": "Production Report",
        "yaxisname": "Units",
        "showvalues": "0",
        "numvdivlines": "10",
        "divlinealpha": "30",
        "drawanchors": "0",
        "labelpadding": "10",
        "yaxisvaluespadding": "10",
        "useroundedges": "1",
        "legendborderalpha": "0",
        "showborder": "0"
    },
    "categories": [
        {
            "category": [
                {
                    "label": "2009"
                },
                {
                    "label": "2010"
                },
                {
                    "label": "2011"
                },
                {
                    "label": "2012"
                },
                {
                    "label": "2013"
                },
                {
                    "label": "2014 (Projected)"
                }
            ]
        }
    ],
    "dataset": [
        {
            "seriesname": "Model A12",
            "color": "A66EDD",
            "data": [
                {
                    "value": "35"
                },
                {
                    "value": "42"
                },
                {
                    "value": "31"
                },
                {
                    "value": "28"
                },
                {
                    "value": "34"
                },
                {
                    "value": "30",
                    "dashed": "1"
                }
            ]
        },
        {
            "seriesname": "Model A15",
            "color": "F6BD0F",
            "data": [
                {
                    "value": "22"
                },
                {
                    "value": "25"
                },
                {
                    "value": "18"
                },
                {
                    "value": "22"
                },
                {
                    "value": "17"
                },
                {
                    "value": "16",
                    "dashed": "1"
                }
            ]
        }
    ]
}

To generate fusion charts from controller mvc, we will transform our chart data to form above.

1. Create a class named FusionChartData, it express for dataset fusion chart.

public class FusionChartData { /// <summary> /// data array title /// </summary> public string Seriesname { get; set; } /// <summary> /// Color show on chart (column format) /// </summary> public string Color { get; set; } /// <summary> /// Tooltip text when hover on chart (this data) /// </summary> public string[] ToolTips { get; set; } /// <summary> /// Mảng label tương ứng cho từng value mảng Data /// </summary> public string[] Labels { get; set; } /// <summary> /// Dữ liệu mảng data /// </summary> public string[] Datas { get; set; } /// <summary> /// Color serial pie chart /// </summary> public string[] Colors { get; set; } /// <summary> /// Contructor chart which have column form /// </summary> /// <param name="Seriesname"></param> /// <param name="Color"></param> /// <param name="Datas"></param> public FusionChartData(string Seriesname, string Color, string[] Datas) { this.Seriesname = Seriesname; this.Color = Color; this.Datas = Datas; } /// <summary> ///Contructor chart which have column form + column tooltip /// </summary> /// <param name="Seriesname">The seriesname.</param> /// <param name="Color">The color.</param> /// <param name="ToolTips">The tool tips.</param> /// <param name="Datas">The datas.</param> /// <Modified> /// Name Date Comments /// phongnc 1/30/2015 created /// </Modified> public FusionChartData(string Seriesname, string Color, string[] ToolTips, string[] Datas) { this.Seriesname = Seriesname; this.Color = Color; this.ToolTips = ToolTips; this.Datas = Datas; } /// <summary> /// Contructor Pie chart /// </summary> /// <param name="Labels"></param> /// <param name="Datas"></param> public FusionChartData(string[] Labels, string[] Datas) { this.Labels = Labels; this.Datas = Datas; } /// <summary> /// Contructor Pie chart /// </summary> /// <param name="Labels"></param> /// <param name="Datas"></param> public FusionChartData(string[] Labels, string[] Datas, string[] Colors) : this(Labels, Datas) { this.Colors = Colors; } }
2. Create a class named FusionChartHelper to generate chart script from our data: 
We have chart base properties ex: width, height, background color...And we can add more properties with "string[] Properties". Base on FussionChart format above we will generate script "chart",  "categories", "dataset" through methods RenderFusionChart, RenderCategories, RenderDataset and from that we generate final script RenderChart.

public class FusionChartHelper
    {
        private string _bgColor = "ffffff";
        private string _width = "500";
        private string _height = "300";
        private string _idDivContainer = "chartContainer";
        /// <summary>
        /// Chart type
//// http://docs.fusioncharts.com/flex/charts/Contents/introduction_chartTypes.html
        /// </summary>
        public string ChartType { get; set; }
        /// <summary>
        /// ID div container
        /// </summary>
        public string IDDivContainer { get { return _idDivContainer; } set { _idDivContainer = value; } }
        /// <summary>
        /// Chiều rộng biểu đồ
        /// </summary>
        public string Width { get { return _width; } set { _width = value; } }
        /// <summary>
        /// Chiều cao biểu đồ
        /// </summary>
        public string Height { get { return _height; } set { _height = value; } }
        /// <summary>
        /// Background color
        /// default: ffffff
        /// </summary>
        public string BgColor { get { return _bgColor; } set { _bgColor = value; } }
        /// <summary>
        /// chart title
        /// </summary>
        public string Caption { get; set; }
        /// <summary>
        /// horizontal axis title
        /// </summary>
        public string XAxisName { get; set; }
        /// <summary>
        /// vertical axis title
        /// </summary>
        public string YAxisName { get; set; }
        /// <summary>
        /// proprerty array
        /// Format : 'property name':'value'
        /// Ex: 'useroundedges': '1'
        /// </summary>
        public string[] Properties { get; set; }
        /// <summary>
        /// label category array
        /// </summary>
        public string[] Category { get; set; }
        /// <summary>
        /// chart style
        /// </summary>
        public string Style { get; set; }

        //Nếu dùng 1 mầu
        public string Palettecolors { get; set; }
        /// <summary>
        /// Chart data
        /// </summary>
        public List<FusionChartData> Data { get; set; }

        public bool IsGenExport { get; set; }

        /// <summary>
        /// Render 'chart'
        /// </summary>
        /// <returns></returns>
        private string RenderFusionChart()
        {
            StringBuilder chart = new StringBuilder("'chart' : {");
            chart.AppendFormat("'bgcolor': '{0}',", this.BgColor);
            chart.AppendFormat("'caption': '{0}',", this.Caption);
            //chèn mảng property
            if (this.Properties.Length > 0)
            {
                foreach (var p in Properties)
                {
                    chart.Append(p + ",");
                }
            }
            chart.AppendFormat("'xaxisname': '{0}',", this.XAxisName);
            chart.AppendFormat("'yaxisname': '{0}',", this.YAxisName);
            if (!string.IsNullOrEmpty(Palettecolors)) chart.AppendFormat(string.Format("'palettecolors':'{0}',", Palettecolors));
            //xuất image, pdf
            chart.Append("'exportenabled': '1',");
            chart.Append("'exportatclient': '0',");
            chart.Append("'exporthandler': 'http://107.21.74.91/',");
            chart.Append("'html5exporthandler': 'http://107.21.74.91/',");
            chart.Append("'exportFormats': 'PNG=" + Resources.Resources.Common_ExportPNG + "|JPG=" + Resources.Resources.Common_ExportJPEG + "|PDF=" + Resources.Resources.Common_ExportPdf + "',");
            chart.AppendFormat("'exportFileName': '{0}'", this.Caption);
            //chart.Append("'useroundedges': '1',");
            //if (this.Formatnumberscale)
            //{
            //    chart.Append("'formatnumberscale': '1'");
            //}
            //else
            //{
            //    chart.Append("'formatnumberscale': '0'");
            //}
            chart.Append("}");
            return chart.ToString();
        }

        /// <summary>
        /// Render categories
        /// </summary>
        /// <returns></returns>
        private string RenderCategories()
        {
            StringBuilder cate = new StringBuilder();
            try
            {
                if (this.Category.Length > 0) //nếu mà có category
                {
                    if (this.Category.Length == 1 && this.Category[0].Equals(""))
                    {
                        return string.Empty;
                    }
                    foreach (var c in this.Category)
                    {
                        cate.AppendFormat("{{ 'label': '{0}' }},", c);
                    }
                    cate.Remove(cate.Length - 1, 1); //xóa ký tự ',' ở cuối chuỗi
                    cate.Append("] } ]");
                }
            }
            catch (Exception ex)
            {
                return string.Empty;
            }
            return "'categories': [ { 'category': [" + cate.ToString();
        }

        /// <summary>
        /// Renders dataset
        /// </summary>
        /// <returns></returns>
        /// <Modified>
        /// Name     Date         Comments
        /// phongnc  1/26/2015   created
        /// </Modified>
        protected virtual string RenderDataset()
        {
            StringBuilder data = new StringBuilder("'dataset': [" + Environment.NewLine);
            if (this.Data != null && this.Data.Count > 0) //nếu có dữ liệu
            {
                foreach (var fd in this.Data)
                {
                    data.Append("{");
                    data.AppendFormat("'seriesname' : '{0}','color': '{1}', 'data' : [" + Environment.NewLine, fd.Seriesname, fd.Color);
                    //kiểm tra xem data của thành phần có dữ liệu ko
                    if (fd.Datas.Length > 0)
                    {
                        for (int i = 0; i < fd.Datas.Length; i++)
                        {
                            if (fd.ToolTips != null && fd.ToolTips.Length > 0)
                            {
                                if (fd.ToolTips.Length > i)
                                {
                                    if (string.IsNullOrEmpty(fd.ToolTips[i]))
                                    {
                                        data.AppendFormat("{{'value' : '{0}'}},", fd.Datas[i]);
                                    }
                                    else //if (!fd.ToolTips[i].Contains("{0}"))
                                    {
                                        data.AppendFormat("{{'tooltext': '" + fd.ToolTips[i] + "', 'value' : '{0}'}},", fd.Datas[i]);
                                    }
                                    //else
                                    //{
                                    //    data.AppendFormat("{{'tooltext': '" + fd.ToolTips[i] + "', 'value' : '{1}'}},", fd.Datas[i], fd.Datas[i]);
                                    //}
                                }
                                else
                                {
                                    data.AppendFormat("{{'value' : '{0}'}},", fd.Datas[i]);
                                }
                            }
                            else
                            {
                                data.AppendFormat("{{'value' : '{0}'}},", fd.Datas[i]);
                            }
                        }
                        data.Remove(data.Length - 1, 1); //xóa ký tự ',' ở cuối chuỗi
                    }
                    data.Append("] },");
                }
                data.Remove(data.Length - 1, 1); //xóa ký tự ',' ở cuối chuỗi
                data.Append("]");
            }
            else
            {
                return string.Empty;
            }
            return data.ToString();
        }

        /// <summary>
        /// Render chart script
        /// </summary>
        /// <returns></returns>
        public string RenderChart()
        {
            StringBuilder chart = new StringBuilder();
            chart.AppendLine(@"<script type=""text/javascript"">");
            chart.AppendLine(@"FusionCharts.ready(function () { var revenueChart" + IDDivContainer + " = new FusionCharts({");
            chart.AppendFormat("type: '{0}',", this.ChartType);
            chart.AppendFormat("renderAt: '{0}',", this.IDDivContainer);
            chart.AppendFormat("width: '{0}',", this.Width);
            chart.AppendFormat("height: '{0}',", this.Height);
            chart.Append("dataFormat: 'json', dataSource: {");
            chart.Append(this.RenderFusionChart());
            if (!string.IsNullOrEmpty(this.Style))
            {
                chart.Append(',' + this.Style);
            }
            string cate = this.RenderCategories();
            if (!string.IsNullOrEmpty(cate))
            {
                chart.Append(',' + cate);
            }
            string dataset = this.RenderDataset();
            if (!string.IsNullOrEmpty(dataset))
            {
                chart.Append(',' + dataset);
            }
            chart.AppendLine("}});");
            chart.AppendFormat("revenueChart" + IDDivContainer + ".render('{0}');", this.IDDivContainer);
            chart.AppendLine("}); </script>");
            return chart.ToString();
        }

        public FusionChartHelper() { }

        public FusionChartHelper(string ChartType, string Caption, string XAxisName, string YAxisName,
            string IDDivContainer, string Width, string Height, string[] Properties,
            string[] Category, List<FusionChartData> Data)
        {
            this.ChartType = ChartType;
            this.Caption = Caption;
            this.XAxisName = XAxisName;
            this.YAxisName = YAxisName;
            this.IDDivContainer = IDDivContainer;
            this.Width = Width;
            this.Height = Height;
            this.Properties = Properties;
            this.Category = Category;
            this.Data = Data;
        }
    }
3. Using:
- Controller: controller bellow show how to generate ScrollColumn2D
public ActionResult GenChart(){
FusionChartData fcd = new FusionChartData("", "00CC00", new string[] {"Data 01","Data 02","Data 03"}, new string[]{"100","200","300"});
FusionChartHelper fc = new FusionChartHelper("ScrollColumn2D" ,"Demo ScrollColumn2D"
, "horizontal axis name", "vertical axis name", "chartContainer", "95%", "400",
new string[] { "'useroundedges': '1', 'numberScaleValue' : '1000', 'numberScaleUnit':' '" }, new string[] {"01","02","03"}, new List<FusionChartData>() { fcd }); chart = fc.RenderChart();
return Json(chart, JsonRequestBehavior.AllowGet);
}
- Index:
<html>
<head><title>Demo generate fusion chart</title>
<script>
function Search(){
$.ajax({ type: "POST", dataType: "json", contentType: 'application/json; charset=utf-8', url: "/Chart/GenChart",, success: function (result) { $('#chartContainer').html(result); } });
}
</script>
</head>
<body>
<a id="btnSearch" href="javascript:void(0);" onclick="Search()"> @Resources.Common_ViewDiagram </a>
<div id="chartContainer" style="text-align:center;">
</div>
</body>
</html>

Click btnSearch -> generate chart. Here is a example:

Không có nhận xét nào:

Đăng nhận xét