using Arction.Wpf.ChartingMVVM; using Arction.Wpf.ChartingMVVM.Axes; using Arction.Wpf.ChartingMVVM.Views.ViewXY; using mseedChart.Core; using mseedChart.MainModule.Models; using Prism.Events; using Prism.Mvvm; using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.ComponentModel; using System.Diagnostics; using System.IO; using System.Linq; using System.Threading; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Media; using System.Windows.Threading; namespace mseedChart.MainModule.ViewModels { public class ChartPlotViewModel : BindableBase { #region variable Dispatcher _dispatcher; /// /// Delegate for data generation. /// /// /// 当前采样数 /// public int CurPoints; private readonly IEventAggregator _ea; private int _selectResult = 0; public int SelectResult { get { return _selectResult; } set { SetProperty(ref _selectResult, value); } } int _channelCount = 60; // Channel count. double _samplingFrequency = 500; // Sampling frequency (Hz). double _xLength = 10; // X axis length. double _previousX = 0; // Latest X value on axis. long _now; // Latest time stamp. long _startTicks; // Controls timing. long _samplesOutput; // Generated samples quantity. // Constants const double YMin = 30000; // Minimal y-value. const double YMax = 33000; // Maximal y-value. WavesModel _wavesModel; #endregion /// /// Thread. /// private delegate void ChartUpdateFromThreadHandler(double[][] samples); private ChartUpdateFromThreadHandler _chartUpdate; private Random _rand = new Random((int)DateTime.Now.Ticks); #region "属性" private int _lChartCount = 1; /// /// 波形控件数量 /// public int LChartCount { get { return _lChartCount; } set { _lChartCount = value; } } public List WaveComList { get; set; } private ShareProperty _wavesCombination; /// /// 波形组合 /// public ShareProperty WavesCombination { get { return _wavesCombination; } set { _wavesCombination = value; SetWavesCombination(); } } private DataSourcesEnum _dataSources; /// /// 数据来源 /// public DataSourcesEnum DataSources { get { return _dataSources; } set { _dataSources = value; } } private DataTypeEnum _wavesType; /// /// 波形类型 /// public DataTypeEnum WavesType { get { return _wavesType; } set { _wavesType = value; } } private DisplayModeEnum _displayMode; /// /// 显示模式 /// public DisplayModeEnum DisplayMode { get { return _displayMode; } set { _displayMode = value; } } private ScollModeEnum _scollMode; /// /// 滚动方式 /// public ScollModeEnum ScollMode { get { return _scollMode; } set { _scollMode = value; } } private DateTime _startTime; /// /// 开始时间 /// public DateTime StartTime { get { return _startTime; } set { _startTime = value; } } private DateTime _endTime; /// /// 开始时间 /// public DateTime EndTime { get { return _endTime; } set { _endTime = value; } } private int _sampling = 500; /// /// 采样频率 /// public int Sampling { get { return _sampling; } set { _sampling = value; } } /// /// 延时(min) /// public int DelayMin { get; set; } = 10; /// /// 文件数据位置 /// public string FileDataPath { get; set; } = @"D:\TaySystemPath\Downloads"; private string _cachePath; private int _cacheSize; /// /// 缓存大小 /// public int CacheSize { get { return _cacheSize; } set { _cacheSize = value; } } private ObservableCollection _stationList; /// /// 台站列表 /// public ObservableCollection StationList { get { return _stationList; } set { _stationList = value; } } private LightningChart _lChartAll; /// /// 所有波形 /// public LightningChart LChartALL { get { return _lChartAll; } set { _lChartAll = value; } } private LightningChart _lChartZ; /// /// Z通道波形 /// public LightningChart LChartZ { get { return _lChartZ; } set { _lChartZ = value; } } private LightningChart _lChartE; /// /// E通道波形 /// public LightningChart LChartE { get { return _lChartE; } set { _lChartE = value; } } private LightningChart _lChartN; /// /// N通道波形 /// public LightningChart LChartN { get { return _lChartN; } set { _lChartN = 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; } } public List smList; #endregion public ChartPlotViewModel() { _dispatcher = Application.Current.Dispatcher; SelectResult = 10; var wcList = (WavesCombinationEnum[])Enum.GetValues(typeof(WavesCombinationEnum)); WaveComList = wcList.Select(value => new ShareProperty((int)value, value.ToString())).ToList(); WavesCombination = WaveComList.SingleOrDefault(wc => wc.ID == 0); _chartUpdate = new ChartUpdateFromThreadHandler(FeedNewDataToChartPingPu); _wavesModel = new WavesModel(); LChartALL.ViewXY.XAxes = new AxisXCollection(); LChartALL.ViewXY.XAxes.Add(_wavesModel.GetAxisX(10)); InitData(); (Application.Current.MainWindow as System.Windows.Window).Closing += ApplicationClosingDispose; ShowWave(); } private void ShowWave(string obj= "2023-03-29T06:41:21.348") { string EventTimeStr = obj; string datePath = EventTimeStr.Substring(0, 4) + EventTimeStr.Substring(5, 2) + EventTimeStr.Substring(8, 2); string dataFilePath = RegionNames.MseedFilePath + "\\" + datePath + "\\"; string dataFileName = "HA." + EventTimeStr.Substring(0, 4) + EventTimeStr.Substring(5, 2) + EventTimeStr.Substring(8, 2) + EventTimeStr.Substring(10, 3) + EventTimeStr.Substring(14, 2) + EventTimeStr.Substring(17, 2) + ".01" + RegionNames.DataTypeString; string mseedStr = ".mseed"; string asciiSavePath = RegionNames.TxtFilePath + "\\" + datePath + "\\" + dataFileName + ".txt"; if (!Directory.Exists(dataFilePath)) { Directory.CreateDirectory(dataFilePath); } if (!Directory.Exists(Path.GetDirectoryName(asciiSavePath))) { Directory.CreateDirectory(Path.GetDirectoryName(asciiSavePath)); } if (!File.Exists(dataFilePath + dataFileName + mseedStr)) { //TaskData taskData = new TaskData(); //taskData.EventTimeStr = EventTimeStr; //taskData.Tasks = new Task(() => //{ // int res = new DownloadWavedata().Download(EventTimeStr, dataFilePath, dataFileName + mseedStr, GlobalConfig.UseWaveDataTable); // if (res > -1) // { // MSeed2Asc(dataFilePath + dataFileName + mseedStr, asciiSavePath); // } // //Console.WriteLine(taskData.IsComplete); //}); //taskData.CallBack = (string res) => //{ // _dispatcher.Invoke(() => // { // UpdateWavesFromTxt(asciiSavePath); // _channelCount = smList.Count * 3; // UpdateChart(); // UpdateChartData(); // }); //}; //TaskQueue.Instance.AddTaskAndRuning(taskData); } else { if (!File.Exists(asciiSavePath)) { MSeed2Asc(dataFilePath + dataFileName + mseedStr, asciiSavePath); } _dispatcher.Invoke(() => { UpdateWavesFromTxt(asciiSavePath); _channelCount = smList.Count * 3; UpdateChart(); UpdateChartData(); }); } } private void UpdateChart() { //线程问题 LChartALL.ViewXY.YAxes = new AxisYCollection(); LChartALL.ViewXY.YAxes.Clear(); LChartALL.ViewXY.YAxes.AddRange(_wavesModel.CreateYAxisPingPu(smList, LChartALL)); for (int i = 0; i < LChartALL.ViewXY.YAxes.Count; i++) { LChartALL.ViewXY.YAxes[i].LabelsColor = Colors.Black; LChartALL.ViewXY.YAxes[i].AxisColor = Colors.Black; LChartALL.ViewXY.YAxes[i].GridStripColor = Colors.Black; LChartALL.ViewXY.YAxes[i].Title.Color = Colors.Black; LChartALL.ViewXY.YAxes[i].Title.Shadow.DropColor = Colors.Transparent; LChartALL.ViewXY.YAxes[i].Title.Shadow.ContrastColor = Colors.Transparent; } LChartALL.ViewXY.XAxes = new AxisXCollection(); LChartALL.ViewXY.XAxes.Add(_wavesModel.GetAxisX(CurPoints / Sampling)); LChartALL.ViewXY.XAxes[0].LabelsColor = Colors.Black; LChartALL.ViewXY.SampleDataSeries = new SampleDataSeriesCollection(); LChartALL.ViewXY.SampleDataSeries.AddRange( _wavesModel.GetSampleDataSeriesPingPu(smList, LChartALL, LChartALL.ViewXY.XAxes[0], LChartALL.ViewXY.YAxes, _samplingFrequency)); } private void UpdateChartData() { double[][] multiChannelData = new double[smList.Count * 3][]; try { for (int channelIndex = 0; channelIndex < smList.Count; channelIndex++) { multiChannelData[channelIndex * 3] = smList[channelIndex].dz.ToArray(); multiChannelData[channelIndex * 3 + 1] = smList[channelIndex].dn.ToArray(); multiChannelData[channelIndex * 3 + 2] = smList[channelIndex].de.ToArray(); } // Invoke FeedNewDataToChart. _dispatcher.Invoke(_chartUpdate, System.Windows.Threading.DispatcherPriority.ContextIdle, multiChannelData as object); } catch (Exception ex) { throw ex; } } public void UpdateWavesFromTxt(string fn) { string allStr; smList = 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; int num = 0; string[] snStr = strLines[0].Trim().Split(','); string tmpName = snStr[0].Substring(14, 3); CurPoints = int.Parse(snStr[1].Trim().Split(' ')[0]); StationModel station = new StationModel(); station.Name = tmpName; station.dz = new List(); station.dn = new List(); station.de = new List(); int channelFlag = 0; for (int i = 1; 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); if (chnStr1 == "SHZ") { smList.Add(station); station = new StationModel(); station.Name = rowStr[0].Substring(14, 3); channelFlag = 0;//Z } else if (chnStr1 == "SHN") { channelFlag = 1;//N } else { channelFlag = 2;//E } } 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; } } } smList.Add(station); smList.Reverse(); } } 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.Start(); compiler.WaitForExit(); } } private void ApplicationClosingDispose(object sender, CancelEventArgs e) { if (LChartALL != null) { LChartALL.Dispose(); LChartALL = null; } } public void Dispose() { gridChart.Children.Clear(); if (LChartALL != null) { LChartALL.Dispose(); LChartALL = null; } } public void SetWavesCombination() { switch (WavesCombination.Name) { case "平铺": LChartCount = 1; CreateGridChartPingPu(); break; case "叠加": LChartCount = 1; CreateGridChartDieJia(); break; case "分类": LChartCount = 3; CreateGridChartFenLei(); break; } } public void CreateGridChartPingPu() { if (LChartALL != null) { LChartALL = null; } LChartALL = new LightningChart(); LChartALL.Title.Text = "事件波形"; LChartALL.Title.Color = Colors.Black; LChartALL.Title.Shadow.DropColor = Colors.Transparent; LChartALL.Title.Shadow.ContrastColor = Colors.Transparent; 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.GraphBackground.Color = Colors.White; LChartALL.ViewXY.GraphBackground.GradientFill = GradientFill.Solid; 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; } public void CreateGridChartDieJia() { if (LChartALL != null) { LChartALL = null; } LChartALL = new LightningChart(); LChartALL.Title.Text = "叠加"; GridChart = new Grid(); GridChart.ColumnDefinitions.Add(new ColumnDefinition()); GridChart.Name = "chartGrid"; GridChart.Children.Add(LChartALL); this.ChildContent = GridChart; } public void CreateGridChartFenLei() { LChartZ = new LightningChart(); LChartALL.Title.Text = "Z"; LChartZ.SetValue(Grid.ColumnProperty, 0); LChartE = new LightningChart(); LChartALL.Title.Text = "E"; LChartE.SetValue(Grid.ColumnProperty, 1); LChartN = new LightningChart(); LChartALL.Title.Text = "N"; LChartN.SetValue(Grid.ColumnProperty, 2); GridChart = new Grid(); GridChart.ColumnDefinitions.Add(new ColumnDefinition()); GridChart.ColumnDefinitions.Add(new ColumnDefinition()); GridChart.ColumnDefinitions.Add(new ColumnDefinition()); GridChart.Name = "chartGrid"; GridChart.Children.Add(LChartZ); GridChart.Children.Add(LChartE); GridChart.Children.Add(LChartN); this.ChildContent = GridChart; } private void InitData() { LChartALL.ViewXY.YAxes = new AxisYCollection(); LChartALL.ViewXY.YAxes.Clear(); RegionNames.StationDic= RegionNames.CreateStationFromCSV(AppDomain.CurrentDomain.BaseDirectory + @"resources/N3102_staion_20230312.txt"); LChartALL.ViewXY.YAxes.AddRange(_wavesModel.CreateYAxisPingPu(RegionNames.StationDic, LChartALL)); for (int i = 0; i < LChartALL.ViewXY.YAxes.Count; i++) { LChartALL.ViewXY.YAxes[i].LabelsColor = Colors.Black; LChartALL.ViewXY.YAxes[i].AxisColor = Colors.Black; LChartALL.ViewXY.YAxes[i].GridStripColor = Colors.Black; LChartALL.ViewXY.YAxes[i].Title.Color = Colors.Black; LChartALL.ViewXY.YAxes[i].Title.Shadow.DropColor = Colors.Transparent; LChartALL.ViewXY.YAxes[i].Title.Shadow.ContrastColor = Colors.Transparent; LChartALL.ViewXY.YAxes[i].Title.Font = new WpfFont("Calibri", 12); } LChartALL.ViewXY.XAxes = new AxisXCollection(); LChartALL.ViewXY.XAxes.Add(_wavesModel.GetAxisX(CurPoints / Sampling)); LChartALL.ViewXY.XAxes[0].LabelsColor = Colors.Black; LChartALL.ViewXY.SampleDataSeries = new SampleDataSeriesCollection(); LChartALL.ViewXY.SampleDataSeries.AddRange( _wavesModel.GetSampleDataSeriesPingPu(RegionNames.StationDic, LChartALL, LChartALL.ViewXY.XAxes[0], LChartALL.ViewXY.YAxes, _samplingFrequency)); //string mseedPath = FileDataPath + "\\" + StartTime.Year.ToString("D2"); //Console.WriteLine(mseedPath); //Start(); } private void FeedNewDataToChartPingPu(double[][] data) { LChartALL.BeginUpdate(); for (int channelIndex = 0; channelIndex < _channelCount; channelIndex++) { LChartALL.ViewXY.SampleDataSeries[channelIndex].AddSamples(data[channelIndex], true); //LChartALL.ViewXY.YAxes[channelIndex].Minimum = data[channelIndex].Min(); //LChartALL.ViewXY.YAxes[channelIndex].Maximum = data[channelIndex].Max(); } _previousX = (double)_samplesOutput / _samplingFrequency; LChartALL.ViewXY.XAxes[0].ScrollPosition = _previousX; LChartALL.EndUpdate(); } } /// /// 波形组合 /// public enum WavesCombinationEnum { 平铺 = 0, 叠加, 分类 } /// /// 波形类型 /// public enum DataTypeEnum { 原始数据 = 0, 事件数据 } /// /// 数据来源 /// public enum DataSourcesEnum { 文件 = 0, 数据库 } /// /// 显示模式 /// public enum DisplayModeEnum { 自动 = 0, 手动 } public enum ScollModeEnum { Scrolling = 0, Stepping } }