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; using WeifenLuo.WinFormsUI.Docking; using LiveCharts; using LiveCharts.Wpf; using LiveCharts.WinForms; using LiveCharts.Defaults; using System.Windows.Media; using System.Timers; namespace friction { public partial class PanelTrendGraph : DockContent { public enum GRAPH_TYPE { NONE, HUMIDITY, TEMPERATURE, FORCE, VELOCITY } MainForm m_Owner = null; DataHandler m_DataHandler = null; string m_CurSpring = ""; string m_CurTable = ""; GRAPH_TYPE m_GraphType = GRAPH_TYPE.NONE; // for report bool m_bReport = false; System.Windows.Forms.Timer m_ReportTimer = null; public PanelTrendGraph(MainForm owner, DataHandler data) { InitializeComponent(); m_Owner = owner; m_DataHandler = data; Theme.Apply(this); Theme.Apply(trendChart); Theme.Apply(groupBox1); Theme.Apply(rbHumidity); Theme.Apply(rbTemp); lbPair.ForeColor = Theme.Orange; trendChart.AxisX.Add(new Axis { Title = "Humidity", }); trendChart.AxisY.Add(new Axis { Title = "RPN", MinValue = 0, MaxValue = 10, Sections = new SectionsCollection { new AxisSection { Value = 5, SectionWidth = 5, Fill = new SolidColorBrush { Color = System.Windows.Media.Color.FromArgb(Theme.Red.A, Theme.Red.R, Theme.Red.G, Theme.Red.B), Opacity = .25 } }, new AxisSection { Value = 3, SectionWidth = 2, Fill = new SolidColorBrush { Color = System.Windows.Media.Color.FromArgb(Theme.Yellow.A, Theme.Yellow.R, Theme.Yellow.G, Theme.Yellow.B), Opacity = .25 } }, new AxisSection { Value = 0, SectionWidth = 3, Fill = new SolidColorBrush { Color = System.Windows.Media.Color.FromArgb(Theme.Green.A, Theme.Green.R, Theme.Green.G, Theme.Green.B), Opacity = .25 } } } }); trendChart.LegendLocation = LegendLocation.Right; trendChart.DataClick += TrendChart_DataClick; trendChart.DefaultLegend.Foreground = new SolidColorBrush( System.Windows.Media.Color.FromArgb( Theme.Forecolor.A, Theme.Forecolor.R, Theme.Forecolor.G, Theme.Forecolor.B)); } public void Reset() { m_CurSpring = ""; m_CurTable = ""; m_GraphType = GRAPH_TYPE.NONE; } private void TrendChart_DataClick(object sender, ChartPoint chartPoint) { switch (m_GraphType) { case GRAPH_TYPE.HUMIDITY: m_Owner.OnTrendSelectByHumidity(m_CurSpring, m_CurTable, (float)chartPoint.X, (float)chartPoint.Y); break; case GRAPH_TYPE.TEMPERATURE: m_Owner.OnTrendSelectByTemperature(m_CurSpring, m_CurTable, (float)chartPoint.X, (float)chartPoint.Y); break; case GRAPH_TYPE.FORCE: m_Owner.OnTrendSelectByForce(m_CurSpring, m_CurTable, (float)chartPoint.X, (float)chartPoint.Y); break; case GRAPH_TYPE.VELOCITY: m_Owner.OnTrendSelectByVelocity(m_CurSpring, m_CurTable, (float)chartPoint.X, (float)chartPoint.Y); break; } } private void UpdateGraphHumidity() { string strSpring = m_DataHandler.GetCurSpring(); string strTable = m_DataHandler.GetCurTable(); var Chart = m_DataHandler.GetTrendChart(strSpring, strTable); if (Chart.Count <= 0) return; trendChart.AxisX[0].Title = "Humidity"; ChartValues[] Points = { new ChartValues(), new ChartValues(), new ChartValues() }; var Values = new List(); foreach (var pnt in Chart) { if (pnt.TEMPERATURE < 0) Points[0].Add(new ScatterPoint(pnt.HUMIDITY, pnt.RPN, 2)); else if (pnt.TEMPERATURE > 30) Points[2].Add(new ScatterPoint(pnt.HUMIDITY, pnt.RPN, 2)); else Points[1].Add(new ScatterPoint(pnt.HUMIDITY, pnt.RPN, 2)); Values.Add(new TrendLine.POINT { X = pnt.HUMIDITY, Y = pnt.RPN }); } Values.Sort((a, b) => (a.X == b.X) ? 0 : (a.X < b.X) ? -1 : 1); TrendLine trendline = new TrendLine(Values); ChartValues TrendPoints = new ChartValues(); TrendPoints.Add(new ScatterPoint(Values[0].X, trendline.GetY(Values[0].X))); TrendPoints.Add(new ScatterPoint(Values[Values.Count / 2].X, trendline.GetY(Values[Values.Count / 2].X))); TrendPoints.Add(new ScatterPoint(Values[Values.Count - 1].X, trendline.GetY(Values[Values.Count - 1].X))); System.Windows.Media.SolidColorBrush[] brushes = { System.Windows.Media.Brushes.DodgerBlue.Clone(), System.Windows.Media.Brushes.Green.Clone(), System.Windows.Media.Brushes.IndianRed.Clone() }; foreach (var brush in brushes) brush.Opacity = 1; trendChart.Series = new SeriesCollection { new ScatterSeries { Title = "Low Temp", Values = Points[0], Fill = brushes[0], LabelPoint = p => string.Format("{0:n2}, {1}", p.X, p.Y), }, new ScatterSeries { Title = "Mid Temp", Values = Points[1], Fill = brushes[1], LabelPoint = p => string.Format("{0:n2}, {1}", p.X, p.Y), }, new ScatterSeries { Title = "High Temp", Values = Points[2], Fill = brushes[2], LabelPoint = p => string.Format("{0:n2}, {1}", p.X, p.Y), }, new LineSeries { Title = "Trend", Values = TrendPoints, PointGeometry = DefaultGeometries.None, StrokeThickness = 4, Stroke = System.Windows.Media.Brushes.Orange, }, }; trendChart.AxisX[0].MinValue = Chart.Min(r => r.HUMIDITY - 1); trendChart.AxisX[0].MaxValue = Chart.Max(r => r.HUMIDITY - 1); m_CurSpring = strSpring; m_CurTable = strTable; } private void UpdateGraphTemperature() { string strSpring = m_DataHandler.GetCurSpring(); string strTable = m_DataHandler.GetCurTable(); var Chart = m_DataHandler.GetTrendChart(strSpring, strTable); if (Chart.Count <= 0) return; trendChart.AxisX[0].Title = "Temperature"; ChartValues[] Points = { new ChartValues(), new ChartValues() }; var Values = new List(); foreach (var pnt in Chart) { if (pnt.HUMIDITY <= 60) Points[0].Add(new ScatterPoint(pnt.TEMPERATURE, pnt.RPN, 2)); else Points[1].Add(new ScatterPoint(pnt.TEMPERATURE, pnt.RPN, 2)); Values.Add(new TrendLine.POINT { X = pnt.TEMPERATURE, Y = pnt.RPN }); } Values.Sort((a, b) => (a.X == b.X) ? 0 : (a.X < b.X) ? -1 : 1); TrendLine trendline = new TrendLine(Values); ChartValues TrendPoints = new ChartValues(); TrendPoints.Add(new ScatterPoint(Values[0].X, trendline.GetY(Values[0].X))); TrendPoints.Add(new ScatterPoint(Values[Values.Count / 2].X, trendline.GetY(Values[Values.Count / 2].X))); TrendPoints.Add(new ScatterPoint(Values[Values.Count - 1].X, trendline.GetY(Values[Values.Count - 1].X))); trendChart.Series = new SeriesCollection { new ScatterSeries { Title = "Low Humidity", Values = Points[0], Foreground = System.Windows.Media.Brushes.SkyBlue, LabelPoint = p => string.Format("{0:n2}, {1}", p.X, p.Y), }, new ScatterSeries { Title = "High Humidity", Values = Points[1], Foreground = System.Windows.Media.Brushes.DarkBlue, LabelPoint = p => string.Format("{0:n2}, {1}", p.X, p.Y), }, new LineSeries { Title = "Trend", Values = TrendPoints, PointGeometry = DefaultGeometries.None, StrokeThickness = 4, }, }; trendChart.AxisX[0].MinValue = Chart.Min(r => r.HUMIDITY - 1); trendChart.AxisX[0].MaxValue = Chart.Max(r => r.HUMIDITY - 1); } private void UpdateGraphForce() { string strSpring = m_DataHandler.GetCurSpring(); string strTable = m_DataHandler.GetCurTable(); var Chart = m_DataHandler.GetTrendChart(strSpring, strTable); if (Chart.Count <= 0) return; trendChart.AxisX[0].Title = "Force"; var Points = new ChartValues(); var Values = new List(); foreach (var pnt in Chart) { Points.Add(new ScatterPoint(pnt.FORCE, pnt.RPN, 2)); Values.Add(new TrendLine.POINT { X = pnt.FORCE, Y = pnt.RPN }); } Values.Sort((a, b) => (a.X == b.X) ? 0 : (a.X < b.X) ? -1 : 1); TrendLine trendline = new TrendLine(Values); ChartValues TrendPoints = new ChartValues(); TrendPoints.Add(new ScatterPoint(Values[0].X, trendline.GetY(Values[0].X))); TrendPoints.Add(new ScatterPoint(Values[Values.Count / 2].X, trendline.GetY(Values[Values.Count / 2].X))); TrendPoints.Add(new ScatterPoint(Values[Values.Count - 1].X, trendline.GetY(Values[Values.Count - 1].X))); trendChart.Series = new SeriesCollection { new ScatterSeries { Title = "RPN by force", Values = Points, Foreground = System.Windows.Media.Brushes.SkyBlue, LabelPoint = p => string.Format("{0:n2}, {1}", p.X, p.Y), }, new LineSeries { Title = "Trend", Values = TrendPoints, PointGeometry = DefaultGeometries.None, StrokeThickness = 4, }, }; trendChart.AxisX[0].MinValue = Chart.Min(r => r.HUMIDITY - 1); trendChart.AxisX[0].MaxValue = Chart.Max(r => r.HUMIDITY - 1); } private void UpdateGraphVelocity() { string strSpring = m_DataHandler.GetCurSpring(); string strTable = m_DataHandler.GetCurTable(); var Chart = m_DataHandler.GetTrendChart(strSpring, strTable); if (Chart.Count <= 0) return; trendChart.AxisX[0].Title = "Velocity"; var Points = new ChartValues(); var Values = new List(); foreach (var pnt in Chart) { Points.Add(new ScatterPoint(pnt.VELOCITY, pnt.RPN, 2)); Values.Add(new TrendLine.POINT { X = pnt.VELOCITY, Y = pnt.RPN }); } Values.Sort((a, b) => (a.X == b.X) ? 0 : (a.X < b.X) ? -1 : 1); TrendLine trendline = new TrendLine(Values); ChartValues TrendPoints = new ChartValues(); TrendPoints.Add(new ScatterPoint(Values[0].X, trendline.GetY(Values[0].X))); TrendPoints.Add(new ScatterPoint(Values[Values.Count / 2].X, trendline.GetY(Values[Values.Count / 2].X))); TrendPoints.Add(new ScatterPoint(Values[Values.Count - 1].X, trendline.GetY(Values[Values.Count - 1].X))); trendChart.Series = new SeriesCollection { new ScatterSeries { Title = "RPN by velocity", Values = Points, Foreground = System.Windows.Media.Brushes.SkyBlue, LabelPoint = p => string.Format("{0:n2}, {1}", p.X, p.Y), }, new LineSeries { Title = "Trend", Values = TrendPoints, PointGeometry = DefaultGeometries.None, StrokeThickness = 4, }, }; trendChart.AxisX[0].MinValue = Chart.Min(r => r.HUMIDITY - 1); trendChart.AxisX[0].MaxValue = Chart.Max(r => r.HUMIDITY - 1); } public void UpdateGraph(GRAPH_TYPE Type=GRAPH_TYPE.NONE) { if (Type == GRAPH_TYPE.NONE) { if (rbHumidity.Checked == true) UpdateGraph(GRAPH_TYPE.HUMIDITY); else if (rbTemp.Checked == true) UpdateGraph(GRAPH_TYPE.TEMPERATURE); else if (rbForce.Checked == true) UpdateGraph(GRAPH_TYPE.FORCE); else if (rbVelocity.Checked == true) UpdateGraph(GRAPH_TYPE.VELOCITY); return; } string strSpring = m_DataHandler.GetCurSpring(); string strTable = m_DataHandler.GetCurTable(); switch (Type) { case GRAPH_TYPE.HUMIDITY: UpdateGraphHumidity(); break; case GRAPH_TYPE.TEMPERATURE: UpdateGraphTemperature(); break; case GRAPH_TYPE.FORCE: UpdateGraphForce(); break; case GRAPH_TYPE.VELOCITY: UpdateGraphVelocity(); break; } m_CurSpring = strSpring; m_CurTable = strTable; m_GraphType = Type; lbPair.Text = string.Format("{0} vs {1}", strSpring, strTable); } private void rbHumidity_CheckedChanged(object sender, EventArgs e) { UpdateGraph(GRAPH_TYPE.HUMIDITY); } private void rbTemp_CheckedChanged(object sender, EventArgs e) { UpdateGraph(GRAPH_TYPE.TEMPERATURE); } private void rbForce_CheckedChanged(object sender, EventArgs e) { UpdateGraph(GRAPH_TYPE.FORCE); } private void rbVelocity_CheckedChanged(object sender, EventArgs e) { UpdateGraph(GRAPH_TYPE.VELOCITY); } public void CopyChart(GRAPH_TYPE Type) { Cursor.Current = Cursors.WaitCursor; m_bReport = true; trendChart.DisableAnimations = true; UpdateGraph(Type); } private void trendChart_UpdaterTick(object sender) { if(m_bReport == true) { Cursor.Current = Cursors.WaitCursor; m_ReportTimer = new System.Windows.Forms.Timer(); m_ReportTimer.Interval = 500; m_ReportTimer.Tick += new EventHandler(TimerCallback); m_ReportTimer.Start(); Console.WriteLine("Chart Updated ({0})", m_GraphType); } } private void TimerCallback(object sender, EventArgs e) { Console.WriteLine("Chart Timer Callback ({0})", m_GraphType); m_bReport = false; m_ReportTimer.Stop(); this.Invoke(new Action(() => { Bitmap bm = new Bitmap(Width, Height); panelGraph.DrawToBitmap(bm, new Rectangle(panelGraph.Left, panelGraph.Top, panelGraph.Width, panelGraph.Height)); m_Owner.OnChartUpdate(bm, m_GraphType); })); } } }