跳到主要内容

github/tai

公开

Tai · Windows 软件与网站使用时长统计。上游 Planshit/Tai 的源码镜像,非灵栈原创;MIT 许可。来源:https://github.com/Planshit/Tai 。本次为手动同步,暂不提供安装包。

浏览文件

ChartsItemTypePie.cs

212 行 · 6.6 KB历史下载
1using Newtonsoft.Json.Linq;
2using System;
3using System.Collections.Generic;
4using System.Diagnostics;
5using System.Linq;
6using System.Text;
7using System.Threading.Tasks;
8using System.Windows;
9using System.Windows.Controls;
10using System.Windows.Input;
11using System.Windows.Media;
12using System.Windows.Shapes;
13using UI.Base.Color;
14using UI.Controls.Charts.Model;
15
16namespace UI.Controls.Charts
17{
18 public class ChartsItemTypePie : Canvas
19 {
20 #region Data
21 /// <summary>
22 /// Data
23 /// </summary>
24 public List<ChartsDataModel> Data
25 {
26 get { return (List<ChartsDataModel>)GetValue(DataProperty); }
27 set { SetValue(DataProperty, value); }
28 }
29 public static readonly DependencyProperty DataProperty =
30 DependencyProperty.Register("Data",
31 typeof(List<ChartsDataModel>),
32 typeof(ChartsItemTypePie));
33
34
35 #endregion
36
37 #region MaxValue 最大值
38 /// <summary>
39 /// 样式类型
40 /// </summary>
41 public double MaxValue
42 {
43 get { return (double)GetValue(MaxValueProperty); }
44 set { SetValue(MaxValueProperty, value); }
45 }
46 public static readonly DependencyProperty MaxValueProperty =
47 DependencyProperty.Register("MaxValue",
48 typeof(double),
49 typeof(ChartsItemTypePie));
50
51
52 #endregion
53 private double _lastAngle = -Math.PI / 2;
54 private int _zIndex = 1;
55 private List<Path> _paths = new List<Path>();
56 public ChartsItemTypePie()
57 {
58 DefaultStyleKey = typeof(ChartsItemTypePie);
59 Loaded += ChartsItemTypePie_Loaded;
60 }
61
62 private void ChartsItemTypePie_Loaded(object sender, RoutedEventArgs e)
63 {
64 Render();
65 }
66
67 private void Render()
68 {
69 _paths.Clear();
70 Children.Clear();
71 MaxValue = Data.Sum(m => m.Value);
72
73 int i = 0;
74 foreach (var item in Data)
75 {
76 var angle = item.Value / MaxValue * 360;
77 //if (i == 1)
78 //{
79 // angle += 10;
80 //}
81
82 var path = CreatePath(angle, UI.Base.Color.Colors.GetFromString(item.Color));
83 path.ToolTip = item.PopupText;
84 path.MouseEnter += Path_MouseEnter;
85 path.MouseLeave += Path_MouseLeave;
86 _paths.Add(path);
87 Children.Add(path);
88 i++;
89 }
90 }
91
92 private void Path_MouseLeave(object sender, System.Windows.Input.MouseEventArgs e)
93 {
94 foreach (var p in _paths)
95 {
96 p.Opacity = 1;
97 }
98 }
99
100 private void Path_MouseEnter(object sender, System.Windows.Input.MouseEventArgs e)
101 {
102 var path = sender as Path;
103 foreach (var p in _paths)
104 {
105 if (p != path)
106 {
107 p.Opacity = .2;
108 }
109 }
110 }
111 private double _lastX = -1, _lastY = -1;
112 private Path CreatePath(double angle_, SolidColorBrush color_)
113 {
114 Path path = new Path();
115
116 PathGeometry pathGeometry = new PathGeometry();
117 double Radius = ActualHeight / 2;
118 //double Angle = angle_;
119 //Point startPoint = new Point(Radius, Radius);
120
121 //if (Angle >= 360)
122 //{
123 // Angle = 359;
124 //}
125
126
127 double x = Math.Cos(_lastAngle) * Radius + Radius;
128 double y = Math.Sin(_lastAngle) * Radius + Radius;
129 var lin1 = new LineSegment(new Point(x, y), true);
130
131 _lastAngle += Math.PI * angle_ / 180;
132
133 x = Math.Cos(_lastAngle) * Radius + Radius;
134 y = Math.Sin(_lastAngle) * Radius + Radius;
135 //Point endPoint = ComputeCartesianCoordinate(Angle, Radius);
136 //endPoint.X += Radius;
137 //endPoint.Y += Radius;
138
139 //_lastX = endPoint.X;
140 //_lastY = endPoint.Y;
141 //Debug.WriteLine($"angle:{angle_},start:{startPoint},endpoint:{endPoint}");
142
143 var arcSeg = new ArcSegment()
144 {
145 Size = new Size(Radius, Radius),
146 IsLargeArc = angle_ > 180,
147 SweepDirection = SweepDirection.Clockwise,
148 Point = new Point(x, y),
149 RotationAngle = angle_,
150 };
151 var line2 = new LineSegment(new Point(Radius, Radius), true);
152 var fig = new PathFigure(new Point(Radius, Radius), new PathSegment[] { lin1, arcSeg, line2 }, false);
153 pathGeometry.Figures.Add(fig);
154 path.Data = pathGeometry;
155 path.Fill = color_;
156 return path;
157 }
158 //private Path CreatePath(double angle_, SolidColorBrush color_)
159 //{
160 // Path path = new Path();
161 // path.Stroke = color_;
162 // path.StrokeThickness = ActualHeight / 2;
163 // //path.StrokeStartLineCap = PenLineCap.Round;
164 // //path.StrokeEndLineCap = PenLineCap.Round;
165
166 // double width = path.StrokeThickness;
167
168 // PathGeometry pathGeometry = new PathGeometry();
169 // double Radius = (ActualHeight - width) / 2;
170 // double Angle = angle_ + _lastAngle;
171 // Point startPoint = new Point(Radius, 0);
172 // if (Angle >= 360)
173 // {
174 // Angle = 359;
175 // }
176 // Point endPoint = ComputeCartesianCoordinate(Angle, Radius);
177 // endPoint.X += Radius;
178 // endPoint.Y += Radius;
179
180 // var pf = new PathFigure()
181 // {
182 // StartPoint = startPoint
183 // };
184 // pf.Segments.Add(new ArcSegment()
185 // {
186 // Size = new Size(Radius, Radius),
187 // IsLargeArc = Angle > 180,
188 // SweepDirection = SweepDirection.Clockwise,
189 // Point = endPoint,
190 // });
191 // pathGeometry.Figures.Add(pf);
192 // path.Data = pathGeometry;
193 // _lastAngle = Angle;
194 // Canvas.SetLeft(path, width / 2);
195 // Canvas.SetTop(path, width / 2);
196 // Canvas.SetZIndex(path, _zIndex);
197 // _zIndex--;
198 // return path;
199 //}
200 private Point ComputeCartesianCoordinate(double angle, double radius)
201 {
202 // convert to radians
203 double angleRad = (Math.PI / 180.0) * (angle - 90);
204
205 double x = radius * Math.Cos(angleRad);
206 double y = radius * Math.Sin(angleRad);
207
208 return new Point(x, y);
209 }
210
211 }
212}