+ UIBarChartEx:增加了一个新的柱状图类型,序列个数可以不相等

This commit is contained in:
Sunny 2020-09-26 21:34:47 +08:00
parent 88fc5979cb
commit c3ff5933ba
16 changed files with 678 additions and 394 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -1,120 +0,0 @@
<?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

@ -0,0 +1,158 @@
namespace Sunny.UI.Demo
{
partial class FBarChartEx
{
/// <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.uiSymbolButton1 = new Sunny.UI.UISymbolButton();
this.uiImageButton3 = new Sunny.UI.UIImageButton();
this.uiImageButton2 = new Sunny.UI.UIImageButton();
this.uiImageButton1 = new Sunny.UI.UIImageButton();
this.uiLine1 = new Sunny.UI.UILine();
this.BarChart = new Sunny.UI.UIBarChartEx();
this.PagePanel.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.uiImageButton3)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.uiImageButton2)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.uiImageButton1)).BeginInit();
this.SuspendLayout();
//
// PagePanel
//
this.PagePanel.Controls.Add(this.uiSymbolButton1);
this.PagePanel.Controls.Add(this.uiImageButton3);
this.PagePanel.Controls.Add(this.uiImageButton2);
this.PagePanel.Controls.Add(this.uiImageButton1);
this.PagePanel.Controls.Add(this.uiLine1);
this.PagePanel.Controls.Add(this.BarChart);
this.PagePanel.Size = new System.Drawing.Size(886, 508);
//
// uiSymbolButton1
//
this.uiSymbolButton1.Cursor = System.Windows.Forms.Cursors.Hand;
this.uiSymbolButton1.Font = new System.Drawing.Font("微软雅黑", 12F);
this.uiSymbolButton1.Location = new System.Drawing.Point(348, 466);
this.uiSymbolButton1.MinimumSize = new System.Drawing.Size(1, 1);
this.uiSymbolButton1.Name = "uiSymbolButton1";
this.uiSymbolButton1.Padding = new System.Windows.Forms.Padding(28, 0, 0, 0);
this.uiSymbolButton1.Size = new System.Drawing.Size(100, 27);
this.uiSymbolButton1.Symbol = 61952;
this.uiSymbolButton1.TabIndex = 34;
this.uiSymbolButton1.Text = "数据";
this.uiSymbolButton1.Click += new System.EventHandler(this.uiSymbolButton1_Click);
//
// uiImageButton3
//
this.uiImageButton3.Cursor = System.Windows.Forms.Cursors.Hand;
this.uiImageButton3.Font = new System.Drawing.Font("微软雅黑", 12F);
this.uiImageButton3.Image = global::Sunny.UI.Demo.Properties.Resources.ChartDarkStyle;
this.uiImageButton3.Location = new System.Drawing.Point(242, 466);
this.uiImageButton3.Name = "uiImageButton3";
this.uiImageButton3.Size = new System.Drawing.Size(100, 27);
this.uiImageButton3.TabIndex = 33;
this.uiImageButton3.TabStop = false;
this.uiImageButton3.Text = " Dark";
this.uiImageButton3.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
this.uiImageButton3.Click += new System.EventHandler(this.uiImageButton3_Click);
//
// uiImageButton2
//
this.uiImageButton2.Cursor = System.Windows.Forms.Cursors.Hand;
this.uiImageButton2.Font = new System.Drawing.Font("微软雅黑", 12F);
this.uiImageButton2.Image = global::Sunny.UI.Demo.Properties.Resources.ChartPlainStyle;
this.uiImageButton2.Location = new System.Drawing.Point(136, 466);
this.uiImageButton2.Name = "uiImageButton2";
this.uiImageButton2.Size = new System.Drawing.Size(100, 27);
this.uiImageButton2.TabIndex = 32;
this.uiImageButton2.TabStop = false;
this.uiImageButton2.Text = " Plain";
this.uiImageButton2.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
this.uiImageButton2.Click += new System.EventHandler(this.uiImageButton2_Click);
//
// uiImageButton1
//
this.uiImageButton1.Cursor = System.Windows.Forms.Cursors.Hand;
this.uiImageButton1.Font = new System.Drawing.Font("微软雅黑", 12F);
this.uiImageButton1.Image = global::Sunny.UI.Demo.Properties.Resources.ChartDefaultStyle;
this.uiImageButton1.Location = new System.Drawing.Point(30, 466);
this.uiImageButton1.Name = "uiImageButton1";
this.uiImageButton1.Size = new System.Drawing.Size(100, 27);
this.uiImageButton1.TabIndex = 31;
this.uiImageButton1.TabStop = false;
this.uiImageButton1.Text = " Default";
this.uiImageButton1.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
this.uiImageButton1.Click += new System.EventHandler(this.uiImageButton1_Click);
//
// uiLine1
//
this.uiLine1.Font = new System.Drawing.Font("微软雅黑", 12F);
this.uiLine1.Location = new System.Drawing.Point(30, 20);
this.uiLine1.MinimumSize = new System.Drawing.Size(16, 16);
this.uiLine1.Name = "uiLine1";
this.uiLine1.Size = new System.Drawing.Size(670, 20);
this.uiLine1.TabIndex = 30;
this.uiLine1.Text = "UIBarChart";
this.uiLine1.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
//
// BarChart
//
this.BarChart.FillColor = System.Drawing.Color.FromArgb(((int)(((byte)(244)))), ((int)(((byte)(244)))), ((int)(((byte)(244)))));
this.BarChart.Font = new System.Drawing.Font("微软雅黑", 12F);
this.BarChart.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(54)))), ((int)(((byte)(54)))), ((int)(((byte)(54)))));
this.BarChart.Location = new System.Drawing.Point(30, 48);
this.BarChart.MinimumSize = new System.Drawing.Size(1, 1);
this.BarChart.Name = "BarChart";
this.BarChart.Option = null;
this.BarChart.Size = new System.Drawing.Size(670, 400);
this.BarChart.TabIndex = 35;
this.BarChart.Text = "uiBarChartEx1";
//
// FBarChartEx
//
this.AutoScaleDimensions = new System.Drawing.SizeF(10F, 21F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(886, 543);
this.Name = "FBarChartEx";
this.Symbol = 61568;
this.Text = "BarChartEx";
this.PagePanel.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)(this.uiImageButton3)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.uiImageButton2)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.uiImageButton1)).EndInit();
this.ResumeLayout(false);
}
#endregion
private UISymbolButton uiSymbolButton1;
private UIImageButton uiImageButton3;
private UIImageButton uiImageButton2;
private UIImageButton uiImageButton1;
private UILine uiLine1;
private UIBarChartEx BarChart;
}
}

View File

@ -0,0 +1,81 @@
using System.Drawing;
namespace Sunny.UI.Demo
{
public partial class FBarChartEx : UITitlePage
{
public FBarChartEx()
{
InitializeComponent();
}
private void uiImageButton1_Click(object sender, System.EventArgs e)
{
BarChart.ChartStyleType = UIChartStyleType.Default;
}
private void uiImageButton2_Click(object sender, System.EventArgs e)
{
BarChart.ChartStyleType = UIChartStyleType.Plain;
}
private void uiImageButton3_Click(object sender, System.EventArgs e)
{
BarChart.ChartStyleType = UIChartStyleType.Dark;
}
private void uiSymbolButton1_Click(object sender, System.EventArgs e)
{
UIBarOption option = new UIBarOption();
option.Title = new UITitle();
option.Title.Text = "SunnyUI";
option.Title.SubText = "BarChartEx";
//设置Legend
option.Legend = new UILegend();
option.Legend.Orient = UIOrient.Horizontal;
option.Legend.Top = UITopAlignment.Top;
option.Legend.Left = UILeftAlignment.Left;
option.Legend.AddData("Bar1");
option.Legend.AddData("Bar2");
option.Legend.AddData("Bar3");
var series = new UIBarSeries();
series.Name = "Bar1";
series.AddData("通道1", 11);
series.AddData("通道2", 15);
option.Series.Add(series);
series = new UIBarSeries();
series.Name = "Bar2";
series.AddData("通道1", -22);
series.AddData("通道2", -28);
series.AddData("通道3", -25);
option.Series.Add(series);
series = new UIBarSeries();
series.Name = "Bar3";
series.AddData("通道1", 7);
option.Series.Add(series);
option.XAxis.Data.Add("Mon");
option.XAxis.Data.Add("Tue");
option.XAxis.Data.Add("Wed");
option.XAxis.Data.Add("Thu");
option.XAxis.Data.Add("Fri");
option.ToolTip = new UIBarToolTip();
option.YAxis.Scale = true;
option.XAxis.Name = "日期";
option.YAxis.Name = "数值";
option.FixedSeriesCount = 3;
option.YAxisScaleLines.Add(new UIScaleLine() { Color = Color.Red, Name = "上限", Value = 12 });
option.YAxisScaleLines.Add(new UIScaleLine() { Color = Color.Gold, Name = "下限", Value = -20 });
BarChart.SetOption(option);
}
}
}

View File

@ -1,120 +0,0 @@
<?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

@ -35,7 +35,6 @@
this.uiImageButton2 = new Sunny.UI.UIImageButton();
this.uiImageButton3 = new Sunny.UI.UIImageButton();
this.uiSymbolButton1 = new Sunny.UI.UISymbolButton();
this.toolTip1 = new System.Windows.Forms.ToolTip(this.components);
this.PagePanel.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.uiImageButton1)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.uiImageButton2)).BeginInit();
@ -156,6 +155,5 @@
private UIImageButton uiImageButton3;
private UIImageButton uiImageButton2;
private UISymbolButton uiSymbolButton1;
private System.Windows.Forms.ToolTip toolTip1;
}
}

View File

@ -1,126 +0,0 @@
<?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>
<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

@ -53,8 +53,9 @@ namespace Sunny.UI.Demo
parent = Aside.CreateNode("Charts", 61950, 24, pageIndex);
//直接关联默认自动生成GUID
Aside.CreateChildNode(parent, AddPage(new FPieChart()));
Aside.CreateChildNode(parent, AddPage(new FBarChart()));
Aside.CreateChildNode(parent, AddPage(new FDoughnutChart()));
Aside.CreateChildNode(parent, AddPage(new FBarChart()));
Aside.CreateChildNode(parent, AddPage(new FBarChartEx()));
Header.SetNodeSymbol(Header.Nodes[3], 61502);
var styles = UIStyles.PopularStyles();

View File

@ -53,6 +53,12 @@
<Compile Include="Charts\FBarChart.Designer.cs">
<DependentUpon>FBarChart.cs</DependentUpon>
</Compile>
<Compile Include="Charts\FBarChartEx.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="Charts\FBarChartEx.Designer.cs">
<DependentUpon>FBarChartEx.cs</DependentUpon>
</Compile>
<Compile Include="Charts\FDoughnutChart.cs">
<SubType>Form</SubType>
</Compile>
@ -295,12 +301,6 @@
</Compile>
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<EmbeddedResource Include="Charts\FBarChart.resx">
<DependentUpon>FBarChart.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Charts\FDoughnutChart.resx">
<DependentUpon>FDoughnutChart.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Controls\FAvatar.resx">
<DependentUpon>FAvatar.cs</DependentUpon>
</EmbeddedResource>
@ -316,9 +316,6 @@
<EmbeddedResource Include="Controls\FMeter.resx">
<DependentUpon>FMeter.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Charts\FPieChart.resx">
<DependentUpon>FPieChart.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Controls\FScrollBar.resx">
<DependentUpon>FScrollBar.cs</DependentUpon>
</EmbeddedResource>

View File

@ -34,7 +34,7 @@ namespace Sunny.UI
[ToolboxItem(true)]
public class UIBarChart : UIChart
{
private bool NeedDraw;
protected bool NeedDraw;
protected override void OnSizeChanged(EventArgs e)
{
@ -145,8 +145,8 @@ namespace Sunny.UI
if (k > 0) highV += (float)YAxisInterval;
}
lowH.ConsoleWriteLine();
highH.ConsoleWriteLine();
// lowH.ConsoleWriteLine();
// highH.ConsoleWriteLine();
if (series.Data[j] >= 0)
{
@ -188,17 +188,17 @@ namespace Sunny.UI
}
}
private int selectIndex = -1;
private Point DrawOrigin;
private Size DrawSize;
private float DrawBarWidth;
private int YAxisStart;
private int YAxisEnd;
private double YAxisInterval;
private readonly ConcurrentDictionary<int, List<BarInfo>> Bars = new ConcurrentDictionary<int, List<BarInfo>>();
protected int selectIndex = -1;
protected Point DrawOrigin;
protected Size DrawSize;
protected float DrawBarWidth;
protected int YAxisStart;
protected int YAxisEnd;
protected double YAxisInterval;
protected readonly ConcurrentDictionary<int, List<BarInfo>> Bars = new ConcurrentDictionary<int, List<BarInfo>>();
[DefaultValue(-1), Browsable(false)]
private int SelectIndex
protected int SelectIndex
{
get => selectIndex;
set
@ -258,7 +258,7 @@ namespace Sunny.UI
}
[Browsable(false)]
private UIBarOption BarOption
protected UIBarOption BarOption
{
get
{
@ -344,7 +344,7 @@ namespace Sunny.UI
}
}
private void DrawAxis(Graphics g)
protected virtual void DrawAxis(Graphics g)
{
if (YAxisStart >= 0) g.DrawLine(ChartStyle.ForeColor, DrawOrigin, new Point(DrawOrigin.X + DrawSize.Width, DrawOrigin.Y));
if (YAxisEnd <= 0) g.DrawLine(ChartStyle.ForeColor, new Point(DrawOrigin.X, BarOption.Grid.Top), new Point(DrawOrigin.X + DrawSize.Width, BarOption.Grid.Top));
@ -482,7 +482,7 @@ namespace Sunny.UI
}
}
private void DrawSeries(Graphics g, List<UIBarSeries> series)
protected virtual void DrawSeries(Graphics g, List<UIBarSeries> series)
{
if (series == null || series.Count == 0) return;
@ -501,7 +501,7 @@ namespace Sunny.UI
}
}
internal class BarInfo
protected class BarInfo
{
public RectangleF Rect { get; set; }

View File

@ -0,0 +1,395 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Windows.Forms;
namespace Sunny.UI
{
public class UIBarChartEx : UIBarChart
{
protected override void CalcData(UIOption option)
{
Bars.Clear();
NeedDraw = false;
UIBarOption o = (UIBarOption)option;
if (o == null || o.Series == null || o.SeriesCount == 0) return;
DrawOrigin = new Point(BarOption.Grid.Left, Height - BarOption.Grid.Bottom);
DrawSize = new Size(Width - BarOption.Grid.Left - BarOption.Grid.Right,
Height - BarOption.Grid.Top - BarOption.Grid.Bottom);
if (DrawSize.Width <= 0 || DrawSize.Height <= 0) return;
if (o.Series.Count == 0) return;
NeedDraw = true;
DrawBarWidth = DrawSize.Width * 1.0f / o.Series.Count;
double min = double.MaxValue;
double max = double.MinValue;
foreach (var series in o.Series)
{
min = Math.Min(min, series.Data.Min());
max = Math.Max(max, series.Data.Max());
}
if (min > 0 && max > 0 && !o.YAxis.Scale)
{
min = 0;
}
if (min < 0 && max < 0 && !o.YAxis.Scale)
{
max = 0;
}
if (!o.YAxis.MaxAuto) max = o.YAxis.Max;
if (!o.YAxis.MinAuto) min = o.YAxis.Min;
if ((max - min).IsZero())
{
max = 100;
min = 0;
}
UIChartHelper.CalcDegreeScale(min, max, o.YAxis.SplitNumber,
out int start, out int end, out double interval);
YAxisStart = start;
YAxisEnd = end;
YAxisInterval = interval;
float barX = DrawOrigin.X;
for (int i = 0; i < o.SeriesCount; i++)
{
var series = o.Series[i];
float x1;
if (BarOption.FixedSeriesCount > 0)
x1 = DrawBarWidth / (BarOption.FixedSeriesCount * 2 + BarOption.FixedSeriesCount + 1);
else
x1 = DrawBarWidth / (series.Data.Count * 2 + series.Data.Count + 1);
float x2 = x1 * 2;
Bars.TryAdd(i, new List<BarInfo>());
for (int j = 0; j < series.Data.Count; j++)
{
Color color = ChartStyle.GetColor(i);
if (series.Colors.Count > 0 && j >= 0 && j < series.Colors.Count)
color = series.Colors[j];
float xx;
if (BarOption.FixedSeriesCount > 0)
xx = barX + DrawBarWidth / (series.Data.Count * 2 + series.Data.Count + 1) * ((j + 1) * 3 - 1);
else
xx = barX + x1 * ((j + 1) * 3 - 1);
float ww = Math.Min(x2, series.MaxWidth);
xx = xx - ww / 2.0f;
if (YAxisStart >= 0)
{
float h = Math.Abs((float)(DrawSize.Height * (series.Data[j] - start * interval) / ((end - start) * interval)));
Bars[i].Add(new BarInfo()
{
Rect = new RectangleF(xx, DrawOrigin.Y - h, ww, h),
Color = color
});
}
else if (YAxisEnd <= 0)
{
float h = Math.Abs((float)(DrawSize.Height * (end * interval - series.Data[j]) / ((end - start) * interval)));
Bars[i].Add(new BarInfo()
{
Rect = new RectangleF(xx, BarOption.Grid.Top + 1, ww, h - 1),
Color = color
});
}
else
{
float lowH = 0;
float highH = 0;
float DrawBarHeight = DrawSize.Height * 1.0f / (YAxisEnd - YAxisStart);
float lowV = 0;
float highV = 0;
for (int k = YAxisStart; k <= YAxisEnd; k++)
{
if (k < 0) lowH += DrawBarHeight;
if (k > 0) highH += DrawBarHeight;
if (k < 0) lowV += (float)YAxisInterval;
if (k > 0) highV += (float)YAxisInterval;
}
// lowH.ConsoleWriteLine();
// highH.ConsoleWriteLine();
if (series.Data[j] >= 0)
{
float h = Math.Abs((float)(highH * series.Data[j] / highV));
Bars[i].Add(new BarInfo()
{
Rect = new RectangleF(xx, DrawOrigin.Y - lowH - h, ww, h),
Color = color
});
}
else
{
float h = Math.Abs((float)(lowH * series.Data[j] / lowV));
Bars[i].Add(new BarInfo()
{
Rect = new RectangleF(xx, DrawOrigin.Y - lowH + 1, ww, h - 1),
Color = color
});
}
}
}
barX += DrawBarWidth;
}
if (BarOption.ToolTip != null)
{
for (int i = 0; i < BarOption.Series.Count; i++)
{
var series = BarOption.Series[i];
string str = BarOption.Series[i].Name;
for (int j = 0; j < series.Data.Count; j++)
{
str += '\n';
if (series.BarName.Count >= 0 && j < series.BarName.Count)
str += series.BarName[j] + " : ";
str += series.Data[j].ToString(BarOption.ToolTip.ValueFormat);
}
Bars[i][0].Tips = str;
}
}
}
protected override void DrawSeries(Graphics g, List<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(info.Color, info.Rect);
}
}
for (int i = 0; i < BarOption.Series.Count; i++)
{
Bars[i][0].Size = g.MeasureString(Bars[i][0].Tips, SubFont);
}
}
protected override void DrawAxis(Graphics g)
{
if (YAxisStart >= 0) g.DrawLine(ChartStyle.ForeColor, DrawOrigin, new Point(DrawOrigin.X + DrawSize.Width, DrawOrigin.Y));
if (YAxisEnd <= 0) g.DrawLine(ChartStyle.ForeColor, new Point(DrawOrigin.X, BarOption.Grid.Top), new Point(DrawOrigin.X + DrawSize.Width, BarOption.Grid.Top));
g.DrawLine(ChartStyle.ForeColor, DrawOrigin, new Point(DrawOrigin.X, DrawOrigin.Y - DrawSize.Height));
if (BarOption.XAxis.AxisTick.Show)
{
float start;
if (BarOption.XAxis.AxisTick.AlignWithLabel)
{
start = DrawOrigin.X + DrawBarWidth / 2.0f;
for (int i = 0; i < BarOption.Series.Count; i++)
{
g.DrawLine(ChartStyle.ForeColor, start, DrawOrigin.Y, start, DrawOrigin.Y + BarOption.XAxis.AxisTick.Length);
start += DrawBarWidth;
}
}
else
{
bool haveZero = false;
for (int i = YAxisStart; i <= YAxisEnd; i++)
{
if (i == 0)
{
haveZero = true;
break;
}
}
if (!haveZero)
{
start = DrawOrigin.X;
for (int i = 0; i <= BarOption.Series.Count; i++)
{
g.DrawLine(ChartStyle.ForeColor, start, DrawOrigin.Y, start, DrawOrigin.Y + BarOption.XAxis.AxisTick.Length);
start += DrawBarWidth;
}
}
}
}
if (BarOption.XAxis.AxisLabel.Show)
{
float start = DrawOrigin.X + DrawBarWidth / 2.0f;
foreach (var data in BarOption.Series)
{
SizeF sf = g.MeasureString(data.Name, SubFont);
g.DrawString(data.Name, SubFont, ChartStyle.ForeColor, start - sf.Width / 2.0f, DrawOrigin.Y + BarOption.XAxis.AxisTick.Length);
start += DrawBarWidth;
}
SizeF sfName = g.MeasureString(BarOption.XAxis.Name, SubFont);
g.DrawString(BarOption.XAxis.Name, SubFont, ChartStyle.ForeColor, DrawOrigin.X + (DrawSize.Width - sfName.Width) / 2.0f, DrawOrigin.Y + BarOption.XAxis.AxisTick.Length + sfName.Height);
}
if (BarOption.YAxis.AxisTick.Show)
{
float start = DrawOrigin.Y;
float DrawBarHeight = DrawSize.Height * 1.0f / (YAxisEnd - YAxisStart);
for (int i = YAxisStart; i <= YAxisEnd; i++)
{
g.DrawLine(ChartStyle.ForeColor, DrawOrigin.X, start, DrawOrigin.X - BarOption.YAxis.AxisTick.Length, start);
if (i != 0)
{
using (Pen pn = new Pen(ChartStyle.ForeColor))
{
pn.DashStyle = DashStyle.Dash;
pn.DashPattern = new float[] { 3, 3 };
g.DrawLine(pn, DrawOrigin.X, start, Width - BarOption.Grid.Right, start);
}
}
else
{
g.DrawLine(ChartStyle.ForeColor, DrawOrigin.X, start, Width - BarOption.Grid.Right, start);
float lineStart = DrawOrigin.X;
for (int j = 0; j <= BarOption.Series.Count; j++)
{
g.DrawLine(ChartStyle.ForeColor, lineStart, start, lineStart, start + BarOption.XAxis.AxisTick.Length);
lineStart += DrawBarWidth;
}
}
start -= DrawBarHeight;
}
}
if (BarOption.YAxis.AxisLabel.Show)
{
float start = DrawOrigin.Y;
float DrawBarHeight = DrawSize.Height * 1.0f / (YAxisEnd - YAxisStart);
int idx = 0;
float wmax = 0;
for (int i = YAxisStart; i <= YAxisEnd; i++)
{
string label = BarOption.YAxis.AxisLabel.GetLabel(i * YAxisInterval, idx);
SizeF sf = g.MeasureString(label, SubFont);
wmax = Math.Max(wmax, sf.Width);
g.DrawString(label, SubFont, ChartStyle.ForeColor, DrawOrigin.X - BarOption.YAxis.AxisTick.Length - sf.Width, start - sf.Height / 2.0f);
start -= DrawBarHeight;
}
SizeF sfname = g.MeasureString(BarOption.YAxis.Name, SubFont);
int x = (int)(DrawOrigin.X - BarOption.YAxis.AxisTick.Length - wmax - sfname.Height);
int y = (int)(BarOption.Grid.Top + (DrawSize.Height - sfname.Width) / 2);
g.DrawString(BarOption.YAxis.Name, SubFont, ChartStyle.ForeColor, new Point(x, y),
new StringFormat() { Alignment = StringAlignment.Center }, 270);
}
}
protected override void OnMouseMove(MouseEventArgs e)
{
try
{
if (BarOption.ToolTip == null) return;
if (e.Location.X > BarOption.Grid.Left && e.Location.X < Width - BarOption.Grid.Right
&& e.Location.Y > BarOption.Grid.Top &&
e.Location.Y < Height - BarOption.Grid.Bottom)
{
SelectIndex = (int)((e.Location.X - BarOption.Grid.Left) / DrawBarWidth);
}
else
{
SelectIndex = -1;
}
if (SelectIndex >= 0 && Bars.Count > 0)
{
if (tip.Text != Bars[selectIndex][0].Tips)
{
tip.Text = Bars[selectIndex][0].Tips;
tip.Size = new Size((int)Bars[selectIndex][0].Size.Width + 4, (int)Bars[selectIndex][0].Size.Height + 4);
}
int x = e.Location.X + 15;
int y = e.Location.Y + 20;
if (e.Location.X + 15 + tip.Width > Width - BarOption.Grid.Right)
x = e.Location.X - tip.Width - 2;
if (e.Location.Y + 20 + tip.Height > Height - BarOption.Grid.Bottom)
y = e.Location.Y - tip.Height - 2;
tip.Left = x;
tip.Top = y;
if (!tip.Visible) tip.Visible = Bars[selectIndex][0].Tips.IsValid();
}
}
catch (Exception exception)
{
Console.WriteLine(exception);
}
}
protected override void CreateEmptyOption()
{
if (emptyOption != null) return;
UIBarOption option = new UIBarOption();
option.Title = new UITitle();
option.Title.Text = "SunnyUI";
option.Title.SubText = "BarChart";
//设置Legend
option.Legend = new UILegend();
option.Legend.Orient = UIOrient.Horizontal;
option.Legend.Top = UITopAlignment.Top;
option.Legend.Left = UILeftAlignment.Left;
option.Legend.AddData("Bar1");
option.Legend.AddData("Bar2");
option.Legend.AddData("Bar3");
var series = new UIBarSeries();
series.Name = "Bar1";
series.AddData(1);
option.Series.Add(series);
series = new UIBarSeries();
series.Name = "Bar2";
series.AddData(2);
series.AddData(3);
option.Series.Add(series);
series = new UIBarSeries();
series.Name = "Bar2";
series.AddData(4);
series.AddData(5);
series.AddData(6);
option.Series.Add(series);
option.XAxis.Data.Add("Mon");
option.XAxis.Data.Add("Tue");
option.XAxis.Data.Add("Wed");
option.XAxis.Data.Add("Thu");
option.XAxis.Data.Add("Fri");
option.ToolTip = new UIBarToolTip();
option.ToolTip.AxisPointer.Type = UIAxisPointerType.Shadow;
emptyOption = option;
}
}
}

View File

@ -41,6 +41,8 @@ namespace Sunny.UI
public readonly List<UIScaleLine> YAxisScaleLines = new List<UIScaleLine>();
public int FixedSeriesCount { get; set; } = 0;
public void AddSeries(UIBarSeries series)
{
Series.Add(series);
@ -195,6 +197,8 @@ namespace Sunny.UI
public UISeriesType Type => UISeriesType.Bar;
public readonly List<string> BarName = new List<string>();
public readonly List<double> Data = new List<double>();
public readonly List<Color> Colors = new List<Color>();
@ -215,6 +219,18 @@ namespace Sunny.UI
Colors.Add(color);
}
public void AddData(string name, double value)
{
BarName.Add(name);
AddData(value);
}
public void AddData(string name, double value, Color color)
{
BarName.Add(name);
AddData(value, color);
}
public void Dispose()
{
Data.Clear();
@ -232,6 +248,7 @@ namespace Sunny.UI
public void Clear()
{
BarName.Clear();
Data.Clear();
Colors.Clear();
}

View File

@ -54,6 +54,9 @@
<Compile Include="Charts\UIBarChart.cs">
<SubType>Component</SubType>
</Compile>
<Compile Include="Charts\UIBarChartEx.cs">
<SubType>Component</SubType>
</Compile>
<Compile Include="Charts\UIBarChartOption.cs" />
<Compile Include="Charts\UIChart.cs">
<SubType>Component</SubType>