using Microsoft.VisualBasic;
|
using System;
|
using System.Collections.Generic;
|
using System.ComponentModel;
|
using System.Data;
|
using System.Drawing;
|
using System.Linq;
|
using System.Text;
|
using System.Threading.Tasks;
|
using System.Windows.Forms;
|
|
namespace DPumpHydr.WinFrmUI.Volute
|
{
|
public partial class ChartSectArea : UserControl
|
{
|
public ChartSectArea()
|
{
|
|
if (_allSection == null)
|
{
|
Section sect0 = new Section() { SectIndex = 0, Name = "0", Area = 0 };
|
Section sect1 = new Section() { SectIndex = 1, Name = "1", Area = 0 };
|
Section sect2 = new Section() { SectIndex = 2, Name = "2", Area = 0 };
|
Section sect3 = new Section() { SectIndex = 3, Name = "3", Area = 0 };
|
Section sect4 = new Section() { SectIndex = 4, Name = "4", Area = 0 };
|
Section sect5 = new Section() { SectIndex = 5, Name = "5", Area = 0 };
|
Section sect6 = new Section() { SectIndex = 6, Name = "6", Area = 0 };
|
Section sect7 = new Section() { SectIndex = 7, Name = "7", Area = 0 };
|
Section sect8 = new Section() { SectIndex = 8, Name = "8", Area = 0 };
|
_allSection = new List<Section> { sect0, sect1, sect2, sect3, sect4, sect5, sect6, sect7, sect8 };
|
}
|
|
}
|
public class Section
|
{
|
public int SectIndex { get;set; }
|
public string Name { get; set; }
|
public double Area { get; set; }
|
}
|
class AreaAxisRange
|
{
|
public double CoordMax { get; set; }//坐标上最大值
|
public double CoordMin { get; set; }//坐标上最小值
|
|
}
|
internal float CalcAreaPixelPt(double area)
|
{
|
var areaMaxValue = (from x in _allSection select x.Area).Max();
|
var areaMinValue = (from x in _allSection select x.Area).Min();
|
_areaAxisRange.CoordMin = Math.Ceiling(areaMinValue / 2);
|
_areaAxisRange.CoordMax = Math.Ceiling(areaMaxValue * 1.4);
|
var y = this._diagram_padding_top + this._diagram_padding_top + (_areaAxisRange.CoordMax - area) * (this._diagram_height - _diagram_padding_top - _diagram_padding_bottom) /(_areaAxisRange.CoordMax - _areaAxisRange.CoordMin);
|
|
return Convert.ToSingle( y );
|
}
|
public void RefreshControl()
|
{
|
_selectedPointIndex = -1;
|
this.Invalidate();
|
this.Refresh();
|
}
|
List<Section> _allSection;
|
int _current_section = -1;
|
public void SetBindingData(ViewModel.SectionShapePara para)
|
{
|
_allSection[para.Index].Area = para.SectionArea;
|
_current_section = para.Index;
|
this.Invalidate();
|
this.Refresh();
|
}
|
public void SetBindingData( List<double> sections)
|
{
|
|
if(_selectedPointIndex != -1)
|
{
|
_allSection[_selectedPointIndex].Area = sections[_selectedPointIndex];
|
}
|
else
|
{
|
int i = 0;
|
foreach (var allSection in _allSection)
|
{
|
allSection.Area = sections[i];
|
i++;
|
}
|
}
|
this.Invalidate();
|
this.Refresh();
|
}
|
public List<double> GetBindingData()
|
{
|
List<double> sections = new List<double> ();
|
foreach (var allSection in _allSection)
|
{
|
sections.Add(allSection.Area);
|
}
|
return sections;
|
}
|
AreaAxisRange _areaAxisRange = new AreaAxisRange();
|
/// <summary>
|
///
|
/// </summary>
|
/// <param name="e"></param>
|
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 - 10;
|
|
_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;
|
|
|
Graphics g = e.Graphics;
|
if (_allSection.Any(sect => sect.Area == 0))
|
{
|
return;
|
}
|
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 = 30;
|
|
float _diagram_padding_left = 5;
|
float _diagram_padding_right = 5;
|
float _diagram_padding_top = 2 ;
|
float _diagram_padding_bottom = 2 ;
|
|
Color _tickmarkColorX = Color.Blue;//主刻度
|
float _tickmarkLengthX = 5;
|
|
private void DrawAxisX(Graphics g)
|
{
|
StringFormat sf = new StringFormat();
|
sf.Alignment = StringAlignment.Center;
|
sf.LineAlignment = StringAlignment.Near;
|
|
var sect_count = _allSection.Count ;
|
float space_width = (this._diagram_width - 20 - _diagram_padding_left - _diagram_padding_right) / (sect_count - 2);
|
|
//刻度 tickmark
|
using (SolidBrush brushText = new SolidBrush(Color.Red))
|
using (Font fontText = new Font("Courier New", 11))
|
using (Pen penAxisBase = new Pen(_tickmarkColorX, 2f))
|
{
|
for (int i = 1; i < sect_count; i++)
|
{
|
var sect = _allSection[i];
|
var x = this._diagram_leftBottomPoint.X + _diagram_padding_left +( i - 1 )* space_width;
|
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 + _tickmarkLengthX + 5), 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)
|
{
|
StringFormat sf = new StringFormat();
|
sf.Alignment = StringAlignment.Center;
|
sf.LineAlignment = StringAlignment.Near;
|
var max = ((int)(Math.Ceiling(_allSection.Max(sect => sect.Area) * 1.1) / 10) + 1) * 10;
|
var min =(int)(Math.Ceiling(_allSection.Min(sect => sect.Area) / 2) / 10) * 10;
|
var median = (max + min) / 2;
|
var max_scale = CalcAreaPixelPt(max);
|
var min_scale = CalcAreaPixelPt(min);
|
var median_scale = (max_scale + min_scale) / 2;
|
using (SolidBrush brushText = new SolidBrush(Color.Red))
|
using (Font fontText = new Font("Courier New", 9))
|
using (Pen penCurve = new Pen(Color.Blue, 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, median_scale), new PointF(this._diagram_leftBottomPoint.X - _tickmarkLengthX, median_scale));
|
g.DrawLine(penCurve, _diagram_leftBottomPoint, _diagram_leftTopPoint );
|
|
// 添加y轴末尾的箭头
|
float arrowLength = 10f; // 箭头的长度
|
float arrowWidth = 5f; // 箭头的宽度
|
PointF arrowBase = new PointF(this._diagram_leftBottomPoint.X, _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), new PointF(arrowBase.X, arrowBase.Y )); // 绘制箭头的左翼
|
g.DrawLine(penCurve, new PointF(arrowTip.X + arrowWidth, arrowTip.Y), new PointF(arrowBase.X - 1, arrowBase.Y )); // 绘制箭头的右翼
|
string unit_text = "mm³";
|
PointF unit_position = new PointF(_diagram_leftBottomPoint.X - 20, _diagram_leftTopPoint.Y - 10);
|
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, median_scale - 8);
|
g.DrawString(unit_text, fontText, brushText, unit_position, sf);
|
g.DrawString(max.ToString(), fontText, brushText, max_scale_position, sf);
|
g.DrawString(min.ToString(), fontText, brushText, min_scale_position, sf);
|
g.DrawString(median.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, median_scale), new PointF(this._diagram_leftBottomPoint.X + width, median_scale));
|
}
|
}
|
List<PointF> _lines = new List<PointF>();
|
int _selectedPointIndex = -1;
|
private void DrawDiagram(Graphics g)
|
{
|
using (Pen penCurve = new Pen(Color.Red, 2f))
|
using (SolidBrush penBrush = new SolidBrush(Color.Black))
|
{
|
var sect_count = _allSection.Count;
|
float space_width = (this._diagram_width - 20 - _diagram_padding_left - _diagram_padding_right) / (sect_count - 2);
|
List<PointF> lines = new List<PointF>();
|
PointF pt = new PointF();
|
for (int i = 0; i < sect_count; i++)
|
{
|
if (i == 0)
|
{
|
pt.X = 0;
|
pt.Y = 0;
|
lines.Add(pt);
|
continue;
|
}
|
var sect = _allSection[i];
|
pt.X = this._diagram_leftBottomPoint.X + _diagram_padding_left + (i - 1) * space_width;
|
pt.Y = this.CalcAreaPixelPt(sect.Area);
|
if(_selectedPointIndex != -1)
|
{
|
if(i == _selectedPointIndex)
|
{
|
g.FillEllipse(new SolidBrush(Color.Blue), pt.X - 4f, pt.Y - 4f, 8, 8);
|
lines.Add(pt);
|
continue;
|
}
|
else
|
{
|
g.FillEllipse(new SolidBrush(Color.LightGray), pt.X - 4f, pt.Y - 4f, 8, 8);
|
lines.Add(pt);
|
}
|
}
|
else
|
{
|
g.FillEllipse(penBrush, pt.X - 4f, pt.Y - 4f, 8, 8);
|
lines.Add(pt);
|
}
|
}
|
List<PointF> linesWithoutFirst = new List<PointF>(lines.Skip(1).ToList());
|
|
g.DrawCurve(penCurve, linesWithoutFirst.ToArray());
|
_lines = lines;
|
}
|
//
|
}
|
public int Judgment_point(double X , double Y)
|
{
|
_selectedPointIndex = -1;
|
_selectedPointIndex += 1;
|
if(_current_section != -1)
|
{
|
if (X > _lines[_current_section].X - 5 && X < _lines[_current_section].X + 5 && Y > _lines[_current_section].Y - 5 && Y < _lines[_current_section].Y + 5)
|
{
|
_selectedPointIndex = _current_section;
|
this.Invalidate();
|
this.Refresh();
|
return _selectedPointIndex;
|
}
|
else
|
{
|
_selectedPointIndex = -1;
|
this.Invalidate();
|
this.Refresh();
|
return _selectedPointIndex ;
|
}
|
}
|
foreach (var line in _lines)
|
{
|
if (X>line.X - 5 && X <line.X + 5 && Y > line.Y -5 && Y < line.Y + 5)
|
{
|
this.Invalidate();
|
this.Refresh();
|
return _selectedPointIndex;
|
}
|
_selectedPointIndex++;
|
}
|
return _selectedPointIndex = -1;
|
}
|
}
|
}
|