Advertisement
Guest User

Untitled

a guest
Dec 2nd, 2016
59
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 12.77 KB | None | 0 0
  1. internal class PolarPoint
  2. {
  3. public double Angle { get; private set; }
  4. public double Y { get; private set; }
  5. public PolarPoint(double angle, double y)
  6. {
  7. this.Angle = angle;
  8. this.Y = y;
  9. }
  10. }
  11.  
  12. internal class RectangleInPolarPoints
  13. {
  14. public PolarPoint TopLeft { get; private set; }
  15. public PolarPoint TopRight { get; private set; }
  16. public PolarPoint BottomLeft { get; private set; }
  17. public PolarPoint BottonRight { get; private set; }
  18. public RectangleInPolarPoints(PolarPoint topLeft, PolarPoint bottomLeft, PolarPoint topRight, PolarPoint bottomRight)
  19. {
  20. this.TopLeft = topLeft;
  21. this.TopRight = topRight;
  22. this.BottomLeft = bottomLeft;
  23. this.BottonRight = bottomRight;
  24. }
  25. }
  26.  
  27. internal struct PointD
  28. {
  29. public double X { get; private set; }
  30. public double Y { get; private set; }
  31. public PointD(double x, double y)
  32. : this()
  33. {
  34. this.X = x;
  35. this.Y = y;
  36. }
  37. }
  38.  
  39. #endregion
  40.  
  41. #region Designer code
  42.  
  43. private System.Windows.Forms.DataVisualization.Charting.Chart chart1;
  44. private System.Windows.Forms.TextBox textBox1;
  45. private System.Windows.Forms.SplitContainer splitContainer1;
  46.  
  47. private void InitializeComponent()
  48. {
  49. System.Windows.Forms.DataVisualization.Charting.ChartArea chartArea1 = new System.Windows.Forms.DataVisualization.Charting.ChartArea();
  50. System.Windows.Forms.DataVisualization.Charting.Legend legend1 = new System.Windows.Forms.DataVisualization.Charting.Legend();
  51. System.Windows.Forms.DataVisualization.Charting.Series series1 = new System.Windows.Forms.DataVisualization.Charting.Series();
  52. this.chart1 = new System.Windows.Forms.DataVisualization.Charting.Chart();
  53. this.textBox1 = new System.Windows.Forms.TextBox();
  54. this.splitContainer1 = new System.Windows.Forms.SplitContainer();
  55. ((System.ComponentModel.ISupportInitialize)(this.chart1)).BeginInit();
  56. this.splitContainer1.Panel1.SuspendLayout();
  57. this.splitContainer1.Panel2.SuspendLayout();
  58. this.splitContainer1.SuspendLayout();
  59. this.SuspendLayout();
  60. //
  61. // chart1
  62. //
  63. chartArea1.Name = "ChartArea1";
  64. this.chart1.ChartAreas.Add(chartArea1);
  65. this.chart1.Dock = System.Windows.Forms.DockStyle.Fill;
  66. legend1.Name = "Legend1";
  67. this.chart1.Legends.Add(legend1);
  68. this.chart1.Location = new System.Drawing.Point(0, 0);
  69. this.chart1.Name = "chart1";
  70. series1.ChartArea = "ChartArea1";
  71. series1.Legend = "Legend1";
  72. series1.Name = "Series1";
  73. this.chart1.Series.Add(series1);
  74. this.chart1.Size = new System.Drawing.Size(644, 339);
  75. this.chart1.TabIndex = 0;
  76. this.chart1.Text = "chart1";
  77. //
  78. // textBox1
  79. //
  80. this.textBox1.Dock = System.Windows.Forms.DockStyle.Fill;
  81. this.textBox1.Font = new System.Drawing.Font("Courier New", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
  82. this.textBox1.Location = new System.Drawing.Point(0, 0);
  83. this.textBox1.Multiline = true;
  84. this.textBox1.Name = "textBox1";
  85. this.textBox1.ScrollBars = System.Windows.Forms.ScrollBars.Vertical;
  86. this.textBox1.Size = new System.Drawing.Size(644, 79);
  87. this.textBox1.TabIndex = 1;
  88. //
  89. // splitContainer1
  90. //
  91. this.splitContainer1.Dock = System.Windows.Forms.DockStyle.Fill;
  92. this.splitContainer1.Location = new System.Drawing.Point(0, 0);
  93. this.splitContainer1.Name = "splitContainer1";
  94. this.splitContainer1.Orientation = System.Windows.Forms.Orientation.Horizontal;
  95. //
  96. // splitContainer1.Panel1
  97. //
  98. this.splitContainer1.Panel1.Controls.Add(this.chart1);
  99. //
  100. // splitContainer1.Panel2
  101. //
  102. this.splitContainer1.Panel2.Controls.Add(this.textBox1);
  103. this.splitContainer1.Size = new System.Drawing.Size(644, 422);
  104. this.splitContainer1.SplitterDistance = 339;
  105. this.splitContainer1.TabIndex = 2;
  106. //
  107. // Form1
  108. //
  109. this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
  110. this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
  111. this.ClientSize = new System.Drawing.Size(644, 422);
  112. this.Controls.Add(this.splitContainer1);
  113. this.Name = "MyForm";
  114. this.Text = "Polar chart with selection";
  115. ((System.ComponentModel.ISupportInitialize)(this.chart1)).EndInit();
  116. this.splitContainer1.Panel1.ResumeLayout(false);
  117. this.splitContainer1.Panel2.ResumeLayout(false);
  118. this.splitContainer1.Panel2.PerformLayout();
  119. this.splitContainer1.ResumeLayout(false);
  120. this.ResumeLayout(false);
  121.  
  122. }
  123. #endregion
  124.  
  125. #region Constructor
  126.  
  127. public Form1()
  128. {
  129. InitializeComponent();
  130.  
  131. this.chart1.MouseDown += new MouseEventHandler(chart1_MouseDown);
  132. this.chart1.MouseMove += new MouseEventHandler(chart1_MouseMove);
  133. this.chart1.MouseUp += new MouseEventHandler(chart1_MouseUp);
  134. this.chart1.PostPaint += new EventHandler<ChartPaintEventArgs>(chart1_PostPaint);
  135. }
  136. #endregion
  137.  
  138. #region Chart Data Initialization
  139.  
  140. protected override void OnLoad(EventArgs e)
  141. {
  142. this.FillChart();
  143. }
  144.  
  145. private void FillChart()
  146. {
  147. var items = new[] { new PolarPoint(0, 10), new PolarPoint(30, 4), new PolarPoint(120, 2), new PolarPoint(185, 9), new PolarPoint(240, 7) };
  148.  
  149. this.chart1.Series.Clear();
  150. var seriesLines = this.chart1.Series.Add("Values");
  151. seriesLines.XValueMember = "Angle";
  152. seriesLines.YValueMembers = "Y";
  153. seriesLines.ChartType = SeriesChartType.Polar;
  154.  
  155. this.chart1.DataSource = items;
  156. }
  157. #endregion
  158.  
  159. #region Selection Management
  160.  
  161. Point? clickPoint;
  162. RectangleF? highlightRectAbs;
  163. RectangleInPolarPoints highlightRect;
  164.  
  165. void chart1_MouseDown(object sender, MouseEventArgs e)
  166. {
  167. this.highlightRectAbs = null;
  168. this.highlightRect = null;
  169.  
  170. // deselect all points
  171. var s = this.chart1.Series[0];
  172. for (int i = 0; i < s.Points.Count; i++)
  173. s.Points[i].Tag = false;
  174.  
  175. this.clickPoint = e.Location;
  176. }
  177.  
  178. void chart1_MouseMove(object sender, MouseEventArgs e)
  179. {
  180. if (this.clickPoint.HasValue && this.clickPoint != e.Location)
  181. {
  182. int width = Math.Abs(e.X - this.clickPoint.Value.X);
  183. int height = Math.Abs(e.Y - this.clickPoint.Value.Y);
  184. int x = Math.Min(e.X, this.clickPoint.Value.X);
  185. int y = Math.Min(e.Y, this.clickPoint.Value.Y);
  186.  
  187. this.highlightRectAbs = new RectangleF(x, y, width, height);
  188. this.highlightRect = null;
  189. if (this.highlightRectAbs.Value.Width != 0 && this.highlightRectAbs.Value.Height != 0)
  190. {
  191. this.chart1.Invalidate();
  192. }
  193. }
  194. }
  195.  
  196. void chart1_MouseUp(object sender, MouseEventArgs e)
  197. {
  198. this.clickPoint = null;
  199. this.chart1.Invalidate();
  200.  
  201. // here we have finished our selection
  202. this.SelectionFinished();
  203. }
  204.  
  205. void chart1_PostPaint(object sender, ChartPaintEventArgs e)
  206. {
  207. var area = e.ChartElement as ChartArea;
  208. if (area == null)
  209. return;
  210.  
  211. if (!this.highlightRectAbs.HasValue)
  212. return;
  213.  
  214. // get center and radius
  215. var minY = area.AxisY.ValueToPixelPosition(area.AxisY.Minimum);
  216. var maxX = area.AxisX.ValueToPixelPosition(area.AxisX.Maximum);
  217. var maxY = area.AxisY.ValueToPixelPosition(area.AxisY.Maximum);
  218. var radius = Math.Abs(maxY - minY);
  219. var centerX = maxX;
  220. var centerY = minY;
  221.  
  222. if (this.highlightRect == null)
  223. this.highlightRect = GetRectangleInPolarPoints(this.highlightRectAbs.Value, area, centerX, centerY, radius);
  224. this.highlightRectAbs = GetRectangleF(this.highlightRect, area, centerX, centerY, radius);
  225.  
  226. using (var brush = new SolidBrush(Color.FromArgb(15, Color.Black)))
  227. {
  228. var cg = e.ChartGraphics;
  229. cg.Graphics.FillRectangle(brush, this.highlightRectAbs.Value);
  230. cg.Graphics.DrawRectangle(Pens.Red, this.highlightRectAbs.Value.X, this.highlightRectAbs.Value.Y,
  231. this.highlightRectAbs.Value.Width, this.highlightRectAbs.Value.Height);
  232.  
  233. var s = e.Chart.Series[0];
  234. for (int i = 0; i < s.Points.Count; i++)
  235. {
  236. var point = s.Points[i];
  237.  
  238. var pt = GetCoordsOfPoint(point.XValue, point.YValues[0], area, centerX, centerY, radius);
  239.  
  240. // highlights the points if they're into the selection
  241. if (this.highlightRectAbs.Value.Contains(pt))
  242. {
  243. cg.Graphics.FillEllipse(Brushes.GreenYellow, pt.X - 5, pt.Y - 5, 10, 10);
  244. point.Tag = true;
  245. }
  246. else
  247. {
  248. point.Tag = false;
  249. }
  250. }
  251. }
  252.  
  253. }
  254.  
  255. private void SelectionFinished()
  256. {
  257. this.textBox1.Text = "Selection:" + Environment.NewLine;
  258. var s = this.chart1.Series[0];
  259. for (int i = 0; i < s.Points.Count; i++)
  260. {
  261. var point = s.Points[i];
  262. if (point.Tag is bool && (bool)point.Tag == true)
  263. this.textBox1.AppendText(string.Format("Angle = {0,6:N2}, Y = {1,6:N2}rn", point.XValue, point.YValues[0]));
  264. }
  265. }
  266.  
  267. #endregion
  268.  
  269. #region Helper Methods
  270.  
  271. static PointF GetCoordsOfPoint(PolarPoint polPt, ChartArea area, double centerX, double centerY, double radius)
  272. {
  273. return GetCoordsOfPoint(polPt.Angle, polPt.Y, area, centerX, centerY, radius);
  274. }
  275.  
  276. static PointF GetCoordsOfPoint(double angle, double yVal, ChartArea area, double centerX, double centerY, double radius)
  277. {
  278. double xRatio = 360.0 / Math.Abs(area.AxisX.Maximum - area.AxisX.Minimum);
  279. double radAngle = (-(angle * xRatio + area.AxisX.Crossing) - 270) * Math.PI / 180;
  280. double yRadius = Scale(yVal, area.AxisY.Minimum, area.AxisY.Maximum, 0, radius);
  281.  
  282. double h = Math.Sin(radAngle);
  283. double w = Math.Cos(radAngle);
  284.  
  285. return new PointF((float)(centerX + w * yRadius), (float)(centerY - h * yRadius));
  286. }
  287.  
  288. static PolarPoint GetPolarPointFromCoords(double x, double y, ChartArea area, double centerX, double centerY, double radius)
  289. {
  290. double xRatio = 360.0 / Math.Abs(area.AxisX.Maximum - area.AxisX.Minimum);
  291.  
  292. var xComp = x - centerX;
  293. var yComp = centerY - y;
  294.  
  295. var hypotenuseLength = Math.Sqrt(xComp * xComp + yComp * yComp);
  296. var angle = GetZero360Angle(-(Math.Atan2(yComp, xComp) * 180 / Math.PI) - 270);
  297.  
  298. //angle = Scale(angle, 0, 360, area.AxisX.Minimum, area.AxisX.Maximum);
  299. angle = (angle - area.AxisX.Crossing) / xRatio;
  300.  
  301. return new PolarPoint(angle , Scale(hypotenuseLength, 0, radius, area.AxisY.Minimum, area.AxisY.Maximum));
  302. }
  303.  
  304. static RectangleInPolarPoints GetRectangleInPolarPoints(RectangleF rect, ChartArea area, double centerX, double centerY, double radius)
  305. {
  306. var topLeft = GetPolarPointFromCoords(rect.Left, rect.Top, area, centerX, centerY, radius);
  307. var bottomLeft = GetPolarPointFromCoords(rect.Left, rect.Bottom, area, centerX, centerY, radius);
  308. var topRight = GetPolarPointFromCoords(rect.Right, rect.Top, area, centerX, centerY, radius);
  309. var bottomRight = GetPolarPointFromCoords(rect.Right, rect.Bottom, area, centerX, centerY, radius);
  310. return new RectangleInPolarPoints(topLeft, bottomLeft, topRight, bottomRight);
  311. }
  312.  
  313. static RectangleF GetRectangleF(RectangleInPolarPoints recPolar, ChartArea area, double centerX, double centerY, double radius)
  314. {
  315. var topLeftPt = GetCoordsOfPoint(recPolar.TopLeft, area, centerX, centerY, radius);
  316. var bottomLeftPt = GetCoordsOfPoint(recPolar.BottomLeft, area, centerX, centerY, radius);
  317. var topRightPt = GetCoordsOfPoint(recPolar.TopRight, area, centerX, centerY, radius);
  318.  
  319. var width = (float)(topRightPt.X - topLeftPt.X);
  320. var height = (float)(bottomLeftPt.Y - topLeftPt.Y);
  321.  
  322. return new RectangleF(topLeftPt, new SizeF(width, height));
  323. }
  324.  
  325. static double GetZero360Angle(double angle)
  326. {
  327. while (angle < 0)
  328. angle += 360;
  329. while (angle > 360)
  330. angle -= 360;
  331. return angle;
  332. }
  333.  
  334.  
  335. static double Scale(double oldScaleVal, double oldScaleMin, double oldScaleMax, double newScaleMin, double newScaleMax)
  336. {
  337. return newScaleMin + (oldScaleVal - oldScaleMin) / (oldScaleMax - oldScaleMin) * (newScaleMax - newScaleMin);
  338. }
  339.  
  340. #endregion
  341. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement