Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- internal class PolarPoint
- {
- public double Angle { get; private set; }
- public double Y { get; private set; }
- public PolarPoint(double angle, double y)
- {
- this.Angle = angle;
- this.Y = y;
- }
- }
- internal class RectangleInPolarPoints
- {
- public PolarPoint TopLeft { get; private set; }
- public PolarPoint TopRight { get; private set; }
- public PolarPoint BottomLeft { get; private set; }
- public PolarPoint BottonRight { get; private set; }
- public RectangleInPolarPoints(PolarPoint topLeft, PolarPoint bottomLeft, PolarPoint topRight, PolarPoint bottomRight)
- {
- this.TopLeft = topLeft;
- this.TopRight = topRight;
- this.BottomLeft = bottomLeft;
- this.BottonRight = bottomRight;
- }
- }
- internal struct PointD
- {
- public double X { get; private set; }
- public double Y { get; private set; }
- public PointD(double x, double y)
- : this()
- {
- this.X = x;
- this.Y = y;
- }
- }
- #endregion
- #region Designer code
- private System.Windows.Forms.DataVisualization.Charting.Chart chart1;
- private System.Windows.Forms.TextBox textBox1;
- private System.Windows.Forms.SplitContainer splitContainer1;
- private void InitializeComponent()
- {
- System.Windows.Forms.DataVisualization.Charting.ChartArea chartArea1 = new System.Windows.Forms.DataVisualization.Charting.ChartArea();
- System.Windows.Forms.DataVisualization.Charting.Legend legend1 = new System.Windows.Forms.DataVisualization.Charting.Legend();
- System.Windows.Forms.DataVisualization.Charting.Series series1 = new System.Windows.Forms.DataVisualization.Charting.Series();
- this.chart1 = new System.Windows.Forms.DataVisualization.Charting.Chart();
- this.textBox1 = new System.Windows.Forms.TextBox();
- this.splitContainer1 = new System.Windows.Forms.SplitContainer();
- ((System.ComponentModel.ISupportInitialize)(this.chart1)).BeginInit();
- this.splitContainer1.Panel1.SuspendLayout();
- this.splitContainer1.Panel2.SuspendLayout();
- this.splitContainer1.SuspendLayout();
- this.SuspendLayout();
- //
- // chart1
- //
- chartArea1.Name = "ChartArea1";
- this.chart1.ChartAreas.Add(chartArea1);
- this.chart1.Dock = System.Windows.Forms.DockStyle.Fill;
- legend1.Name = "Legend1";
- this.chart1.Legends.Add(legend1);
- this.chart1.Location = new System.Drawing.Point(0, 0);
- this.chart1.Name = "chart1";
- series1.ChartArea = "ChartArea1";
- series1.Legend = "Legend1";
- series1.Name = "Series1";
- this.chart1.Series.Add(series1);
- this.chart1.Size = new System.Drawing.Size(644, 339);
- this.chart1.TabIndex = 0;
- this.chart1.Text = "chart1";
- //
- // textBox1
- //
- this.textBox1.Dock = System.Windows.Forms.DockStyle.Fill;
- this.textBox1.Font = new System.Drawing.Font("Courier New", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
- this.textBox1.Location = new System.Drawing.Point(0, 0);
- this.textBox1.Multiline = true;
- this.textBox1.Name = "textBox1";
- this.textBox1.ScrollBars = System.Windows.Forms.ScrollBars.Vertical;
- this.textBox1.Size = new System.Drawing.Size(644, 79);
- this.textBox1.TabIndex = 1;
- //
- // splitContainer1
- //
- this.splitContainer1.Dock = System.Windows.Forms.DockStyle.Fill;
- this.splitContainer1.Location = new System.Drawing.Point(0, 0);
- this.splitContainer1.Name = "splitContainer1";
- this.splitContainer1.Orientation = System.Windows.Forms.Orientation.Horizontal;
- //
- // splitContainer1.Panel1
- //
- this.splitContainer1.Panel1.Controls.Add(this.chart1);
- //
- // splitContainer1.Panel2
- //
- this.splitContainer1.Panel2.Controls.Add(this.textBox1);
- this.splitContainer1.Size = new System.Drawing.Size(644, 422);
- this.splitContainer1.SplitterDistance = 339;
- this.splitContainer1.TabIndex = 2;
- //
- // Form1
- //
- this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
- this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
- this.ClientSize = new System.Drawing.Size(644, 422);
- this.Controls.Add(this.splitContainer1);
- this.Name = "MyForm";
- this.Text = "Polar chart with selection";
- ((System.ComponentModel.ISupportInitialize)(this.chart1)).EndInit();
- this.splitContainer1.Panel1.ResumeLayout(false);
- this.splitContainer1.Panel2.ResumeLayout(false);
- this.splitContainer1.Panel2.PerformLayout();
- this.splitContainer1.ResumeLayout(false);
- this.ResumeLayout(false);
- }
- #endregion
- #region Constructor
- public Form1()
- {
- InitializeComponent();
- this.chart1.MouseDown += new MouseEventHandler(chart1_MouseDown);
- this.chart1.MouseMove += new MouseEventHandler(chart1_MouseMove);
- this.chart1.MouseUp += new MouseEventHandler(chart1_MouseUp);
- this.chart1.PostPaint += new EventHandler<ChartPaintEventArgs>(chart1_PostPaint);
- }
- #endregion
- #region Chart Data Initialization
- protected override void OnLoad(EventArgs e)
- {
- this.FillChart();
- }
- private void FillChart()
- {
- var items = new[] { new PolarPoint(0, 10), new PolarPoint(30, 4), new PolarPoint(120, 2), new PolarPoint(185, 9), new PolarPoint(240, 7) };
- this.chart1.Series.Clear();
- var seriesLines = this.chart1.Series.Add("Values");
- seriesLines.XValueMember = "Angle";
- seriesLines.YValueMembers = "Y";
- seriesLines.ChartType = SeriesChartType.Polar;
- this.chart1.DataSource = items;
- }
- #endregion
- #region Selection Management
- Point? clickPoint;
- RectangleF? highlightRectAbs;
- RectangleInPolarPoints highlightRect;
- void chart1_MouseDown(object sender, MouseEventArgs e)
- {
- this.highlightRectAbs = null;
- this.highlightRect = null;
- // deselect all points
- var s = this.chart1.Series[0];
- for (int i = 0; i < s.Points.Count; i++)
- s.Points[i].Tag = false;
- this.clickPoint = e.Location;
- }
- void chart1_MouseMove(object sender, MouseEventArgs e)
- {
- if (this.clickPoint.HasValue && this.clickPoint != e.Location)
- {
- int width = Math.Abs(e.X - this.clickPoint.Value.X);
- int height = Math.Abs(e.Y - this.clickPoint.Value.Y);
- int x = Math.Min(e.X, this.clickPoint.Value.X);
- int y = Math.Min(e.Y, this.clickPoint.Value.Y);
- this.highlightRectAbs = new RectangleF(x, y, width, height);
- this.highlightRect = null;
- if (this.highlightRectAbs.Value.Width != 0 && this.highlightRectAbs.Value.Height != 0)
- {
- this.chart1.Invalidate();
- }
- }
- }
- void chart1_MouseUp(object sender, MouseEventArgs e)
- {
- this.clickPoint = null;
- this.chart1.Invalidate();
- // here we have finished our selection
- this.SelectionFinished();
- }
- void chart1_PostPaint(object sender, ChartPaintEventArgs e)
- {
- var area = e.ChartElement as ChartArea;
- if (area == null)
- return;
- if (!this.highlightRectAbs.HasValue)
- return;
- // get center and radius
- var minY = area.AxisY.ValueToPixelPosition(area.AxisY.Minimum);
- var maxX = area.AxisX.ValueToPixelPosition(area.AxisX.Maximum);
- var maxY = area.AxisY.ValueToPixelPosition(area.AxisY.Maximum);
- var radius = Math.Abs(maxY - minY);
- var centerX = maxX;
- var centerY = minY;
- if (this.highlightRect == null)
- this.highlightRect = GetRectangleInPolarPoints(this.highlightRectAbs.Value, area, centerX, centerY, radius);
- this.highlightRectAbs = GetRectangleF(this.highlightRect, area, centerX, centerY, radius);
- using (var brush = new SolidBrush(Color.FromArgb(15, Color.Black)))
- {
- var cg = e.ChartGraphics;
- cg.Graphics.FillRectangle(brush, this.highlightRectAbs.Value);
- cg.Graphics.DrawRectangle(Pens.Red, this.highlightRectAbs.Value.X, this.highlightRectAbs.Value.Y,
- this.highlightRectAbs.Value.Width, this.highlightRectAbs.Value.Height);
- var s = e.Chart.Series[0];
- for (int i = 0; i < s.Points.Count; i++)
- {
- var point = s.Points[i];
- var pt = GetCoordsOfPoint(point.XValue, point.YValues[0], area, centerX, centerY, radius);
- // highlights the points if they're into the selection
- if (this.highlightRectAbs.Value.Contains(pt))
- {
- cg.Graphics.FillEllipse(Brushes.GreenYellow, pt.X - 5, pt.Y - 5, 10, 10);
- point.Tag = true;
- }
- else
- {
- point.Tag = false;
- }
- }
- }
- }
- private void SelectionFinished()
- {
- this.textBox1.Text = "Selection:" + Environment.NewLine;
- var s = this.chart1.Series[0];
- for (int i = 0; i < s.Points.Count; i++)
- {
- var point = s.Points[i];
- if (point.Tag is bool && (bool)point.Tag == true)
- this.textBox1.AppendText(string.Format("Angle = {0,6:N2}, Y = {1,6:N2}rn", point.XValue, point.YValues[0]));
- }
- }
- #endregion
- #region Helper Methods
- static PointF GetCoordsOfPoint(PolarPoint polPt, ChartArea area, double centerX, double centerY, double radius)
- {
- return GetCoordsOfPoint(polPt.Angle, polPt.Y, area, centerX, centerY, radius);
- }
- static PointF GetCoordsOfPoint(double angle, double yVal, ChartArea area, double centerX, double centerY, double radius)
- {
- double xRatio = 360.0 / Math.Abs(area.AxisX.Maximum - area.AxisX.Minimum);
- double radAngle = (-(angle * xRatio + area.AxisX.Crossing) - 270) * Math.PI / 180;
- double yRadius = Scale(yVal, area.AxisY.Minimum, area.AxisY.Maximum, 0, radius);
- double h = Math.Sin(radAngle);
- double w = Math.Cos(radAngle);
- return new PointF((float)(centerX + w * yRadius), (float)(centerY - h * yRadius));
- }
- static PolarPoint GetPolarPointFromCoords(double x, double y, ChartArea area, double centerX, double centerY, double radius)
- {
- double xRatio = 360.0 / Math.Abs(area.AxisX.Maximum - area.AxisX.Minimum);
- var xComp = x - centerX;
- var yComp = centerY - y;
- var hypotenuseLength = Math.Sqrt(xComp * xComp + yComp * yComp);
- var angle = GetZero360Angle(-(Math.Atan2(yComp, xComp) * 180 / Math.PI) - 270);
- //angle = Scale(angle, 0, 360, area.AxisX.Minimum, area.AxisX.Maximum);
- angle = (angle - area.AxisX.Crossing) / xRatio;
- return new PolarPoint(angle , Scale(hypotenuseLength, 0, radius, area.AxisY.Minimum, area.AxisY.Maximum));
- }
- static RectangleInPolarPoints GetRectangleInPolarPoints(RectangleF rect, ChartArea area, double centerX, double centerY, double radius)
- {
- var topLeft = GetPolarPointFromCoords(rect.Left, rect.Top, area, centerX, centerY, radius);
- var bottomLeft = GetPolarPointFromCoords(rect.Left, rect.Bottom, area, centerX, centerY, radius);
- var topRight = GetPolarPointFromCoords(rect.Right, rect.Top, area, centerX, centerY, radius);
- var bottomRight = GetPolarPointFromCoords(rect.Right, rect.Bottom, area, centerX, centerY, radius);
- return new RectangleInPolarPoints(topLeft, bottomLeft, topRight, bottomRight);
- }
- static RectangleF GetRectangleF(RectangleInPolarPoints recPolar, ChartArea area, double centerX, double centerY, double radius)
- {
- var topLeftPt = GetCoordsOfPoint(recPolar.TopLeft, area, centerX, centerY, radius);
- var bottomLeftPt = GetCoordsOfPoint(recPolar.BottomLeft, area, centerX, centerY, radius);
- var topRightPt = GetCoordsOfPoint(recPolar.TopRight, area, centerX, centerY, radius);
- var width = (float)(topRightPt.X - topLeftPt.X);
- var height = (float)(bottomLeftPt.Y - topLeftPt.Y);
- return new RectangleF(topLeftPt, new SizeF(width, height));
- }
- static double GetZero360Angle(double angle)
- {
- while (angle < 0)
- angle += 360;
- while (angle > 360)
- angle -= 360;
- return angle;
- }
- static double Scale(double oldScaleVal, double oldScaleMin, double oldScaleMax, double newScaleMin, double newScaleMax)
- {
- return newScaleMin + (oldScaleVal - oldScaleMin) / (oldScaleMax - oldScaleMin) * (newScaleMax - newScaleMin);
- }
- #endregion
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement