添加实时数据功能

master
mzhifa 1 year ago
parent b159dcad47
commit 1fcae94da6

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

@ -27,6 +27,7 @@
<TextBlock VerticalAlignment="Center">X轴时间间隔:</TextBlock> <TextBlock VerticalAlignment="Center">X轴时间间隔:</TextBlock>
<TextBox Text="{Binding XaisInterval}" Width="80" VerticalAlignment="Center"></TextBox> <TextBox Text="{Binding XaisInterval}" Width="80" VerticalAlignment="Center"></TextBox>
<Button Grid.Column="1" Grid.Row="1" Command="{Binding IntervalSureCommand}" Margin="20,0,50,0" Background="#FF66B1FF" HorizontalAlignment="Right" Width="60">OK</Button> <Button Grid.Column="1" Grid.Row="1" Command="{Binding IntervalSureCommand}" Margin="20,0,50,0" Background="#FF66B1FF" HorizontalAlignment="Right" Width="60">OK</Button>
<CheckBox Command="{Binding RealTimeDataCommand}" CommandParameter="{Binding RelativeSource={RelativeSource Mode=Self},Path=IsChecked}" Content="实时数据" VerticalContentAlignment="Center" FontSize="15" Foreground="Black" FontWeight="Bold" DockPanel.Dock="Right"></CheckBox>
<CheckBox IsChecked="{Binding IsMultFiles}" Content="MultFiles" VerticalContentAlignment="Center" FontSize="15" Foreground="Black" FontWeight="Bold" DockPanel.Dock="Right"></CheckBox> <CheckBox IsChecked="{Binding IsMultFiles}" Content="MultFiles" VerticalContentAlignment="Center" FontSize="15" Foreground="Black" FontWeight="Bold" DockPanel.Dock="Right"></CheckBox>
<Button Grid.Column="1" Grid.Row="1" Command="{Binding FileSelectorCommand}" Margin="0,0,50,0" Background="#FF66B1FF" HorizontalAlignment="Right" Width="60">Open</Button> <Button Grid.Column="1" Grid.Row="1" Command="{Binding FileSelectorCommand}" Margin="0,0,50,0" Background="#FF66B1FF" HorizontalAlignment="Right" Width="60">Open</Button>
</DockPanel> </DockPanel>

Loading…
Cancel
Save