using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Collections.ObjectModel;
using System.Data;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms.DataVisualization.Charting;
namespace FLY.ControlLibrary
{
///
/// GraphScan.xaml 的交互逻辑
///
public partial class GraphScan_coslight : GraphScan
{
public GraphScan_coslight():base()
{
this.chart1.SizeChanged += new EventHandler(chart1_SizeChanged);
this.PropertyChanged += new PropertyChangedEventHandler(GraphScan_coslight_PropertyChanged);
}
void GraphScan_coslight_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == "IsReversed")
{
chart1.ChartAreas[0].AxisX.IsReversed = IsReversed;
if (!IsReversed)
chart1.ChartAreas[0].Position.X = 0F;
else
chart1.ChartAreas[0].Position.X = 100F - chart1.ChartAreas[0].Position.Width;
}
}
///
/// 解决右边坐标显示问题
///
///
///
void chart1_SizeChanged(object sender, EventArgs e)
{
ChartArea area = chart1.ChartAreas[0];
Graphics g = chart1.CreateGraphics();
SizeF size = g.MeasureString("目标值", area.AxisY.LabelStyle.Font);//获取字符串尺寸
float pw = 100 * (chart1.Width - size.Width - 10) / chart1.Width;
chart1.ChartAreas[0].Position.Width = (int)pw;
chart1.ChartAreas[0].Position.Height = 100F;
chart1.ChartAreas[0].Position.Y = 0F;
if (!IsReversed)
chart1.ChartAreas[0].Position.X = 0F;
else
chart1.ChartAreas[0].Position.X = 100F - chart1.ChartAreas[0].Position.Width;
g.Dispose();
}
///
/// 获取实际应用的目标值,公差
///
///
///
///
///
///
void GetActualTargetAlarm(
out double target,
out double alarm,
out double yrange,
out double ctrlline,
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;
}
ctrlline = CtrlLine / multi;
}
///
/// 画虚线 与 右坐标
///
///
///
protected override void Chart1_PrePaint(object sender, System.Windows.Forms.DataVisualization.Charting.ChartPaintEventArgs e)
{
if (e.ChartElement is ChartArea)
{
ChartArea area = (ChartArea)e.ChartElement;
if (Double.IsNaN(area.AxisY.Minimum))
return;
double alarm;
double yrange;
double target;
double ctrlline;
bool ispercent;
GetActualTargetAlarm(out target, out alarm, out yrange, out ctrlline, out ispercent);
//画目标值
System.Drawing.Pen pen = new System.Drawing.Pen(System.Drawing.Color.Green, 2);
DrawYGridTick(e.ChartGraphics, pen, target);
//画规格线
if (alarm < yrange)
{
pen.Color = System.Drawing.Color.Red;
DrawYGridTick(e.ChartGraphics, pen, target + alarm);
DrawYGridTick(e.ChartGraphics, pen, target - alarm);
}
//画控制线
if (HasCtrlLine)
{
if (ctrlline < yrange)
{
pen.Color = System.Drawing.Color.Orange;
pen.DashStyle = System.Drawing.Drawing2D.DashStyle.Custom;
pen.DashPattern = new float[] { 5, 5 };
DrawYGridTick(e.ChartGraphics, pen, target + ctrlline);
pen.Color = System.Drawing.Color.Blue;
DrawYGridTick(e.ChartGraphics, pen, target - ctrlline);
}
}
//写字
//if (y > area.AxisY.Maximum || y < area.AxisY.Minimum)
// return;
ChartGraphics cg = e.ChartGraphics;
Graphics graph = cg.Graphics;
RectangleF rectangele_target = new RectangleF();
RectangleF rectangele_alarm_min = new RectangleF();
RectangleF rectangele_alarm_max = new RectangleF();
RectangleF rectangele_ctrlline_min = new RectangleF();
RectangleF rectangele_ctrlline_max = new RectangleF();
rectangele_target.Size = graph.MeasureString("目标值", area.AxisY.LabelStyle.Font);//获取字符串尺寸
double XMax = cg.GetPositionFromAxis(area.Name, AxisName.X, area.AxisX.Maximum);
cg.GetAbsolutePoint(
new System.Drawing.PointF()
{
X = (float)(XMax),
Y = 0
});
// Convert relative coordinates to absolute coordinates.
rectangele_target.Location = cg.GetAbsolutePoint(new System.Drawing.PointF() { X = (float)(XMax), Y = (float)cg.GetPositionFromAxis(area.Name, AxisName.Y, target) });
if (!IsReversed)
rectangele_target.X += 2;
else
rectangele_target.X -= (rectangele_target.Width + 2);
rectangele_target.Y -= rectangele_target.Height / 2;//移到中间
graph.DrawString(
"目标值",
area.AxisY.LabelStyle.Font,
new System.Drawing.SolidBrush(System.Drawing.Color.Green), rectangele_target);
//画控制线
if (HasCtrlLine)
{
if ((ctrlline < yrange) && (ctrlline < alarm))
{
rectangele_ctrlline_min.Size = graph.MeasureString("控制线", area.AxisY.LabelStyle.Font);//获取字符串尺寸
// Convert relative coordinates to absolute coordinates.
rectangele_ctrlline_min.Location =
cg.GetAbsolutePoint(
new System.Drawing.PointF()
{
X = (float)(XMax),
Y = (float)cg.GetPositionFromAxis(area.Name, AxisName.Y, target - ctrlline)
});
if (!IsReversed)
rectangele_ctrlline_min.X += 2;
else
rectangele_ctrlline_min.X -= (rectangele_ctrlline_min.Width + 2);
rectangele_ctrlline_min.Y -= rectangele_ctrlline_min.Height / 2;//移到中间
if (rectangele_ctrlline_min.Top < rectangele_target.Bottom)
{
rectangele_ctrlline_min.Y = rectangele_target.Bottom;
}
graph.DrawString(
"控制线",
area.AxisY.LabelStyle.Font,
new System.Drawing.SolidBrush(System.Drawing.Color.Blue), rectangele_ctrlline_min);
rectangele_ctrlline_max.Size = graph.MeasureString("控制线", area.AxisY.LabelStyle.Font);//获取字符串尺寸
// Convert relative coordinates to absolute coordinates.
rectangele_ctrlline_max.Location =
cg.GetAbsolutePoint(
new System.Drawing.PointF()
{
X = (float)(XMax),
Y = (float)cg.GetPositionFromAxis(area.Name, AxisName.Y, target + ctrlline)
});
if (!IsReversed)
rectangele_ctrlline_max.X += 2;
else
rectangele_ctrlline_max.X -= (rectangele_ctrlline_max.Width + 2);
rectangele_ctrlline_max.Y -= rectangele_ctrlline_max.Height / 2;//移到中间
if (rectangele_ctrlline_max.Bottom > rectangele_target.Top)
{
rectangele_ctrlline_max.Y = rectangele_target.Top - rectangele_ctrlline_max.Height;
}
graph.DrawString(
"控制线",
area.AxisY.LabelStyle.Font,
new System.Drawing.SolidBrush(System.Drawing.Color.Orange), rectangele_ctrlline_max);
}
}
//规格线
if (alarm < yrange)
{
rectangele_alarm_min.Size = graph.MeasureString("规格线", area.AxisY.LabelStyle.Font);//获取字符串尺寸
// Convert relative coordinates to absolute coordinates.
rectangele_alarm_min.Location =
cg.GetAbsolutePoint(
new System.Drawing.PointF()
{
X = (float)(XMax),
Y = (float)cg.GetPositionFromAxis(area.Name, AxisName.Y, target - alarm)
});
if (!IsReversed)
rectangele_alarm_min.X += 2;
else
rectangele_alarm_min.X -= (rectangele_alarm_min.Width + 2);
rectangele_alarm_min.Y -= rectangele_alarm_min.Height / 2;//移到中间
if (HasCtrlLine && (ctrlline < alarm))
{
if (rectangele_alarm_min.Top < rectangele_ctrlline_min.Bottom)
{
rectangele_alarm_min.Y = rectangele_ctrlline_min.Bottom;
}
}
else
{
if (rectangele_alarm_min.Top < rectangele_target.Bottom)
{
rectangele_alarm_min.Y = rectangele_target.Bottom;
}
}
graph.DrawString(
"规格线",
area.AxisY.LabelStyle.Font,
new System.Drawing.SolidBrush(System.Drawing.Color.Red), rectangele_alarm_min);
rectangele_alarm_max.Size = graph.MeasureString("规格线", area.AxisY.LabelStyle.Font);//获取字符串尺寸
// Convert relative coordinates to absolute coordinates.
rectangele_alarm_max.Location =
cg.GetAbsolutePoint(
new System.Drawing.PointF()
{
X = (float)(XMax),
Y = (float)cg.GetPositionFromAxis(area.Name, AxisName.Y, target + alarm)
});
if (!IsReversed)
rectangele_alarm_max.X += 2;
else
rectangele_alarm_max.X -= (rectangele_alarm_max.Width + 2);
rectangele_alarm_max.Y -= rectangele_alarm_max.Height / 2;//移到中间
if (HasCtrlLine && (ctrlline < alarm))
{
if (rectangele_alarm_max.Bottom > rectangele_ctrlline_max.Top)
{
rectangele_alarm_max.Y = rectangele_ctrlline_max.Top - rectangele_alarm_max.Height;
}
}
else
{
if (rectangele_alarm_max.Bottom > rectangele_target.Top)
{
rectangele_alarm_max.Y = rectangele_target.Top - rectangele_alarm_max.Height;
}
}
graph.DrawString(
"规格线",
area.AxisY.LabelStyle.Font,
new System.Drawing.SolidBrush(System.Drawing.Color.Red), rectangele_alarm_max);
}
}
}
void DrawYGridTick(ChartGraphics cg, System.Drawing.Pen pen, double y)
{
ChartArea area = chart1.ChartAreas[0];
if (y > area.AxisY.Maximum || y < area.AxisY.Minimum)
return;
// Take Graphics object from chart
Graphics graph = cg.Graphics;
// Convert X and Y values to screen position
double py = cg.GetPositionFromAxis(area.Name, AxisName.Y, y);
double XMin = cg.GetPositionFromAxis(area.Name, AxisName.X, area.AxisX.Minimum);
double XMax = cg.GetPositionFromAxis(area.Name, AxisName.X, area.AxisX.Maximum);
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)py;
// Convert relative coordinates to absolute coordinates.
points[0] = cg.GetAbsolutePoint(points[0]);
points[1] = cg.GetAbsolutePoint(points[1]);
graph.DrawLine(pen, points[0], points[1]);
}
void DrawYLabel(ChartGraphics cg, System.Drawing.Brush brush, Font font, double y, string msg)
{
ChartArea area = chart1.ChartAreas[0];
if (y > area.AxisY.Maximum || y < area.AxisY.Minimum)
return;
// Take Graphics object from chart
Graphics graph = cg.Graphics;
// Convert X and Y values to screen position
double py = cg.GetPositionFromAxis(area.Name, AxisName.Y, y);
double XMax = cg.GetPositionFromAxis(area.Name, AxisName.X, area.AxisX.Maximum);
System.Drawing.PointF point = new System.Drawing.PointF();
point.X = (float)XMax;
point.Y = (float)py;
// Convert relative coordinates to absolute coordinates.
point = cg.GetAbsolutePoint(point);
graph.DrawString(msg, font, brush, point);
}
///
/// 与 Multi,Target,YRange,Alarm 相关
///
public override void UpdateAxisY()
{
double alarm;
double yrange;
double target;
double ctrlline;
bool ispercent;
GetActualTargetAlarm(out target, out alarm, out yrange, out ctrlline, out ispercent);
Axis axisY = chart1.ChartAreas["Default"].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.Red, ispercent, null);
SetCustomLabel(axisY, target - alarm, GridTickTypes.All, System.Drawing.Color.Red, ispercent, null);
//显示范围数值
SetCustomLabel(axisY, axisY.Minimum, GridTickTypes.All, System.Drawing.Color.DarkViolet, ispercent, null);
SetCustomLabel(axisY, axisY.Maximum, GridTickTypes.All, System.Drawing.Color.DarkViolet, ispercent, null);
//显示范围数值
if (yrange != 2 * alarm)
{
SetCustomLabel(axisY, target + alarm * 2, GridTickTypes.TickMark, System.Drawing.Color.Black, ispercent, null);
SetCustomLabel(axisY, target - alarm * 2, 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);
}
}
protected override void UpdateOnePoint(int index)
{
double multi = Multi;
int emptyvalue = EmptyValue;
DataPoint point;
if (index >= chart1.Series["Series 1"].Points.Count)
{
chart1.Series["Series 1"].Points.AddXY(
FirstBoltNo + index,
(double)DataSource[index] / multi);
point = chart1.Series["Series 1"].Points[index];
}
else
{
point = chart1.Series["Series 1"].Points[index];
point.YValues[0] = DataSource[index] / multi;
point.XValue = FirstBoltNo + index;
}
//设定空数据
if (DataSource[index] == emptyvalue)
{
point.IsEmpty = true;
}
else
{
point.IsEmpty = false;
}
System.Drawing.Color c;
double alarm;
double yrange;
double target;
double ctrlline;
bool ispercent;
GetActualTargetAlarm(out target, out alarm, out yrange, out ctrlline, out ispercent);
double data = DataSource[index] / multi;
if (data > (target + yrange))
{
c = System.Drawing.Color.Violet;
}
else if (data > (target + alarm))
{
c = System.Drawing.Color.Red;
}
else if (data >= (target - alarm))
{
if (HasCtrlLine)
{
if (data > (target + ctrlline))
{
c = System.Drawing.Color.Orange;
}
else if (data >= (target - ctrlline))
{
c = System.Drawing.Color.Green;
}
else
{
c = System.Drawing.Color.FromArgb(0x00,0x8B,0xE5);
}
}
else
{
c = System.Drawing.Color.Green;
}
}
else if (data >= (target - yrange))
{
c = System.Drawing.Color.Red;
}
else
{
c = System.Drawing.Color.Violet;
}
if (ChartType == SeriesChartType.Line)
{
point.MarkerColor = c;
point.BorderColor = chart1.Series["Series 1"].BorderColor;
point.Color = chart1.Series["Series 1"].Color;
}
else
{
point.MarkerColor = c;
point.BorderColor = c;
point.Color = c;
}
}
}
}