* UILineChart: 支持数据包括Nan
This commit is contained in:
parent
f11a898b84
commit
39a8472c85
Binary file not shown.
Binary file not shown.
58
SunnyUI.Demo/Charts/FLineChart.Designer.cs
generated
58
SunnyUI.Demo/Charts/FLineChart.Designer.cs
generated
@ -36,8 +36,8 @@
|
||||
this.LineChart = new Sunny.UI.UILineChart();
|
||||
this.uiSymbolButton2 = new Sunny.UI.UISymbolButton();
|
||||
this.timer1 = new System.Windows.Forms.Timer(this.components);
|
||||
this.uiCheckBox1 = new Sunny.UI.UICheckBox();
|
||||
this.uiSymbolButton3 = new Sunny.UI.UISymbolButton();
|
||||
this.cbPoints = new Sunny.UI.UICheckBox();
|
||||
this.cbContainsNan = new Sunny.UI.UICheckBox();
|
||||
((System.ComponentModel.ISupportInitialize)(this.uiImageButton3)).BeginInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.uiImageButton2)).BeginInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.uiImageButton1)).BeginInit();
|
||||
@ -132,41 +132,39 @@
|
||||
//
|
||||
this.timer1.Tick += new System.EventHandler(this.timer1_Tick);
|
||||
//
|
||||
// uiCheckBox1
|
||||
// cbPoints
|
||||
//
|
||||
this.uiCheckBox1.Cursor = System.Windows.Forms.Cursors.Hand;
|
||||
this.uiCheckBox1.Font = new System.Drawing.Font("微软雅黑", 12F);
|
||||
this.uiCheckBox1.Location = new System.Drawing.Point(571, 505);
|
||||
this.uiCheckBox1.MinimumSize = new System.Drawing.Size(1, 1);
|
||||
this.uiCheckBox1.Name = "uiCheckBox1";
|
||||
this.uiCheckBox1.Padding = new System.Windows.Forms.Padding(22, 0, 0, 0);
|
||||
this.uiCheckBox1.Size = new System.Drawing.Size(100, 29);
|
||||
this.uiCheckBox1.TabIndex = 37;
|
||||
this.uiCheckBox1.Text = "显示点";
|
||||
this.uiCheckBox1.CheckedChanged += new System.EventHandler(this.uiCheckBox1_CheckedChanged);
|
||||
this.cbPoints.Cursor = System.Windows.Forms.Cursors.Hand;
|
||||
this.cbPoints.Font = new System.Drawing.Font("微软雅黑", 12F);
|
||||
this.cbPoints.Location = new System.Drawing.Point(571, 505);
|
||||
this.cbPoints.MinimumSize = new System.Drawing.Size(1, 1);
|
||||
this.cbPoints.Name = "cbPoints";
|
||||
this.cbPoints.Padding = new System.Windows.Forms.Padding(22, 0, 0, 0);
|
||||
this.cbPoints.Size = new System.Drawing.Size(95, 27);
|
||||
this.cbPoints.TabIndex = 37;
|
||||
this.cbPoints.Text = "只显示点";
|
||||
this.cbPoints.CheckedChanged += new System.EventHandler(this.uiCheckBox1_CheckedChanged);
|
||||
//
|
||||
// uiSymbolButton3
|
||||
// cbContainsNan
|
||||
//
|
||||
this.uiSymbolButton3.Cursor = System.Windows.Forms.Cursors.Hand;
|
||||
this.uiSymbolButton3.Font = new System.Drawing.Font("微软雅黑", 12F);
|
||||
this.uiSymbolButton3.Location = new System.Drawing.Point(665, 505);
|
||||
this.uiSymbolButton3.MinimumSize = new System.Drawing.Size(1, 1);
|
||||
this.uiSymbolButton3.Name = "uiSymbolButton3";
|
||||
this.uiSymbolButton3.Padding = new System.Windows.Forms.Padding(28, 0, 0, 0);
|
||||
this.uiSymbolButton3.Size = new System.Drawing.Size(100, 27);
|
||||
this.uiSymbolButton3.Symbol = 61952;
|
||||
this.uiSymbolButton3.TabIndex = 38;
|
||||
this.uiSymbolButton3.Text = "数据";
|
||||
this.uiSymbolButton3.Visible = false;
|
||||
this.uiSymbolButton3.Click += new System.EventHandler(this.uiSymbolButton3_Click);
|
||||
this.cbContainsNan.Cursor = System.Windows.Forms.Cursors.Hand;
|
||||
this.cbContainsNan.Font = new System.Drawing.Font("微软雅黑", 12F);
|
||||
this.cbContainsNan.Location = new System.Drawing.Point(571, 535);
|
||||
this.cbContainsNan.MinimumSize = new System.Drawing.Size(1, 1);
|
||||
this.cbContainsNan.Name = "cbContainsNan";
|
||||
this.cbContainsNan.Padding = new System.Windows.Forms.Padding(22, 0, 0, 0);
|
||||
this.cbContainsNan.Size = new System.Drawing.Size(95, 27);
|
||||
this.cbContainsNan.TabIndex = 38;
|
||||
this.cbContainsNan.Text = "包含Nan";
|
||||
this.cbContainsNan.CheckedChanged += new System.EventHandler(this.uiCheckBox2_CheckedChanged);
|
||||
//
|
||||
// FLineChart
|
||||
//
|
||||
this.AllowShowTitle = true;
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;
|
||||
this.ClientSize = new System.Drawing.Size(800, 574);
|
||||
this.Controls.Add(this.uiSymbolButton3);
|
||||
this.Controls.Add(this.uiCheckBox1);
|
||||
this.Controls.Add(this.cbContainsNan);
|
||||
this.Controls.Add(this.cbPoints);
|
||||
this.Controls.Add(this.uiSymbolButton2);
|
||||
this.Controls.Add(this.uiSymbolButton1);
|
||||
this.Controls.Add(this.uiImageButton3);
|
||||
@ -194,7 +192,7 @@
|
||||
private UILineChart LineChart;
|
||||
private UISymbolButton uiSymbolButton2;
|
||||
private System.Windows.Forms.Timer timer1;
|
||||
private UICheckBox uiCheckBox1;
|
||||
private UISymbolButton uiSymbolButton3;
|
||||
private UICheckBox cbPoints;
|
||||
private UICheckBox cbContainsNan;
|
||||
}
|
||||
}
|
@ -29,13 +29,14 @@ namespace Sunny.UI.Demo
|
||||
series.Add(dt.AddHours(0), 1.2);
|
||||
series.Add(dt.AddHours(1), 2.2);
|
||||
series.Add(dt.AddHours(2), 3.2);
|
||||
series.Add(dt.AddHours(3), 4.2);
|
||||
series.Add(dt.AddHours(3), cbContainsNan.Checked ? double.NaN : 4.2);
|
||||
series.Add(dt.AddHours(4), 3.2);
|
||||
series.Add(dt.AddHours(5), 2.2);
|
||||
series.Symbol = UILinePointSymbol.Square;
|
||||
series.SymbolSize = 4;
|
||||
series.SymbolLineWidth = 2;
|
||||
series.SymbolColor = Color.Red;
|
||||
series.ShowLine = !cbPoints.Checked;
|
||||
|
||||
series = option.AddSeries(new UILineSeries("Line2", Color.Lime));
|
||||
series.Add(dt.AddHours(3), 3.3);
|
||||
@ -49,6 +50,7 @@ namespace Sunny.UI.Demo
|
||||
series.SymbolLineWidth = 2;
|
||||
series.SymbolColor = Color.Red;
|
||||
series.Smooth = true;
|
||||
series.ShowLine = !cbPoints.Checked;
|
||||
|
||||
option.GreaterWarningArea = new UILineWarningArea(3.5);
|
||||
option.LessWarningArea = new UILineWarningArea(2.2, Color.Gold);
|
||||
@ -135,14 +137,7 @@ namespace Sunny.UI.Demo
|
||||
|
||||
private void uiCheckBox1_CheckedChanged(object sender, EventArgs e)
|
||||
{
|
||||
if (LineChart.Option == null) return;
|
||||
foreach (var series in LineChart.Option.Series.Values)
|
||||
{
|
||||
series.ShowLine = !uiCheckBox1.Checked;
|
||||
series.Symbol = uiCheckBox1.Checked ? UILinePointSymbol.Circle : UILinePointSymbol.None;
|
||||
}
|
||||
|
||||
LineChart.Refresh();
|
||||
uiSymbolButton1.PerformClick();
|
||||
}
|
||||
|
||||
private void uiSymbolButton3_Click(object sender, EventArgs e)
|
||||
@ -166,7 +161,6 @@ namespace Sunny.UI.Demo
|
||||
series.SymbolSize = 4;
|
||||
series.SymbolLineWidth = 2;
|
||||
series.SymbolColor = Color.Red;
|
||||
series.ContainsNan = true;
|
||||
|
||||
option.XAxis.Name = "日期";
|
||||
option.YAxis.Name = "数值";
|
||||
@ -177,5 +171,10 @@ namespace Sunny.UI.Demo
|
||||
|
||||
LineChart.SetOption(option);
|
||||
}
|
||||
|
||||
private void uiCheckBox2_CheckedChanged(object sender, EventArgs e)
|
||||
{
|
||||
uiSymbolButton1.PerformClick();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -54,10 +54,10 @@ namespace Sunny.UI.Demo
|
||||
Header.SetNodeSymbol(Header.Nodes[2], 61950);
|
||||
parent = Aside.CreateNode("图表", 61950, 24, pageIndex);
|
||||
//直接关联(默认自动生成GUID)
|
||||
Aside.CreateChildNode(parent, AddPage(new FPieChart()));
|
||||
Aside.CreateChildNode(parent, AddPage(new FDoughnutChart()));
|
||||
Aside.CreateChildNode(parent, AddPage(new FBarChart()));
|
||||
Aside.CreateChildNode(parent, AddPage(new FDoughnutChart()));
|
||||
Aside.CreateChildNode(parent, AddPage(new FLineChart()));
|
||||
Aside.CreateChildNode(parent, AddPage(new FPieChart()));
|
||||
|
||||
pageIndex = 4000;
|
||||
Header.SetNodePageIndex(Header.Nodes[3], pageIndex);
|
||||
|
@ -133,11 +133,6 @@ namespace Sunny.UI
|
||||
Bars.Clear();
|
||||
NeedDraw = false;
|
||||
if (Option == null || Option.Series == null || Option.SeriesCount == 0) return;
|
||||
|
||||
DrawOrigin = new Point(Option.Grid.Left, Height - Option.Grid.Bottom);
|
||||
DrawSize = new Size(Width - Option.Grid.Left - Option.Grid.Right,
|
||||
Height - Option.Grid.Top - Option.Grid.Bottom);
|
||||
|
||||
if (DrawSize.Width <= 0 || DrawSize.Height <= 0) return;
|
||||
if (Option.XAxis.Data.Count == 0) return;
|
||||
|
||||
@ -282,9 +277,11 @@ namespace Sunny.UI
|
||||
}
|
||||
}
|
||||
|
||||
protected Point DrawOrigin => new Point(Option.Grid.Left, Height - Option.Grid.Bottom);
|
||||
protected Size DrawSize => new Size(Width - Option.Grid.Left - Option.Grid.Right, Height - Option.Grid.Top - Option.Grid.Bottom);
|
||||
protected Rectangle DrawRect => new Rectangle(Option.Grid.Left, Option.Grid.Top, DrawSize.Width, DrawSize.Height);
|
||||
|
||||
protected int selectIndex = -1;
|
||||
protected Point DrawOrigin;
|
||||
protected Size DrawSize;
|
||||
protected float DrawBarWidth;
|
||||
protected int YAxisStart;
|
||||
protected int YAxisEnd;
|
||||
|
@ -37,11 +37,6 @@ namespace Sunny.UI
|
||||
Bars.Clear();
|
||||
NeedDraw = false;
|
||||
if (Option == null || Option.Series == null || Option.SeriesCount == 0) return;
|
||||
|
||||
DrawOrigin = new Point(Option.Grid.Left, Height - Option.Grid.Bottom);
|
||||
DrawSize = new Size(Width - Option.Grid.Left - Option.Grid.Right,
|
||||
Height - Option.Grid.Top - Option.Grid.Bottom);
|
||||
|
||||
if (DrawSize.Width <= 0 || DrawSize.Height <= 0) return;
|
||||
if (Option.Series.Count == 0) return;
|
||||
|
||||
|
@ -46,30 +46,25 @@ namespace Sunny.UI
|
||||
CalcData();
|
||||
}
|
||||
|
||||
protected Point DrawOrigin;
|
||||
protected Size DrawSize;
|
||||
private Rectangle DrawRect;
|
||||
[Browsable(false)]
|
||||
public Point DrawOrigin => new Point(Option.Grid.Left, Height - Option.Grid.Bottom);
|
||||
|
||||
[Browsable(false)]
|
||||
public Size DrawSize => new Size(Width - Option.Grid.Left - Option.Grid.Right, Height - Option.Grid.Top - Option.Grid.Bottom);
|
||||
|
||||
[Browsable(false)]
|
||||
public Rectangle DrawRect => new Rectangle(Option.Grid.Left, Option.Grid.Top, DrawSize.Width, DrawSize.Height);
|
||||
|
||||
protected override void CalcData()
|
||||
{
|
||||
NeedDraw = false;
|
||||
if (Option?.Series == null || Option.Series.Count == 0) return;
|
||||
|
||||
DrawOrigin = new Point(Option.Grid.Left, Height - Option.Grid.Bottom);
|
||||
DrawSize = new Size(Width - Option.Grid.Left - Option.Grid.Right,
|
||||
Height - Option.Grid.Top - Option.Grid.Bottom);
|
||||
DrawRect = new Rectangle(Option.Grid.Left, Option.Grid.Top, DrawSize.Width, DrawSize.Height);
|
||||
|
||||
|
||||
if (DrawSize.Width <= 0 || DrawSize.Height <= 0) return;
|
||||
CalcAxises();
|
||||
|
||||
foreach (var series in Option.Series.Values)
|
||||
{
|
||||
series.ClearPoints();
|
||||
float[] x = XScale.CalcXPixels(series.XData.ToArray(), DrawOrigin.X, DrawSize.Width);
|
||||
float[] y = YScale.CalcYPixels(series.YData.ToArray(), DrawOrigin.Y, DrawSize.Height);
|
||||
series.AddPoints(x, y);
|
||||
series.CalcData(this, XScale, YScale);
|
||||
}
|
||||
|
||||
NeedDraw = true;
|
||||
@ -199,6 +194,7 @@ namespace Sunny.UI
|
||||
DrawLegend(g, Option.Legend);
|
||||
DrawAxis(g);
|
||||
DrawAxisScales(g);
|
||||
DrawPointSymbols(g);
|
||||
DrawOther(g);
|
||||
}
|
||||
|
||||
@ -396,18 +392,14 @@ namespace Sunny.UI
|
||||
|
||||
if (Option.GreaterWarningArea != null)
|
||||
{
|
||||
using (Graphics graphics = bmpGreater.Graphics())
|
||||
{
|
||||
DrawSeries(graphics, Option.GreaterWarningArea.Color, series);
|
||||
}
|
||||
using Graphics graphics = bmpGreater.Graphics();
|
||||
DrawSeries(graphics, Option.GreaterWarningArea.Color, series);
|
||||
}
|
||||
|
||||
if (Option.LessWarningArea != null)
|
||||
{
|
||||
using (Graphics graphics = bmpLess.Graphics())
|
||||
{
|
||||
DrawSeries(graphics, Option.LessWarningArea.Color, series);
|
||||
}
|
||||
using Graphics graphics = bmpLess.Graphics();
|
||||
DrawSeries(graphics, Option.LessWarningArea.Color, series);
|
||||
}
|
||||
|
||||
idx++;
|
||||
@ -449,7 +441,12 @@ namespace Sunny.UI
|
||||
g.DrawImage(bmp, new Rectangle((int)wLeft, (int)wTop, (int)(wRight - wLeft), (int)(wBottom - wTop)),
|
||||
new Rectangle((int)wLeft, (int)wTop, (int)(wRight - wLeft), (int)(wBottom - wTop)), GraphicsUnit.Pixel);
|
||||
|
||||
idx = 0;
|
||||
|
||||
}
|
||||
|
||||
private void DrawPointSymbols(Graphics g)
|
||||
{
|
||||
int idx = 0;
|
||||
foreach (var series in Option.Series.Values)
|
||||
{
|
||||
Color color = series.Color;
|
||||
@ -462,8 +459,8 @@ namespace Sunny.UI
|
||||
{
|
||||
foreach (var p in series.Points)
|
||||
{
|
||||
if (p.X <= Option.Grid.Left || p.X >= Width - Option.Grid.Right) continue;
|
||||
if (p.Y <= Option.Grid.Top || p.Y >= Height - Option.Grid.Bottom) continue;
|
||||
if (p.X < Option.Grid.Left || p.X > Width - Option.Grid.Right) continue;
|
||||
if (p.Y < Option.Grid.Top || p.Y > Height - Option.Grid.Bottom) continue;
|
||||
if (double.IsNaN(p.X) || double.IsNaN(p.Y)) continue;
|
||||
|
||||
switch (series.Symbol)
|
||||
@ -538,7 +535,7 @@ namespace Sunny.UI
|
||||
|
||||
using (Pen pn = new Pen(line.Color, line.Size))
|
||||
{
|
||||
g.DrawLine(pn, DrawOrigin.X, pos, Width - Option.Grid.Right, pos);
|
||||
g.DrawLine(pn, DrawOrigin.X + 1, pos, Width - Option.Grid.Right - 1, pos);
|
||||
}
|
||||
|
||||
SizeF sf = g.MeasureString(line.Name, SubFont);
|
||||
@ -559,7 +556,7 @@ namespace Sunny.UI
|
||||
|
||||
using (Pen pn = new Pen(line.Color, line.Size))
|
||||
{
|
||||
g.DrawLine(pn, pos, DrawOrigin.Y, pos, Option.Grid.Top);
|
||||
g.DrawLine(pn, pos, DrawOrigin.Y - 1, pos, Option.Grid.Top + 1);
|
||||
}
|
||||
|
||||
SizeF sf = g.MeasureString(line.Name, SubFont);
|
||||
|
@ -288,7 +288,7 @@ namespace Sunny.UI
|
||||
|
||||
public bool ShowLine { get; set; } = true;
|
||||
|
||||
public bool ContainsNan { get; set; }
|
||||
public bool ContainsNan { get; private set; }
|
||||
|
||||
public UILineSeries(string name)
|
||||
{
|
||||
@ -354,12 +354,13 @@ namespace Sunny.UI
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
ContainsNan = false;
|
||||
XData.Clear();
|
||||
YData.Clear();
|
||||
ClearPoints();
|
||||
}
|
||||
|
||||
public void ClearPoints()
|
||||
private void ClearPoints()
|
||||
{
|
||||
Points.Clear();
|
||||
PointsX.Clear();
|
||||
@ -383,10 +384,19 @@ namespace Sunny.UI
|
||||
}
|
||||
}
|
||||
|
||||
public void CalcData(UILineChart chart, UIScale XScale, UIScale YScale)
|
||||
{
|
||||
ClearPoints();
|
||||
float[] x = XScale.CalcXPixels(XData.ToArray(), chart.DrawOrigin.X, chart.DrawSize.Width);
|
||||
float[] y = YScale.CalcYPixels(YData.ToArray(), chart.DrawOrigin.Y, chart.DrawSize.Height);
|
||||
AddPoints(x, y);
|
||||
}
|
||||
|
||||
public void Add(double x, double y)
|
||||
{
|
||||
XData.Add(x);
|
||||
if (double.IsInfinity(y)) y = double.NaN;
|
||||
if (y.IsInfinity()) y = double.NaN;
|
||||
if (y.IsNan()) ContainsNan = true;
|
||||
YData.Add(y);
|
||||
}
|
||||
|
||||
@ -394,7 +404,8 @@ namespace Sunny.UI
|
||||
{
|
||||
DateTimeInt64 t = new DateTimeInt64(x);
|
||||
XData.Add(t);
|
||||
if (double.IsInfinity(y)) y = double.NaN;
|
||||
if (y.IsInfinity()) y = double.NaN;
|
||||
if (y.IsNan()) ContainsNan = true;
|
||||
YData.Add(y);
|
||||
}
|
||||
|
||||
@ -402,7 +413,8 @@ namespace Sunny.UI
|
||||
{
|
||||
int cnt = XData.Count;
|
||||
XData.Add(cnt);
|
||||
if (double.IsInfinity(y)) y = double.NaN;
|
||||
if (y.IsInfinity()) y = double.NaN;
|
||||
if (y.IsNan()) ContainsNan = true;
|
||||
YData.Add(y);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user