提交记录修改UI/Controls/Charts/Charts.cs+62 −0看文件
新增UI/Controls/Charts/ChartsItemTypeRadar.cs+323 −0看文件
修改UI/Controls/Charts/ChartsType.cs+4 −0看文件
新增UI/Librays/RadarDemo.cs+157 −0看文件
修改UI/Themes/Charts/Charts.xaml+16 −3看文件
新增UI/Themes/Charts/ChartsItemTypeRadar.xaml+65 −0看文件
修改UI/Themes/Generic.xaml+1 −0看文件
修改UI/UI.csproj+6 −0看文件
修改UI/ViewModels/ChartPageVM.cs+14 −4看文件
| @@ -294,7 +294,23 @@ namespace UI.Controls.Charts | ||
| 294 | 294 | |
| 295 | 295 | |
| 296 | 296 | #endregion |
| 297 | 新增: #region 是否显示总计值(仅柱状图有效,默认显示) | |
| 298 | 新增: /// <summary> | |
| 299 | 新增: /// 是否显示总计值(仅柱状图有效,默认显示) | |
| 300 | 新增: /// </summary> | |
| 301 | 新增: public bool IsShowTotal | |
| 302 | 新增: { | |
| 303 | 新增: get { return (bool)GetValue(IsShowTotalProperty); } | |
| 304 | 新增: set { SetValue(IsShowTotalProperty, value); } | |
| 305 | 新增: } | |
| 306 | 新增: public static readonly DependencyProperty IsShowTotalProperty = | |
| 307 | 新增: DependencyProperty.Register("IsShowTotal", | |
| 308 | 新增: typeof(bool), | |
| 309 | 新增: typeof(Charts), | |
| 310 | 新增: new PropertyMetadata(true)); | |
| 311 | 新增: | |
| 297 | 312 | |
| 313 | 新增: #endregion | |
| 298 | 314 | public bool IsShowValuesPopup |
| 299 | 315 | { |
| 300 | 316 | get { return (bool)GetValue(IsShowValuesPopupProperty); } |
| @@ -398,6 +414,7 @@ namespace UI.Controls.Charts | ||
| 398 | 414 | private Grid MonthContainer; |
| 399 | 415 | private ScrollViewer ScrollViewer; |
| 400 | 416 | private Grid ColumnContainer; |
| 417 | 新增: private Border RadarContainer; | |
| 401 | 418 | /// <summary> |
| 402 | 419 | /// 是否在渲染中 |
| 403 | 420 | /// </summary> |
| @@ -448,6 +465,7 @@ namespace UI.Controls.Charts | ||
| 448 | 465 | ScrollViewer = GetTemplateChild("ScrollViewer") as ScrollViewer; |
| 449 | 466 | NoScrollContainer = GetTemplateChild("NoScrollContainer") as StackPanel; |
| 450 | 467 | ColumnContainer = GetTemplateChild("ColumnContainer") as Grid; |
| 468 | 新增: RadarContainer = GetTemplateChild("Radar") as Border; | |
| 451 | 469 | |
| 452 | 470 | if (IsLoading) |
| 453 | 471 | { |
| @@ -540,12 +558,15 @@ namespace UI.Controls.Charts | ||
| 540 | 558 | MonthContainer.Children.Clear(); |
| 541 | 559 | NoScrollContainer.Children.Clear(); |
| 542 | 560 | ColumnContainer.Children.Clear(); |
| 561 | 新增: RadarContainer.Child = null; | |
| 543 | 562 | |
| 544 | 563 | if (Data == null || Data.Count() <= 0) |
| 545 | 564 | { |
| 546 | 565 | Container.Children.Add(new EmptyData()); |
| 547 | 566 | NoScrollContainer.Children.Add(new EmptyData()); |
| 548 | 567 | CardContainer.Children.Add(new EmptyData()); |
| 568 | 新增: RadarContainer.Child = new EmptyData(); | |
| 569 | 新增: | |
| 549 | 570 | IsEmpty = true; |
| 550 | 571 | return; |
| 551 | 572 | } |
| @@ -569,6 +590,9 @@ namespace UI.Controls.Charts | ||
| 569 | 590 | case ChartsType.Column: |
| 570 | 591 | RenderColumnStyle(); |
| 571 | 592 | break; |
| 593 | 新增: case ChartsType.Radar: | |
| 594 | 新增: RenderLadarStyle(); | |
| 595 | 新增: break; | |
| 572 | 596 | } |
| 573 | 597 | |
| 574 | 598 | } |
| @@ -996,6 +1020,44 @@ namespace UI.Controls.Charts | ||
| 996 | 1020 | } |
| 997 | 1021 | #endregion |
| 998 | 1022 | |
| 1023 | 新增: #region 渲染雷达图 | |
| 1024 | 新增: private void RenderLadarStyle() | |
| 1025 | 新增: { | |
| 1026 | 新增: if (Data.Count() <= 2) | |
| 1027 | 新增: { | |
| 1028 | 新增: RadarContainer.Child = new EmptyData(); | |
| 1029 | 新增: return; | |
| 1030 | 新增: } | |
| 1031 | 新增: // 最大值 | |
| 1032 | 新增: double total = 0; | |
| 1033 | 新增: // 查找最大值 | |
| 1034 | 新增: foreach (var item in Data) | |
| 1035 | 新增: { | |
| 1036 | 新增: // 查找最大值 | |
| 1037 | 新增: double max = item.Values.Sum(); | |
| 1038 | 新增: if (max > maxValue) | |
| 1039 | 新增: { | |
| 1040 | 新增: maxValue = max; | |
| 1041 | 新增: } | |
| 1042 | 新增: | |
| 1043 | 新增: total += item.Values.Sum(); | |
| 1044 | 新增: | |
| 1045 | 新增: } | |
| 1046 | 新增: //maxValue = total; | |
| 1047 | 新增: | |
| 1048 | 新增: if (DataMaximum > 0) | |
| 1049 | 新增: { | |
| 1050 | 新增: maxValue = DataMaximum; | |
| 1051 | 新增: } | |
| 1052 | 新增: var radar = new ChartsItemTypeRadar(); | |
| 1053 | 新增: radar.Data = Data.OrderBy(m => m.Values.Sum()).ToList(); | |
| 1054 | 新增: radar.MaxValue = maxValue; | |
| 1055 | 新增: RadarContainer.Child = radar; | |
| 1056 | 新增: | |
| 1057 | 新增: isRendering = false; | |
| 1058 | 新增: } | |
| 1059 | 新增: #endregion | |
| 1060 | 新增: | |
| 999 | 1061 | private string Covervalue(double value) |
| 1000 | 1062 | { |
| 1001 | 1063 | if (DataValueType == ChartDataValueType.Seconds) |
| @@ -0,0 +1,323 @@ | ||
| 1 | 新增:using Core.Librarys; | |
| 2 | 新增:using Core.Librarys.Image; | |
| 3 | 新增:using System; | |
| 4 | 新增:using System.Collections.Generic; | |
| 5 | 新增:using System.Diagnostics; | |
| 6 | 新增:using System.Globalization; | |
| 7 | 新增:using System.IO; | |
| 8 | 新增:using System.Linq; | |
| 9 | 新增:using System.Text; | |
| 10 | 新增:using System.Threading.Tasks; | |
| 11 | 新增:using System.Windows; | |
| 12 | 新增:using System.Windows.Controls; | |
| 13 | 新增:using System.Windows.Data; | |
| 14 | 新增:using System.Windows.Documents; | |
| 15 | 新增:using System.Windows.Input; | |
| 16 | 新增:using System.Windows.Media; | |
| 17 | 新增:using System.Windows.Media.Imaging; | |
| 18 | 新增:using System.Windows.Navigation; | |
| 19 | 新增:using System.Windows.Shapes; | |
| 20 | 新增:using UI.Controls.Charts.Model; | |
| 21 | 新增:using UI.Librays; | |
| 22 | 新增: | |
| 23 | 新增:namespace UI.Controls.Charts | |
| 24 | 新增:{ | |
| 25 | 新增: public class ChartsItemTypeRadar : Control | |
| 26 | 新增: { | |
| 27 | 新增: #region Data | |
| 28 | 新增: /// <summary> | |
| 29 | 新增: /// Data | |
| 30 | 新增: /// </summary> | |
| 31 | 新增: public List<ChartsDataModel> Data | |
| 32 | 新增: { | |
| 33 | 新增: get { return (List<ChartsDataModel>)GetValue(DataProperty); } | |
| 34 | 新增: set { SetValue(DataProperty, value); } | |
| 35 | 新增: } | |
| 36 | 新增: public static readonly DependencyProperty DataProperty = | |
| 37 | 新增: DependencyProperty.Register("Data", | |
| 38 | 新增: typeof(List<ChartsDataModel>), | |
| 39 | 新增: typeof(ChartsItemTypeRadar)); | |
| 40 | 新增: | |
| 41 | 新增: | |
| 42 | 新增: #endregion | |
| 43 | 新增: | |
| 44 | 新增: #region MaxValue 最大值 | |
| 45 | 新增: /// <summary> | |
| 46 | 新增: /// 样式类型 | |
| 47 | 新增: /// </summary> | |
| 48 | 新增: public double MaxValue | |
| 49 | 新增: { | |
| 50 | 新增: get { return (double)GetValue(MaxValueProperty); } | |
| 51 | 新增: set { SetValue(MaxValueProperty, value); } | |
| 52 | 新增: } | |
| 53 | 新增: public static readonly DependencyProperty MaxValueProperty = | |
| 54 | 新增: DependencyProperty.Register("MaxValue", | |
| 55 | 新增: typeof(double), | |
| 56 | 新增: typeof(ChartsItemTypeRadar)); | |
| 57 | 新增: | |
| 58 | 新增: | |
| 59 | 新增: #endregion | |
| 60 | 新增: | |
| 61 | 新增: #region IsLoading 是否正在加载中 | |
| 62 | 新增: /// <summary> | |
| 63 | 新增: /// 是否正在加载中 | |
| 64 | 新增: /// </summary> | |
| 65 | 新增: public bool IsLoading | |
| 66 | 新增: { | |
| 67 | 新增: get { return (bool)GetValue(IsLoadingProperty); } | |
| 68 | 新增: set { SetValue(IsLoadingProperty, value); } | |
| 69 | 新增: } | |
| 70 | 新增: public static readonly DependencyProperty IsLoadingProperty = | |
| 71 | 新增: DependencyProperty.Register("IsLoading", | |
| 72 | 新增: typeof(bool), | |
| 73 | 新增: typeof(ChartsItemTypeRadar)); | |
| 74 | 新增: | |
| 75 | 新增: | |
| 76 | 新增: #endregion | |
| 77 | 新增: | |
| 78 | 新增: public Geometry RadarPathData | |
| 79 | 新增: { | |
| 80 | 新增: get { return (Geometry)GetValue(RadarPathDataProperty); } | |
| 81 | 新增: set { SetValue(RadarPathDataProperty, value); } | |
| 82 | 新增: } | |
| 83 | 新增: public static readonly DependencyProperty RadarPathDataProperty = | |
| 84 | 新增: DependencyProperty.Register("RadarPathData", | |
| 85 | 新增: typeof(Geometry), | |
| 86 | 新增: typeof(ChartsItemTypeRadar)); | |
| 87 | 新增: | |
| 88 | 新增: private Canvas canvas; | |
| 89 | 新增: public ChartsItemTypeRadar() | |
| 90 | 新增: { | |
| 91 | 新增: DefaultStyleKey = typeof(ChartsItemTypeRadar); | |
| 92 | 新增: } | |
| 93 | 新增: | |
| 94 | 新增: | |
| 95 | 新增: public override void OnApplyTemplate() | |
| 96 | 新增: { | |
| 97 | 新增: base.OnApplyTemplate(); | |
| 98 | 新增: canvas = GetTemplateChild("Canvas") as Canvas; | |
| 99 | 新增: Loaded += ChartsItemTypeRadar_Loaded; | |
| 100 | 新增: } | |
| 101 | 新增: | |
| 102 | 新增: private void ChartsItemTypeRadar_Loaded(object sender, RoutedEventArgs e) | |
| 103 | 新增: { | |
| 104 | 新增: Render(); | |
| 105 | 新增: } | |
| 106 | 新增: | |
| 107 | 新增: private void Render() | |
| 108 | 新增: { | |
| 109 | 新增: if (Data == null || Data.Count == 0) | |
| 110 | 新增: { | |
| 111 | 新增: return; | |
| 112 | 新增: } | |
| 113 | 新增: double size = ActualWidth != double.NaN ? ActualWidth : 200; | |
| 114 | 新增: //size -= 50; | |
| 115 | 新增: int count = Data.Count; | |
| 116 | 新增: | |
| 117 | 新增: // 边长 | |
| 118 | 新增: double lineWidth = size / 2; | |
| 119 | 新增: | |
| 120 | 新增: // 角度 | |
| 121 | 新增: double angle = (Math.PI * 2) / count; | |
| 122 | 新增: | |
| 123 | 新增: var r = lineWidth / count; | |
| 124 | 新增: | |
| 125 | 新增: // 多边形边框 | |
| 126 | 新增: for (int i = 0; i < 3; i++) | |
| 127 | 新增: { | |
| 128 | 新增: var points = new List<Point>(); | |
| 129 | 新增: // 当前半径 | |
| 130 | 新增: var currR = (r - (5 * i)) * (count - i); | |
| 131 | 新增: | |
| 132 | 新增: for (int j = 0; j < count; j++) | |
| 133 | 新增: { | |
| 134 | 新增: points.Add(new Point(lineWidth + currR * Math.Cos(angle * j), lineWidth + currR * Math.Sin(angle * j))); | |
| 135 | 新增: } | |
| 136 | 新增: // 画出边框 | |
| 137 | 新增: for (int i2 = 0; i2 < points.Count; i2++) | |
| 138 | 新增: { | |
| 139 | 新增: var line = new Line(); | |
| 140 | 新增: line.X1 = points[i2].X; | |
| 141 | 新增: line.Y1 = points[i2].Y; | |
| 142 | 新增: | |
| 143 | 新增: line.X2 = i2 == points.Count - 1 ? points[0].X : points[i2 + 1].X; | |
| 144 | 新增: line.Y2 = i2 == points.Count - 1 ? points[0].Y : points[i2 + 1].Y; | |
| 145 | 新增: | |
| 146 | 新增: line.StrokeThickness = i == 0 ? 1 : 1; | |
| 147 | 新增: | |
| 148 | 新增: line.Stroke = UI.Base.Color.Colors.GetFromString(i == 0 ? "#eeeef2" : "#eeeef2"); | |
| 149 | 新增: | |
| 150 | 新增: canvas.Children.Add(line); | |
| 151 | 新增: | |
| 152 | 新增: } | |
| 153 | 新增: } | |
| 154 | 新增: | |
| 155 | 新增: // 顶点连线 | |
| 156 | 新增: for (var i = 0; i < count; i++) | |
| 157 | 新增: { | |
| 158 | 新增: //double diff = i == 0 || i == count - 1 ? 0 : 5; | |
| 159 | 新增: double diff = 0; | |
| 160 | 新增: var x = (double)(lineWidth + (lineWidth - diff) * Math.Cos((angle) * i)); | |
| 161 | 新增: var y = (double)(lineWidth + (lineWidth - diff) * Math.Sin((angle) * i)); | |
| 162 | 新增: | |
| 163 | 新增: var line = new Line(); | |
| 164 | 新增: line.X1 = lineWidth; | |
| 165 | 新增: line.Y1 = lineWidth; | |
| 166 | 新增: | |
| 167 | 新增: line.X2 = x; | |
| 168 | 新增: line.Y2 = y; | |
| 169 | 新增: | |
| 170 | 新增: line.StrokeThickness = .5; | |
| 171 | 新增: line.Stroke = UI.Base.Color.Colors.GetFromString("#dedede"); | |
| 172 | 新增: | |
| 173 | 新增: canvas.Children.Add(line); | |
| 174 | 新增: | |
| 175 | 新增: // 类别文字 | |
| 176 | 新增: var font = new TextBlock(); | |
| 177 | 新增: font.Text = Data[i].Name.Length > 4 ? Data[i].Name.Substring(0, 4) : Data[i].Name; | |
| 178 | 新增: font.Foreground = UI.Base.Color.Colors.GetFromString("#7f7f7f"); | |
| 179 | 新增: font.FontSize = 12; | |
| 180 | 新增: font.ToolTip = $"{Data[i].Name} {Time.ToString((int)Data[i].Values.Sum())}"; | |
| 181 | 新增: | |
| 182 | 新增: var textSize = MeasureString(font); | |
| 183 | 新增: Debug.WriteLine(font.Text + " -> " + angle * i); | |
| 184 | 新增: if (angle * i > 0 && angle * i <= Math.PI / 2) | |
| 185 | 新增: { | |
| 186 | 新增: // >0 && < 1.57 | |
| 187 | 新增: x += textSize.Height / 2; | |
| 188 | 新增: y += textSize.Height / 2; | |
| 189 | 新增: } | |
| 190 | 新增: else if (angle * i > 1.79 && angle * i < 1.8) | |
| 191 | 新增: { | |
| 192 | 新增: x += textSize.Height / 2; | |
| 193 | 新增: y += textSize.Width / 2; | |
| 194 | 新增: } | |
| 195 | 新增: else if (angle * i > 2.09 && angle * i < 2.1) | |
| 196 | 新增: { | |
| 197 | 新增: x += textSize.Height / 2; | |
| 198 | 新增: y += textSize.Height / 2; | |
| 199 | 新增: } | |
| 200 | 新增: else if (angle * i > 2.51 && angle * i < 2.52) | |
| 201 | 新增: { | |
| 202 | 新增: x += textSize.Height / 2; | |
| 203 | 新增: y += textSize.Height / 2; | |
| 204 | 新增: } | |
| 205 | 新增: else if (angle * i > 2.69 && angle * i < 2.7) | |
| 206 | 新增: { | |
| 207 | 新增: x += textSize.Height / 2; | |
| 208 | 新增: y += textSize.Height / 2; | |
| 209 | 新增: } | |
| 210 | 新增: else if (angle * i > Math.PI / 2 && angle * i <= Math.PI) | |
| 211 | 新增: { | |
| 212 | 新增: // > 1.57 && < 3.14 | |
| 213 | 新增: x -= textSize.Height / 2; | |
| 214 | 新增: y -= textSize.Width / 2; | |
| 215 | 新增: | |
| 216 | 新增: } | |
| 217 | 新增: //else if (angle * i > 3.5 && angle * i < 4.2) | |
| 218 | 新增: //{ | |
| 219 | 新增: // x -= textSize.Height / 2; | |
| 220 | 新增: // y -= textSize.Width / 2; | |
| 221 | 新增: | |
| 222 | 新增: //} | |
| 223 | 新增: else if (angle * i > Math.PI && angle * i <= Math.PI * 3 / 2) | |
| 224 | 新增: { | |
| 225 | 新增: // > 3.14 && < 4.71 | |
| 226 | 新增: x += font.FontSize / 2; | |
| 227 | 新增: y -= textSize.Width + textSize.Height / 2; | |
| 228 | 新增: } | |
| 229 | 新增: else if (angle * i > Math.PI * 3 / 2) | |
| 230 | 新增: { | |
| 231 | 新增: // > 4.71 | |
| 232 | 新增: x += textSize.Height / 2; | |
| 233 | 新增: y -= textSize.Width + textSize.Height / 2; | |
| 234 | 新增: } | |
| 235 | 新增: else | |
| 236 | 新增: { | |
| 237 | 新增: // 顶点 | |
| 238 | 新增: x += textSize.Height + textSize.Height / 2; | |
| 239 | 新增: y -= textSize.Width / 2; | |
| 240 | 新增: } | |
| 241 | 新增: | |
| 242 | 新增: font.RenderTransform = new RotateTransform() | |
| 243 | 新增: { | |
| 244 | 新增: Angle = 90 | |
| 245 | 新增: }; | |
| 246 | 新增: Canvas.SetLeft(font, x); | |
| 247 | 新增: Canvas.SetTop(font, y); | |
| 248 | 新增: canvas.Children.Add(font); | |
| 249 | 新增: } | |
| 250 | 新增: | |
| 251 | 新增: // 中心装饰点 | |
| 252 | 新增: var centerPoint = new Ellipse(); | |
| 253 | 新增: centerPoint.Width = 15; | |
| 254 | 新增: centerPoint.Height = 15; | |
| 255 | 新增: centerPoint.Fill = UI.Base.Color.Colors.GetFromString("#ffffff"); | |
| 256 | 新增: centerPoint.Stroke = UI.Base.Color.Colors.GetFromString("#dedede"); | |
| 257 | 新增: centerPoint.StrokeThickness = 1; | |
| 258 | 新增: Canvas.SetLeft(centerPoint, lineWidth - centerPoint.Width / 2); | |
| 259 | 新增: Canvas.SetTop(centerPoint, lineWidth - centerPoint.Width / 2); | |
| 260 | 新增: canvas.Children.Add(centerPoint); | |
| 261 | 新增: | |
| 262 | 新增: // 数据区域 | |
| 263 | 新增: var pc = new PointCollection(); | |
| 264 | 新增: | |
| 265 | 新增: for (int i = 0; i < count; i++) | |
| 266 | 新增: { | |
| 267 | 新增: double sum = Data[i].Values.Sum(); | |
| 268 | 新增: double value = sum / MaxValue; | |
| 269 | 新增: value = value == 1 ? 0.97 : value; | |
| 270 | 新增: | |
| 271 | 新增: var x = (double)(lineWidth + (lineWidth) * Math.Cos((angle) * i) * value); | |
| 272 | 新增: var y = (double)(lineWidth + (lineWidth) * Math.Sin((angle) * i) * value); | |
| 273 | 新增: | |
| 274 | 新增: pc.Add(new Point(x, y)); | |
| 275 | 新增: | |
| 276 | 新增: // 数据点 | |
| 277 | 新增: var dataPoint = new Ellipse(); | |
| 278 | 新增: dataPoint.Width = 5; | |
| 279 | 新增: dataPoint.Height = 5; | |
| 280 | 新增: dataPoint.Fill = UI.Base.Color.Colors.GetFromString("#2b20d9"); | |
| 281 | 新增: dataPoint.Stroke = UI.Base.Color.Colors.GetFromString("#2b20d9"); | |
| 282 | 新增: dataPoint.StrokeThickness = 1; | |
| 283 | 新增: Canvas.SetLeft(dataPoint, x - dataPoint.Width / 2); | |
| 284 | 新增: Canvas.SetTop(dataPoint, y - dataPoint.Width / 2); | |
| 285 | 新增: canvas.Children.Add(dataPoint); | |
| 286 | 新增: } | |
| 287 | 新增: | |
| 288 | 新增: var p = new Polygon(); | |
| 289 | 新增: p.Stroke = UI.Base.Color.Colors.GetFromString("#2b20d9"); | |
| 290 | 新增: p.Fill = UI.Base.Color.Colors.GetFromString("#2b20d9", .3); | |
| 291 | 新增: p.StrokeThickness = 1; | |
| 292 | 新增: p.HorizontalAlignment = HorizontalAlignment.Left; | |
| 293 | 新增: p.VerticalAlignment = VerticalAlignment.Center; | |
| 294 | 新增: p.Points = pc; | |
| 295 | 新增: canvas.Children.Add(p); | |
| 296 | 新增: | |
| 297 | 新增: } | |
| 298 | 新增: private Size MeasureString(TextBlock textBlock) | |
| 299 | 新增: { | |
| 300 | 新增: var formattedText = new FormattedText( | |
| 301 | 新增: textBlock.Text, | |
| 302 | 新增: CultureInfo.CurrentCulture, | |
| 303 | 新增: FlowDirection.LeftToRight, | |
| 304 | 新增: new Typeface(textBlock.FontFamily, textBlock.FontStyle, textBlock.FontWeight, textBlock.FontStretch), | |
| 305 | 新增: textBlock.FontSize, | |
| 306 | 新增: Brushes.Black, | |
| 307 | 新增: new NumberSubstitution()); | |
| 308 | 新增: | |
| 309 | 新增: return new Size(formattedText.Width, formattedText.Height); | |
| 310 | 新增: } | |
| 311 | 新增: | |
| 312 | 新增: protected override void OnMouseEnter(MouseEventArgs e) | |
| 313 | 新增: { | |
| 314 | 新增: base.OnMouseEnter(e); | |
| 315 | 新增: VisualStateManager.GoToState(this, "MouseOver", true); | |
| 316 | 新增: } | |
| 317 | 新增: protected override void OnMouseLeave(MouseEventArgs e) | |
| 318 | 新增: { | |
| 319 | 新增: base.OnMouseLeave(e); | |
| 320 | 新增: VisualStateManager.GoToState(this, "NormalState", true); | |
| 321 | 新增: } | |
| 322 | 新增: } | |
| 323 | 新增:} | |
| @@ -27,5 +27,9 @@ namespace UI.Controls.Charts | ||
| 27 | 27 | /// 柱形图 |
| 28 | 28 | /// </summary> |
| 29 | 29 | Column = 4, |
| 30 | 新增: /// <summary> | |
| 31 | 新增: /// 雷达图 | |
| 32 | 新增: /// </summary> | |
| 33 | 新增: Radar = 5, | |
| 30 | 34 | } |
| 31 | 35 | } |
| @@ -0,0 +1,157 @@ | ||
| 1 | 新增:using System; | |
| 2 | 新增:using System.Collections.Generic; | |
| 3 | 新增:using System.Drawing; | |
| 4 | 新增:using System.Drawing.Imaging; | |
| 5 | 新增:using System.Linq; | |
| 6 | 新增:using System.Text; | |
| 7 | 新增:using System.Threading.Tasks; | |
| 8 | 新增: | |
| 9 | 新增:namespace UI.Librays | |
| 10 | 新增:{ | |
| 11 | 新增: public static class RadarDemo | |
| 12 | 新增: { | |
| 13 | 新增: static float mW = 1200; | |
| 14 | 新增: static float mH = 1200; | |
| 15 | 新增: static Dictionary<string, float> mData = new Dictionary<string, float> | |
| 16 | 新增: { | |
| 17 | 新增: //{ "速度",77}, | |
| 18 | 新增: { "力量", 72}, | |
| 19 | 新增: { "防守", 110}, | |
| 20 | 新增: { "射门", 50}, | |
| 21 | 新增: { "传球", 80}, | |
| 22 | 新增: { "耐力", 60 } | |
| 23 | 新增: };//维度数据 | |
| 24 | 新增: static float mCount = mData.Count; //边数 | |
| 25 | 新增: static float mCenter = mW * 0.5f; //中心点 | |
| 26 | 新增: static float mRadius = mCenter - 100; //半径(减去的值用于给绘制的文本留空间) | |
| 27 | 新增: static double mAngle = (Math.PI * 2) / mCount; //角度 | |
| 28 | 新增: static Graphics graphics = null; | |
| 29 | 新增: static int mPointRadius = 5; // 各个维度分值圆点的半径 | |
| 30 | 新增: static int textFontSize = 18; //顶点文字大小 px | |
| 31 | 新增: const string textFontFamily = "Microsoft Yahei"; //顶点字体 | |
| 32 | 新增: static Color lineColor = Color.Green; | |
| 33 | 新增: static Color fillColor = Color.FromArgb(128, 255, 0, 0); | |
| 34 | 新增: static Color fontColor = Color.Black; | |
| 35 | 新增: public static void Show() | |
| 36 | 新增: { | |
| 37 | 新增: Bitmap img = new Bitmap((int)mW, (int)mH); | |
| 38 | 新增: graphics = Graphics.FromImage(img); | |
| 39 | 新增: graphics.Clear(Color.White); | |
| 40 | 新增: img.Save($"{AppDomain.CurrentDomain.BaseDirectory}/0.png", ImageFormat.Jpeg); | |
| 41 | 新增: DrawPolygon(graphics); | |
| 42 | 新增: img.Save($"{AppDomain.CurrentDomain.BaseDirectory}/1.png", ImageFormat.Png); | |
| 43 | 新增: DrawLines(graphics); | |
| 44 | 新增: img.Save($"{AppDomain.CurrentDomain.BaseDirectory}/2.png", ImageFormat.Png); | |
| 45 | 新增: DrawText(graphics); | |
| 46 | 新增: img.Save($"{AppDomain.CurrentDomain.BaseDirectory}/3.png", ImageFormat.Png); | |
| 47 | 新增: DrawRegion(graphics); | |
| 48 | 新增: img.Save($"{AppDomain.CurrentDomain.BaseDirectory}/4.png", ImageFormat.Png); | |
| 49 | 新增: DrawCircle(graphics); | |
| 50 | 新增: img.Save($"{AppDomain.CurrentDomain.BaseDirectory}/5.png", ImageFormat.Png); | |
| 51 | 新增: img.Dispose(); | |
| 52 | 新增: graphics.Dispose(); | |
| 53 | 新增: } | |
| 54 | 新增: // 绘制多边形边 | |
| 55 | 新增: private static void DrawPolygon(Graphics ctx) | |
| 56 | 新增: { | |
| 57 | 新增: var r = mRadius / mCount; //单位半径 | |
| 58 | 新增: Pen pen = new Pen(lineColor); | |
| 59 | 新增: //画6个圈 | |
| 60 | 新增: for (var i = 0; i < mCount; i++) | |
| 61 | 新增: { | |
| 62 | 新增: var points = new List<PointF>(); | |
| 63 | 新增: var currR = r * (i + 1); //当前半径 | |
| 64 | 新增: //画6条边 | |
| 65 | 新增: for (var j = 0; j < mCount; j++) | |
| 66 | 新增: { | |
| 67 | 新增: var x = (float)(mCenter + currR * Math.Cos(mAngle * j)); | |
| 68 | 新增: var y = (float)(mCenter + currR * Math.Sin(mAngle * j)); | |
| 69 | 新增: points.Add(new PointF { X = x, Y = y }); | |
| 70 | 新增: } | |
| 71 | 新增: ctx.DrawPolygon(pen, points.ToArray()); | |
| 72 | 新增: //break; | |
| 73 | 新增: } | |
| 74 | 新增: ctx.Save(); | |
| 75 | 新增: } | |
| 76 | 新增: //顶点连线 | |
| 77 | 新增: private static void DrawLines(Graphics ctx) | |
| 78 | 新增: { | |
| 79 | 新增: for (var i = 0; i < mCount; i++) | |
| 80 | 新增: { | |
| 81 | 新增: var x = (float)(mCenter + mRadius * Math.Cos(mAngle * i)); | |
| 82 | 新增: var y = (float)(mCenter + mRadius * Math.Sin(mAngle * i)); | |
| 83 | 新增: ctx.DrawLine(new Pen(lineColor), new PointF { X = mCenter, Y = mCenter }, new PointF { X = x, Y = y }); | |
| 84 | 新增: //break; | |
| 85 | 新增: } | |
| 86 | 新增: ctx.Save(); | |
| 87 | 新增: } | |
| 88 | 新增: //绘制文本 | |
| 89 | 新增: private static void DrawText(Graphics ctx) | |
| 90 | 新增: { | |
| 91 | 新增: var fontSize = textFontSize;//mCenter / 12; | |
| 92 | 新增: Font font = new Font(textFontFamily, fontSize, FontStyle.Regular); | |
| 93 | 新增: int i = 0; | |
| 94 | 新增: foreach (var item in mData) | |
| 95 | 新增: { | |
| 96 | 新增: var x = (float)(mCenter + mRadius * Math.Cos(mAngle * i)); | |
| 97 | 新增: var y = (float)(mCenter + mRadius * Math.Sin(mAngle * i) - fontSize); | |
| 98 | 新增: if (mAngle * i > 0 && mAngle * i <= Math.PI / 2) | |
| 99 | 新增: { | |
| 100 | 新增: ctx.DrawString(item.Key, font, new SolidBrush(fontColor), x - ctx.MeasureString(item.Key, font).Width * 0.5f, y + fontSize/* y + fontSize*/); | |
| 101 | 新增: } | |
| 102 | 新增: else if (mAngle * i > Math.PI / 2 && mAngle * i <= Math.PI) | |
| 103 | 新增: { | |
| 104 | 新增: ctx.DrawString(item.Key, font, new SolidBrush(fontColor), x - ctx.MeasureString(item.Key, font).Width, y /*y + fontSize*/); | |
| 105 | 新增: } | |
| 106 | 新增: else if (mAngle * i > Math.PI && mAngle * i <= Math.PI * 3 / 2) | |
| 107 | 新增: { | |
| 108 | 新增: ctx.DrawString(item.Key, font, new SolidBrush(fontColor), x - ctx.MeasureString(item.Key, font).Width, y); | |
| 109 | 新增: } | |
| 110 | 新增: else if (mAngle * i > Math.PI * 3 / 2) | |
| 111 | 新增: { | |
| 112 | 新增: ctx.DrawString(item.Key, font, new SolidBrush(fontColor), x - ctx.MeasureString(item.Key, font).Width * 0.5f, y - fontSize * 0.5f); | |
| 113 | 新增: } | |
| 114 | 新增: else | |
| 115 | 新增: { | |
| 116 | 新增: ctx.DrawString(item.Key, font, new SolidBrush(fontColor), x, y /* y + fontSize*/); | |
| 117 | 新增: } | |
| 118 | 新增: i++; | |
| 119 | 新增: } | |
| 120 | 新增: ctx.Save(); | |
| 121 | 新增: } | |
| 122 | 新增: //绘制数据区域 | |
| 123 | 新增: private static void DrawRegion(Graphics ctx) | |
| 124 | 新增: { | |
| 125 | 新增: int i = 0; | |
| 126 | 新增: List<PointF> points = new List<PointF>(); | |
| 127 | 新增: foreach (var item in mData) | |
| 128 | 新增: { | |
| 129 | 新增: var x = (float)(mCenter + mRadius * Math.Cos(mAngle * i) * item.Value / 100); | |
| 130 | 新增: var y = (float)(mCenter + mRadius * Math.Sin(mAngle * i) * item.Value / 100); | |
| 131 | 新增: points.Add(new PointF { X = x, Y = y }); | |
| 132 | 新增: //ctx.DrawArc(new Pen(lineColor), x, y, r, r, 0, (float)Math.PI * 2); | |
| 133 | 新增: i++; | |
| 134 | 新增: } | |
| 135 | 新增: //GraphicsPath path = new GraphicsPath(); | |
| 136 | 新增: //path.AddLines(points.ToArray()); | |
| 137 | 新增: ctx.FillPolygon(new SolidBrush(fillColor), points.ToArray()); | |
| 138 | 新增: ctx.Save(); | |
| 139 | 新增: } | |
| 140 | 新增: //画点 | |
| 141 | 新增: private static void DrawCircle(Graphics ctx) | |
| 142 | 新增: { | |
| 143 | 新增: //var r = mCenter / 18; | |
| 144 | 新增: var r = mPointRadius; | |
| 145 | 新增: int i = 0; | |
| 146 | 新增: foreach (var item in mData) | |
| 147 | 新增: { | |
| 148 | 新增: var x = (float)(mCenter + mRadius * Math.Cos(mAngle * i) * item.Value / 100); | |
| 149 | 新增: var y = (float)(mCenter + mRadius * Math.Sin(mAngle * i) * item.Value / 100); | |
| 150 | 新增: ctx.FillPie(new SolidBrush(fillColor), x - r, y - r, r * 2, r * 2, 0, 360); | |
| 151 | 新增: //ctx.DrawArc(new Pen(lineColor), x, y, r, r, 0, (float)Math.PI * 2); | |
| 152 | 新增: i++; | |
| 153 | 新增: } | |
| 154 | 新增: ctx.Save(); | |
| 155 | 新增: } | |
| 156 | 新增: } | |
| 157 | 新增:} | |
| @@ -13,6 +13,9 @@ | ||
| 13 | 13 | <Setter.Value> |
| 14 | 14 | <ControlTemplate TargetType="{x:Type local:Charts}"> |
| 15 | 15 | <Grid Background="{TemplateBinding Background}" SnapsToDevicePixels="True"> |
| 16 | 新增: <Border x:Name="Radar" Visibility="Collapsed"> | |
| 17 | 新增: | |
| 18 | 新增: </Border> | |
| 16 | 19 | <Grid x:Name="HorizontalA" Visibility="Collapsed"> |
| 17 | 20 | <ScrollViewer Visibility="Collapsed" x:Name="ScrollViewer" VerticalScrollBarVisibility="Auto" Height="{Binding ElementName=HorizontalA,Path=ActualHeight}" CanContentScroll="False"> |
| 18 | 21 | <StackPanel x:Name="Container"> |
| @@ -33,7 +36,7 @@ | ||
| 33 | 36 | <RowDefinition Height="*"/> |
| 34 | 37 | <RowDefinition Height="auto"/> |
| 35 | 38 | </Grid.RowDefinitions> |
| 36 | 删除: <StackPanel> | |
| 39 | 新增: <StackPanel x:Name="ColumnTotal"> | |
| 37 | 40 | <TextBlock Text="总计" Foreground="#626262"/> |
| 38 | 41 | <TextBlock Margin="0,10,0,0" Text="{TemplateBinding Total}" FontSize="20" Foreground="#1a1919"/> |
| 39 | 42 | </StackPanel> |
| @@ -115,7 +118,7 @@ | ||
| 115 | 118 | <Border Width="10" CornerRadius="4" Height="10" Background="{Binding Color,Converter={StaticResource HextoColorConverter}}"> |
| 116 | 119 | <!--颜色--> |
| 117 | 120 | </Border> |
| 118 | 删除: | |
| 121 | 新增: | |
| 119 | 122 | <Border Grid.Column="1" Margin="5,0,0,0"> |
| 120 | 123 | <!--名称--> |
| 121 | 124 | <TextBlock Foreground="#5c5c5c" VerticalAlignment="Center" Text="{Binding Name}" FontSize="12"/> |
| @@ -249,7 +252,13 @@ | ||
| 249 | 252 | <Setter Property="Visibility" Value="Visible" TargetName="ColumnEmpty"/> |
| 250 | 253 | <Setter Property="Visibility" Value="Collapsed" TargetName="ColumnMain"/> |
| 251 | 254 | </MultiTrigger> |
| 252 | 删除: | |
| 255 | 新增: <MultiTrigger> | |
| 256 | 新增: <MultiTrigger.Conditions> | |
| 257 | 新增: <Condition Property="IsShowTotal" Value="False"/> | |
| 258 | 新增: <Condition Property="ChartsType" Value="Column"/> | |
| 259 | 新增: </MultiTrigger.Conditions> | |
| 260 | 新增: <Setter Property="Visibility" Value="Collapsed" TargetName="ColumnTotal"/> | |
| 261 | 新增: </MultiTrigger> | |
| 253 | 262 | <Trigger Property="ChartsType" |
| 254 | 263 | Value="HorizontalA"> |
| 255 | 264 | <Setter TargetName="HorizontalA" Property="Visibility" Value="Visible"/> |
| @@ -266,6 +275,10 @@ | ||
| 266 | 275 | Value="Column"> |
| 267 | 276 | <Setter TargetName="Column" Property="Visibility" Value="Visible"/> |
| 268 | 277 | </Trigger> |
| 278 | 新增: <Trigger Property="ChartsType" | |
| 279 | 新增: Value="Radar"> | |
| 280 | 新增: <Setter TargetName="Radar" Property="Visibility" Value="Visible"/> | |
| 281 | 新增: </Trigger> | |
| 269 | 282 | </ControlTemplate.Triggers> |
| 270 | 283 | </ControlTemplate> |
| 271 | 284 | </Setter.Value> |
| @@ -0,0 +1,65 @@ | ||
| 1 | 新增:<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" | |
| 2 | 新增: xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" | |
| 3 | 新增: xmlns:local="clr-namespace:UI.Controls.Charts" | |
| 4 | 新增: xmlns:base="clr-namespace:UI.Controls.Base"> | |
| 5 | 新增: <Style TargetType="{x:Type local:ChartsItemTypeRadar}"> | |
| 6 | 新增: <Setter Property="SnapsToDevicePixels" | |
| 7 | 新增: Value="true" /> | |
| 8 | 新增: | |
| 9 | 新增: <Setter Property="Background" Value="Transparent"/> | |
| 10 | 新增: <!--<Setter Property="Margin" Value="0,5"/>--> | |
| 11 | 新增: | |
| 12 | 新增: <Setter Property="Template"> | |
| 13 | 新增: <Setter.Value> | |
| 14 | 新增: <ControlTemplate TargetType="{x:Type local:ChartsItemTypeRadar}"> | |
| 15 | 新增: <Grid Background="{TemplateBinding Background}"> | |
| 16 | 新增: <Grid x:Name="Normal"> | |
| 17 | 新增: | |
| 18 | 新增: <Canvas x:Name="Canvas" RenderTransformOrigin=".5,.5"> | |
| 19 | 新增: <Canvas.RenderTransform> | |
| 20 | 新增: <RotateTransform Angle="-90"></RotateTransform> | |
| 21 | 新增: </Canvas.RenderTransform> | |
| 22 | 新增: </Canvas> | |
| 23 | 新增: | |
| 24 | 新增: <Rectangle | |
| 25 | 新增: x:Name="ValueBlockObj" | |
| 26 | 新增: Width="20" | |
| 27 | 新增: Height="20" | |
| 28 | 新增: | |
| 29 | 新增: HorizontalAlignment="Center" | |
| 30 | 新增: VerticalAlignment="Center" | |
| 31 | 新增: Margin="0" | |
| 32 | 新增: RenderTransformOrigin="0.5,0.5" | |
| 33 | 新增: | |
| 34 | 新增: > | |
| 35 | 新增: <Rectangle.Effect> | |
| 36 | 新增: <BlurEffect RenderOptions.BitmapScalingMode="LowQuality" Radius="35" RenderingBias="Performance"/> | |
| 37 | 新增: </Rectangle.Effect> | |
| 38 | 新增: <Rectangle.Fill> | |
| 39 | 新增: <LinearGradientBrush RenderOptions.BitmapScalingMode="LowQuality" EndPoint="2,1" StartPoint="-2,0"> | |
| 40 | 新增: <GradientStop Color="White"/> | |
| 41 | 新增: <GradientStop Color="#ff305b" Offset="1"/> | |
| 42 | 新增: </LinearGradientBrush> | |
| 43 | 新增: </Rectangle.Fill> | |
| 44 | 新增: <Rectangle.RenderTransform> | |
| 45 | 新增: <ScaleTransform ScaleX="3" ScaleY="3" CenterX="0" CenterY="0"/> | |
| 46 | 新增: </Rectangle.RenderTransform> | |
| 47 | 新增: </Rectangle> | |
| 48 | 新增: </Grid> | |
| 49 | 新增: <Grid x:Name="Loading"> | |
| 50 | 新增: </Grid> | |
| 51 | 新增: </Grid> | |
| 52 | 新增: | |
| 53 | 新增: <!--</Border>--> | |
| 54 | 新增: | |
| 55 | 新增: <ControlTemplate.Triggers> | |
| 56 | 新增: <Trigger Property="IsLoading" Value="True"> | |
| 57 | 新增: <Setter TargetName="Loading" Property="Visibility" Value="Visible"/> | |
| 58 | 新增: <Setter TargetName="Normal" Property="Visibility" Value="Hidden"/> | |
| 59 | 新增: </Trigger> | |
| 60 | 新增: </ControlTemplate.Triggers> | |
| 61 | 新增: </ControlTemplate> | |
| 62 | 新增: </Setter.Value> | |
| 63 | 新增: </Setter> | |
| 64 | 新增: </Style> | |
| 65 | 新增:</ResourceDictionary> | |
| 文件末尾没有换行 | ||
| @@ -21,6 +21,7 @@ | ||
| 21 | 21 | <ResourceDictionary Source="/Tai;component/Themes/Charts/ChartsItemTypeCard.xaml"/> |
| 22 | 22 | <ResourceDictionary Source="/Tai;component/Themes/Charts/ChartsItemTypeMonth.xaml"/> |
| 23 | 23 | <ResourceDictionary Source="/Tai;component/Themes/Charts/ChartsItemTypeColumn.xaml"/> |
| 24 | 新增: <ResourceDictionary Source="/Tai;component/Themes/Charts/ChartsItemTypeRadar.xaml"/> | |
| 24 | 25 | |
| 25 | 26 | <ResourceDictionary Source="/Tai;component/Themes/Tabbar/Tabbar.xaml"/> |
| 26 | 27 | <ResourceDictionary Source="/Tai;component/Themes/DatePickerBar/DatePickerBar.xaml"/> |
| @@ -142,6 +142,7 @@ | ||
| 142 | 142 | <Compile Include="Controls\Button\IconButton.cs" /> |
| 143 | 143 | <Compile Include="Controls\Charts\ChartDataValueType.cs" /> |
| 144 | 144 | <Compile Include="Controls\Charts\ChartItemTypeColumn.cs" /> |
| 145 | 新增: <Compile Include="Controls\Charts\ChartsItemTypeRadar.cs" /> | |
| 145 | 146 | <Compile Include="Controls\Charts\ChartsItemTypeMonth.cs" /> |
| 146 | 147 | <Compile Include="Controls\Charts\ChartsItemTypeCard.cs" /> |
| 147 | 148 | <Compile Include="Controls\Charts\ChartsItemTypeA.cs" /> |
| @@ -174,6 +175,7 @@ | ||
| 174 | 175 | <Compile Include="Controls\Toggle\Toggle.cs" /> |
| 175 | 176 | <Compile Include="Controls\Window\ToastType.cs" /> |
| 176 | 177 | <Compile Include="Extensions\ListExtensions.cs" /> |
| 178 | 新增: <Compile Include="Librays\RadarDemo.cs" /> | |
| 177 | 179 | <Compile Include="Librays\Image\Imager.cs" /> |
| 178 | 180 | <Compile Include="Models\CategoryAppListPageModel.cs" /> |
| 179 | 181 | <Compile Include="Models\CategoryAppList\ChooseAppModel.cs" /> |
| @@ -276,6 +278,10 @@ | ||
| 276 | 278 | <Generator>MSBuild:Compile</Generator> |
| 277 | 279 | <SubType>Designer</SubType> |
| 278 | 280 | </Page> |
| 281 | 新增: <Page Include="Themes\Charts\ChartsItemTypeRadar.xaml"> | |
| 282 | 新增: <Generator>MSBuild:Compile</Generator> | |
| 283 | 新增: <SubType>Designer</SubType> | |
| 284 | 新增: </Page> | |
| 279 | 285 | <Page Include="Themes\Charts\ChartsItemTypeColumn.xaml"> |
| 280 | 286 | <Generator>MSBuild:Compile</Generator> |
| 281 | 287 | <SubType>Designer</SubType> |
| @@ -3,6 +3,7 @@ using Core.Models; | ||
| 3 | 3 | using Core.Servicers.Interfaces; |
| 4 | 4 | using System; |
| 5 | 5 | using System.Collections.Generic; |
| 6 | 新增:using System.Diagnostics; | |
| 6 | 7 | using System.Linq; |
| 7 | 8 | using System.Text; |
| 8 | 9 | using System.Threading.Tasks; |
| @@ -180,7 +181,8 @@ namespace UI.ViewModels | ||
| 180 | 181 | } |
| 181 | 182 | |
| 182 | 183 | Data = chartData; |
| 183 | 删除: | |
| 184 | 新增: double totalUse = Data.Sum(m => m.Values.Sum()); | |
| 185 | 新增: TotalHours = Time.ToHoursString(totalUse); | |
| 184 | 186 | LoadTopData(); |
| 185 | 187 | }); |
| 186 | 188 | } |
| @@ -236,6 +238,8 @@ namespace UI.ViewModels | ||
| 236 | 238 | } |
| 237 | 239 | |
| 238 | 240 | Data = chartData; |
| 241 | 新增: double totalUse = Data.Sum(m => m.Values.Sum()); | |
| 242 | 新增: TotalHours = Time.ToHoursString(totalUse); | |
| 239 | 243 | }); |
| 240 | 244 | |
| 241 | 245 | |
| @@ -289,7 +293,8 @@ namespace UI.ViewModels | ||
| 289 | 293 | } |
| 290 | 294 | |
| 291 | 295 | Data = chartData; |
| 292 | 删除: | |
| 296 | 新增: double totalUse = Data.Sum(m => m.Values.Sum()); | |
| 297 | 新增: TotalHours = Time.ToHoursString(totalUse); | |
| 293 | 298 | LoadTopData(); |
| 294 | 299 | }); |
| 295 | 300 | |
| @@ -346,7 +351,8 @@ namespace UI.ViewModels | ||
| 346 | 351 | } |
| 347 | 352 | |
| 348 | 353 | Data = chartData; |
| 349 | 删除: | |
| 354 | 新增: double totalUse = Data.Sum(m => m.Values.Sum()); | |
| 355 | 新增: TotalHours = Time.ToHoursString(totalUse); | |
| 350 | 356 | LoadTopData(); |
| 351 | 357 | }); |
| 352 | 358 | } |
| @@ -380,9 +386,13 @@ namespace UI.ViewModels | ||
| 380 | 386 | dateStart = dateArr[0]; |
| 381 | 387 | dateEnd = dateArr[1]; |
| 382 | 388 | } |
| 383 | 删除: var list = data.GetDateRangelogList(dateStart, dateEnd, 10); | |
| 389 | 新增: var list = data.GetDateRangelogList(dateStart, dateEnd, 5); | |
| 384 | 390 | |
| 385 | 391 | TopData = MapToChartsData(list); |
| 392 | 新增: | |
| 393 | 新增: TopHours = TopData.Count > 0 ? Time.ToHoursString(TopData[0].Value) : "0"; | |
| 394 | 新增: | |
| 395 | 新增: AppCount = data.GetDateRangeAppCount(dateStart, dateEnd).ToString(); | |
| 386 | 396 | }); |
| 387 | 397 | } |
| 388 | 398 | |

