diff --git a/mseedChart.MainModule/ViewModels/ChartPlotViewModel.cs b/mseedChart.MainModule/ViewModels/ChartPlotViewModel.cs index 5d87e25..e7a8065 100644 --- a/mseedChart.MainModule/ViewModels/ChartPlotViewModel.cs +++ b/mseedChart.MainModule/ViewModels/ChartPlotViewModel.cs @@ -31,6 +31,7 @@ using System.Windows.Markup; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Threading; +using System.Xml.Linq; namespace mseedChart.MainModule.ViewModels { @@ -72,7 +73,7 @@ namespace mseedChart.MainModule.ViewModels public int CurPoints; int _channelCount = 0; - double _samplingFrequency = 500; // 采样频率 (Hz). + int _samplingFrequency = 500; // 采样频率 (Hz). WavesModel _wavesModel; private int _lChartCount = 1; public ConcurrentQueue smList; @@ -165,9 +166,9 @@ namespace mseedChart.MainModule.ViewModels public List StationYaxis { get { return _stationYaxis; } - set { + set { - SetProperty(ref _stationYaxis, value); + SetProperty(ref _stationYaxis, value); } } @@ -188,7 +189,7 @@ namespace mseedChart.MainModule.ViewModels get { return _stationYaxisIsChecked; } set { StationYaxisVisible(value); - SetProperty(ref _stationYaxisIsChecked , value); + SetProperty(ref _stationYaxisIsChecked, value); } } #endregion @@ -200,6 +201,8 @@ namespace mseedChart.MainModule.ViewModels public DelegateCommand YasixZENVisibleCommand => new DelegateCommand(YasixZENVisible); public DelegateCommand IntervalSureCommand => new DelegateCommand(IntervalSure); + public DelegateCommand RealTimeDataCommand => new DelegateCommand(RealTimeData); + private void AxesYVisible(object isCheck) { if (_lChartAll != null) @@ -232,7 +235,7 @@ namespace mseedChart.MainModule.ViewModels { yAxis.AxisThickness = 0; } - // lastYAxis.MiniScale.Visible = !yAxesVisible; + // lastYAxis.MiniScale.Visible = !yAxesVisible; } } _lChartAll.EndUpdate(); @@ -249,20 +252,20 @@ namespace mseedChart.MainModule.ViewModels }; if (openFileDialog.ShowDialog() == true) { - string asciiSavePath = openFileDialog.FileName; - asciiSavePath = asciiSavePath.Replace("Mseed","Txt"); - asciiSavePath= Path.ChangeExtension(asciiSavePath, ".txt"); - - ShowWave(openFileDialog.FileName, asciiSavePath, IsMultFiles); + string asciiSavePath = openFileDialog.FileName; + asciiSavePath = asciiSavePath.Replace("Mseed", "Txt"); + asciiSavePath = Path.ChangeExtension(asciiSavePath, ".txt"); + + ShowWave(openFileDialog.FileName, asciiSavePath, IsMultFiles); } } private void OtimeSort(object isCheck) - { + { if (_lChartAll != null) { LChartALL.BeginUpdate(); bool yAxesVisible = ((bool)isCheck == true); - ViewXY v= _lChartAll.ViewXY; + ViewXY v = _lChartAll.ViewXY; IOrderedEnumerable lines; if (yAxesVisible) { @@ -274,7 +277,7 @@ namespace mseedChart.MainModule.ViewModels } foreach (var item in lines) { - var a= item.Tag.ToString().Contains("SHZ"); + var a = item.Tag.ToString().Contains("SHZ"); } foreach (var item in lines.Reverse()) { @@ -370,6 +373,33 @@ namespace mseedChart.MainModule.ViewModels _lChartAll.EndUpdate(); } } + + + private void RealTimeData(object isCheck) + { + if (_lChartAll != null) + { + bool yAxesVisible = ((bool)isCheck == true); + _lChartAll.BeginUpdate(); + if (yAxesVisible) + { + + //Set real-time monitoring automatic old data destruction + LChartALL.ViewXY.DropOldSeriesData = true; + _pointsAppended = LChartALL.ViewXY.XAxes[0].Minimum; + CompositionTarget.Rendering -= CompositionTarget_Rendering; + CompositionTarget.Rendering += CompositionTarget_Rendering; + LChartALL.ViewXY.XAxes[0].ScrollMode = XAxisScrollMode.Scrolling; + } + else + { + LChartALL.ViewXY.XAxes[0].ScrollMode = XAxisScrollMode.None; + CompositionTarget.Rendering -= CompositionTarget_Rendering; + } + + _lChartAll.EndUpdate(); + } + } #endregion public List UpdateWavesFromTxt(string fn) { @@ -404,7 +434,7 @@ namespace mseedChart.MainModule.ViewModels { station = new StationModel(); station.Name = stationName; - station.BeginTime =Convert.ToDateTime(rowStr[3]); + station.BeginTime = Convert.ToDateTime(rowStr[3]); station.PointCount = int.Parse(rowStr[1].Trim().Split(' ')[0]); station.SamplingFrequency = int.Parse(rowStr[2].Trim().Split(' ')[0]); temSM.Add(station); @@ -528,16 +558,16 @@ namespace mseedChart.MainModule.ViewModels var asciiFiles = new DirectoryInfo(Path.GetDirectoryName(asciiSavePath)); var asciifile = asciiFiles.GetFiles(); - if (asciifile.Count()==0) + if (asciifile.Count() == 0) { - // 并行运算 - Stopwatch sw = Stopwatch.StartNew(); + // 并行运算 + Stopwatch sw = Stopwatch.StartNew(); Parallel.ForEach(mseedFiles, (item) => { MSeed2Asc(item.FullName, Path.Combine(Path.GetDirectoryName(asciiSavePath), Path.GetFileNameWithoutExtension(item.Name))); }); sw.Stop(); - Debug.WriteLine("MSeed2Asc解压时间:" +sw.Elapsed.TotalSeconds); + Debug.WriteLine("MSeed2Asc解压时间:" + sw.Elapsed.TotalSeconds); } // 并行运算 Parallel.ForEach(asciiFiles.GetFiles(), (item) => @@ -545,7 +575,7 @@ namespace mseedChart.MainModule.ViewModels var list = UpdateWavesFromTxt(item.FullName); list.ForEach(i => smList.Enqueue(i)); }); - } + } else { if (!File.Exists(asciiSavePath)) @@ -554,17 +584,17 @@ namespace mseedChart.MainModule.ViewModels } var list = UpdateWavesFromTxt(asciiSavePath); list.ForEach(i => smList.Enqueue(i)); - } - + } + _channelCount = smList.Count * 3; StationYaxis = smList.Select(a => a.Name).ToList(); UpdateChart(); UpdateChartData(); } - + private void UpdateChart() - { - ViewXY v= LChartALL.ViewXY; + { + ViewXY v = LChartALL.ViewXY; DisposeAllAndClear(v.YAxes); DisposeAllAndClear(v.SampleDataSeries); DisposeAllAndClear(v.LineCollections); @@ -576,7 +606,7 @@ namespace mseedChart.MainModule.ViewModels v.LegendBoxes[0].Visible = false; v.AutoSpaceLegendBoxes = true; v.AxisLayout.SegmentsGap = 3; - v.LegendBoxes[0].Shadow.Visible =false; + v.LegendBoxes[0].Shadow.Visible = false; StationModel stationModel = smList.ElementAt(0); if (AxisValueType.DateTime == v.XAxes[0].ValueType) @@ -598,7 +628,7 @@ namespace mseedChart.MainModule.ViewModels for (int k = 0; k < smList.ElementAt(i).Dzne.Count; k++) { int seriesIndex = i * 3 + k; - AxisY axisY= v.YAxes[seriesIndex]; + AxisY axisY = v.YAxes[seriesIndex]; axisY.LabelsColor = Colors.Black; axisY.Title.Shadow.DropColor = Colors.Transparent; axisY.Title.Shadow.ContrastColor = Colors.Transparent; @@ -643,7 +673,7 @@ namespace mseedChart.MainModule.ViewModels { series.LineStyle.Color = System.Windows.Media.Colors.Green; } - series.LineStyle.Width =0.5; + series.LineStyle.Width = 0.5; series.LineStyle.AntiAliasing = LineAntialias.None; series.ScrollModePointsKeepLevel = 1; series.ScrollingStabilizing = true; @@ -663,6 +693,7 @@ namespace mseedChart.MainModule.ViewModels multiChannelData[channelIndex * 3 + 1] = smList.ElementAt(channelIndex).dn.ToArray(); multiChannelData[channelIndex * 3 + 2] = smList.ElementAt(channelIndex).de.ToArray(); } + _data = multiChannelData; // Invoke FeedNewDataToChart. _dispatcher.Invoke(() => { @@ -725,5 +756,91 @@ namespace mseedChart.MainModule.ViewModels } + + #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++; + } + } + + #endregion } } diff --git a/mseedChart.MainModule/Views/ChartPlotView.xaml b/mseedChart.MainModule/Views/ChartPlotView.xaml index 75a9901..cebb82e 100644 --- a/mseedChart.MainModule/Views/ChartPlotView.xaml +++ b/mseedChart.MainModule/Views/ChartPlotView.xaml @@ -27,6 +27,7 @@ X轴时间间隔: +