diff --git a/StartServerWPF.Modules.MseedChart/Mseed2asciiApi.cs b/StartServerWPF.Modules.MseedChart/Mseed2asciiApi.cs index a2e3105..39abf27 100644 --- a/StartServerWPF.Modules.MseedChart/Mseed2asciiApi.cs +++ b/StartServerWPF.Modules.MseedChart/Mseed2asciiApi.cs @@ -45,16 +45,26 @@ namespace StartServerWPF.Modules.MseedChart public double samprate { set; get; } public double StartOATime { set; get; } public Int64 numsamples { set; get; } + public double Average { set; get; } = 0; public List datas { get; }=new List(); public void AddData(double aoTime, double[] da) { StartOATime = aoTime; - if (datas.Count>=60) + if (datas.Count >= 30) { datas.RemoveAt(0); } - datas.Add(da); + if (da[0] == 0) + { + if (datas.Count!= 0) + { + double[] temp = datas.Last(); + Average = temp.Average(); + da = Enumerable.Repeat(Average, temp.Length).ToArray(); + } + } + datas.Add(da); } } } diff --git a/StartServerWPF.Modules.MseedChart/ViewModels/ChartPlotRealDataViewModel.cs b/StartServerWPF.Modules.MseedChart/ViewModels/ChartPlotRealDataViewModel.cs index 20ff83f..ede4cf8 100644 --- a/StartServerWPF.Modules.MseedChart/ViewModels/ChartPlotRealDataViewModel.cs +++ b/StartServerWPF.Modules.MseedChart/ViewModels/ChartPlotRealDataViewModel.cs @@ -60,6 +60,7 @@ namespace StartServerWPF.Modules.MseedChart.ViewModels // Dictionary cacheChartDic=new Dictionary(); Dictionary subNameList; + bool isSubScribeOK = false; #endregion #region 属性 @@ -475,7 +476,6 @@ namespace StartServerWPF.Modules.MseedChart.ViewModels _lChartAll.EndUpdate(); } } - int i = 1; private void RealTimeData(object isCheck) { _channelCount = smList.Count * 3; @@ -494,6 +494,7 @@ namespace StartServerWPF.Modules.MseedChart.ViewModels { currentOATime = 0; _data = new double[smList.Count * 3][]; + StartChart(); //Set real-time monitoring automatic old data destruction LChartALL.ViewXY.DropOldSeriesData = true; @@ -504,7 +505,7 @@ namespace StartServerWPF.Modules.MseedChart.ViewModels LChartALL.ViewXY.XAxes[0].ScrollMode = XAxisScrollMode.Scrolling; Task.Run(() => { - Thread.Sleep(5000); + Thread.Sleep(3000); time.Start(); }); using (RedisListService service = new RedisListService()) @@ -517,8 +518,13 @@ namespace StartServerWPF.Modules.MseedChart.ViewModels { using (RedisListService service = new RedisListService()) { - Debug.WriteLine($"注册{1}:{subName.Key}"); + Debug.WriteLine($"注册,:{subName.Key},时间:{DateTime.Now}"); { + if(subName.Key== subNameList.Keys.Last()) + { + isSubScribeOK = true; + Debug.WriteLine($"******注册完成********,:{subName.Key},时间:{DateTime.Now}"); + } service.Subscribe(subName.Key, (c, message, iRedisSubscription) => { if(message.Length==7 && System.Text.Encoding.Default.GetString(message)== "shutoff") @@ -589,6 +595,10 @@ namespace StartServerWPF.Modules.MseedChart.ViewModels } Debug.WriteLine($"接收:{asciiData.sid}:{startTime},count:{lines.Count}"); string lineStr = String.Join(",", lines); + if(!isSubScribeOK) + { + return; + } using (RedisListService service = new RedisListService()) { service.LPush(name, lineStr); @@ -677,16 +687,16 @@ namespace StartServerWPF.Modules.MseedChart.ViewModels v.LegendBoxes[0].Shadow.Visible = false; StationModel stationModel = smList.First(); - var beginTime= stationModel.BeginTime; + var beginTime = DateTime.Now;// 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].DateOriginYear = beginTime.Year; + // v.XAxes[0].DateOriginDay = beginTime.Day; + // v.XAxes[0].DateOriginMonth = beginTime.Month; + DateTime MaxDateTime = beginTime.AddSeconds(_samplingFrequency == 500 ? 31 : 61); v.XAxes[0].SetRange(v.XAxes[0].DateTimeToAxisValue(beginTime), v.XAxes[0].DateTimeToAxisValue(MaxDateTime)); } double firstSampleTimeStamp = v.XAxes[0].DateTimeToAxisValue(beginTime); @@ -863,16 +873,21 @@ namespace StartServerWPF.Modules.MseedChart.ViewModels #region 实时数据 private void CompositionTarget_Rendering(object sender, System.Timers.ElapsedEventArgs e) { - RenderNextFrame(); + RenderNextFrame(); + //_dispatcher.Invoke(() => + //{ + //测试数据 + // FeedDataTest(); + //}); } static double currentOATime = 0; - List tempData = new List(); private void RenderNextFrame() { Stopwatch stopwatch = Stopwatch.StartNew(); string minName = string.Empty; - if (_lChartAll == null) + if (_lChartAll == null && !isSubScribeOK) { + Debug.WriteLine("注册未完成,时间:{1}", DateTime.Now); return; } List datasStr = new List(); @@ -926,19 +941,18 @@ namespace StartServerWPF.Modules.MseedChart.ViewModels } else if ((currentTime - firstTime).TotalSeconds < 0) { - _data[item.Value.Index] = new double[datasStr.Count]; + _data[item.Value.Index] = new double[_samplingFrequency]; } else if ((currentTime - firstTime).TotalSeconds > 0) { firstTime.AddMilliseconds(-firstTime.Millisecond); //出更数据需要重新绘图表点 - _data[item.Value.Index] = new double[datasStr.Count]; + _data[item.Value.Index] = new double[_samplingFrequency]; int offset = (int)(currentTime - firstTime).TotalSeconds; while (offset > 0) { service.RemoveStartFromList(item.Key); - tempData.Add(item.Key+ firstTime); - if (offset < 60) + if (offset < 30) { // 不能超过缓存数, 更新数据 var time = currentTime.AddSeconds(-offset); @@ -964,136 +978,186 @@ namespace StartServerWPF.Modules.MseedChart.ViewModels } else { - _data[item.Value.Index] = new double[500]; + _data[item.Value.Index] = new double[_samplingFrequency]; } } item.Value.AddData(currentOATime, _data[item.Value.Index]); } stopwatch.Stop(); double time1 = stopwatch.ElapsedMilliseconds; - stopwatch.Start(); - bool isRefresh = false; + stopwatch.Restart(); //有新数据开始刷新 - if (tempData.Count > 5) + DateTime startTime = DateTime.Today; + foreach (var item in subNameList) { - DateTime startTime = DateTime.Today; - foreach (var item in subNameList) - { - List temDou = new List(); - var number = item.Value.datas.Count; - for (int i = 0; i < number; i++) - { - temDou.AddRange(item.Value.datas[i]); - } - _data[item.Value.Index] = temDou.ToArray(); - if (startTime == DateTime.Today) - { - startTime = DateTime.FromOADate(item.Value.StartOATime).AddSeconds(-item.Value.datas.Count); - } - } - _lChartAll.ViewXY.XAxes[0].SetRange(_lChartAll.ViewXY.XAxes[0].DateTimeToAxisValue(startTime), - _lChartAll.ViewXY.XAxes[0].DateTimeToAxisValue(startTime.AddSeconds(30))); - LChartALL.ViewXY.DropOldSeriesData = true; - _pointsAppended = LChartALL.ViewXY.XAxes[0].Minimum; - - isRefresh = true; - tempData.Clear(); + List temDou = new List(); + item.Value.datas.ForEach(d => temDou.AddRange(d)); + _data[item.Value.Index] = temDou.ToArray(); } + stopwatch.Stop(); + double time2 = stopwatch.ElapsedMilliseconds; + stopwatch.Restart(); _dispatcher.Invoke(() => { - FeedData(isRefresh /*chartTitleText*/); + FeedData(); }); stopwatch.Stop(); - double time2 = stopwatch.ElapsedMilliseconds; - Debug.WriteLine("timeFrame:{0},time1:{1},time1:{2}", DateTime.FromOADate(currentOATime), time1, time2); + double time3 = stopwatch.ElapsedMilliseconds; + Debug.WriteLine("timeFrame:{0},time1:{1},time2:{2},time3:{3}", DateTime.FromOADate(currentOATime), time1, time2,time3); } double _pointsAppended = 0; double[][] _data; - private void FeedData(bool isRefresh) + private void FeedData() { if (_lChartAll == null) return; _lChartAll.BeginUpdate(); - if (isRefresh) + foreach (var item in _lChartAll.ViewXY.SampleDataSeries) { - for (int seriesIndex = 0; seriesIndex < _channelCount; seriesIndex++) - { - _lChartAll.ViewXY.SampleDataSeries[seriesIndex].Clear(); - } - - //foreach (var item in subNameList.Values) - //{ - // startTime = DateTime.FromOADate(item.StartOATime).AddSeconds(item.datas.Count); - // _lChartAll.ViewXY.XAxes[0].SetRange(_lChartAll.ViewXY.XAxes[0].DateTimeToAxisValue(startTime), - // _lChartAll.ViewXY.XAxes[0].DateTimeToAxisValue(startTime.AddSeconds(60))); - // LChartALL.ViewXY.DropOldSeriesData = true; - // _pointsAppended = LChartALL.ViewXY.XAxes[0].Minimum; - // var number = item.datas.Count; - // for (int i = 0; i < number; i++) - // { - // foreach (var d in subNameList) - // { - // double[] thisSeriesData = subNameList[d.Key].datas[i]; - // _lChartAll.ViewXY.SampleDataSeries[d.Value.Index].AddSamples(thisSeriesData, false); - // } - // _pointsAppended += 1; - // //Set X axis real-time scrolling position - // double last = _pointsAppended; - // _lChartAll.ViewXY.XAxes[0].ScrollPosition = last; - // } - // break; - //} + item.Clear(); + item.FirstSampleTimeStamp = _lChartAll.ViewXY.XAxes[0].Minimum; } //Append data to series - for (int seriesIndex = 0; seriesIndex < _channelCount; seriesIndex++) + System.Threading.Tasks.Parallel.For(0, _channelCount, (seriesIndex) => { double[] thisSeriesData = _data[seriesIndex]; + _lChartAll.ViewXY.YAxes[seriesIndex].SetRange(thisSeriesData.Min(), thisSeriesData.Max()+1); _lChartAll.ViewXY.SampleDataSeries[seriesIndex].AddSamples(thisSeriesData, false); - _data[seriesIndex] = null; - // System.Diagnostics.Debug.WriteLine("***********index:{0}, pointCount:{1},time:{2}", seriesIndex, - // _lChartAll.ViewXY.SampleDataSeries[seriesIndex].PointCount, DateTime.Now); - } + // _data[seriesIndex] = null; + System.Diagnostics.Debug.WriteLine("***********index:{0}, pointCount:{1}", seriesIndex, + _lChartAll.ViewXY.SampleDataSeries[seriesIndex].PointCount); + }); _pointsAppended += 1; //Set X axis real-time scrolling position - double lastX = _pointsAppended; + double lastX = _pointsAppended * XInterval; _lChartAll.ViewXY.XAxes[0].ScrollPosition = lastX; + _lChartAll.EndUpdate(); - //Update sweep bands - if (_lChartAll.ViewXY.XAxes[0].ScrollMode == XAxisScrollMode.Sweeping) + } + //Append data point per round count + private int _appendCountPerRound=30000; + //X axis length + private double _xLen; + //Generate this many rounds of data + private const int PreGenerateDataForRoundCount = 10; + //X data point step + private const double XInterval = 1; + //Data feeding round + private int _iRound = 0; + + //Y axis minimum + private const double YMin = 0; + + //Y axis maximum + private const double YMax = 100; + private double[][] CreateInputData(int seriesCount, int appendCountPerRound) + { + //Create input data for all series. + double[][] data = new double[seriesCount][]; + // System.Threading.Tasks.Parallel.For(0, seriesCount, (seriesIndex) => + for (int seriesIndex = 0; seriesIndex < seriesCount; seriesIndex++) { - //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) + int dataPointCount = PreGenerateDataForRoundCount * appendCountPerRound; + double[] seriesData = new double[dataPointCount]; + float seriesIndexPlus1 = seriesIndex + 1; + Random rand = new Random((int)DateTime.Now.Ticks / (seriesIndex + 1)); + + double y = 50; + for (int i = 0; i < dataPointCount; i++) { - _lChartAll.ViewXY.Bands[0].Visible = true; + y = y - 0.05 + rand.NextDouble() / 10.0; + if (y > YMax) + { + y = YMax; + } + + if (y < YMin) + { + y = YMin; + } + + seriesData[i] = (float)y; } + data[seriesIndex] = seriesData; + }//); + return data; + } + private void PrefillChartWithData() + { + /* test + _lChartAll.BeginUpdate(); + _data = CreateInputData(smList.Count * 3, _appendCountPerRound); + LChartALL.ViewXY.DropOldSeriesData = true; + _pointsAppended = LChartALL.ViewXY.XAxes[0].Minimum; + time.Elapsed -= CompositionTarget_Rendering; + time.Elapsed += CompositionTarget_Rendering; + LChartALL.ViewXY.XAxes[0].ScrollMode = XAxisScrollMode.Scrolling; + LChartALL.ViewXY.AxisLayout.AutoShrinkSegmentsGap = true; + _lChartAll.EndUpdate(); + time.Start();*/ + //Set data almost till the end, + //so it will reach end and start scrolling quite soon. - //Bright new page band - _lChartAll.ViewXY.Bands[1].SetValues(lastX - sweepGapWidth / 6, lastX); - if (_lChartAll.ViewXY.Bands[1].Visible == false) + //How many rounds to prefill in the series + int roundsToPrefill = 50;// (int)(0.9 * _xLen) / _appendCountPerRound; + + //How many points to prefill in the series + int pointCount = roundsToPrefill * _appendCountPerRound; + + System.Threading.Tasks.Parallel.For(0, _channelCount, (seriesIndex) => + { + double[] thisSeriesData = _data[seriesIndex]; + + for (int round = 0; round < roundsToPrefill; round++) { - _lChartAll.ViewXY.Bands[1].Visible = true; + float[] dataArray = new float[_appendCountPerRound]; + Array.Copy(thisSeriesData, (round % PreGenerateDataForRoundCount) * _appendCountPerRound, dataArray, 0, _appendCountPerRound); + _lChartAll.ViewXY.SampleDataBlockSeries[seriesIndex].AddSamples(dataArray, false); } - } - else + }); + + _pointsAppended += pointCount; + _iRound += roundsToPrefill; + + //Set X axis real-time scrolling position + double lastX = _pointsAppended * XInterval; + _lChartAll.ViewXY.XAxes[0].ScrollPosition = lastX; + } + private void FeedDataTest(/*string chartTitleText*/) + { + if (_lChartAll != null) { - //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(); + _lChartAll.BeginUpdate(); + foreach (var item in _lChartAll.ViewXY.SampleDataSeries) + { + item.Clear(); + item.FirstSampleTimeStamp = _lChartAll.ViewXY.XAxes[0].Minimum; + + } + //Append data to series + System.Threading.Tasks.Parallel.For(0, _channelCount, (seriesIndex) => + { + double[] thisSeriesData = _data[seriesIndex]; + double[] dataToAppendNow = new double[_appendCountPerRound]; + Array.Copy(thisSeriesData, (_iRound % PreGenerateDataForRoundCount) * _appendCountPerRound, dataToAppendNow, 0, _appendCountPerRound); + _lChartAll.ViewXY.YAxes[seriesIndex].SetRange(dataToAppendNow.Min(), dataToAppendNow.Max()); + _lChartAll.ViewXY.SampleDataSeries[seriesIndex].AddSamples(dataToAppendNow, false); + System.Diagnostics.Debug.WriteLine("***********index:{0}, pointCount:{1}", seriesIndex, + _lChartAll.ViewXY.SampleDataSeries[seriesIndex].PointCount); + }); + _pointsAppended += 1;//;_appendCountPerRound; + + //Set X axis real-time scrolling position + double lastX = _pointsAppended * XInterval; + _lChartAll.ViewXY.XAxes[0].ScrollPosition = lastX; + + _lChartAll.EndUpdate(); + + _iRound++; + } } public void OnNavigatedTo(NavigationContext navigationContext) diff --git a/mseedC/mseedC.vcxproj b/mseedC/mseedC.vcxproj index 3b2a001..ddf03b3 100644 --- a/mseedC/mseedC.vcxproj +++ b/mseedC/mseedC.vcxproj @@ -80,7 +80,7 @@ ..\ConsoleApp\bin\Debug - $(SolutionDir)StartServer\bin\$(IntDir)net6.0-windows + $(SolutionDir)StartServerWPF\bin\$(IntDir)net6.0-windows