Esempio n. 1
0
        /// <summary>
        /// 通过实体list生成报表
        /// </summary>
        /// <typeparam name="T">泛型</typeparam>
        /// <param name="entityList">实体list</param>
        /// <param name="highchartsType">图表类型</param>
        /// <param name="xCategoryColumnName">X轴标记列名</param>
        /// <param name="stackColumnName">分组列名,如果没有分组,则使用null</param>
        /// <param name="dataColumnName">数据列名</param>
        /// <param name="sortBy">按哪列排序</param>
        /// <param name="title">标题</param>
        /// <param name="subTitle">子标题</param>
        /// <param name="unit">单位</param>
        /// <param name="showStackTotal">是否显示堆数据的总和</param>
        /// <param name="stackFor">哪种类型的分组累计?对应图表类型就会出现分组累计效果,不对应则没有分组累计效果,比如像要3月上海北京的总数,则X轴是月份,分组列是大区,我们使用bar图表,分组累计类型也要用bar</param>
        /// <param name="needAbs">是否使用绝对值样式,可以让条形图左右(柱状图上下)分开显示不同组别的数据</param>
        /// <param name="showLabel">是否显示数据标签</param>
        /// <param name="drawTable">是否在图表下面画table</param>
        /// <returns>highcharts的html代码</returns>
        public string FillHighchartsByEntityList <T>(IList <T> entityList, HighchartsType highchartsType, string xCategoryColumnName
                                                     , string stackColumnName, string dataColumnName, string sortBy, string title, string subTitle, string unit, string showStackTotal, string stackFor, bool needAbs, bool showLabel, bool drawTable)
        {
            var dataTable = new System.Data.DataTable();

            if (entityList.Count == 0)
            {
                return("");
            }
            #region 获取类型的属性
            PropertyInfo[] propertyInfos = typeof(T).GetProperties();
            foreach (PropertyInfo propertyInfo in propertyInfos)
            {
                if (propertyInfo.PropertyType.FullName == "System.Data.EntityState" || propertyInfo.PropertyType.FullName == "System.Data.EntityKey")
                {
                    continue;
                }            //去掉系统自带的属性
                dataTable.Columns.Add(propertyInfo.Name);
            }
            #endregion
            #region 把对象转换成datatable
            foreach (T entity in entityList)
            {
                DataRow data = dataTable.NewRow();
                foreach (PropertyInfo propertyInfo in propertyInfos)
                {
                    if (propertyInfo.PropertyType.FullName == "System.Data.EntityState" || propertyInfo.PropertyType.FullName == "System.Data.EntityKey")
                    {
                        continue;
                    }            //去掉系统自带的属性
                    data[propertyInfo.Name] = propertyInfo.GetValue(entity, null);
                }
                dataTable.Rows.Add(data);
            }
            #endregion
            return(FillHighchartsByDataTable(dataTable, "container", highchartsType, xCategoryColumnName, stackColumnName, dataColumnName, sortBy, title, subTitle, unit, showStackTotal, stackFor, needAbs, showLabel, drawTable, "400px", "400px"));
        }
Esempio n. 2
0
        /// <summary>
        /// 根据datatable画highcharts图表
        /// </summary>
        /// <param name="dataTable">数据源</param>
        /// <param name="containerId">图表DIV的ID</param>
        /// <param name="highchartsType">图表类型</param>
        /// <param name="xCategoryColumnName">X轴标记列名</param>
        /// <param name="stackColumnName">分组列名,如果没有分组,则使用null</param>
        /// <param name="dataColumnName">数据列名</param>
        /// <param name="sortBy">按哪列排序</param>
        /// <param name="title">标题</param>
        /// <param name="subTitle">子标题</param>
        /// <param name="unit">单位</param>
        /// <param name="showStackTotal">是否显示堆数据的总和</param>
        /// <param name="stackFor">哪种类型的分组累计?对应图表类型就会出现分组累计效果,不对应则没有分组累计效果,比如像要3月上海北京的总数,则X轴是月份,分组列是大区,我们使用bar图表,分组累计类型也要用bar</param>
        /// <param name="needAbs">是否使用绝对值样式,可以让条形图左右(柱状图上下)分开显示不同组别的数据</param>
        /// <param name="showLabel">是否显示数据标签</param>
        /// <param name="drawTable">是否在图表下面画table</param>
        /// <param name="width">宽 例400px</param>
        /// <param name="height">高 例400px</param>
        /// <returns>highcharts的html代码</returns>
        public string FillHighchartsByDataTable(System.Data.DataTable dataTable, string containerId, HighchartsType highchartsType, string xCategoryColumnName, string stackColumnName, string dataColumnName, string sortBy
                                                , string title, string subTitle, string unit, string showStackTotal, string stackFor, bool needAbs, bool showLabel, bool drawTable, string width, string height)
        {
            #region 准备数据
            var hsCategory = new HashSet <string>();
            var hsStack    = new HashSet <string>();
            dataTable.DefaultView.Sort = sortBy;// xCategoryColumnName;//排序,让图表和table表按序排列
            for (int i = 0; i < dataTable.DefaultView.Count; i++)
            {
                string xName = dataTable.DefaultView[i][xCategoryColumnName].ToString();
                xName = xName == "" ? " " : xName;//如果分组数据为空字符串,则用空格代替,因为后面创建datatable的列的时候,空字符串会被自动改成Colum1,为了防止这种问题,这里暂时用空格代替
                if (!hsCategory.Contains(xName))
                {
                    hsCategory.Add(xName);   //获取X轴数据列表
                }
                if (stackColumnName == null) //如果只有一行数据的,我们就传null进来,这里就会知道只保存一行数据
                {
                    if (!hsStack.Contains(null))
                    {
                        hsStack.Add(null);
                    }
                }
                else
                {
                    if (!hsStack.Contains(dataTable.DefaultView[i][stackColumnName].ToString()))
                    {
                        hsStack.Add(dataTable.DefaultView[i][stackColumnName].ToString());//如果X轴数据要堆分组的话,这里获取堆分组的数据列表
                    }
                }
            }

            string xcategory = "";//传给highcharts的X轴数据
            foreach (string hscate in hsCategory)
            {
                xcategory += "'" + hscate + "',";
            }
            xcategory = xcategory.Substring(0, xcategory.Length - 1);
            string series = "";
            string tooltip;
            if (highchartsType == HighchartsType.pie)//暂时这样处理,因为pie与其他类型的相关性不大,所以分开做series数据与tootip鼠标掩盖提示
            {
                #region pie类型
                series += "[";
                const string dataTemplate = "['{0}',{1}],";
                series += "{type: 'pie',name: 'Browser share',data: [";
                foreach (DataRow dataRow in dataTable.Rows)
                {
                    series += string.Format(dataTemplate, dataRow[xCategoryColumnName], dataRow[dataColumnName]);
                }
                series  = series.Substring(0, series.Length - 1) + "]}]";
                tooltip = "'<b>'+ this.point.name +'</b>: '+this.y+' , '+ Math.round(this.percentage*100)/100 +' %'";//这里鼠标提示类别名称,值,百分比
                #endregion
            }
            else
            {
                #region 非pie类型
                series += "[";
                foreach (string stack in hsStack)
                {
                    series += "{type:'" + highchartsType + "',name:'" + (stack ?? unit) + "',data:[";//如果没有分组数据,分组列名就用单位名称吧
                    foreach (string cate in hsCategory)
                    {
                        DataRow[] rows;
                        if (stack == null)
                        {
                            rows = dataTable.Select(xCategoryColumnName + "='" + cate + "'");
                        }                                                                    //没有堆分组的时候,只有一列数据
                        else
                        {
                            rows = dataTable.Select(stackColumnName + "='" + stack + "' and " + xCategoryColumnName + "='" + cate + "'");
                        }

                        if (rows.Length == 0)
                        {
                            series += "0,";
                        }
                        else
                        {
                            series += rows[0][dataColumnName] + ",";
                        }
                    }
                    series  = series.Substring(0, series.Length - 1);
                    series += "],stack:0},";
                }
                series = series.Substring(0, series.Length - 1) + "]";
                if (needAbs)
                {
                    tooltip = "'<b>'+ this.series.name +'</b><br/>'+this.x +': '+ (Math.abs(this.y)) +'" + unit + "'";
                }                                                                                                     //使用绝对值
                else
                {
                    tooltip = "'<b>'+ this.series.name +'</b><br/>'+this.x +': '+ this.y +'" + unit + "'";
                }
                #endregion
            }
            string abs       = "";
            string mirror    = "";//目前做法是,如果选择使用了绝对值,则默认制造镜像效果,比如数轴左边是男,右边是女
            string dataLabel = showLabel ? "true" : "false";
            if (needAbs)
            {
                abs    = @"labels: {
				    formatter: function(){
					    return (Math.abs(this.value));
				    }
			    },"            ;
                mirror =
                    @", { // mirror axis on right side
			opposite: true,
			reversed: false,
			categories: categories,
			linkedTo: 0
		}"        ;
            }
            #endregion
            string        highcharts = FormatSimpleHighcharts(containerId, title, subTitle, xcategory, unit, showStackTotal, tooltip, stackFor, series, abs, mirror, dataLabel, width, height);
            StringBuilder sbTable    = new StringBuilder();
            #region 画table
            if (drawTable)
            {
                #region 画表头,并重新做一个用来显示table用的临时数据表,给临时数据表添加列
                sbTable.AppendLine("<table id='tableContainer' class='list-table'>");//id固定是这个,为了将来导出excel做准备
                sbTable.AppendLine("<thead><tr><th>表头</th>");
                DataTable showTable = new DataTable();
                showTable.Columns.Add("stack");//默认添加一列分组数据
                foreach (string cate in hsCategory)
                {
                    showTable.Columns.Add(cate);//给新表添加列
                    sbTable.Append("<th>");
                    sbTable.Append(cate);
                    sbTable.Append("</th>");
                }
                sbTable.AppendLine("</tr></thead>");
                #endregion
                #region 给临时表添加数据
                foreach (string stack in hsStack)
                {
                    DataRow showRow = showTable.NewRow();
                    showRow["stack"] = stack;
                    foreach (string cate in hsCategory)
                    {
                        DataRow[] drs =
                            dataTable.Select(xCategoryColumnName + "='" + cate +
                                             (stack == null ? "" : ("' and " + stackColumnName + "='" + stack)) + "'");
                        string tableData = ""; //如果没数据,则添空字符串
                        if (drs.Length > 0)
                        {
                            tableData = drs[0][dataColumnName].ToString();
                            if (needAbs) //如果会用绝对值了,则表格也要使用绝对值
                            {
                                tableData = Math.Abs(Convert.ToDouble(tableData)).ToString();
                            }
                        }
                        showRow[cate] = tableData;
                    }
                    showTable.Rows.Add(showRow);
                }
                #endregion
                #region 把新表数据填充到字符串中
                int columnNumber = showTable.Columns.Count;
                foreach (DataRow dataRow in showTable.Rows)
                {
                    for (int i = 0; i < columnNumber; i++)
                    {
                        sbTable.Append("<td>");
                        sbTable.Append(dataRow[i].ToString());
                        sbTable.Append("</td>");
                    }
                    sbTable.AppendLine("</tr>");
                }
                sbTable.Append("</table>");
                #endregion
            }
            #endregion
            #region 原始表
            ////表格暂时没想到好办法
            //sbTable.AppendLine("<table border=1>");
            //int columnNumber = dataTable.Columns.Count;
            //foreach (DataRow dataRow in dataTable.Rows)
            //{
            //    sbTable.Append("<tr>");
            //    for (int i = 0; i < columnNumber; i++)
            //    {
            //        sbTable.Append("<td>");
            //        sbTable.Append(dataRow[i].ToString());
            //        sbTable.Append("</td>");
            //    }
            //    sbTable.AppendLine("</tr>");
            //}
            //sbTable.Append("</table>");
            #endregion
            return(highcharts + sbTable);
        }