diff --git a/StartServerWPF.Modules.Main/Models/MenuItemModel.cs b/StartServerWPF.Modules.Main/Models/MenuItemModel.cs index 762e332..29181e0 100644 --- a/StartServerWPF.Modules.Main/Models/MenuItemModel.cs +++ b/StartServerWPF.Modules.Main/Models/MenuItemModel.cs @@ -40,9 +40,11 @@ namespace StartServerWPF.Modules.Main.Models if (_openViewCommand == null) _openViewCommand = new DelegateCommand((model) => { + var para= new NavigationParameters(); + para.Add("model", model.MenuHeader); if ((model.Children == null || model.Children.Count == 0) && !string.IsNullOrEmpty(model.TargetView)) - _regionManager.RequestNavigate("MainContentRegion", model.TargetView); + _regionManager.RequestNavigate("MainContentRegion", model.TargetView, para); else IsExpanded = !IsExpanded; }); diff --git a/StartServerWPF.Modules.Main/ViewModels/MainViewModel.cs b/StartServerWPF.Modules.Main/ViewModels/MainViewModel.cs index 09d1850..f239952 100644 --- a/StartServerWPF.Modules.Main/ViewModels/MainViewModel.cs +++ b/StartServerWPF.Modules.Main/ViewModels/MainViewModel.cs @@ -273,7 +273,6 @@ namespace StartServerWPF.Modules.Main.ViewModels public DelegateCommand DisplayLogCommand => new(DisplayLog); public DelegateCommand StartCommand => new(Start); // public DelegateCommand OneKeyStopCommand => new(OneKeyStop); - public DelegateCommand DisplayRealWavesCommand => new(DisplayRealWaves); private void Loaded() { @@ -415,7 +414,7 @@ namespace StartServerWPF.Modules.Main.ViewModels if (pro != null) { int indexPro = KillProcess(pro); - var model= ProcessDataSource.Where(x => x.ProcessTile == pro.ProName).FirstOrDefault(); + var model= ProcessDataSource.Where(x => x.ProName == pro.ProName).FirstOrDefault(); if (model == null) continue; model.MonitorTime= DateTime.Now.ToString(); model.ProcessStatus = "已停止"; @@ -428,10 +427,7 @@ namespace StartServerWPF.Modules.Main.ViewModels StartTime = new DateTime(); } - private void DisplayRealWaves() - { - StartProcess(sc.proPlot); - } + #endregion private void ConnectVpn() @@ -594,7 +590,7 @@ namespace StartServerWPF.Modules.Main.ViewModels private int StartProcess(ProcessInfo proInfo) { bool res= CMDStartProcess(proInfo); - int seInd = res ? 37 : 0; + int seInd = res ? 0 : 37; return seInd; } /// @@ -695,7 +691,7 @@ namespace StartServerWPF.Modules.Main.ViewModels if (pro != null) { int sfp = FindProcess(pro); - var model = ProcessDataSource.Where(x => x.ProcessTile == pro.ProName).FirstOrDefault(); + var model = ProcessDataSource.Where(x => x.ProName == pro.ProName).FirstOrDefault(); if (sfp == 0) { model.ProcessStatus = "正常运行"; diff --git a/StartServerWPF.Modules.Main/ViewModels/TreeMenuViewModel.cs b/StartServerWPF.Modules.Main/ViewModels/TreeMenuViewModel.cs index 3161a68..cc56951 100644 --- a/StartServerWPF.Modules.Main/ViewModels/TreeMenuViewModel.cs +++ b/StartServerWPF.Modules.Main/ViewModels/TreeMenuViewModel.cs @@ -74,6 +74,6 @@ namespace StartServerWPF.Modules.Main.ViewModels } } List menuNames = new List() {"首页","实时波形","波形回放","设置","日志", }; - List viewName = new List() { "MainView", "RealTimeWaveformView", "WaveformPlayBackView", "SetParamView", "LogManagementView"}; + List viewName = new List() { "MainView", "ChartPlotView", "ChartPlotView", "SetParamView", "LogManagementView"}; } } diff --git a/StartServerWPF.Modules.Main/Views/RealTimeWaveformView.xaml b/StartServerWPF.Modules.Main/Views/RealTimeWaveformView.xaml index 2a7fa52..74bdd41 100644 --- a/StartServerWPF.Modules.Main/Views/RealTimeWaveformView.xaml +++ b/StartServerWPF.Modules.Main/Views/RealTimeWaveformView.xaml @@ -17,39 +17,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + diff --git a/StartServerWPF.Modules.MseedChart/Libs/Arction.DirectX.dll b/StartServerWPF.Modules.MseedChart/Libs/Arction.DirectX.dll new file mode 100644 index 0000000..b5b9539 Binary files /dev/null and b/StartServerWPF.Modules.MseedChart/Libs/Arction.DirectX.dll differ diff --git a/StartServerWPF.Modules.MseedChart/Libs/Arction.DirectXFiles.dll b/StartServerWPF.Modules.MseedChart/Libs/Arction.DirectXFiles.dll new file mode 100644 index 0000000..0b80a1a Binary files /dev/null and b/StartServerWPF.Modules.MseedChart/Libs/Arction.DirectXFiles.dll differ diff --git a/StartServerWPF.Modules.MseedChart/Libs/Arction.DirectXInit.dll b/StartServerWPF.Modules.MseedChart/Libs/Arction.DirectXInit.dll new file mode 100644 index 0000000..cd795a1 Binary files /dev/null and b/StartServerWPF.Modules.MseedChart/Libs/Arction.DirectXInit.dll differ diff --git a/StartServerWPF.Modules.MseedChart/Libs/Arction.Licensing.dll b/StartServerWPF.Modules.MseedChart/Libs/Arction.Licensing.dll new file mode 100644 index 0000000..c3c0728 Binary files /dev/null and b/StartServerWPF.Modules.MseedChart/Libs/Arction.Licensing.dll differ diff --git a/StartServerWPF.Modules.MseedChart/Libs/Arction.RenderingDefinitions.dll b/StartServerWPF.Modules.MseedChart/Libs/Arction.RenderingDefinitions.dll new file mode 100644 index 0000000..3bad862 Binary files /dev/null and b/StartServerWPF.Modules.MseedChart/Libs/Arction.RenderingDefinitions.dll differ diff --git a/StartServerWPF.Modules.MseedChart/Libs/Arction.RenderingEngine.dll b/StartServerWPF.Modules.MseedChart/Libs/Arction.RenderingEngine.dll new file mode 100644 index 0000000..956a537 Binary files /dev/null and b/StartServerWPF.Modules.MseedChart/Libs/Arction.RenderingEngine.dll differ diff --git a/StartServerWPF.Modules.MseedChart/Libs/Arction.RenderingEngine11.dll b/StartServerWPF.Modules.MseedChart/Libs/Arction.RenderingEngine11.dll new file mode 100644 index 0000000..da4b97f Binary files /dev/null and b/StartServerWPF.Modules.MseedChart/Libs/Arction.RenderingEngine11.dll differ diff --git a/StartServerWPF.Modules.MseedChart/Libs/Arction.RenderingEngine9.dll b/StartServerWPF.Modules.MseedChart/Libs/Arction.RenderingEngine9.dll new file mode 100644 index 0000000..bc5e1fa Binary files /dev/null and b/StartServerWPF.Modules.MseedChart/Libs/Arction.RenderingEngine9.dll differ diff --git a/StartServerWPF.Modules.MseedChart/Libs/Arction.Wpf.Charting.LightningChart.dll b/StartServerWPF.Modules.MseedChart/Libs/Arction.Wpf.Charting.LightningChart.dll new file mode 100644 index 0000000..318934a Binary files /dev/null and b/StartServerWPF.Modules.MseedChart/Libs/Arction.Wpf.Charting.LightningChart.dll differ diff --git a/StartServerWPF.Modules.MseedChart/Models/CoordBase.cs b/StartServerWPF.Modules.MseedChart/Models/CoordBase.cs new file mode 100644 index 0000000..6a82854 --- /dev/null +++ b/StartServerWPF.Modules.MseedChart/Models/CoordBase.cs @@ -0,0 +1,70 @@ + +namespace StartServerWPF.Modules.MseedChart.Models +{ + public class CoordBase + { + private double _x = 0.0; + + private double _y = 0.0; + + private double _z = 0.0; + + private double _md = 0.0; + + public double X + { + get + { + return _x; + } + set + { + _x = value; + } + } + + public double Y + { + get + { + return _y; + } + set + { + _y = value; + } + } + + public double Z + { + get + { + return _z; + } + set + { + _z = value; + } + } + + public double MD + { + get + { + return _md; + } + set + { + _md = value; + } + } + } + + public enum FocalMechanismType + { + strikeSlip, + dipSlip, + tensile, + unknown + } +} diff --git a/StartServerWPF.Modules.MseedChart/Models/LineDatas.cs b/StartServerWPF.Modules.MseedChart/Models/LineDatas.cs new file mode 100644 index 0000000..70f6007 --- /dev/null +++ b/StartServerWPF.Modules.MseedChart/Models/LineDatas.cs @@ -0,0 +1,52 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StartServerWPF.Modules.MseedChart.Models +{ + public class LineDatas + { + private string lable; + + public string Lable + { + get { return lable; } + set { lable = value; } + } + + private string color; + + public string Color + { + get { return color; } + set { color = value; } + } + + private double smoothTension; + + public double SmoothTension + { + get { return smoothTension; } + set { smoothTension = value; } + } + + private double[] xData; + + public double[] XData + { + get { return xData; } + set { xData = value; } + } + + private double[] yData; + + public double[] YData + { + get { return yData; } + set { yData = value; } + } + } + +} diff --git a/StartServerWPF.Modules.MseedChart/Models/MmEvent.cs b/StartServerWPF.Modules.MseedChart/Models/MmEvent.cs new file mode 100644 index 0000000..d0341e7 --- /dev/null +++ b/StartServerWPF.Modules.MseedChart/Models/MmEvent.cs @@ -0,0 +1,125 @@ +#region 程序集 Txgy.Microseismic.BaseLib, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null +// E:\mingzf\txgy\Txgy.EWS\Client\output\Txgy.Microseismic.BaseLib.dll +// Decompiled with ICSharpCode.Decompiler 7.1.0.6543 +#endregion + +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; + +namespace StartServerWPF.Modules.MseedChart.Models +{ + public class MmEvent : CoordBase + { + + private DateTime _eventTime; + + private double _ml; + + private double _rms; + + public string EventTimeStr { get; set; } + + public DateTime EventTime + { + get + { + return _eventTime; + } + set + { + _eventTime = value; + } + } + + public double ML + { + get + { + return _ml; + } + set + { + _ml = value; + } + } + + public double RMS + { + get + { + return _rms; + } + set + { + _rms = value; + } + } + + private Dictionary _phases; + public Dictionary Phases + { + get + { + return _phases; + } + set + { + _phases = value; + } + } + + public double DominantFreq { get; set; } + + public string JsonFile { get; set; } + + public string AsciiFile { get; set; } + + public static float SetAmp(List amps) + { + amps.Sort(); + return amps[amps.Count / 2]; + } + } + + + public class StationEventJson + { + public DateTime otime { get;set;} + public double lon { get; set; } + public double lat { get; set; } + public double depth { get; set; } + public double ml { get; set; } + public double rms { get; set; } + public List phases { get; set; } + public List amps { get; set; } + } + + public class phases + { + public string id { get; set; } + public string name { get; set; } + public DateTime atime { get; set; } + public double resi { get; set; } + public double first_motion_direct { get; set; } + public double fmd_semi_period { get; set; } + public double deltaKm { get; set; } + + public double disKm { get; set; } + public double model_time { get; set; } + public double weight { get; set; } + public double prob { get; set; } + } + public class amps + { + public string id { get; set; } + public string name { get; set; } + public DateTime atime { get; set; } + public string mag_type { get; set; } + public double mag_value { get; set; } + public double amp { get; set; + } + } + +} \ No newline at end of file diff --git a/StartServerWPF.Modules.MseedChart/Models/StationAxis.cs b/StartServerWPF.Modules.MseedChart/Models/StationAxis.cs new file mode 100644 index 0000000..8ad956d --- /dev/null +++ b/StartServerWPF.Modules.MseedChart/Models/StationAxis.cs @@ -0,0 +1,36 @@ +using Prism.Commands; +using Prism.Common; +using Prism.Mvvm; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Input; + +namespace StartServerWPF.Modules.MseedChart.Models +{ + public class StationAxis : BindableBase + { + + public string Name { get; set; } + + private bool _isChecked=true; + + public bool IsChecked + { + get + { + return _isChecked; + } + set + { + _isChecked = value; + SetProperty(ref _isChecked, value); + } + } + + public DelegateCommand SelectCommand { set; get; } + + } +} diff --git a/StartServerWPF.Modules.MseedChart/Models/StationModel.cs b/StartServerWPF.Modules.MseedChart/Models/StationModel.cs new file mode 100644 index 0000000..f116476 --- /dev/null +++ b/StartServerWPF.Modules.MseedChart/Models/StationModel.cs @@ -0,0 +1,52 @@ +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StartServerWPF.Modules.MseedChart.Models +{ + public class StationModel + { + + public StationModel() + { + Dzne.Add("dz", dz); + Dzne.Add("dn", dn); + Dzne.Add("de", de); + } + public double E; + + public double N; + + public double Z; + + public double ELon; + + public double NLat; + + public int PointCount { get; set; } + + public int SamplingFrequency { get; set; } + + public DateTime BeginTime; + + public bool IsVisible = true; + + public Dictionary> Dzne { get; } = new Dictionary>(); + + public List dz { get; } = new List(); + + public List dn { get; } = new List(); + + public List de { get; } = new List(); + + + public string Name { get; set; } + + public string FilePath { get; set; } + + public double Sens { get; set; } + } +} diff --git a/StartServerWPF.Modules.MseedChart/Models/WavesModel.cs b/StartServerWPF.Modules.MseedChart/Models/WavesModel.cs new file mode 100644 index 0000000..abd0ec2 --- /dev/null +++ b/StartServerWPF.Modules.MseedChart/Models/WavesModel.cs @@ -0,0 +1,276 @@ +using Arction.Wpf.Charting; +using Arction.Wpf.Charting.Axes; +using Arction.Wpf.Charting.SeriesXY; +using Arction.Wpf.Charting.Views.ViewXY; +using Newtonsoft.Json; +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Linq; +using System.Threading.Tasks; + +namespace StartServerWPF.Modules.MseedChart.Models +{ + public class WavesModel + { + public List CreateYAxisChart(List stationModels, LightningChart curChart) + { + List axisYList = new List(); + foreach (var item in stationModels) + { + int distancetoX= SetYasixPlacement(curChart); + AxisY axisY = new AxisY(curChart.ViewXY); + //添加Z分量波形 + if (item.dz.Count > 0) + { + axisY.SetRange(item.dz.Min(), item.dz.Max()); + } + axisY.Title.Text = string.Format("Ch{0}.Z", item.Name); + axisY.Title.DistanceToAxis = distancetoX; + axisYList.Add(axisY); + //添加N分量波形 + axisY = new AxisY(curChart.ViewXY); + if (item.dn.Count > 0) + { + axisY.SetRange(item.dn.Min(), item.dn.Max()); + } + axisY.Title.Text = string.Format("Ch{0}.N", item.Name); + axisY.Title.DistanceToAxis = distancetoX; + axisYList.Add(axisY); + + //添加E分量波形 + axisY = new AxisY(curChart.ViewXY); + if (item.de.Count > 0) + { + axisY.SetRange(item.de.Min(), item.de.Max()); + } + axisY.Title.Text = string.Format("Ch{0}.E", item.Name); + axisY.Title.DistanceToAxis = distancetoX; + axisYList.Add(axisY); + + } + return axisYList; + } + public int SetYasixPlacement(LightningChart chart) + { + int distancetoX = 0; + if (chart.ViewXY.AxisLayout.YAxisAutoPlacement == YAxisAutoPlacement.AllLeft) + { + distancetoX = -(int)chart.ActualWidth + 70; + } + else if (chart.ViewXY.AxisLayout.YAxisAutoPlacement == YAxisAutoPlacement.AllRight) + { + distancetoX = (int)chart.ActualWidth-2*60; + } + return distancetoX; + } + + public List CreateAxisYEventTime(StationEventJson stationEventJson, ViewXY chartV, List stationModels) + { + for (int i = 0; i < stationEventJson.phases.Count; i++) + { + phases ph= stationEventJson.phases[i]; + var index= stationModels.FindIndex(a =>ph.id.Contains(a.Name)); + if(index == -1) + { + continue; + } + int assignYAxisIndex = index * 3; + LineCollection lineCollection = new LineCollection() + { + AssignXAxisIndex = 0, + AssignYAxisIndex = assignYAxisIndex, + Tag=ph.id, //用于排序otime,只需要排更SHZ通道 + Lines = new SegmentLine[] { new SegmentLine(chartV.XAxes[0].DateTimeToAxisValue(ph.atime), chartV.YAxes[assignYAxisIndex].Minimum, chartV.XAxes[0].DateTimeToAxisValue(ph.atime), chartV.YAxes[assignYAxisIndex].Maximum) }, + ShowInLegendBox = false + }; + + lineCollection.LineStyle.Color = System.Windows.Media.Colors.Red; + lineCollection.Title.Text = chartV.YAxes[assignYAxisIndex].Title.Text + ph.atime.ToString(); + lineCollection.Title.Visible = true; + lineCollection.Title.Font.Size = 10; + lineCollection.Title.Shadow.DropColor = System.Windows.Media.Colors.Transparent; + //lineCollection.Title.Shadow.ContrastColor = System.Windows.Media.Colors.Transparent; + lineCollection.Title.AutoPlacement = false; + lineCollection.Title.HorizontalAlign = AlignmentHorizontal.Left; + var b = chartV.XAxes[0].ValueToCoordD(chartV.XAxes[0].DateTimeToAxisValue(ph.atime))-80; + lineCollection.Title.Offset.SetValues((int)b, 3); + lineCollection.Title.Color = System.Windows.Media.Colors.Red; + chartV.LineCollections.Add(lineCollection); + } + + for (int i = 0; i < stationEventJson.amps.Count; i++) + { + amps am = stationEventJson.amps[i]; + var index = stationModels.FindIndex(a => am.id.Contains(a.Name)); + if (index == -1) + { + continue; + } + int assignYAxisIndex = index * 3; + assignYAxisIndex = am.id.Contains("SHN") ? assignYAxisIndex + 1 : assignYAxisIndex + 2; + LineCollection lineCollection = new LineCollection() + { + AssignXAxisIndex = 0, + AssignYAxisIndex = assignYAxisIndex, + Lines = new SegmentLine[] { new SegmentLine(chartV.XAxes[0].DateTimeToAxisValue(am.atime), chartV.YAxes[assignYAxisIndex].Minimum, chartV.XAxes[0].DateTimeToAxisValue(am.atime), chartV.YAxes[assignYAxisIndex].Maximum) }, + ShowInLegendBox = false + }; + lineCollection.LineStyle.Color = System.Windows.Media.Colors.Red; + lineCollection.Title.Text = chartV.YAxes[assignYAxisIndex].Title.Text+ " "+ am.atime.ToString("HH:mm:ss.fff"); + lineCollection.Title.Visible = true; + lineCollection.Title.Font.Size = 10; + lineCollection.Title.Shadow.DropColor = System.Windows.Media.Colors.Transparent; + // lineCollection.Title.Shadow.ContrastColor = System.Windows.Media.Colors.Transparent; + lineCollection.Title.AutoPlacement = false; + lineCollection.Title.HorizontalAlign = AlignmentHorizontal.Left; + var b= chartV.XAxes[0].ValueToCoordD(chartV.XAxes[0].DateTimeToAxisValue(am.atime))-80; + lineCollection.Title.Offset.SetValues((int)b,3); + lineCollection.Title.Color = System.Windows.Media.Colors.Red; + chartV.LineCollections.Add(lineCollection); + } + return new List(); + } + + + public ConcurrentQueue ReadMseedFile(string dataFilePath, string asciiSavePath, bool isMultFile = false) + { + if (!Directory.Exists(Path.GetDirectoryName(dataFilePath))) + { + Directory.CreateDirectory(Path.GetDirectoryName(dataFilePath)); + } + if (!Directory.Exists(Path.GetDirectoryName(asciiSavePath))) + { + Directory.CreateDirectory(Path.GetDirectoryName(asciiSavePath)); + } + ConcurrentQueue smList = new ConcurrentQueue(); + Stopwatch sw = Stopwatch.StartNew(); + if (isMultFile) + { + var filePath = new DirectoryInfo(Path.GetDirectoryName(dataFilePath)); + FileInfo[] files = filePath.GetFiles(); + var mseedFiles = files.Where(i => i.Extension == ".mseed"); + + var asciiFiles = new DirectoryInfo(Path.GetDirectoryName(asciiSavePath)); + var asciifile = asciiFiles.GetFiles(); + if (asciifile.Count() == 0) + { + // 并行运算 + Parallel.ForEach(mseedFiles, (item) => + { + MSeed2Asc(item.FullName, Path.Combine(Path.GetDirectoryName(asciiSavePath), Path.GetFileNameWithoutExtension(item.Name))); + }); + + } + // 并行运算 + Parallel.ForEach(asciiFiles.GetFiles(), (item) => + { + var list = UpdateWavesFromTxt(item.FullName); + list.ForEach(i => smList.Enqueue(i)); + }); + } + else + { + if (!File.Exists(asciiSavePath)) + { + MSeed2Asc(dataFilePath, asciiSavePath); + } + var list = UpdateWavesFromTxt(asciiSavePath); + list.ForEach(i => smList.Enqueue(i)); + } + sw.Stop(); + Debug.WriteLine("MSeed2Asc解压时间:" + sw.Elapsed.TotalSeconds); + return smList; + } + + public List UpdateWavesFromTxt(string fn) + { + string allStr; + List temSM = new List(); + using (StreamReader streamReader = new StreamReader(fn)) + { + allStr = streamReader.ReadToEnd(); + } + if (allStr.Length > 0) + { + string[] strLines = allStr.Trim().Split(new char[] { '\n' }); + // List strList = strLines.ToList(); + // int cnt = strList.Count; + // string[] snStr = strLines[0].Trim().Split(','); + // string tmpName = snStr[0].Substring(14, 3); + StationModel station = new StationModel(); + // station.Name = tmpName; + + int channelFlag = 0; + + for (int i = 0; i < strLines.Length; i++) + { + string row = strLines[i].Trim(); + if (strLines[i].Contains("HA")) + { + string[] rowStr = strLines[i].Split(','); + string chnStr1 = rowStr[0].Substring(21, 3); + string stationName = rowStr[0].Substring(14, 3); + if (!temSM.Any(name => name.Name == stationName)) + { + station = new StationModel(); + station.Name = stationName; + station.BeginTime = Convert.ToDateTime(rowStr[3]).AddHours(8); + station.PointCount = int.Parse(rowStr[1].Trim().Split(' ')[0]); + station.SamplingFrequency = int.Parse(rowStr[2].Trim().Split(' ')[0]); + temSM.Add(station); + } + channelFlag = (chnStr1 == "SHZ") ? 0 : (chnStr1 == "SHN") ? 1 : 2; + } + else + { + switch (channelFlag) + { + case 0://Z + station.dz.Add(double.Parse(row)); + break; + case 1://N + station.dn.Add(double.Parse(row)); + break; + case 2://E + station.de.Add(double.Parse(row)); + break; + } + } + } + // temSM.Add(station); + temSM.Reverse(); + } + return temSM; + } + + public void MSeed2Asc(string filePath, string savePath) + { + using (Process compiler = new Process()) + { + compiler.StartInfo.FileName = "mseed2ascii.exe"; + compiler.StartInfo.Arguments = filePath + " -o " + savePath; + compiler.StartInfo.WindowStyle = ProcessWindowStyle.Hidden; + compiler.StartInfo.CreateNoWindow = true; + compiler.Start(); + compiler.WaitForExit(); + } + } + + public StationEventJson ReadChartJsonFile(string jsonFile) + { + if (File.Exists(jsonFile)) + { + var str = File.ReadAllText(jsonFile); + var st = JsonConvert.DeserializeObject(str); + + StationEventJson jsonST = st[0]; + return jsonST; + } + return null; + + } + } +} diff --git a/StartServerWPF.Modules.MseedChart/MseedChartModule.cs b/StartServerWPF.Modules.MseedChart/MseedChartModule.cs new file mode 100644 index 0000000..ebd632f --- /dev/null +++ b/StartServerWPF.Modules.MseedChart/MseedChartModule.cs @@ -0,0 +1,25 @@ +using StartServerWPF.Modules.MseedChart.ViewModels; +using StartServerWPF.Modules.MseedChart.Views; +using Prism.Ioc; +using Prism.Modularity; +using Prism.Regions; +using StartServerWPF.Modules.MseedChart.Core; + +namespace StartServerWPF.Modules.MseedChart +{ + public class MseedChartModule : IModule + { + public void OnInitialized(IContainerProvider containerProvider) + { + var regionManager = containerProvider.Resolve(); + // regionManager.RegisterViewWithRegion(RegionNames.ContentRegion, typeof(ChartPlotView)); + } + + public void RegisterTypes(IContainerRegistry containerRegistry) + { + containerRegistry.RegisterForNavigation(); + containerRegistry.RegisterSingleton(); + + } + } +} \ No newline at end of file diff --git a/StartServerWPF.Modules.MseedChart/Properties/AssemblyInfo.cs b/StartServerWPF.Modules.MseedChart/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..42e61ad --- /dev/null +++ b/StartServerWPF.Modules.MseedChart/Properties/AssemblyInfo.cs @@ -0,0 +1,55 @@ +using System.Reflection; +using System.Resources; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Windows; + +// 有关程序集的一般信息由以下 +// 控制。更改这些特性值可修改 +// 与程序集关联的信息。 +[assembly: AssemblyTitle("StartServerWPF.Modules.MseedChart")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("StartServerWPF.Modules.MseedChart")] +[assembly: AssemblyCopyright("Copyright © 2023")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// 将 ComVisible 设置为 false 会使此程序集中的类型 +//对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型 +//请将此类型的 ComVisible 特性设置为 true。 +[assembly: ComVisible(false)] + +//若要开始生成可本地化的应用程序,请设置 +//.csproj 文件中的 CultureYouAreCodingWith +//例如,如果您在源文件中使用的是美国英语, +//使用的是美国英语,请将 设置为 en-US。 然后取消 +//对以下 NeutralResourceLanguage 特性的注释。 更新 +//以下行中的“en-US”以匹配项目文件中的 UICulture 设置。 + +//[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)] + + +[assembly:ThemeInfo( + ResourceDictionaryLocation.None, //主题特定资源词典所处位置 + //(未在页面中找到资源时使用, + //或应用程序资源字典中找到时使用) + ResourceDictionaryLocation.SourceAssembly //常规资源词典所处位置 + //(未在页面中找到资源时使用, + //、应用程序或任何主题专用资源字典中找到时使用) +)] + + +// 程序集的版本信息由下列四个值组成: +// +// 主版本 +// 次版本 +// 生成号 +// 修订号 +// +//可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值 +//通过使用 "*",如下所示: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/StartServerWPF.Modules.MseedChart/Properties/Resources.Designer.cs b/StartServerWPF.Modules.MseedChart/Properties/Resources.Designer.cs new file mode 100644 index 0000000..98c8532 --- /dev/null +++ b/StartServerWPF.Modules.MseedChart/Properties/Resources.Designer.cs @@ -0,0 +1,62 @@ +//------------------------------------------------------------------------------ +// +// 此代码由工具生成。 +// 运行时版本: 4.0.30319.42000 +// +// 对此文件的更改可能导致不正确的行为,如果 +// 重新生成代码,则所做更改将丢失。 +// +//------------------------------------------------------------------------------ + +namespace StartServerWPF.Modules.MseedChart.Properties { + + + /// + /// 强类型资源类,用于查找本地化字符串等。 + /// + // 此类是由 StronglyTypedResourceBuilder + // 类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。 + // 若要添加或移除成员,请编辑 .ResX 文件,然后重新运行 ResGen + // (以 /str 作为命令选项),或重新生成 VS 项目。 + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() { + } + + /// + /// 返回此类使用的缓存 ResourceManager 实例。 + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if ((resourceMan == null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("StartServerWPF.Modules.MseedChart.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// 重写当前线程的 CurrentUICulture 属性,对 + /// 使用此强类型资源类的所有资源查找执行重写。 + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + } +} diff --git a/StartServerWPF.Modules.MseedChart/Properties/Resources.resx b/StartServerWPF.Modules.MseedChart/Properties/Resources.resx new file mode 100644 index 0000000..af7dbeb --- /dev/null +++ b/StartServerWPF.Modules.MseedChart/Properties/Resources.resx @@ -0,0 +1,117 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/StartServerWPF.Modules.MseedChart/Properties/Settings.Designer.cs b/StartServerWPF.Modules.MseedChart/Properties/Settings.Designer.cs new file mode 100644 index 0000000..7b22f64 --- /dev/null +++ b/StartServerWPF.Modules.MseedChart/Properties/Settings.Designer.cs @@ -0,0 +1,30 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace StartServerWPF.Modules.MseedChart.Properties +{ + + + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")] + internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase + { + + private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); + + public static Settings Default + { + get + { + return defaultInstance; + } + } + } +} diff --git a/StartServerWPF.Modules.MseedChart/Properties/Settings.settings b/StartServerWPF.Modules.MseedChart/Properties/Settings.settings new file mode 100644 index 0000000..033d7a5 --- /dev/null +++ b/StartServerWPF.Modules.MseedChart/Properties/Settings.settings @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/StartServerWPF.Modules.MseedChart/RegionNames.cs b/StartServerWPF.Modules.MseedChart/RegionNames.cs new file mode 100644 index 0000000..6334781 --- /dev/null +++ b/StartServerWPF.Modules.MseedChart/RegionNames.cs @@ -0,0 +1,27 @@ +using StartServerWPF.Modules.MseedChart.Models; +using System; +using System.Collections.Generic; +using System.Data; +using System.IO; +using System.Linq; + +namespace StartServerWPF.Modules.MseedChart.Core +{ + public static class RegionNames + { + public const string ContentRegion = "ContentRegion"; + + public static string MseedFilePath = @"H:\EwsCache\Mseed"; //AppDomain.CurrentDomain.BaseDirectory + "EwsCache\\Mseed"; + + + public static string TxtFilePath = @"H:\EwsCache\Txt";//;AppDomain.CurrentDomain.BaseDirectory + "EwsCache\\Txt"; + + + public static string DataTypeString = "A"; + + + public static Dictionary StationDic { get; set; } + + } + +} diff --git a/StartServerWPF.Modules.MseedChart/StartServerWPF.Modules.MseedChart.csproj b/StartServerWPF.Modules.MseedChart/StartServerWPF.Modules.MseedChart.csproj new file mode 100644 index 0000000..65cca3f --- /dev/null +++ b/StartServerWPF.Modules.MseedChart/StartServerWPF.Modules.MseedChart.csproj @@ -0,0 +1,151 @@ + + + + + Debug + AnyCPU + {E0B8EEB4-E63B-488C-BEAD-F03D488CDCB6} + library + StartServerWPF.Modules.MseedChart + StartServerWPF.Modules.MseedChart + v4.6.1 + 512 + {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + 4 + true + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + False + Libs\Arction.DirectX.dll + + + False + Libs\Arction.DirectXFiles.dll + + + False + Libs\Arction.DirectXInit.dll + + + False + Libs\Arction.Licensing.dll + + + False + Libs\Arction.RenderingDefinitions.dll + + + False + Libs\Arction.RenderingEngine.dll + + + False + Libs\Arction.RenderingEngine11.dll + + + False + Libs\Arction.RenderingEngine9.dll + + + False + Libs\Arction.Wpf.Charting.LightningChart.dll + + + ..\packages\DryIoc.dll.4.7.7\lib\net45\DryIoc.dll + + + ..\packages\Microsoft.Xaml.Behaviors.Wpf.1.1.31\lib\net45\Microsoft.Xaml.Behaviors.dll + + + ..\packages\Newtonsoft.Json.13.0.3\lib\net45\Newtonsoft.Json.dll + + + ..\packages\Prism.Core.8.1.97\lib\net461\Prism.dll + + + ..\packages\Prism.DryIoc.8.1.97\lib\net461\Prism.DryIoc.Wpf.dll + + + ..\packages\Prism.Wpf.8.1.97\lib\net461\Prism.Wpf.dll + + + + + + ..\packages\System.ValueTuple.4.5.0\lib\net461\System.ValueTuple.dll + + + + + + + + + 4.0 + + + + + + + + + + + + + + + Code + + + True + True + Resources.resx + + + True + Settings.settings + True + + + + + ChartPlotView.xaml + + + ResXFileCodeGenerator + Resources.Designer.cs + + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + + + MSBuild:Compile + Designer + + + + \ No newline at end of file diff --git a/StartServerWPF.Modules.MseedChart/ViewModels/ChartPlotViewModel.cs b/StartServerWPF.Modules.MseedChart/ViewModels/ChartPlotViewModel.cs new file mode 100644 index 0000000..218aa44 --- /dev/null +++ b/StartServerWPF.Modules.MseedChart/ViewModels/ChartPlotViewModel.cs @@ -0,0 +1,812 @@ +using Arction.Wpf.Charting; +using Arction.Wpf.Charting.Axes; +using Arction.Wpf.Charting.SeriesXY; +using Arction.Wpf.Charting.Views.ViewXY; +using Microsoft.Win32; +using StartServerWPF.Modules.MseedChart.Models; +using Prism.Commands; +using Prism.Events; +using Prism.Mvvm; +using SharpDX.Direct2D1; +using SharpDX.DirectWrite; +using System; +using System.Collections; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.ComponentModel; +using System.ComponentModel.Design.Serialization; +using System.Diagnostics; +using System.IO; +using System.Linq; +using System.Net.Http.Headers; +using System.Reflection; +using System.Security.Cryptography; +using System.Threading; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Documents; +using System.Windows.Markup; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Threading; +using System.Xml.Linq; +using Prism.Regions; + +namespace StartServerWPF.Modules.MseedChart.ViewModels +{ + public class ChartPlotViewModel : BindableBase, INavigationAware + { + + public ChartPlotViewModel() + { + _dispatcher = Application.Current.Dispatcher; + _wavesModel = new WavesModel(); + (Application.Current.MainWindow as System.Windows.Window).Closing += ApplicationClosingDispose; + IntervalTime=100; + CreateChart(); + + } + + #region 字段 + Dispatcher _dispatcher; + public int CurPoints; + int _channelCount = 0; + int _samplingFrequency = 500; // 采样频率 (Hz). + WavesModel _wavesModel; + private int _lChartCount = 1; + public ConcurrentQueue smList=new ConcurrentQueue(); + + public List _chartAxisY=new List(); + + private DispatcherTimer dispatcherTimer=new DispatcherTimer(); + #endregion + + #region 属性 + + private bool _isMultFiles; + + public bool IsMultFiles + { + get { return _isMultFiles; } + set + { + SetProperty(ref _isMultFiles, value); + } + } + private int _xaisInterval; + + public int XaisInterval + { + get { return _xaisInterval; } + set + { + SetProperty(ref _xaisInterval, value); + } + } + /// + /// 波形控件数量 + /// + public int LChartCount + { + get { return _lChartCount; } + set { _lChartCount = value; } + } + private LightningChart _lChartAll; + /// + /// 所有波形 + /// + public LightningChart LChartALL + { + get { return _lChartAll; } + set { _lChartAll = value; } + } + + private FrameworkElement childContent; + public FrameworkElement ChildContent + { + get { return childContent; } + set { childContent = value; } + } + + private Grid gridChart; + + public Grid GridChart + { + get { return gridChart; } + set { gridChart = value; } + } + private StationEventJson _currentEventTime; + + public StationEventJson CurrentEventTime + { + + get { return _currentEventTime; } + set { _currentEventTime = value; } + } + + private List _stationsName; + + public List StationsName + { + get { return _stationsName; } + set { + + SetProperty(ref _stationsName, value); + } + } + + private string _currentTime; + + public string CurrentTime + { + get { return _currentTime; } + set { + + SetProperty(ref _currentTime, value); + } + } + + private YAxisAutoPlacement _yaxisPlacement; + + public YAxisAutoPlacement YaxisPlacement + { + get { return _yaxisPlacement; } + set + { + LChartALL.ViewXY.AxisLayout.YAxisAutoPlacement = value; + int distancetoX =_wavesModel.SetYasixPlacement(LChartALL); + foreach (var item in LChartALL.ViewXY.YAxes) + { + item.Title.DistanceToAxis = distancetoX; + } + SetProperty(ref _yaxisPlacement, value); + } + } + + private int _IntervalTime=10; + + public int IntervalTime + { + get { return _IntervalTime; } + set + { + if (value >=10) + { + dispatcherTimer.Interval = TimeSpan.FromMilliseconds(value); + } + SetProperty(ref _IntervalTime, value); + } + } + + + private bool _SingleChannel=false; + + public bool SingleChannel + { + get { return _SingleChannel; } + set + { + if(!value) + { + YasixZENVisible("SHN", true); + YasixZENVisible("SHN", true); + YasixZENVisible("SHE", true); + } + else + { + YasixZENVisible("SHN", false); + YasixZENVisible("SHE", false); + YasixZENVisible("SHZ", false); + YasixZENVisible(SelectChannel, false); + } + + SetProperty(ref _SingleChannel, value); + } + } + + private string _SelectChannel; + public string SelectChannel + { + get { return _SelectChannel; } + set + { + if (SingleChannel) + { + YasixZENVisible(_SelectChannel, false); + YasixZENVisible(value, true); + } + SetProperty(ref _SelectChannel, value); + } + } + #endregion + + #region 事件 + public DelegateCommand LoadedCommand => new DelegateCommand(Loaded); + public DelegateCommand AxesYVisibleCommand => new DelegateCommand(AxesYVisible); + public DelegateCommand FileSelectorCommand => new DelegateCommand(FileSelector); + public DelegateCommand OtimeSortCommand => new DelegateCommand(OtimeSort); + public DelegateCommand IntervalSureCommand => new DelegateCommand(IntervalSure); + public DelegateCommand RealTimeDataCommand => new DelegateCommand(RealTimeData); + + private void Loaded() + { + + } + + private void AxesYVisible(object isCheck) + { + if (_lChartAll != null) + { + bool yAxesVisible = ((bool)isCheck == true); + _lChartAll.BeginUpdate(); + foreach (AxisY yAxis in _lChartAll.ViewXY.YAxes) + { + yAxis.Visible = yAxesVisible; + } + _lChartAll.EndUpdate(); + + } + } + + private void FileSelector(object obj) + { + IsMultFiles = Convert.ToBoolean(obj); + OpenFileDialog openFileDialog = new OpenFileDialog + { + RestoreDirectory = true, + Filter = ".mseed|*.mseed|.json|*.json|.txt|*.txt", + }; + if (openFileDialog.ShowDialog() == true) + { + string asciiSavePath = openFileDialog.FileName.Replace("Mseed", "Txt"); + asciiSavePath = Path.ChangeExtension(asciiSavePath, ".txt"); + string JsonPath = Path.ChangeExtension(openFileDialog.FileName, "Json"); + Stopwatch st = new Stopwatch(); + st.Start(); + //读取.json文件 + CurrentEventTime = _wavesModel.ReadChartJsonFile(JsonPath); + //读取.mseed文件 + smList = _wavesModel.ReadMseedFile(openFileDialog.FileName, asciiSavePath, IsMultFiles); + _channelCount = smList.Count * 3; + CurrentTime = smList.First().BeginTime.ToShortDateString(); + StationsName = smList.Select(a => new StationAxis{Name= a.Name,IsChecked=true,SelectCommand =new DelegateCommand(StationsNameVisible)}).ToList(); + StartChart(); + st.Stop(); + Debug.WriteLine("统计时间StartChart************:{0}", st.Elapsed); + FeedDatasToChart(); + _wavesModel.CreateAxisYEventTime(CurrentEventTime, LChartALL.ViewXY, smList.ToList()); + + } + } + + private void OtimeSort(object isCheck) + { + if (_lChartAll != null) + { + LChartALL.BeginUpdate(); + bool yAxesVisible = ((bool)isCheck == true); + ViewXY v = _lChartAll.ViewXY; + IOrderedEnumerable lines; + if (yAxesVisible) + { + lines = v.LineCollections.Where(a => a.Tag != null && a.Tag.ToString().Contains("SHZ")).OrderBy(a => a.Lines[0].AX); + } + else + { + lines = v.LineCollections.Where(a => a.Tag != null && a.Tag.ToString().Contains("SHZ")).OrderByDescending(b => b.Lines[0].AX); ; + } + int number = v.YAxes.Count / (_chartAxisY.Count / 3); + foreach (var item in lines.Reverse()) + { + int index = item.AssignYAxisIndex; + for (int i = 0; i < number; i++) + { + if (index == -1) continue; //隐藏轴不需要处理 + AxisY axisY = v.YAxes[index + i]; + v.YAxes.RemoveAt(index + i); + v.YAxes.Insert(i, axisY); + } + } + LChartALL.EndUpdate(); + } + } + + private void YasixZENVisible(string content, bool yAxesVisible) + { + if (_lChartAll != null) + { + _lChartAll.BeginUpdate(); + + ViewXY v = _lChartAll.ViewXY; + string conStr = (content == "SHZ") ? ".Z" : (content == "SHN") ? ".N" : ".E"; + for (int i = 0; i <_chartAxisY.Count; i++) + { + AxisY axisY = _chartAxisY[i]; + if (axisY.Title.Text.Contains(conStr)) + { + if (yAxesVisible) + { + v.YAxes.Remove(axisY); + } + else + { + string str = axisY.Title.Text.Replace(conStr, ""); + int yIndex = 0; + if (content == "SHZ") + { + yIndex = v.YAxes.FindIndex(y => y.Title.Text.Contains(str)); + } + else if (content == "SHE") + { + yIndex = v.YAxes.FindLastIndex(y => y.Title.Text.Contains(str)); + if (yIndex != -1) yIndex += 1; + } + else + { + yIndex = v.YAxes.FindIndex(y => y.Title.Text.Contains(str)); + if (yIndex != -1) + { + if (v.YAxes[yIndex].Title.Text.Contains(".Z")) + { + yIndex = yIndex + 1; + } + } + } + //如果没有查到,直接添加到前面,如果为容器最大索引,只能添加到后面 + if (yIndex == -1 || (yIndex == v.YAxes.Count)) + { + yIndex = v.YAxes.Count; + v.YAxes.Add(axisY); + } + else + { + v.YAxes.Insert(yIndex, axisY); + } + int sampleIndex = v.SampleDataSeries.FindIndex(y => y.Title.Text == _chartAxisY[i].Title.Text); + v.SampleDataSeries[sampleIndex].AssignYAxisIndex = yIndex; + int lineIndex = v.LineCollections.FindIndex(a => a.Title.Text.Contains(_chartAxisY[i].Title.Text)); + if (lineIndex != -1) + { + v.LineCollections[lineIndex].AssignYAxisIndex = yIndex; + } + } + } + } + _lChartAll.EndUpdate(); + } + } + + private void IntervalSure() + { + if (_lChartAll != null) + { + _lChartAll.BeginUpdate(); + + if (XaisInterval >= 2) + { + _lChartAll.ViewXY.XAxes[0].MajorDivCount = XaisInterval; + } + _lChartAll.EndUpdate(); + + } + } + + private void StationsNameVisible(object obj) + { + var station = obj as StationAxis; + if (_lChartAll != null) + { + _lChartAll.BeginUpdate(); + bool yAxesVisible = (station.IsChecked == false); + ViewXY v = _lChartAll.ViewXY; + var yAxisList= _chartAxisY.Where(y => y.Title.Text.Contains(station.Name)); + foreach (var item in yAxisList) + { + if (yAxesVisible) + { + v.YAxes.Remove(item); + } + else + { + v.YAxes.Add(item); + //SampleDataSeries查找数据对应的Y轴索引, 重新分配到对应的轴 + int sampleIndex = v.SampleDataSeries.FindIndex(s => s.Title.Text == item.Title.Text); + v.SampleDataSeries[sampleIndex].AssignYAxisIndex = v.YAxes.Count()-1; + //LineCollections查找数据对应的Y轴索引, 重新分配到对应的轴 + int lineIndex = v.LineCollections.FindIndex(s => s.Title.Text.Contains(item.Title.Text)); + if (lineIndex != -1) + { + v.LineCollections[lineIndex].AssignYAxisIndex = v.YAxes.Count() - 1; + } + } + } + _lChartAll.EndUpdate(); + } + } + + private void RealTimeData(object isCheck) + { + if (_lChartAll != null) + { + bool yAxesVisible = ((bool)isCheck == true); + if (smList.Count == 0) + { + return; + } + _lChartAll.BeginUpdate(); + if (yAxesVisible) + { + StartChart(); + //Set real-time monitoring automatic old data destruction + LChartALL.ViewXY.DropOldSeriesData = true; + _pointsAppended = LChartALL.ViewXY.XAxes[0].Minimum; + dispatcherTimer.Tick -= CompositionTarget_Rendering; + dispatcherTimer.Tick += CompositionTarget_Rendering; + LChartALL.ViewXY.XAxes[0].ScrollMode = XAxisScrollMode.Scrolling; + dispatcherTimer.Start(); + } + else + { + dispatcherTimer.Stop(); + + LChartALL.ViewXY.XAxes[0].ScrollMode = XAxisScrollMode.None; + dispatcherTimer.Tick -= CompositionTarget_Rendering; + } + + _lChartAll.EndUpdate(); + } + } + #endregion + private void CreateChart() + { + if (LChartALL != null) + { + LChartALL = null; + } + LChartALL = new LightningChart(); + LChartALL.Title.Align = ChartTitleAlignment.TopCenter; + LChartALL.ChartRenderOptions.DeviceType = RendererDeviceType.AutoPreferD11; + LChartALL.ChartRenderOptions.LineAAType2D = LineAntiAliasingType.QLAA; + + LChartALL.Title.Text = "事件波形"; + LChartALL.Title.Font = new WpfFont("等线", 20); + + //轴属性和布局 + LChartALL.ViewXY.AxisLayout.YAxesLayout = YAxesLayout.Stacked; + LChartALL.ViewXY.AxisLayout.SegmentsGap = 0; + LChartALL.ViewXY.ZoomPanOptions.PanDirection = PanDirection.Horizontal; + LChartALL.ViewXY.ZoomPanOptions.WheelZooming = WheelZooming.Horizontal; + LChartALL.ViewXY.AxisLayout.YAxisAutoPlacement = YAxisAutoPlacement.AllRight; + LChartALL.ViewXY.AxisLayout.YAxisTitleAutoPlacement = false; + LChartALL.ViewXY.AxisLayout.AutoAdjustMargins = false; + + LChartALL.ViewXY.ZoomPanOptions.DevicePrimaryButtonAction = UserInteractiveDeviceButtonAction.Pan; + LChartALL.ViewXY.ZoomPanOptions.DeviceSecondaryButtonAction = UserInteractiveDeviceButtonAction.None; + LChartALL.ViewXY.ZoomPanOptions.WheelZooming = WheelZooming.Horizontal; + // 反锯齿系数。值0和1都不会应用反锯齿 + LChartALL.ChartRenderOptions.AntiAliasLevel = 0; + //X轴设置 + LChartALL.ViewXY.XAxes[0].AllowScrolling = true; + LChartALL.ViewXY.XAxes[0].PanningEnabled = true; + LChartALL.ViewXY.XAxes[0].MajorGrid.Pattern = LinePattern.Solid; + LChartALL.ViewXY.XAxes[0].ValueType = AxisValueType.DateTime; + LChartALL.ViewXY.XAxes[0].KeepDivCountOnRangeChange = true; + //LChartALL.ViewXY.XAxes[0].MajorDiv =6; + LChartALL.ViewXY.XAxes[0].LabelsColor = Colors.Black; + LChartALL.ViewXY.XAxes[0].AutoDivSpacing = false; + LChartALL.ViewXY.XAxes[0].MajorDivCount = 5; + XaisInterval = 5; + + //图表背景颜色 + LChartALL.ViewXY.GraphBackground.Color = Colors.White; + LChartALL.ViewXY.GraphBackground.GradientColor = Colors.White; + LChartALL.ChartBackground.GradientFill = GradientFill.Solid; + LChartALL.ChartBackground.Color = Color.FromArgb(0, 0, 0, 0); + GridChart = new Grid(); + GridChart.ColumnDefinitions.Add(new ColumnDefinition()); + GridChart.Name = "chartGrid"; + GridChart.Children.Add(LChartALL); + + this.ChildContent = GridChart; + } + + private void StartChart() + { + DisposeAllAndClear(_chartAxisY); + ViewXY v = LChartALL.ViewXY; + LChartALL.SizeChanged -= LChartALL_SizeChanged; + LChartALL.SizeChanged += LChartALL_SizeChanged; + LChartALL.ViewXY.Zoomed -= ViewXY_Zoomed; + LChartALL.ViewXY.Zoomed += ViewXY_Zoomed; + LChartALL.ViewXY.Panned -= ViewXY_Panned; + LChartALL.ViewXY.Panned += ViewXY_Panned; + DisposeAllAndClear(v.YAxes); + DisposeAllAndClear(v.SampleDataSeries); + DisposeAllAndClear(v.LineCollections); + v.Margins=new Thickness(60, 30, 60, 60); + + v.YAxes.AddRange(_wavesModel.CreateYAxisChart(smList.ToList(), LChartALL)); + v.LegendBoxes[0].Position = LegendBoxPositionXY.RightCenter; + v.LegendBoxes[0].Offset.SetValues(-10, 180); + v.LegendBoxes[0].Layout = LegendBoxLayout.Vertical; + v.LegendBoxes[0].Visible = false; + v.LegendBoxes[0].Shadow.Color = Colors.Transparent; + v.LegendBoxes[0].BorderColor = Colors.Transparent; + v.AutoSpaceLegendBoxes = true; + v.AxisLayout.SegmentsGap = 3; + v.LegendBoxes[0].Shadow.Visible = false; + + StationModel stationModel = smList.First(); + var beginTime= stationModel.BeginTime; + if (AxisValueType.DateTime == v.XAxes[0].ValueType) + { + //设置X轴的开始时间 + v.XAxes[0].AutoFormatLabels = false; + v.XAxes[0].LabelsTimeFormat = "HH:mm:ss.ff"; + v.XAxes[0].DateOriginYear = beginTime.Year; + v.XAxes[0].DateOriginDay = beginTime.Day; + v.XAxes[0].DateOriginMonth = beginTime.Month; + DateTime MaxDateTime = beginTime.AddSeconds(_samplingFrequency == 500 ? 30 : 60); + v.XAxes[0].SetRange(v.XAxes[0].DateTimeToAxisValue(beginTime), v.XAxes[0].DateTimeToAxisValue(MaxDateTime)); + } + double firstSampleTimeStamp = v.XAxes[0].DateTimeToAxisValue(beginTime); + + int count = stationModel.Dzne.Count; + int number= smList.Count*3; + + for (int i = 0; i < number; i++) + { + int seriesIndex = i; + AxisY axisY = v.YAxes[seriesIndex]; + axisY.LabelsColor = Colors.Black; + axisY.Title.Shadow.DropColor = Colors.Transparent; + // axisY.Title.Shadow.ContrastColor = Colors.Transparent; + axisY.Title.AllowDragging = false; + axisY.AllowAutoYFit = false; + axisY.Units.Visible = false; + axisY.LabelsFont.Size = 10; + axisY.Title.Angle = 0; + axisY.MinorGrid.Visible = false; + axisY.AutoDivSpacing = false; + axisY.MajorDivCount = 2; + axisY.MinorDivTickStyle.Visible = false; + axisY.MajorDivTickStyle.Alignment = seriesIndex % 2 == 0 ? Alignment.Near : Alignment.Far; + // axisY.MajorDivTickStyle.LineLength = 6; + axisY.MajorDivTickStyle.Color = Colors.Black; + axisY.Title.Color = Colors.Black; + axisY.Title.Font = new WpfFont("Segoe UI", 10, false, false); + axisY.PanningEnabled = false; + axisY.AllowScrolling = false; + axisY.AllowScaling = false; + + SampleDataSeries series = new SampleDataSeries(v, v.XAxes[0], axisY); + series.ShowInLegendBox = false; + series.FirstSampleTimeStamp = firstSampleTimeStamp; + series.SamplingFrequency = _samplingFrequency; + series.Title.Text = axisY.Title.Text; + series.SampleFormat = SampleFormat.DoubleFloat; + if (seriesIndex % 3 == 0) + { + series.LineStyle.Color = System.Windows.Media.Colors.DeepSkyBlue; + } + else if (seriesIndex % 3 == 1) + { + series.LineStyle.Color = System.Windows.Media.Colors.OrangeRed; + } + else if (seriesIndex % 3 == 2) + { + series.LineStyle.Color = System.Windows.Media.Colors.ForestGreen; + } + series.LineStyle.Width = 0.2; + series.ScrollModePointsKeepLevel = 1; + //series.ScrollingStabilizing = true; + v.SampleDataSeries.Add(series); + _chartAxisY.Add(axisY); + } + } + + private void ViewXY_Panned(object sender, PannedXYEventArgs e) + { + foreach (var item in LChartALL.ViewXY.LineCollections) + { + double b = LChartALL.ViewXY.XAxes[0].ValueToCoordD(item.Lines[0].AX) - 80; + item.Title.Offset.SetValues((int)b, 3); + } + } + + private void ViewXY_Zoomed(object sender, ZoomedXYEventArgs e) + { + foreach (var item in LChartALL.ViewXY.LineCollections) + { + double b = LChartALL.ViewXY.XAxes[0].ValueToCoordD(item.Lines[0].AX) - 80; + item.Title.Offset.SetValues((int)b, 3); + } + } + + private void LChartALL_SizeChanged(object sender, SizeChangedEventArgs e) + { + int distancetoX = _wavesModel.SetYasixPlacement(LChartALL); + foreach (var item in LChartALL.ViewXY.YAxes) + { + item.Title.DistanceToAxis = distancetoX; + } + foreach (var item in LChartALL.ViewXY.LineCollections) + { + double b = LChartALL.ViewXY.XAxes[0].ValueToCoordD(item.Lines[0].AX)-80; + item.Title.Offset.SetValues((int)b, 3); + } + } + + private void FeedDatasToChart() + { + _data = new double[smList.Count * 3][]; + try + { + for (int channelIndex = 0; channelIndex < smList.Count; channelIndex++) + { + _data[channelIndex * 3] = smList.ElementAt(channelIndex).dz.ToArray(); + _data[channelIndex * 3 + 1] = smList.ElementAt(channelIndex).dn.ToArray(); + _data[channelIndex * 3 + 2] = smList.ElementAt(channelIndex).de.ToArray(); + } + // Invoke FeedNewDataToChart. + _dispatcher.Invoke(() => + { + LChartALL.BeginUpdate(); + for (int channelIndex = 0; channelIndex < _channelCount; channelIndex++) + { + LChartALL.ViewXY.SampleDataSeries[channelIndex].AddSamples(_data[channelIndex], true); + } + LChartALL.EndUpdate(); + }); + } + catch (Exception ex) + { + throw ex; + } + } + + private void ApplicationClosingDispose(object sender, CancelEventArgs e) + { + if (LChartALL != null) + { + LChartALL.Dispose(); + LChartALL = null; + } + } + + private void DisposeAllAndClear(List list) where T : IDisposable + { + if (list == null) + { + return; + } + + while (list.Count > 0) + { + int lastInd = list.Count - 1; + T item = list[lastInd]; // take item ref from list. + list.RemoveAt(lastInd); // remove item first + if (item != null) + { + (item as IDisposable).Dispose(); // then dispose it. + } + } + } + public void Dispose() + { + gridChart.Children.Clear(); + + if (LChartALL != null) + { + LChartALL.Dispose(); + LChartALL = null; + } + } + + #region 实时数据 + private void CompositionTarget_Rendering(object sender, EventArgs e) + { + RenderNextFrame(); + } + private void RenderNextFrame() + { + if (_lChartAll == null) + { + return; + } + + _dispatcher.Invoke(() => + { + FeedData(/*chartTitleText*/); + }); + } + int _iRound = 0; + double _pointsAppended = 0; + double[][] _data; + int PreGenerateDataForRoundCount = 6; + private void FeedData(/*string chartTitleText*/) + { + if (_lChartAll != null) + { + _lChartAll.BeginUpdate(); + + //Append data to series + System.Threading.Tasks.Parallel.For(0, _channelCount, (seriesIndex) => + { + double[] thisSeriesData = _data[seriesIndex]; + double[] dataToAppendNow = new double[_samplingFrequency]; + Array.Copy(thisSeriesData, (_iRound % PreGenerateDataForRoundCount) * _samplingFrequency, dataToAppendNow, 0, _samplingFrequency); + _lChartAll.ViewXY.SampleDataSeries[seriesIndex].AddSamples(dataToAppendNow, false); + System.Diagnostics.Debug.WriteLine("***********index:{0}, pointCount:{1},time:{2}", seriesIndex, + _lChartAll.ViewXY.SampleDataSeries[seriesIndex].PointCount, DateTime.Now); + }); + _pointsAppended += 1; + + //Set X axis real-time scrolling position + double lastX = _pointsAppended; + _lChartAll.ViewXY.XAxes[0].ScrollPosition = lastX; + + //Update sweep bands + if (_lChartAll.ViewXY.XAxes[0].ScrollMode == XAxisScrollMode.Sweeping) + { + + //Dark band of old page fading away + double pageLen = _lChartAll.ViewXY.XAxes[0].Maximum - _lChartAll.ViewXY.XAxes[0].Minimum; + double sweepGapWidth = pageLen / 20.0; + _lChartAll.ViewXY.Bands[0].SetValues(lastX - pageLen, lastX - pageLen + sweepGapWidth); + if (_lChartAll.ViewXY.Bands[0].Visible == false) + { + _lChartAll.ViewXY.Bands[0].Visible = true; + } + + + //Bright new page band + _lChartAll.ViewXY.Bands[1].SetValues(lastX - sweepGapWidth / 6, lastX); + if (_lChartAll.ViewXY.Bands[1].Visible == false) + { + _lChartAll.ViewXY.Bands[1].Visible = true; + } + } + else + { + //Hide sweeping bands if not in sweeping mode + //if (_lChartAll.ViewXY.Bands[0].Visible == true) + //{ + // _lChartAll.ViewXY.Bands[0].Visible = false; + //} + + //if (_lChartAll.ViewXY.Bands[1].Visible == true) + //{ + // _lChartAll.ViewXY.Bands[1].Visible = false; + //} + } + _lChartAll.EndUpdate(); + + _iRound++; + } + } + + public void OnNavigatedTo(NavigationContext navigationContext) + { + var str= navigationContext.Parameters.GetValue("model"); + if(str == "实时波形") + { + + } + } + + public bool IsNavigationTarget(NavigationContext navigationContext) + { + return true; + } + + public void OnNavigatedFrom(NavigationContext navigationContext) + { + + } + + #endregion + } +} diff --git a/StartServerWPF.Modules.MseedChart/Views/ChartPlotView.xaml b/StartServerWPF.Modules.MseedChart/Views/ChartPlotView.xaml new file mode 100644 index 0000000..a5c07c8 --- /dev/null +++ b/StartServerWPF.Modules.MseedChart/Views/ChartPlotView.xaml @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + + + X轴间隔: + + + + + + + + + + + + + + + + + + + + + + diff --git a/StartServerWPF.Modules.MseedChart/Views/ChartPlotView.xaml.cs b/StartServerWPF.Modules.MseedChart/Views/ChartPlotView.xaml.cs new file mode 100644 index 0000000..4a28fe5 --- /dev/null +++ b/StartServerWPF.Modules.MseedChart/Views/ChartPlotView.xaml.cs @@ -0,0 +1,29 @@ +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 StartServerWPF.Modules.MseedChart.Views +{ + /// + /// Interaction logic for ViewA.xaml + /// + public partial class ChartPlotView : UserControl + { + public ChartPlotView() + { + InitializeComponent(); + } + + } +} diff --git a/StartServerWPF.Modules.MseedChart/packages.config b/StartServerWPF.Modules.MseedChart/packages.config new file mode 100644 index 0000000..d4f8144 --- /dev/null +++ b/StartServerWPF.Modules.MseedChart/packages.config @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/StartServerWPF.sln b/StartServerWPF.sln index 9e75803..38fd939 100644 --- a/StartServerWPF.sln +++ b/StartServerWPF.sln @@ -7,6 +7,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "StartServerWPF.Modules.Main EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "StartServerWPF", "StartServerWPF\StartServerWPF.csproj", "{7585A28B-9A36-4B10-9033-0214C93F68F5}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StartServerWPF.Modules.MseedChart", "StartServerWPF.Modules.MseedChart\StartServerWPF.Modules.MseedChart.csproj", "{E0B8EEB4-E63B-488C-BEAD-F03D488CDCB6}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -21,6 +23,10 @@ Global {7585A28B-9A36-4B10-9033-0214C93F68F5}.Debug|Any CPU.Build.0 = Debug|Any CPU {7585A28B-9A36-4B10-9033-0214C93F68F5}.Release|Any CPU.ActiveCfg = Release|Any CPU {7585A28B-9A36-4B10-9033-0214C93F68F5}.Release|Any CPU.Build.0 = Release|Any CPU + {E0B8EEB4-E63B-488C-BEAD-F03D488CDCB6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E0B8EEB4-E63B-488C-BEAD-F03D488CDCB6}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E0B8EEB4-E63B-488C-BEAD-F03D488CDCB6}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E0B8EEB4-E63B-488C-BEAD-F03D488CDCB6}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/StartServerWPF/App.xaml.cs b/StartServerWPF/App.xaml.cs index ba2d42a..715f06d 100644 --- a/StartServerWPF/App.xaml.cs +++ b/StartServerWPF/App.xaml.cs @@ -10,6 +10,7 @@ using System; using System.Threading.Tasks; using System.Windows; using System.Windows.Threading; +using StartServerWPF.Modules.MseedChart; namespace StartServerWPF { @@ -37,6 +38,7 @@ namespace StartServerWPF protected override void ConfigureModuleCatalog(IModuleCatalog moduleCatalog) { moduleCatalog.AddModule(); + moduleCatalog.AddModule(); base.ConfigureModuleCatalog(moduleCatalog); } diff --git a/StartServerWPF/StartServerWPF.csproj b/StartServerWPF/StartServerWPF.csproj index 3b8075d..695a3ec 100644 --- a/StartServerWPF/StartServerWPF.csproj +++ b/StartServerWPF/StartServerWPF.csproj @@ -9,6 +9,7 @@ + diff --git a/StartServerWPF/SystemConfig.json b/StartServerWPF/SystemConfig.json index 238a71c..5585232 100644 --- a/StartServerWPF/SystemConfig.json +++ b/StartServerWPF/SystemConfig.json @@ -29,7 +29,7 @@ "ShowState": 0 }, "proRecv": { - "ProName": "recvftp", + "ProName": "gw.recvftp", "ProTitle": "数据接收", "ProPath": "serverprogram\\recvftp\\", "ProParams": "-cfg gw.recvftp.json >outRecv.txt", @@ -39,7 +39,7 @@ "ShowState": 0 }, "proApms": { - "ProName": "apms", + "ProName": "gw.apms", "ProTitle": "实时处理", "ProPath": "serverprogram\\apms\\", "ProParams": "-cfg apms.json >outApms.txt", @@ -49,7 +49,7 @@ "ShowState": 0 }, "proTools": { - "ProName": "tools", + "ProName": "gw.tools", "ProTitle": "后处理", "ProPath": "serverprogram\\tools\\", "ProParams": "-cfg apms.json -savepath e:\\yuwuN3102mseed -delay 600",