using DevExpress.Utils;
|
using DevExpress.XtraCharts;
|
|
namespace Yw.WinFrmUI.Phart
|
{
|
/// <summary>
|
///
|
/// </summary>
|
public partial class UniversalEditChart : DevExpress.XtraEditors.XtraUserControl
|
{
|
public UniversalEditChart()
|
{
|
InitializeComponent();
|
InitialChart();
|
}
|
|
#region Private Variable
|
|
private XYDiagram _diagram;
|
private XYDiagramDefaultPane _default_pane;
|
private AxisX _axis_x;
|
private AxisY _axis_y;
|
|
private List<Yw.Geometry.Point2d> _point_pt_list;
|
private List<Yw.Geometry.Point2d> _line_pt_list;
|
|
private UniversalCoordinate _coordinate;
|
private bool _initial_data = false;
|
private bool _mouse_mode = false;//鼠标模式
|
|
#endregion Private Variable
|
|
#region Public Variable
|
|
/// <summary>
|
/// X轴标题
|
/// </summary>
|
public string AxisXTitle
|
{
|
get
|
{
|
return _axis_x.Title.Text;
|
}
|
set
|
{
|
_axis_x.Title.Text = value;
|
}
|
}
|
|
/// <summary>
|
/// Y轴标题
|
/// </summary>
|
public string AxisYTitle
|
{
|
get
|
{
|
return _axis_y.Title.Text;
|
}
|
set
|
{
|
_axis_y.Title.Text = value;
|
}
|
}
|
|
/// <summary>
|
/// 鼠标模式
|
/// </summary>
|
public bool MouseModel
|
{
|
get
|
{
|
return _mouse_mode;
|
}
|
set
|
{
|
_mouse_mode = value;
|
}
|
}
|
|
#endregion Public Variable
|
|
#region Public Evnet
|
|
/// <summary>
|
/// 坐标变更事件
|
/// </summary>
|
public event Action<UniversalCoordinate> CoordinateChangedEvent;
|
|
/// <summary>
|
/// 定义点变更事件
|
/// </summary>
|
public event Action<List<Yw.Geometry.Point2d>> DefinePointChangedEvent;
|
|
#endregion Public Evnet
|
|
|
|
#region Initial
|
|
/// <summary>
|
/// 初始化图表
|
/// </summary>
|
private void InitialChart()
|
{
|
this.chartControl1.SetChartDisplay();
|
this.chartControl1.Legend.Visibility = DevExpress.Utils.DefaultBoolean.False;
|
this.chartControl1.SeriesSelectionMode = SeriesSelectionMode.Point;
|
this.chartControl1.SelectionMode = ElementSelectionMode.Single;
|
this.chartControl1.RuntimeHitTesting = true;
|
this.chartControl1.MouseMove += new System.Windows.Forms.MouseEventHandler(this.chartControl1_MouseMove);
|
this.chartControl1.MouseUp += new System.Windows.Forms.MouseEventHandler(this.chartControl1_MouseUp);
|
this.chartControl1.MouseDown += new System.Windows.Forms.MouseEventHandler(this.chartControl1_MouseDown);
|
this.chartControl1.KeyUp += new System.Windows.Forms.KeyEventHandler(this.chartControl1_KeyUp);
|
|
_diagram = (XYDiagram)chartControl1.Diagram;
|
_default_pane = _diagram.DefaultPane;
|
_axis_x = _diagram.AxisX;
|
//_axis_x.SetAxisXQDisplay();
|
_axis_y = _diagram.AxisY;
|
//_axis_y.SetAxisYQLDisplay();
|
|
_axis_x.Visibility = DefaultBoolean.False;
|
_axis_x.GridLines.Visible = false;
|
_axis_y.Visibility = DefaultBoolean.False;
|
_axis_y.GridLines.Visible = false;
|
|
this.chartControl1.SetChartMonoColorDisplay();
|
}
|
|
/// <summary>
|
/// 初始化坐标轴
|
/// </summary>
|
private void InitialCoordinate()
|
{
|
//设置成白板坐标
|
_coordinate = new UniversalCoordinate();
|
_coordinate.GridNumberX = 30;
|
_coordinate.GridNumberY = 16;
|
_coordinate.StartLineNoY = 10;
|
_coordinate.EndLineNoY = 15;
|
_coordinate.CoordMinX = 0; _coordinate.CoordSpaceX = 1000;
|
_coordinate.CoordMinY = 10; _coordinate.CoordSpaceY = 100;
|
}
|
|
#endregion Initial
|
|
#region SetBindingData
|
|
/// <summary>
|
/// 绑定数据
|
/// </summary>
|
public void SetBindingData(List<Yw.Geometry.Point2d> point_pt_list, List<Yw.Geometry.Point2d> line_pt_list, string coordinate = null, Color? color = null)
|
{
|
_initial_data = false;
|
_point_pt_list = point_pt_list;
|
_line_pt_list = line_pt_list;
|
_coordinate = UniversalCoordinate.ToModel(coordinate);
|
|
this.chartControl1.BeginInit();
|
this.chartControl1.Series.Clear();
|
this.chartControl1.AnnotationRepository.Clear();
|
this.chartControl1.Legend.CustomItems.Clear();
|
if (IsInvalidData())
|
{
|
_initial_data = false;
|
this.chartControl1.EndInit();
|
return;
|
}
|
|
AddPointSeries(color.Value, _axis_x, _axis_y, _default_pane, _point_pt_list);
|
AddLineSeries(color.Value, _axis_x, _axis_y, _default_pane, _line_pt_list);
|
if (_coordinate == null)
|
SetCoordinate();
|
|
SetChartAxis();
|
this.chartControl1.EndInit();
|
_initial_data = true;
|
}
|
|
//是否是无效数据
|
private bool IsInvalidData()
|
{
|
if (!_initial_data)
|
return true;
|
if (_point_pt_list == null || !_point_pt_list.Any())
|
{
|
return true;
|
}
|
if (_line_pt_list == null || !_line_pt_list.Any())
|
{
|
return true;
|
}
|
return false;
|
}
|
|
#region Add Chart Data
|
|
private void AddPointSeries(Color color, AxisXBase axis_x, AxisYBase axis_y, XYDiagramPaneBase pane, List<Yw.Geometry.Point2d> pt_list)
|
{
|
if (pt_list == null || !pt_list.Any())
|
return;
|
|
var view = new DevExpress.XtraCharts.PointSeriesView();
|
view.PointMarkerOptions.Size = 8;
|
view.PointMarkerOptions.Kind = MarkerKind.Circle;
|
view.PointMarkerOptions.BorderColor = color;
|
view.Color = color;
|
view.AxisX = axis_x;
|
view.AxisY = axis_y;
|
view.EmptyPointOptions.Color = Color.Transparent;
|
view.Pane = pane;
|
|
var series_pt_list = new List<SeriesPoint>();
|
for (int i = 0; i < pt_list.Count; i++)
|
{
|
var pt = pt_list[i];
|
var series_pt = new DevExpress.XtraCharts.SeriesPoint(pt.X, new double[] { pt.Y });
|
series_pt_list.Add(series_pt);
|
}
|
|
var series = new DevExpress.XtraCharts.Series();
|
series.ShowInLegend = false;
|
series.ArgumentScaleType = DevExpress.XtraCharts.ScaleType.Numerical;
|
series.LabelsVisibility = DevExpress.Utils.DefaultBoolean.False;
|
series.CrosshairEnabled = DefaultBoolean.False;
|
series.CrosshairLabelVisibility = DefaultBoolean.False;
|
series.ToolTipEnabled = DefaultBoolean.False;
|
series.SeriesPointsSorting = SortingMode.None;
|
series.Visible = true;
|
series.View = view;
|
series.CrosshairLabelPattern = "{A}";
|
series.Points.AddRange(series_pt_list.ToArray());
|
this.chartControl1.Series.Add(series);
|
}
|
|
private void AddLineSeries(Color color, AxisXBase axis_x, AxisYBase axis_y, XYDiagramPaneBase pane, List<Yw.Geometry.Point2d> pt_list, DashStyle dash = DashStyle.Solid)
|
{
|
if (pt_list == null || !pt_list.Any())
|
return;
|
|
var view = new DevExpress.XtraCharts.LineSeriesView();
|
view.LineStyle.DashStyle = dash;
|
view.LineStyle.LineJoin = System.Drawing.Drawing2D.LineJoin.Round;
|
view.LineStyle.Thickness = 2;
|
view.Color = color;
|
view.EnableAntialiasing = DefaultBoolean.True;
|
view.MarkerVisibility = DefaultBoolean.False;
|
view.AxisX = axis_x;
|
view.AxisY = axis_y;
|
view.EmptyPointOptions.Color = Color.Transparent;
|
view.Pane = pane;
|
|
var series_pt_list = pt_list.Select(x => x.ToSeriesPoint()).ToArray();
|
var series = new DevExpress.XtraCharts.Series();
|
series.ShowInLegend = false;
|
series.ArgumentScaleType = DevExpress.XtraCharts.ScaleType.Numerical;
|
series.LabelsVisibility = DevExpress.Utils.DefaultBoolean.False;
|
series.CrosshairEnabled = DefaultBoolean.False;
|
series.ToolTipEnabled = DefaultBoolean.False;
|
series.SeriesPointsSorting = SortingMode.None;
|
series.Visible = true;
|
series.View = view;
|
series.Points.AddRange(series_pt_list);
|
|
this.chartControl1.Series.Add(series);
|
}
|
|
#endregion Add Chart Data
|
|
#endregion SetBindingData
|
|
#region Set Axis
|
|
private double _minX, _maxX;
|
private double _maxY = 0, _minY = 10000;
|
|
/// <summary>
|
/// 设置坐标
|
/// </summary>
|
private void SetCoordinate()
|
{
|
if (IsInvalidData())
|
{
|
InitialCoordinate();
|
return;
|
}
|
|
_minX = _point_pt_list.Min(x => x.X);
|
_maxX = _point_pt_list.Max(x => x.X);
|
|
_minY = _point_pt_list.Min(x => x.Y);
|
_maxY = _point_pt_list.Max(x => x.Y);
|
|
_minX = Math.Min(_line_pt_list.Min(x => x.X), _minX);
|
_maxX = Math.Min(_line_pt_list.Max(x => x.X), _maxX);
|
|
_minY = Math.Min(_line_pt_list.Min(x => x.Y), _minY);
|
_maxY = Math.Min(_line_pt_list.Max(x => x.Y), _maxY);
|
|
_coordinate = UniversalCoordinate.CalcCoordinate(_minX, _maxX, _minY, _maxY);
|
if (_coordinate == null)
|
return;
|
if (_coordinate.CoordMinX + _coordinate.CoordSpaceX * this._coordinate.GridNumberX < _maxX * 1.05)
|
{
|
_coordinate.GridNumberX++;
|
}
|
}
|
|
/// <summary>
|
/// 设置图表轴
|
/// </summary>
|
public void SetChartAxis()
|
{
|
if (_coordinate == null || IsInvalidData())
|
{
|
_axis_x.Visibility = DefaultBoolean.False;
|
_axis_x.GridLines.Visible = false;
|
_axis_y.Visibility = DefaultBoolean.False;
|
_axis_y.GridLines.Visible = false;
|
return;
|
}
|
|
//计算刻度 X
|
var axis_x_labels = new List<CustomAxisLabel>();
|
var dis_x = _coordinate.CoordMinX;
|
for (int i = 0; i < _coordinate.GridNumberX + 1; i++)
|
{
|
axis_x_labels.Add(new CustomAxisLabel(dis_x.ToString("N0"), dis_x));
|
dis_x = dis_x + _coordinate.CoordSpaceX;
|
}
|
|
_axis_x.CustomLabels.Clear();
|
_axis_x.CustomLabels.AddRange(axis_x_labels.ToArray());
|
_axis_x.Visibility = DefaultBoolean.True;
|
_axis_x.GridLines.Visible = true;
|
|
//计算刻度 Y
|
var axis_y_labels = new List<CustomAxisLabel>();
|
var dis_y = _coordinate.CoordMinY + _coordinate.CoordSpaceY * _coordinate.StartLineNoY;
|
for (int i = _coordinate.StartLineNoY; i < _coordinate.EndLineNoY + 1; i++)
|
{
|
axis_y_labels.Add(new CustomAxisLabel(dis_y.ToString(), dis_y));
|
dis_y = dis_y + _coordinate.CoordSpaceY;
|
}
|
|
_axis_y.CustomLabels.Clear();
|
_axis_y.CustomLabels.AddRange(axis_y_labels.ToArray());
|
_axis_y.Visibility = DefaultBoolean.True;
|
_axis_y.GridLines.Visible = true;
|
|
_axis_x.SetAxisRange(_coordinate.CoordMinX, _coordinate.DispMaxX());
|
_axis_y.SetAxisRange(_coordinate.DispMinY(), _coordinate.DispMaxY());
|
}
|
|
#endregion Set Axis
|
|
#region ChartEvent
|
|
private SeriesPoint _pick_point = null;// 选中点
|
|
private void chartControl1_MouseDown(object sender, MouseEventArgs e)
|
{
|
if (!_initial_data)
|
return;
|
var hitInfo = chartControl1.CalcHitInfo(e.Location);
|
_pick_point = null;
|
if (e.Button == MouseButtons.Left)
|
{
|
if (hitInfo.InSeriesPoint && hitInfo.SeriesPoint.Tag is int)
|
{
|
_pick_point = hitInfo.SeriesPoint;
|
}
|
}
|
}
|
|
private void chartControl1_MouseMove(object sender, MouseEventArgs e)
|
{
|
if (!_mouse_mode)
|
return;
|
if (IsInvalidData())
|
return;
|
if (_pick_point == null)
|
return;
|
var diagram_coordinates = _diagram.PointToDiagram(e.Location);
|
var axis_value = diagram_coordinates.GetAxisValue(_axis_y);
|
if (axis_value == null)
|
return;
|
_pick_point.Values[0] = axis_value.NumericalValue;
|
_pick_point.NumericalArgument = diagram_coordinates.NumericalArgument;
|
}
|
|
private void chartControl1_MouseUp(object sender, MouseEventArgs e)
|
{
|
if (!_mouse_mode)
|
return;
|
if (IsInvalidData())
|
return;
|
if (_pick_point == null)
|
return;
|
if (_pick_point.Tag is not int index)
|
return;
|
var x = _pick_point.NumericalArgument;
|
var y = _pick_point.Values[0];
|
SetPointPtValue(index, x, y);
|
|
_pick_point = null;
|
}
|
|
private void chartControl1_KeyUp(object sender, KeyEventArgs e)
|
{
|
if (!_initial_data)
|
return;
|
if (_pick_point == null)
|
return;
|
if (IsInvalidData())
|
return;
|
double space_x = _coordinate.CoordSpaceX / 50;
|
double space_y = _coordinate.CoordSpaceY / 50;
|
double x = _pick_point.NumericalArgument;
|
double y = _pick_point.Values[0];
|
if (e.KeyCode == Keys.Up)
|
{
|
y += space_y;
|
}
|
else if (e.KeyCode == Keys.Down)
|
{
|
y -= space_y;
|
}
|
else if (e.KeyCode == Keys.Left)
|
{
|
x -= space_x;
|
}
|
else if (e.KeyCode == Keys.Right)
|
{
|
x += space_x;
|
}
|
_pick_point.Values[0] = y;
|
_pick_point.NumericalArgument = x;
|
/* var index = _pick_point.Tag.is
|
SetPointPtValue();*/
|
}
|
|
/// <summary>
|
/// 更新数据
|
/// </summary>
|
private void SetPointPtValue(int index, double x, double y)
|
{
|
if (IsInvalidData())
|
return;
|
_point_pt_list[index].X = x;
|
_point_pt_list[index].Y = y;
|
this.DefinePointChangedEvent?.Invoke(_point_pt_list);
|
}
|
|
#endregion ChartEvent
|
}
|
}
|