rawaccel/grapher/Models/Charts/ChartXY.cs
2021-07-10 14:21:26 -07:00

411 lines
12 KiB
C#

using grapher.Models.Mouse;
using System;
using System.Collections;
using System.Windows.Forms.DataVisualization.Charting;
namespace grapher
{
public class ChartXY
{
#region Fields
public static ElementPosition DefaultLegendPosition = new ElementPosition(25, 0, 50, 25);
public static ElementPosition GainLegendPosition = new ElementPosition(25, -1, 50, 25);
#endregion Fields
#region Constructors
public ChartXY(Chart chartX, Chart chartY, string title)
{
ChartX = chartX;
ChartY = chartY;
Title = title;
ChartY.Top = ChartX.Top;
ChartY.Height = ChartX.Height;
ChartY.Width = ChartX.Width;
ChartY.Left = ChartX.Left + ChartX.Width + Constants.ChartSeparationHorizontal;
SetupChart(ChartX);
SetupChart(ChartY);
Combined = false;
SetCombined();
Visible = true;
}
#endregion Constructors
private const double VerticalMargin = 0.1;
#region Properties
public Chart ChartX { get; }
public Chart ChartY { get; }
public int Height {
get
{
return ChartX.Height;
}
}
public int Width {
get
{
if (Combined)
{
return ChartX.Width;
}
else
{
return ChartY.Left + ChartY.Width - ChartX.Left;
}
}
}
public int Top {
get
{
return ChartX.Top;
}
}
public int Left {
get
{
return ChartX.Left;
}
}
public bool Combined { get; set; }
public bool Visible { get; set; }
public string Title { get; }
private PointData CombinedPointData { get; set; }
private PointData XPointData { get; set; }
private PointData YPointData { get; set; }
#endregion Properties
#region Methods
public static void setChartColors(Chart chart, System.Drawing.Color fgColor, System.Drawing.Color bgColor)
{
chart.ForeColor = fgColor;
chart.BackColor = bgColor;
chart.Titles[0].ForeColor = fgColor;
chart.ChartAreas[0].AxisX.LabelStyle.ForeColor = fgColor;
chart.ChartAreas[0].AxisY.LabelStyle.ForeColor = fgColor;
chart.ChartAreas[0].AxisX.LineColor = fgColor;
chart.ChartAreas[0].AxisY.LineColor = fgColor;
chart.ChartAreas[0].AxisY.MajorTickMark.LineColor = fgColor;
chart.ChartAreas[0].AxisX.MajorTickMark.LineColor = fgColor;
chart.ChartAreas[0].AxisX.MajorGrid.LineColor = fgColor;
chart.ChartAreas[0].AxisY.MajorGrid.LineColor = fgColor;
chart.ChartAreas[0].AxisX.MinorGrid.LineColor = fgColor;
chart.Legends[0].ForeColor = fgColor;
chart.ChartAreas[0].AxisX.TitleForeColor = fgColor;
chart.ChartAreas[0].AxisY.TitleForeColor = fgColor;
chart.ChartAreas[0].BorderColor = fgColor;
}
public static void SetupChart(Chart chart)
{
ChartArea area = chart.ChartAreas[0];
Legend legend = chart.Legends[0];
Title title = chart.Titles[0];
area.AxisX.RoundAxisValues();
area.AxisX.ScaleView.Zoomable = true;
area.AxisY.ScaleView.Zoomable = true;
area.AxisY.ScaleView.MinSize = 0.01;
area.AxisY.ScaleView.SmallScrollSize = 0.001;
area.AxisX.LabelStyle.Format = "0.##";
area.AxisY.LabelStyle.Format = "0.##";
area.CursorY.Interval = 0.001;
area.CursorX.AutoScroll = true;
area.CursorY.AutoScroll = true;
area.CursorX.IsUserSelectionEnabled = true;
area.CursorY.IsUserSelectionEnabled = true;
area.CursorX.IsUserEnabled = true;
area.CursorY.IsUserEnabled = true;
chart.Series[1].Points.Clear();
chart.Series[1].Points.AddXY(0, 0);
area.AxisX.TitleFont = new System.Drawing.Font(area.AxisX.TitleFont.Name, Constants.ChartAxisFontSize, System.Drawing.FontStyle.Bold);
area.AxisY.TitleFont = area.AxisX.TitleFont;
title.Font = new System.Drawing.Font(title.Font.Name, Constants.ChartTitleFontSize, System.Drawing.FontStyle.Italic | System.Drawing.FontStyle.Bold);
chart.Series[0].BorderWidth = Constants.ChartSeriesLineWidth;
chart.Series[0].MarkerSize = Constants.ChartSeriesLineWidth * 2;
chart.Series[2].BorderWidth = Constants.ChartSeriesLineWidth;
chart.Series[2].MarkerSize = Constants.ChartSeriesLineWidth * 2;
area.AxisX.MinorGrid.Enabled = true;
area.AxisX.MinorGrid.LineDashStyle = ChartDashStyle.Dot;
title.Alignment = System.Drawing.ContentAlignment.MiddleCenter;
legend.DockedToChartArea = area.Name;
legend.LegendStyle = LegendStyle.Row;
legend.IsTextAutoFit = true;
legend.MaximumAutoSize = 100;
legend.AutoFitMinFontSize = 5;
ElementPosition legendPosNew = DefaultLegendPosition;
legend.Position = legendPosNew;
System.Drawing.Color bgTrans = System.Drawing.Color.Transparent;
area.BackColor = bgTrans;
legend.BackColor = bgTrans;
}
public static void DrawPoint(Chart chart, PointData pointOne, PointData pointTwo = null)
{
if (chart.Visible)
{
pointOne.Get(out var x, out var y);
chart.Series[1].Points.DataBindXY(x, y);
if (pointTwo != null)
{
pointTwo.Get(out x, out y);
chart.Series[3].Points.DataBindXY(x, y);
}
}
}
public static void SetLogarithmic(Chart chart)
{
/*
chart.ChartAreas[0].AxisX.Minimum = 0.001;
chart.ChartAreas[0].AxisX.Maximum = 3500;
chart.ChartAreas[0].AxisY.Minimum = 0.001;
chart.ChartAreas[0].AxisY.Maximum = 10;
chart.ChartAreas[0].AxisX.IsLogarithmic = true;
chart.ChartAreas[0].AxisY.IsLogarithmic = true;
*/
}
public static void SetStandard(Chart chart)
{
/*
chart.ChartAreas[0].AxisX.IsLogarithmic = false;
chart.ChartAreas[0].AxisY.IsLogarithmic = false;
*/
}
public void ClearSecondDots()
{
ChartX.Series[3].Points.Clear();
}
public void Update()
{
ChartX.Update();
if (ChartY.Visible)
{
ChartY.Update();
}
}
public void SetPointBinds(PointData combined, PointData x, PointData y)
{
CombinedPointData = combined;
XPointData = x;
YPointData = y;
}
public void DrawLastMovementValue(bool twoDotsPerGraph = false)
{
if(Combined)
{
if (twoDotsPerGraph)
{
DrawPoint(ChartX, XPointData, YPointData);
}
else
{
DrawPoint(ChartX, CombinedPointData);
}
}
else
{
DrawPoint(ChartX, XPointData);
DrawPoint(ChartY, YPointData);
}
}
public void ClearLastValue()
{
ChartX.Series[1].Points.Clear();
ChartY.Series[1].Points.Clear();
}
public void Bind(IDictionary data)
{
ChartX.Series[0].Points.DataBindXY(data.Keys, data.Values);
ChartX.Series[2].IsVisibleInLegend = false;
ChartX.Series[2].Points.Clear();
}
public void BindXY(IDictionary dataX, IDictionary dataY)
{
ChartX.Series[0].Points.DataBindXY(dataX.Keys, dataX.Values);
ChartY.Series[0].Points.DataBindXY(dataY.Keys, dataY.Values);
ChartX.Series[2].IsVisibleInLegend = false;
ChartX.Series[2].Points.Clear();
}
public void BindXYCombined(IDictionary dataX, IDictionary dataY)
{
ChartX.Series[0].Points.DataBindXY(dataX.Keys, dataX.Values);
ChartX.Series[2].Points.DataBindXY(dataY.Keys, dataY.Values);
ChartX.Series[2].IsVisibleInLegend = true;
}
public void SetLegendPosition(ElementPosition position)
{
ChartX.Legends[0].Position = position;
ChartY.Legends[0].Position = position;
}
private void VerifyRange(double min, double max)
{
if (min > max)
{
throw new ArgumentException($"invalid chart range: ({min}, {max})");
}
}
public void SetMinMax(double min, double max)
{
VerifyRange(min, max);
ChartX.ChartAreas[0].AxisY.Minimum = min * (1 - VerticalMargin);
ChartX.ChartAreas[0].AxisY.Maximum = max * (1 + VerticalMargin);
}
public void SetMinMaxXY(double minX, double maxX, double minY, double maxY)
{
VerifyRange(minX, maxX);
ChartX.ChartAreas[0].AxisY.Minimum = minX * (1 - VerticalMargin);
ChartX.ChartAreas[0].AxisY.Maximum = maxX * (1 + VerticalMargin);
VerifyRange(minY, maxY);
ChartY.ChartAreas[0].AxisY.Minimum = minY * (1 - VerticalMargin);
ChartY.ChartAreas[0].AxisY.Maximum = maxY * (1 + VerticalMargin);
}
public void SetCombined()
{
if (!Combined)
{
ChartY.Hide();
Combined = true;
ChartX.Titles[0].Text = Title;
}
}
public void SetSeparate()
{
if (Combined)
{
if (Visible)
{
ChartY.Show();
}
ChartX.Titles[0].Text = SetComponentTitle(Constants.XComponent);
ChartY.Titles[0].Text = SetComponentTitle(Constants.YComponent);
Combined = false;
}
}
public void Hide()
{
if (Visible)
{
ChartX.Hide();
ChartY.Hide();
Visible = false;
}
}
public void Show()
{
if (!Visible)
{
ChartX.Show();
if (!Combined)
{
ChartY.Show();
}
Visible = true;
}
}
public void SetTop(int top)
{
ChartX.Top = top;
ChartY.Top = top;
}
public void SetHeight(int height)
{
ChartX.Height = height;
ChartY.Height = height;
}
public void SetStreaming(bool streaming)
{
var fgColor = Constants.fgNoStreamer;
var bgColor = Constants.bgNoStreamer;
if (streaming)
{
fgColor = Constants.fgStreamer;
bgColor = Constants.bgStreamer;
}
setChartColors(ChartX, fgColor, bgColor);
setChartColors(ChartY, fgColor, bgColor);
Update();
}
private string SetComponentTitle(string component)
{
return $"{Title} : {component}";
}
#endregion Methods
}
}