diff --git a/ControlUse/Timeline/ChartConstants.cs b/ControlUse/Timeline/ChartConstants.cs index 4fcdc2c..324c2bb 100644 --- a/ControlUse/Timeline/ChartConstants.cs +++ b/ControlUse/Timeline/ChartConstants.cs @@ -1,10 +1,10 @@ using System; using System.Collections.Generic; -using Timeline.Model; +using Timelines.Model; using System.Windows.Forms; using System.Drawing; -namespace Timeline +namespace Timelines { public static class ChartConstants { diff --git a/ControlUse/Timeline/Model/BarModel.cs b/ControlUse/Timeline/Model/BarModel.cs index 133c6a5..1954bf8 100644 --- a/ControlUse/Timeline/Model/BarModel.cs +++ b/ControlUse/Timeline/Model/BarModel.cs @@ -1,7 +1,7 @@ using System; using System.Drawing; -namespace Timeline.Model +namespace Timelines.Model { public class BarModel { diff --git a/ControlUse/Timeline/Model/HeaderModel.cs b/ControlUse/Timeline/Model/HeaderModel.cs index a21a68a..0d3faa1 100644 --- a/ControlUse/Timeline/Model/HeaderModel.cs +++ b/ControlUse/Timeline/Model/HeaderModel.cs @@ -1,6 +1,6 @@ using System; -namespace Timeline.Model +namespace Timelines.Model { public class HeaderModel { diff --git a/ControlUse/Timeline/Model/ItemModel.cs b/ControlUse/Timeline/Model/ItemModel.cs index 77556fa..4b0b2db 100644 --- a/ControlUse/Timeline/Model/ItemModel.cs +++ b/ControlUse/Timeline/Model/ItemModel.cs @@ -1,7 +1,7 @@ using System; using System.Drawing; -namespace Timeline.Model +namespace Timelines.Model { public class ItemModel { diff --git a/ControlUse/Timeline/Processor/BarChartProcessor.cs b/ControlUse/Timeline/Processor/BarChartProcessor.cs index 72a6d9f..de92ed9 100644 --- a/ControlUse/Timeline/Processor/BarChartProcessor.cs +++ b/ControlUse/Timeline/Processor/BarChartProcessor.cs @@ -3,11 +3,11 @@ using System.Collections.Generic; using System.Drawing; using System.Linq; using System.Runtime.Remoting.Messaging; -using Timeline.Model; -using Timeline; +using Timelines.Model; +using Timelines; using System.Threading.Tasks; -namespace Timeline.Processor +namespace Timelines.Processor { public class BarChartProcessor { diff --git a/ControlUse/Timeline/Properties/AssemblyInfo.cs b/ControlUse/Timeline/Properties/AssemblyInfo.cs index 75997b8..77bbfad 100644 --- a/ControlUse/Timeline/Properties/AssemblyInfo.cs +++ b/ControlUse/Timeline/Properties/AssemblyInfo.cs @@ -2,35 +2,32 @@ using System.Runtime.CompilerServices; using System.Runtime.InteropServices; -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("Timeline")] +// 有关程序集的一般信息由以下 +// 控制。更改这些特性值可修改 +// 与程序集关联的信息。 +[assembly: AssemblyTitle("Timelines")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("Timeline")] -[assembly: AssemblyCopyright("Copyright © 2014")] +[assembly: AssemblyProduct("Timelines")] +[assembly: AssemblyCopyright("Copyright © 2024")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. +// 将 ComVisible 设置为 false 会使此程序集中的类型 +//对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型 +//请将此类型的 ComVisible 特性设置为 true。 [assembly: ComVisible(false)] -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("40f4c82a-50c5-4880-a19b-dec078fac398")] +// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID +[assembly: Guid("fcaa62db-0f2f-449c-8511-c6f0821688a7")] -// Version information for an assembly consists of the following four values: +// 程序集的版本信息由下列四个值组成: // -// Major Version -// Minor Version -// Build Number -// Revision +// 主版本 +// 次版本 +// 生成号 +// 修订号 // -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] [assembly: AssemblyVersion("1.0.0.0")] [assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/ControlUse/Timeline/Timeline.Designer.cs b/ControlUse/Timeline/Timeline.Designer.cs new file mode 100644 index 0000000..25ba3b8 --- /dev/null +++ b/ControlUse/Timeline/Timeline.Designer.cs @@ -0,0 +1,38 @@ +namespace Timelines +{ + partial class Timeline + { + /// + /// 必需的设计器变量。 + /// + private System.ComponentModel.IContainer components = null; + + /// + /// 清理所有正在使用的资源。 + /// + /// 如果应释放托管资源,为 true;否则为 false。 + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region 组件设计器生成的代码 + + /// + /// 设计器支持所需的方法 - 不要修改 + /// 使用代码编辑器修改此方法的内容。 + /// + private void InitializeComponent() + { + components = new System.ComponentModel.Container(); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(800, 450); + } + + #endregion + } +} diff --git a/ControlUse/Timeline/Timeline.cs b/ControlUse/Timeline/Timeline.cs new file mode 100644 index 0000000..033a4d9 --- /dev/null +++ b/ControlUse/Timeline/Timeline.cs @@ -0,0 +1,314 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using System.Data; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; +using Timelines.Model; +using Timelines.Processor; + +namespace Timelines +{ + public partial class Timeline : UserControl + { + #region public properties + public SolidBrush HoverClickSolidBrush { get; set; } + public Font RowFont { get; set; } + public Font DateFont { get; set; } + public Font TimeFont { get; set; } + #endregion + + #region private properties + private ToolTip ToolTip { get; set; } + private VScrollBar VScrollBar1 { get; set; } + private int AvailableWidth { get; set; } + private Point OldMousePosition { get; set; } + private int ScrollPosition { get; set; } + private List ToolTipTextList { get; set; } + private string ToolTipTextTitle { get; set; } + private List BarList { get; set; } + private DateTime StartDate { get; set; } + private int DistinctItemCount { get; set; } + private DateTime EndDate { get; set; } + #endregion + public Timeline() + { + InitializeComponent(); + } + public void ShowBarChart(DateTime chartStartDate, DateTime chartEndDate, List items) + { + this.StartDate = chartStartDate; + this.EndDate = chartEndDate; + var proc = new BarChartProcessor(); + this.BarList = proc.GetBarList(items); + this.DistinctItemCount = items.Select(i => i.ItemName).Distinct().Count(); + + this.Refresh(); + } + private void ChartMouseMove(Object sender, MouseEventArgs e) + { + var localMousePosition = new Point(e.X, e.Y); + + if (BarList == null || BarList.Count == 0) + { + return; + } + + if (localMousePosition == this.OldMousePosition) + { + return; + } + + var proc = new BarChartProcessor(); + + var mouseOverObject = false; + var tempText = new List(); + var tempTitle = ""; + + Parallel.ForEach(this.BarList, bar => + { + if (proc.MouseInsideBar(localMousePosition, bar) && bar.Visible) + { + bar.IsMouseOver = true; + tempTitle = bar.Name; + tempText.Add("Event Start: " + bar.StartValue.ToUniversalTime()); + tempText.Add("Event End: " + bar.EndValue.ToUniversalTime()); + mouseOverObject = true; + } + else + { + bar.IsMouseOver = false; + } + }); + + this.ToolTipTextList = tempText; + this.ToolTipTextTitle = tempTitle; + this.ToolTip.SetToolTip(this, this.ToolTipTextList.Count > 0 ? this.ToolTipTextList.ToString() : ""); + + if (mouseOverObject) + { + this.Refresh(); + } + + this.OldMousePosition = localMousePosition; + } + private void ChartMouseClick(Object sender, MouseEventArgs e) + { + if (BarList == null || BarList.Count == 0) + { + return; + } + + var localMousePosition = new Point(e.X, e.Y); + + var proc = new BarChartProcessor(); + + this.BarList = proc.MouseClickHandler(this.BarList, localMousePosition); + } + private void ChartMouseWheel(object sender, MouseEventArgs e) + { + this.VScrollBar1.Focus(); + } + private void Timeline_Load(object sender, EventArgs e) + { + //initialize public properties + RowFont = TimeFont = DateFont = new Font("Segoe UI", 10, FontStyle.Regular, GraphicsUnit.Point); + HoverClickSolidBrush = new SolidBrush(Color.LightBlue); + BackColor = Color.White; + + //initialize mouse controls + MouseMove += ChartMouseMove; + MouseWheel += ChartMouseWheel; + MouseClick += ChartMouseClick; + + //initialize Tooltip + this.ToolTip = new ToolTip + { + OwnerDraw = true + }; + this.ToolTip.Draw += ToolTipText_Draw; + this.ToolTip.Popup += ToolTipText_Popup; + + //Flicker free drawing + SetStyle(ControlStyles.DoubleBuffer | ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint, true); + + //ScrollBar + this.VScrollBar1 = new VScrollBar + { + Dock = DockStyle.Right, + Visible = false + }; + Controls.Add(this.VScrollBar1); + this.VScrollBar1.Scroll += vScrollBar1_Scroll; + } + private void vScrollBar1_Scroll(object sender, ScrollEventArgs e) + { + this.ScrollPosition = this.VScrollBar1.Value; + this.Refresh(); + } + private void ToolTipText_Draw(Object sender, DrawToolTipEventArgs e) + { + if (this.ToolTipTextList.Count == 0) + { + return; + } + e.Graphics.FillRectangle(Brushes.White, e.Bounds); + e.Graphics.DrawString(this.ToolTipTextTitle, ChartConstants.TitleFont, Brushes.Black, 5, 0); + + // Draws the lines in the text box + foreach (var item in this.ToolTipTextList) + { + var stringY = (ChartConstants.ToolTipTitleHeight - ChartConstants.ToolTipfontHeight - e.Graphics.MeasureString(item, ChartConstants.RowFont).Height) / 2 + + 10 + ((this.ToolTipTextList.IndexOf(item) + 1) * 14); + e.Graphics.DrawString(item, ChartConstants.RowFont, Brushes.Black, 5, stringY); + } + } + private void ToolTipText_Popup(Object sender, PopupEventArgs e) + { + var toolTipHeight = (ChartConstants.ToolTipTitleHeight + 4) + (this.ToolTipTextList.Count * (ChartConstants.ToolTipfontHeight + 3)); + e.ToolTipSize = new Size(230, toolTipHeight); + } + private void PaintChart(Graphics graphics) + { + if (BarList == null || BarList.Count == 0) + { + return; + } + var proc = new BarChartProcessor(); + var headerList = proc.GetFullHeaderList(this.StartDate, this.EndDate, this.Width, this.TimeFont); + if (headerList.Count == 0 || this.DistinctItemCount == 0) + { + return; + } + + var pixelsPerSecond = proc.GetPixelsPerSecond(headerList); + + this.AvailableWidth = Width - ChartConstants.BarStartLeft - ChartConstants.BarStartRight; + + if (this.DistinctItemCount * (ChartConstants.BarHeight + ChartConstants.BarSpace) > Height) + { + this.VScrollBar1.Visible = true; + this.VScrollBar1.Maximum = this.DistinctItemCount - 3; + } + + graphics.Clear(BackColor); + DrawChartHeadersAndNet(graphics, headerList); + + DrawBars(graphics, this.BarList, pixelsPerSecond); + } + protected override void OnPaint(PaintEventArgs pe) + { + PaintChart(pe.Graphics); + } + private void DrawBars(Graphics graphics, IEnumerable barList, double pixelsPerSecond) + { + //list of machineNames to add to the left of each row + var rowTitleList = new List(); + + var proc = new BarChartProcessor(); + + // Draws each bar + foreach (var bar in barList) + { + var numberOfBarsInControl = (Height - ChartConstants.BarStartTop) / (ChartConstants.BarHeight + ChartConstants.BarSpace); + + if ((bar.RowIndex >= this.ScrollPosition && + bar.RowIndex < numberOfBarsInControl + this.ScrollPosition)) + { + var newBar = proc.GetBar(bar, this.StartDate, pixelsPerSecond, ScrollPosition, this.Width); + DrawBarAndRowText(newBar, rowTitleList, graphics); + } + else + { + bar.Visible = false; + } + } + } + private void DrawBarAndRowText(BarModel newBar, ICollection rowTitleList, Graphics graphics) + { + var barBrush = new SolidBrush(newBar.Color); + if (newBar.IsMouseOver || newBar.IsClicked) + { + barBrush = HoverClickSolidBrush; + } + + graphics.FillRectangle(barBrush, newBar.BarRectangle); + graphics.DrawRectangle(Pens.Black, newBar.BarRectangle); + + // Draws the rowtext, only once for each machine + if (!rowTitleList.Contains(newBar.Name)) + { + graphics.DrawString(newBar.Name, + RowFont, + Brushes.Black, + 0, + ChartConstants.BarStartTop + (ChartConstants.BarHeight * (newBar.RowIndex - this.ScrollPosition)) + + (ChartConstants.BarSpace * (newBar.RowIndex - this.ScrollPosition))); + + rowTitleList.Add(newBar.Name); + } + } + private void DrawChartHeadersAndNet(Graphics graphics, IList headerList) + { + var verticalLineLastY = ChartConstants.BarStartTop + (this.DistinctItemCount - this.ScrollPosition) * (ChartConstants.BarHeight + ChartConstants.BarSpace); + + //draw headers + foreach (var header in headerList) + { + //draw the date when there is a change of day + var index = headerList.IndexOf(header); + + if (headerList.IndexOf(header) == 0 + || header.HeaderDateTime.Day != headerList[index - 1].HeaderDateTime.Day) + { + graphics.DrawString( + header.HeaderDateTime.ToShortDateString(), + DateFont, + Brushes.Black, + header.StartLocation, + 0); + } + + graphics.DrawString( + header.HeaderDateTime.ToShortTimeString(), + TimeFont, + Brushes.Black, + header.StartLocation, + ChartConstants.HeaderTimeStartTop); + + //draw vertical line under header + graphics.DrawLine( + ChartConstants.GridColor, + header.StartLocation, + ChartConstants.HeaderTimeStartTop, + header.StartLocation, + verticalLineLastY); + + } + + //draw last vertical line + graphics.DrawLine( + ChartConstants.GridColor, + ChartConstants.BarStartLeft + this.AvailableWidth, + ChartConstants.HeaderTimeStartTop, + ChartConstants.BarStartLeft + this.AvailableWidth, + verticalLineLastY); + + //draw horizontal net + for (var index = 0; index < this.DistinctItemCount; index++) + { + var y = ChartConstants.BarStartTop + index * (ChartConstants.BarHeight + ChartConstants.BarSpace); + graphics.DrawLine( + ChartConstants.GridColor, + ChartConstants.BarStartLeft, + y, + ChartConstants.BarStartLeft + this.AvailableWidth, + y + ); + } + } + } +} diff --git a/ControlUse/Timeline/Timelines.csproj b/ControlUse/Timeline/Timelines.csproj index 93a39fe..a789eec 100644 --- a/ControlUse/Timeline/Timelines.csproj +++ b/ControlUse/Timeline/Timelines.csproj @@ -1,17 +1,16 @@ - - + + Debug AnyCPU - {77D9FB0A-D628-4002-A118-B3D6E6601092} + {FCAA62DB-0F2F-449C-8511-C6F0821688A7} Library - Properties - Timeline - Timeline + Timelines + Timelines v4.7.2 512 - + true true @@ -38,6 +37,7 @@ + @@ -47,27 +47,14 @@ - + UserControl - - TimelineChart.cs + + Timeline.cs - - - TimelineChart.cs - - - - \ No newline at end of file diff --git a/SunlightCentralizedControlManagement(SCCM).sln b/SunlightCentralizedControlManagement(SCCM).sln index 5833aca..9588d6c 100644 --- a/SunlightCentralizedControlManagement(SCCM).sln +++ b/SunlightCentralizedControlManagement(SCCM).sln @@ -5,7 +5,7 @@ VisualStudioVersion = 17.11.35312.102 MinimumVisualStudioVersion = 10.0.40219.1 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SunlightCentralizedControlManagement_SCCM_", "SunlightCentralizedControlManagement_SCCM_.csproj", "{2CFE8A79-C7DC-47AC-8D0C-2E03010E2458}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Timelines", "ControlUse\Timeline\Timelines.csproj", "{77D9FB0A-D628-4002-A118-B3D6E6601092}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Timelines", "..\Timelines\Timelines.csproj", "{FCAA62DB-0F2F-449C-8511-C6F0821688A7}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -17,10 +17,10 @@ Global {2CFE8A79-C7DC-47AC-8D0C-2E03010E2458}.Debug|Any CPU.Build.0 = Debug|Any CPU {2CFE8A79-C7DC-47AC-8D0C-2E03010E2458}.Release|Any CPU.ActiveCfg = Release|Any CPU {2CFE8A79-C7DC-47AC-8D0C-2E03010E2458}.Release|Any CPU.Build.0 = Release|Any CPU - {77D9FB0A-D628-4002-A118-B3D6E6601092}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {77D9FB0A-D628-4002-A118-B3D6E6601092}.Debug|Any CPU.Build.0 = Debug|Any CPU - {77D9FB0A-D628-4002-A118-B3D6E6601092}.Release|Any CPU.ActiveCfg = Release|Any CPU - {77D9FB0A-D628-4002-A118-B3D6E6601092}.Release|Any CPU.Build.0 = Release|Any CPU + {FCAA62DB-0F2F-449C-8511-C6F0821688A7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {FCAA62DB-0F2F-449C-8511-C6F0821688A7}.Debug|Any CPU.Build.0 = Debug|Any CPU + {FCAA62DB-0F2F-449C-8511-C6F0821688A7}.Release|Any CPU.ActiveCfg = Release|Any CPU + {FCAA62DB-0F2F-449C-8511-C6F0821688A7}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/SunlightCentralizedControlManagement_SCCM_.csproj b/SunlightCentralizedControlManagement_SCCM_.csproj index af7960d..7342bf6 100644 --- a/SunlightCentralizedControlManagement_SCCM_.csproj +++ b/SunlightCentralizedControlManagement_SCCM_.csproj @@ -31,7 +31,7 @@ true - x64 + AnyCPU true full false @@ -39,6 +39,7 @@ DEBUG;TRACE prompt 4 + false AnyCPU @@ -55,6 +56,26 @@ sunlightlogo.ico + + true + bin\x64\Debug\ + DEBUG;TRACE + full + x64 + 7.3 + prompt + true + + + bin\x64\Release\ + TRACE + true + pdbonly + x64 + 7.3 + prompt + true + @@ -79,6 +100,28 @@ MSBuild:Compile Designer + + + + + + + + + + + + + + + + + Timeline.cs + + + + TimelineChart.cs + @@ -256,6 +299,12 @@ Settings.settings True + + + + + TimelineChart.cs + PublicResXFileCodeGenerator @@ -264,6 +313,24 @@ + + + + + + + + + + + + + + + + + + @@ -345,9 +412,29 @@ - + + + + + + + + + + + + + + + + + + + + + @@ -387,8 +474,8 @@ - - {77d9fb0a-d628-4002-a118-b3d6e6601092} + + {fcaa62db-0f2f-449c-8511-c6f0821688a7} Timelines diff --git a/View/ProductionPlanningView.xaml b/View/ProductionPlanningView.xaml index 6a54523..7d6fd68 100644 --- a/View/ProductionPlanningView.xaml +++ b/View/ProductionPlanningView.xaml @@ -10,7 +10,7 @@ xmlns:lvc="clr-namespace:LiveChartsCore.SkiaSharpView.WPF;assembly=LiveChartsCore.SkiaSharpView.WPF" xmlns:viewmodel="clr-namespace:SunlightCentralizedControlManagement_SCCM_.ViewModel" xmlns:wf="clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms" - xmlns:UserTimeline="clr-namespace:Timeline;assembly=Timeline" + xmlns:UserTimeline="clr-namespace:Timelines;assembly=Timelines" xmlns:wfi ="clr-namespace:System.Windows.Forms.Integration;assembly=WindowsFormsIntegration" d:DataContext="{d:DesignInstance Type=viewmodel:ProductionPlanningModel}" mc:Ignorable="d" Loaded="UserControl_Loaded" @@ -24,10 +24,9 @@ - - - - + + + diff --git a/View/ProductionPlanningView.xaml.cs b/View/ProductionPlanningView.xaml.cs index 50ddfca..b0be816 100644 --- a/View/ProductionPlanningView.xaml.cs +++ b/View/ProductionPlanningView.xaml.cs @@ -33,8 +33,8 @@ using static System.Windows.Forms.VisualStyles.VisualStyleElement; using SunlightCentralizedControlManagement_SCCM_.ViewModel; using LiveChartsCore.SkiaSharpView.WPF; using System.Data.Entity.Core.Common.CommandTrees.ExpressionBuilder; -using Timeline.Model; -using Timeline; +using Timelines.Model; +using Timelines; namespace SunlightCentralizedControlManagement_SCCM_.View { @@ -79,7 +79,7 @@ namespace SunlightCentralizedControlManagement_SCCM_.View } } - + qwe.ShowBarChart(startDate,endDate,testList); // var dfg = new TimelineChart(); // qwe.Child = dfg.ShowBarChart(startDate, endDate, testList); // timeline1.ShowBarChart(startDate, endDate, testList);