using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Forms.DataVisualization.Charting;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace FLY.ControlLibrary
{
///
/// GraphScan.xaml 的交互逻辑
///
public partial class GraphScan4 : UserControl, INotifyPropertyChanged
{
//设定数据统计范围
#region IGraphBase
#region 附加属性
public static readonly DependencyProperty TitleProperty =
DependencyProperty.Register("Title", typeof(string), typeof(GraphScan4), new PropertyMetadata("Title"));
public string Title
{
get
{
return GetValue(TitleProperty) as string;
}
set
{
if (value != Title)
{
SetValue(TitleProperty, value);
NotifyPropertyChanged("Title");
}
}
}
public static readonly DependencyProperty Title2Property =
DependencyProperty.Register("Title2", typeof(string), typeof(GraphScan4), new PropertyMetadata(""));
public string Title2
{
get
{
return GetValue(Title2Property) as string;
}
set
{
if (value != Title2)
{
SetValue(Title2Property, value);
NotifyPropertyChanged("Title2");
}
}
}
public static readonly DependencyProperty IsValidProperty =
DependencyProperty.Register("IsValid", typeof(bool), typeof(GraphScan4), new PropertyMetadata(true));
public bool IsValid
{
get
{
return (bool)GetValue(IsValidProperty);
}
set
{
if (value != IsValid)
{
SetValue(IsValidProperty, value);
NotifyPropertyChanged("IsValid");
}
}
}
///
/// 计算结果
///
public static readonly DependencyProperty CalStateProperty =
DependencyProperty.Register("CalState", typeof(string), typeof(GraphScan4), new PropertyMetadata(
"Max:null Min:null Avg:null 2σ:null",
new PropertyChangedCallback(delegate (DependencyObject d, DependencyPropertyChangedEventArgs e)
{
})));
public string CalState
{
get
{
return (string)GetValue(CalStateProperty);
}
set
{
SetValue(CalStateProperty, value);
}
}
///
/// 空的数据,定义某个值为空,默认为 99999998
///
public static readonly DependencyProperty EmptyValueProperty =
DependencyProperty.Register("EmptyValue", typeof(int), typeof(GraphScan4), new PropertyMetadata(
99999998,
new PropertyChangedCallback(delegate (DependencyObject d, DependencyPropertyChangedEventArgs e)
{
})));
public int EmptyValue
{
get
{
return (int)GetValue(EmptyValueProperty);
}
set
{
SetValue(EmptyValueProperty, value);
}
}
///
/// 放大倍数, 目标值= Target/放大倍数
///
public static readonly DependencyProperty MultiProperty =
DependencyProperty.Register("Multi", typeof(int), typeof(GraphScan4), new PropertyMetadata(
100,
new PropertyChangedCallback(delegate (DependencyObject d, DependencyPropertyChangedEventArgs e)
{
})));
public int Multi
{
get
{
return (int)GetValue(MultiProperty);
}
set
{
SetValue(MultiProperty, value);
}
}
///
/// 目标值
///
public static readonly DependencyProperty TargetProperty =
DependencyProperty.Register("Target", typeof(int), typeof(GraphScan4), new PropertyMetadata(
3000,
new PropertyChangedCallback(delegate (DependencyObject d, DependencyPropertyChangedEventArgs e)
{
(d as GraphScan4).NotifyPropertyChanged("Target");
})));
public int Target
{
get
{
return (int)GetValue(TargetProperty);
}
set
{
SetValue(TargetProperty, value);
}
}
private int autotarget;
public int AutoTarget
{
get { return autotarget; }
set
{
if (autotarget != value)
{
autotarget = value;
NotifyPropertyChanged("AutoTarget");
}
}
}
///
/// 自动目标值
///
public static readonly DependencyProperty IsAutoTargetProperty =
DependencyProperty.Register("IsAutoTarget", typeof(bool), typeof(GraphScan4), new PropertyMetadata(
false,
new PropertyChangedCallback(delegate (DependencyObject d, DependencyPropertyChangedEventArgs e)
{
(d as GraphScan4).NotifyPropertyChanged("IsAutoTarget");
})));
public bool IsAutoTarget
{
get
{
return (bool)GetValue(IsAutoTargetProperty);
}
set
{
SetValue(IsAutoTargetProperty, value);
}
}
///
/// 获取或设置指示是否将轴反转的标志
///
public static readonly DependencyProperty IsReversedProperty =
DependencyProperty.Register("IsReversed", typeof(bool), typeof(GraphScan4), new PropertyMetadata(
false,
new PropertyChangedCallback(delegate (DependencyObject d, DependencyPropertyChangedEventArgs e)
{
(d as GraphScan4).NotifyPropertyChanged("IsReversed");
})));
public bool IsReversed
{
get
{
return (bool)GetValue(IsReversedProperty);
}
set
{
SetValue(IsReversedProperty, value);
}
}
///
/// 获取或设置 左右标示是否反转 的标志
///
public static readonly DependencyProperty LeftRightIsReversedProperty =
DependencyProperty.Register("LeftRightIsReversed", typeof(bool), typeof(GraphScan4), new PropertyMetadata(
false,
new PropertyChangedCallback(delegate (DependencyObject d, DependencyPropertyChangedEventArgs e)
{
(d as GraphScan4).NotifyPropertyChanged("LeftRightIsReversed");
})));
///
/// 左右标示 反转
///
public bool LeftRightIsReversed
{
get
{
return (bool)GetValue(LeftRightIsReversedProperty);
}
set
{
SetValue(LeftRightIsReversedProperty, value);
}
}
///
/// 左右标示 可见
///
public static readonly DependencyProperty LeftRightIsVisableProperty =
DependencyProperty.Register("LeftRightIsVisable", typeof(bool), typeof(GraphScan4), new PropertyMetadata(
false,
new PropertyChangedCallback(delegate (DependencyObject d, DependencyPropertyChangedEventArgs e)
{
(d as GraphScan4).NotifyPropertyChanged("LeftRightIsVisable");
})));
///
/// 左右标示 反转
///
public bool LeftRightIsVisable
{
get
{
return (bool)GetValue(LeftRightIsVisableProperty);
}
set
{
SetValue(LeftRightIsVisableProperty, value);
}
}
///
/// %显示
///
public static readonly DependencyProperty IsPercentProperty =
DependencyProperty.Register("IsPercent", typeof(bool), typeof(GraphScan4), new PropertyMetadata(
false,
new PropertyChangedCallback(delegate (DependencyObject d, DependencyPropertyChangedEventArgs e)
{
(d as GraphScan4).NotifyPropertyChanged("IsPercent");
})));
public bool IsPercent
{
get
{
return (bool)GetValue(IsPercentProperty);
}
set
{
SetValue(IsPercentProperty, value);
}
}
///
/// 报警值
///
public static readonly DependencyProperty AlarmProperty =
DependencyProperty.Register("Alarm", typeof(int), typeof(GraphScan4), new PropertyMetadata(
1000,
new PropertyChangedCallback(delegate (DependencyObject d, DependencyPropertyChangedEventArgs e)
{
(d as GraphScan4).NotifyPropertyChanged("Alarm");
})));
public int Alarm
{
get
{
return (int)GetValue(AlarmProperty);
}
set
{
SetValue(AlarmProperty, value);
}
}
///
/// Y轴是 Alarm 的N倍 默认3倍
///
public static readonly DependencyProperty YRangePercentProperty =
DependencyProperty.Register("YRangePercent", typeof(double), typeof(GraphScan4), new PropertyMetadata(
3.0,
new PropertyChangedCallback(delegate (DependencyObject d, DependencyPropertyChangedEventArgs e)
{
(d as GraphScan4).NotifyPropertyChanged("YRangePercent");
})));
public double YRangePercent
{
get
{
return (double)GetValue(YRangePercentProperty);
}
set
{
SetValue(YRangePercentProperty, value);
}
}
///
/// 控制线
///
public static readonly DependencyProperty HasCtrlLineProperty =
DependencyProperty.Register("HasCtrlLine", typeof(bool), typeof(GraphScan4), new PropertyMetadata(
false,
new PropertyChangedCallback(delegate (DependencyObject d, DependencyPropertyChangedEventArgs e)
{
(d as GraphScan4).NotifyPropertyChanged("HasCtrlLine");
})));
public bool HasCtrlLine
{
get
{
return (bool)GetValue(HasCtrlLineProperty);
}
set
{
SetValue(HasCtrlLineProperty, value);
}
}
///
/// 控制线
///
public static readonly DependencyProperty CtrlLineProperty =
DependencyProperty.Register("CtrlLine", typeof(int), typeof(GraphScan4), new PropertyMetadata(
1000,
new PropertyChangedCallback(delegate (DependencyObject d, DependencyPropertyChangedEventArgs e)
{
(d as GraphScan4).NotifyPropertyChanged("CtrlLine");
})));
public int CtrlLine
{
get
{
return (int)GetValue(CtrlLineProperty);
}
set
{
SetValue(CtrlLineProperty, value);
}
}
///
/// 第一个分区号
///
public static readonly DependencyProperty FirstBoltNoProperty =
DependencyProperty.Register("FirstBoltNo", typeof(int), typeof(GraphScan4), new PropertyMetadata(
0,
new PropertyChangedCallback(delegate (DependencyObject d, DependencyPropertyChangedEventArgs e)
{
(d as GraphScan4).NotifyPropertyChanged("FirstBoltNo");
})));
public int FirstBoltNo
{
get
{
return (int)GetValue(FirstBoltNoProperty);
}
set
{
SetValue(FirstBoltNoProperty, value);
}
}
///
///
///
public static readonly DependencyProperty FirstIndexProperty =
DependencyProperty.Register("FirstIndex", typeof(int), typeof(GraphScan4), new PropertyMetadata(
0,
new PropertyChangedCallback(delegate (DependencyObject d, DependencyPropertyChangedEventArgs e)
{
(d as GraphScan4).NotifyPropertyChanged("FirstIndex");
})));
public int FirstIndex
{
get
{
return (int)GetValue(FirstIndexProperty);
}
set
{
SetValue(FirstIndexProperty, value);
}
}
///
///
///
public static readonly DependencyProperty LastIndexProperty =
DependencyProperty.Register("LastIndex", typeof(int), typeof(GraphScan4), new PropertyMetadata(
49,
new PropertyChangedCallback(delegate (DependencyObject d, DependencyPropertyChangedEventArgs e)
{
(d as GraphScan4).NotifyPropertyChanged("LastIndex");
})));
public int LastIndex
{
get
{
return (int)GetValue(LastIndexProperty);
}
set
{
SetValue(LastIndexProperty, value);
}
}
///
/// 数据统计的开始
///
public static readonly DependencyProperty DataFirstProperty =
DependencyProperty.Register("DataFirst", typeof(int), typeof(GraphScan4), new PropertyMetadata(
0,
new PropertyChangedCallback(delegate (DependencyObject d, DependencyPropertyChangedEventArgs e)
{
(d as GraphScan4).NotifyPropertyChanged("DataFirst");
})));
public int DataFirst
{
get
{
return (int)GetValue(DataFirstProperty);
}
set
{
SetValue(DataFirstProperty, value);
}
}
///
/// 数据统计的结束
///
public static readonly DependencyProperty DataLastProperty =
DependencyProperty.Register("DataLast", typeof(int), typeof(GraphScan4), new PropertyMetadata(
49,
new PropertyChangedCallback(delegate (DependencyObject d, DependencyPropertyChangedEventArgs e)
{
(d as GraphScan4).NotifyPropertyChanged("DataLast");
})));
public int DataLast
{
get
{
return (int)GetValue(DataLastProperty);
}
set
{
SetValue(DataLastProperty, value);
}
}
#endregion
#region IGraphBase3
///
/// mm/分区
///
public static readonly DependencyProperty MmOfBoltProperty =
DependencyProperty.Register("MmOfBolt", typeof(double), typeof(GraphScan4), new PropertyMetadata(
10.0,
new PropertyChangedCallback(delegate (DependencyObject d, DependencyPropertyChangedEventArgs e)
{
(d as GraphScan4).NotifyPropertyChanged("MmOfBolt");
})));
///
/// mm/分区
///
public double MmOfBolt
{
get
{
return (double)GetValue(MmOfBoltProperty);
}
set
{
if (value != MmOfBolt)
{
SetValue(MmOfBoltProperty, value);
NotifyPropertyChanged("MmOfBolt");
}
}
}
///
/// X轴间隔 单位分区
///
public static readonly DependencyProperty XIntervalProperty =
DependencyProperty.Register("XInterval", typeof(int), typeof(GraphScan4), new PropertyMetadata(
5,
new PropertyChangedCallback(delegate (DependencyObject d, DependencyPropertyChangedEventArgs e)
{
(d as GraphScan4).NotifyPropertyChanged("XInterval");
})));
///
/// X轴间隔 单位分区
///
public int XInterval
{
get
{
return (int)GetValue(XIntervalProperty);
}
set
{
if (value != XInterval)
{
SetValue(XIntervalProperty, value);
NotifyPropertyChanged("XInterval");
}
}
}
#endregion
///
/// 数据源
///
private ObservableCollection _datasource;
///
/// 数据源
///
public virtual ObservableCollection DataSource
{
get
{
return _datasource;
}
set
{
if (_datasource != null)
_datasource.CollectionChanged -= dataSource_CollectionChanged;
_datasource = value;
_datasource.CollectionChanged += dataSource_CollectionChanged;
mRefresh.UpdateData = true;
}
}
public event EventHandler ShowSettingDialogEvent;
public event EventHandler TitleClickEvent;
#endregion
#region 刷新率控制
protected class Refresh
{
///
/// 控制刷新率
///
System.Windows.Threading.DispatcherTimer timer;
bool updatedata_flag = false;
bool updatey_flag = false;
bool updatex_flag = false;
bool updatecalx_flag = false;
///
/// 最快0.1s 刷新一次
///
TimeSpan REFRESH_RATE = TimeSpan.FromSeconds(0.1);
public Refresh(GraphScan4 graph)
{
timer = new System.Windows.Threading.DispatcherTimer();
timer.Tick += new EventHandler(delegate (object sender, EventArgs e)
{
if (UpdateData)
{
UpdateData = false;
graph.DataBindAll_all();
}
if (UpdateY)
{
UpdateY = false;
graph.UpdateAxisY();
}
if (UpdateX)
{
UpdateX = false;
graph.UpdateXRange();
}
if (UpdateCalX)
{
UpdateCalX = false;
graph.UpdateDataCalRange();
graph.UpdateCalState_all();
}
timer.Stop();
});
timer.Interval = REFRESH_RATE;
timer.Start();
}
public bool UpdateData
{
get { return updatedata_flag; }
set
{
updatedata_flag = value;
if (value)
{
if (!timer.IsEnabled)
timer.Start();
}
}
}
public bool UpdateY
{
get { return updatey_flag; }
set
{
updatey_flag = value;
if (value)
{
if (!timer.IsEnabled)
timer.Start();
}
}
}
public bool UpdateX
{
get { return updatex_flag; }
set
{
updatex_flag = value;
if (value)
{
if (!timer.IsEnabled)
timer.Start();
}
}
}
public bool UpdateCalX
{
get { return updatecalx_flag; }
set
{
updatecalx_flag = value;
if (value)
{
if (!timer.IsEnabled)
timer.Start();
}
}
}
}
protected Refresh mRefresh;
#endregion
public GraphScan4()
{
InitializeComponent();
InitializeComponent2();
grid_title.DataContext = this;
PropertyChanged += new PropertyChangedEventHandler(GraphScan_PropertyChanged);
mRefresh = new Refresh(this);
SetDefault();
//Test();
}
void GraphScan_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
//if (e.PropertyName == "AutoTarget")
//{
// if (IsAutoTarget)
// {
// mRefresh.UpdateY = true;
// mRefresh.UpdateData = true;
// }
//}
if ((e.PropertyName == "Target") ||
(e.PropertyName == "Alarm") ||
(e.PropertyName == "YRangePercent") ||
(e.PropertyName == "IsAutoTarget") ||
(e.PropertyName == "IsPercent") ||
(e.PropertyName == "AutoTarget"))
{
mRefresh.UpdateY = true;
mRefresh.UpdateData = true;
}
else if (e.PropertyName == "FirstBoltNo")
{
mRefresh.UpdateCalX = true;
mRefresh.UpdateX = true;
mRefresh.UpdateData = true;
}
else if (e.PropertyName == "FirstIndex" || e.PropertyName == "LastIndex")
{
mRefresh.UpdateX = true;
}
else if (e.PropertyName == "DataFirst" || e.PropertyName == "DataLast")
{
mRefresh.UpdateCalX = true;
}
else if (e.PropertyName == "IsReversed")
{
chart1.ChartAreas[0].AxisX.IsReversed = IsReversed;
}
else if ((e.PropertyName == "HasCtrlLine") || (e.PropertyName == "CtrlLine"))
{
UpdateCtrlLine();
}
if (e.PropertyName == "MmOfBolt")
{
mRefresh.UpdateData = true;
}
else if (e.PropertyName == "XInterval")
{
mRefresh.UpdateX = true;
}
}
public void SetDefault()
{
NotifyPropertyChanged("Target");
NotifyPropertyChanged("TAlarm");
NotifyPropertyChanged("YRangePercent");
NotifyPropertyChanged("ChartType");
NotifyPropertyChanged("FirstBoltNo");
NotifyPropertyChanged("FirstIndex");
NotifyPropertyChanged("LastIndex");
NotifyPropertyChanged("DataFirst");
NotifyPropertyChanged("DataLast");
AutoTarget = Target;
}
void InitializeComponent2()
{
System.Windows.Forms.DataVisualization.Charting.ChartArea chartArea1 = new System.Windows.Forms.DataVisualization.Charting.ChartArea();
System.Windows.Forms.DataVisualization.Charting.Series series_sigma = new System.Windows.Forms.DataVisualization.Charting.Series();
System.Windows.Forms.DataVisualization.Charting.Series series_avg = new System.Windows.Forms.DataVisualization.Charting.Series();
chart1.Name = "chart1";
chart1.BackColor = System.Drawing.Color.Transparent;
//
// chart1
//---------------------------------------------------------------------------------------
chartArea1.Name = "chartArea1";
chartArea1.AxisX.LabelStyle.Font = new System.Drawing.Font("Trebuchet MS", 8.25F, System.Drawing.FontStyle.Bold);
chartArea1.AxisX.LineColor = System.Drawing.Color.FromArgb(((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64)))));
chartArea1.AxisX.MajorGrid.LineColor = System.Drawing.Color.FromArgb(((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64)))));
chartArea1.AxisX.IsMarksNextToAxis = false;
chartArea1.AxisX.IsLabelAutoFit = true;
chartArea1.AxisX.LabelAutoFitStyle = LabelAutoFitStyles.DecreaseFont;
chartArea1.AxisX.IntervalAutoMode = System.Windows.Forms.DataVisualization.Charting.IntervalAutoMode.VariableCount;
chartArea1.AxisY.LabelStyle.Font = new System.Drawing.Font("Trebuchet MS", 8.25F, System.Drawing.FontStyle.Bold);
chartArea1.AxisY.LineColor = System.Drawing.Color.FromArgb(((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64)))));
chartArea1.AxisY.MajorGrid.LineColor = System.Drawing.Color.FromArgb(((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64)))));
chartArea1.BorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64)))));
chartArea1.BorderDashStyle = System.Windows.Forms.DataVisualization.Charting.ChartDashStyle.Solid;
//chartArea1.Position.Height = 100;// 42F;
//chartArea1.Position.Width = 100;// 88F;
//chartArea1.Position.X = 0;// 3F;
//chartArea1.Position.Y = 0;// 10F;
chart1.ChartAreas.Add(chartArea1);
//---------------------------------------------------------------------------------------
series_sigma.Name = "series_sigma";
series_sigma.ChartArea = chartArea1.Name;
series_sigma.ChartType = System.Windows.Forms.DataVisualization.Charting.SeriesChartType.Range;
series_sigma.Color = System.Drawing.Color.FromArgb(((int)(((byte)(220)))), ((int)(((byte)(65)))), ((int)(((byte)(140)))), ((int)(((byte)(240)))));
series_sigma.BorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(180)))), ((int)(((byte)(26)))), ((int)(((byte)(59)))), ((int)(((byte)(105)))));
series_sigma.BorderWidth = 2;
//series_sigma.ShadowColor = System.Drawing.Color.Black;
//series_sigma.ShadowOffset = 2;
series_sigma.XValueType = System.Windows.Forms.DataVisualization.Charting.ChartValueType.Int32;
series_sigma.YValueType = System.Windows.Forms.DataVisualization.Charting.ChartValueType.Double;
chart1.Series.Add(series_sigma);
//---------------------------------------------------------------------------------------
series_avg.Name = "series_avg";
series_avg.ChartArea = chartArea1.Name;
series_avg.ChartType = System.Windows.Forms.DataVisualization.Charting.SeriesChartType.Spline;
series_avg.Color = System.Drawing.Color.FromArgb(((int)(((byte)(220)))), ((int)(((byte)(65)))), ((int)(((byte)(140)))), ((int)(((byte)(240)))));
series_avg.BorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(180)))), ((int)(((byte)(26)))), ((int)(((byte)(59)))), ((int)(((byte)(105)))));
series_avg.BorderWidth = 3;
series_avg.ShadowColor = System.Drawing.Color.Black;
series_avg.ShadowOffset = 2;
series_avg.XValueType = System.Windows.Forms.DataVisualization.Charting.ChartValueType.Int32;
series_avg.YValueType = System.Windows.Forms.DataVisualization.Charting.ChartValueType.Double;
chart1.Series.Add(series_avg);
//chart1.PrePaint += new EventHandler(Chart1_PrePaint);
this.chart1.PrePaint += new System.EventHandler(Chart1_PrePaint);
}
protected virtual void SetCustomLabel(Axis axisY, double p, GridTickTypes gt, System.Drawing.Color c, bool ispercent, string message)
{
double r = axisY.Maximum - axisY.Minimum;
double f, t;
f = p + r / 2;
t = p - r / 2;
double target = (axisY.Maximum + axisY.Minimum) / 2;
CustomLabel customLabel;
string str;
if (!ispercent)
{
str = p.ToString("N1");
}
else
{
//百分比模式!!!!!!!
if (target == p)
{
str = p.ToString("N1");
}
else
{
double percent;
percent = ((p - target) / target) * 100;
str = percent.ToString("N1") + "%";
}
}
if (!string.IsNullOrEmpty(message))
str = message + " " + str;
customLabel = axisY.CustomLabels.Add(f, t, str);
customLabel.GridTicks = gt;
customLabel.ForeColor = c;
}
///
/// 获取实际应用的目标值,公差
///
///
///
///
///
protected void GetActualTargetAlarm(out double target, out double alarm, out double yrange, out bool ispercent)
{
double multi = Multi;
if (IsAutoTarget)
target = AutoTarget / multi;//AutoTarget 计算得到的平均值
else
target = Target / multi;
ispercent = IsPercent;
if ((ispercent) && (Target <= 0) || (Alarm < 0) || (target <= 0))
ispercent = false;
if (ispercent)
{
alarm = target * Alarm / Target;
}
else
{
alarm = Alarm / multi;
}
yrange = alarm * YRangePercent;
if ((alarm < 0.1) || (yrange < 0.3))
{
alarm = 0.1;
yrange = 0.3;
}
}
///
/// 与 Multi,Target,YRange,Alarm 相关
///
public virtual void UpdateAxisY()
{
double alarm;
double yrange;
double target;
bool ispercent;
GetActualTargetAlarm(out target, out alarm, out yrange, out ispercent);
Axis axisY = chart1.ChartAreas[0].AxisY;
axisY.Crossing = target;
// Set manual minimum and maximum values.
axisY.Minimum = target - yrange;
axisY.Maximum = target + yrange;
axisY.CustomLabels.Clear();
//中间目标值,肯定不以%显示
SetCustomLabel(axisY, target, GridTickTypes.All, System.Drawing.Color.Green, false, null);
//上下限
SetCustomLabel(axisY, target + alarm, GridTickTypes.All, System.Drawing.Color.DarkGoldenrod, ispercent, null);
SetCustomLabel(axisY, target - alarm, GridTickTypes.All, System.Drawing.Color.DarkGoldenrod, ispercent, null);
//2倍上下限
SetCustomLabel(axisY, target + alarm * 2, GridTickTypes.All, System.Drawing.Color.Red, ispercent, null);
SetCustomLabel(axisY, target - alarm * 2, GridTickTypes.All, System.Drawing.Color.Red, ispercent, null);
//显示范围数值
if ((yrange != alarm) && (yrange != 2 * alarm))
{
SetCustomLabel(axisY, axisY.Minimum, GridTickTypes.TickMark, System.Drawing.Color.Black, ispercent, null);
SetCustomLabel(axisY, axisY.Maximum, GridTickTypes.TickMark, System.Drawing.Color.Black, ispercent, null);
}
//显示范围太小,多加纵坐标
if (yrange <= alarm)
{
SetCustomLabel(axisY, target - yrange / 2, GridTickTypes.All, System.Drawing.Color.Black, ispercent, null);
SetCustomLabel(axisY, target + yrange / 2, GridTickTypes.All, System.Drawing.Color.Black, ispercent, null);
}
}
///
/// 与 FirstBoltNo,DataFirst,DataLast 相关
///
public virtual void UpdateDataCalRange()
{
int firstBoltNo = FirstBoltNo;
int datafirst = DataFirst;
int datalast = DataLast;
if (datafirst > datalast)
{
int swap = datalast;
datalast = datafirst;
datafirst = swap;
}
System.Windows.Forms.DataVisualization.Charting.Axis axisX = chart1.ChartAreas[0].AxisX;
axisX.CustomLabels.Clear();
System.Windows.Forms.DataVisualization.Charting.CustomLabel customlabel
= new System.Windows.Forms.DataVisualization.Charting.CustomLabel(
datafirst + firstBoltNo, datalast + firstBoltNo, CalState, 1,
System.Windows.Forms.DataVisualization.Charting.LabelMarkStyle.LineSideMark);
axisX.CustomLabels.Add(customlabel);
}
///
/// 与 FirstBoltNo,FirstIndex,LastIndex 相关
///
public virtual void UpdateXRange()
{
int firstBoltNo = FirstBoltNo;
int first = FirstIndex;
int last = LastIndex;
if (first > last)
{
//交换
int swap = last;
last = first;
first = swap;
}
else if (first == last)
{
last = first + 10;
}
// Set manual minimum and maximum values.
Axis axis = chart1.ChartAreas[0].AxisX;
axis.Minimum = firstBoltNo + first;
axis.Maximum = firstBoltNo + last;
axis.Interval = XInterval;
//0必须在 写着0mm
axis.IntervalOffset = (0 - axis.Minimum) % XInterval;
}
public virtual void UpdateCtrlLine()
{
chart1.Invalidate();
}
protected virtual void Chart1_PrePaint(object sender, System.Windows.Forms.DataVisualization.Charting.ChartPaintEventArgs e)
{
if (e.ChartElement is ChartArea)
{
ChartArea area = (ChartArea)e.ChartElement;
//if (area.Name == "Default")
{
if (!HasCtrlLine)
return;
double c1 = ((double)(Target + CtrlLine)) / Multi;
double c2 = ((double)(Target - CtrlLine)) / Multi;
if (c1 > area.AxisY.Maximum || c2 < area.AxisY.Minimum)
return;
// Take Graphics object from chart
Graphics graph = e.ChartGraphics.Graphics;
// Convert X and Y values to screen position
c1 = e.ChartGraphics.GetPositionFromAxis(area.Name, AxisName.Y, c1);
c2 = e.ChartGraphics.GetPositionFromAxis(area.Name, AxisName.Y, c2);
double XMin = e.ChartGraphics.GetPositionFromAxis(area.Name, AxisName.X, area.AxisX.Minimum);
double XMax = e.ChartGraphics.GetPositionFromAxis(area.Name, AxisName.X, area.AxisX.Maximum);
// Draw Maximum trangle
System.Drawing.Pen darkPen = new System.Drawing.Pen(System.Drawing.Color.LightPink, 1);
System.Drawing.PointF[] points = new System.Drawing.PointF[2];
points[0].X = (float)XMin;
points[1].X = (float)XMax;
points[0].Y = points[1].Y = (float)c1;
// Convert relative coordinates to absolute coordinates.
points[0] = e.ChartGraphics.GetAbsolutePoint(points[0]);
points[1] = e.ChartGraphics.GetAbsolutePoint(points[1]);
graph.DrawLine(darkPen, points[0], points[1]);
points[0].X = (float)XMin;
points[1].X = (float)XMax;
points[0].Y = points[1].Y = (float)c2;
// Convert relative coordinates to absolute coordinates.
points[0] = e.ChartGraphics.GetAbsolutePoint(points[0]);
points[1] = e.ChartGraphics.GetAbsolutePoint(points[1]);
graph.DrawLine(darkPen, points[0], points[1]);
}
}
}
protected virtual void UpdateOnePoint_all(int index)
{
double multi = Multi;
int emptyvalue = EmptyValue;
DataPoint point_sigma;
DataPoint point_avg;
double avg;
double upper;
double lower;
if ((DataSource[index].Avg == emptyvalue) || (DataSource[index].Sigma == emptyvalue))
{
avg = double.NaN;
upper = double.NaN;
lower = double.NaN;
}
else
{
double sigma2 = 2 * DataSource[index].Sigma / multi;
avg = DataSource[index].Avg / multi;
upper = avg + sigma2;
lower = avg - sigma2;
}
if (index >= chart1.Series["series_sigma"].Points.Count)
{
chart1.Series["series_sigma"].Points.AddXY(
FirstBoltNo + index,
upper, lower);
point_sigma = chart1.Series["series_sigma"].Points[index];
chart1.Series["series_avg"].Points.AddXY(
FirstBoltNo + index,
avg);
point_avg = chart1.Series["series_avg"].Points[index];
}
else
{
point_sigma = chart1.Series["series_sigma"].Points[index];
point_sigma.YValues[0] = upper;
point_sigma.YValues[1] = lower;
point_sigma.XValue = FirstBoltNo + index;
point_avg = chart1.Series["series_avg"].Points[index];
point_avg.YValues[0] = avg;
point_avg.XValue = FirstBoltNo + index;
}
point_avg.AxisLabel = (point_avg.XValue * MmOfBolt).ToString("F0") + "mm";
//设定空数据
if (double.IsNaN(avg))
{
point_sigma.IsEmpty = true;
point_avg.IsEmpty = true;
System.Drawing.Color c = System.Drawing.Color.Transparent;
point_sigma.MarkerColor = c;
point_sigma.BorderColor = c;
point_sigma.Color = c;
point_avg.MarkerColor = c;
point_avg.BorderColor = c;
point_avg.Color = c;
}
else
{
point_sigma.IsEmpty = false;
point_avg.IsEmpty = false;
double alarm;
double target;
double yrange;
bool ispercent;
GetActualTargetAlarm(out target, out alarm, out yrange, out ispercent);
double threshold1 = alarm;
double threshold2 = alarm * 2;
System.Drawing.Color c;
if (((upper) > (target + threshold2)) || ((upper) < (target - threshold2)))
{
c = System.Drawing.Color.Red;
}
else if (((lower) > (target + threshold2)) || ((lower) < (target - threshold2)))
{
c = System.Drawing.Color.Red;
}
else if (((upper) > (target + threshold1)) || ((upper) < (target - threshold1)))
{
c = System.Drawing.Color.Orange;
}
else if (((lower) > (target + threshold1)) || ((lower) < (target - threshold1)))
{
c = System.Drawing.Color.Orange;
}
else
{
c = System.Drawing.Color.Green;
}
point_sigma.BorderColor = c;
point_sigma.Color = c;
point_avg.Color = System.Drawing.Color.FromArgb(((int)(((byte)(220)))), ((int)(((byte)(65)))), ((int)(((byte)(140)))), ((int)(((byte)(240)))));
point_avg.BorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(180)))), ((int)(((byte)(26)))), ((int)(((byte)(59)))), ((int)(((byte)(105)))));
}
}
void DataBindAll_all()
{
chart1.Series["series_avg"].Points.Clear();
chart1.Series["series_sigma"].Points.Clear();
if (DataSource != null)
{
for (int i = 0; i < DataSource.Count(); i++)
{
UpdateOnePoint_all(i);
}
}
CheckDataSourceEmpty();
UpdateCalState_all();
}
///
/// 与 Multi,EmptyValue,DataFirst,DataLast 相关
///
public void UpdateCalState_all()
{
int emptyvalue = EmptyValue;
double multi = Multi;
if (DataSource == null)
{
goto _err;
}
string title;
var dats_max = from data in DataSource where data.Avg != emptyvalue select data.Avg + data.Sigma * 2;
var dats_min = from data in DataSource where data.Avg != emptyvalue select data.Avg - data.Sigma * 2;
List dats = new List();
dats.AddRange(dats_max);
dats.AddRange(dats_min);
if (dats.Count() == 0)
{
goto _err;
}
else
{
//AutoTarget = (int)dats.Average();
double avg = dats.Average() / multi;
double max = dats.Max() / multi;
double min = dats.Min() / multi;
double sum = 0;
foreach (int dat in dats)
{
sum += Math.Pow(avg - (double)dat / multi, 2);
}
sum /= (dats.Count() - 1);
double sigma = Math.Sqrt(sum);
if (IsPercent)
{
title = "Max:+" + ((max / avg * 100) - 100).ToString("N1") + "% " +
"Min:-" + (100 - (min / avg * 100)).ToString("N1") + "% " +
"Avg:" + avg.ToString("N1") + " " +
"2σ:" + (sigma / avg * 2 * 100).ToString("N1") + "%";
}
else
{
title = "Max:" + max.ToString("N1") + " " +
"Min:" + min.ToString("N1") + " " +
"Avg:" + avg.ToString("N1") + " " +
"2σ:" + (sigma * 2).ToString("N1");
}
}
goto _end;
_err:
//title = Properties.Resources.StrMax + ":" + "NULL " +
// Properties.Resources.StrMin+":"+"NULL "+
// Properties.Resources.StrAvg+":"+"NULL "+
// "3Sigma:"+"NULL ";
title = "Max:null Min:null Avg:null 2σ:null";
_end:
CalState = title;
UpdateDataCalRange();
}
///
/// DataSource 里面的数据都是 EmptyValue 组成, 当修改数据时,应该clear ,再添加
///
private bool DataSourceIsEmpty = false;
///
/// 当一个数据都没有时,需要添加空数据
///
public void CheckDataSourceEmpty()
{
if ((DataSource == null) || (DataSource.Count() == 0))
{
chart1.Series["series_avg"].Points.Clear();
chart1.Series["series_avg"].Points.AddXY(FirstBoltNo, EmptyValue);
chart1.Series["series_avg"].Points[0].IsEmpty = true;
DataSourceIsEmpty = true;
}
else
{
DataSourceIsEmpty = false;
}
}
void dataSource_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
mRefresh.UpdateData = true;
}
public void Button_Click(object sender, RoutedEventArgs e)
{
ShowSettingDialogEvent?.Invoke(this, new EventArgs());
}
private void Button2_Click(object sender, RoutedEventArgs e)
{
TitleClickEvent?.Invoke(this, new EventArgs());
}
#region INotifyPropertyChanged 成员
public void NotifyPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
PropertyChanged.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
public event PropertyChangedEventHandler PropertyChanged;
#endregion
}
public struct GraphScan4Data
{
public int Avg;
public int Sigma;
}
}