From 066b4882b95700e16956ee65299ab79fcd2a23f3 Mon Sep 17 00:00:00 2001 From: Candy Date: Tue, 28 Apr 2020 18:06:55 +0800 Subject: [PATCH] =?UTF-8?q?=E6=97=A5=E5=B8=B8Bug=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../{QulityConst.cs => QualityConst.cs} | 8 +- DBDevelopClientApi/DevelopServiceHelper.cs | 137 +++- DBDevelopClientApi/developService.proto | 10 +- DBDevelopService/DBDevelopService.csproj | 2 + DBDevelopService/Protos/developService.proto | 10 +- .../Services/DevelopServerService.cs | 114 +-- DBHisData/HisQuery/DataFileManager.cs | 6 +- DBHisData/HisQuery/QuerySerivce.cs | 24 +- DBHisData/HisQuery/TimeFile/DataFileInfo.cs | 92 ++- DBHisData/HisQuery/TimeFile/YearTimeFile.cs | 11 +- DBInRun/Program.cs | 30 +- DBStudio/Properties/launchSettings.json | 8 + .../Compress/Special/LosslessCompressUnit.cs | 2 +- .../His/Compress/Special/NoneCompressUnit.cs | 703 ++++++----------- DataRunner/His/HisEnginer.cs | 14 +- DataRunner/His/Tag/HisRunTag.cs | 2 +- DataRunner/Real/RealEnginer.cs | 52 +- DbManager.Desktop/Image/export.png | Bin 0 -> 272 bytes DbManager.Desktop/Image/import.png | Bin 0 -> 268 bytes DbManager.Desktop/MainWindow.xaml | 20 + .../Properties/Resources.Designer.cs | 60 +- DbManager.Desktop/Properties/Resources.resx | 22 +- .../Properties/launchSettings.json | 8 + .../View/DeadAreaCompressParameter.xaml | 13 +- .../View/SlopeCompressParameterView.xaml | 9 +- .../View/TagGroupDetailView.xaml | 31 +- .../ViewModel/CompressParameterModelBase.cs | 88 ++- DbManager.Desktop/ViewModel/ITreeViewModel.cs | 2 +- DbManager.Desktop/ViewModel/LoginViewModel.cs | 2 +- DbManager.Desktop/ViewModel/MainViewModel.cs | 139 +++- .../ViewModel/TagExportHelper.cs | 86 --- .../ViewModel/TagGroupDetailViewModel.cs | 99 ++- DbManager.Desktop/ViewModel/TagViewModel.cs | 87 ++- HisDataTools/App.xaml | 2 +- HisDataTools/Chart/Brush/Bitmap/BitmapBase.cs | 86 +++ HisDataTools/Chart/Brush/Bitmap/IBitmap.cs | 13 + .../Chart/Brush/Bitmap/LinearBitmap.cs | 153 ++++ .../Chart/Brush/Bitmap/PlanarGridBitmap.cs | 18 + HisDataTools/Chart/Brush/Brushes/IBrush.cs | 9 + .../Chart/Brush/Brushes/LinearBrush.cs | 107 +++ .../Chart/Brush/Brushes/PlanarGridBrush.cs | 55 ++ HisDataTools/Chart/ChartGeneric.xaml | 15 + HisDataTools/Chart/ICurveChart.cs | 34 + HisDataTools/Chart/Legend/Legend.xaml | 22 + HisDataTools/Chart/Legend/Legend.xaml.cs | 294 +++++++ HisDataTools/Chart/Legend/LineLegendItem.xaml | 30 + .../Chart/Legend/LineLegendItem.xaml.cs | 87 +++ .../CardiogramCurveChartPlotter.cs | 162 ++++ .../ChartInstance/StaticCurveChartPlotter.cs | 37 + HisDataTools/Chart/Plotter/ChartPlotter.cs | 180 +++++ .../Chart/Plotter/Common/CursorGraphLine.xaml | 75 ++ .../Plotter/Common/CursorGraphLine.xaml.cs | 330 ++++++++ .../Plotter/Common/LineLegendDetail.xaml | 37 + .../Plotter/Common/LineLegendDetail.xaml.cs | 102 +++ HisDataTools/Chart/Plotter/Common/PointC.cs | 59 ++ .../Chart/Plotter/Common/SplitItem.cs | 120 +++ .../Chart/Plotter/CurveChartPlotter.cs | 717 ++++++++++++++++++ .../DataSource/CardiogramCurveEntitySource.cs | 65 ++ .../Plotter/DataSource/CurveEntitySource.cs | 170 +++++ .../Plotter/DataSource/ICurveEntitySource.cs | 146 ++++ .../Chart/Plotter/Marker/CirclePointMarker.cs | 52 ++ HisDataTools/Chart/Plotter/Marker/IMark.cs | 679 +++++++++++++++++ .../Chart/Plotter/Marker/T5PointMarker.cs | 119 +++ .../Plotter/Marker/TrianglePointMarker.cs | 61 ++ HisDataTools/Chart/Plotter/PlotterBase.cs | 138 ++++ .../Chart/Plotter/PlotterBaseStyle.xaml | 551 ++++++++++++++ HisDataTools/Chart/Plotter/ViewPlotter.cs | 36 + HisDataTools/Properties/Resources.Designer.cs | 81 ++ HisDataTools/Properties/Resources.resx | 27 + HisDataTools/Properties/Resources.zh-CN.resx | 57 ++ HisDataTools/Themes/Generic.xaml | 3 + HisDataTools/View/HisDataQueryView.xaml | 48 +- HisDataTools/View/HisDataQueryView.xaml.cs | 76 +- HisDataTools/ViewModel/HisDataQueryModel.cs | 433 ++++++++++- .../ViewModel/ListDatabaseViewModel.cs | 2 +- 75 files changed, 6597 insertions(+), 782 deletions(-) rename Cdy.Tag.Common/Common/{QulityConst.cs => QualityConst.cs} (86%) create mode 100644 DBStudio/Properties/launchSettings.json create mode 100644 DbManager.Desktop/Image/export.png create mode 100644 DbManager.Desktop/Image/import.png create mode 100644 DbManager.Desktop/Properties/launchSettings.json delete mode 100644 DbManager.Desktop/ViewModel/TagExportHelper.cs create mode 100644 HisDataTools/Chart/Brush/Bitmap/BitmapBase.cs create mode 100644 HisDataTools/Chart/Brush/Bitmap/IBitmap.cs create mode 100644 HisDataTools/Chart/Brush/Bitmap/LinearBitmap.cs create mode 100644 HisDataTools/Chart/Brush/Bitmap/PlanarGridBitmap.cs create mode 100644 HisDataTools/Chart/Brush/Brushes/IBrush.cs create mode 100644 HisDataTools/Chart/Brush/Brushes/LinearBrush.cs create mode 100644 HisDataTools/Chart/Brush/Brushes/PlanarGridBrush.cs create mode 100644 HisDataTools/Chart/ChartGeneric.xaml create mode 100644 HisDataTools/Chart/ICurveChart.cs create mode 100644 HisDataTools/Chart/Legend/Legend.xaml create mode 100644 HisDataTools/Chart/Legend/Legend.xaml.cs create mode 100644 HisDataTools/Chart/Legend/LineLegendItem.xaml create mode 100644 HisDataTools/Chart/Legend/LineLegendItem.xaml.cs create mode 100644 HisDataTools/Chart/Plotter/ChartInstance/CardiogramCurveChartPlotter.cs create mode 100644 HisDataTools/Chart/Plotter/ChartInstance/StaticCurveChartPlotter.cs create mode 100644 HisDataTools/Chart/Plotter/ChartPlotter.cs create mode 100644 HisDataTools/Chart/Plotter/Common/CursorGraphLine.xaml create mode 100644 HisDataTools/Chart/Plotter/Common/CursorGraphLine.xaml.cs create mode 100644 HisDataTools/Chart/Plotter/Common/LineLegendDetail.xaml create mode 100644 HisDataTools/Chart/Plotter/Common/LineLegendDetail.xaml.cs create mode 100644 HisDataTools/Chart/Plotter/Common/PointC.cs create mode 100644 HisDataTools/Chart/Plotter/Common/SplitItem.cs create mode 100644 HisDataTools/Chart/Plotter/CurveChartPlotter.cs create mode 100644 HisDataTools/Chart/Plotter/DataSource/CardiogramCurveEntitySource.cs create mode 100644 HisDataTools/Chart/Plotter/DataSource/CurveEntitySource.cs create mode 100644 HisDataTools/Chart/Plotter/DataSource/ICurveEntitySource.cs create mode 100644 HisDataTools/Chart/Plotter/Marker/CirclePointMarker.cs create mode 100644 HisDataTools/Chart/Plotter/Marker/IMark.cs create mode 100644 HisDataTools/Chart/Plotter/Marker/T5PointMarker.cs create mode 100644 HisDataTools/Chart/Plotter/Marker/TrianglePointMarker.cs create mode 100644 HisDataTools/Chart/Plotter/PlotterBase.cs create mode 100644 HisDataTools/Chart/Plotter/PlotterBaseStyle.xaml create mode 100644 HisDataTools/Chart/Plotter/ViewPlotter.cs diff --git a/Cdy.Tag.Common/Common/QulityConst.cs b/Cdy.Tag.Common/Common/QualityConst.cs similarity index 86% rename from Cdy.Tag.Common/Common/QulityConst.cs rename to Cdy.Tag.Common/Common/QualityConst.cs index e638bfe..53fbd34 100644 --- a/Cdy.Tag.Common/Common/QulityConst.cs +++ b/Cdy.Tag.Common/Common/QualityConst.cs @@ -15,7 +15,7 @@ namespace Cdy.Tag /// /// 质量戳常量 /// - public enum QulityConst + public enum QualityConst { /// /// 好 @@ -26,9 +26,13 @@ namespace Cdy.Tag /// Bad= 20, /// + /// 初始状态 + /// + Init = 63, + /// /// 无数据 /// - Tick=253, + Tick =253, /// /// 保持和前置一样 /// diff --git a/DBDevelopClientApi/DevelopServiceHelper.cs b/DBDevelopClientApi/DevelopServiceHelper.cs index e021c66..dcf5853 100644 --- a/DBDevelopClientApi/DevelopServiceHelper.cs +++ b/DBDevelopClientApi/DevelopServiceHelper.cs @@ -185,52 +185,135 @@ namespace DBDevelopClientApi /// /// /// - /// /// - public Dictionary> QueryTagByGroup(string database,string group) + public Dictionary> QueryAllTag(string database) { Dictionary> re = new Dictionary>(); if (mCurrentClient != null && !string.IsNullOrEmpty(mLoginId)) { - var result = mCurrentClient.GetTagByGroup(new DBDevelopService.GetTagByGroupRequest() { Database = database, LoginId = mLoginId,Group=group }); - Dictionary mRealTag = new Dictionary(); - foreach(var vv in result.RealTag) + int idx = 0; + int count = 0; + do { - var tag = GetTag((int)vv.TagType); - tag.Id = (int)vv.Id; - tag.LinkAddress = vv.LinkAddress; - tag.Name = vv.Name; - tag.Desc = vv.Desc; - mRealTag.Add(tag.Id, tag); - } + var result = mCurrentClient.GetAllTag(new DBDevelopService.GetTagByGroupRequest() { Database = database, LoginId = mLoginId }); - Dictionary mHisTag = new Dictionary(); - foreach (var vv in result.HisTag) - { - var tag = new Cdy.Tag.HisTag { Id = (int)vv.Id, TagType = (Cdy.Tag.TagType)vv.TagType, Type = (Cdy.Tag.RecordType)vv.Type, CompressType = (int)vv.CompressType }; - if(vv.Parameter.Count>0) + idx = result.Index; + count = result.Count; + + if (!result.Result) break; + + Dictionary mRealTag = new Dictionary(); + foreach (var vv in result.RealTag) + { + var tag = GetTag((int)vv.TagType); + tag.Id = (int)vv.Id; + tag.LinkAddress = vv.LinkAddress; + tag.Name = vv.Name; + tag.Desc = vv.Desc; + tag.Group = vv.Group; + mRealTag.Add(tag.Id, tag); + } + + Dictionary mHisTag = new Dictionary(); + foreach (var vv in result.HisTag) + { + var tag = new Cdy.Tag.HisTag { Id = (int)vv.Id, TagType = (Cdy.Tag.TagType)vv.TagType, Type = (Cdy.Tag.RecordType)vv.Type, CompressType = (int)vv.CompressType }; + if (vv.Parameter.Count > 0) + { + tag.Parameters = new Dictionary(); + foreach (var vvv in vv.Parameter) + { + tag.Parameters.Add(vvv.Name, vvv.Value); + } + + } + mHisTag.Add(tag.Id, tag); + } + + foreach (var vv in mRealTag) { - tag.Parameters = new Dictionary(); - foreach(var vvv in vv.Parameter) + if (mHisTag.ContainsKey(vv.Key)) { - tag.Parameters.Add(vvv.Name, vvv.Value); + re.Add(vv.Key, new Tuple(mRealTag[vv.Key], mHisTag[vv.Key])); + } + else + { + re.Add(vv.Key, new Tuple(mRealTag[vv.Key], null)); } - } - mHisTag.Add(tag.Id, tag); + + idx++; } + while (idx < count); + } + return re; + } - foreach(var vv in mRealTag) + /// + /// + /// + /// + /// + /// + public Dictionary> QueryTagByGroup(string database,string group) + { + Dictionary> re = new Dictionary>(); + if (mCurrentClient != null && !string.IsNullOrEmpty(mLoginId)) + { + int idx = 0; + int count = 0; + do { - if (mHisTag.ContainsKey(vv.Key)) + var result = mCurrentClient.GetTagByGroup(new DBDevelopService.GetTagByGroupRequest() { Database = database, LoginId = mLoginId, Group = group,Index=idx }); + + idx = result.Index; + count = result.Count; + + if (!result.Result) break; + + Dictionary mRealTag = new Dictionary(); + foreach (var vv in result.RealTag) { - re.Add(vv.Key, new Tuple(mRealTag[vv.Key], mHisTag[vv.Key])); + var tag = GetTag((int)vv.TagType); + tag.Id = (int)vv.Id; + tag.LinkAddress = vv.LinkAddress; + tag.Name = vv.Name; + tag.Desc = vv.Desc; + tag.Group = vv.Group; + mRealTag.Add(tag.Id, tag); } - else + + Dictionary mHisTag = new Dictionary(); + foreach (var vv in result.HisTag) { - re.Add(vv.Key, new Tuple(mRealTag[vv.Key], null)); + var tag = new Cdy.Tag.HisTag { Id = (int)vv.Id, TagType = (Cdy.Tag.TagType)vv.TagType, Type = (Cdy.Tag.RecordType)vv.Type, CompressType = (int)vv.CompressType }; + if (vv.Parameter.Count > 0) + { + tag.Parameters = new Dictionary(); + foreach (var vvv in vv.Parameter) + { + tag.Parameters.Add(vvv.Name, vvv.Value); + } + + } + mHisTag.Add(tag.Id, tag); } + + foreach (var vv in mRealTag) + { + if (mHisTag.ContainsKey(vv.Key)) + { + re.Add(vv.Key, new Tuple(mRealTag[vv.Key], mHisTag[vv.Key])); + } + else + { + re.Add(vv.Key, new Tuple(mRealTag[vv.Key], null)); + } + } + + idx++; } + while (idx < count); } return re; } diff --git a/DBDevelopClientApi/developService.proto b/DBDevelopClientApi/developService.proto index 330c064..25c5926 100644 --- a/DBDevelopClientApi/developService.proto +++ b/DBDevelopClientApi/developService.proto @@ -76,6 +76,7 @@ service DevelopServer { //ȡб rpc GetAllTag(GetTagByGroupRequest) returns (GetTagMessageReply); + //ȡʷ rpc GetHisAllTag(GetRequest) returns (GetHistTagMessageReply); @@ -351,6 +352,7 @@ message GetTagByGroupRequest string LoginId=1; string Database=2; string Group=3; + int32 Index=4; } // @@ -360,13 +362,17 @@ message BoolResultReplay string ErroMessage=2; } + + //ȡ message GetTagMessageReply { bool Result =1; string ErroMessage=2; - repeated RealTagMessage realTag=3; - repeated HisTagMessage hisTag=4; + int32 Count=3; + int32 Index=4; + repeated RealTagMessage realTag=5; + repeated HisTagMessage hisTag=6; } message GetRealTagMessageReply diff --git a/DBDevelopService/DBDevelopService.csproj b/DBDevelopService/DBDevelopService.csproj index ff2fdc6..62c1bc8 100644 --- a/DBDevelopService/DBDevelopService.csproj +++ b/DBDevelopService/DBDevelopService.csproj @@ -6,6 +6,8 @@ Library + false + false diff --git a/DBDevelopService/Protos/developService.proto b/DBDevelopService/Protos/developService.proto index 330c064..25c5926 100644 --- a/DBDevelopService/Protos/developService.proto +++ b/DBDevelopService/Protos/developService.proto @@ -76,6 +76,7 @@ service DevelopServer { //ȡб rpc GetAllTag(GetTagByGroupRequest) returns (GetTagMessageReply); + //ȡʷ rpc GetHisAllTag(GetRequest) returns (GetHistTagMessageReply); @@ -351,6 +352,7 @@ message GetTagByGroupRequest string LoginId=1; string Database=2; string Group=3; + int32 Index=4; } // @@ -360,13 +362,17 @@ message BoolResultReplay string ErroMessage=2; } + + //ȡ message GetTagMessageReply { bool Result =1; string ErroMessage=2; - repeated RealTagMessage realTag=3; - repeated HisTagMessage hisTag=4; + int32 Count=3; + int32 Index=4; + repeated RealTagMessage realTag=5; + repeated HisTagMessage hisTag=6; } message GetRealTagMessageReply diff --git a/DBDevelopService/Services/DevelopServerService.cs b/DBDevelopService/Services/DevelopServerService.cs index 046dac6..b733fae 100644 --- a/DBDevelopService/Services/DevelopServerService.cs +++ b/DBDevelopService/Services/DevelopServerService.cs @@ -9,6 +9,8 @@ namespace DBDevelopService { public class DevelopServerService : DevelopServer.DevelopServerBase { + public const int PageCount = 500; + /// /// /// @@ -432,7 +434,7 @@ namespace DBDevelopService { foreach(var vv in db.RealDatabase.Groups) { - re.Group.Add(new TagGroup() { Name = vv.Key, Parent = vv.Value.Parent.FullName }); + re.Group.Add(new TagGroup() { Name = vv.Key, Parent = vv.Value.Parent!=null? vv.Value.Parent.FullName:"" }); } } return Task.FromResult(re); @@ -448,34 +450,47 @@ namespace DBDevelopService { if (!CheckLoginId(request.LoginId)) { - return Task.FromResult(new GetTagMessageReply() { Result = false }); + return Task.FromResult(new GetTagMessageReply() { Result = false, Index = request.Index }); } var db = DbManager.Instance.GetDatabase(request.Database); List rre = new List(); List re = new List(); + int totalpage = 0; if (db != null) { - foreach (var vv in db.RealDatabase.ListAllTags().Where(e=>e.Group == request.Group)) + + int from = request.Index * PageCount; + var res = db.RealDatabase.ListAllTags().Where(e => e.Group == request.Group); + var total = res.Count(); + + totalpage = total / PageCount; + totalpage = total % PageCount > 0 ? totalpage + 1 : totalpage; + int cc = 0; + foreach (var vv in res) { - rre.Add(new RealTagMessage() { Id = (uint)vv.Id, Name = vv.Name, Desc = vv.Desc, Group = vv.Group, LinkAddress = vv.LinkAddress, TagType = (uint)vv.Type }); - - if(db.HisDatabase.HisTags.ContainsKey(vv.Id)) + if (cc >= from && cc < (from + PageCount)) { - var vvv = db.HisDatabase.HisTags[vv.Id]; - var vitem = new HisTagMessage() { Id = (uint)vv.Id, Type = (uint)vvv.Type, TagType = (uint)vvv.TagType, CompressType = (uint)vvv.CompressType,Circle=(ulong)vvv.Circle }; - if (vvv.Parameters != null && vvv.Parameters.Count > 0) + rre.Add(new RealTagMessage() { Id = (uint)vv.Id, Name = vv.Name, Desc = vv.Desc, Group = vv.Group, LinkAddress = vv.LinkAddress, TagType = (uint)vv.Type }); + + if (db.HisDatabase.HisTags.ContainsKey(vv.Id)) { - foreach (var vvp in vvv.Parameters) + var vvv = db.HisDatabase.HisTags[vv.Id]; + var vitem = new HisTagMessage() { Id = (uint)vv.Id, Type = (uint)vvv.Type, TagType = (uint)vvv.TagType, CompressType = (uint)vvv.CompressType, Circle = (ulong)vvv.Circle }; + if (vvv.Parameters != null && vvv.Parameters.Count > 0) { - vitem.Parameter.Add(new hisTagParameterItem() { Name = vvp.Key, Value = vvp.Value }); + foreach (var vvp in vvv.Parameters) + { + vitem.Parameter.Add(new hisTagParameterItem() { Name = vvp.Key, Value = vvp.Value }); + } } + re.Add(vitem); } - re.Add(vitem); } + cc++; } } - var msg = new GetTagMessageReply() { Result = true }; + var msg = new GetTagMessageReply() { Result = true,Count= totalpage, Index=request.Index }; msg.RealTag.AddRange(rre); msg.HisTag.AddRange(re); return Task.FromResult(msg); @@ -497,28 +512,41 @@ namespace DBDevelopService List rre = new List(); List re = new List(); + int totalpage = 0; if (db != null) { - foreach (var vv in db.RealDatabase.ListAllTags()) - { - rre.Add(new RealTagMessage() { Id = (uint)vv.Id, Name = vv.Name, Desc = vv.Desc, Group = vv.Group, LinkAddress = vv.LinkAddress, TagType = (uint)vv.Type }); + int from = request.Index * PageCount; + var res = db.RealDatabase.ListAllTags(); + var total = res.Count(); + + totalpage = total / PageCount; + totalpage = total % PageCount > 0 ? totalpage + 1 : totalpage; + int cc = 0; - if (db.HisDatabase.HisTags.ContainsKey(vv.Id)) + foreach (var vv in res) + { + if (cc >= from && cc < (from + PageCount)) { - var vvv = db.HisDatabase.HisTags[vv.Id]; - var vitem = new HisTagMessage() { Id = (uint)vv.Id, Type = (uint)vv.Type, TagType = (uint)vvv.TagType, CompressType = (uint)vvv.CompressType, Circle = (ulong)vvv.Circle }; - if (vvv.Parameters != null && vvv.Parameters.Count > 0) + rre.Add(new RealTagMessage() { Id = (uint)vv.Id, Name = vv.Name, Desc = vv.Desc, Group = vv.Group, LinkAddress = vv.LinkAddress, TagType = (uint)vv.Type }); + + if (db.HisDatabase.HisTags.ContainsKey(vv.Id)) { - foreach (var vvp in vvv.Parameters) + var vvv = db.HisDatabase.HisTags[vv.Id]; + var vitem = new HisTagMessage() { Id = (uint)vv.Id, Type = (uint)vv.Type, TagType = (uint)vvv.TagType, CompressType = (uint)vvv.CompressType, Circle = (ulong)vvv.Circle }; + if (vvv.Parameters != null && vvv.Parameters.Count > 0) { - vitem.Parameter.Add(new hisTagParameterItem() { Name = vvp.Key, Value = vvp.Value }); + foreach (var vvp in vvv.Parameters) + { + vitem.Parameter.Add(new hisTagParameterItem() { Name = vvp.Key, Value = vvp.Value }); + } } + re.Add(vitem); } - re.Add(vitem); } + cc++; } } - var msg = new GetTagMessageReply() { Result = true }; + var msg = new GetTagMessageReply() { Result = true, Count = totalpage, Index = request.Index }; msg.RealTag.AddRange(rre); msg.HisTag.AddRange(re); return Task.FromResult(msg); @@ -779,7 +807,7 @@ namespace DBDevelopService } catch(Exception ex) { - return Task.FromResult(new BoolResultReplay() { Result = true,ErroMessage = ex.Message }); + return Task.FromResult(new BoolResultReplay() { Result = false,ErroMessage = ex.Message }); } } @@ -804,11 +832,11 @@ namespace DBDevelopService { db.RealDatabase.AddOrUpdate(tag); } - return Task.FromResult(new BoolResultReplay() { Result = false }); + return Task.FromResult(new BoolResultReplay() { Result = true }); } catch(Exception ex) { - return Task.FromResult(new BoolResultReplay() { Result = true, ErroMessage = ex.Message }); + return Task.FromResult(new BoolResultReplay() { Result = false, ErroMessage = ex.Message }); } } @@ -889,33 +917,27 @@ namespace DBDevelopService Cdy.Tag.Tagbase tag = GetRealTag(request.RealTag); - db.RealDatabase.Append(tag); + db.RealDatabase.AddOrUpdate(tag); var vtag = request.HisTag; if (vtag.Id != uint.MaxValue) { - if (db.HisDatabase.HisTags.ContainsKey(tag.Id)) + Cdy.Tag.HisTag hisTag = new Cdy.Tag.HisTag(); + hisTag.Id = (int)vtag.Id; + hisTag.TagType = (Cdy.Tag.TagType)(vtag.TagType); + hisTag.Type = (Cdy.Tag.RecordType)(vtag.Type); + hisTag.CompressType = (int)(vtag.CompressType); + + hisTag.Parameters = new Dictionary(); + if (vtag.Parameter != null) { - Cdy.Tag.HisTag hisTag = new Cdy.Tag.HisTag(); - hisTag.Id = (int)vtag.Id; - hisTag.TagType = (Cdy.Tag.TagType)(vtag.TagType); - hisTag.Type = (Cdy.Tag.RecordType)(vtag.Type); - hisTag.CompressType = (int)(vtag.CompressType); - - hisTag.Parameters = new Dictionary(); - if (vtag.Parameter != null) + foreach (var vv in vtag.Parameter) { - foreach (var vv in vtag.Parameter) - { - hisTag.Parameters.Add(vv.Name, vv.Value); - } + hisTag.Parameters.Add(vv.Name, vv.Value); } - - //hisTag.CompressParameter1 = vtag.CompressParameter1; - //hisTag.CompressParameter2 = vtag.CompressParameter2; - //hisTag.CompressParameter3 = vtag.CompressParameter3; - db.HisDatabase.AddOrUpdate(hisTag); } + + db.HisDatabase.AddOrUpdate(hisTag); } return Task.FromResult(new AddTagReplyMessage() { Result = true, TagId = tag.Id }); } diff --git a/DBHisData/HisQuery/DataFileManager.cs b/DBHisData/HisQuery/DataFileManager.cs index af42805..bb38368 100644 --- a/DBHisData/HisQuery/DataFileManager.cs +++ b/DBHisData/HisQuery/DataFileManager.cs @@ -96,7 +96,7 @@ namespace Cdy.Tag public async Task Int() { await Scan(GetPrimaryHisDataPath()); - await Scan(GetBackHisDataPath()); + //await Scan(GetBackHisDataPath()); } /// @@ -162,8 +162,7 @@ namespace Cdy.Tag DateTime startTime = new DateTime(yy, mm, dd, hh, 0, 0); YearTimeFile yt = new YearTimeFile() { TimeKey = yy }; - yt.AddFile(startTime, new TimeSpan(hhspan, 0, 0), new DataFileInfo() { Duration = new TimeSpan(hhspan, 0, 0), StartTime = startTime, FileName = file.FullName } ); - + if(mTimeFileMaps.ContainsKey(id)) { if (mTimeFileMaps[id].ContainsKey(yy)) @@ -180,6 +179,7 @@ namespace Cdy.Tag mTimeFileMaps.Add(id, new Dictionary()); mTimeFileMaps[id].Add(yy, yt); } + yt.AddFile(startTime, new TimeSpan(hhspan, 0, 0), new DataFileInfo() { Duration = new TimeSpan(hhspan, 0, 0), StartTime = startTime, FileName = file.FullName }); } /// diff --git a/DBHisData/HisQuery/QuerySerivce.cs b/DBHisData/HisQuery/QuerySerivce.cs index facdd8a..8f0c059 100644 --- a/DBHisData/HisQuery/QuerySerivce.cs +++ b/DBHisData/HisQuery/QuerySerivce.cs @@ -72,7 +72,7 @@ namespace Cdy.Tag mPreFile = null; mtime.Clear(); } - result.Add(false, vv.Key, (byte)QulityConst.Null); + result.Add(false, vv.Key, (byte)QualityConst.Null); } else if (vv.Value != mPreFile) { @@ -117,7 +117,7 @@ namespace Cdy.Tag mPreFile = null; mtime.Clear(); } - result.Add((byte)0, vv.Key, (byte)QulityConst.Null); + result.Add((byte)0, vv.Key, (byte)QualityConst.Null); } else if (vv.Value != mPreFile) { @@ -163,7 +163,7 @@ namespace Cdy.Tag mPreFile = null; mtime.Clear(); } - result.Add((short)0, vv.Key, (byte)QulityConst.Null); + result.Add((short)0, vv.Key, (byte)QualityConst.Null); } else if (vv.Value != mPreFile) { @@ -208,7 +208,7 @@ namespace Cdy.Tag mPreFile = null; mtime.Clear(); } - result.Add((ushort)0, vv.Key, (byte)QulityConst.Null); + result.Add((ushort)0, vv.Key, (byte)QualityConst.Null); } else if (vv.Value != mPreFile) { @@ -253,7 +253,7 @@ namespace Cdy.Tag mPreFile = null; mtime.Clear(); } - result.Add((int)0, vv.Key, (byte)QulityConst.Null); + result.Add((int)0, vv.Key, (byte)QualityConst.Null); } else if (vv.Value != mPreFile) { @@ -298,7 +298,7 @@ namespace Cdy.Tag mPreFile = null; mtime.Clear(); } - result.Add((uint)0, vv.Key, (byte)QulityConst.Null); + result.Add((uint)0, vv.Key, (byte)QualityConst.Null); } else if (vv.Value != mPreFile) { @@ -343,7 +343,7 @@ namespace Cdy.Tag mPreFile = null; mtime.Clear(); } - result.Add((ulong)0, vv.Key, (byte)QulityConst.Null); + result.Add((ulong)0, vv.Key, (byte)QualityConst.Null); } else if (vv.Value != mPreFile) { @@ -389,7 +389,7 @@ namespace Cdy.Tag mtime.Clear(); } - result.Add((long)0, vv.Key, (byte)QulityConst.Null); + result.Add((long)0, vv.Key, (byte)QualityConst.Null); } else if (vv.Value != mPreFile) { @@ -436,7 +436,7 @@ namespace Cdy.Tag mtime.Clear(); } - result.Add((float)0, vv.Key, (byte)QulityConst.Null); + result.Add((float)0, vv.Key, (byte)QualityConst.Null); } else if (vv.Value != mPreFile) { @@ -482,7 +482,7 @@ namespace Cdy.Tag mtime.Clear(); } - result.Add((double)0, vv.Key, (byte)QulityConst.Null); + result.Add((double)0, vv.Key, (byte)QualityConst.Null); } else if (vv.Value != mPreFile) { @@ -527,7 +527,7 @@ namespace Cdy.Tag mPreFile = null; mtime.Clear(); } - result.Add(DateTime.Now, vv.Key, (byte)QulityConst.Null); + result.Add(DateTime.Now, vv.Key, (byte)QualityConst.Null); } else if (vv.Value != mPreFile) { @@ -572,7 +572,7 @@ namespace Cdy.Tag mPreFile = null; mtime.Clear(); } - result.Add("", vv.Key, (byte)QulityConst.Null); + result.Add("", vv.Key, (byte)QualityConst.Null); } else if (vv.Value != mPreFile) { diff --git a/DBHisData/HisQuery/TimeFile/DataFileInfo.cs b/DBHisData/HisQuery/TimeFile/DataFileInfo.cs index ad3a6ab..da5dc2e 100644 --- a/DBHisData/HisQuery/TimeFile/DataFileInfo.cs +++ b/DBHisData/HisQuery/TimeFile/DataFileInfo.cs @@ -1048,6 +1048,7 @@ namespace Cdy.Tag foreach (var vv in times) { var ff = file.GetFileOffsets(vv); + if (ff <= 0) continue; if (moffs.ContainsKey(ff)) { moffs[ff].Add(vv); @@ -2554,6 +2555,17 @@ namespace Cdy.Tag { //Tag id 列表经过压缩,内容格式为:DataSize + Data var dsize = datafile.ReadInt(dataoffset); + + if (dsize <= 0) + { + tagCount = 0; + fileDuration = 0; + blockDuration = 0; + timetick = 0; + blockPointer = 0; + return new Dictionary(); + } + dataoffset += 4; blockPointer = dataoffset + dsize - offset; @@ -2748,10 +2760,12 @@ namespace Cdy.Tag int fileDuration, blockDuration = 0; int tagCount = 0; long blockpointer = 0; - var blockIndex = datafile.ReadTagIndexInDataPointer(tid, offset, out tagCount, out fileDuration, out blockDuration, out timetick,out blockpointer); + + var tagIndex = datafile.ReadTagIndexInDataPointer(tid, offset, out tagCount, out fileDuration, out blockDuration, out timetick,out blockpointer); + int blockcount = fileDuration * 60 / blockDuration; - var startTime = datafile.ReadDateTime(16); + var startTime = datafile.ReadDateTime(0); Dictionary rtmp = new Dictionary(); @@ -2760,46 +2774,60 @@ namespace Cdy.Tag foreach (var vdd in dataTimes) { var ttmp = (vdd - startTime).TotalMinutes; - int dindex = (int)(ttmp / blockDuration); - if (ttmp % blockDuration > 0) - { - dindex++; - } + int blockindex = (int)(ttmp / blockDuration); + //if (ttmp % blockDuration > 0) + //{ + // blockindex++; + //} - if (dindex > blockcount) + if (blockindex > blockcount) { throw new Exception("DataPointer index is out of total block number"); } - var dataPointer = datafile.ReadLong(blockIndex * 8 + dindex * tagCount * 8); //读取DataBlock的地址 - var datasize = datafile.ReadInt(dataPointer); //读取DataBlock 的大小 + var dataPointer = datafile.ReadLong(offset + blockpointer + tagIndex * 8 + blockindex * tagCount * 8); //读取DataBlock的地址 - if (!rtmp.ContainsKey(dataPointer)) - { - var rmm = datafile.Read(dataPointer, datasize); - if (!re.ContainsKey(rmm)) - { - re.Add(rmm, new List() { vdd }); - } - else - { - re[rmm].Add(vdd); - } - rtmp.Add(dataPointer, rmm); - } - else + if (dataPointer > 0) { - var rmm = rtmp[dataPointer]; - if (!re.ContainsKey(rmm)) - { - re.Add(rmm, new List() { vdd }); - } - else + var datasize = datafile.ReadInt(dataPointer); //读取DataBlock 的大小 + if (datasize > 0) { - re[rmm].Add(vdd); + //var rmm = datafile.Read(dataPointer + 4, (int)datasize); + //if (!re.ContainsKey(rmm)) + //{ + // re.Add(rmm, new Tuple(sstart, end)); + //} + + if (!rtmp.ContainsKey(dataPointer)) + { + var rmm = datafile.Read(dataPointer + 4, datasize); + if (!re.ContainsKey(rmm)) + { + re.Add(rmm, new List() { vdd }); + } + else + { + re[rmm].Add(vdd); + } + rtmp.Add(dataPointer, rmm); + } + else + { + var rmm = rtmp[dataPointer]; + if (!re.ContainsKey(rmm)) + { + re.Add(rmm, new List() { vdd }); + } + else + { + re[rmm].Add(vdd); + } + } } + } + } return re; } @@ -2834,7 +2862,7 @@ namespace Cdy.Tag while (sstart < end) { var ttmp = (sstart - startTime).TotalMinutes; - send = sstart.AddMinutes(blockDuration); + send = (sstart - new TimeSpan(0, 0, 0, sstart.Second, sstart.Millisecond)).AddMinutes(blockDuration); if (send > end) { send = end; diff --git a/DBHisData/HisQuery/TimeFile/YearTimeFile.cs b/DBHisData/HisQuery/TimeFile/YearTimeFile.cs index e916219..a2ae573 100644 --- a/DBHisData/HisQuery/TimeFile/YearTimeFile.cs +++ b/DBHisData/HisQuery/TimeFile/YearTimeFile.cs @@ -76,8 +76,15 @@ namespace Cdy.Tag /// public MonthTimeFile AddMonth(int month, MonthTimeFile file) { - file.Parent = this; - return this.AddTimefile(month, file) as MonthTimeFile; + if (this.ContainsKey(month)) + { + return this[month] as MonthTimeFile; + } + else + { + file.Parent = this; + return this.AddTimefile(month, file) as MonthTimeFile; + } } /// diff --git a/DBInRun/Program.cs b/DBInRun/Program.cs index d2b41d1..0ebadbf 100644 --- a/DBInRun/Program.cs +++ b/DBInRun/Program.cs @@ -119,14 +119,40 @@ namespace DBInRun Cdy.Tag.RealDatabase test = db.RealDatabase; db.RealDatabase = test; + string address = ""; + for (int i=0;i skey.Value.Item1 && time < snext.Value.Item1) { switch (type) { case QueryValueMatchType.Previous: - return source.ReadDateTime(valaddr + i); + return source.ReadDateTime(valaddr + i*8); case QueryValueMatchType.After: - return source.ReadDateTime(valaddr + i + 1); + return source.ReadDateTime(valaddr + (i + 1) * 8); case QueryValueMatchType.Linear: case QueryValueMatchType.Closed: var pval = (time - skey.Value.Item1).TotalMilliseconds; var fval = (snext.Value.Item1 - time).TotalMilliseconds; if (pval < fval) { - return source.ReadDateTime(valaddr + i); + return source.ReadDateTime(valaddr + i*8); } else { - return source.ReadDateTime(valaddr + i + 1); + return source.ReadDateTime(valaddr + (i + 1) * 8); } } } else if (time == snext.Value.Item1) { - return source.ReadDateTime(valaddr + i + 1); + return source.ReadDateTime(valaddr + (i + 1) * 8); } } @@ -1226,7 +1226,7 @@ namespace Cdy.Tag if (time1 == skey.Value.Item1) { - var val = source.ReadDateTime(valaddr + i); + var val = source.ReadDateTime(valaddr + i*8); result.Add(val, time1, qq[skey.Key]); count++; break; @@ -1237,13 +1237,13 @@ namespace Cdy.Tag switch (type) { case QueryValueMatchType.Previous: - var val = source.ReadDateTime(valaddr + i); + var val = source.ReadDateTime(valaddr + i * 8); result.Add(val, time1, qq[skey.Key]); count++; break; case QueryValueMatchType.After: - val = source.ReadDateTime(valaddr + i + 1); + val = source.ReadDateTime(valaddr + (i + 1)*8); result.Add(val, time1, qq[snext.Key]); count++; break; @@ -1255,13 +1255,13 @@ namespace Cdy.Tag if (pval < fval) { - val = source.ReadDateTime(valaddr + i); + val = source.ReadDateTime(valaddr + i * 8); result.Add(val, time1, qq[skey.Key]); break; } else { - val = source.ReadDateTime(valaddr + i + 1); + val = source.ReadDateTime(valaddr + (i + 1) * 8); result.Add(val, time1, qq[snext.Key]); break; } @@ -1271,7 +1271,7 @@ namespace Cdy.Tag } else if (time1 == snext.Value.Item1) { - var val = source.ReadDateTime(valaddr + i + 1); + var val = source.ReadDateTime(valaddr + (i + 1) * 8); result.Add(val, time1, qq[snext.Key]); count++; break; @@ -1311,33 +1311,33 @@ namespace Cdy.Tag if (time == skey.Value.Item1) { - return source.ReadDouble(valaddr + i); + return source.ReadDouble(valaddr + i*8); } else if (time > skey.Value.Item1 && time < snext.Value.Item1) { switch (type) { case QueryValueMatchType.Previous: - return source.ReadDouble(valaddr + i); + return source.ReadDouble(valaddr + i * 8); case QueryValueMatchType.After: - return source.ReadDouble(valaddr + i + 1); + return source.ReadDouble(valaddr + (i + 1)*8); case QueryValueMatchType.Linear: if (qq[skey.Key] < 20 && qq[snext.Key] < 20) { var pval1 = (time1 - skey.Value.Item1).TotalMilliseconds; var tval1 = (snext.Value.Item1 - skey.Value.Item1).TotalMilliseconds; - var sval1 = source.ReadDouble(valaddr + i); - var sval2 = source.ReadDouble(valaddr + i + 1); + var sval1 = source.ReadDouble(valaddr + i * 8); + var sval2 = source.ReadDouble(valaddr + (i + 1) * 8); return (double)(pval1 / tval1 * (sval2 - sval1) + sval1); } else if (qq[skey.Key] < 20) { - return source.ReadDouble(valaddr + i); + return source.ReadDouble(valaddr + i * 8); } else if (qq[snext.Key] < 20) { - return source.ReadDouble(valaddr + i + 1); + return source.ReadDouble(valaddr + (i + 1) * 8); } break; @@ -1346,17 +1346,17 @@ namespace Cdy.Tag var fval = (snext.Value.Item1 - time).TotalMilliseconds; if (pval < fval) { - return source.ReadDouble(valaddr + i); + return source.ReadDouble(valaddr + i * 8); } else { - return source.ReadDouble(valaddr + i + 1); + return source.ReadDouble(valaddr + (i + 1) * 8); } } } else if (time == snext.Value.Item1) { - return source.ReadDouble(valaddr + i + 1); + return source.ReadDouble(valaddr + (i + 1) * 8); } } @@ -1365,6 +1365,16 @@ namespace Cdy.Tag } + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// public override int DeCompressDoubleValue(MarshalMemoryBlock source, int sourceAddr, List time, int timeTick, QueryValueMatchType type, HisQueryResult result) { DateTime stime; @@ -1387,7 +1397,7 @@ namespace Cdy.Tag if (time1 == skey.Value.Item1) { - var val = source.ReadDouble(valaddr + i); + var val = source.ReadDouble(valaddr + i*8); result.Add(val, time1, qq[skey.Key]); count++; break; @@ -1398,12 +1408,12 @@ namespace Cdy.Tag switch (type) { case QueryValueMatchType.Previous: - var val = source.ReadDouble(valaddr + i); + var val = source.ReadDouble(valaddr + i*8); result.Add(val, time1, qq[skey.Key]); count++; break; case QueryValueMatchType.After: - val = source.ReadDouble(valaddr + i + 1); + val = source.ReadDouble(valaddr + (i + 1)*8); result.Add(val, time1, qq[snext.Key]); count++; break; @@ -1412,24 +1422,24 @@ namespace Cdy.Tag { var pval1 = (time1 - skey.Value.Item1).TotalMilliseconds; var tval1 = (snext.Value.Item1 - skey.Value.Item1).TotalMilliseconds; - var sval1 = source.ReadDouble(valaddr + i); - var sval2 = source.ReadDouble(valaddr + i + 1); + var sval1 = source.ReadDouble(valaddr + i*8); + var sval2 = source.ReadDouble(valaddr + (i + 1)*8); var val1 = pval1 / tval1 * (sval2 - sval1) + sval1; result.Add(val1, time1, 0); } else if (qq[skey.Key] < 20) { - val = source.ReadDouble(valaddr + i); + val = source.ReadDouble(valaddr + i*8); result.Add(val, time1, qq[skey.Key]); } else if (qq[snext.Key] < 20) { - val = source.ReadDouble(valaddr + i + 1); + val = source.ReadDouble(valaddr + (i + 1)*8); result.Add(val, time1, qq[snext.Key]); } else { - result.Add(0, time1, (byte)QulityConst.Null); + result.Add(0, time1, (byte)QualityConst.Null); } count++; break; @@ -1439,12 +1449,12 @@ namespace Cdy.Tag if (pval < fval) { - val = source.ReadDouble(valaddr + i); + val = source.ReadDouble(valaddr + i*8); result.Add(val, time1, qq[skey.Key]); } else { - val = source.ReadDouble(valaddr + i + 1); + val = source.ReadDouble(valaddr + (i + 1)*8); result.Add(val, time1, qq[snext.Key]); } count++; @@ -1455,7 +1465,7 @@ namespace Cdy.Tag } else if (time1 == snext.Value.Item1) { - var val = source.ReadDouble(valaddr + i + 1); + var val = source.ReadDouble(valaddr + (i + 1)*8); result.Add(val, time1, qq[snext.Key]); count++; break; @@ -1486,33 +1496,33 @@ namespace Cdy.Tag if (time == skey.Value.Item1) { - return source.ReadFloat(valaddr + i); + return source.ReadFloat(valaddr + i*4); } else if (time > skey.Value.Item1 && time < snext.Value.Item1) { switch (type) { case QueryValueMatchType.Previous: - return source.ReadFloat(valaddr + i); + return source.ReadFloat(valaddr + i * 4); case QueryValueMatchType.After: - return source.ReadFloat(valaddr + i + 1); + return source.ReadFloat(valaddr + (i + 1)*4); case QueryValueMatchType.Linear: if (qq[skey.Key] < 20 && qq[snext.Key] < 20) { var pval1 = (time1 - skey.Value.Item1).TotalMilliseconds; var tval1 = (snext.Value.Item1 - skey.Value.Item1).TotalMilliseconds; - var sval1 = source.ReadFloat(valaddr + i); - var sval2 = source.ReadFloat(valaddr + i + 1); + var sval1 = source.ReadFloat(valaddr + i * 4); + var sval2 = source.ReadFloat(valaddr + (i + 1) * 4); return (float)(pval1 / tval1 * (sval2 - sval1) + sval1); } else if (qq[skey.Key] < 20) { - return source.ReadFloat(valaddr + i); + return source.ReadFloat(valaddr + i * 4); } else if (qq[snext.Key] < 20) { - return source.ReadFloat(valaddr + i + 1); + return source.ReadFloat(valaddr + (i + 1) * 4); } break; @@ -1521,17 +1531,17 @@ namespace Cdy.Tag var fval = (snext.Value.Item1 - time).TotalMilliseconds; if (pval < fval) { - return source.ReadFloat(valaddr + i); + return source.ReadFloat(valaddr + i * 4); } else { - return source.ReadFloat(valaddr + i + 1); + return source.ReadFloat(valaddr + (i + 1) * 4); } } } else if (time == snext.Value.Item1) { - return source.ReadFloat(valaddr + i + 1); + return source.ReadFloat(valaddr + (i + 1) * 4); } } @@ -1570,7 +1580,7 @@ namespace Cdy.Tag if (time1 == skey.Value.Item1) { - var val = source.ReadFloat(valaddr + i); + var val = source.ReadFloat(valaddr + i*4); result.Add(val, time1, qq[skey.Key]); count++; break; @@ -1581,12 +1591,12 @@ namespace Cdy.Tag switch (type) { case QueryValueMatchType.Previous: - var val = source.ReadFloat(valaddr + i); + var val = source.ReadFloat(valaddr + i * 4); result.Add(val, time1, qq[skey.Key]); count++; break; case QueryValueMatchType.After: - val = source.ReadFloat(valaddr + i + 1); + val = source.ReadFloat(valaddr + (i + 1) * 4); result.Add(val, time1, qq[snext.Key]); count++; break; @@ -1595,24 +1605,24 @@ namespace Cdy.Tag { var pval1 = (time1 - skey.Value.Item1).TotalMilliseconds; var tval1 = (snext.Value.Item1 - skey.Value.Item1).TotalMilliseconds; - var sval1 = source.ReadFloat(valaddr + i); - var sval2 = source.ReadFloat(valaddr + i + 1); - var val1 = (float)(pval1 / tval1 * (sval2 - sval1) + sval1); - result.Add(val1, time1, 0); + var sval1 = source.ReadFloat(valaddr + i * 4); + var sval2 = source.ReadFloat(valaddr + (i + 1) * 4); + var val1 = pval1 / tval1 * (sval2 - sval1) + sval1; + result.Add((float)val1, time1, 0); } else if (qq[skey.Key] < 20) { - val = source.ReadFloat(valaddr + i); + val = source.ReadFloat(valaddr + i * 4); result.Add(val, time1, qq[skey.Key]); } else if (qq[snext.Key] < 20) { - val = source.ReadFloat(valaddr + i + 1); + val = source.ReadFloat(valaddr + (i + 1) * 4); result.Add(val, time1, qq[snext.Key]); } else { - result.Add(0, time1, (byte)QulityConst.Null); + result.Add(0, time1, (byte)QualityConst.Null); } count++; break; @@ -1622,23 +1632,23 @@ namespace Cdy.Tag if (pval < fval) { - val = source.ReadFloat(valaddr + i); + val = source.ReadFloat(valaddr + i * 4); result.Add(val, time1, qq[skey.Key]); } else { - val = source.ReadFloat(valaddr + i + 1); + val = source.ReadFloat(valaddr + (i + 1) * 4); result.Add(val, time1, qq[snext.Key]); } count++; break; } - + break; } else if (time1 == snext.Value.Item1) { - var val = source.ReadFloat(valaddr + i + 1); + var val = source.ReadFloat(valaddr + (i + 1) * 4); result.Add(val, time1, qq[snext.Key]); count++; break; @@ -1677,33 +1687,33 @@ namespace Cdy.Tag if (time == skey.Value.Item1) { - return source.ReadInt(valaddr + i); + return source.ReadInt(valaddr + i * 4); } else if (time > skey.Value.Item1 && time < snext.Value.Item1) { switch (type) { case QueryValueMatchType.Previous: - return source.ReadInt(valaddr + i); + return source.ReadInt(valaddr + i * 4); case QueryValueMatchType.After: - return source.ReadInt(valaddr + i + 1); + return source.ReadInt(valaddr + (i + 1) * 4); case QueryValueMatchType.Linear: if (qq[skey.Key] < 20 && qq[snext.Key] < 20) { var pval1 = (time1 - skey.Value.Item1).TotalMilliseconds; var tval1 = (snext.Value.Item1 - skey.Value.Item1).TotalMilliseconds; - var sval1 = source.ReadInt(valaddr + i); - var sval2 = source.ReadInt(valaddr + i + 1); + var sval1 = source.ReadInt(valaddr + i * 4); + var sval2 = source.ReadInt(valaddr + (i + 1) * 4); return (int)(pval1 / tval1 * (sval2 - sval1) + sval1); } else if (qq[skey.Key] < 20) { - return source.ReadInt(valaddr + i); + return source.ReadInt(valaddr + i * 4); } else if (qq[snext.Key] < 20) { - return source.ReadInt(valaddr + i + 1); + return source.ReadInt(valaddr + (i + 1) * 4); } break; @@ -1712,17 +1722,17 @@ namespace Cdy.Tag var fval = (snext.Value.Item1 - time).TotalMilliseconds; if (pval < fval) { - return source.ReadInt(valaddr + i); + return source.ReadInt(valaddr + i*4); } else { - return source.ReadInt(valaddr + i + 1); + return source.ReadInt(valaddr + (i + 1) * 4); } } } else if (time == snext.Value.Item1) { - return source.ReadInt(valaddr + i + 1); + return source.ReadInt(valaddr + (i + 1) * 4); } } @@ -1761,7 +1771,7 @@ namespace Cdy.Tag if (time1 == skey.Value.Item1) { - var val = source.ReadInt(valaddr + i); + var val = source.ReadInt(valaddr + i*4); result.Add(val, time1, qq[skey.Key]); count++; break; @@ -1772,12 +1782,12 @@ namespace Cdy.Tag switch (type) { case QueryValueMatchType.Previous: - var val = source.ReadInt(valaddr + i); + var val = source.ReadInt(valaddr + i * 4); result.Add(val, time1, qq[skey.Key]); count++; break; case QueryValueMatchType.After: - val = source.ReadInt(valaddr + i + 1); + val = source.ReadInt(valaddr + (i + 1) * 4); result.Add(val, time1, qq[snext.Key]); count++; break; @@ -1786,24 +1796,24 @@ namespace Cdy.Tag { var pval1 = (time1 - skey.Value.Item1).TotalMilliseconds; var tval1 = (snext.Value.Item1 - skey.Value.Item1).TotalMilliseconds; - var sval1 = source.ReadInt(valaddr + i); - var sval2 = source.ReadInt(valaddr + i + 1); - var val1 = (int)(pval1 / tval1 * (sval2 - sval1) + sval1); - result.Add(val1, time1, 0); + var sval1 = source.ReadInt(valaddr + i * 4); + var sval2 = source.ReadInt(valaddr + (i + 1) * 4); + var val1 = pval1 / tval1 * (sval2 - sval1) + sval1; + result.Add((int)val1, time1, 0); } else if (qq[skey.Key] < 20) { - val = source.ReadInt(valaddr + i); + val = source.ReadInt(valaddr + i * 4); result.Add(val, time1, qq[skey.Key]); } else if (qq[snext.Key] < 20) { - val = source.ReadInt(valaddr + i + 1); + val = source.ReadInt(valaddr + (i + 1) * 4); result.Add(val, time1, qq[snext.Key]); } else { - result.Add(0, time1, (byte)QulityConst.Null); + result.Add(0, time1, (byte)QualityConst.Null); } count++; break; @@ -1813,22 +1823,23 @@ namespace Cdy.Tag if (pval < fval) { - val = source.ReadInt(valaddr + i); + val = source.ReadInt(valaddr + i * 4); result.Add(val, time1, qq[skey.Key]); } else { - val = source.ReadInt(valaddr + i + 1); + val = source.ReadInt(valaddr + (i + 1) * 4); result.Add(val, time1, qq[snext.Key]); } + count++; break; } - count++; + break; } else if (time1 == snext.Value.Item1) { - var val = source.ReadInt(valaddr + i + 1); + var val = source.ReadInt(valaddr + (i + 1) * 4); result.Add(val, time1, qq[snext.Key]); count++; break; @@ -1867,33 +1878,33 @@ namespace Cdy.Tag if (time == skey.Value.Item1) { - return source.ReadLong(valaddr + i); + return source.ReadLong(valaddr + i*8); } else if (time > skey.Value.Item1 && time < snext.Value.Item1) { switch (type) { case QueryValueMatchType.Previous: - return source.ReadLong(valaddr + i); + return source.ReadLong(valaddr + i * 8); case QueryValueMatchType.After: - return source.ReadLong(valaddr + i + 1); + return source.ReadLong(valaddr + (i + 1)*8); case QueryValueMatchType.Linear: if (qq[skey.Key] < 20 && qq[snext.Key] < 20) { var pval1 = (time1 - skey.Value.Item1).TotalMilliseconds; var tval1 = (snext.Value.Item1 - skey.Value.Item1).TotalMilliseconds; - var sval1 = source.ReadLong(valaddr + i); - var sval2 = source.ReadLong(valaddr + i + 1); + var sval1 = source.ReadLong(valaddr + i * 8); + var sval2 = source.ReadLong(valaddr + (i + 1) * 8); return (long)(pval1 / tval1 * (sval2 - sval1) + sval1); } else if (qq[skey.Key] < 20) { - return source.ReadLong(valaddr + i); + return source.ReadLong(valaddr + i * 8); } else if (qq[snext.Key] < 20) { - return source.ReadLong(valaddr + i + 1); + return source.ReadLong(valaddr + (i + 1) * 8); } break; @@ -1902,89 +1913,21 @@ namespace Cdy.Tag var fval = (snext.Value.Item1 - time).TotalMilliseconds; if (pval < fval) { - return source.ReadLong(valaddr + i); + return source.ReadLong(valaddr + i * 8); } else { - return source.ReadLong(valaddr + i + 1); + return source.ReadLong(valaddr + (i + 1) * 8); } } } else if (time == snext.Value.Item1) { - return source.ReadLong(valaddr + i + 1); + return source.ReadLong(valaddr + (i + 1) * 8); } } return null; - - //DateTime time1; - //int valuecount = 0; - //var qs = ReadTimeQulity(source, sourceAddr, timeTick, out valuecount, out time1); - //var qq = source.ReadBytes(qs.Count * 10, qs.Count); - - //var valaddr = qs.Count * 2; - - //var vv = qs.ToArray(); - - //for (int i = 0; i < vv.Length - 1; i++) - //{ - // var skey = vv[i]; - - // var snext = vv[i + 1]; - - // if (time == skey.Key) - // { - // return source.ReadInt(valaddr + i); - // } - // else if (time > skey.Key && time < snext.Key) - // { - // switch (type) - // { - // case QueryValueMatchType.Previous: - // return source.ReadLong(valaddr + i); - // case QueryValueMatchType.After: - // return source.ReadLong(valaddr + i + 1); - // case QueryValueMatchType.Linear: - - // if (qq[skey.Value] < 20 && qq[snext.Value] < 20) - // { - // var pval1 = (time1 - skey.Key).TotalMilliseconds; - // var tval1 = (snext.Key - skey.Key).TotalMilliseconds; - // var sval1 = source.ReadLong(valaddr + i); - // var sval2 = source.ReadLong(valaddr + i + 1); - // return (long)(pval1 / tval1 * (sval2 - sval1) + sval1); - // } - // else if (qq[skey.Value] < 20) - // { - // return source.ReadLong(valaddr + i); - // } - // else if (qq[snext.Value] < 20) - // { - // return source.ReadLong(valaddr + i + 1); - // } - // break; - - // case QueryValueMatchType.Closed: - // var pval = (time - skey.Key).TotalMilliseconds; - // var fval = (snext.Key - time).TotalMilliseconds; - // if (pval < fval) - // { - // return source.ReadLong(valaddr + i); - // } - // else - // { - // return source.ReadLong(valaddr + i + 1); - // } - // } - // } - // else if (time == snext.Key) - // { - // return source.ReadLong(valaddr + i + 1); - // } - - //} - //return null; } /// @@ -2019,7 +1962,7 @@ namespace Cdy.Tag if (time1 == skey.Value.Item1) { - var val = source.ReadLong(valaddr + i); + var val = source.ReadLong(valaddr + i*8); result.Add(val, time1, qq[skey.Key]); count++; break; @@ -2030,12 +1973,12 @@ namespace Cdy.Tag switch (type) { case QueryValueMatchType.Previous: - var val = source.ReadLong(valaddr + i); + var val = source.ReadLong(valaddr + i * 8); result.Add(val, time1, qq[skey.Key]); count++; break; case QueryValueMatchType.After: - val = source.ReadLong(valaddr + i + 1); + val = source.ReadLong(valaddr + (i + 1) * 8); result.Add(val, time1, qq[snext.Key]); count++; break; @@ -2044,24 +1987,24 @@ namespace Cdy.Tag { var pval1 = (time1 - skey.Value.Item1).TotalMilliseconds; var tval1 = (snext.Value.Item1 - skey.Value.Item1).TotalMilliseconds; - var sval1 = source.ReadLong(valaddr + i); - var sval2 = source.ReadLong(valaddr + i + 1); - var val1 = (long)(pval1 / tval1 * (sval2 - sval1) + sval1); - result.Add(val1, time1, 0); + var sval1 = source.ReadLong(valaddr + i * 8); + var sval2 = source.ReadLong(valaddr + (i + 1) * 8); + var val1 = pval1 / tval1 * (sval2 - sval1) + sval1; + result.Add((long)val1, time1, 0); } else if (qq[skey.Key] < 20) { - val = source.ReadLong(valaddr + i); + val = source.ReadLong(valaddr + i * 8); result.Add(val, time1, qq[skey.Key]); } else if (qq[snext.Key] < 20) { - val = source.ReadLong(valaddr + i + 1); + val = source.ReadLong(valaddr + (i + 1) * 8); result.Add(val, time1, qq[snext.Key]); } else { - result.Add(0, time1, (byte)QulityConst.Null); + result.Add(0, time1, (byte)QualityConst.Null); } count++; break; @@ -2071,23 +2014,23 @@ namespace Cdy.Tag if (pval < fval) { - val = source.ReadLong(valaddr + i); + val = source.ReadLong(valaddr + i * 8); result.Add(val, time1, qq[skey.Key]); } else { - val = source.ReadLong(valaddr + i + 1); + val = source.ReadLong(valaddr + (i + 1) * 8); result.Add(val, time1, qq[snext.Key]); } count++; break; } - + break; } else if (time1 == snext.Value.Item1) { - var val = source.ReadLong(valaddr + i + 1); + var val = source.ReadLong(valaddr + (i + 1) * 8); result.Add(val, time1, qq[snext.Key]); count++; break; @@ -2097,7 +2040,7 @@ namespace Cdy.Tag } return count; - + } /// @@ -2128,33 +2071,33 @@ namespace Cdy.Tag if (time == skey.Value.Item1) { - return source.ReadShort(valaddr + i); + return source.ReadShort(valaddr + i*2); } else if (time > skey.Value.Item1 && time < snext.Value.Item1) { switch (type) { case QueryValueMatchType.Previous: - return source.ReadShort(valaddr + i); + return source.ReadShort(valaddr + i * 2); case QueryValueMatchType.After: - return source.ReadShort(valaddr + i + 1); + return source.ReadShort(valaddr + (i + 1)*2); case QueryValueMatchType.Linear: if (qq[skey.Key] < 20 && qq[snext.Key] < 20) { var pval1 = (time1 - skey.Value.Item1).TotalMilliseconds; var tval1 = (snext.Value.Item1 - skey.Value.Item1).TotalMilliseconds; - var sval1 = source.ReadShort(valaddr + i); - var sval2 = source.ReadShort(valaddr + i + 1); + var sval1 = source.ReadShort(valaddr + i * 2); + var sval2 = source.ReadShort(valaddr + (i + 1) * 2); return (short)(pval1 / tval1 * (sval2 - sval1) + sval1); } else if (qq[skey.Key] < 20) { - return source.ReadShort(valaddr + i); + return source.ReadShort(valaddr + i * 2); } else if (qq[snext.Key] < 20) { - return source.ReadShort(valaddr + i + 1); + return source.ReadShort(valaddr + (i + 1) * 2); } break; @@ -2163,89 +2106,21 @@ namespace Cdy.Tag var fval = (snext.Value.Item1 - time).TotalMilliseconds; if (pval < fval) { - return source.ReadShort(valaddr + i); + return source.ReadShort(valaddr + i * 2); } else { - return source.ReadShort(valaddr + i + 1); + return source.ReadShort(valaddr + (i + 1) * 2); } } } else if (time == snext.Value.Item1) { - return source.ReadShort(valaddr + i + 1); + return source.ReadShort(valaddr + (i + 1) * 2); } } return null; - - //DateTime time1; - //int valuecount = 0; - //var qs = ReadTimeQulity(source, sourceAddr, timeTick, out valuecount, out time1); - //var qq = source.ReadBytes(qs.Count * 4, qs.Count); - - //var valaddr = qs.Count * 2; - - //var vv = qs.ToArray(); - - //for (int i = 0; i < vv.Length - 1; i++) - //{ - // var skey = vv[i]; - - // var snext = vv[i + 1]; - - // if (time == skey.Key) - // { - // return source.ReadShort(valaddr + i); - // } - // else if (time > skey.Key && time < snext.Key) - // { - // switch (type) - // { - // case QueryValueMatchType.Previous: - // return source.ReadShort(valaddr + i); - // case QueryValueMatchType.After: - // return source.ReadShort(valaddr + i + 1); - // case QueryValueMatchType.Linear: - - // if (qq[skey.Value] < 20 && qq[snext.Value] < 20) - // { - // var pval1 = (time1 - skey.Key).TotalMilliseconds; - // var tval1 = (snext.Key - skey.Key).TotalMilliseconds; - // var sval1 = source.ReadShort(valaddr + i); - // var sval2 = source.ReadShort(valaddr + i + 1); - // return (short)(pval1 / tval1 * (sval2 - sval1) + sval1); - // } - // else if (qq[skey.Value] < 20) - // { - // return source.ReadShort(valaddr + i); - // } - // else if (qq[snext.Value] < 20) - // { - // return source.ReadShort(valaddr + i + 1); - // } - // break; - - // case QueryValueMatchType.Closed: - // var pval = (time - skey.Key).TotalMilliseconds; - // var fval = (snext.Key - time).TotalMilliseconds; - // if (pval < fval) - // { - // return source.ReadShort(valaddr + i); - // } - // else - // { - // return source.ReadShort(valaddr + i + 1); - // } - // } - // } - // else if (time == snext.Key) - // { - // return source.ReadShort(valaddr + i + 1); - // } - - //} - //return null; } /// @@ -2260,6 +2135,7 @@ namespace Cdy.Tag /// public override int DeCompressShortValue(MarshalMemoryBlock source, int sourceAddr, List time, int timeTick, QueryValueMatchType type, HisQueryResult result) { + DateTime stime; int valuecount = 0; var qs = ReadTimeQulity(source, sourceAddr, timeTick, out valuecount, out stime); @@ -2280,7 +2156,7 @@ namespace Cdy.Tag if (time1 == skey.Value.Item1) { - var val = source.ReadShort(valaddr + i); + var val = source.ReadShort(valaddr + i*2); result.Add(val, time1, qq[skey.Key]); count++; break; @@ -2291,12 +2167,12 @@ namespace Cdy.Tag switch (type) { case QueryValueMatchType.Previous: - var val = source.ReadShort(valaddr + i); + var val = source.ReadShort(valaddr + i * 2); result.Add(val, time1, qq[skey.Key]); count++; break; case QueryValueMatchType.After: - val = source.ReadShort(valaddr + i + 1); + val = source.ReadShort(valaddr + (i + 1) * 2); result.Add(val, time1, qq[snext.Key]); count++; break; @@ -2305,24 +2181,24 @@ namespace Cdy.Tag { var pval1 = (time1 - skey.Value.Item1).TotalMilliseconds; var tval1 = (snext.Value.Item1 - skey.Value.Item1).TotalMilliseconds; - var sval1 = source.ReadShort(valaddr + i); - var sval2 = source.ReadShort(valaddr + i + 1); - var val1 = (short)(pval1 / tval1 * (sval2 - sval1) + sval1); - result.Add(val1, time1, 0); + var sval1 = source.ReadShort(valaddr + i * 2); + var sval2 = source.ReadShort(valaddr + (i + 1) * 2); + var val1 = pval1 / tval1 * (sval2 - sval1) + sval1; + result.Add((short)val1, time1, 0); } else if (qq[skey.Key] < 20) { - val = source.ReadShort(valaddr + i); + val = source.ReadShort(valaddr + i * 2); result.Add(val, time1, qq[skey.Key]); } else if (qq[snext.Key] < 20) { - val = source.ReadShort(valaddr + i + 1); + val = source.ReadShort(valaddr + (i + 1) * 2); result.Add(val, time1, qq[snext.Key]); } else { - result.Add(0, time1, (byte)QulityConst.Null); + result.Add(0, time1, (byte)QualityConst.Null); } count++; break; @@ -2332,22 +2208,23 @@ namespace Cdy.Tag if (pval < fval) { - val = source.ReadShort(valaddr + i); + val = source.ReadShort(valaddr + i * 2); result.Add(val, time1, qq[skey.Key]); } else { - val = source.ReadShort(valaddr + i + 1); + val = source.ReadShort(valaddr + (i + 1) * 2); result.Add(val, time1, qq[snext.Key]); } + count++; break; } - count++; + break; } else if (time1 == snext.Value.Item1) { - var val = source.ReadShort(valaddr + i + 1); + var val = source.ReadShort(valaddr + (i + 1) * 2); result.Add(val, time1, qq[snext.Key]); count++; break; @@ -2356,6 +2233,8 @@ namespace Cdy.Tag } } return count; + + } /// @@ -2437,13 +2316,14 @@ namespace Cdy.Tag /// public override int DeCompressStringValue(MarshalMemoryBlock source, int sourceAddr, List time, int timeTick, QueryValueMatchType type, HisQueryResult result) { + DateTime stime; int valuecount = 0; var qs = ReadTimeQulity(source, sourceAddr, timeTick, out valuecount, out stime); //var dtmp = source.ToStringList(sourceAddr + 12, Encoding.Unicode); - var valaddr = qs.Count * 2+sourceAddr; + var valaddr = qs.Count * 2 + sourceAddr; Dictionary dtmp = new Dictionary(); source.Position = valaddr; @@ -2548,33 +2428,33 @@ namespace Cdy.Tag if (time == skey.Value.Item1) { - return source.ReadUInt(valaddr + i); + return source.ReadUInt(valaddr + i*4); } else if (time > skey.Value.Item1 && time < snext.Value.Item1) { switch (type) { case QueryValueMatchType.Previous: - return source.ReadUInt(valaddr + i); + return source.ReadUInt(valaddr + i * 4); case QueryValueMatchType.After: - return source.ReadUInt(valaddr + i + 1); + return source.ReadUInt(valaddr + (i + 1)*4); case QueryValueMatchType.Linear: if (qq[skey.Key] < 20 && qq[snext.Key] < 20) { var pval1 = (time1 - skey.Value.Item1).TotalMilliseconds; var tval1 = (snext.Value.Item1 - skey.Value.Item1).TotalMilliseconds; - var sval1 = source.ReadUInt(valaddr + i); - var sval2 = source.ReadUInt(valaddr + i + 1); + var sval1 = source.ReadUInt(valaddr + i * 4); + var sval2 = source.ReadUInt(valaddr + (i + 1) * 4); return (uint)(pval1 / tval1 * (sval2 - sval1) + sval1); } else if (qq[skey.Key] < 20) { - return source.ReadUInt(valaddr + i); + return source.ReadUInt(valaddr + i * 4); } else if (qq[snext.Key] < 20) { - return source.ReadUInt(valaddr + i + 1); + return source.ReadUInt(valaddr + (i + 1) * 4); } break; @@ -2583,90 +2463,21 @@ namespace Cdy.Tag var fval = (snext.Value.Item1 - time).TotalMilliseconds; if (pval < fval) { - return source.ReadUInt(valaddr + i); + return source.ReadUInt(valaddr + i * 4); } else { - return source.ReadUInt(valaddr + i + 1); + return source.ReadUInt(valaddr + (i + 1) * 4); } } } else if (time == snext.Value.Item1) { - return source.ReadUInt(valaddr + i + 1); + return source.ReadUInt(valaddr + (i + 1) * 4); } } return null; - - //DateTime time1; - //int valuecount = 0; - //var qs = ReadTimeQulity(source, sourceAddr, timeTick, out valuecount, out time1); - //var qq = source.ReadBytes(qs.Count * 6, qs.Count); - - //var valaddr = qs.Count * 2; - - //var vv = qs.ToArray(); - - //for (int i = 0; i < vv.Length - 1; i++) - //{ - // var skey = vv[i]; - - // var snext = vv[i + 1]; - - // if (time == skey.Key) - // { - // return source.ReadUInt(valaddr + i); - // } - // else if (time > skey.Key && time < snext.Key) - // { - // switch (type) - // { - // case QueryValueMatchType.Previous: - // return source.ReadUInt(valaddr + i); - // case QueryValueMatchType.After: - // return source.ReadUInt(valaddr + i + 1); - // case QueryValueMatchType.Linear: - - // if (qq[skey.Value] < 20 && qq[snext.Value] < 20) - // { - // var pval1 = (time1 - skey.Key).TotalMilliseconds; - // var tval1 = (snext.Key - skey.Key).TotalMilliseconds; - // var sval1 = source.ReadUInt(valaddr + i); - // var sval2 = source.ReadUInt(valaddr + i + 1); - // return (uint)(pval1 / tval1 * (sval2 - sval1) + sval1); - // } - // else if (qq[skey.Value] < 20) - // { - // return source.ReadUInt(valaddr + i); - // } - // else if (qq[snext.Value] < 20) - // { - // return source.ReadUInt(valaddr + i + 1); - // } - // break; - - // case QueryValueMatchType.Closed: - // var pval = (time - skey.Key).TotalMilliseconds; - // var fval = (snext.Key - time).TotalMilliseconds; - // if (pval < fval) - // { - // return source.ReadUInt(valaddr + i); - // } - // else - // { - // return source.ReadUInt(valaddr + i + 1); - // } - // } - // } - // else if (time == snext.Key) - // { - // return source.ReadUInt(valaddr + i + 1); - // } - - //} - //return null; - } @@ -2702,7 +2513,7 @@ namespace Cdy.Tag if (time1 == skey.Value.Item1) { - var val = source.ReadUInt(valaddr + i); + var val = source.ReadUInt(valaddr + i*4); result.Add(val, time1, qq[skey.Key]); count++; break; @@ -2713,12 +2524,12 @@ namespace Cdy.Tag switch (type) { case QueryValueMatchType.Previous: - var val = source.ReadUInt(valaddr + i); + var val = source.ReadUInt(valaddr + i * 4); result.Add(val, time1, qq[skey.Key]); count++; break; case QueryValueMatchType.After: - val = source.ReadUInt(valaddr + i + 1); + val = source.ReadUInt(valaddr + (i + 1) * 4); result.Add(val, time1, qq[snext.Key]); count++; break; @@ -2727,24 +2538,24 @@ namespace Cdy.Tag { var pval1 = (time1 - skey.Value.Item1).TotalMilliseconds; var tval1 = (snext.Value.Item1 - skey.Value.Item1).TotalMilliseconds; - var sval1 = source.ReadUInt(valaddr + i); - var sval2 = source.ReadUInt(valaddr + i + 1); - var val1 = (uint)(pval1 / tval1 * (sval2 - sval1) + sval1); - result.Add(val1, time1, 0); + var sval1 = source.ReadUInt(valaddr + i * 4); + var sval2 = source.ReadUInt(valaddr + (i + 1) * 4); + var val1 = pval1 / tval1 * (sval2 - sval1) + sval1; + result.Add((uint)val1, time1, 0); } else if (qq[skey.Key] < 20) { - val = source.ReadUInt(valaddr + i); + val = source.ReadUInt(valaddr + i * 4); result.Add(val, time1, qq[skey.Key]); } else if (qq[snext.Key] < 20) { - val = source.ReadUInt(valaddr + i + 1); + val = source.ReadUInt(valaddr + (i + 1) * 4); result.Add(val, time1, qq[snext.Key]); } else { - result.Add(0, time1, (byte)QulityConst.Null); + result.Add(0, time1, (byte)QualityConst.Null); } count++; break; @@ -2754,22 +2565,23 @@ namespace Cdy.Tag if (pval < fval) { - val = source.ReadUInt(valaddr + i); + val = source.ReadUInt(valaddr + i * 4); result.Add(val, time1, qq[skey.Key]); } else { - val = source.ReadUInt(valaddr + i + 1); + val = source.ReadUInt(valaddr + (i + 1) * 4); result.Add(val, time1, qq[snext.Key]); } + count++; break; } - count++; + break; } else if (time1 == snext.Value.Item1) { - var val = source.ReadUInt(valaddr + i + 1); + var val = source.ReadUInt(valaddr + (i + 1) * 4); result.Add(val, time1, qq[snext.Key]); count++; break; @@ -2778,8 +2590,6 @@ namespace Cdy.Tag } } return count; - - } /// @@ -2810,33 +2620,33 @@ namespace Cdy.Tag if (time == skey.Value.Item1) { - return source.ReadULong(valaddr + i); + return source.ReadULong(valaddr + i*8); } else if (time > skey.Value.Item1 && time < snext.Value.Item1) { switch (type) { case QueryValueMatchType.Previous: - return source.ReadULong(valaddr + i); + return source.ReadULong(valaddr + i*8); case QueryValueMatchType.After: - return source.ReadULong(valaddr + i + 1); + return source.ReadULong(valaddr + (i + 1)*8); case QueryValueMatchType.Linear: if (qq[skey.Key] < 20 && qq[snext.Key] < 20) { var pval1 = (time1 - skey.Value.Item1).TotalMilliseconds; var tval1 = (snext.Value.Item1 - skey.Value.Item1).TotalMilliseconds; - var sval1 = source.ReadULong(valaddr + i); - var sval2 = source.ReadULong(valaddr + i + 1); + var sval1 = source.ReadULong(valaddr + i * 8); + var sval2 = source.ReadULong(valaddr + (i + 1) * 8); return (ulong)(pval1 / tval1 * (sval2 - sval1) + sval1); } else if (qq[skey.Key] < 20) { - return source.ReadULong(valaddr + i); + return source.ReadULong(valaddr + i * 8); } else if (qq[snext.Key] < 20) { - return source.ReadULong(valaddr + i + 1); + return source.ReadULong(valaddr + (i + 1) * 8); } break; @@ -2845,89 +2655,23 @@ namespace Cdy.Tag var fval = (snext.Value.Item1 - time).TotalMilliseconds; if (pval < fval) { - return source.ReadULong(valaddr + i); + return source.ReadULong(valaddr + i * 8); } else { - return source.ReadULong(valaddr + i + 1); + return source.ReadULong(valaddr + (i + 1) * 8); } } } else if (time == snext.Value.Item1) { - return source.ReadULong(valaddr + i + 1); + return source.ReadULong(valaddr + (i + 1) * 8); } } return null; - //DateTime time1; - //int valuecount = 0; - //var qs = ReadTimeQulity(source, sourceAddr, timeTick, out valuecount, out time1); - //var qq = source.ReadBytes(qs.Count * 10, qs.Count); - - //var valaddr = qs.Count * 2; - - //var vv = qs.ToArray(); - - //for (int i = 0; i < vv.Length - 1; i++) - //{ - // var skey = vv[i]; - - // var snext = vv[i + 1]; - - // if (time == skey.Key) - // { - // return source.ReadULong(valaddr + i); - // } - // else if (time > skey.Key && time < snext.Key) - // { - // switch (type) - // { - // case QueryValueMatchType.Previous: - // return source.ReadULong(valaddr + i); - // case QueryValueMatchType.After: - // return source.ReadULong(valaddr + i + 1); - // case QueryValueMatchType.Linear: - - // if (qq[skey.Value] < 20 && qq[snext.Value] < 20) - // { - // var pval1 = (time1 - skey.Key).TotalMilliseconds; - // var tval1 = (snext.Key - skey.Key).TotalMilliseconds; - // var sval1 = source.ReadULong(valaddr + i); - // var sval2 = source.ReadULong(valaddr + i + 1); - // return (ulong)(pval1 / tval1 * (sval2 - sval1) + sval1); - // } - // else if (qq[skey.Value] < 20) - // { - // return source.ReadULong(valaddr + i); - // } - // else if (qq[snext.Value] < 20) - // { - // return source.ReadULong(valaddr + i + 1); - // } - // break; - - // case QueryValueMatchType.Closed: - // var pval = (time - skey.Key).TotalMilliseconds; - // var fval = (snext.Key - time).TotalMilliseconds; - // if (pval < fval) - // { - // return source.ReadULong(valaddr + i); - // } - // else - // { - // return source.ReadULong(valaddr + i + 1); - // } - // } - // } - // else if (time == snext.Key) - // { - // return source.ReadULong(valaddr + i + 1); - // } - - //} - //return null; + } /// @@ -2962,7 +2706,7 @@ namespace Cdy.Tag if (time1 == skey.Value.Item1) { - var val = source.ReadULong(valaddr + i); + var val = source.ReadULong(valaddr + i * 8); result.Add(val, time1, qq[skey.Key]); count++; break; @@ -2973,12 +2717,12 @@ namespace Cdy.Tag switch (type) { case QueryValueMatchType.Previous: - var val = source.ReadULong(valaddr + i); + var val = source.ReadULong(valaddr + i * 8); result.Add(val, time1, qq[skey.Key]); count++; break; case QueryValueMatchType.After: - val = source.ReadULong(valaddr + i + 1); + val = source.ReadULong(valaddr + (i + 1) * 8); result.Add(val, time1, qq[snext.Key]); count++; break; @@ -2987,24 +2731,24 @@ namespace Cdy.Tag { var pval1 = (time1 - skey.Value.Item1).TotalMilliseconds; var tval1 = (snext.Value.Item1 - skey.Value.Item1).TotalMilliseconds; - var sval1 = source.ReadULong(valaddr + i); - var sval2 = source.ReadULong(valaddr + i + 1); - var val1 = (ulong)(pval1 / tval1 * (sval2 - sval1) + sval1); - result.Add(val1, time1, 0); + var sval1 = source.ReadULong(valaddr + i * 8); + var sval2 = source.ReadULong(valaddr + (i + 1) * 8); + var val1 = pval1 / tval1 * (sval2 - sval1) + sval1; + result.Add((ulong)val1, time1, 0); } else if (qq[skey.Key] < 20) { - val = source.ReadULong(valaddr + i); + val = source.ReadULong(valaddr + i * 8); result.Add(val, time1, qq[skey.Key]); } else if (qq[snext.Key] < 20) { - val = source.ReadULong(valaddr + i + 1); + val = source.ReadULong(valaddr + (i + 1) * 8); result.Add(val, time1, qq[snext.Key]); } else { - result.Add(0, time1, (byte)QulityConst.Null); + result.Add(0, time1, (byte)QualityConst.Null); } count++; break; @@ -3014,27 +2758,27 @@ namespace Cdy.Tag if (pval < fval) { - val = source.ReadULong(valaddr + i); + val = source.ReadULong(valaddr + i * 8); result.Add(val, time1, qq[skey.Key]); } else { - val = source.ReadULong(valaddr + i + 1); + val = source.ReadULong(valaddr + (i + 1) * 8); result.Add(val, time1, qq[snext.Key]); } + count++; break; } - count++; + break; } else if (time1 == snext.Value.Item1) { - var val = source.ReadULong(valaddr + i + 1); + var val = source.ReadULong(valaddr + (i + 1) * 8); result.Add(val, time1, qq[snext.Key]); count++; break; } - } } return count; @@ -3075,26 +2819,26 @@ namespace Cdy.Tag switch (type) { case QueryValueMatchType.Previous: - return source.ReadUShort(valaddr + i); + return source.ReadUShort(valaddr + i*2); case QueryValueMatchType.After: - return source.ReadUShort(valaddr + i + 1); + return source.ReadUShort(valaddr + (i + 1)*2); case QueryValueMatchType.Linear: if (qq[skey.Key] < 20 && qq[snext.Key] < 20) { var pval1 = (time1 - skey.Value.Item1).TotalMilliseconds; var tval1 = (snext.Value.Item1 - skey.Value.Item1).TotalMilliseconds; - var sval1 = source.ReadUShort(valaddr + i); - var sval2 = source.ReadUShort(valaddr + i + 1); + var sval1 = source.ReadUShort(valaddr + i * 2); + var sval2 = source.ReadUShort(valaddr + (i + 1) * 2); return (ushort)(pval1 / tval1 * (sval2 - sval1) + sval1); } else if (qq[skey.Key] < 20) { - return source.ReadUShort(valaddr + i); + return source.ReadUShort(valaddr + i * 2); } else if (qq[snext.Key] < 20) { - return source.ReadUShort(valaddr + i + 1); + return source.ReadUShort(valaddr + (i + 1) * 2); } break; @@ -3103,17 +2847,17 @@ namespace Cdy.Tag var fval = (snext.Value.Item1 - time).TotalMilliseconds; if (pval < fval) { - return source.ReadUShort(valaddr + i); + return source.ReadUShort(valaddr + i * 2); } else { - return source.ReadUShort(valaddr + i + 1); + return source.ReadUShort(valaddr + (i + 1) * 2); } } } else if (time == snext.Value.Item1) { - return source.ReadUShort(valaddr + i + 1); + return source.ReadUShort(valaddr + (i + 1) * 2); } } @@ -3127,11 +2871,11 @@ namespace Cdy.Tag DateTime stime; int valuecount = 0; var qs = ReadTimeQulity(source, sourceAddr, timeTick, out valuecount, out stime); - var qq = source.ReadBytes(valuecount * 4+10+sourceAddr, qs.Count); + var qq = source.ReadBytes(qs.Count * 4 + 10 + sourceAddr, qs.Count); var vv = qs.ToArray(); - var valaddr = valuecount * 2+10 + sourceAddr; + var valaddr = qs.Count * 2 + 10 + sourceAddr; int count = 0; foreach (var time1 in time) @@ -3144,7 +2888,7 @@ namespace Cdy.Tag if (time1 == skey.Value.Item1) { - var val = source.ReadUShort(valaddr + i); + var val = source.ReadUShort(valaddr + i * 2); result.Add(val, time1, qq[skey.Key]); count++; break; @@ -3155,12 +2899,12 @@ namespace Cdy.Tag switch (type) { case QueryValueMatchType.Previous: - var val = source.ReadUShort(valaddr + i); + var val = source.ReadUShort(valaddr + i * 2); result.Add(val, time1, qq[skey.Key]); count++; break; case QueryValueMatchType.After: - val = source.ReadUShort(valaddr + i + 1); + val = source.ReadUShort(valaddr + (i + 1) * 2); result.Add(val, time1, qq[snext.Key]); count++; break; @@ -3169,24 +2913,24 @@ namespace Cdy.Tag { var pval1 = (time1 - skey.Value.Item1).TotalMilliseconds; var tval1 = (snext.Value.Item1 - skey.Value.Item1).TotalMilliseconds; - var sval1 = source.ReadUShort(valaddr + i); - var sval2 = source.ReadUShort(valaddr + i + 1); - var val1 = (ushort)(pval1 / tval1 * (sval2 - sval1) + sval1); - result.Add(val1, time1, 0); + var sval1 = source.ReadUShort(valaddr + i * 2); + var sval2 = source.ReadUShort(valaddr + (i + 1) * 2); + var val1 = pval1 / tval1 * (sval2 - sval1) + sval1; + result.Add((ushort)val1, time1, 0); } else if (qq[skey.Key] < 20) { - val = source.ReadUShort(valaddr + i); + val = source.ReadUShort(valaddr + i * 2); result.Add(val, time1, qq[skey.Key]); } else if (qq[snext.Key] < 20) { - val = source.ReadUShort(valaddr + i + 1); + val = source.ReadUShort(valaddr + (i + 1) * 2); result.Add(val, time1, qq[snext.Key]); } else { - result.Add(0, time1, (byte)QulityConst.Null); + result.Add(0, time1, (byte)QualityConst.Null); } count++; break; @@ -3196,22 +2940,23 @@ namespace Cdy.Tag if (pval < fval) { - val = source.ReadUShort(valaddr + i); + val = source.ReadUShort(valaddr + i * 2); result.Add(val, time1, qq[skey.Key]); } else { - val = source.ReadUShort(valaddr + i + 1); + val = source.ReadUShort(valaddr + (i + 1) * 2); result.Add(val, time1, qq[snext.Key]); } + count++; break; } - count++; + break; } else if (time1 == snext.Value.Item1) { - var val = source.ReadUShort(valaddr + i + 1); + var val = source.ReadUShort(valaddr + (i + 1) * 2); result.Add(val, time1, qq[snext.Key]); count++; break; diff --git a/DataRunner/His/HisEnginer.cs b/DataRunner/His/HisEnginer.cs index 637cd2e..8ef0ac9 100644 --- a/DataRunner/His/HisEnginer.cs +++ b/DataRunner/His/HisEnginer.cs @@ -521,7 +521,11 @@ namespace Cdy.Tag /// private void MemoryMerge(int count) { - if (count == 0) mMergeMemory.CurrentDatetime = mWaitForMergeMemory.CurrentDatetime; + if (count == 0) + { + mMergeMemory.CurrentDatetime = mWaitForMergeMemory.CurrentDatetime; + LoggerService.Service.Info("HisEnginer", "MergeMemory 使用新的时间起点:" + mWaitForMergeMemory.Name + mMergeMemory.CurrentDatetime.ToString()); + } var mcc = mWaitForMergeMemory; LoggerService.Service.Info("Record", "开始内存合并" + mcc.Name); @@ -591,9 +595,11 @@ namespace Cdy.Tag CurrentMemory = mCachMemory1; } - if(mMergeCount==0) + CurrentMemory.CurrentDatetime = dateTime; + + if (mMergeCount==0) { - CurrentMemory.CurrentDatetime = dateTime; + LoggerService.Service.Info("HisEnginer", "使用新的时间起点:" + CurrentMemory.Name + " " + CurrentMemory.CurrentDatetime.ToString()); HisRunTag.StartTime = dateTime; } //PrepareForReadyMemory(); @@ -665,7 +671,7 @@ namespace Cdy.Tag var tag = mHisTags[vv.Key]; - long timeraddr = vv.Value.Item1 + vv.Value.Item2-4; + long timeraddr = vv.Value.Item1 + vv.Value.Item2-2; long valueaddr = vv.Value.Item1 + vv.Value.Item3-tag.SizeOfValue; long qaddr = vv.Value.Item1 + vv.Value.Item4-1; diff --git a/DataRunner/His/Tag/HisRunTag.cs b/DataRunner/His/Tag/HisRunTag.cs index 87a6010..09b771d 100644 --- a/DataRunner/His/Tag/HisRunTag.cs +++ b/DataRunner/His/Tag/HisRunTag.cs @@ -140,7 +140,7 @@ namespace Cdy.Tag public void UpdateNone() { Count = ++Count > MaxCount ? MaxCount : Count; - HisAddr[HisQulityStartAddr + Count] = (byte)QulityConst.Tick; + HisAddr[HisQulityStartAddr + Count] = (byte)QualityConst.Tick; } /// diff --git a/DataRunner/Real/RealEnginer.cs b/DataRunner/Real/RealEnginer.cs index 9475bbc..bf48c2a 100644 --- a/DataRunner/Real/RealEnginer.cs +++ b/DataRunner/Real/RealEnginer.cs @@ -90,6 +90,9 @@ namespace Cdy.Tag } } + /// + /// + /// public IntPtr MemoryHandle { get @@ -119,6 +122,7 @@ namespace Cdy.Tag public void Init() { long msize = 0; + byte unknowQuality = (byte)QualityConst.Init; mIdAndAddr.Clear(); foreach (var vv in mConfigDatabase.Tags) { @@ -128,7 +132,7 @@ namespace Cdy.Tag { case TagType.Bool: case TagType.Byte: - msize+=10; + msize +=10; break; case TagType.Short: case TagType.UShort: @@ -153,6 +157,35 @@ namespace Cdy.Tag mUsedSize = (long)(msize * 1.2); mMemory = new byte[mUsedSize]; mMHandle = mMemory.AsMemory().Pin().Pointer; + + foreach (var vv in mConfigDatabase.Tags) + { + switch (vv.Value.Type) + { + case TagType.Bool: + case TagType.Byte: + MemoryHelper.WriteByte(mMHandle, vv.Value.ValueAddress + 9, unknowQuality); + break; + case TagType.Short: + case TagType.UShort: + MemoryHelper.WriteByte(mMHandle, vv.Value.ValueAddress + 10, unknowQuality); + break; + case TagType.Int: + case TagType.UInt: + case TagType.Float: + MemoryHelper.WriteByte(mMHandle, vv.Value.ValueAddress + 12, unknowQuality); + break; + case TagType.Long: + case TagType.ULong: + case TagType.Double: + MemoryHelper.WriteByte(mMHandle, vv.Value.ValueAddress + 16, unknowQuality); + break; + case TagType.String: + MemoryHelper.WriteByte(mMHandle, vv.Value.ValueAddress + Const.StringSize + 8, unknowQuality); + break; + } + } + } /// @@ -223,6 +256,7 @@ namespace Cdy.Tag public void SetValueByAddr(long addr, byte value) { mMemory[addr] = value; + MemoryHelper.WriteByte(mMHandle, addr + 9, 0); } /// @@ -247,6 +281,7 @@ namespace Cdy.Tag public void SetValueByAddr(long addr, short value) { MemoryHelper.WriteShort(mMHandle, addr, value); + MemoryHelper.WriteByte(mMHandle, addr + 10, 0); } /// @@ -271,6 +306,7 @@ namespace Cdy.Tag public void SetValueByAddr(long addr, int value) { MemoryHelper.WriteInt32(mMHandle, addr, value); + MemoryHelper.WriteByte(mMHandle, addr + 12, 0); } /// @@ -295,6 +331,7 @@ namespace Cdy.Tag public void SetValueByAddr(long addr, long value) { MemoryHelper.WriteInt64(mMHandle, addr, value); + MemoryHelper.WriteByte(mMHandle, addr + 16, 0); } /// @@ -308,7 +345,7 @@ namespace Cdy.Tag { MemoryHelper.WriteInt64(mMHandle, addr, value); MemoryHelper.WriteDateTime(mMHandle, addr + 8, time); - MemoryHelper.WriteByte(mMHandle, addr + 16, qulity); ; + MemoryHelper.WriteByte(mMHandle, addr + 16, qulity); } @@ -321,6 +358,7 @@ namespace Cdy.Tag public void SetValueByAddr(long addr, float value) { MemoryHelper.WriteFloat(mMHandle, addr, value); + MemoryHelper.WriteByte(mMHandle, addr + 12, 0); } /// @@ -345,6 +383,7 @@ namespace Cdy.Tag public void SetValueByAddr(long addr, double value) { MemoryHelper.WriteDouble(mMHandle, addr, value); + MemoryHelper.WriteByte(mMHandle, addr + 16, 0); } /// @@ -369,6 +408,7 @@ namespace Cdy.Tag public void SetValueByAddr(long addr, DateTime value) { MemoryHelper.WriteDateTime(mMHandle, addr, value); + MemoryHelper.WriteByte(mMHandle, addr + 16, 0); } /// @@ -396,6 +436,7 @@ namespace Cdy.Tag MemoryHelper.WriteByte(mMHandle, addr, (byte)value.Length); System.Buffer.BlockCopy(value.ToCharArray(), 0, mMemory, (int)addr+1, value.Length); + MemoryHelper.WriteByte(mMHandle, Const.StringSize + 8, 0); } /// @@ -409,9 +450,14 @@ namespace Cdy.Tag { System.Buffer.BlockCopy(value.ToCharArray(), 0, mMemory, (int)addr, value.Length); MemoryHelper.WriteDateTime(mMHandle, Const.StringSize, time); - MemoryHelper.WriteByte(mMHandle, Const.StringSize + 8, qulity); ; + MemoryHelper.WriteByte(mMHandle, Const.StringSize + 8, qulity); } + /// + /// + /// + /// + /// public void SetValue(int id, bool value) { if (value) diff --git a/DbManager.Desktop/Image/export.png b/DbManager.Desktop/Image/export.png new file mode 100644 index 0000000000000000000000000000000000000000..b75e9b4368a8eedf5687385090d5ea05fe071f79 GIT binary patch literal 272 zcmV+r0q_2aP)Q0)`DBDw^O)P$X2

X(;fgzbp z-$!0*I(F{)-+RuTDeQQPmiimqrJ58FE^kYKY0U=DIRCH9FNYc61D_b6hk0yrhT~A1 z1IjEtVT@NSagQ1LIB5a|@gXL7kB}=YaE*sLz(Ev@@D{Cw48C!J$0iGx=wO=U5-fzU zU#ddPGYC_x>sH;AL76s8aEjlJ?H`~U*Hve`(n8f!&S76T!Ya?8<-htXZ~Gg!n*0Eo WZ7dN08K6u60000m4k literal 0 HcmV?d00001 diff --git a/DbManager.Desktop/Image/import.png b/DbManager.Desktop/Image/import.png new file mode 100644 index 0000000000000000000000000000000000000000..47a533b4e8e095ce250a2e5c4c2b5fcf4b10d133 GIT binary patch literal 268 zcmV+n0rUQeP)3dy)wPaEoPB9fEuQL)-m>%Ok<%nq&=&@+uL+ Sot`}a0000 + + diff --git a/DbManager.Desktop/Properties/Resources.Designer.cs b/DbManager.Desktop/Properties/Resources.Designer.cs index 4816619..37ce869 100644 --- a/DbManager.Desktop/Properties/Resources.Designer.cs +++ b/DbManager.Desktop/Properties/Resources.Designer.cs @@ -60,6 +60,15 @@ namespace DBInStudio.Desktop.Properties { } } + ///

+ /// 查找类似 Value 的本地化字符串。 + /// + internal static string AbsoluteValue { + get { + return ResourceManager.GetString("AbsoluteValue", resourceCulture); + } + } + /// /// 查找类似 Add 的本地化字符串。 /// @@ -69,6 +78,15 @@ namespace DBInStudio.Desktop.Properties { } } + /// + /// 查找类似 Add tag {0} failed! 的本地化字符串。 + /// + internal static string AddTagFail { + get { + return ResourceManager.GetString("AddTagFail", resourceCulture); + } + } + /// /// 查找类似 Cancel 的本地化字符串。 /// @@ -114,6 +132,15 @@ namespace DBInStudio.Desktop.Properties { } } + /// + /// 查找类似 Type 的本地化字符串。 + /// + internal static string DeadAreaType { + get { + return ResourceManager.GetString("DeadAreaType", resourceCulture); + } + } + /// /// 查找类似 Dead zone 的本地化字符串。 /// @@ -141,6 +168,15 @@ namespace DBInStudio.Desktop.Properties { } } + /// + /// 查找类似 erro 的本地化字符串。 + /// + internal static string erro { + get { + return ResourceManager.GetString("erro", resourceCulture); + } + } + /// /// 查找类似 Export 的本地化字符串。 /// @@ -250,11 +286,11 @@ namespace DBInStudio.Desktop.Properties { } /// - /// 查找类似 Nome 的本地化字符串。 + /// 查找类似 None 的本地化字符串。 /// - internal static string NomeCompress { + internal static string NoneCompress { get { - return ResourceManager.GetString("NomeCompress", resourceCulture); + return ResourceManager.GetString("NoneCompress", resourceCulture); } } @@ -276,6 +312,15 @@ namespace DBInStudio.Desktop.Properties { } } + /// + /// 查找类似 Percent 的本地化字符串。 + /// + internal static string PercentValue { + get { + return ResourceManager.GetString("PercentValue", resourceCulture); + } + } + /// /// 查找类似 Record 的本地化字符串。 /// @@ -411,6 +456,15 @@ namespace DBInStudio.Desktop.Properties { } } + /// + /// 查找类似 Update tag {0} failed! 的本地化字符串。 + /// + internal static string UpdateTagFail { + get { + return ResourceManager.GetString("UpdateTagFail", resourceCulture); + } + } + /// /// 查找类似 UserName 的本地化字符串。 /// diff --git a/DbManager.Desktop/Properties/Resources.resx b/DbManager.Desktop/Properties/Resources.resx index 46699bd..e0c6846 100644 --- a/DbManager.Desktop/Properties/Resources.resx +++ b/DbManager.Desktop/Properties/Resources.resx @@ -117,9 +117,15 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + Value + Add + + Add tag {0} failed! + Cancel @@ -136,6 +142,9 @@ Dead zone + + Type + Dead zone @@ -145,6 +154,9 @@ Driver + + erro + Export @@ -182,8 +194,8 @@ New database failed! - - Nome + + None OK @@ -191,6 +203,9 @@ Password + + Percent + Record @@ -237,6 +252,9 @@ Type + + Update tag {0} failed! + UserName diff --git a/DbManager.Desktop/Properties/launchSettings.json b/DbManager.Desktop/Properties/launchSettings.json new file mode 100644 index 0000000..99729c7 --- /dev/null +++ b/DbManager.Desktop/Properties/launchSettings.json @@ -0,0 +1,8 @@ +{ + "profiles": { + "DBInStudio.Desktop": { + "commandName": "Executable", + "executablePath": "D:\\Project\\Galaxy\\Output\\DBInStudio.exe" + } + } +} \ No newline at end of file diff --git a/DbManager.Desktop/View/DeadAreaCompressParameter.xaml b/DbManager.Desktop/View/DeadAreaCompressParameter.xaml index 9c88f58..e5c1227 100644 --- a/DbManager.Desktop/View/DeadAreaCompressParameter.xaml +++ b/DbManager.Desktop/View/DeadAreaCompressParameter.xaml @@ -10,9 +10,16 @@ - + + + - - + + + + + + + diff --git a/DbManager.Desktop/View/SlopeCompressParameterView.xaml b/DbManager.Desktop/View/SlopeCompressParameterView.xaml index 1408708..b1e3346 100644 --- a/DbManager.Desktop/View/SlopeCompressParameterView.xaml +++ b/DbManager.Desktop/View/SlopeCompressParameterView.xaml @@ -10,9 +10,16 @@ - + + + + + + + + diff --git a/DbManager.Desktop/View/TagGroupDetailView.xaml b/DbManager.Desktop/View/TagGroupDetailView.xaml index 0c207cf..ef39697 100644 --- a/DbManager.Desktop/View/TagGroupDetailView.xaml +++ b/DbManager.Desktop/View/TagGroupDetailView.xaml @@ -107,29 +107,28 @@ - + - - - - - - - - - - - - - - - + + + + + + + + + + + + + + diff --git a/DbManager.Desktop/ViewModel/CompressParameterModelBase.cs b/DbManager.Desktop/ViewModel/CompressParameterModelBase.cs index 50d6682..79b3ebc 100644 --- a/DbManager.Desktop/ViewModel/CompressParameterModelBase.cs +++ b/DbManager.Desktop/ViewModel/CompressParameterModelBase.cs @@ -82,6 +82,7 @@ namespace DBInStudio.Desktop.ViewModel #region ... Variables ... private double mDeadValue; + private int mDeadType; #endregion ...Variables... #region ... Events ... @@ -94,8 +95,8 @@ namespace DBInStudio.Desktop.ViewModel #region ... Properties ... /// - /// 死区值 - /// + /// 死区值 + ///
public double DeadValue { get @@ -112,6 +113,23 @@ namespace DBInStudio.Desktop.ViewModel } } + + public int Type + { + get + { + return mDeadType; + } + set + { + mDeadType = value; + FillParameters(); + OnPropertyChanged("Type"); + } + } + + + #endregion ...Properties... #region ... Methods ... @@ -129,6 +147,15 @@ namespace DBInStudio.Desktop.ViewModel { this.mDeadValue = 0; } + + if (Parameters.ContainsKey("DeadType")) + { + this.mDeadType = (int)(Parameters["DeadType"]); + } + else + { + this.mDeadType = 0; + } } /// @@ -144,6 +171,15 @@ namespace DBInStudio.Desktop.ViewModel { Parameters.Add("DeadValue", DeadValue); } + + if (Parameters.ContainsKey("DeadType")) + { + Parameters["DeadType"] = Type; + } + else + { + Parameters.Add("DeadType", Type); + } } #endregion ...Methods... @@ -158,6 +194,7 @@ namespace DBInStudio.Desktop.ViewModel #region ... Variables ... private double mSlopeValue; + private int mSlopeType; #endregion ...Variables... #region ... Events ... @@ -170,8 +207,8 @@ namespace DBInStudio.Desktop.ViewModel #region ... Properties ... /// - /// 斜率值 - /// + /// 斜率值 + /// public double SlopeValue { get @@ -189,6 +226,21 @@ namespace DBInStudio.Desktop.ViewModel } } + public int Type + { + get + { + return mSlopeType; + } + set + { + mSlopeType = value; + FillParameters(); + OnPropertyChanged("SlopeType"); + } + } + + #endregion ...Properties... #region ... Methods ... @@ -198,14 +250,23 @@ namespace DBInStudio.Desktop.ViewModel ///
public override void Init() { - if (Parameters.ContainsKey("SlopeValue")) + if (Parameters.ContainsKey("SlopeArea")) { - this.mSlopeValue = Parameters["SlopeValue"]; + this.mSlopeValue = Parameters["SlopeArea"]; } else { this.mSlopeValue = 0; } + + if (Parameters.ContainsKey("SlopeType")) + { + this.mSlopeType = (int)Parameters["SlopeType"]; + } + else + { + this.mSlopeType = 0; + } } /// @@ -213,13 +274,22 @@ namespace DBInStudio.Desktop.ViewModel /// public override void FillParameters() { - if (Parameters.ContainsKey("SlopeValue")) + if (Parameters.ContainsKey("SlopeArea")) + { + Parameters["SlopeArea"] = SlopeValue; + } + else + { + Parameters.Add("SlopeArea", SlopeValue); + } + + if (Parameters.ContainsKey("SlopeType")) { - Parameters["SlopeValue"] = SlopeValue; + Parameters["SlopeType"] = Type; } else { - Parameters.Add("SlopeValue", SlopeValue); + Parameters.Add("SlopeType", Type); } } diff --git a/DbManager.Desktop/ViewModel/ITreeViewModel.cs b/DbManager.Desktop/ViewModel/ITreeViewModel.cs index fd7d4a3..fe1a2e7 100644 --- a/DbManager.Desktop/ViewModel/ITreeViewModel.cs +++ b/DbManager.Desktop/ViewModel/ITreeViewModel.cs @@ -18,7 +18,7 @@ namespace DBInStudio.Desktop { #region ... Variables ... - private string mName; + internal string mName; private bool mIsSelected = false; private bool mIsExpanded = false; private bool mIsEdit; diff --git a/DbManager.Desktop/ViewModel/LoginViewModel.cs b/DbManager.Desktop/ViewModel/LoginViewModel.cs index 519c67a..1fd559f 100644 --- a/DbManager.Desktop/ViewModel/LoginViewModel.cs +++ b/DbManager.Desktop/ViewModel/LoginViewModel.cs @@ -143,7 +143,7 @@ namespace DBInStudio.Desktop.ViewModel private void CheckLocalServerRun() { - if(mServer=="127.0.0.1"&&mServer=="localhost") + if(mServer=="127.0.0.1"||mServer=="localhost") { var pps = Process.GetProcessesByName("DBInStudioServer"); if(pps==null||pps.Length==0) diff --git a/DbManager.Desktop/ViewModel/MainViewModel.cs b/DbManager.Desktop/ViewModel/MainViewModel.cs index 378bcad..a59cba8 100644 --- a/DbManager.Desktop/ViewModel/MainViewModel.cs +++ b/DbManager.Desktop/ViewModel/MainViewModel.cs @@ -17,6 +17,8 @@ using System.Threading.Tasks; using System.Threading; using System.Windows; using DBDevelopClientApi; +using Microsoft.Win32; +using System.IO; namespace DBInStudio.Desktop { @@ -36,6 +38,10 @@ namespace DBInStudio.Desktop private ICommand mAddGroupCommand; private ICommand mRemoveGroupCommand; + private ICommand mExportCommand; + + private ICommand mImportCommand; + private TreeItemViewModel mCurrentSelectTreeItem; @@ -49,6 +55,8 @@ namespace DBInStudio.Desktop private ViewModelBase mContentViewModel; + private bool mIsCanOperate = true; + #endregion ...Variables... #region ... Events ... @@ -61,6 +69,63 @@ namespace DBInStudio.Desktop #region ... Properties ... + /// + /// + /// + public bool IsCanOperate + { + get + { + return mIsCanOperate; + } + set + { + if (mIsCanOperate != value) + { + mIsCanOperate = value; + OnPropertyChanged("IsCanOperate"); + } + } + } + + /// + /// + /// + public ICommand ImportCommand + { + get + { + if(mImportCommand==null) + { + mImportCommand = new RelayCommand(() => { + ImportFromFile(); + }); + } + return mImportCommand; + } + } + + /// + /// + /// + public ICommand ExportCommand + { + get + { + if (mExportCommand == null) + { + mExportCommand = new RelayCommand(() => { + ExportToFile(); + }); + } + return mExportCommand; + } + } + + + /// + /// + /// public ViewModelBase ContentViewModel { get @@ -204,6 +269,78 @@ namespace DBInStudio.Desktop #region ... Methods ... + + /// + /// + /// + private void ImportFromFile() + { + IsCanOperate = false; + + OpenFileDialog ofd = new OpenFileDialog(); + ofd.Filter = "csv|*.csv"; + List ltmp = new List(); + + if (ofd.ShowDialog().Value) + { + var stream = new StreamReader(File.Open(ofd.FileName, FileMode.OpenOrCreate, FileAccess.ReadWrite)); + while (!stream.EndOfStream) + { + string sval = stream.ReadLine(); + if (!string.IsNullOrEmpty(sval)) + { + TagViewModel tm = TagViewModel.LoadFromCSVString(sval); + ltmp.Add(tm); + } + } + stream.Close(); + } + + Task.Run(() => { + + int id; + foreach (var vv in ltmp) + { + if (!DevelopServiceHelper.Helper.AddTag(this.mDatabase, new Tuple(vv.RealTagMode, vv.HisTagMode), out id)) + { + MessageBox.Show(string.Format(Res.Get("UpdateTagFail"), vv.RealTagMode.Name), Res.Get("erro"), MessageBoxButton.OK, MessageBoxImage.Error); + break; + } + } + Application.Current.Dispatcher.BeginInvoke(new Action(() => { + IsCanOperate = true; + SelectContentModel(); + })); + }); + + + + + } + + /// + /// + /// + private void ExportToFile() + { + IsCanOperate = false; + SaveFileDialog ofd = new SaveFileDialog(); + ofd.Filter = "csv|*.csv"; + if (ofd.ShowDialog().Value) + { + + var stream = new StreamWriter(File.Open(ofd.FileName, FileMode.OpenOrCreate, FileAccess.ReadWrite)); + var res = DevelopServiceHelper.Helper.QueryAllTag(mDatabase); + foreach (var vv in res.Select(e=>new TagViewModel(e.Value.Item1,e.Value.Item2))) + { + stream.WriteLine(vv.SaveToCSVString()); + } + stream.Close(); + } + + IsCanOperate = true; + } + /// @@ -305,7 +442,7 @@ namespace DBInStudio.Desktop foreach(var vvv in vv.Where(e=>string.IsNullOrEmpty(e.Value))) { Application.Current.Dispatcher.Invoke(() => { - TagGroupViewModel groupViewModel = new TagGroupViewModel() { Name = vvv.Key,Database=mDatabase }; + TagGroupViewModel groupViewModel = new TagGroupViewModel() { mName = vvv.Key,Database=mDatabase }; mRootTagGroupModel.Children.Add(groupViewModel); groupViewModel.InitData(vv); }); diff --git a/DbManager.Desktop/ViewModel/TagExportHelper.cs b/DbManager.Desktop/ViewModel/TagExportHelper.cs deleted file mode 100644 index 2b78662..0000000 --- a/DbManager.Desktop/ViewModel/TagExportHelper.cs +++ /dev/null @@ -1,86 +0,0 @@ -//============================================================== -// Copyright (C) 2020 Inc. All rights reserved. -// -//============================================================== -// Create by 种道洋 at 2020/4/7 11:28:35. -// Version 1.0 -// 种道洋 -//============================================================== - -using System; -using System.Collections.Generic; -using System.Text; -using Cdy.Tag; - -namespace DBInStudio.Desktop.ViewModel -{ - /// - /// - /// - public static class TagExportHelper - { - /// - /// - /// - /// - /// - public static void ExportToCSV(this List tags,string file) - { - System.IO.StreamWriter writer = new System.IO.StreamWriter(System.IO.File.Open(file, System.IO.FileMode.CreateNew,System.IO.FileAccess.ReadWrite,System.IO.FileShare.ReadWrite),Encoding.Unicode); - - foreach(var vv in tags) - { - writer.WriteLine(vv.SaveToCSV()); - } - writer.Flush(); - writer.Close(); - } - - /// - /// - /// - /// - /// - public static string SaveToCSV(this TagViewModel tag) - { - string re = string.Empty; - re = tag.RealTagMode.Id + "," + tag.RealTagMode.Name + "," + tag.RealTagMode.Desc + "," + tag.RealTagMode.Type.ToString() + "," + tag.RealTagMode.LinkAddress + "," + tag.RealTagMode.Group; - if (tag.HisTagMode != null) - { - re += ";" + tag.HisTagMode.Type + "," + tag.HisTagMode.Circle + "," + tag.HisTagMode.CompressType; - if (tag.HisTagMode.Parameters != null && tag.HisTagMode.Parameters.Count > 0) - { - foreach (var vv in tag.HisTagMode.Parameters) - { - re += "," + vv.Key + "," + vv.Value; - } - } - } - return re; - } - - /// - /// - /// - /// - /// - public static Tuple LoadFromCSV(string value) - { - Tuple re; - Cdy.Tag.Tagbase realtag = null; - Cdy.Tag.HisTag histag = null; - - var strs = value.Split(new char[] { ';' }); - string[] sval = strs[0].Split(new char[] { ',' }); - realtag = Cdy.Tag.TagTypeExtends.GetTag((Cdy.Tag.TagType)Enum.Parse(typeof(Cdy.Tag.TagType), sval[3])); - realtag.Id = int.Parse(sval[0]); - realtag.Name = sval[1]; - re = new Tuple(realtag, histag); - return re; - } - - - - - } -} diff --git a/DbManager.Desktop/ViewModel/TagGroupDetailViewModel.cs b/DbManager.Desktop/ViewModel/TagGroupDetailViewModel.cs index 36be82e..79116f3 100644 --- a/DbManager.Desktop/ViewModel/TagGroupDetailViewModel.cs +++ b/DbManager.Desktop/ViewModel/TagGroupDetailViewModel.cs @@ -8,8 +8,10 @@ //============================================================== using DBDevelopClientApi; +using Microsoft.Win32; using System; using System.Collections.Generic; +using System.IO; using System.Linq; using System.Text; using System.Windows; @@ -90,7 +92,7 @@ namespace DBInStudio.Desktop.ViewModel if (mExportCommand == null) { mExportCommand = new RelayCommand(() => { - + ExportToFile(); }); } return mExportCommand; @@ -107,7 +109,7 @@ namespace DBInStudio.Desktop.ViewModel if (mImportCommand == null) { mImportCommand = new RelayCommand(() => { - + ImportFromFile(); }); } return mImportCommand; @@ -167,18 +169,99 @@ namespace DBInStudio.Desktop.ViewModel { return mSelectGroupTags; } + set + { + mSelectGroupTags = value; + OnPropertyChanged("SelectGroupTags"); + } } #endregion ...Properties... #region ... Methods ... + /// + /// + /// + private void ExportToFile() + { + SaveFileDialog ofd = new SaveFileDialog(); + ofd.Filter = "csv|*.csv"; + if(ofd.ShowDialog().Value) + { + var stream = new StreamWriter(File.Open(ofd.FileName, FileMode.OpenOrCreate, FileAccess.ReadWrite)); + foreach(var vv in mSelectGroupTags) + { + stream.WriteLine(vv.SaveToCSVString()); + } + stream.Close(); + } + } + + /// + /// + /// + private void ImportFromFile() + { + OpenFileDialog ofd = new OpenFileDialog(); + ofd.Filter = "csv|*.csv"; + List ltmp = new List(); + if (ofd.ShowDialog().Value) + { + var stream = new StreamReader(File.Open(ofd.FileName, FileMode.OpenOrCreate, FileAccess.ReadWrite)); + while(!stream.EndOfStream) + { + string sval = stream.ReadLine(); + if (!string.IsNullOrEmpty(sval)) + { + TagViewModel tm = TagViewModel.LoadFromCSVString(sval); + ltmp.Add(tm); + } + } + stream.Close(); + } + + var tags = mSelectGroupTags.ToDictionary(e => e.RealTagMode.Id); + foreach(var vv in ltmp) + { + if(tags.ContainsKey(vv.RealTagMode.Id)) + { + if(!DevelopServiceHelper.Helper.UpdateTag(GroupModel.Database, new Tuple(vv.RealTagMode, vv.HisTagMode))) + { + MessageBox.Show(string.Format(Res.Get("UpdateTagFail"), vv.RealTagMode.Name),Res.Get("erro"),MessageBoxButton.OK,MessageBoxImage.Error); + break; + } + } + else + { + int id; + if (!DevelopServiceHelper.Helper.AddTag(GroupModel.Database, new Tuple(vv.RealTagMode, vv.HisTagMode), out id)) + { + MessageBox.Show(string.Format(Res.Get("AddTagFail"), vv.RealTagMode.Name), Res.Get("erro"), MessageBoxButton.OK, MessageBoxImage.Error); + break; + } + else + { + vv.RealTagMode.Id = id; + if (vv.HisTagMode != null) vv.HisTagMode.Id = id; + vv.IsChanged = false; + vv.IsNew = false; + } + } + } + + System.Threading.Tasks.Task.Run(() => { QueryTags();}); + + } + + /// + /// + /// private void QueryTags() { - Application.Current.Dispatcher.Invoke(() => { - mSelectGroupTags.Clear(); - }); + var vtags = new System.Collections.ObjectModel.ObservableCollection(); + var vv = DevelopServiceHelper.Helper.QueryTagByGroup(this.GroupModel.Database, this.GroupModel.FullName); if (vv != null) @@ -187,11 +270,13 @@ namespace DBInStudio.Desktop.ViewModel { Application.Current.Dispatcher.BeginInvoke(new Action(() => { TagViewModel model = new TagViewModel(vvv.Value.Item1, vvv.Value.Item2); - mSelectGroupTags.Add(model); + vtags.Add(model); })); - } } + + SelectGroupTags = vtags; + } diff --git a/DbManager.Desktop/ViewModel/TagViewModel.cs b/DbManager.Desktop/ViewModel/TagViewModel.cs index 091f8d3..c86b658 100644 --- a/DbManager.Desktop/ViewModel/TagViewModel.cs +++ b/DbManager.Desktop/ViewModel/TagViewModel.cs @@ -14,6 +14,7 @@ using System.Linq; using System.Windows.Input; using DBDevelopClientApi; using DBInStudio.Desktop.ViewModel; +using Cdy.Tag; namespace DBInStudio.Desktop { @@ -60,7 +61,7 @@ namespace DBInStudio.Desktop InitEnumType(); mCompressTypeList = new string[] { - Res.Get("NomeCompress"), + Res.Get("NoneCompress"), Res.Get("LosslessCompress"), Res.Get("DeadAreaCompress"), Res.Get("SlopeCompress") @@ -646,6 +647,9 @@ namespace DBInStudio.Desktop IsChanged = true; } + /// + /// + /// private void CheckRecordTypeParameterModel() { if(mHisTagMode==null) @@ -746,6 +750,87 @@ namespace DBInStudio.Desktop return new TagViewModel(ntag,htag); } + /// + /// + /// + /// + public string SaveToCSVString() + { + StringBuilder sb = new StringBuilder(); + sb.Append(mRealTagMode.Id+","); + sb.Append(mRealTagMode.Name + ","); + sb.Append(mRealTagMode.Desc + ","); + sb.Append(mRealTagMode.Group + ","); + sb.Append(mRealTagMode.Type + ","); + sb.Append(mRealTagMode.LinkAddress + ","); + if(this.mHisTagMode!=null) + { + sb.Append(mHisTagMode.Type + ","); + sb.Append(mHisTagMode.Circle + ","); + sb.Append(mHisTagMode.CompressType + ","); + if(mHisTagMode.Parameters!=null) + { + foreach(var vv in mHisTagMode.Parameters) + { + sb.Append(vv.Key + ","); + sb.Append(vv.Value + ","); + } + } + } + sb.Length = sb.Length > 0 ? sb.Length - 1 : sb.Length; + return sb.ToString(); + } + + /// + /// + /// + /// + public static TagViewModel LoadFromCSVString(string val) + { + string[] stmp = val.Split(new char[] { ',' }); + Cdy.Tag.TagType tp = (Cdy.Tag.TagType)Enum.Parse(typeof(Cdy.Tag.TagType),stmp[4]); + var realtag = TagTypeExtends.GetTag(tp); + + realtag.Id = int.Parse(stmp[0]); + realtag.Name = stmp[1]; + realtag.Desc = stmp[2]; + realtag.Group = stmp[3]; + realtag.LinkAddress = stmp[5]; + + if (stmp.Length > 6) + { + Cdy.Tag.HisTag histag = new HisTag(); + histag.Type = (Cdy.Tag.RecordType)Enum.Parse(typeof(Cdy.Tag.RecordType), stmp[6]); + + histag.Circle = long.Parse(stmp[7]); + histag.CompressType = int.Parse(stmp[8]); + histag.Parameters = new Dictionary(); + histag.TagType = realtag.Type; + histag.Id = realtag.Id; + + for (int i=9;i - + diff --git a/HisDataTools/Chart/Brush/Bitmap/BitmapBase.cs b/HisDataTools/Chart/Brush/Bitmap/BitmapBase.cs new file mode 100644 index 0000000..1899c22 --- /dev/null +++ b/HisDataTools/Chart/Brush/Bitmap/BitmapBase.cs @@ -0,0 +1,86 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Media; +using System.Windows.Media.Imaging; + +namespace HeBianGu.General.DrawingBrush.Bitmap +{ + + public class BitmapBase : IBitmap + { + public WriteableBitmap Source { get; set; } + + public BitmapBase(int width,int height) + { + Source = new WriteableBitmap(width, height, 96, 96, PixelFormats.Bgr32, null); + + this.Width = width; + + this.Height = height; + } + + public int Height { get; set; } + + public int Width { get; } + + public List Brushs { get; set; } = new List(); + + public IBitmap Draw() + { + Int32Rect rect = new Int32Rect(0, 0, (int)Width, Height); + + byte[] pixels = new byte[(int)Width * Height * Source.Format.BitsPerPixel / 8]; + + for (int y = 0; y < Source.PixelHeight; y++) + { + for (int x = 0; x < Source.PixelWidth; x++) + { + int alpha = 0; + int red = 0; + int green = 0; + int blue = 0; + + int weight = x; + int height = y; + + //red = (int)((double)height / Source.PixelWidth * 255); + //green = rand.Next(100, 255); + //blue = (int)((double)weight / wb.PixelHeight * 255); + alpha = 50; + + foreach (var item in this.Brushs) + { + item.Draw(weight, height, ref red, ref green, ref blue); + } + + int pixelOffset = (x + y * Source.PixelWidth) * Source.Format.BitsPerPixel / 8; + + pixels[pixelOffset] = (byte)blue; + pixels[pixelOffset + 1] = (byte)green; + pixels[pixelOffset + 2] = (byte)red; + pixels[pixelOffset + 3] = (byte)alpha; + + } + + int stride = (Source.PixelWidth * Source.Format.BitsPerPixel) / 8; + + Source.WritePixels(rect, pixels, stride, 0); + + } + + return this; + } + + public void GetColor(int x, int y, ref int red, ref int green, ref int blue) + { + foreach (var item in this.Brushs) + { + item.Draw(x, y, ref red, ref green, ref blue); + } + } + } +} diff --git a/HisDataTools/Chart/Brush/Bitmap/IBitmap.cs b/HisDataTools/Chart/Brush/Bitmap/IBitmap.cs new file mode 100644 index 0000000..455c323 --- /dev/null +++ b/HisDataTools/Chart/Brush/Bitmap/IBitmap.cs @@ -0,0 +1,13 @@ +using System.Windows.Media.Imaging; + +namespace HeBianGu.General.DrawingBrush +{ + public interface IBitmap + { + WriteableBitmap Source { get; set; } + + IBitmap Draw(); + + void GetColor(int x, int y, ref int red, ref int green, ref int blue); + } +} \ No newline at end of file diff --git a/HisDataTools/Chart/Brush/Bitmap/LinearBitmap.cs b/HisDataTools/Chart/Brush/Bitmap/LinearBitmap.cs new file mode 100644 index 0000000..52a00e9 --- /dev/null +++ b/HisDataTools/Chart/Brush/Bitmap/LinearBitmap.cs @@ -0,0 +1,153 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Media; +using System.Windows.Media.Imaging; + +namespace HeBianGu.General.DrawingBrush +{ + public class LinearBitmap : IBitmap + { + public WriteableBitmap Source { get; set; } + + public LinearBitmap(int width) + { + Source = new WriteableBitmap((int)width, Height, 96, 96, PixelFormats.Bgr32, null); + + this.Width = width; + } + + public int Height { get; set; } = 1; + + public int Width { get; } + + public int Mosaic { get; set; } = 2; + + public List LinearBrushs { get; set; } = new List(); + + public IBitmap Draw() + { + Int32Rect rect = new Int32Rect(0, 0, (int)Width, Height); + + byte[] pixels = new byte[(int)Width * Height * Source.Format.BitsPerPixel / 8]; + + for (int y = 0; y < Source.PixelHeight; y++) + { + for (int x = 0; x < Source.PixelWidth; x++) + { + int alpha = 0; + int red = 0; + int green = 0; + int blue = 0; + + int weight = x - x % Mosaic; + int height = y - y % Mosaic; + + //red = (int)((double)height / Source.PixelWidth * 255); + //green = rand.Next(100, 255); + //blue = (int)((double)weight / wb.PixelHeight * 255); + alpha = 50; + + foreach (var item in this.LinearBrushs) + { + item.Draw(weight, height, ref red, ref green, ref blue); + } + + int pixelOffset = (x + y * Source.PixelWidth) * Source.Format.BitsPerPixel / 8; + + pixels[pixelOffset] = (byte)blue; + pixels[pixelOffset + 1] = (byte)green; + pixels[pixelOffset + 2] = (byte)red; + pixels[pixelOffset + 3] = (byte)alpha; + + } + + int stride = (Source.PixelWidth * Source.Format.BitsPerPixel) / 8; + + Source.WritePixels(rect, pixels, stride, 0); + + } + + return this; + } + + public static LinearBitmap operator +(LinearBitmap b, LinearBitmap c) + { + int width = b.Width + c.Width; + + LinearBitmap result = new LinearBitmap(width); + + foreach (var item in b.LinearBrushs) + { + result.LinearBrushs.Add(item); + } + + foreach (var item in c.LinearBrushs) + { + LinearBrush linearBrush = item.Clone(); + + linearBrush.Start = linearBrush.Start + b.Width; + linearBrush.End = linearBrush.End + b.Width; + + result.LinearBrushs.Add(linearBrush); + } + + result.Draw(); + + return result; + } + + public static LinearBitmap operator -(LinearBitmap b, LinearBitmap c) + { + int width = b.Width - c.Width; + + LinearBitmap result = new LinearBitmap(width); + + var collection = b.LinearBrushs.Take(b.LinearBrushs.Count - c.LinearBrushs.Count); + + foreach (var item in collection) + { + result.LinearBrushs.Add(item); + } + + result.Draw(); + + return result; + } + + public LinearBitmap RemoveLast() + { + var last = this.LinearBrushs.LastOrDefault(); + + if (last == null || this.LinearBrushs.Count == 1) return null; + + int width = this.Width - last.End + last.Start; + + LinearBitmap result = new LinearBitmap(width); + + var collection = this.LinearBrushs.Take(this.LinearBrushs.Count - 1); + + foreach (var item in collection) + { + result.LinearBrushs.Add(item); + } + + result.Draw(); + + return result; + + } + + + public void GetColor(int x, int y, ref int red, ref int green, ref int blue) + { + foreach (var item in this.LinearBrushs) + { + item.Draw(x, y, ref red, ref green, ref blue); + } + } + } +} diff --git a/HisDataTools/Chart/Brush/Bitmap/PlanarGridBitmap.cs b/HisDataTools/Chart/Brush/Bitmap/PlanarGridBitmap.cs new file mode 100644 index 0000000..56a9219 --- /dev/null +++ b/HisDataTools/Chart/Brush/Bitmap/PlanarGridBitmap.cs @@ -0,0 +1,18 @@ +using HeBianGu.General.DrawingBrush.Bitmap; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Media; + +namespace HeBianGu.General.DrawingBrush +{ + public class PlanarGridBitmap: BitmapBase + { + public PlanarGridBitmap(int width, int height):base(width, height) + { + + } + } +} diff --git a/HisDataTools/Chart/Brush/Brushes/IBrush.cs b/HisDataTools/Chart/Brush/Brushes/IBrush.cs new file mode 100644 index 0000000..2d78cbf --- /dev/null +++ b/HisDataTools/Chart/Brush/Brushes/IBrush.cs @@ -0,0 +1,9 @@ + +namespace HeBianGu.General.DrawingBrush +{ + public interface IBrush + { + + void Draw(int x, int y, ref int r, ref int g, ref int b); + } +} \ No newline at end of file diff --git a/HisDataTools/Chart/Brush/Brushes/LinearBrush.cs b/HisDataTools/Chart/Brush/Brushes/LinearBrush.cs new file mode 100644 index 0000000..9b6a9d0 --- /dev/null +++ b/HisDataTools/Chart/Brush/Brushes/LinearBrush.cs @@ -0,0 +1,107 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Media; + +namespace HeBianGu.General.DrawingBrush +{ + public class LinearBrush : IBrush + { + public GradientStopCollection GradientStops { get; set; } = new GradientStopCollection(); + + public int Start { get; set; } + + public int End { get; set; } + + List> _gradientStopTuple; + + public List> GradientStopTuple + { + get + { + if (_gradientStopTuple == null) + { + _gradientStopTuple = this.BeginDraw(); + } + + return _gradientStopTuple; + } + } + + public void Draw(int x, int y, ref int r, ref int g, ref int b) + { + if (x < Start || x > End) return; + + var red = this.Get(x, (l, k) => k.Color.R - l.Color.R, l => l.Color.R); + + if (red != null) r = red.Value; + + var green = this.Get(x, (l, k) => k.Color.G - l.Color.G, l => l.Color.G); + + if (green != null) g = green.Value; + + var blue = this.Get(x, (l, k) => k.Color.B - l.Color.B, l => l.Color.B); + + if (blue != null) b = blue.Value; + + } + + int? Get(int x, Func func, Func func1) + { + int lenght = this.End - this.Start; + + foreach (var item in GradientStopTuple) + { + int s = (int)(item.Item1.Offset * lenght) + this.Start; + int e = (int)(item.Item2.Offset * lenght) + this.Start; + + if (x < s || x > e) continue; + + var ss = (double)(x - s) / (double)(e - s); + + var sss = func(item.Item1, item.Item2); + + return (int)((double)(x - s) / (double)(e - s) * func(item.Item1, item.Item2)) + func1(item.Item1); + } + + return null; + } + + List> BeginDraw() + { + List> tuples = new List>(); + + GradientStop last = null; + + foreach (var item in GradientStops) + { + if (last != null) + { + tuples.Add(Tuple.Create(last, item)); + } + + last = item; + } + + return tuples; + } + + public LinearBrush Clone() + { + LinearBrush linearBrush = new LinearBrush(); + + foreach (var item in GradientStops) + { + linearBrush.GradientStops.Add(item); + } + + linearBrush.Start = this.Start; + linearBrush.End = this.End; + + return linearBrush; + } + + } +} diff --git a/HisDataTools/Chart/Brush/Brushes/PlanarGridBrush.cs b/HisDataTools/Chart/Brush/Brushes/PlanarGridBrush.cs new file mode 100644 index 0000000..c65df89 --- /dev/null +++ b/HisDataTools/Chart/Brush/Brushes/PlanarGridBrush.cs @@ -0,0 +1,55 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Media; + +namespace HeBianGu.General.DrawingBrush +{ + public class PlanarGridBrush : IBrush + { + + public double[,] Values; + + public int Start { get; set; } + + public int End { get; set; } + + public int ItemWidth { get; set; } + + public int ItemHeigh { get; set; } + + public Color MaxColor { get; set; } + + public Color MinColor { get; set; } + + public double MaxValue { get; set; } + + public double MinValue { get; set; } + + public void Draw(int x, int y, ref int r, ref int g, ref int b) + { + int wIndex = x / ItemWidth; + + int hIndex = y / ItemHeigh; + + var value = Values[wIndex, hIndex]; + + r = this.GetColor(value, (l, k) => l.R - k.R, l => l.R); + g = this.GetColor(value, (l, k) => l.G - k.G, l => l.G); + b = this.GetColor(value, (l, k) => l.B - k.B, l => l.B); + } + + int GetColor(double value, Func func, Func func1) + { + double lenght = this.MaxValue - this.MinValue + 1; + + double persent = (double)(value - this.MinValue) / lenght; + + return (int)(persent * func(this.MaxColor, this.MinColor) + func1(this.MinColor)); + + + } + } +} diff --git a/HisDataTools/Chart/ChartGeneric.xaml b/HisDataTools/Chart/ChartGeneric.xaml new file mode 100644 index 0000000..dc873af --- /dev/null +++ b/HisDataTools/Chart/ChartGeneric.xaml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/HisDataTools/Chart/ICurveChart.cs b/HisDataTools/Chart/ICurveChart.cs new file mode 100644 index 0000000..c6e9cb1 --- /dev/null +++ b/HisDataTools/Chart/ICurveChart.cs @@ -0,0 +1,34 @@ +#region <版 本 注 释> +/* + * ======================================================================== + * Copyright(c) 四川*******公司, All Rights Reserved. + * ======================================================================== + * + * 作者:[HeBianGu] 时间:2018/1/10 11:50:15 + * 文件名:ICurveChart + * 说明: + * + * + * 修改者: 时间: + * 修改说明: + * ======================================================================== +*/ +#endregion +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Controls; + +namespace HeBianGu.WPF.EChart +{ + public interface ICurveChart + { + double GetY(double value); + + double GetX(double value); + + Canvas ParallelCanvas { get; } + } +} diff --git a/HisDataTools/Chart/Legend/Legend.xaml b/HisDataTools/Chart/Legend/Legend.xaml new file mode 100644 index 0000000..13d30bc --- /dev/null +++ b/HisDataTools/Chart/Legend/Legend.xaml @@ -0,0 +1,22 @@ + + + + + + + + + + diff --git a/HisDataTools/Chart/Legend/Legend.xaml.cs b/HisDataTools/Chart/Legend/Legend.xaml.cs new file mode 100644 index 0000000..b137c45 --- /dev/null +++ b/HisDataTools/Chart/Legend/Legend.xaml.cs @@ -0,0 +1,294 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; +using System.Windows.Shapes; + +namespace HeBianGu.WPF.EChart +{ + /// + /// Legend.xaml 的交互逻辑 + /// + public partial class Legend : UserControl + { + public Legend() + { + InitializeComponent(); + } + + #region Position properties + + public double LegendLeft + { + get { return (double)GetValue(LegendLeftProperty); } + set { SetValue(LegendLeftProperty, value); } + } + + public static readonly DependencyProperty LegendLeftProperty = DependencyProperty.Register( + "LegendLeft", + typeof(double), + typeof(Legend), + new FrameworkPropertyMetadata(Double.NaN)); + + public double LegendRight + { + get { return (double)GetValue(LegendRightProperty); } + set { SetValue(LegendRightProperty, value); } + } + + public static readonly DependencyProperty LegendRightProperty = DependencyProperty.Register( + "LegendRight", + typeof(double), + typeof(Legend), + new FrameworkPropertyMetadata(10.0)); + + public double LegendBottom + { + get { return (double)GetValue(LegendBottomProperty); } + set { SetValue(LegendBottomProperty, value); } + } + + public static readonly DependencyProperty LegendBottomProperty = DependencyProperty.Register( + "LegendBottom", + typeof(double), + typeof(Legend), + new FrameworkPropertyMetadata(Double.NaN)); + + public double LegendTop + { + get { return (double)GetValue(LegendTopProperty); } + set { SetValue(LegendTopProperty, value); } + } + + public static readonly DependencyProperty LegendTopProperty = DependencyProperty.Register( + "LegendTop", + typeof(double), + typeof(Legend), + new FrameworkPropertyMetadata(10.0)); + + #endregion + + /// + /// Adds new legend item. + /// + /// The legend item. + public void AddLegendItem(LegendItem legendItem) + { + stackPanel.Children.Add(legendItem); + } + } + + /// + /// is a base class for item in legend, that represents some chart. + /// + public abstract class LegendItem : CheckBox + { + /// + /// Initializes a new instance of the class. + /// + protected LegendItem() { } + + /// + /// Initializes a new instance of the class. + /// + /// The description. + protected LegendItem(Description description) + { + Description = description; + } + + private Description description; + /// + /// Gets or sets the description. + /// + /// The description. + public Description Description + { + get { return description; } + set + { + description = value; + //Content = description; + } + } + } + + + + #region - Description - + + + public class ResolveLegendItemEventArgs : EventArgs + { + public ResolveLegendItemEventArgs(LegendItem legendItem) + { + LegendItem = legendItem; + } + + public LegendItem LegendItem { get; set; } + } + + public abstract class Description + { + + private LegendItem legendItem; + public LegendItem LegendItem + { + get + { + if (legendItem == null) + { + legendItem = CreateLegendItem(); + } + return legendItem; + } + } + + private LegendItem CreateLegendItem() + { + LegendItem item = CreateLegendItemCore(); + return RaiseResolveLegendItem(item); + } + + protected virtual LegendItem CreateLegendItemCore() + { + return null; + } + + public event EventHandler ResolveLegendItem; + private LegendItem RaiseResolveLegendItem(LegendItem uncustomizedLegendItem) + { + if (ResolveLegendItem != null) + { + ResolveLegendItemEventArgs e = new ResolveLegendItemEventArgs(uncustomizedLegendItem); + ResolveLegendItem(this, e); + return e.LegendItem; + } + else + { + return uncustomizedLegendItem; + } + } + + private UIElement viewportElement; + public UIElement ViewportElement + { + get { return viewportElement; } + } + + internal void Attach(UIElement element) + { + this.viewportElement = element; + AttachCore(element); + } + + protected virtual void AttachCore(UIElement element) { } + + internal void Detach() + { + viewportElement = null; + } + + public abstract string Brief { get; } + + public abstract string Full { get; } + + public override string ToString() + { + return Brief; + } + } + + + public class StandardDescription : Description + { + public StandardDescription() { } + public StandardDescription(string description) + { + if (String.IsNullOrEmpty(description)) + throw new ArgumentNullException("description"); + + this.description = description; + } + + protected override void AttachCore(UIElement element) + { + if (description == null) + { + string str = element.GetType().Name; + description = str; + } + } + + private string description; + public string DescriptionString + { + get { return description; } + set { description = value; } + } + + public sealed override string Brief + { + get { return description; } + } + + public sealed override string Full + { + get { return description; } + } + } + + + public sealed class PenDescription : StandardDescription + { + /// + /// Initializes a new instance of the class. + /// + public PenDescription() { } + + /// + /// Initializes a new instance of the class. + /// + /// Custom description. + public PenDescription(string description) : base(description) { } + + //protected override LegendItem CreateLegendItemCore() + //{ + // return new LineLegendItem(this); + //} + + protected override void AttachCore(UIElement graph) + { + base.AttachCore(graph); + + //LineGraph g = graph as LineGraph; + + //if (g == null) + //{ + // throw new ArgumentException("Pen description can only be attached to PointsGraph", "graph"); + //} + //pen = g.LinePen; + + pen = new Pen(Brushes.Red, 1); + } + + private Pen pen; + + public Pen Pen + { + get { return pen; } + } + } + #endregion + + +} diff --git a/HisDataTools/Chart/Legend/LineLegendItem.xaml b/HisDataTools/Chart/Legend/LineLegendItem.xaml new file mode 100644 index 0000000..974a622 --- /dev/null +++ b/HisDataTools/Chart/Legend/LineLegendItem.xaml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/HisDataTools/Chart/Legend/LineLegendItem.xaml.cs b/HisDataTools/Chart/Legend/LineLegendItem.xaml.cs new file mode 100644 index 0000000..16769ff --- /dev/null +++ b/HisDataTools/Chart/Legend/LineLegendItem.xaml.cs @@ -0,0 +1,87 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; +using System.Windows.Shapes; + +namespace HeBianGu.WPF.EChart +{ + /// 直线图例 + public partial class LineLegendItem : LegendItem + { + + ICurveEntitySource _curve; + public LineLegendItem(ICurveEntitySource c) + { + _curve = c; + + this.Color = c.Color; + this.Text = c.Text; + this.Marker = c.Marker.Clone(); + + this.Checked += LineLegendItem_Checked; + this.Unchecked += LineLegendItem_Checked; + } + + private void LineLegendItem_Checked(object sender, RoutedEventArgs e) + { + Curve.Visibility = this.IsChecked.Value ? Visibility.Hidden : Visibility.Visible; + } + + public Brush Color + { + get { return (Brush)GetValue(ColorProperty); } + set { SetValue(ColorProperty, value); } + } + + // Using a DependencyProperty as the backing store for Color. This enables animation, styling, binding, etc... + public static readonly DependencyProperty ColorProperty = + DependencyProperty.Register("Color", typeof(Brush), typeof(LineLegendItem), new PropertyMetadata(Brushes.Black)); + + + public string Text + { + get { return (string)GetValue(TextProperty); } + set { SetValue(TextProperty, value); } + } + + // Using a DependencyProperty as the backing store for Text. This enables animation, styling, binding, etc... + public static readonly DependencyProperty TextProperty = + DependencyProperty.Register("Text", typeof(string), typeof(LineLegendItem), new PropertyMetadata("")); + + + + public ShapePointMarker Marker + { + get { return (ShapePointMarker)GetValue(MarkerProperty); } + set { SetValue(MarkerProperty, value); } + } + + public ICurveEntitySource Curve { get => _curve; set => _curve = value; } + + // Using a DependencyProperty as the backing store for Marker. This enables animation, styling, binding, etc... + public static readonly DependencyProperty MarkerProperty = + DependencyProperty.Register("Marker", typeof(ShapePointMarker), typeof(LineLegendItem), new PropertyMetadata(null)); + + + public void RefreshValue(string text) + { + //v.Text = text; + } + + static LineLegendItem() + { + DefaultStyleKeyProperty.OverrideMetadata(typeof(LineLegendItem), new FrameworkPropertyMetadata(typeof(LineLegendItem))); + } + } +} diff --git a/HisDataTools/Chart/Plotter/ChartInstance/CardiogramCurveChartPlotter.cs b/HisDataTools/Chart/Plotter/ChartInstance/CardiogramCurveChartPlotter.cs new file mode 100644 index 0000000..097ff68 --- /dev/null +++ b/HisDataTools/Chart/Plotter/ChartInstance/CardiogramCurveChartPlotter.cs @@ -0,0 +1,162 @@ +#region <版 本 注 释> +/* + * ======================================================================== + * Copyright(c) 四川*******公司, All Rights Reserved. + * ======================================================================== + * + * 作者:[HeBianGu] 时间:2018/1/19 15:41:51 + * 文件名:CardiogramCurveChartPlotter + * 说明: + * + * + * 修改者: 时间: + * 修改说明: + * ======================================================================== +*/ +#endregion +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Media; + +namespace HeBianGu.WPF.EChart +{ + + /// 心电图图表 + public class CardiogramCurveChartPlotter : CurveChartPlotter + { + + public CardiogramCurveChartPlotter() + { + //this.InitData(); + + //this.RunDemo(); + + this.Loaded += CardiogramCurveChartPlotter_Loaded; + } + + private void CardiogramCurveChartPlotter_Loaded(object sender, System.Windows.RoutedEventArgs e) + { + + } + + private Brush _gridLineColor = Brushes.Red; + /// 网格线颜色 + public Brush GridLineColor + { + get { return _gridLineColor; } + set { _gridLineColor = value; } + } + + + /// 此方法的说明 + public void RunDemo() + { + //CardiogramCurveEntitySource source = new CardiogramCurveEntitySource(); + + //source.Color = this.Foreground; + + //Random r = new Random(); + + //// Todo :初始化X网线 + //for (double i = this.MinValueX; i < this.MaxValueX; i = i + 0.1) + //{ + // PointC p = new PointC(); + + // p.Y = r.Next(1800, 2500); + // p.X = i; + + // source.Source.Add(p); + + //} + + //this.DataSource.Add(source); + } + + private bool _isShowX; + /// 说明 + public bool IsShowX + { + get { return _isShowX; } + set { _isShowX = value; } + } + + private bool _isShowY; + /// 说明 + public bool IsShowY + { + get { return _isShowY; } + set { _isShowY = value; } + } + + private bool _isShowBaseLine; + /// 说明 + public bool IsShowBaseLine + { + get { return _isShowBaseLine; } + set { _isShowBaseLine = value; } + } + + + + /// 初始化心电图表 + void InitData() + { + //this.FontSize = 12; + this.MaxValueY = 2448; + this.MinValueY = 1848; + this.MaxValueX = 11; + this.MinValueX = 0; + //this.Height = 150; + + + int tempIndex = 0; + // Todo :初始化X网线 + for (double i = this.MinValueX; i <= this.MaxValueX; i = i + 0.25) + { + SplitItem s = new SplitItem(); + s.Value = i; + s.Text = (i * 80).ToString(); + s.Color = this._gridLineColor; + int param = (int)(tempIndex % 4); + + s.SpliteType = param == 0 && this.IsShowX ? SplitItemType.Normal : SplitItemType.InnerOnly; + + this.SlpitItemXs.Add(s); + tempIndex++; + } + + // Todo :2048基准线 + if (this.IsShowBaseLine) + { + SplitItem sbase = new SplitItem(); + sbase.Value = 2048; + sbase.Text = (2048).ToString(); + sbase.Color = this.Foreground; + sbase.SpliteType = SplitItemType.HeighLight; + this.SplitItemYs.Add(sbase); + } + + + tempIndex = 0; + // Todo :初始化Y网线 + for (double i = this.MinValueY; i <= this.MaxValueY; i = i + 30) + { + SplitItem s = new SplitItem(); + s.Value = i; + s.Text = i.ToString(); + s.Color = this._gridLineColor; + + int param = (int)(tempIndex % 4); + + s.SpliteType = param == 0 && this.IsShowY ? SplitItemType.Normal : SplitItemType.InnerOnly; + + this.SplitItemYs.Add(s); + + tempIndex++; + } + } + } +} diff --git a/HisDataTools/Chart/Plotter/ChartInstance/StaticCurveChartPlotter.cs b/HisDataTools/Chart/Plotter/ChartInstance/StaticCurveChartPlotter.cs new file mode 100644 index 0000000..740564c --- /dev/null +++ b/HisDataTools/Chart/Plotter/ChartInstance/StaticCurveChartPlotter.cs @@ -0,0 +1,37 @@ +#region <版 本 注 释> +/* + * ======================================================================== + * Copyright(c) 四川*******公司, All Rights Reserved. + * ======================================================================== + * + * 作者:[HeBianGu] 时间:2018/1/18 11:30:25 + * 文件名:StaticCurveChartPlotter + * 说明: + * + * + * 修改者: 时间: + * 修改说明: + * ======================================================================== +*/ +#endregion +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Media; +using System.Windows.Shapes; + +namespace HeBianGu.WPF.EChart +{ + /// 静态曲线视图 + public class StaticCurveChartPlotter: CurveChartPlotter + { + public StaticCurveChartPlotter() + { + } + + } +} diff --git a/HisDataTools/Chart/Plotter/ChartPlotter.cs b/HisDataTools/Chart/Plotter/ChartPlotter.cs new file mode 100644 index 0000000..736970a --- /dev/null +++ b/HisDataTools/Chart/Plotter/ChartPlotter.cs @@ -0,0 +1,180 @@ +#region <版 本 注 释> +/* + * ======================================================================== + * Copyright(c) 四川*******公司, All Rights Reserved. + * ======================================================================== + * + * 作者:[HeBianGu] 时间:2018/1/18 11:28:41 + * 文件名:ChartPlotter + * 说明: + * + * + * 修改者: 时间: + * 修改说明: + * ======================================================================== +*/ +#endregion +using HeBianGu.WPF.EChart; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Media; + +namespace HeBianGu.WPF.EChart +{ + + /// 图表基类 + public abstract class ChartPlotter : ViewPlotter + { + #region - 基础方法 - + + /// 获取值对应Canvas的位置 + public double GetY(double value) + { + if ((this.MaxValueY - this.MinValueY) == 0) return 0; + var bottom = this.ParallelCanvas.ActualHeight - ((value - this.MinValueY) / (this.MaxValueY - this.MinValueY)) * this.ParallelCanvas.ActualHeight; + + return bottom; + } + + /// 获取值对应Canvas的位置 + public double GetX(double value) + { + if ((this.MaxValueX - this.MinValueX) == 0) return 0; + var bottom = ((value - this.MinValueX) / (this.MaxValueX - this.MinValueX)) * this.ParallelCanvas.ActualWidth; + + + return bottom; + } + + /// 获取值对应Canvas的位置应有的 Y 值 + public double GetYValue(double value) + { + //var bottom = this.ParallelCanvas.ActualHeight - ((value - this.MinValueY) / (this.MaxValueY - this.MinValueY)) * this.ParallelCanvas.ActualHeight; + + var bottom = (((this.ParallelCanvas.ActualHeight - value) / this.ParallelCanvas.ActualHeight) * (this.MaxValueY - this.MinValueY)) + this.MinValueY; + return bottom; + } + + #endregion + + #region - 控制参数 - + + + public double MinValueY + { + get { return (double)GetValue(MinValueYProperty); } + set { SetValue(MinValueYProperty, value); } + } + + // Using a DependencyProperty as the backing store for MinValueX. This enables animation, styling, binding, etc... + public static readonly DependencyProperty MinValueYProperty = + DependencyProperty.Register("MinValueY", typeof(double), typeof(ChartPlotter), new PropertyMetadata(0.0)); + + + + public double MaxValueY + { + get { return (double)GetValue(MaxValueYProperty); } + set { SetValue(MaxValueYProperty, value); } + } + + // Using a DependencyProperty as the backing store for MaxValueX. This enables animation, styling, binding, etc... + public static readonly DependencyProperty MaxValueYProperty = + DependencyProperty.Register("MaxValueY", typeof(double), typeof(ChartPlotter), new PropertyMetadata(0.0)); + + //private double _maxValueX; + ///// 要显示的最大值 + //public double MaxValueX + //{ + // get { return _maxValueX; } + // set { _maxValueX = value; } + //} + + //private double _minValueX; + ///// 要显示的最小值 + //public double MinValueX + //{ + // get { return _minValueX; } + // set { _minValueX = value; } + //} + + public double MinValueX + { + get { return (double)GetValue(MinValueXProperty); } + set { SetValue(MinValueXProperty, value); } + } + + // Using a DependencyProperty as the backing store for MinValueX. This enables animation, styling, binding, etc... + public static readonly DependencyProperty MinValueXProperty = + DependencyProperty.Register("MinValueX", typeof(double), typeof(ChartPlotter), new PropertyMetadata(0.0)); + + + + public double MaxValueX + { + get { return (double)GetValue(MaxValueXProperty); } + set { SetValue(MaxValueXProperty, value); } + } + + // Using a DependencyProperty as the backing store for MaxValueX. This enables animation, styling, binding, etc... + public static readonly DependencyProperty MaxValueXProperty = + DependencyProperty.Register("MaxValueX", typeof(double), typeof(ChartPlotter), new PropertyMetadata(0.0)); + + + //private List _splitItemYs = new List(); + ///// Y范围分割线 + //public List SplitItemYs + //{ + // get { return _splitItemYs; } + // set { _splitItemYs = value; } + //} + + + + public List SplitItemYs + { + get { return (List)GetValue(SplitItemYsProperty); } + set { SetValue(SplitItemYsProperty, value); } + } + + // Using a DependencyProperty as the backing store for SplitItemYs. This enables animation, styling, binding, etc... + public static readonly DependencyProperty SplitItemYsProperty = DependencyProperty.Register("SplitItemYs", typeof(List), typeof(ChartPlotter), new PropertyMetadata(null)); + + + + private List _slpitItemXs = new List(); + /// 说明 + public List SlpitItemXs + { + get { return _slpitItemXs; } + set { _slpitItemXs = value; } + } + + + + //public List SlpitItemXs + //{ + // get { return (List)GetValue(SlpitItemXsProperty); } + // set { SetValue(SlpitItemXsProperty, value); } + //} + + //// Using a DependencyProperty as the backing store for SlpitItemXs. This enables animation, styling, binding, etc... + //public static readonly DependencyProperty SlpitItemXsProperty = + // DependencyProperty.Register("SlpitItemXs", typeof(List), typeof(ChartPlotter), new PropertyMetadata(new List())); + + + + #endregion + + + + + + } + + +} diff --git a/HisDataTools/Chart/Plotter/Common/CursorGraphLine.xaml b/HisDataTools/Chart/Plotter/Common/CursorGraphLine.xaml new file mode 100644 index 0000000..dd754ec --- /dev/null +++ b/HisDataTools/Chart/Plotter/Common/CursorGraphLine.xaml @@ -0,0 +1,75 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/HisDataTools/Chart/Plotter/Common/CursorGraphLine.xaml.cs b/HisDataTools/Chart/Plotter/Common/CursorGraphLine.xaml.cs new file mode 100644 index 0000000..f953a64 --- /dev/null +++ b/HisDataTools/Chart/Plotter/Common/CursorGraphLine.xaml.cs @@ -0,0 +1,330 @@ +using HeBianGu.WPF.EChart; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; +using System.Windows.Shapes; + +namespace HeBianGu.General.WpfChart +{ + /// 浮动标尺控件 + public partial class CursorGraphLine : UserControl + { + + CurveChartPlotter _curve; + + List _items = new List(); + public CursorGraphLine(CurveChartPlotter c) + { + InitializeComponent(); + + _curve = c; + + this.content.Visibility = Visibility.Hidden; + } + + #region - 绘图方法 - + + ///// 绑定到指定曲线图中 + //public static void BindingInTo(CurveChartPlotter c) + //{ + // CursorGraphLine cursorgraphline = new CursorGraphLine(); + + // cursorgraphline._curve = c; + + // cursorgraphline.SetParent(c.ParallelCanvas); + //} + + public void SetParent(Canvas c) + { + this.content.Width = c.ActualWidth; + this.content.Height = c.ActualHeight; + + c.MouseMove += parent_MouseMove; + c.MouseEnter += Parent_MouseEnter; + c.MouseLeave += Parent_MouseLeave; + + // Todo :增加蒙版用于响应事件 + Rectangle r1 = new Rectangle(); + r1.Width = c.ActualWidth; + r1.Height = c.ActualHeight; + r1.Fill = Brushes.Transparent; + Canvas.SetTop(r1, 0); + c.Children.Add(r1); + c.Children.Add(this); + + foreach (var item in _curve.DataSource) + { + if (item.Visibility != Visibility.Visible) continue; + + LineLegendDetail con = new LineLegendDetail(item); + + Style s = this.TryFindResource("DefaultLineLegendDetail") as Style; + con.Style = s; + + this._items.Add(con); + if (item.Marker.Parent != null) + { + this.content.Children.Add(item.Marker.Clone()); + } + else + { + this.content.Children.Add(item.Marker); + } + + this.stackPanel.Children.Add(con); + } + + } + + + /// 刷新ToolTip + public void Refresh() + { + this._items.Clear(); + + this.stackPanel.Children.Clear(); + + foreach (var item in _curve.DataSource) + { + if (item.Visibility != Visibility.Visible) continue; + + LineLegendDetail con = new LineLegendDetail(item); + + Style s = this.TryFindResource("DefaultLineLegendDetail") as Style; + + con.Style = s; + + this._items.Add(con); + + //this.content.Children.Add(item.Marker); + + this.stackPanel.Children.Add(con); + } + } + + + double param = 20; + void parent_MouseMove(object sender, MouseEventArgs e) + { + if (_items.Count == 0) + { + this.Visibility = Visibility.Hidden; return; + } + + this.Visibility = Visibility.Visible; + + // Todo :检测设置是否只显示有效值 + Point mousePos = Mouse.GetPosition(this); + + bool isHaveValue = false; + + foreach (var item in _items) + { + var f = item.Curve.Source.Find(l => Math.Abs(_curve.GetX(l.X) - mousePos.X) < param); + + if (f != null) + { + isHaveValue = true; + mousePos.X = _curve.GetX(f.X); + this.tb_title.Text = f.Text; + break; + } + } + + if (this.IsOnlyHasValue) + { + if (!isHaveValue) + { + return; + } + } + + // Todo :说明 + RefreshRepresentation(mousePos); + + // Todo :说明 + RefreshCurveSource(mousePos); + } + + bool _isCenteryOnly = true; + /// 绘制标尺线 + private void RefreshRepresentation(Point mousePos) + { + // Todo :移动坐标线 + horizLine.X1 = 0; + horizLine.X2 = this.content.ActualWidth; + horizLine.Y1 = mousePos.Y; + horizLine.Y2 = mousePos.Y; + + vertLine.X1 = mousePos.X; + vertLine.X2 = mousePos.X; + vertLine.Y1 = 0; + vertLine.Y2 = this.content.ActualHeight; + + double space = 10; + + Canvas.SetLeft(this.grid_center, mousePos.X + space); + + + Canvas.SetBottom(this.grid_center, _isCenteryOnly ? 0: mousePos.Y + space); + + if (this.content.ActualWidth - mousePos.X < this.stackPanel.ActualWidth + space) + { + Canvas.SetLeft(this.grid_center, mousePos.X - this.stackPanel.ActualWidth - space); + } + + if (this.content.ActualHeight - mousePos.Y < this.stackPanel.ActualHeight + space) + { + Canvas.SetBottom(this.grid_center, _isCenteryOnly ? 0: mousePos.Y - this.stackPanel.ActualHeight - space); + } + } + + /// 绘制和曲线的焦点标记 + void RefreshCurveSource(Point mousePos) + { + foreach (var item in _items) + { + var minXC = item.Curve.Source.FindLast(l => _curve.GetX(l.X) <= mousePos.X); + var maxXC = item.Curve.Source.Find(l => _curve.GetX(l.X) >= mousePos.X); + + if (minXC == null || maxXC == null) continue; + + Point minX = new Point(_curve.GetX(minXC.X), _curve.GetY(minXC.Y)); + + + Point maxX = new Point(_curve.GetX(maxXC.X), _curve.GetY(maxXC.Y)); + + double xpercent = maxX.X == minX.X ? 0 : (mousePos.X - minX.X) / (maxX.X - minX.X); + + // Todo :焦点的Y值 + double resultY = xpercent * (maxX.Y - minX.Y) + minX.Y; + + item.Curve.Marker.Stroke = this.horizLine.Stroke; + item.Curve.Marker.Fill = this.horizLine.Stroke; + + Point cross = new Point(mousePos.X, resultY); + Canvas.SetLeft(item.Curve.Marker, cross.X); + Canvas.SetTop(item.Curve.Marker, cross.Y); + + string value = Math.Round(this._curve.GetYValue(resultY), 2).ToString(); + + item.RefreshValue(value); + } + + } + + private void Parent_MouseEnter(object sender, MouseEventArgs e) + { + if (AutoHide) + { + horizLine.Visibility = ShowHorizontalLine ? Visibility.Visible : Visibility.Hidden; + vertLine.Visibility = ShowVerticalLine ? Visibility.Visible : Visibility.Hidden; + this.grid_center.Visibility = Visibility; + + this.content.Visibility = Visibility; + } + } + + private void Parent_MouseLeave(object sender, MouseEventArgs e) + { + if (AutoHide) + { + horizLine.Visibility = Visibility.Hidden; + vertLine.Visibility = Visibility.Hidden; + this.grid_center.Visibility = Visibility.Hidden; + this.content.Visibility = Visibility.Hidden; + } + } + + #endregion + + #region - 绑定属性 - + + + #region LineStroke property + + public Brush LineStroke + { + get { return (Brush)GetValue(LineStrokeProperty); } + set { SetValue(LineStrokeProperty, value); } + } + + public static readonly DependencyProperty LineStrokeProperty = DependencyProperty.Register( + "LineStroke", + typeof(Brush), + typeof(CursorGraphLine), + new PropertyMetadata(new SolidColorBrush(Color.FromArgb(170, 86, 86, 86)))); + + #endregion + + #region LineStrokeThickness property + + public double LineStrokeThickness + { + get { return (double)GetValue(LineStrokeThicknessProperty); } + set { SetValue(LineStrokeThicknessProperty, value); } + } + + public static readonly DependencyProperty LineStrokeThicknessProperty = DependencyProperty.Register( + "LineStrokeThickness", + typeof(double), + typeof(CursorGraphLine), + new PropertyMetadata(2.0)); + + #endregion + + #region LineStrokeDashArray property + + public DoubleCollection LineStrokeDashArray + { + get { return (DoubleCollection)GetValue(LineStrokeDashArrayProperty); } + set { SetValue(LineStrokeDashArrayProperty, value); } + } + + public static readonly DependencyProperty LineStrokeDashArrayProperty = DependencyProperty.Register( + "LineStrokeDashArray", + typeof(DoubleCollection), + typeof(CursorGraphLine), + new FrameworkPropertyMetadata(new DoubleCollection(new double[] { 3, 3 }))); + + #endregion + + #endregion + + #region - 控制变量 - + + bool showHorizontalLine = false; + bool showVerticalLine = true; + bool autoHide = true; + bool _isOnlyHasValue = true; + + /// 设置成true则只显示有效值部分的浮动标尺 + public bool IsOnlyHasValue { get => _isOnlyHasValue; set => _isOnlyHasValue = value; } + + + /// 设置标尺离开绘图区域是否自动隐藏 + public bool AutoHide { get => autoHide; set => autoHide = value; } + + + /// 是否显示竖直方向标尺 + public bool ShowVerticalLine { get => showVerticalLine; set => showVerticalLine = value; } + + /// 是否显示水平方向标尺 + public bool ShowHorizontalLine { get => showHorizontalLine; set => showHorizontalLine = value; } + + #endregion + + } + + +} diff --git a/HisDataTools/Chart/Plotter/Common/LineLegendDetail.xaml b/HisDataTools/Chart/Plotter/Common/LineLegendDetail.xaml new file mode 100644 index 0000000..ab09847 --- /dev/null +++ b/HisDataTools/Chart/Plotter/Common/LineLegendDetail.xaml @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/HisDataTools/Chart/Plotter/Common/LineLegendDetail.xaml.cs b/HisDataTools/Chart/Plotter/Common/LineLegendDetail.xaml.cs new file mode 100644 index 0000000..b58cb09 --- /dev/null +++ b/HisDataTools/Chart/Plotter/Common/LineLegendDetail.xaml.cs @@ -0,0 +1,102 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; +using System.Windows.Shapes; + +namespace HeBianGu.WPF.EChart +{ + /// 直线图例 + public partial class LineLegendDetail : LegendItem + { + + ICurveEntitySource _curve; + public LineLegendDetail(ICurveEntitySource c) + { + _curve = c; + + this.Color = c.Color; + this.Text = c.Text; + this.Marker = c.Marker.Clone(); + + this.Checked += LineLegendItem_Checked; + this.Unchecked += LineLegendItem_Checked; + } + + private void LineLegendItem_Checked(object sender, RoutedEventArgs e) + { + Curve.Visibility = this.IsChecked.Value ? Visibility.Hidden : Visibility.Visible; + } + + public Brush Color + { + get { return (Brush)GetValue(ColorProperty); } + set { SetValue(ColorProperty, value); } + } + + // Using a DependencyProperty as the backing store for Color. This enables animation, styling, binding, etc... + public static readonly DependencyProperty ColorProperty = + DependencyProperty.Register("Color", typeof(Brush), typeof(LineLegendDetail), new PropertyMetadata(Brushes.Black)); + + + public string Value + { + get { return (string)GetValue(ValueProperty); } + set { SetValue(ValueProperty, value); } + } + + // Using a DependencyProperty as the backing store for Value. This enables animation, styling, binding, etc... + public static readonly DependencyProperty ValueProperty = + DependencyProperty.Register("Value", typeof(string), typeof(LineLegendDetail), new PropertyMetadata("")); + + + + public string Text + { + get { return (string)GetValue(TextProperty); } + set { SetValue(TextProperty, value); } + } + + // Using a DependencyProperty as the backing store for Text. This enables animation, styling, binding, etc... + public static readonly DependencyProperty TextProperty = + DependencyProperty.Register("Text", typeof(string), typeof(LineLegendDetail), new PropertyMetadata("")); + + + + + public ShapePointMarker Marker + { + get { return (ShapePointMarker)GetValue(MarkerProperty); } + set { SetValue(MarkerProperty, value); } + } + + public ICurveEntitySource Curve { get => _curve; set => _curve = value; } + + // Using a DependencyProperty as the backing store for Marker. This enables animation, styling, binding, etc... + public static readonly DependencyProperty MarkerProperty = + DependencyProperty.Register("Marker", typeof(ShapePointMarker), typeof(LineLegendDetail), new PropertyMetadata(null)); + + + public void RefreshValue(string text) + { + //v.Text = text; + + this.Value = " : " + text; + } + + static LineLegendDetail() + { + DefaultStyleKeyProperty.OverrideMetadata(typeof(LineLegendDetail), new FrameworkPropertyMetadata(typeof(LineLegendDetail))); + } + } +} diff --git a/HisDataTools/Chart/Plotter/Common/PointC.cs b/HisDataTools/Chart/Plotter/Common/PointC.cs new file mode 100644 index 0000000..d5a7d32 --- /dev/null +++ b/HisDataTools/Chart/Plotter/Common/PointC.cs @@ -0,0 +1,59 @@ +#region <版 本 注 释> +/* + * ======================================================================== + * Copyright(c) 四川*******公司, All Rights Reserved. + * ======================================================================== + * + * 作者:[HeBianGu] 时间:2018/1/18 12:37:03 + * 文件名:Class1 + * 说明: + * + * + * 修改者: 时间: + * 修改说明: + * ======================================================================== +*/ +#endregion +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; + +namespace HeBianGu.WPF.EChart +{ + + /// 数据源点 + public class PointC : DependencyObject + { + private double _x; + /// 说明 + public double X + { + get { return _x; } + set { _x = value; } + } + + private double _y; + /// 说明 + public double Y + { + get { return _y; } + set { _y = value; } + } + + private string _text; + /// 说明 + public string Text + { + get { return _text; } + set { _text = value; } + } + + public Point ToPoint() + { + return new Point(this.X, this.Y); + } + } +} diff --git a/HisDataTools/Chart/Plotter/Common/SplitItem.cs b/HisDataTools/Chart/Plotter/Common/SplitItem.cs new file mode 100644 index 0000000..336dbb6 --- /dev/null +++ b/HisDataTools/Chart/Plotter/Common/SplitItem.cs @@ -0,0 +1,120 @@ +#region <版 本 注 释> +/* + * ======================================================================== + * Copyright(c) 四川*******公司, All Rights Reserved. + * ======================================================================== + * + * 作者:[HeBianGu] 时间:2018/1/19 16:45:44 + * 文件名:Class1 + * 说明: + * + * + * 修改者: 时间: + * 修改说明: + * ======================================================================== +*/ +#endregion +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Media; + +namespace HeBianGu.WPF.EChart +{ + /// 网格分割线 + public class SplitItem : FrameworkElement + { + private double _value; + /// + public double Value + { + get { return _value; } + set { _value = value; } + } + + private Brush _color; + /// 颜色 + public Brush Color + { + get { return _color; } + set { _color = value; } + } + + private string _text; + /// 文本 + public string Text + { + get { return _text; } + set { _text = value; } + } + + private SplitItemType _spliteType; + /// 说明 + public SplitItemType SpliteType + { + get { return _spliteType; } + set { _spliteType = value; } + } + + public Style LineStyle + { + get { return (Style)GetValue(LineStyleProperty); } + set { SetValue(LineStyleProperty, value); } + } + + // Using a DependencyProperty as the backing store for LineStyle. This enables animation, styling, binding, etc... + public static readonly DependencyProperty LineStyleProperty = + DependencyProperty.Register("LineStyle", typeof(Style), typeof(SplitItem), new PropertyMetadata(null)); + + + public string Group + { + get { return (string)GetValue(GroupProperty); } + set { SetValue(GroupProperty, value); } + } + + // Using a DependencyProperty as the backing store for Group. This enables animation, styling, binding, etc... + public static readonly DependencyProperty GroupProperty = + DependencyProperty.Register("Group", typeof(string), typeof(SplitItem), new PropertyMetadata(null)); + + + public bool IsShowTrangle + { + get { return (bool)GetValue(IsShowTrangleProperty); } + set { SetValue(IsShowTrangleProperty, value); } + } + + // Using a DependencyProperty as the backing store for IsShowTrangle. This enables animation, styling, binding, etc... + public static readonly DependencyProperty IsShowTrangleProperty = + DependencyProperty.Register("IsShowTrangle", typeof(bool), typeof(SplitItem), new PropertyMetadata(true)); + + + + public bool IsShowText + { + get { return (bool)GetValue(IsShowTextProperty); } + set { SetValue(IsShowTextProperty, value); } + } + + // Using a DependencyProperty as the backing store for IsShowText. This enables animation, styling, binding, etc... + public static readonly DependencyProperty IsShowTextProperty = + DependencyProperty.Register("IsShowText", typeof(bool), typeof(SplitItem), new PropertyMetadata(true)); + + } + + + /// 线坐标类型 + public enum SplitItemType + { + /// 正常线 + Normal = 0, + /// 特殊线 + HeighLight, + + /// 只显示内部网格线 + InnerOnly + } +} diff --git a/HisDataTools/Chart/Plotter/CurveChartPlotter.cs b/HisDataTools/Chart/Plotter/CurveChartPlotter.cs new file mode 100644 index 0000000..fa0454f --- /dev/null +++ b/HisDataTools/Chart/Plotter/CurveChartPlotter.cs @@ -0,0 +1,717 @@ +#region <版 本 注 释> +/* + * ======================================================================== + * Copyright(c) 四川*******公司, All Rights Reserved. + * ======================================================================== + * + * 作者:[HeBianGu] 时间:2018/1/18 11:29:45 + * 文件名:CurveChartPlotter + * 说明: + * + * + * 修改者: 时间: + * 修改说明: + * ======================================================================== +*/ +#endregion +using HeBianGu.General.WpfChart; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Shapes; + +namespace HeBianGu.WPF.EChart +{ + + /// 曲线图图表 + public abstract class CurveChartPlotter : ChartPlotter + { + + public CurveChartPlotter() + { + this.Loaded += CurveChartPlotter_Loaded; + } + + private void CurveChartPlotter_Loaded(object sender, RoutedEventArgs e) + { + RefreshCurve(); + } + + + public void Clear() + { + this.CenterBottomCanvas.Children.Clear(); + + this.LeftCanvas.Children.Clear(); + + this.RightCanvas.Children.Clear(); + + this.BottomCanvas.Children.Clear(); + + this.TopCanvas.Children.Clear(); + + this.ParallelCanvas.Children.Clear(); + + + this.PathCanvas.Children.Clear(); + } + /// 刷新数据 + void RefreshCurve() + { + this.Clear(); + + this.RefreshXYZoom(); + + this.RefreshSplitItemY(); + + this.RefreshSplitItemX(); + + this.RefreshDataSource(); + + this.RefreshLegend(); + + this.RefreshCursorGraph(); + + // Todo :注册刷新事件 + foreach (var item in this.DataSource) + { + item.VisibleChanged += () => + { + if (_graphLine != null) + { + _graphLine.Refresh(); + + //this.RefreshXYZoom(); + } + }; + } + } + + #region - 元素绘制 - + + /// 刷新标尺线 + void RefreshSplitItemY() + { + if (this.SplitItemYs == null) return; + + var t = this.TryFindResource("line") as Style; + + var d = this.TryFindResource("dashCapline") as Style; + + var a = this.TryFindResource("pathTrangle") as Style; + + //var rs = this.TryFindResource("MarkBoardRectangle") as Style; + + var color = this.TryFindResource("MaxLineColor") as Brush; + + + // Todo :绘制普通网格线 + var ns = this.SplitItemYs.FindAll(l => l.SpliteType == SplitItemType.Normal || l.SpliteType == SplitItemType.InnerOnly); + + foreach (var item in ns) + { + Line l = new Line(); + l.X1 = 0; + l.Y1 = 0; + l.Y2 = 0; + l.Height = 5; + if (item.Color != null) l.Stroke = item.Color; + l.X2 = ParallelCanvas.ActualWidth; + l.Style = this.InnerVerticalLineStyle == null ? t : this.InnerVerticalLineStyle; + l.Style = item.LineStyle == null ? l.Style : item.LineStyle; + Canvas.SetTop(l, this.GetY(item.Value)); + this.ParallelCanvas.Children.Add(l); + } + + // Todo :绘制范围网格线 + var hs = this.SplitItemYs.FindAll(l => l.SpliteType == SplitItemType.HeighLight); + + foreach (var item in hs) + { + Line l = new Line(); + l.X1 = 0; + l.Y1 = 0; + l.Y2 = 0; + l.Height = 5; + if (item.Color != null) l.Stroke = item.Color; + l.Style = item.LineStyle == null ? l.Style : item.LineStyle; + + l.X2 = ParallelCanvas.ActualWidth + ParallelCanvas.ActualWidth / 100; + l.Style = d; + Canvas.SetTop(l, this.GetY(item.Value)); + + if (!this.IsShowTrangle) continue; + + // Todo :绘制三角箭头 + Path p = new Path(); + p.Width = 20; + p.Height = 6; + p.Style = a; + p.Fill = item.Color; + p.Stretch = Stretch.Fill; + if (item.Color != null) l.Stroke = item.Color; + Canvas.SetTop(p, this.GetY(item.Value) - p.Height / 2); + Canvas.SetLeft(p, l.X2 - ParallelCanvas.ActualWidth); + + // Todo :绘制文本 + TextBlock text = new TextBlock(); + text.Text = item.Text; + text.FontSize = this.FontSize; + text.Foreground = item.Color; + Canvas.SetLeft(text, l.X2 - ParallelCanvas.ActualWidth); + + if (item.IsShowTrangle) + { + Canvas.SetTop(text, this.GetY(item.Value) + p.Height / 2); + } + else + { + Canvas.SetTop(text, this.GetY(item.Value) - this.FontSize / 2); + } + + Canvas.SetLeft(l, -ParallelCanvas.ActualWidth); + + // Todo :不隐藏 + if (item.IsShowTrangle) + { + this.RightCanvas.Children.Add(p); + this.RightCanvas.Children.Add(l); + } + + if (item.IsShowText) + this.RightCanvas.Children.Add(text); + } + + if (hs.Count < 2) return; + + // Todo :增加最大最小蒙版 + //_maxMinRectVisible = true; + if (_maxMinRectVisible) + { + if (!hs.Exists(l => (l.Value - this.MinValueY) < double.Epsilon)) + { + SplitItem sMin = new SplitItem(); + sMin.Color = color; + sMin.Value = this.MinValueY; + hs.Add(sMin); + } + + if (!hs.Exists(l => (this.MaxValueY - l.Value) < double.Epsilon)) + { + SplitItem sMax = new SplitItem(); + sMax.Color = color; + sMax.Value = this.MaxValueY; + hs.Add(sMax); + } + } + + hs = hs.OrderByDescending(l => l.Value).ToList(); + + var group = hs.GroupBy(l => l.Group); + + foreach (var item in group) + { + var collection = item.ToList(); + + // Todo :绘制蒙版 + for (int i = 0; i < item.ToList().Count; i++) + { + if (i == 0) continue; + + Rectangle r = new Rectangle(); + r.Width = this.ParallelCanvas.ActualWidth; + var height = this.GetY(collection[i].Value) - this.GetY(collection[i - 1].Value); + if (height < 0) continue; + r.Height = height; + r.Fill = Brushes.Orange; + r.Opacity = this.CoverOpacity; + //r.Style = rs; + + Color color1 = (Color)ColorConverter.ConvertFromString(collection[i - 1].Color.ToString()); + Color color2 = (Color)ColorConverter.ConvertFromString(collection[i].Color.ToString()); + + LinearGradientBrush brush = new LinearGradientBrush(color1, color2, new Point(0, 0), new Point(0, 1)); + r.Fill = brush; + + Canvas.SetTop(r, this.GetY(collection[i - 1].Value)); + + this.ParallelCanvas.Children.Add(r); + } + } + + } + + /// 刷新标尺线 + void RefreshSplitItemX() + { + var t = this.TryFindResource("line") as Style; + + var d = this.TryFindResource("dashCapline") as Style; + + var a = this.TryFindResource("pathTrangle") as Style; + + var rs = this.TryFindResource("MarkBoardRectangle") as Style; + + var color = this.TryFindResource("MaxLineColor") as Brush; + + + // Todo :绘制普通网格线 + var ns = this.SlpitItemXs.FindAll(l => l.SpliteType == SplitItemType.Normal || l.SpliteType == SplitItemType.InnerOnly); + + foreach (var item in ns) + { + Line l = new Line(); + l.X1 = 0; + l.Y1 = 0; + l.Y2 = ParallelCanvas.ActualHeight; + l.Stroke = item.Color; + l.X2 = 0; + l.Width = 5; + l.Style = this.InnerHorizontalLineStyle == null ? l.Style = t : this.InnerHorizontalLineStyle; + l.Style = item.LineStyle == null ? l.Style : item.LineStyle; + + Canvas.SetLeft(l, this.GetX(item.Value)); + this.ParallelCanvas.Children.Add(l); + } + return; + } + + private bool _maxMinRectVisible = false; + /// 说明 + public bool MaxMinRectVisible + { + get { return _maxMinRectVisible; } + set { _maxMinRectVisible = value; } + } + /// 刷新坐标轴 + void RefreshXYZoom() + { + this.BottomCanvas.Children.Clear(); + + this.LeftCanvas.Children.Clear(); + + double param = 5; + + var ts = this.TryFindResource("XCenterLable") as Style; + var tsright = this.TryFindResource("YRightLable") as Style; + //var d = this.TryFindResource("dashCapline") as Style; + + + // Todo :绘制轮廓 + Line xleft = new Line(); + xleft.X1 = 0; + xleft.X2 = 0; + xleft.Y1 = 0; + xleft.Y2 = this.ParallelCanvas.ActualHeight; + xleft.Stroke = this.Foreground; + xleft.StrokeThickness = 1; + Canvas.SetLeft(xleft, 0); + + Line xright = new Line(); + xright.X1 = 0; + xright.X2 = 0; + xright.Y1 = 0; + xright.Y2 = this.ParallelCanvas.ActualHeight; + xright.Stroke = this.Foreground; + xright.StrokeThickness = 1; + Canvas.SetRight(xright, 0); + + Line yleft = new Line(); + yleft.X1 = 0; + yleft.X2 = this.ParallelCanvas.ActualWidth; + yleft.Y1 = 0; + yleft.Y2 = 0; + yleft.Stroke = this.Foreground; + yleft.StrokeThickness = 1; + Canvas.SetTop(yleft, 0); + + Line yright = new Line(); + yright.X1 = 0; + yright.X2 = this.ParallelCanvas.ActualWidth; + yright.Y1 = 0; + yright.Y2 = 0; + yright.Stroke = this.Foreground; + yright.StrokeThickness = 1; + Canvas.SetBottom(yright, 0); + + + this.ParallelCanvas.Children.Add(xleft); + this.ParallelCanvas.Children.Add(xright); + this.ParallelCanvas.Children.Add(yleft); + this.ParallelCanvas.Children.Add(yright); + + + // Todo :绘制X坐标轴 + if (!this.IsAutoXAxis) + { + //X坐标 + foreach (var item in this.SlpitItemXs) + { + if (item.SpliteType == SplitItemType.InnerOnly) continue; + + Line l = new Line(); + l.X1 = 0; + l.X2 = 0; + l.Y1 = 0; + l.Y2 = param; + l.Stroke = this.Foreground; + Canvas.SetLeft(l, this.GetX(item.Value)); + this.BottomCanvas.Children.Add(l); + + Label t = new Label(); + t.Content = item.Text; + t.Style = ts; + t.Foreground = this.Foreground; + t.FontSize = this.FontSize; + + Canvas.SetLeft(t, this.GetX(item.Value) - t.Width / 2); + Canvas.SetTop(t, 2 * param - t.Height / 2); + this.BottomCanvas.Children.Add(t); + } + } + else + { + //List vs = new List(); + + //double minSpace = (this.MaxValueX - this.MinValueX) / AutoXAxisCount; + + //// Todo :按照实际值画坐标 + //foreach (var item in this.DataSource) + //{ + // if (item.Visibility != Visibility.Visible) continue; + + // foreach (var c in item.Source) + // { + // // Todo :存在在范围之内的不添加坐标 + // if (vs.Exists(k => Math.Abs(k.X - c.X) < minSpace)) continue; + + // Line l = new Line(); + // l.X1 = 0; + // l.X2 = 0; + // l.Y1 = 0; + // l.Y2 = param; + // l.Stroke = this.Foreground; + // Canvas.SetLeft(l, this.GetX(c.X)); + // this.BottomCanvas.Children.Add(l); + + // Label t = new Label(); + // t.Content = c.Text; + // t.Style = ts; + // t.FontSize = this.FontSize - 3; + // Canvas.SetLeft(t, this.GetX(c.X) - t.Width / 2); + // Canvas.SetTop(t, 2 * param - t.Height / 2); + // this.BottomCanvas.Children.Add(t); + + // // Todo :增加虚线 + // Line lx = new Line(); + // lx.X1 = 0; + // lx.X2 = 0; + // lx.Y1 = this.ParallelCanvas.ActualHeight - this.GetY(c.Y); + // lx.Y2 = 0; + // lx.Style = d; + // lx.Stroke = this.Foreground; + // lx.StrokeThickness = 0.5; + // Canvas.SetLeft(lx, this.GetX(c.X)); + // Canvas.SetBottom(lx, 0); + + // if (lx.Y1 > lx.Y2) + // { + // this.ParallelCanvas.Children.Add(lx); + + // item.ValueLines.Add(lx); + // } + + + // vs.Add(c.ToPoint()); + // } + //} + } + + if (this.SplitItemYs != null) + { + //Y坐标 + foreach (var item in this.SplitItemYs) + { + + if (item.SpliteType == SplitItemType.InnerOnly) continue; + + if (item.SpliteType == SplitItemType.Normal) + { + // Todo :绘制线 + Line l = new Line(); + l.X1 = 0; + l.X2 = param; + l.Y1 = 0; + l.Y2 = 0; + l.Stroke = this.Foreground; + Canvas.SetTop(l, this.GetY(item.Value)); + Canvas.SetRight(l, 0); + this.LeftCanvas.Children.Add(l); + + // Todo :绘制文本 + Label t = new Label(); + t.Content = item.Text; + t.FontSize = this.FontSize; + t.Foreground = this.Foreground; + t.Style = tsright; + Canvas.SetTop(t, this.GetY(item.Value) - t.Height / 2); + Canvas.SetRight(t, param); + this.LeftCanvas.Children.Add(t); + } + else + { + // Todo :绘制图标 + Ellipse e = new Ellipse(); + e.Fill = Brushes.White; + e.Stroke = item.Color; + e.Height = param; + e.Width = param; + Canvas.SetTop(e, this.GetY(item.Value) - param / 2); + Canvas.SetRight(e, -param / 2); + this.LeftCanvas.Children.Add(e); + } + + } + } + } + + /// 绘制图例 + void BindLegend(ICurveEntitySource item) + { + LineLegendItem l = new LineLegendItem(item); + Style s = this.TryFindResource("DefaultLineLegendItem") as Style; + l.Style = s; + l.Background = this.Background; + + this.legend.AddLegendItem(l); + } + + Legend legend; + /// 刷新数据源 + void RefreshDataSource() + { + // Todo :绘制数据 + foreach (var cs in this.DataSource) + { + cs.Draw(this); + } + } + + /// 刷新图例 + public void RefreshLegend() + { + legend = new Legend(); + + if (this.IsLegendVisible) + { + this.RightCanvas.Children.Add(legend); + } + + if (this.IsLegendVisible) + { + // Todo :绘制图例 + foreach (var cs in this.DataSource) + { + this.BindLegend(cs); + } + } + } + + private CursorGraphLine _graphLine; + + /// 说明 + public CursorGraphLine GraphLine + { + get { return _graphLine; } + set { _graphLine = value; } + } + + + /// 绘制浮动标尺线 + void RefreshCursorGraph() + { + if (!this.IsShowCursorLine) return; + + CursorGraphLine cursorgraphline = new CursorGraphLine(this); + + this._graphLine = cursorgraphline; + + cursorgraphline.SetParent(this.ParallelCanvas); + } + + + + #endregion + + #region - 依赖属性 - + + + + public double CoverOpacity + { + get { return (double)GetValue(CoverOpacityProperty); } + set { SetValue(CoverOpacityProperty, value); } + } + + // Using a DependencyProperty as the backing store for MyProperty. This enables animation, styling, binding, etc... + public static readonly DependencyProperty CoverOpacityProperty = + DependencyProperty.Register("CoverOpacity", typeof(double), typeof(CurveChartPlotter), new PropertyMetadata(0.1, (d, e) => + { + CurveChartPlotter control = d as CurveChartPlotter; + + if (control == null) return; + + //double config = e.NewValue as double; + + })); + + + public List DataSource + { + get { return (List)GetValue(DataSourceProperty); } + set { SetValue(DataSourceProperty, value); } + } + + // Using a DependencyProperty as the backing store for DataSource. This enables animation, styling, binding, etc... + public static readonly DependencyProperty DataSourceProperty = + DependencyProperty.Register("DataSource", typeof(List), typeof(CurveChartPlotter), new PropertyMetadata(new List(), PropertyChangedCallback)); + + + + /// 数据源改变是否触发动画 + public bool DataSourceChangeBegionStory + { + get { return (bool)GetValue(DataSourceChangeBegionStoryProperty); } + set { SetValue(DataSourceChangeBegionStoryProperty, value); } + } + + // Using a DependencyProperty as the backing store for DataSourceChangeBegionStory. This enables animation, styling, binding, etc... + public static readonly DependencyProperty DataSourceChangeBegionStoryProperty = + DependencyProperty.Register("DataSourceChangeBegionStory", typeof(bool), typeof(CurveChartPlotter), new PropertyMetadata(true)); + + + + + static void PropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + var control + = d as CurveChartPlotter; + + if (control.IsLoaded) + { + control.RefreshCurve(); + + if (control.DataSourceChangeBegionStory) + { + control.BeginStory(); + + } + } + + } + + + /// 是否启用图例 + public bool IsLegendVisible + { + get { return (bool)GetValue(IsLegendVisibleProperty); } + set { SetValue(IsLegendVisibleProperty, value); } + } + + // Using a DependencyProperty as the backing store for IsLegendVisible. This enables animation, styling, binding, etc... + public static readonly DependencyProperty IsLegendVisibleProperty = + DependencyProperty.Register("IsLegendVisible", typeof(bool), typeof(CurveChartPlotter), new PropertyMetadata(true)); + + + /// 是否显示上下左右坐标线 + public bool IsAsixBoth + { + get { return (bool)GetValue(IsAsixBothProperty); } + set { SetValue(IsAsixBothProperty, value); } + } + + // Using a DependencyProperty as the backing store for IsAsixBoth. This enables animation, styling, binding, etc... + public static readonly DependencyProperty IsAsixBothProperty = + DependencyProperty.Register("IsAsixBoth", typeof(bool), typeof(CurveChartPlotter), new PropertyMetadata(false)); + + + /// 是否显示范围值箭头 + public bool IsShowTrangle + { + get { return (bool)GetValue(ShowTrangleProperty); } + set { SetValue(ShowTrangleProperty, value); } + } + + + + // Using a DependencyProperty as the backing store for ShowTrangle. This enables animation, styling, binding, etc... + public static readonly DependencyProperty ShowTrangleProperty = + DependencyProperty.Register("IsShowTrangle", typeof(bool), typeof(CurveChartPlotter), new PropertyMetadata(true)); + + + + /// X坐标自动排列 + public bool IsAutoXAxis + { + get { return (bool)GetValue(IsShowXAxisProperty); } + set { SetValue(IsShowXAxisProperty, value); } + } + + // Using a DependencyProperty as the backing store for IsShowXAxis. This enables animation, styling, binding, etc... + public static readonly DependencyProperty IsShowXAxisProperty = + DependencyProperty.Register("IsAutoXAxis", typeof(bool), typeof(CurveChartPlotter), new PropertyMetadata(true)); + + + + /// 自动排列数量 + public int AutoXAxisCount + { + get { return (int)GetValue(AutoXAxisCountProperty); } + set { SetValue(AutoXAxisCountProperty, value); } + } + + // Using a DependencyProperty as the backing store for AutoXAxisCount. This enables animation, styling, binding, etc... + public static readonly DependencyProperty AutoXAxisCountProperty = + DependencyProperty.Register("AutoXAxisCount", typeof(int), typeof(CurveChartPlotter), new PropertyMetadata(12)); + + + /// 内部竖直网线样式 + public Style InnerVerticalLineStyle + { + get { return (Style)GetValue(InnerVerticalLineStyleProperty); } + set { SetValue(InnerVerticalLineStyleProperty, value); } + } + + // Using a DependencyProperty as the backing store for InnerVerticalLineStyle. This enables animation, styling, binding, etc... + public static readonly DependencyProperty InnerVerticalLineStyleProperty = + DependencyProperty.Register("InnerVerticalLineStyle", typeof(Style), typeof(CurveChartPlotter), new PropertyMetadata(null)); + + + /// 内部水平网线样式 + public Style InnerHorizontalLineStyle + { + get { return (Style)GetValue(InnerHorizontalLineStyleProperty); } + set { SetValue(InnerHorizontalLineStyleProperty, value); } + } + + // Using a DependencyProperty as the backing store for InnerHorizontalLineStyle. This enables animation, styling, binding, etc... + public static readonly DependencyProperty InnerHorizontalLineStyleProperty = + DependencyProperty.Register("InnerHorizontalLineStyle", typeof(Style), typeof(CurveChartPlotter), new PropertyMetadata(null)); + + private bool _isShowCursorLine = true; + /// 是否显示浮动光标 + public bool IsShowCursorLine + { + get { return _isShowCursorLine; } + set { _isShowCursorLine = value; } + } + + #endregion + } +} diff --git a/HisDataTools/Chart/Plotter/DataSource/CardiogramCurveEntitySource.cs b/HisDataTools/Chart/Plotter/DataSource/CardiogramCurveEntitySource.cs new file mode 100644 index 0000000..3345b65 --- /dev/null +++ b/HisDataTools/Chart/Plotter/DataSource/CardiogramCurveEntitySource.cs @@ -0,0 +1,65 @@ +#region <版 本 注 释> +/* + * ======================================================================== + * Copyright(c) 四川*******公司, All Rights Reserved. + * ======================================================================== + * + * 作者:[HeBianGu] 时间:2018/1/19 16:39:09 + * 文件名:Class1 + * 说明: + * + * + * 修改者: 时间: + * 修改说明: + * ======================================================================== +*/ +#endregion +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Media; +using System.Windows.Shapes; + +namespace HeBianGu.WPF.EChart +{ + /// 心电曲线图数据源 + public class CardiogramCurveEntitySource : BaseEntitySource + { + public override void Draw(CurveChartPlotter chart) + { + + var ps = chart.TryFindResource("CardiogramDefaultPath") as Style; + Path path = new Path(); + path.Style = ps; + + if (this.Color != null) + { + path.Stroke = this.Color; + } + + PolyLineSegment pls = new PolyLineSegment(); + + foreach (var item in this.Source) + { + // Todo :增加线 + Point ptem = new Point(chart.GetX(item.X), chart.GetY(item.Y)); + pls.Points.Add(ptem); + } + + PathFigure pf = new PathFigure(); + pf.StartPoint = pls.Points.FirstOrDefault(); + pf.Segments.Add(pls); + PathGeometry pg = new PathGeometry(new List() { pf }); + path.Data = pg; + chart.PathCanvas.Children.Add(path); + + + this.Elements.Clear(); + this.Elements.Add(path); + } + + } +} diff --git a/HisDataTools/Chart/Plotter/DataSource/CurveEntitySource.cs b/HisDataTools/Chart/Plotter/DataSource/CurveEntitySource.cs new file mode 100644 index 0000000..74d3611 --- /dev/null +++ b/HisDataTools/Chart/Plotter/DataSource/CurveEntitySource.cs @@ -0,0 +1,170 @@ +#region <版 本 注 释> +/* + * ======================================================================== + * Copyright(c) 四川*******公司, All Rights Reserved. + * ======================================================================== + * + * 作者:[HeBianGu] 时间:2018/1/17 16:43:40 + * 文件名:Class1 + * 说明: + * + * + * 修改者: 时间: + * 修改说明: + * ======================================================================== +*/ +#endregion +using HeBianGu.WPF.EChart; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Media; +using System.Windows.Shapes; + +namespace HeBianGu.WPF.EChart +{ + /// 普通曲线数据实体 + public class CurveEntitySource : BaseEntitySource + { + private int _markTextVisbleLeight = 15; + /// 设置要显示Mark文本的距离 防止过密显示 + public int MarkTextVisbleLeight + { + get { return _markTextVisbleLeight; } + set { _markTextVisbleLeight = value; } + } + + public override void Draw(CurveChartPlotter chart) + { + + if (chart.CenterBottomCanvas.ActualHeight == 0) + return; + + List es = new List(); + + var ps = chart.TryFindResource("DefaultCurvePath") as Style; + var ms = chart.TryFindResource("DefaultMarker") as Style; + + var ts = chart.TryFindResource("XCenterLable") as Style; + var d = chart.TryFindResource("XdashCapline") as Style; + + Path path = new Path(); + path.Style = ps; + path.Stroke = this.Color; + PolyLineSegment pls = new PolyLineSegment(); + + List vs = new List(); + + double minSpace = (chart.MaxValueX - chart.MinValueX) / chart.AutoXAxisCount; + + double param = 5; + + this.Elements.Clear(); + + foreach (var item in this.Source) + { + // Todo :增加线 + Point ptem = new Point(chart.GetX(item.X), chart.GetY(item.Y)); + + if (this.Marker != null && this.Marker.Visibility == Visibility.Visible) + { + ShapePointMarker m = Activator.CreateInstance(this.Marker.GetType()) as ShapePointMarker; + m.ScreenPoint = ptem; + m.Fill = this.Marker.Fill; + m.Stroke = this.Marker.Stroke; + m.Text = Math.Round(item.Y, 1).ToString(); + m.Style = ms; + + // Todo :如果周边有小于5的值不显示文本 + var f = es.Find(k => Math.Abs(k.ScreenPoint.X - ptem.X) < _markTextVisbleLeight && Math.Abs(k.ScreenPoint.Y - ptem.Y) < _markTextVisbleLeight); + + if (f != null && !string.IsNullOrEmpty(f.Text)) + { + m.Text = string.Empty; + } + es.Add(m); + } + + pls.Points.Add(ptem); + + // Todo :增加虚线 + + // Todo :存在在范围之内的不添加坐标 + if (vs.Exists(k => Math.Abs(k.X - item.X) < minSpace)) continue; + + Line l = new Line(); + l.X1 = 0; + l.X2 = 0; + l.Y1 = 0; + l.Y2 = param; + l.Stroke = chart.Foreground; + Canvas.SetLeft(l, chart.GetX(item.X)); + chart.BottomCanvas.Children.Add(l); + + this.Elements.Add(l); + + Label t = new Label(); + t.Content = item.Text; + t.Style = ts; + t.Foreground = chart.Foreground; + t.FontSize = chart.FontSize - 3; + Canvas.SetLeft(t, chart.GetX(item.X) - t.Width / 2); + Canvas.SetTop(t, 2 * param - t.Height / 2); + chart.BottomCanvas.Children.Add(t); + + this.Elements.Add(t); + + // Todo :增加虚线 + Line lx = new Line(); + lx.X1 = 0; + lx.X2 = 0; + lx.Y1 = chart.CenterBottomCanvas.ActualHeight - chart.GetY(item.Y); + lx.Y2 = 0; + lx.Width = 5; + lx.Style = d; + lx.Stroke = chart.Foreground; + lx.StrokeThickness = 0.5; + Canvas.SetLeft(lx, chart.GetX(item.X)); + Canvas.SetBottom(lx, 0); + + if (lx.Y1 > lx.Y2) + { + chart.CenterBottomCanvas.Children.Add(lx); + + this.Elements.Add(lx); + } + + vs.Add(item.ToPoint()); + + } + + PathFigure pf = new PathFigure(); + + pf.StartPoint = pls.Points.FirstOrDefault(); + pf.Segments.Add(pls); + PathGeometry pg = new PathGeometry(new List() { pf }); + path.Data = pg; + chart.PathCanvas.Children.Add(path); + + + this.Elements.Add(path); + + // Todo :绘制Marker + foreach (var item in es) + { + chart.ParallelCanvas.Children.Add(item); + + this.Elements.Add(item); + } + + } + + + } + + +} diff --git a/HisDataTools/Chart/Plotter/DataSource/ICurveEntitySource.cs b/HisDataTools/Chart/Plotter/DataSource/ICurveEntitySource.cs new file mode 100644 index 0000000..8c901f7 --- /dev/null +++ b/HisDataTools/Chart/Plotter/DataSource/ICurveEntitySource.cs @@ -0,0 +1,146 @@ +#region <版 本 注 释> +/* + * ======================================================================== + * Copyright(c) 四川*******公司, All Rights Reserved. + * ======================================================================== + * + * 作者:[HeBianGu] 时间:2018/1/19 16:39:59 + * 文件名:Class1 + * 说明: + * + * + * 修改者: 时间: + * 修改说明: + * ======================================================================== +*/ +#endregion +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Media; + +namespace HeBianGu.WPF.EChart +{ + /// 曲线数据源接口 + public interface ICurveEntitySource + { + /// 绘制方法 + void Draw(CurveChartPlotter chart); + + /// 数据集合 + List Source { get; set; } + + /// 曲线颜色 + Brush Color { get; set; } + + /// 标记 + ShapePointMarker Marker { get; set; } + + /// 名称 + string Text { get; set; } + + + /// 是否可见 + Visibility Visibility { get; set; } + + + event Action VisibleChanged; + + } + + + /// 抽象基类 + public abstract class BaseEntitySource : ICurveEntitySource + { + private List _source = new List(); + /// 说明 + public List Source + { + get { return _source; } + set { _source = value; } + } + + private Brush _color = Brushes.Black; + /// 曲线颜色 + public Brush Color + { + get { return _color; } + set { _color = value; } + } + + private ShapePointMarker _marker = new CirclePointMarker(); + /// 说明 + public ShapePointMarker Marker + { + get { return _marker; } + set { _marker = value; } + } + + + private string _text; + /// 文本 + public string Text + { + get { return _text; } + set { _text = value; } + } + + List _elements = new List(); + /// 包含的所有元素 + public List Elements + { + get { return _elements; } + set { _elements = value; } + } + + private Visibility _vsibility = Visibility.Visible; + /// 是否可见 + public Visibility Visibility + { + get { return _vsibility; } + set + { + foreach (var item in _elements) + { + item.Visibility = value; + } + + if (_vsibility != value) + { + _vsibility = value; + + if (_visibleChanged != null) + { + _visibleChanged(); + } + } + + + + + } + } + + + Action _visibleChanged; + + event Action ICurveEntitySource.VisibleChanged + { + add + { + _visibleChanged += value; + } + + remove + { + _visibleChanged -= value; + } + } + + public abstract void Draw(CurveChartPlotter chart); + } + +} diff --git a/HisDataTools/Chart/Plotter/Marker/CirclePointMarker.cs b/HisDataTools/Chart/Plotter/Marker/CirclePointMarker.cs new file mode 100644 index 0000000..84dd705 --- /dev/null +++ b/HisDataTools/Chart/Plotter/Marker/CirclePointMarker.cs @@ -0,0 +1,52 @@ +#region <版 本 注 释> +/* + * ======================================================================== + * Copyright(c) 四川*******公司, All Rights Reserved. + * ======================================================================== + * + * 作者:[HeBianGu] 时间:2018/1/19 16:41:51 + * 文件名:Class2 + * 说明: + * + * + * 修改者: 时间: + * 修改说明: + * ======================================================================== +*/ +#endregion +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Media; + +namespace HeBianGu.WPF.EChart +{ + + /// 圆环Marker + public class CirclePointMarker : ShapePointMarker + { + + /// 描绘形状 + protected override Geometry DefiningGeometry + { + get + { + EllipseGeometry e = new EllipseGeometry(ScreenPoint, this.Size / 2, this.Size / 2); + return e; + } + } + + protected override void OnRender(DrawingContext drawingContext) + { + base.OnRender(drawingContext); + + Pen p = new Pen(this.Fill, 1); + + drawingContext.DrawGeometry(Brushes.White, p, DefiningGeometry); + + //drawingContext.DrawGeometry(this.Fill, this.Pen, DefiningGeometry); + } + } +} diff --git a/HisDataTools/Chart/Plotter/Marker/IMark.cs b/HisDataTools/Chart/Plotter/Marker/IMark.cs new file mode 100644 index 0000000..5e3735b --- /dev/null +++ b/HisDataTools/Chart/Plotter/Marker/IMark.cs @@ -0,0 +1,679 @@ +using System; +using System.Collections.Generic; +using System.Data; +using System.Diagnostics; +using System.Linq; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Media; +using System.Windows.Shapes; + +namespace HeBianGu.WPF.EChart +{ + + #region - Base - + + //public delegate void MarkerRenderer(DrawingContext dc, Point screenPoint); + + ///// Renders markers along graph + //public abstract class PointMarker : DependencyObject + //{ + + // /// Renders marker on screen + // /// Drawing context to render marker on + // /// Point from data source + // /// Marker center coordinates on drawing context + // public abstract void Render(DrawingContext dc, Point screenPoint); + + // public static implicit operator PointMarker(MarkerRenderer renderer) + // { + // return FromRenderer(renderer); + // } + + // public static PointMarker FromRenderer(MarkerRenderer renderer) + // { + // return new DelegatePointMarker(renderer); + // } + //} + + ///// Invokes specified delegate for rendering custon marker + ///// at every point of graph + //public sealed class DelegatePointMarker : PointMarker + //{ + // public MarkerRenderer RenderCallback { get; set; } + + // public DelegatePointMarker() { } + // public DelegatePointMarker(MarkerRenderer renderCallback) + // { + // if (renderCallback == null) + // throw new ArgumentNullException("renderCallback"); + + // RenderCallback = renderCallback; + // } + + // public override void Render(DrawingContext dc, Point screenPoint) + // { + // RenderCallback(dc, screenPoint); + // } + //} + + #endregion + + /// Abstract class that extends PointMarker and contains + /// marker property as Pen, Brush and Size + public class ShapePointMarker : Shape + { + /// Size of marker in points + public double Size + { + get { return (double)GetValue(SizeProperty); } + set { SetValue(SizeProperty, value); } + } + + public static readonly DependencyProperty SizeProperty = + DependencyProperty.Register( + "Size", + typeof(double), + typeof(ShapePointMarker), + new FrameworkPropertyMetadata(5.0)); + + + /// Pen to outline marker + public Pen Pen + { + get { return (Pen)GetValue(PenProperty); } + set { SetValue(PenProperty, value); } + } + + public static readonly DependencyProperty PenProperty = + DependencyProperty.Register( + "Pen", + typeof(Pen), + typeof(ShapePointMarker), + new FrameworkPropertyMetadata(null)); + + + public new Brush Fill + { + get { return (Brush)GetValue(FillProperty); } + set { SetValue(FillProperty, value); } + } + + public new static readonly DependencyProperty FillProperty = + DependencyProperty.Register( + "Fill", + typeof(Brush), + typeof(ShapePointMarker), + new FrameworkPropertyMetadata(Brushes.Black)); + + + + public Point ScreenPoint + { + get { return (Point)GetValue(ScreenPointProperty); } + set { SetValue(ScreenPointProperty, value); } + } + + // Using a DependencyProperty as the backing store for ScreenPoint. This enables animation, styling, binding, etc... + public static readonly DependencyProperty ScreenPointProperty = + DependencyProperty.Register("ScreenPoint", typeof(Point), typeof(ShapePointMarker), new PropertyMetadata(new Point(0, 0))); + + + public string Text + { + get { return (string)GetValue(TextProperty); } + set { SetValue(TextProperty, value); } + } + + public static readonly DependencyProperty TextProperty = + DependencyProperty.Register( + "Text", + typeof(string), + typeof(ShapePointMarker), + new FrameworkPropertyMetadata("")); + + public int FontZize + { + get { return (int)GetValue(FontZizeProperty); } + set { SetValue(FontZizeProperty, value); } + } + + // Using a DependencyProperty as the backing store for FontZize. This enables animation, styling, binding, etc... + public static readonly DependencyProperty FontZizeProperty = + DependencyProperty.Register("FontZize", typeof(int), typeof(ShapePointMarker), new PropertyMetadata(10)); + + + + public Brush FontColor + { + get { return (Brush)GetValue(FontColorProperty); } + set { SetValue(FontColorProperty, value); } + } + + /// 描绘形状 + protected override Geometry DefiningGeometry + { + get + { + EllipseGeometry e = new EllipseGeometry(ScreenPoint, this.Size / 2, this.Size / 2); + return e; + } + } + + // Using a DependencyProperty as the backing store for FontColor. This enables animation, styling, binding, etc... + public static readonly DependencyProperty FontColorProperty = + DependencyProperty.Register("FontColor", typeof(Brush), typeof(ShapePointMarker), new PropertyMetadata(Brushes.Black)); + + + /// 绘制形状 + protected override void OnRender(DrawingContext drawingContext) + { + + //if (string.IsNullOrEmpty(Text)) return; + + //FormattedText textToDraw = new FormattedText(Text, Thread.CurrentThread.CurrentCulture, + // FlowDirection.LeftToRight, new Typeface("Arial"), FontZize, FontColor); + + //double width = textToDraw.Width; + //double height = textToDraw.Height; + //double verticalShift = -this.Size / 2; // px + + //Rect bounds = RectExtensions.FromCenterSize(new Point(ScreenPoint.X, ScreenPoint.Y + verticalShift - height / 2), + // new Size(width, height)); + + //Point loc = bounds.Location; + + //bounds = CoordinateUtilities.RectZoom(bounds, 1.05, 1.15); + + ////drawingContext.DrawLine(new Pen(Brushes.Black, 1), Point.Add(ScreenPoint, new Vector(0, verticalShift)), ScreenPoint); + ////drawingContext.DrawRectangle(Brushes.White, new Pen(Brushes.Black, 1), bounds); + //drawingContext.DrawText(textToDraw, loc); + + base.OnRender(drawingContext); + + Pen p = new Pen(this.Fill, 1); + + drawingContext.DrawGeometry(Brushes.White, p, DefiningGeometry); + } + + + /// 复制 + public virtual void CloneTo(ShapePointMarker mark) + { + mark.Fill = this.Fill; + mark.FontColor = this.FontColor; + mark.FontZize = this.FontZize; + mark.Pen = this.Pen; + mark.Text = this.Text; + mark.ScreenPoint = this.ScreenPoint; + } + + /// 复制 + public virtual ShapePointMarker Clone() + { + ShapePointMarker mark = Activator.CreateInstance(this.GetType()) as ShapePointMarker; + + mark.Fill = this.Fill; + mark.FontColor = this.FontColor; + mark.FontZize = this.FontZize; + mark.Pen = this.Pen; + mark.Text = this.Text; + mark.ScreenPoint = this.ScreenPoint; + + return mark; + } + + } + + #region - Tool - + + public static class RectExtensions + { + public static Point GetCenter(this Rect rect) + { + return new Point(rect.Left + rect.Width * 0.5, rect.Top + rect.Height * 0.5); + } + + public static Rect FromCenterSize(Point center, Size size) + { + return FromCenterSize(center, size.Width, size.Height); + } + + public static Rect FromCenterSize(Point center, double width, double height) + { + Rect res = new Rect(center.X - width / 2, center.Y - height / 2, width, height); + return res; + } + + public static Rect Zoom(this Rect rect, Point to, double ratio) + { + return CoordinateUtilities.RectZoom(rect, to, ratio); + } + + public static Rect ZoomX(this Rect rect, Point to, double ratio) + { + return CoordinateUtilities.RectZoomX(rect, to, ratio); + } + + public static Rect ZoomY(this Rect rect, Point to, double ratio) + { + return CoordinateUtilities.RectZoomY(rect, to, ratio); + } + + public static Int32Rect ToInt32Rect(this Rect rect) + { + Int32Rect intRect = new Int32Rect( + (int)rect.X, + (int)rect.Y, + (int)rect.Width, + (int)rect.Height); + + return intRect; + } + + [DebuggerStepThrough] + public static DataRect ToDataRect(this Rect rect) + { + return new DataRect(rect); + } + } + + public static class CoordinateUtilities + { + public static Rect RectZoom(Rect rect, double ratio) + { + return RectZoom(rect, rect.GetCenter(), ratio); + } + + public static Rect RectZoom(Rect rect, double horizontalRatio, double verticalRatio) + { + return RectZoom(rect, rect.GetCenter(), horizontalRatio, verticalRatio); + } + + public static Rect RectZoom(Rect rect, Point zoomCenter, double ratio) + { + return RectZoom(rect, zoomCenter, ratio, ratio); + } + + public static Rect RectZoom(Rect rect, Point zoomCenter, double horizontalRatio, double verticalRatio) + { + Rect res = new Rect(); + res.X = zoomCenter.X - (zoomCenter.X - rect.X) * horizontalRatio; + res.Y = zoomCenter.Y - (zoomCenter.Y - rect.Y) * verticalRatio; + res.Width = rect.Width * horizontalRatio; + res.Height = rect.Height * verticalRatio; + return res; + } + + public static Rect RectZoomX(Rect rect, Point zoomCenter, double ratio) + { + Rect res = rect; + res.X = zoomCenter.X - (zoomCenter.X - rect.X) * ratio; + res.Width = rect.Width * ratio; + return res; + } + + public static Rect RectZoomY(Rect rect, Point zoomCenter, double ratio) + { + Rect res = rect; + res.Y = zoomCenter.Y - (zoomCenter.Y - rect.Y) * ratio; + res.Height = rect.Height * ratio; + return res; + } + } + + [DebuggerDisplay("{XMin};{YMin} → {Width}*{Height}")] + public struct DataRect : IEquatable + { + #region Ctors + + /// + /// Initializes a new instance of the struct. + /// + /// Source rect. + public DataRect(Rect rect) + { + xMin = rect.X; + yMin = rect.Y; + width = rect.Width; + height = rect.Height; + } + + /// + /// Initializes a new instance of the struct. + /// + /// The size. + public DataRect(Size size) + { + if (size.IsEmpty) + { + this = emptyRect; + } + else + { + xMin = yMin = 0.0; + width = size.Width; + height = size.Height; + } + } + + /// + /// Initializes a new instance of the struct. + /// + /// The location. + /// The size. + public DataRect(Point location, Size size) + { + if (size.IsEmpty) + { + this = emptyRect; + } + else + { + xMin = location.X; + yMin = location.Y; + width = size.Width; + height = size.Height; + } + } + + /// + /// Initializes a new instance of the struct. + /// + /// The point1. + /// The point2. + public DataRect(Point point1, Point point2) + { + xMin = Math.Min(point1.X, point2.X); + yMin = Math.Min(point1.Y, point2.Y); + width = Math.Max((double)(Math.Max(point1.X, point2.X) - xMin), 0); + height = Math.Max((double)(Math.Max(point1.Y, point2.Y) - yMin), 0); + } + + /// + /// Initializes a new instance of the struct. + /// + /// The point. + /// The vector. + public DataRect(Point point, Vector vector) + : this(point, point + vector) + { + } + + /// + /// Initializes a new instance of the struct. + /// + /// The x. + /// The y. + /// The width. + /// The height. + public DataRect(double x, double y, double width, double height) + { + if ((width < 0) || (height < 0)) + { + throw new ArgumentException(); + } + this.xMin = x; + this.yMin = y; + this.width = width; + this.height = height; + } + + #endregion + + #region Static + + public static DataRect FromPoints(double x1, double y1, double x2, double y2) + { + return new DataRect(new Point(x1, y1), new Point(x2, y2)); + } + + public static implicit operator DataRect(Rect rect) + { + return rect.ToDataRect(); + } + + public static implicit operator Rect(DataRect rect) + { + return rect.ToRect(); + } + + #endregion + + public Rect ToRect() + { + return new Rect(xMin, yMin, width, height); + } + + public DataRect Intersect(DataRect rect) + { + if (!IntersectsWith(rect)) + return DataRect.Empty; + + DataRect res = new DataRect(); + + double x = Math.Max(this.XMin, rect.XMin); + double y = Math.Max(this.YMin, rect.YMin); + res.width = Math.Max((double)(Math.Min(this.XMax, rect.XMax) - x), 0.0); + res.height = Math.Max((double)(Math.Min(this.YMax, rect.YMax) - y), 0.0); + res.xMin = x; + res.yMin = y; + + return res; + } + + public bool IntersectsWith(DataRect rect) + { + if (IsEmpty || rect.IsEmpty) + return false; + + return ((((rect.XMin <= this.XMax) && (rect.XMax >= this.XMin)) && (rect.YMax >= this.YMin)) && (rect.YMin <= this.YMax)); + } + + private double xMin; + private double yMin; + private double width; + private double height; + + /// + /// Gets a value indicating whether this instance is empty. + /// + /// true if this instance is empty; otherwise, false. + public bool IsEmpty + { + get { return width < 0; } + } + + /// + /// Gets the bottom. + /// + /// The bottom. + public double YMin + { + get { return yMin; } + } + + /// + /// Gets the top. + /// + /// The top. + public double YMax + { + get + { + if (IsEmpty) + { + return Double.PositiveInfinity; + } + return yMin + height; + } + } + + /// + /// Gets the left. + /// + /// The left. + public double XMin + { + get { return xMin; } + } + + /// + /// Gets the right. + /// + /// The right. + public double XMax + { + get + { + if (IsEmpty) + { + return Double.PositiveInfinity; + } + return xMin + width; + } + } + + /// + /// Gets or sets the location. + /// + /// The location. + public Point Location + { + get { return new Point(xMin, yMin); } + set + { + if (IsEmpty) + { + throw new InvalidOperationException(); + } + xMin = value.X; + yMin = value.Y; + } + } + + /// + /// Gets or sets the size. + /// + /// The size. + public Size Size + { + get + { + if (IsEmpty) + { + return Size.Empty; + } + return new Size(width, height); + } + set + { + if (value.IsEmpty) + { + this = emptyRect; + } + else + { + if (IsEmpty) + { + throw new InvalidOperationException(); + } + width = value.Width; + height = value.Height; + } + } + } + + public double Width + { + get { return width; } + } + + public double Height + { + get { return height; } + } + + private static readonly DataRect emptyRect = CreateEmptyRect(); + + public static DataRect Empty + { + get { return DataRect.emptyRect; } + } + + private static DataRect CreateEmptyRect() + { + DataRect rect = new DataRect(); + rect.xMin = Double.PositiveInfinity; + rect.yMin = Double.PositiveInfinity; + rect.width = Double.NegativeInfinity; + rect.height = Double.NegativeInfinity; + return rect; + } + + #region Object overrides + + public override bool Equals(object obj) + { + if (obj == null) + return false; + + if (!(obj is DataRect)) + return false; + + DataRect other = (DataRect)obj; + + return Equals(other); + } + + public override int GetHashCode() + { + if (IsEmpty) + return 0; + + return xMin.GetHashCode() ^ + width.GetHashCode() ^ + yMin.GetHashCode() ^ + height.GetHashCode(); + } + + public override string ToString() + { + if (IsEmpty) + return "Empty"; + + return String.Format("{0},{1},{2},{3}", xMin, yMin, width, height); + } + + public static bool operator ==(DataRect rect1, DataRect rect2) + { + return rect1.Equals(rect2); + } + + public static bool operator !=(DataRect rect1, DataRect rect2) + { + return !rect1.Equals(rect2); + } + + #endregion + + #region IEquatable Members + + public bool Equals(DataRect other) + { + if (this.IsEmpty) + return other.IsEmpty; + + return xMin == other.xMin && + width == other.width && + yMin == other.yMin && + height == other.height; + } + + #endregion + } + #endregion + +} diff --git a/HisDataTools/Chart/Plotter/Marker/T5PointMarker.cs b/HisDataTools/Chart/Plotter/Marker/T5PointMarker.cs new file mode 100644 index 0000000..6902679 --- /dev/null +++ b/HisDataTools/Chart/Plotter/Marker/T5PointMarker.cs @@ -0,0 +1,119 @@ +#region <版 本 注 释> +/* + * ======================================================================== + * Copyright(c) 四川*******公司, All Rights Reserved. + * ======================================================================== + * + * 作者:[HeBianGu] 时间:2018/1/19 16:41:43 + * 文件名:Class1 + * 说明: + * + * + * 修改者: 时间: + * 修改说明: + * ======================================================================== +*/ +#endregion +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Media; + +namespace HeBianGu.WPF.EChart +{ + /// 五角星Marker + public class T5PointMarker : ShapePointMarker + { + + /// 描绘形状 + protected override Geometry DefiningGeometry + { + get + { + + //两个圆的半径 和第一个点初始角度 + //r1 = r / 2.5, r2 = r值的互换确定是正五角星还是倒五角星 + double r1 = this.Size / 2.5, r2 = this.Size, g = 18; + + + double pi = Math.PI; + + + List values = new List(10);//十个点 + + + List values1 = new List(5);//(内)外接五个点 + + + List values2 = new List(5);//(外)内接五个点 + + + for (int i = 0; i < 5; i++) + { + //计算10个点的坐标 + Point p1 = new Point(r1 * Math.Cos(g * pi / 180), r1 * Math.Sin(g * pi / 180)); + + + Point p2 = new Point(r2 * Math.Cos((g + 36) * pi / 180), r2 * Math.Sin((g + 36) * pi / 180)); + + + values1.Add(p1); + + + values2.Add(p2); + + + g += 72; + } + //左半边:3,4,5,6,7,8 + //右半边:1,2,3,8,9,10 + values.Add(values1[0]);//1 + values.Add(values2[0]);//2 + values.Add(values1[1]);//3 + values.Add(values2[1]);//4 + values.Add(values1[2]);//5 + values.Add(values2[2]);//6 + values.Add(values1[3]);//7 + values.Add(values2[3]);//8 + values.Add(values1[4]);//9 + values.Add(values2[4]);//10 + + PointCollection pcollect = new PointCollection(); + + foreach (var item in values) + { + Point p = Point.Add(item, new Vector(this.ScreenPoint.X, this.ScreenPoint.Y)); + + pcollect.Add(p); + } + + StreamGeometry streamGeom = new StreamGeometry(); + + using (var context = streamGeom.Open()) + { + + context.BeginFigure(pcollect[0], true, true); + + foreach (var item in pcollect) + { + context.LineTo(item, true, true); + } + + } + + return streamGeom; + } + } + + protected override void OnRender(DrawingContext drawingContext) + { + base.OnRender(drawingContext); + + drawingContext.DrawGeometry(Fill, Pen, DefiningGeometry); + + } + } +} diff --git a/HisDataTools/Chart/Plotter/Marker/TrianglePointMarker.cs b/HisDataTools/Chart/Plotter/Marker/TrianglePointMarker.cs new file mode 100644 index 0000000..56bbad5 --- /dev/null +++ b/HisDataTools/Chart/Plotter/Marker/TrianglePointMarker.cs @@ -0,0 +1,61 @@ +#region <版 本 注 释> +/* + * ======================================================================== + * Copyright(c) 四川*******公司, All Rights Reserved. + * ======================================================================== + * + * 作者:[HeBianGu] 时间:2018/1/19 16:42:36 + * 文件名:Class1 + * 说明: + * + * + * 修改者: 时间: + * 修改说明: + * ======================================================================== +*/ +#endregion +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Media; + +namespace HeBianGu.WPF.EChart +{ + /// 下三角Marker + public class TrianglePointMarker : ShapePointMarker + { + + /// 描绘形状 + protected override Geometry DefiningGeometry + { + get + { + double Size = 5; + Point pt0 = Point.Add(ScreenPoint, new Vector(-Size / 2, -Size / 2)); + Point pt1 = Point.Add(ScreenPoint, new Vector(0, Size / 2)); + Point pt2 = Point.Add(ScreenPoint, new Vector(Size / 2, -Size / 2)); + + StreamGeometry streamGeom = new StreamGeometry(); + using (var context = streamGeom.Open()) + { + context.BeginFigure(pt0, true, true); + context.LineTo(pt1, true, true); + context.LineTo(pt2, true, true); + } + return streamGeom; + } + } + + + /// 绘制形状 + protected override void OnRender(DrawingContext drawingContext) + { + base.OnRender(drawingContext); + + drawingContext.DrawGeometry(Fill, Pen, DefiningGeometry); + } + } +} diff --git a/HisDataTools/Chart/Plotter/PlotterBase.cs b/HisDataTools/Chart/Plotter/PlotterBase.cs new file mode 100644 index 0000000..bdced12 --- /dev/null +++ b/HisDataTools/Chart/Plotter/PlotterBase.cs @@ -0,0 +1,138 @@ +#region <版 本 注 释> +/* + * ======================================================================== + * Copyright(c) 四川*******公司, All Rights Reserved. + * ======================================================================== + * + * 作者:[HeBianGu] 时间:2018/1/18 11:08:41 + * 文件名:Plotter + * 说明: + * + * + * 修改者: 时间: + * 修改说明: + * ======================================================================== +*/ +#endregion +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Media; +using System.Windows.Media.Animation; + +namespace HeBianGu.WPF.EChart +{ + + /// 绘图机基类 + [TemplatePart(Name = "PART_ParallelCanvas", Type = typeof(Canvas))] + [TemplatePart(Name = "PART_TopCanvas", Type = typeof(Canvas))] + [TemplatePart(Name = "PART_BottomCanvas", Type = typeof(Canvas))] + [TemplatePart(Name = "PART_LeftCanvas", Type = typeof(Canvas))] + [TemplatePart(Name = "PART_RightCanvas", Type = typeof(Canvas))] + [TemplatePart(Name = "PART_ParallelBottomCanvas", Type = typeof(Canvas))] + + public abstract class PlotterBase : ContentControl + { + protected PlotterBase() + { + this.InitParts(); + } + + private void InitParts() + { + ResourceDictionary dict = new ResourceDictionary + { + Source = new Uri("/HisDataTools;component/Chart/Plotter/PlotterBaseStyle.xaml", UriKind.Relative) + }; + + Style = (Style)dict["DefaultPlotterStyle"]; + + ApplyTemplate(); + + //// Todo :初始化淡出初始效果 + //parallelCanvas.OpacityMask = this.FindResource("WindowOpMack") as Brush; + } + + #region - 模板重写 - + + Canvas _topCanvas; + Canvas _bottomCanvas; + Canvas _leftCanvas; + Canvas _rightCanvas; + Canvas parallelCanvas; + Canvas _centerBottomCanvas; + Canvas _pathCanvas; + public Canvas ParallelCanvas { get => parallelCanvas; } + public Canvas RightCanvas { get => _rightCanvas; set => _rightCanvas = value; } + public Canvas LeftCanvas { get => _leftCanvas; set => _leftCanvas = value; } + public Canvas BottomCanvas { get => _bottomCanvas; set => _bottomCanvas = value; } + public Canvas TopCanvas { get => _topCanvas; set => _topCanvas = value; } + public Canvas PathCanvas { get => _pathCanvas; set => _pathCanvas = value; } + public Canvas CenterBottomCanvas { get => _centerBottomCanvas; set => _centerBottomCanvas = value; } + + public override void OnApplyTemplate() + { + base.OnApplyTemplate(); + + parallelCanvas = GetPart("PART_ParallelCanvas"); + BottomCanvas = GetPart("PART_BottomCanvas"); + LeftCanvas = GetPart("PART_LeftCanvas"); + RightCanvas = GetPart("PART_RightCanvas"); + TopCanvas = GetPart("PART_TopCanvas"); + PathCanvas = GetPart("PART_PathCanvas"); + CenterBottomCanvas = GetPart("PART_ParallelBottomCanvas"); + } + private T GetPart(string name) + { + return (T)Template.FindName(name, this); + } + + #endregion + + #region - 动画 - + + public void BeginStory() + { + //this.PathCanvas.Width = 0; + //this.CenterBottomCanvas.Width = 0; + + + Storyboard start1storyboard = new Storyboard(); + + DoubleAnimation start1 = new DoubleAnimation(0, 0, new Duration(TimeSpan.FromSeconds(1))); + Storyboard.SetTarget(start1, this.PathCanvas); + Storyboard.SetTargetProperty(start1, new PropertyPath("Width")); + start1storyboard.Children.Add(start1); + + DoubleAnimation double1 = new DoubleAnimation(0, this.ParallelCanvas.ActualWidth, new Duration(TimeSpan.FromSeconds(1))); + double1.BeginTime = TimeSpan.FromSeconds(1); + Storyboard.SetTarget(double1, this.PathCanvas); + Storyboard.SetTargetProperty(double1, new PropertyPath("Width")); + start1storyboard.Children.Add(double1); + + start1storyboard.Begin(); + + + Storyboard start2storyboard = new Storyboard(); + + DoubleAnimation start2 = new DoubleAnimation(0, 0, new Duration(TimeSpan.FromSeconds(1))); + Storyboard.SetTarget(start2, this.CenterBottomCanvas); + Storyboard.SetTargetProperty(start2, new PropertyPath("Width")); + start2storyboard.Children.Add(start2); + + DoubleAnimation double2 = new DoubleAnimation(0, this.ParallelCanvas.ActualWidth, new Duration(TimeSpan.FromSeconds(1.5))); + double2.BeginTime = TimeSpan.FromSeconds(1.5); + Storyboard.SetTarget(double2, this.CenterBottomCanvas); + Storyboard.SetTargetProperty(double2, new PropertyPath("Width")); + start2storyboard.Children.Add(double2); + start2storyboard.Begin(); + + + } + #endregion + } +} diff --git a/HisDataTools/Chart/Plotter/PlotterBaseStyle.xaml b/HisDataTools/Chart/Plotter/PlotterBaseStyle.xaml new file mode 100644 index 0000000..ac7d193 --- /dev/null +++ b/HisDataTools/Chart/Plotter/PlotterBaseStyle.xaml @@ -0,0 +1,551 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/HisDataTools/Chart/Plotter/ViewPlotter.cs b/HisDataTools/Chart/Plotter/ViewPlotter.cs new file mode 100644 index 0000000..e9fe9ea --- /dev/null +++ b/HisDataTools/Chart/Plotter/ViewPlotter.cs @@ -0,0 +1,36 @@ +#region <版 本 注 释> +/* + * ======================================================================== + * Copyright(c) 四川*******公司, All Rights Reserved. + * ======================================================================== + * + * 作者:[HeBianGu] 时间:2018/1/18 11:23:08 + * 文件名:CurvePlotter + * 说明: + * + * + * 修改者: 时间: + * 修改说明: + * ======================================================================== +*/ +#endregion +using HeBianGu.WPF.EChart; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Media; + +namespace HeBianGu.WPF.EChart +{ + + /// 绘图结构关系 + public abstract class ViewPlotter : PlotterBase + { + + } + + +} diff --git a/HisDataTools/Properties/Resources.Designer.cs b/HisDataTools/Properties/Resources.Designer.cs index 55aed5f..3ee7541 100644 --- a/HisDataTools/Properties/Resources.Designer.cs +++ b/HisDataTools/Properties/Resources.Designer.cs @@ -60,6 +60,33 @@ namespace HisDataTools.Properties { } } + /// + /// 查找类似 Null 的本地化字符串。 + /// + internal static string _null { + get { + return ResourceManager.GetString("null", resourceCulture); + } + } + + /// + /// 查找类似 All value 的本地化字符串。 + /// + internal static string AllValue { + get { + return ResourceManager.GetString("AllValue", resourceCulture); + } + } + + /// + /// 查找类似 Bad 的本地化字符串。 + /// + internal static string bad { + get { + return ResourceManager.GetString("bad", resourceCulture); + } + } + /// /// 查找类似 Cancel 的本地化字符串。 /// @@ -78,6 +105,15 @@ namespace HisDataTools.Properties { } } + /// + /// 查找类似 Database select 的本地化字符串。 + /// + internal static string DatabaseSelectTitle { + get { + return ResourceManager.GetString("DatabaseSelectTitle", resourceCulture); + } + } + /// /// 查找类似 DataTable 的本地化字符串。 /// @@ -105,6 +141,15 @@ namespace HisDataTools.Properties { } } + /// + /// 查找类似 Good 的本地化字符串。 + /// + internal static string good { + get { + return ResourceManager.GetString("good", resourceCulture); + } + } + /// /// 查找类似 HisDataQuery 的本地化字符串。 /// @@ -132,6 +177,15 @@ namespace HisDataTools.Properties { } } + /// + /// 查找类似 Init 的本地化字符串。 + /// + internal static string Init { + get { + return ResourceManager.GetString("Init", resourceCulture); + } + } + /// /// 查找类似 OK 的本地化字符串。 /// @@ -150,6 +204,15 @@ namespace HisDataTools.Properties { } } + /// + /// 查找类似 Value count {0}/{1} ms 的本地化字符串。 + /// + internal static string OpMsgFormate { + get { + return ResourceManager.GetString("OpMsgFormate", resourceCulture); + } + } + /// /// 查找类似 Quality 的本地化字符串。 /// @@ -186,6 +249,15 @@ namespace HisDataTools.Properties { } } + /// + /// 查找类似 StartValue 的本地化字符串。 + /// + internal static string startvalue { + get { + return ResourceManager.GetString("startvalue", resourceCulture); + } + } + /// /// 查找类似 Tag 的本地化字符串。 /// @@ -195,6 +267,15 @@ namespace HisDataTools.Properties { } } + /// + /// 查找类似 TimeSpan 的本地化字符串。 + /// + internal static string TimeSpan { + get { + return ResourceManager.GetString("TimeSpan", resourceCulture); + } + } + /// /// 查找类似 Value 的本地化字符串。 /// diff --git a/HisDataTools/Properties/Resources.resx b/HisDataTools/Properties/Resources.resx index 8d6819b..9cb3906 100644 --- a/HisDataTools/Properties/Resources.resx +++ b/HisDataTools/Properties/Resources.resx @@ -117,12 +117,21 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + All value + + + Bad + Cancel Chart + + Database select + DataTable @@ -132,6 +141,9 @@ EndTime + + Good + HisDataQuery @@ -141,12 +153,21 @@ Id + + Init + + + Null + OK Open + + Value count {0}/{1} ms + Quality @@ -159,9 +180,15 @@ StartTime + + StartValue + Tag + + TimeSpan + Value diff --git a/HisDataTools/Properties/Resources.zh-CN.resx b/HisDataTools/Properties/Resources.zh-CN.resx index ee68acb..2876120 100644 --- a/HisDataTools/Properties/Resources.zh-CN.resx +++ b/HisDataTools/Properties/Resources.zh-CN.resx @@ -117,22 +117,79 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + 所有值 + + + + 取消 + + 图表显示 + + + 数据库选择 + + + 表格显示 + + + 时间 + + + 结束时间 + + + + 历史数据查询 历史数据工具 + + 编号 + + + 初始态 + + + + 确定 打开 + + {1} ms 查询到{0} 个值 + + + 质量 + + + 查询 + 选择一个数据库 + + 开始时间 + + + 起停值 + + + 变量 + + + 时间间隔 + + + + \ No newline at end of file diff --git a/HisDataTools/Themes/Generic.xaml b/HisDataTools/Themes/Generic.xaml index 46118b0..3923e24 100644 --- a/HisDataTools/Themes/Generic.xaml +++ b/HisDataTools/Themes/Generic.xaml @@ -4,6 +4,9 @@ xmlns:viewmodel="clr-namespace:HisDataTools.ViewModel" xmlns:view="clr-namespace:HisDataTools.View" > + + + diff --git a/HisDataTools/View/HisDataQueryView.xaml b/HisDataTools/View/HisDataQueryView.xaml index 9c4ec9e..16e73cd 100644 --- a/HisDataTools/View/HisDataQueryView.xaml +++ b/HisDataTools/View/HisDataQueryView.xaml @@ -5,15 +5,17 @@ xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:local="clr-namespace:HisDataTools.View" xmlns:res="clr-namespace:HisDataTools" + xmlns:chart="clr-namespace:HeBianGu.WPF.EChart" mc:Ignorable="d" d:DesignHeight="450" d:DesignWidth="926"> - + + - + @@ -23,18 +25,22 @@ - -