* 重构图表控件,准备开发UIBarChart
* UITextBox:增加EnterAsTab
This commit is contained in:
parent
04f3640217
commit
e9b80647d3
BIN
Bin/SunnyUI.dll
BIN
Bin/SunnyUI.dll
Binary file not shown.
BIN
Bin/SunnyUI.pdb
BIN
Bin/SunnyUI.pdb
Binary file not shown.
Binary file not shown.
Binary file not shown.
1
SunnyUI.Demo/Charts/FPieChart.Designer.cs
generated
1
SunnyUI.Demo/Charts/FPieChart.Designer.cs
generated
@ -70,7 +70,6 @@
|
|||||||
this.PieChart.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(54)))), ((int)(((byte)(54)))), ((int)(((byte)(54)))));
|
this.PieChart.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(54)))), ((int)(((byte)(54)))), ((int)(((byte)(54)))));
|
||||||
this.PieChart.Location = new System.Drawing.Point(26, 46);
|
this.PieChart.Location = new System.Drawing.Point(26, 46);
|
||||||
this.PieChart.Name = "PieChart";
|
this.PieChart.Name = "PieChart";
|
||||||
this.PieChart.Option = null;
|
|
||||||
this.PieChart.RectSides = System.Windows.Forms.ToolStripStatusLabelBorderSides.None;
|
this.PieChart.RectSides = System.Windows.Forms.ToolStripStatusLabelBorderSides.None;
|
||||||
this.PieChart.Size = new System.Drawing.Size(687, 399);
|
this.PieChart.Size = new System.Drawing.Size(687, 399);
|
||||||
this.PieChart.TabIndex = 20;
|
this.PieChart.TabIndex = 20;
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
namespace Sunny.UI.Demo.Controls
|
using System;
|
||||||
|
|
||||||
|
namespace Sunny.UI.Demo.Controls
|
||||||
{
|
{
|
||||||
public partial class FPieChart : UITitlePage
|
public partial class FPieChart : UITitlePage
|
||||||
{
|
{
|
||||||
@ -22,9 +24,11 @@
|
|||||||
PieChart.ChartStyleType = UIChartStyleType.Dark;
|
PieChart.ChartStyleType = UIChartStyleType.Dark;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private void uiSymbolButton1_Click(object sender, System.EventArgs e)
|
private void uiSymbolButton1_Click(object sender, System.EventArgs e)
|
||||||
{
|
{
|
||||||
var option = new UIOption();
|
var option = new UIPieOption();
|
||||||
|
|
||||||
//设置Title
|
//设置Title
|
||||||
option.Title = new UITitle();
|
option.Title = new UITitle();
|
||||||
@ -33,11 +37,11 @@
|
|||||||
option.Title.Left = UILeftAlignment.Center;
|
option.Title.Left = UILeftAlignment.Center;
|
||||||
|
|
||||||
//设置ToolTip
|
//设置ToolTip
|
||||||
option.ToolTip = new UIToolTip();
|
option.ToolTip = new UIPieToolTip();
|
||||||
|
|
||||||
//设置Legend
|
//设置Legend
|
||||||
option.Legend = new UILegend();
|
option.Legend = new UIPieLegend();
|
||||||
option.Legend.Orient = Orient.Vertical;
|
option.Legend.Orient = UIOrient.Vertical;
|
||||||
option.Legend.Top = UITopAlignment.Top;
|
option.Legend.Top = UITopAlignment.Top;
|
||||||
option.Legend.Left = UILeftAlignment.Left;
|
option.Legend.Left = UILeftAlignment.Left;
|
||||||
|
|
||||||
@ -50,9 +54,8 @@
|
|||||||
option.Legend.AddData("2020-05-25");
|
option.Legend.AddData("2020-05-25");
|
||||||
|
|
||||||
//设置Series
|
//设置Series
|
||||||
var series = new UISeries();
|
var series = new UIPieSeries();
|
||||||
series.Name = "Star count";
|
series.Name = "Star count";
|
||||||
series.Type = UISeriesType.Pie;
|
|
||||||
series.Center = new UICenter(50, 55);
|
series.Center = new UICenter(50, 55);
|
||||||
series.Radius = 70;
|
series.Radius = 70;
|
||||||
|
|
||||||
|
9
SunnyUI.Demo/Forms/FEdit.Designer.cs
generated
9
SunnyUI.Demo/Forms/FEdit.Designer.cs
generated
@ -52,10 +52,13 @@
|
|||||||
// edtName
|
// edtName
|
||||||
//
|
//
|
||||||
this.edtName.Cursor = System.Windows.Forms.Cursors.IBeam;
|
this.edtName.Cursor = System.Windows.Forms.Cursors.IBeam;
|
||||||
|
this.edtName.EnterAsTab = true;
|
||||||
this.edtName.FillColor = System.Drawing.Color.White;
|
this.edtName.FillColor = System.Drawing.Color.White;
|
||||||
this.edtName.Font = new System.Drawing.Font("微软雅黑", 12F);
|
this.edtName.Font = new System.Drawing.Font("微软雅黑", 12F);
|
||||||
this.edtName.Location = new System.Drawing.Point(150, 55);
|
this.edtName.Location = new System.Drawing.Point(150, 55);
|
||||||
this.edtName.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
|
this.edtName.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
|
||||||
|
this.edtName.Maximum = 2147483647D;
|
||||||
|
this.edtName.Minimum = -2147483648D;
|
||||||
this.edtName.Name = "edtName";
|
this.edtName.Name = "edtName";
|
||||||
this.edtName.Padding = new System.Windows.Forms.Padding(5);
|
this.edtName.Padding = new System.Windows.Forms.Padding(5);
|
||||||
this.edtName.Size = new System.Drawing.Size(340, 29);
|
this.edtName.Size = new System.Drawing.Size(340, 29);
|
||||||
@ -113,6 +116,8 @@
|
|||||||
this.edtAge.Font = new System.Drawing.Font("微软雅黑", 12F);
|
this.edtAge.Font = new System.Drawing.Font("微软雅黑", 12F);
|
||||||
this.edtAge.Location = new System.Drawing.Point(150, 135);
|
this.edtAge.Location = new System.Drawing.Point(150, 135);
|
||||||
this.edtAge.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
|
this.edtAge.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
|
||||||
|
this.edtAge.Maximum = 2147483647D;
|
||||||
|
this.edtAge.Minimum = -2147483648D;
|
||||||
this.edtAge.Name = "edtAge";
|
this.edtAge.Name = "edtAge";
|
||||||
this.edtAge.Padding = new System.Windows.Forms.Padding(5);
|
this.edtAge.Padding = new System.Windows.Forms.Padding(5);
|
||||||
this.edtAge.Size = new System.Drawing.Size(170, 29);
|
this.edtAge.Size = new System.Drawing.Size(170, 29);
|
||||||
@ -187,6 +192,8 @@
|
|||||||
this.edtDate.Name = "edtDate";
|
this.edtDate.Name = "edtDate";
|
||||||
this.edtDate.Padding = new System.Windows.Forms.Padding(0, 0, 30, 0);
|
this.edtDate.Padding = new System.Windows.Forms.Padding(0, 0, 30, 0);
|
||||||
this.edtDate.Size = new System.Drawing.Size(170, 29);
|
this.edtDate.Size = new System.Drawing.Size(170, 29);
|
||||||
|
this.edtDate.SymbolDropDown = 61555;
|
||||||
|
this.edtDate.SymbolNormal = 61555;
|
||||||
this.edtDate.TabIndex = 5;
|
this.edtDate.TabIndex = 5;
|
||||||
this.edtDate.Text = "2020-05-08";
|
this.edtDate.Text = "2020-05-08";
|
||||||
this.edtDate.TextAlignment = System.Drawing.ContentAlignment.MiddleLeft;
|
this.edtDate.TextAlignment = System.Drawing.ContentAlignment.MiddleLeft;
|
||||||
@ -199,6 +206,8 @@
|
|||||||
this.edtAddress.Font = new System.Drawing.Font("微软雅黑", 12F);
|
this.edtAddress.Font = new System.Drawing.Font("微软雅黑", 12F);
|
||||||
this.edtAddress.Location = new System.Drawing.Point(150, 254);
|
this.edtAddress.Location = new System.Drawing.Point(150, 254);
|
||||||
this.edtAddress.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
|
this.edtAddress.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
|
||||||
|
this.edtAddress.Maximum = 2147483647D;
|
||||||
|
this.edtAddress.Minimum = -2147483648D;
|
||||||
this.edtAddress.Name = "edtAddress";
|
this.edtAddress.Name = "edtAddress";
|
||||||
this.edtAddress.Padding = new System.Windows.Forms.Padding(5);
|
this.edtAddress.Padding = new System.Windows.Forms.Padding(5);
|
||||||
this.edtAddress.Size = new System.Drawing.Size(340, 29);
|
this.edtAddress.Size = new System.Drawing.Size(340, 29);
|
||||||
|
89
SunnyUI/Charts/UIBarChart.cs
Normal file
89
SunnyUI/Charts/UIBarChart.cs
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
using System.Collections.Concurrent;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.Drawing;
|
||||||
|
using Sunny.UI.Charts;
|
||||||
|
|
||||||
|
namespace Sunny.UI
|
||||||
|
{
|
||||||
|
[ToolboxItem(false)]
|
||||||
|
public class UIBarChart : UIChart
|
||||||
|
{
|
||||||
|
protected override void CalcData(UIOption option)
|
||||||
|
{
|
||||||
|
Bars.Clear();
|
||||||
|
UIBarOption o = (UIBarOption)option;
|
||||||
|
if (o == null || o.Series == null || o.Series.Count == 0) return;
|
||||||
|
|
||||||
|
DrawOrigin = new Point(PieOption.Grid.Left,Height - PieOption.Grid.Bottom);
|
||||||
|
DrawSize = new Size(Width- PieOption.Grid.Left- PieOption.Grid.Right,
|
||||||
|
Height -PieOption.Grid.Top-PieOption.Grid.Bottom);
|
||||||
|
|
||||||
|
if (DrawSize.Width<=0 || DrawSize.Height<=0) return;
|
||||||
|
if (o.XAxis.Data.Count==0) return;
|
||||||
|
|
||||||
|
DrawBarWidth = DrawSize.Width / o.XAxis.Data.Count;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Point DrawOrigin;
|
||||||
|
private Size DrawSize;
|
||||||
|
private int DrawBarWidth;
|
||||||
|
private readonly ConcurrentDictionary<int, BarInfo> Bars = new ConcurrentDictionary<int, BarInfo>();
|
||||||
|
|
||||||
|
[Browsable(false)]
|
||||||
|
private UIBarOption PieOption
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
UIOption option = Option ?? EmptyOption;
|
||||||
|
UIBarOption o = (UIBarOption)option;
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void CreateEmptyOption()
|
||||||
|
{
|
||||||
|
if (emptyOption != null) return;
|
||||||
|
|
||||||
|
UIBarOption option = new UIBarOption();
|
||||||
|
option.Title = new UITitle();
|
||||||
|
option.Title = new UITitle();
|
||||||
|
option.Title.Text = "SunnyUI";
|
||||||
|
option.Title.SubText = "BarChart";
|
||||||
|
|
||||||
|
var series = new UIBarSeries();
|
||||||
|
series.Name = "柱状图";
|
||||||
|
series.AddData(1);
|
||||||
|
series.AddData(5);
|
||||||
|
series.AddData(2);
|
||||||
|
series.AddData(4);
|
||||||
|
series.AddData(3);
|
||||||
|
|
||||||
|
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.Series.Add(series);
|
||||||
|
emptyOption = option;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DrawTitle(Graphics g, UITitle title)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DrawSeries(Graphics g, UIPieOption o, List<UIPieSeries> series)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DrawLegend(Graphics g, UIPieLegend legend)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
internal class BarInfo
|
||||||
|
{
|
||||||
|
public Rectangle Rect { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
96
SunnyUI/Charts/UIBarChartOption.cs
Normal file
96
SunnyUI/Charts/UIBarChartOption.cs
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace Sunny.UI.Charts
|
||||||
|
{
|
||||||
|
public class UIBarOption : UIOption, IDisposable
|
||||||
|
{
|
||||||
|
public UITitle Title;
|
||||||
|
|
||||||
|
public UICategoryAxis XAxis { get; set; } = new UICategoryAxis();
|
||||||
|
|
||||||
|
public UIValueAxis YAxis { get; set; } = new UIValueAxis();
|
||||||
|
|
||||||
|
public List<UIBarSeries> Series = new List<UIBarSeries>();
|
||||||
|
|
||||||
|
public UIChartGrid Grid = new UIChartGrid();
|
||||||
|
|
||||||
|
//public UIPieLegend Legend;
|
||||||
|
|
||||||
|
//public UIPieToolTip ToolTip;
|
||||||
|
|
||||||
|
|
||||||
|
public void AddSeries(UIBarSeries series)
|
||||||
|
{
|
||||||
|
Series.Add(series);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
foreach (var series in Series)
|
||||||
|
{
|
||||||
|
series?.Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
Series.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int SeriesCount => Series.Count;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class UIAxis
|
||||||
|
{
|
||||||
|
public string Name { get; set; }
|
||||||
|
|
||||||
|
public UIAxisType Type { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 坐标轴的分割段数,需要注意的是这个分割段数只是个预估值
|
||||||
|
/// 最后实际显示的段数会在这个基础上根据分割后坐标轴刻度显示的易读程度作调整。
|
||||||
|
/// 在类目轴中无效。
|
||||||
|
/// </summary>
|
||||||
|
public int SplitNumber { get; set; } = 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class UICategoryAxis : UIAxis
|
||||||
|
{
|
||||||
|
public UICategoryAxis()
|
||||||
|
{
|
||||||
|
Type = UIAxisType.Category;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<string> Data = new List<string>();
|
||||||
|
|
||||||
|
public void Clear()
|
||||||
|
{
|
||||||
|
Data.Clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class UIValueAxis : UIAxis
|
||||||
|
{
|
||||||
|
public UIValueAxis()
|
||||||
|
{
|
||||||
|
Type = UIAxisType.Value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class UIBarSeries : IDisposable
|
||||||
|
{
|
||||||
|
public string Name { get; set; }
|
||||||
|
|
||||||
|
public UISeriesType Type => UISeriesType.Bar;
|
||||||
|
|
||||||
|
public List<double> Data = new List<double>();
|
||||||
|
|
||||||
|
public void AddData(double value)
|
||||||
|
{
|
||||||
|
Data.Add(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
Data.Clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -19,7 +19,6 @@
|
|||||||
* 2020-06-06: V2.2.5 增加文件说明
|
* 2020-06-06: V2.2.5 增加文件说明
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using System.Drawing.Drawing2D;
|
using System.Drawing.Drawing2D;
|
||||||
@ -60,22 +59,6 @@ namespace Sunny.UI
|
|||||||
tip.Visible = false;
|
tip.Visible = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private int decimalNumber;
|
|
||||||
|
|
||||||
[DefaultValue(0),Description("显示数据格式化小数点后位数")]
|
|
||||||
public int DecimalNumber
|
|
||||||
{
|
|
||||||
get => decimalNumber;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
if (decimalNumber != value)
|
|
||||||
{
|
|
||||||
decimalNumber = value;
|
|
||||||
Invalidate();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected readonly UITransparentPanel tip = new UITransparentPanel();
|
protected readonly UITransparentPanel tip = new UITransparentPanel();
|
||||||
private UIChartStyleType chartStyleType = UIChartStyleType.Plain;
|
private UIChartStyleType chartStyleType = UIChartStyleType.Plain;
|
||||||
|
|
||||||
@ -154,6 +137,7 @@ namespace Sunny.UI
|
|||||||
|
|
||||||
protected UIOption emptyOption;
|
protected UIOption emptyOption;
|
||||||
|
|
||||||
|
[Browsable(false)]
|
||||||
protected UIOption EmptyOption
|
protected UIOption EmptyOption
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
@ -171,7 +155,11 @@ namespace Sunny.UI
|
|||||||
protected override void OnPaint(PaintEventArgs e)
|
protected override void OnPaint(PaintEventArgs e)
|
||||||
{
|
{
|
||||||
base.OnPaint(e);
|
base.OnPaint(e);
|
||||||
DrawOption(e.Graphics, Option ?? EmptyOption);
|
DrawOption(e.Graphics);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual void DrawOption(Graphics g)
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual void CreateEmptyOption()
|
protected virtual void CreateEmptyOption()
|
||||||
@ -180,26 +168,6 @@ namespace Sunny.UI
|
|||||||
|
|
||||||
protected UIChartStyle ChartStyle => UIChartStyles.GetChartStyle(ChartStyleType);
|
protected UIChartStyle ChartStyle => UIChartStyles.GetChartStyle(ChartStyleType);
|
||||||
|
|
||||||
private void DrawOption(Graphics g, UIOption o)
|
|
||||||
{
|
|
||||||
if (o == null) return;
|
|
||||||
if (o.Title != null) DrawTitle(g, o.Title);
|
|
||||||
if (o.Series.Count > 0) DrawSeries(g,o, o.Series);
|
|
||||||
if (o.Legend != null) DrawLegend(g, o.Legend);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected virtual void DrawTitle(Graphics g, UITitle title)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
protected virtual void DrawSeries(Graphics g,UIOption o, List<UISeries> series)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
protected virtual void DrawLegend(Graphics g, UILegend legend)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void SetStyleColor(UIBaseStyle uiColor)
|
public override void SetStyleColor(UIBaseStyle uiColor)
|
||||||
{
|
{
|
||||||
base.SetStyleColor(uiColor);
|
base.SetStyleColor(uiColor);
|
||||||
|
90
SunnyUI/Charts/UIChartStyle.cs
Normal file
90
SunnyUI/Charts/UIChartStyle.cs
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
using System.Drawing;
|
||||||
|
|
||||||
|
namespace Sunny.UI
|
||||||
|
{
|
||||||
|
public class UIChartStyle
|
||||||
|
{
|
||||||
|
public virtual Color BackColor => Color.FromArgb(244, 244, 244);
|
||||||
|
|
||||||
|
public virtual Color ForeColor => Color.FromArgb(54, 54, 54);
|
||||||
|
|
||||||
|
public int ColorCount => 11;
|
||||||
|
|
||||||
|
public virtual Color[] SeriesColor
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return new[]
|
||||||
|
{
|
||||||
|
Color.FromArgb(241,42,38),
|
||||||
|
Color.FromArgb(43,71,85),
|
||||||
|
Color.FromArgb(69,161,168),
|
||||||
|
Color.FromArgb(229,125,96),
|
||||||
|
Color.FromArgb(125,200,175),
|
||||||
|
Color.FromArgb(101,159,132),
|
||||||
|
Color.FromArgb(216,130,27),
|
||||||
|
Color.FromArgb(195,160,152),
|
||||||
|
Color.FromArgb(109,112,115),
|
||||||
|
Color.FromArgb(79,101,112),
|
||||||
|
Color.FromArgb(193,204,211)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class UIDefaultChartStyle : UIChartStyle
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public class UILightChartStyle : UIChartStyle
|
||||||
|
{
|
||||||
|
public override Color[] SeriesColor
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return new[]
|
||||||
|
{
|
||||||
|
Color.FromArgb(0,163,219),
|
||||||
|
Color.FromArgb(0,199,235),
|
||||||
|
Color.FromArgb(0,227,230),
|
||||||
|
Color.FromArgb(131,232,187),
|
||||||
|
Color.FromArgb(255,217,91),
|
||||||
|
Color.FromArgb(255,153,120),
|
||||||
|
Color.FromArgb(255,104,139),
|
||||||
|
Color.FromArgb(245,89,168),
|
||||||
|
Color.FromArgb(247,139,205),
|
||||||
|
Color.FromArgb(241,185,242),
|
||||||
|
Color.FromArgb(156,149,245)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class UIDarkChartStyle : UIChartStyle
|
||||||
|
{
|
||||||
|
public override Color BackColor => Color.FromArgb(54, 54, 54);
|
||||||
|
|
||||||
|
public override Color ForeColor => Color.FromArgb(239, 239, 239);
|
||||||
|
|
||||||
|
public override Color[] SeriesColor
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return new[]
|
||||||
|
{
|
||||||
|
Color.FromArgb(242,99,95),
|
||||||
|
Color.FromArgb(103,154,160),
|
||||||
|
Color.FromArgb(246,152,130),
|
||||||
|
Color.FromArgb(122,194,170),
|
||||||
|
Color.FromArgb(255,119,74),
|
||||||
|
Color.FromArgb(244,220,120),
|
||||||
|
Color.FromArgb(98,163,117),
|
||||||
|
Color.FromArgb(83,186,189),
|
||||||
|
Color.FromArgb(105,137,170),
|
||||||
|
Color.FromArgb(124,203,143),
|
||||||
|
Color.FromArgb(255,154,59)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -20,68 +20,35 @@
|
|||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Drawing;
|
|
||||||
|
|
||||||
namespace Sunny.UI
|
namespace Sunny.UI
|
||||||
{
|
{
|
||||||
public class UIOption : IDisposable
|
public abstract class UIOption
|
||||||
{
|
{
|
||||||
public UITitle Title;
|
|
||||||
|
|
||||||
public List<UISeries> Series = new List<UISeries>();
|
|
||||||
|
|
||||||
public UILegend Legend;
|
|
||||||
|
|
||||||
public UIToolTip ToolTip;
|
|
||||||
|
|
||||||
public void AddSeries(UISeries series)
|
|
||||||
{
|
|
||||||
Series.Add(series);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Dispose()
|
|
||||||
{
|
|
||||||
foreach (var series in Series)
|
|
||||||
{
|
|
||||||
series?.Dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
Series.Clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
public int SeriesCount => Series.Count;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class UIToolTip
|
public class UIChartGrid
|
||||||
{
|
{
|
||||||
public string formatter { get; set; } = "{{a}}" + '\n' + "{{b}} : {{c}} ({{d}}%)";
|
public int Left { get; set; } = 80;
|
||||||
|
public int Right { get; set; } = 80;
|
||||||
|
public int Top { get; set; } = 40;
|
||||||
|
public int Bottom { get; set; } = 40;
|
||||||
}
|
}
|
||||||
|
|
||||||
public class UILegend
|
public enum UIOrient
|
||||||
{
|
|
||||||
public UILeftAlignment Left { get; set; } = UILeftAlignment.Center;
|
|
||||||
|
|
||||||
public UITopAlignment Top { get; set; } = UITopAlignment.Top;
|
|
||||||
|
|
||||||
public Orient Orient { get; set; } = Orient.Vertical;
|
|
||||||
|
|
||||||
public readonly List<string> Data = new List<string>();
|
|
||||||
|
|
||||||
public int DataCount => Data.Count;
|
|
||||||
|
|
||||||
public void AddData(string data)
|
|
||||||
{
|
|
||||||
Data.Add(data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public enum Orient
|
|
||||||
{
|
{
|
||||||
Vertical,
|
Vertical,
|
||||||
Horizontal
|
Horizontal
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public enum UIAxisType
|
||||||
|
{
|
||||||
|
Value,
|
||||||
|
Category,
|
||||||
|
Time,
|
||||||
|
Log
|
||||||
|
}
|
||||||
|
|
||||||
public class UITitle
|
public class UITitle
|
||||||
{
|
{
|
||||||
public string Text { get; set; } = "UIPieChart";
|
public string Text { get; set; } = "UIPieChart";
|
||||||
@ -107,29 +74,6 @@ namespace Sunny.UI
|
|||||||
Bottom
|
Bottom
|
||||||
}
|
}
|
||||||
|
|
||||||
public class UISeries : IDisposable
|
|
||||||
{
|
|
||||||
public string Name { get; set; }
|
|
||||||
|
|
||||||
public UISeriesType Type { get; set; }
|
|
||||||
|
|
||||||
public int Radius { get; set; } = 50;
|
|
||||||
|
|
||||||
public UICenter Center { get; set; } = new UICenter(50, 50);
|
|
||||||
|
|
||||||
public readonly List<UISeriesData> Data = new List<UISeriesData>();
|
|
||||||
|
|
||||||
public void AddData(string name, double value)
|
|
||||||
{
|
|
||||||
Data.Add(new UISeriesData(name, value));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Dispose()
|
|
||||||
{
|
|
||||||
Data.Clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class UICenter
|
public class UICenter
|
||||||
{
|
{
|
||||||
public int Left { get; set; }
|
public int Left { get; set; }
|
||||||
@ -147,23 +91,6 @@ namespace Sunny.UI
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class UISeriesData
|
|
||||||
{
|
|
||||||
public string Name { get; set; }
|
|
||||||
|
|
||||||
public double Value { get; set; }
|
|
||||||
|
|
||||||
public UISeriesData()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public UISeriesData(string name, double value)
|
|
||||||
{
|
|
||||||
Name = name;
|
|
||||||
Value = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public enum UISeriesType
|
public enum UISeriesType
|
||||||
{
|
{
|
||||||
Pie,
|
Pie,
|
||||||
@ -194,89 +121,94 @@ namespace Sunny.UI
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class UIChartStyle
|
public static class UIChartHelper
|
||||||
{
|
{
|
||||||
public virtual Color BackColor => Color.FromArgb(244, 244, 244);
|
/// <summary>
|
||||||
|
/// 计算刻度
|
||||||
public virtual Color ForeColor => Color.FromArgb(54, 54, 54);
|
/// 起始值必须小于结束值
|
||||||
|
/// </summary>
|
||||||
public int ColorCount => 11;
|
/// <param name="start">起始值</param>
|
||||||
|
/// <param name="end">结束值</param>
|
||||||
public virtual Color[] SeriesColor
|
/// <param name="expect_num">期望刻度数量,实际数接近此数</param>
|
||||||
|
/// <param name="degree_start">刻度起始值,须乘以间隔使用</param>
|
||||||
|
/// <param name="degree_end">刻度结束值,须乘以间隔使用</param>
|
||||||
|
/// <param name="degree_gap">刻度间隔</param>
|
||||||
|
public static void CalcDegreeScale(double start, double end, int expect_num,
|
||||||
|
out int degree_start, out int degree_end, out double degree_gap)
|
||||||
{
|
{
|
||||||
get
|
if (start >= end)
|
||||||
{
|
{
|
||||||
return new[]
|
throw new Exception("起始值必须小于结束值");
|
||||||
{
|
|
||||||
Color.FromArgb(241,42,38),
|
|
||||||
Color.FromArgb(43,71,85),
|
|
||||||
Color.FromArgb(69,161,168),
|
|
||||||
Color.FromArgb(229,125,96),
|
|
||||||
Color.FromArgb(125,200,175),
|
|
||||||
Color.FromArgb(101,159,132),
|
|
||||||
Color.FromArgb(216,130,27),
|
|
||||||
Color.FromArgb(195,160,152),
|
|
||||||
Color.FromArgb(109,112,115),
|
|
||||||
Color.FromArgb(79,101,112),
|
|
||||||
Color.FromArgb(193,204,211)
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
double differ = end - start;
|
||||||
|
double differ_gap = differ / (expect_num - 1); //35, 4.6, 0.27
|
||||||
|
|
||||||
|
double exponent = Math.Log10(differ_gap) - 1; //0.54, -0.34, -1.57
|
||||||
|
int _exponent = (int)exponent; //0, 0=>-1, -1=>-2
|
||||||
|
if (exponent < 0 && Math.Abs(exponent) > 1e-8)
|
||||||
|
{
|
||||||
|
_exponent--;
|
||||||
|
}
|
||||||
|
|
||||||
|
int step = (int)(differ_gap / Math.Pow(10, _exponent)); //35, 46, 27
|
||||||
|
int[] fix_steps = new int[] { 10, 20, 25, 50, 100 };
|
||||||
|
int fix_step = 10; //25, 50, 25
|
||||||
|
for (int i = fix_steps.Length - 1; i >= 1; i--)
|
||||||
|
{
|
||||||
|
if (step > (fix_steps[i] + fix_steps[i - 1]) / 2)
|
||||||
|
{
|
||||||
|
fix_step = fix_steps[i];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
degree_gap = fix_step * Math.Pow(10, _exponent); //25, 5, 0.25
|
||||||
|
|
||||||
|
double start1 = start / degree_gap;
|
||||||
|
int start2 = (int)start1;
|
||||||
|
if (start1 < 0 && Math.Abs(start1 - start2) > 1e-8)
|
||||||
|
{
|
||||||
|
start2--;
|
||||||
|
}
|
||||||
|
|
||||||
|
degree_start = start2;
|
||||||
|
|
||||||
|
double end1 = end / degree_gap;
|
||||||
|
int end2 = (int)end1;
|
||||||
|
if (end1 >= 0 && Math.Abs(end1 - end2) > 1e-8)
|
||||||
|
{
|
||||||
|
end2++;
|
||||||
|
}
|
||||||
|
|
||||||
|
degree_end = end2;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public class UIDefaultChartStyle : UIChartStyle
|
/// <summary>
|
||||||
{
|
/// 计算刻度
|
||||||
}
|
/// 起始值必须小于结束值
|
||||||
|
/// </summary>
|
||||||
public class UILightChartStyle : UIChartStyle
|
/// <param name="start">起始值</param>
|
||||||
{
|
/// <param name="end">结束值</param>
|
||||||
public override Color[] SeriesColor
|
/// <param name="expect_num">期望刻度数量,实际数接近此数</param>
|
||||||
|
/// <returns>刻度列表</returns>
|
||||||
|
public static double[] CalcDegreeScale(double start, double end, int expect_num)
|
||||||
{
|
{
|
||||||
get
|
if (start >= end)
|
||||||
{
|
{
|
||||||
return new[]
|
throw new Exception("起始值必须小于结束值");
|
||||||
{
|
|
||||||
Color.FromArgb(0,163,219),
|
|
||||||
Color.FromArgb(0,199,235),
|
|
||||||
Color.FromArgb(0,227,230),
|
|
||||||
Color.FromArgb(131,232,187),
|
|
||||||
Color.FromArgb(255,217,91),
|
|
||||||
Color.FromArgb(255,153,120),
|
|
||||||
Color.FromArgb(255,104,139),
|
|
||||||
Color.FromArgb(245,89,168),
|
|
||||||
Color.FromArgb(247,139,205),
|
|
||||||
Color.FromArgb(241,185,242),
|
|
||||||
Color.FromArgb(156,149,245)
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class UIDarkChartStyle : UIChartStyle
|
CalcDegreeScale(start, end, expect_num, out int degree_start, out int degree_end,
|
||||||
{
|
out double degree_gap);
|
||||||
public override Color BackColor => Color.FromArgb(54, 54, 54);
|
|
||||||
|
|
||||||
public override Color ForeColor => Color.FromArgb(239, 239, 239);
|
double[] list = new double[degree_end - degree_start + 1];
|
||||||
|
for (int i = degree_start; i <= degree_end; i++)
|
||||||
public override Color[] SeriesColor
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
{
|
||||||
return new[]
|
list[i - degree_start] = i * degree_gap;
|
||||||
{
|
|
||||||
Color.FromArgb(242,99,95),
|
|
||||||
Color.FromArgb(103,154,160),
|
|
||||||
Color.FromArgb(246,152,130),
|
|
||||||
Color.FromArgb(122,194,170),
|
|
||||||
Color.FromArgb(255,119,74),
|
|
||||||
Color.FromArgb(244,220,120),
|
|
||||||
Color.FromArgb(98,163,117),
|
|
||||||
Color.FromArgb(83,186,189),
|
|
||||||
Color.FromArgb(105,137,170),
|
|
||||||
Color.FromArgb(124,203,143),
|
|
||||||
Color.FromArgb(255,154,59)
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return list;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -35,15 +35,14 @@ namespace Sunny.UI
|
|||||||
{
|
{
|
||||||
if (emptyOption != null) return;
|
if (emptyOption != null) return;
|
||||||
|
|
||||||
emptyOption = new UIOption();
|
UIPieOption option = new UIPieOption();
|
||||||
|
|
||||||
emptyOption.Title = new UITitle();
|
option.Title = new UITitle();
|
||||||
emptyOption.Title.Text = "SunnyUI";
|
option.Title.Text = "SunnyUI";
|
||||||
emptyOption.Title.SubText = "PieChart";
|
option.Title.SubText = "PieChart";
|
||||||
|
|
||||||
var series = new UISeries();
|
var series = new UIPieSeries();
|
||||||
series.Name = "饼状图";
|
series.Name = "饼状图";
|
||||||
series.Type = UISeriesType.Pie;
|
|
||||||
series.Center = new UICenter(50, 55);
|
series.Center = new UICenter(50, 55);
|
||||||
series.Radius = 70;
|
series.Radius = 70;
|
||||||
for (int i = 0; i < 5; i++)
|
for (int i = 0; i < 5; i++)
|
||||||
@ -51,10 +50,19 @@ namespace Sunny.UI
|
|||||||
series.AddData("Data" + i, (i + 1) * 20);
|
series.AddData("Data" + i, (i + 1) * 20);
|
||||||
}
|
}
|
||||||
|
|
||||||
emptyOption.Series.Add(series);
|
option.Series.Add(series);
|
||||||
|
emptyOption = option;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void DrawTitle(Graphics g, UITitle title)
|
protected override void DrawOption(Graphics g)
|
||||||
|
{
|
||||||
|
if (PieOption == null) return;
|
||||||
|
if (PieOption.Title != null) DrawTitle(g, PieOption.Title);
|
||||||
|
if (PieOption.Series.Count > 0) DrawSeries(g, PieOption.Series);
|
||||||
|
if (PieOption.Legend != null) DrawLegend(g, PieOption.Legend);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DrawTitle(Graphics g, UITitle title)
|
||||||
{
|
{
|
||||||
if (title == null) return;
|
if (title == null) return;
|
||||||
SizeF sf = g.MeasureString(title.Text, Font);
|
SizeF sf = g.MeasureString(title.Text, Font);
|
||||||
@ -93,17 +101,17 @@ namespace Sunny.UI
|
|||||||
g.DrawString(title.SubText, subFont, ChartStyle.ForeColor, left, top);
|
g.DrawString(title.SubText, subFont, ChartStyle.ForeColor, left, top);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void CalcData(UIOption o)
|
protected override void CalcData(UIOption option)
|
||||||
{
|
{
|
||||||
Angles.Clear();
|
Angles.Clear();
|
||||||
|
UIPieOption o = (UIPieOption)option;
|
||||||
if (o == null || o.Series == null || o.Series.Count == 0) return;
|
if (o == null || o.Series == null || o.Series.Count == 0) return;
|
||||||
UITemplate template = null;
|
UITemplate template = null;
|
||||||
if (o.ToolTip != null)
|
if (o.ToolTip != null)
|
||||||
{
|
{
|
||||||
template = new UITemplate(o.ToolTip.formatter);
|
template = new UITemplate(o.ToolTip.Formatter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
for (int pieIndex = 0; pieIndex < o.Series.Count; pieIndex++)
|
for (int pieIndex = 0; pieIndex < o.Series.Count; pieIndex++)
|
||||||
{
|
{
|
||||||
var pie = o.Series[pieIndex];
|
var pie = o.Series[pieIndex];
|
||||||
@ -130,14 +138,14 @@ namespace Sunny.UI
|
|||||||
{
|
{
|
||||||
template.Set("a", pie.Name);
|
template.Set("a", pie.Name);
|
||||||
template.Set("b", pie.Data[i].Name);
|
template.Set("b", pie.Data[i].Name);
|
||||||
template.Set("c", pie.Data[i].Value.ToString("F" + DecimalNumber));
|
template.Set("c", pie.Data[i].Value.ToString(o.ToolTip.ValueFormat));
|
||||||
template.Set("d", percent.ToString("F2"));
|
template.Set("d", percent.ToString("F2"));
|
||||||
text = template.Render();
|
text = template.Render();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
text = pie.Data[i].Name + " : " + pie.Data[i].Value.ToString("F" + DecimalNumber) + "(" + percent.ToString("F2") + "%)";
|
text = pie.Data[i].Name + " : " + pie.Data[i].Value.ToString("F2") + "(" + percent.ToString("F2") + "%)";
|
||||||
if (pie.Name.IsValid()) text = pie.Name + '\n' + text;
|
if (pie.Name.IsValid()) text = pie.Name + '\n' + text;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -148,7 +156,7 @@ namespace Sunny.UI
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void DrawSeries(Graphics g, UIOption o, List<UISeries> series)
|
private void DrawSeries(Graphics g, List<UIPieSeries> series)
|
||||||
{
|
{
|
||||||
if (series == null || series.Count == 0) return;
|
if (series == null || series.Count == 0) return;
|
||||||
|
|
||||||
@ -168,7 +176,7 @@ namespace Sunny.UI
|
|||||||
|
|
||||||
private readonly ConcurrentDictionary<int, ConcurrentDictionary<int, Angle>> Angles = new ConcurrentDictionary<int, ConcurrentDictionary<int, Angle>>();
|
private readonly ConcurrentDictionary<int, ConcurrentDictionary<int, Angle>> Angles = new ConcurrentDictionary<int, ConcurrentDictionary<int, Angle>>();
|
||||||
|
|
||||||
protected override void DrawLegend(Graphics g, UILegend legend)
|
private void DrawLegend(Graphics g, UIPieLegend legend)
|
||||||
{
|
{
|
||||||
if (legend == null) return;
|
if (legend == null) return;
|
||||||
|
|
||||||
@ -191,7 +199,7 @@ namespace Sunny.UI
|
|||||||
float top = 0;
|
float top = 0;
|
||||||
float left = 0;
|
float left = 0;
|
||||||
|
|
||||||
if (legend.Orient == Orient.Horizontal)
|
if (legend.Orient == UIOrient.Horizontal)
|
||||||
{
|
{
|
||||||
if (legend.Left == UILeftAlignment.Left) left = TextInterval;
|
if (legend.Left == UILeftAlignment.Left) left = TextInterval;
|
||||||
if (legend.Left == UILeftAlignment.Center) left = (Width - totalWidth) / 2.0f;
|
if (legend.Left == UILeftAlignment.Center) left = (Width - totalWidth) / 2.0f;
|
||||||
@ -202,7 +210,7 @@ namespace Sunny.UI
|
|||||||
if (legend.Top == UITopAlignment.Bottom) top = Height - oneHeight - TextInterval;
|
if (legend.Top == UITopAlignment.Bottom) top = Height - oneHeight - TextInterval;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (legend.Orient == Orient.Vertical)
|
if (legend.Orient == UIOrient.Vertical)
|
||||||
{
|
{
|
||||||
if (legend.Left == UILeftAlignment.Left) left = TextInterval;
|
if (legend.Left == UILeftAlignment.Left) left = TextInterval;
|
||||||
if (legend.Left == UILeftAlignment.Center) left = (Width - maxWidth) / 2.0f - 10;
|
if (legend.Left == UILeftAlignment.Center) left = (Width - maxWidth) / 2.0f - 10;
|
||||||
@ -219,7 +227,7 @@ namespace Sunny.UI
|
|||||||
{
|
{
|
||||||
var data = legend.Data[i];
|
var data = legend.Data[i];
|
||||||
SizeF sf = g.MeasureString(data, LegendFont);
|
SizeF sf = g.MeasureString(data, LegendFont);
|
||||||
if (legend.Orient == Orient.Horizontal)
|
if (legend.Orient == UIOrient.Horizontal)
|
||||||
{
|
{
|
||||||
g.FillRoundRectangle(ChartStyle.SeriesColor[i % ChartStyle.ColorCount], (int)startleft, (int)top + 1, 18, (int)oneHeight - 2, 5);
|
g.FillRoundRectangle(ChartStyle.SeriesColor[i % ChartStyle.ColorCount], (int)startleft, (int)top + 1, 18, (int)oneHeight - 2, 5);
|
||||||
g.DrawString(data, LegendFont, ChartStyle.ForeColor, startleft + 20, top);
|
g.DrawString(data, LegendFont, ChartStyle.ForeColor, startleft + 20, top);
|
||||||
@ -227,7 +235,7 @@ namespace Sunny.UI
|
|||||||
startleft += sf.Width;
|
startleft += sf.Width;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (legend.Orient == Orient.Vertical)
|
if (legend.Orient == UIOrient.Vertical)
|
||||||
{
|
{
|
||||||
g.FillRoundRectangle(ChartStyle.SeriesColor[i % ChartStyle.ColorCount], (int)left, (int)starttop + 1, 18, (int)oneHeight - 2, 5);
|
g.FillRoundRectangle(ChartStyle.SeriesColor[i % ChartStyle.ColorCount], (int)left, (int)starttop + 1, 18, (int)oneHeight - 2, 5);
|
||||||
g.DrawString(data, LegendFont, ChartStyle.ForeColor, left + 20, starttop);
|
g.DrawString(data, LegendFont, ChartStyle.ForeColor, left + 20, starttop);
|
||||||
@ -236,27 +244,37 @@ namespace Sunny.UI
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Browsable(false)]
|
||||||
|
private UIPieOption PieOption
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
UIOption option = Option ?? EmptyOption;
|
||||||
|
UIPieOption o = (UIPieOption)option;
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected override void OnMouseMove(MouseEventArgs e)
|
protected override void OnMouseMove(MouseEventArgs e)
|
||||||
{
|
{
|
||||||
base.OnMouseMove(e);
|
base.OnMouseMove(e);
|
||||||
UIOption option = Option ?? EmptyOption;
|
|
||||||
|
|
||||||
if (option.SeriesCount == 0)
|
if (PieOption.SeriesCount == 0)
|
||||||
{
|
{
|
||||||
SetPieAndAzIndex(-1, -1);
|
SetPieAndAzIndex(-1, -1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int pieIndex = 0; pieIndex < option.SeriesCount; pieIndex++)
|
for (int pieIndex = 0; pieIndex < PieOption.SeriesCount; pieIndex++)
|
||||||
{
|
{
|
||||||
RectangleF rect = GetSeriesRect(option.Series[pieIndex]);
|
RectangleF rect = GetSeriesRect(PieOption.Series[pieIndex]);
|
||||||
if (!e.Location.InRect(rect)) continue;
|
if (!e.Location.InRect(rect)) continue;
|
||||||
|
|
||||||
PointF pf = new PointF(rect.Left + rect.Width / 2.0f, rect.Top + rect.Height / 2.0f);
|
PointF pf = new PointF(rect.Left + rect.Width / 2.0f, rect.Top + rect.Height / 2.0f);
|
||||||
if (MathEx.CalcDistance(e.Location, pf) * 2 > rect.Width) continue;
|
if (MathEx.CalcDistance(e.Location, pf) * 2 > rect.Width) continue;
|
||||||
|
|
||||||
double az = MathEx.CalcAngle(e.Location, pf);
|
double az = MathEx.CalcAngle(e.Location, pf);
|
||||||
for (int azIndex = 0; azIndex < option.Series[pieIndex].Data.Count; azIndex++)
|
for (int azIndex = 0; azIndex < PieOption.Series[pieIndex].Data.Count; azIndex++)
|
||||||
{
|
{
|
||||||
if (az >= Angles[pieIndex][azIndex].Start && az <= Angles[pieIndex][azIndex].Start + Angles[pieIndex][azIndex].Sweep)
|
if (az >= Angles[pieIndex][azIndex].Start && az <= Angles[pieIndex][azIndex].Start + Angles[pieIndex][azIndex].Sweep)
|
||||||
{
|
{
|
||||||
@ -311,7 +329,7 @@ namespace Sunny.UI
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private RectangleF GetSeriesRect(UISeries series)
|
private RectangleF GetSeriesRect(UIPieSeries series)
|
||||||
{
|
{
|
||||||
int left = series.Center.Left;
|
int left = series.Center.Left;
|
||||||
int top = series.Center.Top;
|
int top = series.Center.Top;
|
||||||
@ -321,7 +339,7 @@ namespace Sunny.UI
|
|||||||
return new RectangleF(left - halfRadius, top - halfRadius, halfRadius * 2, halfRadius * 2);
|
return new RectangleF(left - halfRadius, top - halfRadius, halfRadius * 2, halfRadius * 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Angle
|
internal class Angle
|
||||||
{
|
{
|
||||||
public float Start { get; set; }
|
public float Start { get; set; }
|
||||||
public float Sweep { get; set; }
|
public float Sweep { get; set; }
|
||||||
|
164
SunnyUI/Charts/UIPieChartOption.cs
Normal file
164
SunnyUI/Charts/UIPieChartOption.cs
Normal file
@ -0,0 +1,164 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace Sunny.UI
|
||||||
|
{
|
||||||
|
public class UIPieOption : UIOption, IDisposable
|
||||||
|
{
|
||||||
|
public UITitle Title;
|
||||||
|
|
||||||
|
public List<UIPieSeries> Series = new List<UIPieSeries>();
|
||||||
|
|
||||||
|
public UIPieLegend Legend;
|
||||||
|
|
||||||
|
public UIPieToolTip ToolTip;
|
||||||
|
|
||||||
|
public void AddSeries(UIPieSeries series)
|
||||||
|
{
|
||||||
|
Series.Clear();
|
||||||
|
Series.Add(series);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
foreach (var series in Series)
|
||||||
|
{
|
||||||
|
series?.Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
Series.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int SeriesCount => Series.Count;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class UIDoughnutPieOption : UIOption, IDisposable
|
||||||
|
{
|
||||||
|
public UITitle Title;
|
||||||
|
|
||||||
|
public List<UIDoughnutPieSeries> Series = new List<UIDoughnutPieSeries>();
|
||||||
|
|
||||||
|
public UIPieLegend Legend;
|
||||||
|
|
||||||
|
public UIPieToolTip ToolTip;
|
||||||
|
|
||||||
|
public void AddSeries(UIDoughnutPieSeries series)
|
||||||
|
{
|
||||||
|
Series.Clear();
|
||||||
|
Series.Add(series);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
foreach (var series in Series)
|
||||||
|
{
|
||||||
|
series?.Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
Series.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int SeriesCount => Series.Count;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class UIPieToolTip
|
||||||
|
{
|
||||||
|
public string Formatter { get; set; } = "{{a}}" + '\n' + "{{b}} : {{c}} ({{d}}%)";
|
||||||
|
|
||||||
|
public string ValueFormat { get; set; } = "F0";
|
||||||
|
}
|
||||||
|
|
||||||
|
public class UIPieLegend
|
||||||
|
{
|
||||||
|
public UILeftAlignment Left { get; set; } = UILeftAlignment.Center;
|
||||||
|
|
||||||
|
public UITopAlignment Top { get; set; } = UITopAlignment.Top;
|
||||||
|
|
||||||
|
public UIOrient Orient { get; set; } = UIOrient.Vertical;
|
||||||
|
|
||||||
|
public readonly List<string> Data = new List<string>();
|
||||||
|
|
||||||
|
public int DataCount => Data.Count;
|
||||||
|
|
||||||
|
public void AddData(string data)
|
||||||
|
{
|
||||||
|
Data.Add(data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class UIPieSeries : IDisposable
|
||||||
|
{
|
||||||
|
public string Name { get; set; }
|
||||||
|
|
||||||
|
public UISeriesType Type => UISeriesType.Pie;
|
||||||
|
|
||||||
|
public int Radius { get; set; } = 70;
|
||||||
|
|
||||||
|
public UICenter Center { get; set; } = new UICenter(50, 50);
|
||||||
|
|
||||||
|
public readonly List<UIPieSeriesData> Data = new List<UIPieSeriesData>();
|
||||||
|
|
||||||
|
public void AddData(string name, double value)
|
||||||
|
{
|
||||||
|
Data.Add(new UIPieSeriesData(name, value));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
Data.Clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class RadiusInOut
|
||||||
|
{
|
||||||
|
public int Inner { get; set; }
|
||||||
|
|
||||||
|
public int Outer { get; set; }
|
||||||
|
|
||||||
|
public RadiusInOut(int inner,int outer)
|
||||||
|
{
|
||||||
|
Inner = inner;
|
||||||
|
Outer = outer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class UIDoughnutPieSeries : IDisposable
|
||||||
|
{
|
||||||
|
public string Name { get; set; }
|
||||||
|
|
||||||
|
public UISeriesType Type { get; set; }
|
||||||
|
|
||||||
|
public RadiusInOut Radius { get; set; } = new RadiusInOut(50,70);
|
||||||
|
|
||||||
|
public UICenter Center { get; set; } = new UICenter(50, 50);
|
||||||
|
|
||||||
|
public readonly List<UIPieSeriesData> Data = new List<UIPieSeriesData>();
|
||||||
|
|
||||||
|
public void AddData(string name, double value)
|
||||||
|
{
|
||||||
|
Data.Add(new UIPieSeriesData(name, value));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
Data.Clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class UIPieSeriesData
|
||||||
|
{
|
||||||
|
public string Name { get; set; }
|
||||||
|
|
||||||
|
public double Value { get; set; }
|
||||||
|
|
||||||
|
public UIPieSeriesData()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public UIPieSeriesData(string name, double value)
|
||||||
|
{
|
||||||
|
Name = name;
|
||||||
|
Value = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -25,7 +25,6 @@ using System.Collections;
|
|||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using System.Drawing.Design;
|
using System.Drawing.Design;
|
||||||
using System.Drawing.Drawing2D;
|
|
||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
|
|
||||||
namespace Sunny.UI
|
namespace Sunny.UI
|
||||||
@ -86,7 +85,7 @@ namespace Sunny.UI
|
|||||||
private void OnMouseWheel(object sender, MouseEventArgs e)
|
private void OnMouseWheel(object sender, MouseEventArgs e)
|
||||||
{
|
{
|
||||||
base.OnMouseWheel(e);
|
base.OnMouseWheel(e);
|
||||||
if (bar!=null && bar.Visible && edit!=null)
|
if (bar != null && bar.Visible && edit != null)
|
||||||
{
|
{
|
||||||
var si = ScrollBarInfo.GetInfo(edit.Handle);
|
var si = ScrollBarInfo.GetInfo(edit.Handle);
|
||||||
if (e.Delta > 10)
|
if (e.Delta > 10)
|
||||||
@ -509,7 +508,6 @@ namespace Sunny.UI
|
|||||||
edit.Paste(text);
|
edit.Paste(text);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
internal class TextBoxAutoCompleteSourceConverter : EnumConverter
|
internal class TextBoxAutoCompleteSourceConverter : EnumConverter
|
||||||
{
|
{
|
||||||
public TextBoxAutoCompleteSourceConverter(Type type) : base(type)
|
public TextBoxAutoCompleteSourceConverter(Type type) : base(type)
|
||||||
@ -541,6 +539,13 @@ namespace Sunny.UI
|
|||||||
set => edit.AcceptsTab = value;
|
set => edit.AcceptsTab = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[DefaultValue(false)]
|
||||||
|
public bool EnterAsTab
|
||||||
|
{
|
||||||
|
get => edit.EnterAsTab;
|
||||||
|
set => edit.EnterAsTab = value;
|
||||||
|
}
|
||||||
|
|
||||||
[DefaultValue(true)]
|
[DefaultValue(true)]
|
||||||
public bool ShortcutsEnabled
|
public bool ShortcutsEnabled
|
||||||
{
|
{
|
||||||
|
@ -51,10 +51,16 @@
|
|||||||
<Reference Include="System.Xml" />
|
<Reference Include="System.Xml" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<Compile Include="Charts\UIBarChart.cs">
|
||||||
|
<SubType>Component</SubType>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="Charts\UIBarChartOption.cs" />
|
||||||
<Compile Include="Charts\UIChart.cs">
|
<Compile Include="Charts\UIChart.cs">
|
||||||
<SubType>Component</SubType>
|
<SubType>Component</SubType>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
<Compile Include="Charts\UIChartStyle.cs" />
|
||||||
<Compile Include="Charts\UIOption.cs" />
|
<Compile Include="Charts\UIOption.cs" />
|
||||||
|
<Compile Include="Charts\UIPieChartOption.cs" />
|
||||||
<Compile Include="Controls\Color\UIColorBar.cs">
|
<Compile Include="Controls\Color\UIColorBar.cs">
|
||||||
<SubType>Component</SubType>
|
<SubType>Component</SubType>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
@ -1,5 +1,9 @@
|
|||||||
+ 增加; - 删除; * 修改
|
+ 增加; - 删除; * 修改
|
||||||
|
|
||||||
|
2020.06.14
|
||||||
|
* 重构图表控件,准备开发UIBarChart
|
||||||
|
* UITextBox:增加EnterAsTab
|
||||||
|
|
||||||
2020.06.12
|
2020.06.12
|
||||||
+ UIComboBox:增加数据绑定,可设置DataSource,DisplayMember,ValueMember
|
+ UIComboBox:增加数据绑定,可设置DataSource,DisplayMember,ValueMember
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user