+UIBarChart:新增UIBarChart控件

This commit is contained in:
Sunny 2020-06-15 23:10:32 +08:00
parent 2569f8d3b1
commit 7608291778
26 changed files with 896 additions and 234 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

153
SunnyUI.Demo/Charts/FBarChart.Designer.cs generated Normal file
View File

@ -0,0 +1,153 @@
namespace Sunny.UI.Demo.Charts
{
partial class FBarChart
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.BarChart = new Sunny.UI.UIBarChart();
this.uiLine1 = new Sunny.UI.UILine();
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.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(800, 528);
//
// 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.Name = "BarChart";
this.BarChart.Option = null;
this.BarChart.Size = new System.Drawing.Size(670, 400);
this.BarChart.TabIndex = 0;
this.BarChart.Text = "uiBarChart1";
//
// 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 = 20;
this.uiLine1.Text = "UIBarChart";
this.uiLine1.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
//
// 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.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 = 28;
this.uiSymbolButton1.Text = "数据";
this.uiSymbolButton1.Click += new System.EventHandler(this.uiSymbolButton1_Click);
//
// uiImageButton3
//
this.uiImageButton3.Cursor = System.Windows.Forms.Cursors.Hand;
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 = 27;
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.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 = 26;
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.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 = 25;
this.uiImageButton1.TabStop = false;
this.uiImageButton1.Text = " Default";
this.uiImageButton1.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
this.uiImageButton1.Click += new System.EventHandler(this.uiImageButton1_Click);
//
// FBarChart
//
this.AutoScaleDimensions = new System.Drawing.SizeF(10F, 21F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(800, 563);
this.Name = "FBarChart";
this.Symbol = 61568;
this.Text = "BarChart";
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 UIBarChart BarChart;
private UILine uiLine1;
private UISymbolButton uiSymbolButton1;
private UIImageButton uiImageButton3;
private UIImageButton uiImageButton2;
private UIImageButton uiImageButton1;
}
}

View File

@ -0,0 +1,67 @@
namespace Sunny.UI.Demo.Charts
{
public partial class FBarChart : UITitlePage
{
public FBarChart()
{
InitializeComponent();
}
private void uiSymbolButton1_Click(object sender, System.EventArgs e)
{
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");
var series = new UIBarSeries();
series.Name = "Bar1";
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(21);
series.AddData(25);
series.AddData(23);
series.AddData(24);
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");
BarChart.SetOption(option);
}
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;
}
}
}

View File

@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@ -68,10 +68,11 @@
this.PieChart.FillColor = System.Drawing.Color.FromArgb(((int)(((byte)(244)))), ((int)(((byte)(244)))), ((int)(((byte)(244)))));
this.PieChart.Font = new System.Drawing.Font("微软雅黑", 12F);
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(30, 48);
this.PieChart.Name = "PieChart";
this.PieChart.Option = null;
this.PieChart.RectSides = System.Windows.Forms.ToolStripStatusLabelBorderSides.None;
this.PieChart.Size = new System.Drawing.Size(687, 399);
this.PieChart.Size = new System.Drawing.Size(670, 400);
this.PieChart.TabIndex = 20;
this.PieChart.Text = "uiPieChart1";
//
@ -79,7 +80,7 @@
//
this.uiImageButton1.Cursor = System.Windows.Forms.Cursors.Hand;
this.uiImageButton1.Image = global::Sunny.UI.Demo.Properties.Resources.ChartDefaultStyle;
this.uiImageButton1.Location = new System.Drawing.Point(26, 470);
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 = 21;
@ -92,7 +93,7 @@
//
this.uiImageButton2.Cursor = System.Windows.Forms.Cursors.Hand;
this.uiImageButton2.Image = global::Sunny.UI.Demo.Properties.Resources.ChartPlainStyle;
this.uiImageButton2.Location = new System.Drawing.Point(132, 470);
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 = 22;
@ -105,7 +106,7 @@
//
this.uiImageButton3.Cursor = System.Windows.Forms.Cursors.Hand;
this.uiImageButton3.Image = global::Sunny.UI.Demo.Properties.Resources.ChartDarkStyle;
this.uiImageButton3.Location = new System.Drawing.Point(238, 470);
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 = 23;
@ -118,7 +119,7 @@
//
this.uiSymbolButton1.Cursor = System.Windows.Forms.Cursors.Hand;
this.uiSymbolButton1.Font = new System.Drawing.Font("微软雅黑", 12F);
this.uiSymbolButton1.Location = new System.Drawing.Point(344, 470);
this.uiSymbolButton1.Location = new System.Drawing.Point(348, 466);
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);

View File

@ -1,6 +1,4 @@
using System;
namespace Sunny.UI.Demo.Controls
namespace Sunny.UI.Demo.Controls
{
public partial class FPieChart : UITitlePage
{
@ -24,8 +22,6 @@ namespace Sunny.UI.Demo.Controls
PieChart.ChartStyleType = UIChartStyleType.Dark;
}
private void uiSymbolButton1_Click(object sender, System.EventArgs e)
{
var option = new UIPieOption();
@ -40,7 +36,7 @@ namespace Sunny.UI.Demo.Controls
option.ToolTip = new UIPieToolTip();
//设置Legend
option.Legend = new UIPieLegend();
option.Legend = new UILegend();
option.Legend.Orient = UIOrient.Vertical;
option.Legend.Top = UITopAlignment.Top;
option.Legend.Left = UILeftAlignment.Left;

View File

@ -120,4 +120,7 @@
<metadata name="toolTip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
<metadata name="$this.TrayHeight" type="System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>25</value>
</metadata>
</root>

View File

@ -713,7 +713,7 @@
this.uiSymbolButton13.Name = "uiSymbolButton13";
this.uiSymbolButton13.Padding = new System.Windows.Forms.Padding(28, 0, 0, 0);
this.uiSymbolButton13.RadiusSides = Sunny.UI.UICornerRadiusSides.None;
this.uiSymbolButton13.RectSides = ((System.Windows.Forms.ToolStripStatusLabelBorderSides)(((System.Windows.Forms.ToolStripStatusLabelBorderSides.Top | System.Windows.Forms.ToolStripStatusLabelBorderSides.Right)
this.uiSymbolButton13.RectSides = ((System.Windows.Forms.ToolStripStatusLabelBorderSides)(((System.Windows.Forms.ToolStripStatusLabelBorderSides.Top | System.Windows.Forms.ToolStripStatusLabelBorderSides.Right)
| System.Windows.Forms.ToolStripStatusLabelBorderSides.Bottom)));
this.uiSymbolButton13.Size = new System.Drawing.Size(46, 35);
this.uiSymbolButton13.Symbol = 61518;
@ -727,7 +727,7 @@
this.uiSymbolButton14.Name = "uiSymbolButton14";
this.uiSymbolButton14.Padding = new System.Windows.Forms.Padding(28, 0, 0, 0);
this.uiSymbolButton14.RadiusSides = Sunny.UI.UICornerRadiusSides.None;
this.uiSymbolButton14.RectSides = ((System.Windows.Forms.ToolStripStatusLabelBorderSides)(((System.Windows.Forms.ToolStripStatusLabelBorderSides.Top | System.Windows.Forms.ToolStripStatusLabelBorderSides.Right)
this.uiSymbolButton14.RectSides = ((System.Windows.Forms.ToolStripStatusLabelBorderSides)(((System.Windows.Forms.ToolStripStatusLabelBorderSides.Top | System.Windows.Forms.ToolStripStatusLabelBorderSides.Right)
| System.Windows.Forms.ToolStripStatusLabelBorderSides.Bottom)));
this.uiSymbolButton14.Size = new System.Drawing.Size(46, 35);
this.uiSymbolButton14.Symbol = 61514;
@ -741,7 +741,7 @@
this.uiSymbolButton15.Name = "uiSymbolButton15";
this.uiSymbolButton15.Padding = new System.Windows.Forms.Padding(28, 0, 0, 0);
this.uiSymbolButton15.RadiusSides = Sunny.UI.UICornerRadiusSides.None;
this.uiSymbolButton15.RectSides = ((System.Windows.Forms.ToolStripStatusLabelBorderSides)(((System.Windows.Forms.ToolStripStatusLabelBorderSides.Top | System.Windows.Forms.ToolStripStatusLabelBorderSides.Right)
this.uiSymbolButton15.RectSides = ((System.Windows.Forms.ToolStripStatusLabelBorderSides)(((System.Windows.Forms.ToolStripStatusLabelBorderSides.Top | System.Windows.Forms.ToolStripStatusLabelBorderSides.Right)
| System.Windows.Forms.ToolStripStatusLabelBorderSides.Bottom)));
this.uiSymbolButton15.Size = new System.Drawing.Size(46, 35);
this.uiSymbolButton15.Symbol = 61513;
@ -755,7 +755,7 @@
this.uiSymbolButton16.Name = "uiSymbolButton16";
this.uiSymbolButton16.Padding = new System.Windows.Forms.Padding(28, 0, 0, 0);
this.uiSymbolButton16.RadiusSides = Sunny.UI.UICornerRadiusSides.None;
this.uiSymbolButton16.RectSides = ((System.Windows.Forms.ToolStripStatusLabelBorderSides)(((System.Windows.Forms.ToolStripStatusLabelBorderSides.Top | System.Windows.Forms.ToolStripStatusLabelBorderSides.Right)
this.uiSymbolButton16.RectSides = ((System.Windows.Forms.ToolStripStatusLabelBorderSides)(((System.Windows.Forms.ToolStripStatusLabelBorderSides.Top | System.Windows.Forms.ToolStripStatusLabelBorderSides.Right)
| System.Windows.Forms.ToolStripStatusLabelBorderSides.Bottom)));
this.uiSymbolButton16.Size = new System.Drawing.Size(46, 35);
this.uiSymbolButton16.Symbol = 61517;
@ -769,7 +769,7 @@
this.uiSymbolButton17.Name = "uiSymbolButton17";
this.uiSymbolButton17.Padding = new System.Windows.Forms.Padding(28, 0, 0, 0);
this.uiSymbolButton17.RadiusSides = Sunny.UI.UICornerRadiusSides.None;
this.uiSymbolButton17.RectSides = ((System.Windows.Forms.ToolStripStatusLabelBorderSides)(((System.Windows.Forms.ToolStripStatusLabelBorderSides.Top | System.Windows.Forms.ToolStripStatusLabelBorderSides.Right)
this.uiSymbolButton17.RectSides = ((System.Windows.Forms.ToolStripStatusLabelBorderSides)(((System.Windows.Forms.ToolStripStatusLabelBorderSides.Top | System.Windows.Forms.ToolStripStatusLabelBorderSides.Right)
| System.Windows.Forms.ToolStripStatusLabelBorderSides.Bottom)));
this.uiSymbolButton17.Size = new System.Drawing.Size(46, 35);
this.uiSymbolButton17.Symbol = 61516;
@ -807,7 +807,7 @@
this.uiSymbolButton20.Name = "uiSymbolButton20";
this.uiSymbolButton20.Padding = new System.Windows.Forms.Padding(28, 0, 0, 0);
this.uiSymbolButton20.RadiusSides = ((Sunny.UI.UICornerRadiusSides)((Sunny.UI.UICornerRadiusSides.RightTop | Sunny.UI.UICornerRadiusSides.RightBottom)));
this.uiSymbolButton20.RectSides = ((System.Windows.Forms.ToolStripStatusLabelBorderSides)(((System.Windows.Forms.ToolStripStatusLabelBorderSides.Top | System.Windows.Forms.ToolStripStatusLabelBorderSides.Right)
this.uiSymbolButton20.RectSides = ((System.Windows.Forms.ToolStripStatusLabelBorderSides)(((System.Windows.Forms.ToolStripStatusLabelBorderSides.Top | System.Windows.Forms.ToolStripStatusLabelBorderSides.Right)
| System.Windows.Forms.ToolStripStatusLabelBorderSides.Bottom)));
this.uiSymbolButton20.Size = new System.Drawing.Size(46, 35);
this.uiSymbolButton20.Symbol = 61522;
@ -821,7 +821,7 @@
this.uiSymbolButton21.Name = "uiSymbolButton21";
this.uiSymbolButton21.Padding = new System.Windows.Forms.Padding(28, 0, 0, 0);
this.uiSymbolButton21.RadiusSides = Sunny.UI.UICornerRadiusSides.None;
this.uiSymbolButton21.RectSides = ((System.Windows.Forms.ToolStripStatusLabelBorderSides)(((System.Windows.Forms.ToolStripStatusLabelBorderSides.Top | System.Windows.Forms.ToolStripStatusLabelBorderSides.Right)
this.uiSymbolButton21.RectSides = ((System.Windows.Forms.ToolStripStatusLabelBorderSides)(((System.Windows.Forms.ToolStripStatusLabelBorderSides.Top | System.Windows.Forms.ToolStripStatusLabelBorderSides.Right)
| System.Windows.Forms.ToolStripStatusLabelBorderSides.Bottom)));
this.uiSymbolButton21.Size = new System.Drawing.Size(46, 35);
this.uiSymbolButton21.Symbol = 61520;
@ -835,7 +835,7 @@
this.uiSymbolButton22.Name = "uiSymbolButton22";
this.uiSymbolButton22.Padding = new System.Windows.Forms.Padding(28, 0, 0, 0);
this.uiSymbolButton22.RadiusSides = Sunny.UI.UICornerRadiusSides.None;
this.uiSymbolButton22.RectSides = ((System.Windows.Forms.ToolStripStatusLabelBorderSides)(((System.Windows.Forms.ToolStripStatusLabelBorderSides.Top | System.Windows.Forms.ToolStripStatusLabelBorderSides.Right)
this.uiSymbolButton22.RectSides = ((System.Windows.Forms.ToolStripStatusLabelBorderSides)(((System.Windows.Forms.ToolStripStatusLabelBorderSides.Top | System.Windows.Forms.ToolStripStatusLabelBorderSides.Right)
| System.Windows.Forms.ToolStripStatusLabelBorderSides.Bottom)));
this.uiSymbolButton22.Size = new System.Drawing.Size(46, 35);
this.uiSymbolButton22.Symbol = 61508;
@ -849,7 +849,7 @@
this.uiSymbolButton23.Name = "uiSymbolButton23";
this.uiSymbolButton23.Padding = new System.Windows.Forms.Padding(28, 0, 0, 0);
this.uiSymbolButton23.RadiusSides = Sunny.UI.UICornerRadiusSides.None;
this.uiSymbolButton23.RectSides = ((System.Windows.Forms.ToolStripStatusLabelBorderSides)(((System.Windows.Forms.ToolStripStatusLabelBorderSides.Top | System.Windows.Forms.ToolStripStatusLabelBorderSides.Right)
this.uiSymbolButton23.RectSides = ((System.Windows.Forms.ToolStripStatusLabelBorderSides)(((System.Windows.Forms.ToolStripStatusLabelBorderSides.Top | System.Windows.Forms.ToolStripStatusLabelBorderSides.Right)
| System.Windows.Forms.ToolStripStatusLabelBorderSides.Bottom)));
this.uiSymbolButton23.Size = new System.Drawing.Size(46, 35);
this.uiSymbolButton23.Symbol = 61544;
@ -863,7 +863,7 @@
this.uiSymbolButton24.Name = "uiSymbolButton24";
this.uiSymbolButton24.Padding = new System.Windows.Forms.Padding(28, 0, 0, 0);
this.uiSymbolButton24.RadiusSides = ((Sunny.UI.UICornerRadiusSides)((Sunny.UI.UICornerRadiusSides.RightTop | Sunny.UI.UICornerRadiusSides.RightBottom)));
this.uiSymbolButton24.RectSides = ((System.Windows.Forms.ToolStripStatusLabelBorderSides)(((System.Windows.Forms.ToolStripStatusLabelBorderSides.Top | System.Windows.Forms.ToolStripStatusLabelBorderSides.Right)
this.uiSymbolButton24.RectSides = ((System.Windows.Forms.ToolStripStatusLabelBorderSides)(((System.Windows.Forms.ToolStripStatusLabelBorderSides.Top | System.Windows.Forms.ToolStripStatusLabelBorderSides.Right)
| System.Windows.Forms.ToolStripStatusLabelBorderSides.Bottom)));
this.uiSymbolButton24.Size = new System.Drawing.Size(46, 35);
this.uiSymbolButton24.Symbol = 61473;
@ -921,7 +921,7 @@
this.uiImageButton1.ImagePress = global::Sunny.UI.Demo.Properties.Resources.dashboard0;
this.uiImageButton1.Location = new System.Drawing.Point(395, 438);
this.uiImageButton1.Name = "uiImageButton1";
this.uiImageButton1.Size = new System.Drawing.Size(92, 35);
this.uiImageButton1.Size = new System.Drawing.Size(94, 35);
this.uiImageButton1.TabIndex = 49;
this.uiImageButton1.TabStop = false;
this.uiImageButton1.Text = "Home";

View File

@ -2,6 +2,7 @@
using Sunny.UI.Demo.Forms;
using System;
using System.Windows.Forms;
using Sunny.UI.Demo.Charts;
namespace Sunny.UI.Demo
{
@ -50,6 +51,7 @@ namespace Sunny.UI.Demo
parent = Aside.CreateNode("Charts", 61950, 24, pageIndex);
//直接关联默认自动生成GUID
Aside.CreateChildNode(parent, 61952, 24, AddPage(new FPieChart()));
Aside.CreateChildNode(parent, 61568, 24, AddPage(new FBarChart()));
Header.SetNodeSymbol(Header.Nodes[3], 61502);
var styles = UIStyles.PopularStyles();

View File

@ -46,6 +46,12 @@
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Charts\FBarChart.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="Charts\FBarChart.Designer.cs">
<DependentUpon>FBarChart.cs</DependentUpon>
</Compile>
<Compile Include="Controls\FAvatar.cs">
<SubType>Form</SubType>
</Compile>
@ -270,6 +276,9 @@
</Compile>
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<EmbeddedResource Include="Charts\FBarChart.resx">
<DependentUpon>FBarChart.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Controls\FAvatar.resx">
<DependentUpon>FAvatar.cs</DependentUpon>
</EmbeddedResource>

View File

@ -1,43 +1,119 @@
using System.Collections.Concurrent;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using Sunny.UI.Charts;
using System.Linq;
namespace Sunny.UI
{
[ToolboxItem(false)]
[ToolboxItem(true)]
public class UIBarChart : UIChart
{
private bool NeedDraw;
protected override void OnSizeChanged(EventArgs e)
{
base.OnSizeChanged(e);
CalcData(BarOption);
}
protected override void CalcData(UIOption option)
{
Bars.Clear();
NeedDraw = false;
UIBarOption o = (UIBarOption)option;
if (o == null || o.Series == null || o.Series.Count == 0) return;
if (o == null || o.Series == null || o.SeriesCount == 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);
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.XAxis.Data.Count==0) return;
if (DrawSize.Width <= 0 || DrawSize.Height <= 0) return;
if (o.XAxis.Data.Count == 0) return;
DrawBarWidth = DrawSize.Width / o.XAxis.Data.Count;
NeedDraw = true;
DrawBarWidth = DrawSize.Width * 1.0f / o.XAxis.Data.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());
}
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,
out int start, out int end, out double interval);
YAxisStart = start;
YAxisEnd = end;
YAxisInterval = interval;
float x1 = 100.0f / ((o.XAxis.Data.Count * 2) + o.XAxis.Data.Count + 1);
x1 = DrawSize.Width * x1 / 100.0f / o.SeriesCount;
float x2 = x1 * 2;
for (int i = 0; i < o.SeriesCount; i++)
{
float barX = DrawOrigin.X;
var series = o.Series[i];
Bars.TryAdd(i, new List<BarInfo>());
for (int j = 0; j < series.Data.Count; j++)
{
if (minZero)
{
float h = (float)(DrawSize.Height * series.Data[j] / (end * interval));
Bars[i].Add(new BarInfo()
{
Rect = new RectangleF(
barX + x1 * (i + 1) + x2 * i,
DrawOrigin.Y - h,
x2, h)
});
}
else if (maxZero)
{
}
else
{
}
barX += DrawBarWidth;
}
}
}
private Point DrawOrigin;
private Size DrawSize;
private int DrawBarWidth;
private readonly ConcurrentDictionary<int, BarInfo> Bars = new ConcurrentDictionary<int, BarInfo>();
private float DrawBarWidth;
private int YAxisStart;
private int YAxisEnd;
private double YAxisInterval;
private readonly ConcurrentDictionary<int, List<BarInfo>> Bars = new ConcurrentDictionary<int, List<BarInfo>>();
[Browsable(false)]
private UIBarOption PieOption
private UIBarOption BarOption
{
get
{
UIOption option = Option ?? EmptyOption;
UIBarOption o = (UIBarOption)option;
return o;
return (UIBarOption)option;
}
}
@ -47,17 +123,34 @@ namespace Sunny.UI
UIBarOption option = new UIBarOption();
option.Title = new UITitle();
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");
var series = new UIBarSeries();
series.Name = "柱状图";
series.Name = "Bar1";
series.AddData(1);
series.AddData(5);
series.AddData(2);
series.AddData(4);
series.AddData(3);
option.Series.Add(series);
series = new UIBarSeries();
series.Name = "Bar2";
series.AddData(2);
series.AddData(1);
series.AddData(5);
series.AddData(3);
series.AddData(4);
option.Series.Add(series);
option.XAxis.Data.Add("Mon");
option.XAxis.Data.Add("Tue");
@ -65,25 +158,102 @@ namespace Sunny.UI
option.XAxis.Data.Add("Thu");
option.XAxis.Data.Add("Fri");
option.Series.Add(series);
emptyOption = option;
}
private void DrawTitle(Graphics g, UITitle title)
protected override void DrawOption(Graphics g)
{
if (BarOption == null) return;
if (!NeedDraw) return;
DrawAxis(g);
DrawTitle(g, BarOption.Title);
DrawSeries(g, BarOption.Series);
DrawLegend(g, BarOption.Legend);
}
private void DrawSeries(Graphics g, UIPieOption o, List<UIPieSeries> series)
private void DrawAxis(Graphics g)
{
g.DrawLine(ChartStyle.ForeColor, DrawOrigin, new Point(DrawOrigin.X + DrawSize.Width, DrawOrigin.Y));
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.XAxis.Data.Count; i++)
{
g.DrawLine(ChartStyle.ForeColor, start, DrawOrigin.Y, start, DrawOrigin.Y + BarOption.XAxis.AxisTick.Length);
start += DrawBarWidth;
}
}
else
{
start = DrawOrigin.X;
for (int i = 0; i <= BarOption.XAxis.Data.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.XAxis.Data)
{
SizeF sf = g.MeasureString(data, SubFont);
g.DrawString(data, SubFont, ChartStyle.ForeColor, start - sf.Width / 2.0f, DrawOrigin.Y + BarOption.XAxis.AxisTick.Length);
start += DrawBarWidth;
}
}
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);
start -= DrawBarHeight;
}
}
if (BarOption.YAxis.AxisLabel.Show)
{
float start = DrawOrigin.Y;
float DrawBarHeight = DrawSize.Height * 1.0f / (YAxisEnd - YAxisStart);
int idx = 0;
for (int i = YAxisStart; i <= YAxisEnd; i++)
{
string label = BarOption.YAxis.AxisLabel.GetLabel(i * YAxisInterval, idx);
SizeF sf = g.MeasureString(label, SubFont);
g.DrawString(label, SubFont, ChartStyle.ForeColor, DrawOrigin.X - BarOption.YAxis.AxisTick.Length - sf.Width, start - sf.Height / 2.0f);
start -= DrawBarHeight;
}
}
}
private void DrawLegend(Graphics g, UIPieLegend legend)
private void DrawSeries(Graphics g, List<UIBarSeries> 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(ChartStyle.SeriesColor[i], info.Rect);
}
}
}
internal class BarInfo
{
public Rectangle Rect { get; set; }
public RectangleF Rect { get; set; }
}
}
}

View File

@ -1,12 +1,10 @@
using System;
using System.Collections.Generic;
namespace Sunny.UI.Charts
namespace Sunny.UI
{
public class UIBarOption : UIOption, IDisposable
{
public UITitle Title;
public UICategoryAxis XAxis { get; set; } = new UICategoryAxis();
public UIValueAxis YAxis { get; set; } = new UIValueAxis();
@ -18,7 +16,6 @@ namespace Sunny.UI.Charts
//public UIPieLegend Legend;
//public UIPieToolTip ToolTip;
public void AddSeries(UIBarSeries series)
{
@ -50,6 +47,15 @@ namespace Sunny.UI.Charts
/// 在类目轴中无效。
/// </summary>
public int SplitNumber { get; set; } = 5;
/// <summary>
/// 是否是脱离 0 值比例。设置成 true 后坐标刻度不会强制包含零刻度。在双数值轴的散点图中比较有用。
/// </summary>
public bool Scale { get; set; }
public UIAxisTick AxisTick = new UIAxisTick();
public UIAxisLabel AxisLabel = new UIAxisLabel();
}
public class UICategoryAxis : UIAxis
@ -65,6 +71,64 @@ namespace Sunny.UI.Charts
{
Data.Clear();
}
}
public class UIAxisLabel
{
/// <summary>
/// 是否显示刻度标签。
/// </summary>
public bool Show { get; set; } = true;
/// <summary>
/// 坐标轴刻度的显示间隔,在类目轴中有效。默认同 axisLabel.interval 一样。
/// 默认会采用标签不重叠的策略间隔显示标签。
/// 可以设置成 0 强制显示所有标签。
/// 如果设置为 1表示『隔一个标签显示一个标签』如果值为 2表示隔两个标签显示一个标签以此类推。
/// </summary>
public int Interval { get; set; } = 0;
public delegate string DoFormatter(double value,int index);
public event DoFormatter Formatter;
public string GetLabel(double value, int index)
{
return Formatter != null ? Formatter?.Invoke(value, index) : value.ToString("F"+ DecimalCount);
}
/// <summary>
/// 小数位个数Formatter不为空时以Formatter为准
/// </summary>
public int DecimalCount { get; set; } = 0;
}
public class UIAxisTick
{
/// <summary>
/// 类目轴中在为 true 的时候有效,可以保证刻度线和标签对齐。
/// </summary>
public bool AlignWithLabel { get; set; }
/// <summary>
/// 是否显示坐标轴刻度。
/// </summary>
public bool Show { get; set; } = true;
/// <summary>
/// 坐标轴刻度的长度。
/// </summary>
public int Length { get; set; } = 5;
/// <summary>
/// 坐标轴刻度的显示间隔,在类目轴中有效。默认同 axisLabel.interval 一样。
/// 默认会采用标签不重叠的策略间隔显示标签。
/// 可以设置成 0 强制显示所有标签。
/// 如果设置为 1表示『隔一个标签显示一个标签』如果值为 2表示隔两个标签显示一个标签以此类推。
/// </summary>
public int Interval { get; set; } = 0;
}
public class UIValueAxis : UIAxis
@ -80,7 +144,7 @@ namespace Sunny.UI.Charts
public string Name { get; set; }
public UISeriesType Type => UISeriesType.Bar;
public List<double> Data = new List<double>();
public void AddData(double value)

View File

@ -19,6 +19,7 @@
* 2020-06-06: V2.2.5
******************************************************************************/
using System;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
@ -54,7 +55,7 @@ namespace Sunny.UI
tip.MouseEnter += Tip_MouseEnter;
}
private void Tip_MouseEnter(object sender, System.EventArgs e)
private void Tip_MouseEnter(object sender, EventArgs e)
{
tip.Visible = false;
}
@ -178,7 +179,7 @@ namespace Sunny.UI
[DefaultValue(8)]
public int TextInterval { get; set; } = 8;
public Font subFont = UIFontColor.SubFont;
private Font subFont = UIFontColor.SubFont;
[DefaultValue(typeof(Font), "微软雅黑, 9pt")]
public Font SubFont
@ -203,5 +204,112 @@ namespace Sunny.UI
Invalidate();
}
}
protected void DrawTitle(Graphics g, UITitle title)
{
if (title == null) return;
SizeF sf = g.MeasureString(title.Text, Font);
float left = 0;
switch (title.Left)
{
case UILeftAlignment.Left: left = TextInterval; break;
case UILeftAlignment.Center: left = (Width - sf.Width) / 2.0f; break;
case UILeftAlignment.Right: left = Width - TextInterval - sf.Width; break;
}
float top = 0;
switch (title.Top)
{
case UITopAlignment.Top: top = TextInterval; break;
case UITopAlignment.Center: top = (Height - sf.Height) / 2.0f; break;
case UITopAlignment.Bottom: top = Height - TextInterval - sf.Height; break;
}
g.DrawString(title.Text, Font, ChartStyle.ForeColor, left, top);
SizeF sfs = g.MeasureString(title.SubText, SubFont);
switch (title.Left)
{
case UILeftAlignment.Left: left = TextInterval; break;
case UILeftAlignment.Center: left = (Width - sfs.Width) / 2.0f; break;
case UILeftAlignment.Right: left = Width - TextInterval - sf.Width; break;
}
switch (title.Top)
{
case UITopAlignment.Top: top = top + sf.Height; break;
case UITopAlignment.Center: top = top + sf.Height; break;
case UITopAlignment.Bottom: top = top - sf.Height; break;
}
g.DrawString(title.SubText, SubFont, ChartStyle.ForeColor, left, top);
}
protected void DrawLegend(Graphics g, UILegend legend)
{
if (legend == null) return;
float totalHeight = 0;
float totalWidth = 0;
float maxWidth = 0;
float oneHeight = 0;
foreach (var data in legend.Data)
{
SizeF sf = g.MeasureString(data, LegendFont);
totalHeight += sf.Height;
totalWidth += sf.Width;
totalWidth += 20;
maxWidth = Math.Max(sf.Width, maxWidth);
oneHeight = sf.Height;
}
float top = 0;
float left = 0;
if (legend.Orient == UIOrient.Horizontal)
{
if (legend.Left == UILeftAlignment.Left) left = TextInterval;
if (legend.Left == UILeftAlignment.Center) left = (Width - totalWidth) / 2.0f;
if (legend.Left == UILeftAlignment.Right) left = Width - totalWidth - TextInterval;
if (legend.Top == UITopAlignment.Top) top = TextInterval;
if (legend.Top == UITopAlignment.Center) top = (Height - oneHeight) / 2.0f;
if (legend.Top == UITopAlignment.Bottom) top = Height - oneHeight - TextInterval;
}
if (legend.Orient == UIOrient.Vertical)
{
if (legend.Left == UILeftAlignment.Left) left = TextInterval;
if (legend.Left == UILeftAlignment.Center) left = (Width - maxWidth) / 2.0f - 10;
if (legend.Left == UILeftAlignment.Right) left = Width - maxWidth - TextInterval - 20;
if (legend.Top == UITopAlignment.Top) top = TextInterval;
if (legend.Top == UITopAlignment.Center) top = (Height - totalHeight) / 2.0f;
if (legend.Top == UITopAlignment.Bottom) top = Height - totalHeight - TextInterval;
}
float startleft = left;
float starttop = top;
for (int i = 0; i < legend.DataCount; i++)
{
var data = legend.Data[i];
SizeF sf = g.MeasureString(data, LegendFont);
if (legend.Orient == UIOrient.Horizontal)
{
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);
startleft += 20;
startleft += sf.Width;
}
if (legend.Orient == UIOrient.Vertical)
{
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);
starttop += oneHeight;
}
}
}
}
}

View File

@ -20,18 +20,39 @@
******************************************************************************/
using System;
using System.Collections.Generic;
namespace Sunny.UI
{
public abstract class UIOption
{
public UITitle Title;
public UILegend Legend;
}
public class UILegend
{
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 UIChartGrid
{
public int Left { get; set; } = 80;
public int Right { get; set; } = 80;
public int Top { get; set; } = 40;
public int Left { get; set; } = 60;
public int Right { get; set; } = 60;
public int Top { get; set; } = 60;
public int Bottom { get; set; } = 40;
}

View File

@ -54,51 +54,18 @@ namespace Sunny.UI
emptyOption = option;
}
protected override void OnSizeChanged(EventArgs e)
{
base.OnSizeChanged(e);
CalcData(PieOption);
}
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;
SizeF sf = g.MeasureString(title.Text, Font);
float left = 0;
switch (title.Left)
{
case UILeftAlignment.Left: left = TextInterval; break;
case UILeftAlignment.Center: left = (Width - sf.Width) / 2.0f; break;
case UILeftAlignment.Right: left = Width - TextInterval - sf.Width; break;
}
float top = 0;
switch (title.Top)
{
case UITopAlignment.Top: top = TextInterval; break;
case UITopAlignment.Center: top = (Height - sf.Height) / 2.0f; break;
case UITopAlignment.Bottom: top = Height - TextInterval - sf.Height; break;
}
g.DrawString(title.Text, Font, ChartStyle.ForeColor, left, top);
SizeF sfs = g.MeasureString(title.SubText, SubFont);
switch (title.Left)
{
case UILeftAlignment.Left: left = TextInterval; break;
case UILeftAlignment.Center: left = (Width - sfs.Width) / 2.0f; break;
case UILeftAlignment.Right: left = Width - TextInterval - sf.Width; break;
}
switch (title.Top)
{
case UITopAlignment.Top: top = top + sf.Height; break;
case UITopAlignment.Center: top = top + sf.Height; break;
case UITopAlignment.Bottom: top = top - sf.Height; break;
}
g.DrawString(title.SubText, subFont, ChartStyle.ForeColor, left, top);
DrawTitle(g, PieOption.Title);
DrawSeries(g, PieOption.Series);
DrawLegend(g, PieOption.Legend);
}
protected override void CalcData(UIOption option)
@ -176,73 +143,7 @@ namespace Sunny.UI
private readonly ConcurrentDictionary<int, ConcurrentDictionary<int, Angle>> Angles = new ConcurrentDictionary<int, ConcurrentDictionary<int, Angle>>();
private void DrawLegend(Graphics g, UIPieLegend legend)
{
if (legend == null) return;
float totalHeight = 0;
float totalWidth = 0;
float maxWidth = 0;
float oneHeight = 0;
foreach (var data in legend.Data)
{
SizeF sf = g.MeasureString(data, LegendFont);
totalHeight += sf.Height;
totalWidth += sf.Width;
totalWidth += 20;
maxWidth = Math.Max(sf.Width, maxWidth);
oneHeight = sf.Height;
}
float top = 0;
float left = 0;
if (legend.Orient == UIOrient.Horizontal)
{
if (legend.Left == UILeftAlignment.Left) left = TextInterval;
if (legend.Left == UILeftAlignment.Center) left = (Width - totalWidth) / 2.0f;
if (legend.Left == UILeftAlignment.Right) left = Width - totalWidth - TextInterval;
if (legend.Top == UITopAlignment.Top) top = TextInterval;
if (legend.Top == UITopAlignment.Center) top = (Height - oneHeight) / 2.0f;
if (legend.Top == UITopAlignment.Bottom) top = Height - oneHeight - TextInterval;
}
if (legend.Orient == UIOrient.Vertical)
{
if (legend.Left == UILeftAlignment.Left) left = TextInterval;
if (legend.Left == UILeftAlignment.Center) left = (Width - maxWidth) / 2.0f - 10;
if (legend.Left == UILeftAlignment.Right) left = Width - maxWidth - TextInterval - 20;
if (legend.Top == UITopAlignment.Top) top = TextInterval;
if (legend.Top == UITopAlignment.Center) top = (Height - totalHeight) / 2.0f;
if (legend.Top == UITopAlignment.Bottom) top = Height - totalHeight - TextInterval;
}
float startleft = left;
float starttop = top;
for (int i = 0; i < legend.DataCount; i++)
{
var data = legend.Data[i];
SizeF sf = g.MeasureString(data, LegendFont);
if (legend.Orient == UIOrient.Horizontal)
{
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);
startleft += 20;
startleft += sf.Width;
}
if (legend.Orient == UIOrient.Vertical)
{
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);
starttop += oneHeight;
}
}
}
[Browsable(false)]
private UIPieOption PieOption

View File

@ -5,12 +5,8 @@ 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)
@ -34,12 +30,8 @@ namespace Sunny.UI
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)
@ -68,24 +60,6 @@ namespace Sunny.UI
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; }

View File

@ -47,6 +47,25 @@ namespace Sunny.UI
Helper = new UITabControlHelper(this);
}
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
if (ForbidCtrlTab)
{
switch (keyData)
{
case (Keys.Tab | Keys.Control):
//组合键在调试时不容易捕获可以先按住Ctrl键此时在断点处已经捕获然后按下Tab键都释放后再进入断点处单步向下执行
//此时会分两次进入断点第一次好像是处理Ctrl键第二次处理组合键
return true;
}
}
return base.ProcessCmdKey(ref msg, keyData);
}
[DefaultValue(true)]
public bool ForbidCtrlTab { get; set; } = true;
public void SelectPage(int pageIndex)
{
Helper.SelectPage(pageIndex);

View File

@ -35,7 +35,7 @@ namespace Sunny.UI
public readonly Guid Guid = Guid.NewGuid();
public UIStatusForm StatusForm;
private UIStatusForm statusForm;
public UIForm()
{
@ -75,15 +75,12 @@ namespace Sunny.UI
/// <param name="value">当前进度值</param>
public void ShowStatus(string title, string desc, int max = 100, int value = 0)
{
if (StatusForm == null)
{
StatusForm = new UIStatusForm();
}
StatusForm.Style = Style;
StatusForm.Show(title, desc, max, value);
}
public UIStatusForm StatusForm => statusForm ?? (statusForm = new UIStatusForm());
/// <summary>
/// 隐藏进度窗口
/// </summary>
@ -100,6 +97,14 @@ namespace Sunny.UI
StatusForm.StepIt();
}
[DefaultValue(null)]
[Browsable(false)]
public string StatusDescription
{
get => StatusForm?.Description;
set => StatusForm.Description = value;
}
protected override void OnBackColorChanged(EventArgs e)
{
base.OnBackColorChanged(e);

View File

@ -85,5 +85,12 @@ namespace Sunny.UI
processBar.Value = value;
Show();
}
public string Description
{
get => labelDescription.Text;
set => labelDescription.Text = value;
}
}
}

View File

@ -39,7 +39,9 @@ namespace Sunny.UI
protected UIStyle _style = UIStyle.Blue;
public UIStatusForm StatusForm;
private UIStatusForm statusForm;
public UIStatusForm StatusForm => statusForm ?? (statusForm = new UIStatusForm());
public UIPage()
{
@ -172,8 +174,6 @@ namespace Sunny.UI
public void ShowStatus(string title, string desc, int max = 100, int value = 0)
{
if (StatusForm == null) StatusForm = new UIStatusForm();
StatusForm.Style = Style;
StatusForm.Show(title, desc, max, value);
}
@ -188,6 +188,14 @@ namespace Sunny.UI
StatusForm.StepIt();
}
[DefaultValue(null)]
[Browsable(false)]
public string StatusDescription
{
get => StatusForm?.Description;
set => StatusForm.Description = value;
}
protected override void OnControlAdded(ControlEventArgs e)
{
base.OnControlAdded(e);

View File

@ -199,6 +199,26 @@ namespace Sunny.UI
}
}
public static void DrawLine(this Graphics g, Color color, float x1, float y1, float x2, float y2, bool smooth = false)
{
using (Pen pen = new Pen(color))
{
g.Smooth(smooth);
g.DrawLine(pen, x1, y1, x2, y2);
g.Smooth(false);
}
}
public static void DrawLine(this Graphics g, Color color, PointF pt1, PointF pt2, bool smooth = false)
{
using (Pen pen = new Pen(color))
{
g.Smooth(smooth);
g.DrawLine(pen, pt1, pt2);
g.Smooth(false);
}
}
public static void DrawArc(this Graphics g, Color color, int x, int y, int width, int height, int startAngle, int sweepAngle, bool smooth = true)
{
using (Pen pen = new Pen(color))

View File

@ -36,6 +36,14 @@ namespace Sunny.UI
/// </summary>
public static class SystemEx
{
public static void ConsoleWriteLine(this object obj, string preText = "")
{
if (preText != "")
Console.WriteLine(preText + ": " + obj);
else
Console.WriteLine(obj.ToString());
}
/// <summary>
/// Delays the specified ms.
/// </summary>
@ -67,6 +75,7 @@ namespace Sunny.UI
using (Process process = Process.Start(startInfo))
{
if (process == null) return string.Empty;
using (StreamReader reader = process.StandardOutput)
{
str = reader.ReadToEnd();
@ -81,41 +90,41 @@ namespace Sunny.UI
/// <summary>
/// Byte To KB
/// </summary>
/// <param name="bytevalue">Byte value</param>
/// <param name="byteValue">Byte value</param>
/// <returns>KB</returns>
public static long ToKB(this long bytevalue)
public static long ToKB(this long byteValue)
{
return (long)(bytevalue / 1024.0);
return (long)(byteValue / 1024.0);
}
/// <summary>
/// Byte To MB
/// </summary>
/// <param name="bytevalue">Byte value</param>
/// <param name="byteValue">Byte value</param>
/// <returns>MB</returns>
public static long ToMB(this long bytevalue)
public static long ToMB(this long byteValue)
{
return (long)(bytevalue / 1024.0 / 1024.0);
return (long)(byteValue / 1024.0 / 1024.0);
}
/// <summary>
/// Byte To GB
/// </summary>
/// <param name="bytevalue">Byte value</param>
/// <param name="byteValue">Byte value</param>
/// <returns>GB</returns>
public static long ToGB(this long bytevalue)
public static long ToGB(this long byteValue)
{
return (long)(bytevalue / 1024.0 / 1024.0 / 1024.0);
return (long)(byteValue / 1024.0 / 1024.0 / 1024.0);
}
/// <summary>
/// Byte To TB
/// </summary>
/// <param name="bytevalue">Byte value</param>
/// <param name="byteValue">Byte value</param>
/// <returns>TB</returns>
public static long ToTB(this long bytevalue)
public static long ToTB(this long byteValue)
{
return (long)(bytevalue / 1024.0 / 1024.0 / 1024.0 / 1024.0);
return (long)(byteValue / 1024.0 / 1024.0 / 1024.0 / 1024.0);
}
/// <summary>
@ -130,22 +139,22 @@ namespace Sunny.UI
/// <summary>
/// 根据文件名或者磁盘名获取磁盘信息
/// </summary>
/// <param name="diskname">文件名或者磁盘名(取第一个字符)</param>
/// <param name="diskName">文件名或者磁盘名(取第一个字符)</param>
/// <returns>磁盘信息</returns>
public static DriveInfo Disk(string diskname)
public static DriveInfo Disk(string diskName)
{
if (diskname.IsNullOrEmpty())
if (diskName.IsNullOrEmpty())
{
return null;
}
diskname = (diskname.Left(1) + ":\\").ToUpper();
DriveInfo[] diInfos = DriveInfo.GetDrives();
for (int i = 0; i < diInfos.Count(); i++)
diskName = (diskName.Left(1) + ":\\").ToUpper();
DriveInfo[] drives = DriveInfo.GetDrives();
foreach (var drive in drives)
{
if (diInfos[i].Name.ToUpper() == diskname)
if (drive.Name.ToUpper() == diskName)
{
return diInfos[i];
return drive;
}
}
@ -155,11 +164,11 @@ namespace Sunny.UI
/// <summary>
/// 根据文件名或者磁盘名判断磁盘是否存在
/// </summary>
/// <param name="diskname">文件名或者磁盘名(取第一个字符)</param>
/// <param name="diskName">文件名或者磁盘名(取第一个字符)</param>
/// <returns>磁盘是否存在</returns>
public static bool DiskExist(this string diskname)
public static bool DiskExist(this string diskName)
{
return Disk(diskname) != null;
return Disk(diskName) != null;
}
/// <summary>
@ -216,19 +225,21 @@ namespace Sunny.UI
/// <summary>
/// 将程序调至前台
/// </summary>
/// <param name="showstyle">显示风格</param>
/// <param name="showStyle">显示风格</param>
[EnvironmentPermissionAttribute(SecurityAction.LinkDemand, Unrestricted = true)]
public static void BringToFront(int showstyle = SW_SHOW)
public static void BringToFront(int showStyle = SW_SHOW)
{
Process instance = RunningInstance();
HandleRunningInstance(instance, showstyle);
HandleRunningInstance(instance, showStyle);
}
[EnvironmentPermissionAttribute(SecurityAction.LinkDemand, Unrestricted = true)]
private static Process RunningInstance()
public static Process RunningInstance()
{
Process currentProcess = Process.GetCurrentProcess();
Process[] processes = Process.GetProcessesByName(currentProcess.ProcessName);
if (currentProcess.MainModule == null) return null;
//遍历与当前进程名称相同的进程列表
return processes.Where(process => process.Id != currentProcess.Id).FirstOrDefault(
process => string.Equals(
@ -258,9 +269,9 @@ namespace Sunny.UI
}
[EnvironmentPermissionAttribute(SecurityAction.LinkDemand, Unrestricted = true)]
private static void HandleRunningInstance(Process instance, int showstyle)
private static void HandleRunningInstance(Process instance, int showStyle)
{
ShowWindowAsync(instance.MainWindowHandle, showstyle); //调用api函数正常显示窗口
ShowWindowAsync(instance.MainWindowHandle, showStyle); //调用api函数正常显示窗口
SetForegroundWindow(instance.MainWindowHandle); //将窗口放置最前端。
}
@ -278,10 +289,10 @@ namespace Sunny.UI
/// </summary>
/// <param name="frm">窗体</param>
/// <param name="monitor">显示器序号</param>
/// <param name="showmax">最大化</param>
/// <param name="frmleft">左边距离</param>
/// <param name="frmtop">顶部距离</param>
public static void ShowOnMonitor(this Form frm, int monitor, bool showmax = true, int frmleft = 0, int frmtop = 0)
/// <param name="showMax">最大化</param>
/// <param name="left">左边距离</param>
/// <param name="top">顶部距离</param>
public static void ShowOnMonitor(this Form frm, int monitor, bool showMax = true, int left = 0, int top = 0)
{
Screen[] sc = Screen.AllScreens;
if (monitor >= sc.Length)
@ -290,8 +301,8 @@ namespace Sunny.UI
}
frm.StartPosition = FormStartPosition.Manual;
frm.Location = new Point(sc[monitor].Bounds.Left + frmleft, sc[monitor].Bounds.Top + frmtop);
frm.WindowState = showmax ? FormWindowState.Maximized : FormWindowState.Normal;
frm.Location = new Point(sc[monitor].Bounds.Left + left, sc[monitor].Bounds.Top + top);
frm.WindowState = showMax ? FormWindowState.Maximized : FormWindowState.Normal;
}
[DllImport("User32.dll")]

View File

@ -1,5 +1,8 @@
+ 增加; - 删除; * 修改
2020.06.15
+UIBarChart新增UIBarChart控件
2020.06.14
* 重构图表控件准备开发UIBarChart
* UITextBox增加EnterAsTab