/// <summary>
        /// 条件是否为true
        /// </summary>
        /// <param name="condition"></param>
        /// <param name="node"></param>
        /// <returns></returns>
        private static bool IsTrue_StatRetainedUsers(TableTemplate.NodeCondition nCondition, XmlNode node)
        {
            NodeCondition_StatRetainedUsers condition = (NodeCondition_StatRetainedUsers)nCondition;

            return(TableTemplate.IncludeInt(node.Attributes["period"], (int)condition.Period));
        }
        /// <summary>
        /// 构建用户留存率表格
        /// </summary>
        /// <param name="period"></param>
        /// <param name="retainedUsers"></param>
        /// <param name="forDown"></param>
        /// <param name="tableName"></param>
        /// <param name="activeUsers"></param>
        /// <returns></returns>
        public static string BuildStatRetainedUsersTable(int period, List <net91com.Reports.Entities.DataBaseEntity.Sjqd_StatRetainedUsers> retainedUsers, bool forDown, string tableName, bool activeUsers = false)
        {
            #region 表头开始

            StringBuilder htmlBuilder = new StringBuilder();
            if (forDown)
            {
                htmlBuilder.Append("<table border=\"1\">");
            }
            else
            {
                htmlBuilder.AppendFormat("<table id=\"tab0\" class=\"tablesorter\" name=\"{0}\" cellspacing=\"1\">", tableName);
            }

            if (statRetainedUsersXmlDoc == null)
            {
                statRetainedUsersXmlDoc = new XmlDocument();
                statRetainedUsersXmlDoc.Load(HttpContext.Current.Server.MapPath("~/DataTables/StatRetainedUsers.xml"));
            }
            TableTemplate.IsTrueHandler     IsTrue    = new TableTemplate.IsTrueHandler(IsTrue_StatRetainedUsers);
            NodeCondition_StatRetainedUsers nCodition = new NodeCondition_StatRetainedUsers
            {
                Period = (net91com.Stat.Core.PeriodOptions)period
            };
            TableTemplate.ColumnNode rootNode = new TableTemplate.ColumnNode {
                CorrespondXmlNode = statRetainedUsersXmlDoc.DocumentElement
            };
            //生成表头,并返回数据绑定列
            List <TableTemplate.ColumnNode> dataColumns;
            string head = TableTemplate.BuildTableHead(rootNode, IsTrue, nCodition, out dataColumns);
            htmlBuilder.Append(activeUsers ? head.Replace("新增", "活跃") : head);

            #endregion

            #region 表体开始

            htmlBuilder.Append("<tbody>");
            var usersGrpByOrgDate = retainedUsers.GroupBy(a => a.OriginalDate).OrderByDescending(a => a.Key);
            var dataTable         = new double[usersGrpByOrgDate.Count(), dataColumns.Count];

            for (int i = 0; i < usersGrpByOrgDate.Count(); i++)
            {
                htmlBuilder.Append("<tr style=\"text-align:right;\">");
                var columnIndex = 0;
                foreach (TableTemplate.ColumnNode col in dataColumns)
                {
                    htmlBuilder.Append("<td>");
                    DateTime key  = usersGrpByOrgDate.ElementAt(i).Key;
                    var      temp = usersGrpByOrgDate.ElementAt(i).ToList();

                    switch (col.Name)
                    {
                    case "OrignalDate":
                        htmlBuilder.AppendFormat("{0:yyyy-MM-dd}", key);
                        break;

                    case "OrignalNewUserCount":
                        htmlBuilder.AppendFormat("{0:N0}", temp.ElementAt(0).OriginalNewUserCount);
                        dataTable[i, columnIndex] = temp.ElementAt(0).OriginalNewUserCount;
                        break;

                    default:
                        var str = GetRetainedUserCountString(temp, col, (net91com.Stat.Core.PeriodOptions)period);
                        htmlBuilder.Append(GetRetainedUserCountString(temp, col, (net91com.Stat.Core.PeriodOptions)period));
                        var val = 0.0;
                        double.TryParse(str.Replace("%", ""), out val);
                        if (str.Contains("%"))
                        {
                            val = val / 100;
                        }

                        dataTable[i, columnIndex] = val;
                        break;
                    }
                    htmlBuilder.Append("</td>");
                    columnIndex++;
                }
                htmlBuilder.Append("</tr>");
            }

            var sum = new double[dataColumns.Count];
            for (int col = 0; col < dataColumns.Count; col++)
            {
                int counter = 0;
                for (int row = 0; row < usersGrpByOrgDate.Count(); row++)
                {
                    sum[col] += dataTable[row, col];
                    if (!dataTable[row, col].Equals(0))
                    {
                        counter++;
                    }
                }
                sum[col] = sum[col] / counter;
            }
            htmlBuilder.Append("<tr style='text-align:right;'><td>均值</td>");
            for (int i = 1; i < sum.Length; i++)
            {
                if (double.IsNaN(sum[i]))
                {
                    htmlBuilder.Append("<td></td>");
                    continue;
                }
                htmlBuilder.Append("<td>" + (sum[i] > 1 ? sum[i].ToString("N0") : sum[i].ToString("0.00%")) + "</td>");
            }
            htmlBuilder.Append("</tr>");


            #endregion

            #region 表尾开始

            htmlBuilder.Append("</tbody></table>");

            #endregion

            return(htmlBuilder.ToString());
        }