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