diff --git a/Bin/SunnyUI.dll b/Bin/SunnyUI.dll index 7fe6b7c0..cc886930 100644 Binary files a/Bin/SunnyUI.dll and b/Bin/SunnyUI.dll differ diff --git a/Bin/SunnyUI.pdb b/Bin/SunnyUI.pdb index d49a75b0..d43fa333 100644 Binary files a/Bin/SunnyUI.pdb and b/Bin/SunnyUI.pdb differ diff --git a/SunnyUI.Demo/Bin/SunnyUI.Demo.exe b/SunnyUI.Demo/Bin/SunnyUI.Demo.exe index 5ca779db..b314b7cc 100644 Binary files a/SunnyUI.Demo/Bin/SunnyUI.Demo.exe and b/SunnyUI.Demo/Bin/SunnyUI.Demo.exe differ diff --git a/SunnyUI.Demo/Bin/SunnyUI.dll b/SunnyUI.Demo/Bin/SunnyUI.dll index 7fe6b7c0..cc886930 100644 Binary files a/SunnyUI.Demo/Bin/SunnyUI.dll and b/SunnyUI.Demo/Bin/SunnyUI.dll differ diff --git a/SunnyUI.Demo/Charts/FBarChart.resx b/SunnyUI.Demo/Charts/FBarChart.resx deleted file mode 100644 index 1af7de15..00000000 --- a/SunnyUI.Demo/Charts/FBarChart.resx +++ /dev/null @@ -1,120 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - \ No newline at end of file diff --git a/SunnyUI.Demo/Charts/FBarChartEx.Designer.cs b/SunnyUI.Demo/Charts/FBarChartEx.Designer.cs new file mode 100644 index 00000000..ea581a83 --- /dev/null +++ b/SunnyUI.Demo/Charts/FBarChartEx.Designer.cs @@ -0,0 +1,158 @@ +namespace Sunny.UI.Demo +{ + partial class FBarChartEx + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.uiSymbolButton1 = new Sunny.UI.UISymbolButton(); + this.uiImageButton3 = new Sunny.UI.UIImageButton(); + this.uiImageButton2 = new Sunny.UI.UIImageButton(); + this.uiImageButton1 = new Sunny.UI.UIImageButton(); + this.uiLine1 = new Sunny.UI.UILine(); + this.BarChart = new Sunny.UI.UIBarChartEx(); + this.PagePanel.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.uiImageButton3)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this.uiImageButton2)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this.uiImageButton1)).BeginInit(); + this.SuspendLayout(); + // + // PagePanel + // + this.PagePanel.Controls.Add(this.uiSymbolButton1); + this.PagePanel.Controls.Add(this.uiImageButton3); + this.PagePanel.Controls.Add(this.uiImageButton2); + this.PagePanel.Controls.Add(this.uiImageButton1); + this.PagePanel.Controls.Add(this.uiLine1); + this.PagePanel.Controls.Add(this.BarChart); + this.PagePanel.Size = new System.Drawing.Size(886, 508); + // + // uiSymbolButton1 + // + this.uiSymbolButton1.Cursor = System.Windows.Forms.Cursors.Hand; + this.uiSymbolButton1.Font = new System.Drawing.Font("微软雅黑", 12F); + this.uiSymbolButton1.Location = new System.Drawing.Point(348, 466); + this.uiSymbolButton1.MinimumSize = new System.Drawing.Size(1, 1); + this.uiSymbolButton1.Name = "uiSymbolButton1"; + this.uiSymbolButton1.Padding = new System.Windows.Forms.Padding(28, 0, 0, 0); + this.uiSymbolButton1.Size = new System.Drawing.Size(100, 27); + this.uiSymbolButton1.Symbol = 61952; + this.uiSymbolButton1.TabIndex = 34; + this.uiSymbolButton1.Text = "数据"; + this.uiSymbolButton1.Click += new System.EventHandler(this.uiSymbolButton1_Click); + // + // uiImageButton3 + // + this.uiImageButton3.Cursor = System.Windows.Forms.Cursors.Hand; + this.uiImageButton3.Font = new System.Drawing.Font("微软雅黑", 12F); + this.uiImageButton3.Image = global::Sunny.UI.Demo.Properties.Resources.ChartDarkStyle; + this.uiImageButton3.Location = new System.Drawing.Point(242, 466); + this.uiImageButton3.Name = "uiImageButton3"; + this.uiImageButton3.Size = new System.Drawing.Size(100, 27); + this.uiImageButton3.TabIndex = 33; + this.uiImageButton3.TabStop = false; + this.uiImageButton3.Text = " Dark"; + this.uiImageButton3.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; + this.uiImageButton3.Click += new System.EventHandler(this.uiImageButton3_Click); + // + // uiImageButton2 + // + this.uiImageButton2.Cursor = System.Windows.Forms.Cursors.Hand; + this.uiImageButton2.Font = new System.Drawing.Font("微软雅黑", 12F); + this.uiImageButton2.Image = global::Sunny.UI.Demo.Properties.Resources.ChartPlainStyle; + this.uiImageButton2.Location = new System.Drawing.Point(136, 466); + this.uiImageButton2.Name = "uiImageButton2"; + this.uiImageButton2.Size = new System.Drawing.Size(100, 27); + this.uiImageButton2.TabIndex = 32; + this.uiImageButton2.TabStop = false; + this.uiImageButton2.Text = " Plain"; + this.uiImageButton2.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; + this.uiImageButton2.Click += new System.EventHandler(this.uiImageButton2_Click); + // + // uiImageButton1 + // + this.uiImageButton1.Cursor = System.Windows.Forms.Cursors.Hand; + this.uiImageButton1.Font = new System.Drawing.Font("微软雅黑", 12F); + this.uiImageButton1.Image = global::Sunny.UI.Demo.Properties.Resources.ChartDefaultStyle; + this.uiImageButton1.Location = new System.Drawing.Point(30, 466); + this.uiImageButton1.Name = "uiImageButton1"; + this.uiImageButton1.Size = new System.Drawing.Size(100, 27); + this.uiImageButton1.TabIndex = 31; + this.uiImageButton1.TabStop = false; + this.uiImageButton1.Text = " Default"; + this.uiImageButton1.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; + this.uiImageButton1.Click += new System.EventHandler(this.uiImageButton1_Click); + // + // uiLine1 + // + this.uiLine1.Font = new System.Drawing.Font("微软雅黑", 12F); + this.uiLine1.Location = new System.Drawing.Point(30, 20); + this.uiLine1.MinimumSize = new System.Drawing.Size(16, 16); + this.uiLine1.Name = "uiLine1"; + this.uiLine1.Size = new System.Drawing.Size(670, 20); + this.uiLine1.TabIndex = 30; + this.uiLine1.Text = "UIBarChart"; + this.uiLine1.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; + // + // BarChart + // + this.BarChart.FillColor = System.Drawing.Color.FromArgb(((int)(((byte)(244)))), ((int)(((byte)(244)))), ((int)(((byte)(244))))); + this.BarChart.Font = new System.Drawing.Font("微软雅黑", 12F); + this.BarChart.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(54)))), ((int)(((byte)(54)))), ((int)(((byte)(54))))); + this.BarChart.Location = new System.Drawing.Point(30, 48); + this.BarChart.MinimumSize = new System.Drawing.Size(1, 1); + this.BarChart.Name = "BarChart"; + this.BarChart.Option = null; + this.BarChart.Size = new System.Drawing.Size(670, 400); + this.BarChart.TabIndex = 35; + this.BarChart.Text = "uiBarChartEx1"; + // + // FBarChartEx + // + this.AutoScaleDimensions = new System.Drawing.SizeF(10F, 21F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(886, 543); + this.Name = "FBarChartEx"; + this.Symbol = 61568; + this.Text = "BarChartEx"; + this.PagePanel.ResumeLayout(false); + ((System.ComponentModel.ISupportInitialize)(this.uiImageButton3)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this.uiImageButton2)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this.uiImageButton1)).EndInit(); + this.ResumeLayout(false); + + } + + #endregion + + private UISymbolButton uiSymbolButton1; + private UIImageButton uiImageButton3; + private UIImageButton uiImageButton2; + private UIImageButton uiImageButton1; + private UILine uiLine1; + private UIBarChartEx BarChart; + } +} \ No newline at end of file diff --git a/SunnyUI.Demo/Charts/FBarChartEx.cs b/SunnyUI.Demo/Charts/FBarChartEx.cs new file mode 100644 index 00000000..5dbf2203 --- /dev/null +++ b/SunnyUI.Demo/Charts/FBarChartEx.cs @@ -0,0 +1,81 @@ +using System.Drawing; + +namespace Sunny.UI.Demo +{ + public partial class FBarChartEx : UITitlePage + { + public FBarChartEx() + { + InitializeComponent(); + } + + private void uiImageButton1_Click(object sender, System.EventArgs e) + { + BarChart.ChartStyleType = UIChartStyleType.Default; + } + + private void uiImageButton2_Click(object sender, System.EventArgs e) + { + BarChart.ChartStyleType = UIChartStyleType.Plain; + } + + private void uiImageButton3_Click(object sender, System.EventArgs e) + { + BarChart.ChartStyleType = UIChartStyleType.Dark; + } + + private void uiSymbolButton1_Click(object sender, System.EventArgs e) + { + UIBarOption option = new UIBarOption(); + option.Title = new UITitle(); + option.Title.Text = "SunnyUI"; + option.Title.SubText = "BarChartEx"; + + //设置Legend + option.Legend = new UILegend(); + option.Legend.Orient = UIOrient.Horizontal; + option.Legend.Top = UITopAlignment.Top; + option.Legend.Left = UILeftAlignment.Left; + option.Legend.AddData("Bar1"); + option.Legend.AddData("Bar2"); + option.Legend.AddData("Bar3"); + + var series = new UIBarSeries(); + series.Name = "Bar1"; + series.AddData("通道1", 11); + series.AddData("通道2", 15); + option.Series.Add(series); + + series = new UIBarSeries(); + series.Name = "Bar2"; + series.AddData("通道1", -22); + series.AddData("通道2", -28); + series.AddData("通道3", -25); + option.Series.Add(series); + + series = new UIBarSeries(); + series.Name = "Bar3"; + series.AddData("通道1", 7); + option.Series.Add(series); + + option.XAxis.Data.Add("Mon"); + option.XAxis.Data.Add("Tue"); + option.XAxis.Data.Add("Wed"); + option.XAxis.Data.Add("Thu"); + option.XAxis.Data.Add("Fri"); + + option.ToolTip = new UIBarToolTip(); + option.YAxis.Scale = true; + + option.XAxis.Name = "日期"; + option.YAxis.Name = "数值"; + + option.FixedSeriesCount = 3; + + option.YAxisScaleLines.Add(new UIScaleLine() { Color = Color.Red, Name = "上限", Value = 12 }); + option.YAxisScaleLines.Add(new UIScaleLine() { Color = Color.Gold, Name = "下限", Value = -20 }); + + BarChart.SetOption(option); + } + } +} diff --git a/SunnyUI.Demo/Charts/FDoughnutChart.resx b/SunnyUI.Demo/Charts/FDoughnutChart.resx deleted file mode 100644 index 1af7de15..00000000 --- a/SunnyUI.Demo/Charts/FDoughnutChart.resx +++ /dev/null @@ -1,120 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - \ No newline at end of file diff --git a/SunnyUI.Demo/Charts/FPieChart.Designer.cs b/SunnyUI.Demo/Charts/FPieChart.Designer.cs index 813776e3..b1cdd2b0 100644 --- a/SunnyUI.Demo/Charts/FPieChart.Designer.cs +++ b/SunnyUI.Demo/Charts/FPieChart.Designer.cs @@ -35,7 +35,6 @@ this.uiImageButton2 = new Sunny.UI.UIImageButton(); this.uiImageButton3 = new Sunny.UI.UIImageButton(); this.uiSymbolButton1 = new Sunny.UI.UISymbolButton(); - this.toolTip1 = new System.Windows.Forms.ToolTip(this.components); this.PagePanel.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)(this.uiImageButton1)).BeginInit(); ((System.ComponentModel.ISupportInitialize)(this.uiImageButton2)).BeginInit(); @@ -156,6 +155,5 @@ private UIImageButton uiImageButton3; private UIImageButton uiImageButton2; private UISymbolButton uiSymbolButton1; - private System.Windows.Forms.ToolTip toolTip1; } } \ No newline at end of file diff --git a/SunnyUI.Demo/Charts/FPieChart.resx b/SunnyUI.Demo/Charts/FPieChart.resx deleted file mode 100644 index 61b7fb98..00000000 --- a/SunnyUI.Demo/Charts/FPieChart.resx +++ /dev/null @@ -1,126 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - 17, 17 - - - 25 - - \ No newline at end of file diff --git a/SunnyUI.Demo/FMain.cs b/SunnyUI.Demo/FMain.cs index 10fec784..e64118dd 100644 --- a/SunnyUI.Demo/FMain.cs +++ b/SunnyUI.Demo/FMain.cs @@ -53,8 +53,9 @@ namespace Sunny.UI.Demo parent = Aside.CreateNode("Charts", 61950, 24, pageIndex); //直接关联(默认自动生成GUID) Aside.CreateChildNode(parent, AddPage(new FPieChart())); - Aside.CreateChildNode(parent, AddPage(new FBarChart())); Aside.CreateChildNode(parent, AddPage(new FDoughnutChart())); + Aside.CreateChildNode(parent, AddPage(new FBarChart())); + Aside.CreateChildNode(parent, AddPage(new FBarChartEx())); Header.SetNodeSymbol(Header.Nodes[3], 61502); var styles = UIStyles.PopularStyles(); diff --git a/SunnyUI.Demo/SunnyUI.Demo.csproj b/SunnyUI.Demo/SunnyUI.Demo.csproj index 869f5793..65361429 100644 --- a/SunnyUI.Demo/SunnyUI.Demo.csproj +++ b/SunnyUI.Demo/SunnyUI.Demo.csproj @@ -53,6 +53,12 @@ FBarChart.cs + + Form + + + FBarChartEx.cs + Form @@ -295,12 +301,6 @@ - - FBarChart.cs - - - FDoughnutChart.cs - FAvatar.cs @@ -316,9 +316,6 @@ FMeter.cs - - FPieChart.cs - FScrollBar.cs diff --git a/SunnyUI/Charts/UIBarChart.cs b/SunnyUI/Charts/UIBarChart.cs index ef2b69e0..f71f393b 100644 --- a/SunnyUI/Charts/UIBarChart.cs +++ b/SunnyUI/Charts/UIBarChart.cs @@ -34,7 +34,7 @@ namespace Sunny.UI [ToolboxItem(true)] public class UIBarChart : UIChart { - private bool NeedDraw; + protected bool NeedDraw; protected override void OnSizeChanged(EventArgs e) { @@ -145,8 +145,8 @@ namespace Sunny.UI if (k > 0) highV += (float)YAxisInterval; } - lowH.ConsoleWriteLine(); - highH.ConsoleWriteLine(); + // lowH.ConsoleWriteLine(); + // highH.ConsoleWriteLine(); if (series.Data[j] >= 0) { @@ -188,17 +188,17 @@ namespace Sunny.UI } } - private int selectIndex = -1; - private Point DrawOrigin; - private Size DrawSize; - private float DrawBarWidth; - private int YAxisStart; - private int YAxisEnd; - private double YAxisInterval; - private readonly ConcurrentDictionary> Bars = new ConcurrentDictionary>(); + protected int selectIndex = -1; + protected Point DrawOrigin; + protected Size DrawSize; + protected float DrawBarWidth; + protected int YAxisStart; + protected int YAxisEnd; + protected double YAxisInterval; + protected readonly ConcurrentDictionary> Bars = new ConcurrentDictionary>(); [DefaultValue(-1), Browsable(false)] - private int SelectIndex + protected int SelectIndex { get => selectIndex; set @@ -258,7 +258,7 @@ namespace Sunny.UI } [Browsable(false)] - private UIBarOption BarOption + protected UIBarOption BarOption { get { @@ -344,7 +344,7 @@ namespace Sunny.UI } } - private void DrawAxis(Graphics g) + protected virtual void DrawAxis(Graphics g) { if (YAxisStart >= 0) g.DrawLine(ChartStyle.ForeColor, DrawOrigin, new Point(DrawOrigin.X + DrawSize.Width, DrawOrigin.Y)); if (YAxisEnd <= 0) g.DrawLine(ChartStyle.ForeColor, new Point(DrawOrigin.X, BarOption.Grid.Top), new Point(DrawOrigin.X + DrawSize.Width, BarOption.Grid.Top)); @@ -482,7 +482,7 @@ namespace Sunny.UI } } - private void DrawSeries(Graphics g, List series) + protected virtual void DrawSeries(Graphics g, List series) { if (series == null || series.Count == 0) return; @@ -501,7 +501,7 @@ namespace Sunny.UI } } - internal class BarInfo + protected class BarInfo { public RectangleF Rect { get; set; } diff --git a/SunnyUI/Charts/UIBarChartEx.cs b/SunnyUI/Charts/UIBarChartEx.cs new file mode 100644 index 00000000..229c2fd7 --- /dev/null +++ b/SunnyUI/Charts/UIBarChartEx.cs @@ -0,0 +1,395 @@ +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Linq; +using System.Windows.Forms; + +namespace Sunny.UI +{ + public class UIBarChartEx : UIBarChart + { + protected override void CalcData(UIOption option) + { + Bars.Clear(); + NeedDraw = false; + UIBarOption o = (UIBarOption)option; + if (o == null || o.Series == null || o.SeriesCount == 0) return; + + DrawOrigin = new Point(BarOption.Grid.Left, Height - BarOption.Grid.Bottom); + DrawSize = new Size(Width - BarOption.Grid.Left - BarOption.Grid.Right, + Height - BarOption.Grid.Top - BarOption.Grid.Bottom); + + if (DrawSize.Width <= 0 || DrawSize.Height <= 0) return; + if (o.Series.Count == 0) return; + + NeedDraw = true; + DrawBarWidth = DrawSize.Width * 1.0f / o.Series.Count; + + double min = double.MaxValue; + double max = double.MinValue; + foreach (var series in o.Series) + { + min = Math.Min(min, series.Data.Min()); + max = Math.Max(max, series.Data.Max()); + } + + if (min > 0 && max > 0 && !o.YAxis.Scale) + { + min = 0; + } + + if (min < 0 && max < 0 && !o.YAxis.Scale) + { + max = 0; + } + + if (!o.YAxis.MaxAuto) max = o.YAxis.Max; + if (!o.YAxis.MinAuto) min = o.YAxis.Min; + + if ((max - min).IsZero()) + { + max = 100; + min = 0; + } + + UIChartHelper.CalcDegreeScale(min, max, o.YAxis.SplitNumber, + out int start, out int end, out double interval); + + YAxisStart = start; + YAxisEnd = end; + YAxisInterval = interval; + float barX = DrawOrigin.X; + + for (int i = 0; i < o.SeriesCount; i++) + { + var series = o.Series[i]; + float x1; + if (BarOption.FixedSeriesCount > 0) + x1 = DrawBarWidth / (BarOption.FixedSeriesCount * 2 + BarOption.FixedSeriesCount + 1); + else + x1 = DrawBarWidth / (series.Data.Count * 2 + series.Data.Count + 1); + + float x2 = x1 * 2; + + Bars.TryAdd(i, new List()); + for (int j = 0; j < series.Data.Count; j++) + { + Color color = ChartStyle.GetColor(i); + if (series.Colors.Count > 0 && j >= 0 && j < series.Colors.Count) + color = series.Colors[j]; + + float xx; + if (BarOption.FixedSeriesCount > 0) + xx = barX + DrawBarWidth / (series.Data.Count * 2 + series.Data.Count + 1) * ((j + 1) * 3 - 1); + else + xx = barX + x1 * ((j + 1) * 3 - 1); + + float ww = Math.Min(x2, series.MaxWidth); + xx = xx - ww / 2.0f; + + if (YAxisStart >= 0) + { + float h = Math.Abs((float)(DrawSize.Height * (series.Data[j] - start * interval) / ((end - start) * interval))); + + Bars[i].Add(new BarInfo() + { + Rect = new RectangleF(xx, DrawOrigin.Y - h, ww, h), + Color = color + }); + } + else if (YAxisEnd <= 0) + { + float h = Math.Abs((float)(DrawSize.Height * (end * interval - series.Data[j]) / ((end - start) * interval))); + Bars[i].Add(new BarInfo() + { + Rect = new RectangleF(xx, BarOption.Grid.Top + 1, ww, h - 1), + Color = color + }); + } + else + { + float lowH = 0; + float highH = 0; + float DrawBarHeight = DrawSize.Height * 1.0f / (YAxisEnd - YAxisStart); + float lowV = 0; + float highV = 0; + for (int k = YAxisStart; k <= YAxisEnd; k++) + { + if (k < 0) lowH += DrawBarHeight; + if (k > 0) highH += DrawBarHeight; + if (k < 0) lowV += (float)YAxisInterval; + if (k > 0) highV += (float)YAxisInterval; + } + + // lowH.ConsoleWriteLine(); + // highH.ConsoleWriteLine(); + + if (series.Data[j] >= 0) + { + float h = Math.Abs((float)(highH * series.Data[j] / highV)); + Bars[i].Add(new BarInfo() + { + Rect = new RectangleF(xx, DrawOrigin.Y - lowH - h, ww, h), + Color = color + }); + } + else + { + float h = Math.Abs((float)(lowH * series.Data[j] / lowV)); + Bars[i].Add(new BarInfo() + { + Rect = new RectangleF(xx, DrawOrigin.Y - lowH + 1, ww, h - 1), + Color = color + }); + } + } + } + + barX += DrawBarWidth; + } + + if (BarOption.ToolTip != null) + { + for (int i = 0; i < BarOption.Series.Count; i++) + { + var series = BarOption.Series[i]; + string str = BarOption.Series[i].Name; + for (int j = 0; j < series.Data.Count; j++) + { + str += '\n'; + if (series.BarName.Count >= 0 && j < series.BarName.Count) + str += series.BarName[j] + " : "; + + str += series.Data[j].ToString(BarOption.ToolTip.ValueFormat); + } + + Bars[i][0].Tips = str; + } + } + } + + protected override void DrawSeries(Graphics g, List series) + { + if (series == null || series.Count == 0) return; + + for (int i = 0; i < Bars.Count; i++) + { + var bars = Bars[i]; + foreach (var info in bars) + { + g.FillRectangle(info.Color, info.Rect); + } + } + + for (int i = 0; i < BarOption.Series.Count; i++) + { + Bars[i][0].Size = g.MeasureString(Bars[i][0].Tips, SubFont); + } + } + + protected override void DrawAxis(Graphics g) + { + if (YAxisStart >= 0) g.DrawLine(ChartStyle.ForeColor, DrawOrigin, new Point(DrawOrigin.X + DrawSize.Width, DrawOrigin.Y)); + if (YAxisEnd <= 0) g.DrawLine(ChartStyle.ForeColor, new Point(DrawOrigin.X, BarOption.Grid.Top), new Point(DrawOrigin.X + DrawSize.Width, BarOption.Grid.Top)); + + g.DrawLine(ChartStyle.ForeColor, DrawOrigin, new Point(DrawOrigin.X, DrawOrigin.Y - DrawSize.Height)); + + if (BarOption.XAxis.AxisTick.Show) + { + float start; + + if (BarOption.XAxis.AxisTick.AlignWithLabel) + { + start = DrawOrigin.X + DrawBarWidth / 2.0f; + for (int i = 0; i < BarOption.Series.Count; i++) + { + g.DrawLine(ChartStyle.ForeColor, start, DrawOrigin.Y, start, DrawOrigin.Y + BarOption.XAxis.AxisTick.Length); + start += DrawBarWidth; + } + } + else + { + bool haveZero = false; + for (int i = YAxisStart; i <= YAxisEnd; i++) + { + if (i == 0) + { + haveZero = true; + break; + } + } + + if (!haveZero) + { + start = DrawOrigin.X; + for (int i = 0; i <= BarOption.Series.Count; i++) + { + g.DrawLine(ChartStyle.ForeColor, start, DrawOrigin.Y, start, DrawOrigin.Y + BarOption.XAxis.AxisTick.Length); + start += DrawBarWidth; + } + } + } + } + + if (BarOption.XAxis.AxisLabel.Show) + { + float start = DrawOrigin.X + DrawBarWidth / 2.0f; + foreach (var data in BarOption.Series) + { + SizeF sf = g.MeasureString(data.Name, SubFont); + g.DrawString(data.Name, SubFont, ChartStyle.ForeColor, start - sf.Width / 2.0f, DrawOrigin.Y + BarOption.XAxis.AxisTick.Length); + start += DrawBarWidth; + } + + SizeF sfName = g.MeasureString(BarOption.XAxis.Name, SubFont); + g.DrawString(BarOption.XAxis.Name, SubFont, ChartStyle.ForeColor, DrawOrigin.X + (DrawSize.Width - sfName.Width) / 2.0f, DrawOrigin.Y + BarOption.XAxis.AxisTick.Length + sfName.Height); + } + + if (BarOption.YAxis.AxisTick.Show) + { + float start = DrawOrigin.Y; + float DrawBarHeight = DrawSize.Height * 1.0f / (YAxisEnd - YAxisStart); + for (int i = YAxisStart; i <= YAxisEnd; i++) + { + g.DrawLine(ChartStyle.ForeColor, DrawOrigin.X, start, DrawOrigin.X - BarOption.YAxis.AxisTick.Length, start); + + if (i != 0) + { + using (Pen pn = new Pen(ChartStyle.ForeColor)) + { + pn.DashStyle = DashStyle.Dash; + pn.DashPattern = new float[] { 3, 3 }; + g.DrawLine(pn, DrawOrigin.X, start, Width - BarOption.Grid.Right, start); + } + } + else + { + g.DrawLine(ChartStyle.ForeColor, DrawOrigin.X, start, Width - BarOption.Grid.Right, start); + + float lineStart = DrawOrigin.X; + for (int j = 0; j <= BarOption.Series.Count; j++) + { + g.DrawLine(ChartStyle.ForeColor, lineStart, start, lineStart, start + BarOption.XAxis.AxisTick.Length); + lineStart += DrawBarWidth; + } + } + + start -= DrawBarHeight; + } + } + + if (BarOption.YAxis.AxisLabel.Show) + { + float start = DrawOrigin.Y; + float DrawBarHeight = DrawSize.Height * 1.0f / (YAxisEnd - YAxisStart); + int idx = 0; + float wmax = 0; + for (int i = YAxisStart; i <= YAxisEnd; i++) + { + string label = BarOption.YAxis.AxisLabel.GetLabel(i * YAxisInterval, idx); + SizeF sf = g.MeasureString(label, SubFont); + wmax = Math.Max(wmax, sf.Width); + g.DrawString(label, SubFont, ChartStyle.ForeColor, DrawOrigin.X - BarOption.YAxis.AxisTick.Length - sf.Width, start - sf.Height / 2.0f); + start -= DrawBarHeight; + } + + SizeF sfname = g.MeasureString(BarOption.YAxis.Name, SubFont); + int x = (int)(DrawOrigin.X - BarOption.YAxis.AxisTick.Length - wmax - sfname.Height); + int y = (int)(BarOption.Grid.Top + (DrawSize.Height - sfname.Width) / 2); + g.DrawString(BarOption.YAxis.Name, SubFont, ChartStyle.ForeColor, new Point(x, y), + new StringFormat() { Alignment = StringAlignment.Center }, 270); + } + } + + protected override void OnMouseMove(MouseEventArgs e) + { + try + { + if (BarOption.ToolTip == null) return; + if (e.Location.X > BarOption.Grid.Left && e.Location.X < Width - BarOption.Grid.Right + && e.Location.Y > BarOption.Grid.Top && + e.Location.Y < Height - BarOption.Grid.Bottom) + { + SelectIndex = (int)((e.Location.X - BarOption.Grid.Left) / DrawBarWidth); + } + else + { + SelectIndex = -1; + } + + if (SelectIndex >= 0 && Bars.Count > 0) + { + if (tip.Text != Bars[selectIndex][0].Tips) + { + tip.Text = Bars[selectIndex][0].Tips; + tip.Size = new Size((int)Bars[selectIndex][0].Size.Width + 4, (int)Bars[selectIndex][0].Size.Height + 4); + } + + int x = e.Location.X + 15; + int y = e.Location.Y + 20; + if (e.Location.X + 15 + tip.Width > Width - BarOption.Grid.Right) + x = e.Location.X - tip.Width - 2; + if (e.Location.Y + 20 + tip.Height > Height - BarOption.Grid.Bottom) + y = e.Location.Y - tip.Height - 2; + + tip.Left = x; + tip.Top = y; + if (!tip.Visible) tip.Visible = Bars[selectIndex][0].Tips.IsValid(); + } + } + catch (Exception exception) + { + Console.WriteLine(exception); + } + } + + protected override void CreateEmptyOption() + { + if (emptyOption != null) return; + + UIBarOption option = new UIBarOption(); + option.Title = new UITitle(); + option.Title.Text = "SunnyUI"; + option.Title.SubText = "BarChart"; + + //设置Legend + option.Legend = new UILegend(); + option.Legend.Orient = UIOrient.Horizontal; + option.Legend.Top = UITopAlignment.Top; + option.Legend.Left = UILeftAlignment.Left; + option.Legend.AddData("Bar1"); + option.Legend.AddData("Bar2"); + option.Legend.AddData("Bar3"); + + var series = new UIBarSeries(); + series.Name = "Bar1"; + series.AddData(1); + option.Series.Add(series); + + series = new UIBarSeries(); + series.Name = "Bar2"; + series.AddData(2); + series.AddData(3); + option.Series.Add(series); + + series = new UIBarSeries(); + series.Name = "Bar2"; + series.AddData(4); + series.AddData(5); + series.AddData(6); + option.Series.Add(series); + + option.XAxis.Data.Add("Mon"); + option.XAxis.Data.Add("Tue"); + option.XAxis.Data.Add("Wed"); + option.XAxis.Data.Add("Thu"); + option.XAxis.Data.Add("Fri"); + + option.ToolTip = new UIBarToolTip(); + option.ToolTip.AxisPointer.Type = UIAxisPointerType.Shadow; + + emptyOption = option; + } + } +} diff --git a/SunnyUI/Charts/UIBarChartOption.cs b/SunnyUI/Charts/UIBarChartOption.cs index bfd563bf..4d07a9f7 100644 --- a/SunnyUI/Charts/UIBarChartOption.cs +++ b/SunnyUI/Charts/UIBarChartOption.cs @@ -41,6 +41,8 @@ namespace Sunny.UI public readonly List YAxisScaleLines = new List(); + public int FixedSeriesCount { get; set; } = 0; + public void AddSeries(UIBarSeries series) { Series.Add(series); @@ -195,6 +197,8 @@ namespace Sunny.UI public UISeriesType Type => UISeriesType.Bar; + public readonly List BarName = new List(); + public readonly List Data = new List(); public readonly List Colors = new List(); @@ -215,6 +219,18 @@ namespace Sunny.UI Colors.Add(color); } + public void AddData(string name, double value) + { + BarName.Add(name); + AddData(value); + } + + public void AddData(string name, double value, Color color) + { + BarName.Add(name); + AddData(value, color); + } + public void Dispose() { Data.Clear(); @@ -232,6 +248,7 @@ namespace Sunny.UI public void Clear() { + BarName.Clear(); Data.Clear(); Colors.Clear(); } diff --git a/SunnyUI/SunnyUI.csproj b/SunnyUI/SunnyUI.csproj index 59d57d6e..767fe4d3 100644 --- a/SunnyUI/SunnyUI.csproj +++ b/SunnyUI/SunnyUI.csproj @@ -54,6 +54,9 @@ Component + + Component + Component