using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; namespace DPumpHydr.OpenFwUI.Volute { public partial class ChartSectArea : UserControl { public ChartSectArea() { this.KeyDown += chart_KeyDown; this.MouseClick += chart_MouseClick; if (_allSection == null) { SectionInfo sect0 = new SectionInfo() { SectIndex = 0, Name = "0", Area = 0, IsVisible = false }; SectionInfo sect1 = new SectionInfo() { SectIndex = 1, Name = "1", Area = 0, IsVisible = true }; SectionInfo sect2 = new SectionInfo() { SectIndex = 2, Name = "2", Area = 0, IsVisible = true }; SectionInfo sect3 = new SectionInfo() { SectIndex = 3, Name = "3", Area = 0, IsVisible = true }; SectionInfo sect4 = new SectionInfo() { SectIndex = 4, Name = "4", Area = 0, IsVisible = true }; SectionInfo sect5 = new SectionInfo() { SectIndex = 5, Name = "5", Area = 0, IsVisible = true }; SectionInfo sect6 = new SectionInfo() { SectIndex = 6, Name = "6", Area = 0, IsVisible = true }; SectionInfo sect7 = new SectionInfo() { SectIndex = 7, Name = "7", Area = 0, IsVisible = true }; SectionInfo sect8 = new SectionInfo() { SectIndex = 8, Name = "8", Area = 0, IsVisible = true }; SectionInfo sect9 = new SectionInfo() { SectIndex = 9, Name = "9", Area = 0, IsVisible = false }; SectionInfo sect10 = new SectionInfo() { SectIndex = 10, Name = "10", Area = 0, IsVisible = false }; SectionInfo sect99 = new SectionInfo() { SectIndex = 99, Name = "出口", Area = 0, IsVisible = false }; _allSection = new List { sect0, sect1, sect2, sect3, sect4, sect5, sect6, sect7, sect8, sect9, sect10, sect99 }; } } public class SectionInfo { public int SectIndex { get; set; } public string Name { get; set; } public double Area { get; set; } public bool IsVisible { get; set; } public float PosiX { get; set; } public float PosiY { get; set; } public bool IsSelected { get; set; } } class AreaAxisRange { public List AxisValues { get; set; } public double CoordMax { get { return AxisValues.Last(); } }//坐标上最大值 public double CoordMin { get { return AxisValues.First(); } }//坐标上最小值 } private int _area_space_down = 2; private int _area_space_up = 2; private float CalcAreaPixelPt(double area) { var y = this._diagram_margin_top + this._diagram_padding_top + _area_space_up + (_areaAxisRange.CoordMax - area) * (this._diagram_height - this._diagram_padding_top - this._diagram_padding_bottom - this._area_space_up-this._area_space_down) / (_areaAxisRange.CoordMax - _areaAxisRange.CoordMin); return Convert.ToSingle(y); } public void RefreshControl() { this.Invalidate(); this.Refresh(); } List _allSection; public void SetArea18(DPumpHydr.OpenFwUI.Volute.SectionShapePara para) { _allSection[para.Index].Area = para.SectionArea; CalcCoordRange(); this.Invalidate(); } public void SetArea18(List areas) { for (int i = 0; i < areas.Count; i++) { _allSection[i].Area = areas[i]; } CalcCoordRange(); this.Invalidate(); } public void SetArea9(double area) { _allSection[9].Area = area; _allSection[9].IsVisible = true; CalcCoordRange(); this.Invalidate(); } public void SetArea10(double area) { _allSection[10].Area = area; _allSection[10].IsVisible = true; CalcCoordRange(); this.Invalidate(); } public void SetAreaOutletDia(double dia) { _allSection.Last().Area = dia * dia * 3.1415 / 4; _allSection.Last().IsVisible = true; CalcCoordRange(); this.Invalidate(); } private void CalcCoordRange() { var areas = _allSection.Where(x => x.Area > 0 && x.IsVisible).Select(x => x.Area); if (areas.Count() < 3) return; _areaAxisRange = new AreaAxisRange(); _areaAxisRange.AxisValues = new List(); double real_area_max = ((int)(Math.Ceiling(areas.Max() * 1.1) / 100) + 1) * 100; double real_area_min = (int)(Math.Ceiling(areas.Min() / 2) / 10) * 10; _areaAxisRange.AxisValues.Add(real_area_min); _areaAxisRange.AxisValues.Add((real_area_min + real_area_max) / 2); _areaAxisRange.AxisValues.Add(real_area_max); } AreaAxisRange _areaAxisRange = null; float _spaceWidthX = 0; float _crawlDistPixel = 0;//拖动时移动像素位置 double _crawlDistArea = 0;//拖动时移动面积 /// /// /// /// protected override void OnPaint(PaintEventArgs e) { base.OnPaint(e); _diagram_width = this.Width - this._diagram_margin_left - this._diagram_margin_right; _diagram_height = this.Height - this._diagram_margin_top - this._diagram_margin_bottom; if (_diagram_height <= 0 || _diagram_width <= 10) { return; } _diagram_leftTopPoint.X = this._diagram_margin_left; _diagram_leftTopPoint.Y = this._diagram_margin_top ; _diagram_leftBottomPoint.X = this._diagram_margin_left; _diagram_leftBottomPoint.Y = this._diagram_margin_top + _diagram_height; _diagram_rightTopPoint.X = this._diagram_margin_left + _diagram_width; _diagram_rightTopPoint.Y = this._diagram_margin_top; _diagram_rightBottomPoint.X = this._diagram_margin_left + _diagram_width; _diagram_rightBottomPoint.Y = this._diagram_margin_top + _diagram_height; int visile_count = _allSection.Count(x => x.Area > 0 && x.IsVisible); if (visile_count <= 1) return; _spaceWidthX = (this._diagram_width - 20 - _diagram_padding_left - _diagram_padding_right) / (visile_count - 1); _crawlDistPixel = (this._diagram_height - this._diagram_padding_top - this._diagram_padding_bottom - this._area_space_up - this._area_space_down) / 50; _crawlDistArea = (_areaAxisRange.CoordMax - _areaAxisRange.CoordMin) / 50; for (int i = 1; i < _allSection.Count; i++) { var sect = _allSection[i]; if (sect.Area <= 0 || sect.IsVisible == false) continue; sect.PosiX = this._diagram_leftBottomPoint.X + _diagram_padding_left + (i - 1) * _spaceWidthX; sect.PosiY = this.CalcAreaPixelPt(sect.Area); } if (_allSection.Count(sect => sect.Area > 0) > 4) { Graphics g = e.Graphics; DrawAxisX(g); DrawAxisY(g); DrawDiagram(g); } } PointF _diagram_leftTopPoint = new PointF(); PointF _diagram_leftBottomPoint = new PointF(); PointF _diagram_rightTopPoint = new PointF(); PointF _diagram_rightBottomPoint = new PointF(); float _diagram_width = 0; float _diagram_height = 0; float _diagram_margin_left = 60; float _diagram_margin_right = 40; float _diagram_margin_top = 20; float _diagram_margin_bottom = 16; float _diagram_padding_left = 0; float _diagram_padding_right = 0; float _diagram_padding_top = 0; float _diagram_padding_bottom = 0; Color _tickmarkColorX = Color.Black;//主刻度 float _tickmarkLengthX = 5; private void DrawAxisX(Graphics g) { StringFormat sf = new StringFormat(); sf.Alignment = StringAlignment.Center; sf.LineAlignment = StringAlignment.Near; //刻度 tickmark using (SolidBrush brushText = new SolidBrush(Color.Black)) using (Font fontText = new Font("Courier New", 10)) using (Pen penAxisBase = new Pen(_tickmarkColorX, 2f)) { for (int i = 1; i < _allSection.Count; i++) { var sect = _allSection[i]; if(sect.Area<=0 || sect.IsVisible==false) continue; var x = this._diagram_leftBottomPoint.X + _diagram_padding_left + (i - 1) * _spaceWidthX; g.DrawLine(penAxisBase, new PointF(x, _diagram_leftBottomPoint.Y), new PointF(x, _diagram_leftBottomPoint.Y - _tickmarkLengthX)); g.DrawString(sect.Name, fontText, brushText, new PointF(x, _diagram_leftBottomPoint.Y + 2), sf); } //基线 g.DrawLine(penAxisBase, _diagram_leftBottomPoint, _diagram_rightBottomPoint); // 添加箭头 float arrowLength = 10f; // 箭头的长度 float arrowWidth = 5f; // 箭头的宽度 PointF arrowBase = new PointF(_diagram_rightBottomPoint.X, _diagram_rightBottomPoint.Y); PointF arrowTip = new PointF(_diagram_rightBottomPoint.X - arrowLength, _diagram_rightBottomPoint.Y); g.DrawLine(penAxisBase, arrowBase, arrowTip); // 绘制箭头的主体 g.DrawLine(penAxisBase, new PointF(arrowTip.X, arrowTip.Y - arrowWidth), new PointF(arrowBase.X, arrowBase.Y)); // 绘制箭头的左翼 g.DrawLine(penAxisBase, new PointF(arrowTip.X, arrowTip.Y + arrowWidth), new PointF(arrowBase.X, arrowBase.Y)); // 绘制箭头的右翼 // 添加单位 m³ string unitText = "断面"; PointF unitPosition = new PointF(_diagram_rightBottomPoint.X - arrowLength + 30, _diagram_leftBottomPoint.Y - 5); g.DrawString(unitText, fontText, brushText, unitPosition, sf); } } private void DrawAxisY(Graphics g) { var min_scale = CalcAreaPixelPt(_areaAxisRange.AxisValues[0]); var meddle_scale = CalcAreaPixelPt(_areaAxisRange.AxisValues[1]); var max_scale = CalcAreaPixelPt(_areaAxisRange.AxisValues[2]); using (SolidBrush brushText = new SolidBrush(Color.Black)) using (Font fontText = new Font("Courier New", 9)) using (Pen penCurve = new Pen(Color.Black, 2f)) { g.DrawLine(penCurve, new PointF(this._diagram_leftBottomPoint.X, max_scale), new PointF(this._diagram_leftBottomPoint.X - _tickmarkLengthX, max_scale)); g.DrawLine(penCurve, new PointF(this._diagram_leftBottomPoint.X, min_scale), new PointF(this._diagram_leftBottomPoint.X - _tickmarkLengthX, min_scale)); g.DrawLine(penCurve, new PointF(this._diagram_leftBottomPoint.X, meddle_scale), new PointF(this._diagram_leftBottomPoint.X - _tickmarkLengthX, meddle_scale)); g.DrawLine(penCurve, _diagram_leftBottomPoint, _diagram_leftTopPoint); // 添加y轴末尾的箭头 float arrowLength = 14f; // 箭头的长度 //float arrowWidth = 5f; // 箭头的宽度 PointF arrowBase = new PointF(this._diagram_leftBottomPoint.X, this._diagram_leftTopPoint.Y); PointF arrowTip = new PointF(this._diagram_leftBottomPoint.X, this._diagram_leftTopPoint.Y - arrowLength); g.DrawLine(penCurve, arrowBase, arrowTip); // 绘制箭头的主体 //g.DrawLine(penCurve, new PointF(arrowTip.X - arrowWidth, arrowTip.Y-4), new PointF(arrowBase.X, arrowBase.Y)); // 绘制箭头的左翼 //g.DrawLine(penCurve, new PointF(arrowTip.X + arrowWidth, arrowTip.Y-4), new PointF(arrowBase.X - 1, arrowBase.Y)); // 绘制箭头的右翼 PointF unit_position = new PointF(_diagram_leftBottomPoint.X + 20, _diagram_leftTopPoint.Y - 15); PointF max_scale_position = new PointF(_diagram_leftBottomPoint.X - 25, max_scale - 8); PointF min_scale_position = new PointF(_diagram_leftBottomPoint.X - 25, min_scale - 8); PointF median_scale_position = new PointF(_diagram_leftBottomPoint.X - 25, meddle_scale - 8); StringFormat sf = new StringFormat(); sf.Alignment = StringAlignment.Center; sf.LineAlignment = StringAlignment.Near; string unit_text = "mm²"; g.DrawString(unit_text, fontText, brushText, unit_position, sf); g.DrawString(_areaAxisRange.AxisValues[2].ToString(), fontText, brushText, max_scale_position, sf); g.DrawString(_areaAxisRange.AxisValues[0].ToString(), fontText, brushText, min_scale_position, sf); g.DrawString(_areaAxisRange.AxisValues[1].ToString(), fontText, brushText, median_scale_position, sf); } using (Pen penCurve = new Pen(Color.Gray, 1f)) { penCurve.DashStyle = System.Drawing.Drawing2D.DashStyle.Dash; float width = this._diagram_width - _diagram_padding_left - _diagram_padding_right; g.DrawLine(penCurve, new PointF(this._diagram_leftBottomPoint.X, max_scale), new PointF(this._diagram_leftBottomPoint.X + width, max_scale)); g.DrawLine(penCurve, new PointF(this._diagram_leftBottomPoint.X, min_scale), new PointF(this._diagram_leftBottomPoint.X + width, min_scale)); g.DrawLine(penCurve, new PointF(this._diagram_leftBottomPoint.X, meddle_scale), new PointF(this._diagram_leftBottomPoint.X + width, meddle_scale)); } } private void DrawDiagram(Graphics g) { var sect_count = _allSection.Count; List curve_pts = new List(); for (int i = 1; i < sect_count; i++) { var sect = _allSection[i]; if (sect.Area <= 0 || sect.PosiX <= 0 || sect.PosiY <= 0) continue; curve_pts.Add(new PointF(sect.PosiX, sect.PosiY)); } using (Pen penCurve = new Pen(Color.Black, 2f)) g.DrawCurve(penCurve, curve_pts.ToArray()); var select_sect = _allSection.Find(x => x.IsSelected); if (select_sect == null) { using (SolidBrush penBrush = new SolidBrush(Color.Black)) { for (int i = 1; i < sect_count; i++) { var sect = _allSection[i]; if (sect.Area <= 0) continue; if (!sect.IsVisible) continue; g.FillEllipse(penBrush, sect.PosiX - 4f, sect.PosiY - 4f, 8, 8); } } } else { using (SolidBrush selBrush = new SolidBrush(Color.FromArgb(72, 61, 139))) using (SolidBrush unBrush = new SolidBrush(Color.FromArgb(135, 206, 250))) { for (int i = 1; i < sect_count; i++) { var sect = _allSection[i]; if (sect.Area <= 0) continue; if (!sect.IsVisible) continue; if (sect.IsSelected) g.FillEllipse(selBrush, sect.PosiX - 4f, sect.PosiY - 4f, 8, 8); else g.FillEllipse(unBrush, sect.PosiX - 4f, sect.PosiY - 4f, 8, 8); } } } } protected override bool ProcessDialogKey(Keys keyData) { if (keyData == Keys.Up || keyData == Keys.Down || keyData == Keys.Left || keyData == Keys.Right) { return false; } else { return base.ProcessDialogKey(keyData); } } public Action OnRefreshSingleSectArea = null; private void chart_KeyDown(object sender, System.Windows.Forms.KeyEventArgs e) { var select_sect = this._allSection.Find(x => x.IsSelected); if (select_sect == null) { return; } //var data = this.GetBindingData(); //if (data == null) //{ // return; //} //根据按键增加或减少Y值 if (e.KeyCode == Keys.Up) { select_sect.PosiY = select_sect.PosiY + _crawlDistPixel; // 增加Y值 select_sect.Area = select_sect.Area + _crawlDistArea; //this.SetArea18(data); //_bundle.Area[_selectedPointIndex] = data[_selectedPointIndex]; OnRefreshSingleSectArea.Invoke(select_sect.SectIndex, select_sect.Area); this.Invalidate(); } else if (e.KeyCode == Keys.Down) { select_sect.PosiY = select_sect.PosiY - _crawlDistPixel; // 增加Y值 select_sect.Area = select_sect.Area - _crawlDistArea; //chart.SetArea18(data); //_bundle.Area[_selectedPointIndex] = data[_selectedPointIndex]; OnRefreshSingleSectArea.Invoke(select_sect.SectIndex, select_sect.Area); this.Invalidate(); } } //int _sequence = 0; private void chart_MouseClick(object sender, MouseEventArgs e) { for (int i = 1; i <= 8; i++) { _allSection[i].IsSelected = false; } for (int i = 1; i <= 8; i++) { if (e.X > _allSection[i].PosiX - 5 && e.X < _allSection[i].PosiX + 5 && e.Y > _allSection[i].PosiY - 5 && e.Y < _allSection[i].PosiY + 5) { _allSection[i].IsSelected = true ; this.Invalidate(); this.Refresh(); break; } } } } }