diff --git a/Bin/SunnyUI.dll b/Bin/SunnyUI.dll
index 3bac3c51..06d206c2 100644
Binary files a/Bin/SunnyUI.dll and b/Bin/SunnyUI.dll differ
diff --git a/Bin/SunnyUI.pdb b/Bin/SunnyUI.pdb
index c33cf149..3aa614dc 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 b46845ec..2f86d3cb 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 3bac3c51..06d206c2 100644
Binary files a/SunnyUI.Demo/Bin/SunnyUI.dll and b/SunnyUI.Demo/Bin/SunnyUI.dll differ
diff --git a/SunnyUI.Demo/Charts/FBarChart.cs b/SunnyUI.Demo/Charts/FBarChart.cs
index 2dad7e64..4942a955 100644
--- a/SunnyUI.Demo/Charts/FBarChart.cs
+++ b/SunnyUI.Demo/Charts/FBarChart.cs
@@ -24,17 +24,17 @@
var series = new UIBarSeries();
series.Name = "Bar1";
- series.AddData(+11);
- series.AddData(+15);
- series.AddData(+12);
- series.AddData(+14);
- series.AddData(+13);
+ series.AddData(11);
+ series.AddData(15);
+ series.AddData(12);
+ series.AddData(14);
+ series.AddData(13);
option.Series.Add(series);
series = new UIBarSeries();
series.Name = "Bar2";
series.AddData(-22);
- series.AddData(0);
+ series.AddData(-28);
series.AddData(-25);
series.AddData(-23);
series.AddData(-24);
@@ -47,6 +47,10 @@
option.XAxis.Data.Add("Fri");
option.ToolTip = new UIBarToolTip();
+ option.YAxis.Scale = true;
+
+ option.XAxis.Name = "日期";
+ option.YAxis.Name = "数值";
BarChart.SetOption(option);
}
diff --git a/SunnyUI/Charts/UIBarChart.cs b/SunnyUI/Charts/UIBarChart.cs
index 017f96f1..79f89c3b 100644
--- a/SunnyUI/Charts/UIBarChart.cs
+++ b/SunnyUI/Charts/UIBarChart.cs
@@ -37,7 +37,7 @@ namespace Sunny.UI
NeedDraw = true;
DrawBarWidth = DrawSize.Width * 1.0f / o.XAxis.Data.Count;
- double min = Double.MaxValue;
+ double min = double.MaxValue;
double max = double.MinValue;
foreach (var series in o.Series)
{
@@ -45,18 +45,14 @@ namespace Sunny.UI
max = Math.Max(max, series.Data.Max());
}
- bool minZero = false;
- bool maxZero = false;
if (min > 0 && max > 0 && !o.YAxis.Scale)
{
min = 0;
- minZero = true;
}
if (min < 0 && max < 0 && !o.YAxis.Scale)
{
max = 0;
- maxZero = true;
}
UIChartHelper.CalcDegreeScale(min, max, o.YAxis.SplitNumber,
@@ -77,20 +73,21 @@ namespace Sunny.UI
for (int j = 0; j < series.Data.Count; j++)
{
- if (minZero)
+ if (YAxisStart >= 0)
{
- float h = Math.Abs((float)(DrawSize.Height * series.Data[j] / (end * interval)));
+ float h = Math.Abs((float)(DrawSize.Height * (series.Data[j]- start *interval) / ((end -start) * interval)));
+
Bars[i].Add(new BarInfo()
{
Rect = new RectangleF(
- barX + x1 * (i + 1) + x2 * i,
- DrawOrigin.Y - h,
- x2, h)
+ barX + x1 * (i + 1) + x2 * i,
+ DrawOrigin.Y - h,
+ x2, h)
});
}
- else if (maxZero)
+ else if (YAxisEnd<=0)
{
- float h = Math.Abs((float)(DrawSize.Height * series.Data[j] / (start * interval)));
+ float h = Math.Abs((float)(DrawSize.Height * (end * interval-series.Data[j]) / ((end - start) * interval)));
Bars[i].Add(new BarInfo()
{
Rect = new RectangleF(
@@ -119,24 +116,24 @@ namespace Sunny.UI
if (series.Data[j] >= 0)
{
- float h = Math.Abs((float)(highH *series.Data[j] /highV ));
+ float h = Math.Abs((float)(highH * series.Data[j] / highV));
Bars[i].Add(new BarInfo()
{
Rect = new RectangleF(
barX + x1 * (i + 1) + x2 * i,
- DrawOrigin.Y - lowH- h,
+ DrawOrigin.Y - lowH - h,
x2, h)
});
}
else
{
- float h = Math.Abs((float)(lowH*series.Data[j] /lowV ));
+ float h = Math.Abs((float)(lowH * series.Data[j] / lowV));
Bars[i].Add(new BarInfo()
{
Rect = new RectangleF(
barX + x1 * (i + 1) + x2 * i,
- DrawOrigin.Y - lowH+1,
- x2, h-1)
+ DrawOrigin.Y - lowH + 1,
+ x2, h - 1)
});
}
}
@@ -210,8 +207,15 @@ namespace Sunny.UI
tip.Size = new Size((int)Bars[0][selectIndex].Size.Width + 4, (int)Bars[0][selectIndex].Size.Height + 4);
}
- tip.Left = e.Location.X + 15;
- tip.Top = e.Location.Y + 20;
+ 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[0][selectIndex].Tips.IsValid();
}
}
@@ -304,7 +308,9 @@ namespace Sunny.UI
private void DrawAxis(Graphics g)
{
- //g.DrawLine(ChartStyle.ForeColor, DrawOrigin, new Point(DrawOrigin.X + DrawSize.Width, DrawOrigin.Y));
+ 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)
@@ -350,9 +356,12 @@ namespace Sunny.UI
foreach (var data in BarOption.XAxis.Data)
{
SizeF sf = g.MeasureString(data, SubFont);
- g.DrawString(data, SubFont, Color.FromArgb(150, ChartStyle.ForeColor), start - sf.Width / 2.0f, DrawOrigin.Y + BarOption.XAxis.AxisTick.Length);
+ g.DrawString(data, 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)
@@ -393,13 +402,21 @@ namespace Sunny.UI
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);
}
}
diff --git a/SunnyUI/Charts/UIOption.cs b/SunnyUI/Charts/UIOption.cs
index 3ff4cfa5..1174d746 100644
--- a/SunnyUI/Charts/UIOption.cs
+++ b/SunnyUI/Charts/UIOption.cs
@@ -53,7 +53,7 @@ namespace Sunny.UI
public int Left { get; set; } = 60;
public int Right { get; set; } = 60;
public int Top { get; set; } = 60;
- public int Bottom { get; set; } = 40;
+ public int Bottom { get; set; } = 60;
}
public enum UIOrient
diff --git a/SunnyUI/Controls/UIDataGridView.cs b/SunnyUI/Controls/UIDataGridView.cs
index c4d7289b..e230b456 100644
--- a/SunnyUI/Controls/UIDataGridView.cs
+++ b/SunnyUI/Controls/UIDataGridView.cs
@@ -71,7 +71,7 @@ namespace Sunny.UI
SelectionMode = DataGridViewSelectionMode.FullRowSelect;
//禁止调整数据行行高
- AllowUserToResizeRows = false;
+ //AllowUserToResizeRows = false;
//允许调整标题行行宽
AllowUserToResizeColumns = true;
@@ -80,7 +80,7 @@ namespace Sunny.UI
RowHeadersVisible = false;
//禁止行多选
- MultiSelect = false;
+ //MultiSelect = false;
//自动生成行
AutoGenerateColumns = true;
diff --git a/SunnyUI/Static/UGDI.cs b/SunnyUI/Static/UGDI.cs
index d2cdaa7f..1e5cfdad 100644
--- a/SunnyUI/Static/UGDI.cs
+++ b/SunnyUI/Static/UGDI.cs
@@ -641,5 +641,155 @@ namespace Sunny.UI
}
}
}
+
+ public static void DrawString(this Graphics g, string s, Font font, Color color,
+ RectangleF layoutRectangle, StringFormat format, float angle)
+ {
+ using (Brush br= new SolidBrush(color))
+ {
+ g.DrawString(s,font,br,layoutRectangle,format,angle);
+ }
+ }
+
+ public static void DrawString(this Graphics g, string s, Font font, Color color,
+ PointF point, StringFormat format, float angle)
+ {
+ using (Brush br = new SolidBrush(color))
+ {
+ g.DrawString(s,font,br,point,format,angle);
+ }
+ }
+
+ ///
+ /// 绘制根据矩形旋转文本
+ ///
+ /// Graphics
+ /// 文本
+ /// 字体
+ /// 填充
+ /// 局部矩形
+ /// 布局方式
+ /// 角度
+ public static void DrawString(this Graphics g, string s, Font font, Brush brush, RectangleF layoutRectangle, StringFormat format, float angle)
+ {
+ // 求取字符串大小
+ SizeF size = g.MeasureString(s, font);
+
+ // 根据旋转角度,求取旋转后字符串大小
+ SizeF sizeRotate = ConvertSize(size, angle);
+
+ // 根据旋转后尺寸、布局矩形、布局方式计算文本旋转点
+ PointF rotatePt = GetRotatePoint(sizeRotate, layoutRectangle, format);
+
+ // 重设布局方式都为Center
+ StringFormat newFormat = new StringFormat(format);
+ newFormat.Alignment = StringAlignment.Center;
+ newFormat.LineAlignment = StringAlignment.Center;
+
+ // 绘制旋转后文本
+ g.DrawString(s, font, brush, rotatePt, newFormat, angle);
+ }
+
+ ///
+ /// 绘制根据点旋转文本,一般旋转点给定位文本包围盒中心点
+ ///
+ /// Graphics
+ /// 文本
+ /// 字体
+ /// 填充
+ /// 旋转点
+ /// 布局方式
+ /// 角度
+ public static void DrawString(this Graphics g, string s, Font font, Brush brush, PointF point, StringFormat format, float angle)
+ {
+ // Save the matrix
+ Matrix mtxSave = g.Transform;
+
+ Matrix mtxRotate = g.Transform;
+ mtxRotate.RotateAt(angle, point);
+ g.Transform = mtxRotate;
+
+ g.DrawString(s, font, brush, point, format);
+
+ // Reset the matrix
+ g.Transform = mtxSave;
+ }
+
+ private static SizeF ConvertSize(SizeF size, float angle)
+ {
+ Matrix matrix = new Matrix();
+ matrix.Rotate(angle);
+
+ // 旋转矩形四个顶点
+ PointF[] pts = new PointF[4];
+ pts[0].X = -size.Width / 2f;
+ pts[0].Y = -size.Height / 2f;
+ pts[1].X = -size.Width / 2f;
+ pts[1].Y = size.Height / 2f;
+ pts[2].X = size.Width / 2f;
+ pts[2].Y = size.Height / 2f;
+ pts[3].X = size.Width / 2f;
+ pts[3].Y = -size.Height / 2f;
+ matrix.TransformPoints(pts);
+
+ // 求取四个顶点的包围盒
+ float left = float.MaxValue;
+ float right = float.MinValue;
+ float top = float.MaxValue;
+ float bottom = float.MinValue;
+
+ foreach (PointF pt in pts)
+ {
+ // 求取并集
+ if (pt.X < left)
+ left = pt.X;
+ if (pt.X > right)
+ right = pt.X;
+ if (pt.Y < top)
+ top = pt.Y;
+ if (pt.Y > bottom)
+ bottom = pt.Y;
+ }
+
+ SizeF result = new SizeF(right - left, bottom - top);
+ return result;
+ }
+
+ private static PointF GetRotatePoint(SizeF size, RectangleF layoutRectangle, StringFormat format)
+ {
+ PointF pt = new PointF();
+
+ switch (format.Alignment)
+ {
+ case StringAlignment.Near:
+ pt.X = layoutRectangle.Left + size.Width / 2f;
+ break;
+
+ case StringAlignment.Center:
+ pt.X = (layoutRectangle.Left + layoutRectangle.Right) / 2f;
+ break;
+
+ case StringAlignment.Far:
+ pt.X = layoutRectangle.Right - size.Width / 2f;
+ break;
+ }
+
+ switch (format.LineAlignment)
+ {
+ case StringAlignment.Near:
+ pt.Y = layoutRectangle.Top + size.Height / 2f;
+ break;
+
+ case StringAlignment.Center:
+ pt.Y = (layoutRectangle.Top + layoutRectangle.Bottom) / 2f;
+ break;
+
+ case StringAlignment.Far:
+ pt.Y = layoutRectangle.Bottom - size.Height / 2f;
+ break;
+ }
+
+ return pt;
+ }
}
}
\ No newline at end of file