using System; using System.Collections.Generic; using System.Linq; using System.Text; using Aitex.UI.Charting.ViewModel; using System.Collections.ObjectModel; using Aitex.UI.Charting.Command; using System.Windows; using System.Windows.Input; using System.Windows.Threading; using Aitex.UI.Charting.View; using DataAnalysisControl.Core; using Aitex.UI.Charting.Model; namespace Aitex.UI.Charting.ViewModel { public class TabStatisticViewModel : ChartingBaseViewModel { public TabStatisticViewModel() { StatisticDataList = new ObservableCollection(); StatisticDataBeginTime = DateTime.MinValue.ToString("yyyy/MM/dd HH:mm:ss"); StatisticDataEndTime = DateTime.MinValue.ToString("yyyy/MM/dd HH:mm:ss"); StatisticDataTimeSpan = "00:00:00"; Export2File = new ChartingCommand((o) => true, (o) => Export2CsvFile(o)); //初始化静态定时器 _timer.Interval = new TimeSpan(0, 0, 1); _timer.Tick += new EventHandler(_timer_Tick); } public void Start() { PlotViewModel.ShowVerticalTimeLines(true); DoDataStatistic(); _timer.Start(); } public void Stop() { _timer.Stop(); } /// /// 定时检查时间轴是否修改 /// 如果检查到时间轴被修改,则更新统计数据并刷新界面 /// /// /// void _timer_Tick(object sender, EventArgs e) { try { if ((PlotViewModel.PlotView.toggleVerticalLine.IsChecked.HasValue && PlotViewModel.PlotView.toggleVerticalLine.IsChecked.Value) && (_timer1 != CommonViewModel.Instance.Time1 || _timer2 != CommonViewModel.Instance.Time2)) { _timer1 = CommonViewModel.Instance.Time1; _timer2 = CommonViewModel.Instance.Time2; DoDataStatistic(); } } catch (Exception ex) { CONTEXT.WriteLog(ex); } } /// /// 用于定时检查时间轴是否已经被修改,如果修改计算新的统计值并更新界面 /// 此处之所以借助定时器实现,而非通过时间轴的位置移动事件触发计算的原因是: /// sciChart控件的VerticalAnnotationLine控制的事件响应似乎不能正常工作 /// private DispatcherTimer _timer = new DispatcherTimer(); private DateTime _timer1 = DateTime.MinValue; private DateTime _timer2 = DateTime.MaxValue; //private static TabStatisticViewModel Instance { get; set; } /// /// 数据导出至CSV文件 /// /// private void Export2CsvFile(object obj) { try { var dlg = new Microsoft.Win32.SaveFileDialog(); dlg.FileName = "数据统计"; dlg.DefaultExt = ".csv"; // Default file extension dlg.Filter = "Excel (.csv)|*.csv"; // Filter files by extension // Show open file dialog box Nullable result = dlg.ShowDialog(); if (result.HasValue && result.Value) { using (System.IO.StreamWriter fs = new System.IO.StreamWriter(dlg.FileName, false, Encoding.UTF8)) { fs.Write("【数据源名称】,【变量名】,【用户定义名称】,【总数量】,【最小值】,【最大值】,【平均值】,【方差】"); fs.WriteLine(); foreach (var item in StatisticDataList) { fs.Write(item.SourceName); fs.Write(","); fs.Write(item.DataName); fs.Write(","); fs.Write(item.UserDefinedName); fs.Write(","); fs.Write(item.TotalNum); fs.Write(","); fs.Write(item.Min); fs.Write(","); fs.Write(item.Max); fs.Write(","); fs.Write(item.Average); fs.Write(","); fs.Write(item.Deviation); fs.Write("\n"); } fs.Close(); } } } catch (Exception ex) { CONTEXT.WriteLog(ex); MessageBox.Show("数据导出失败:\n" + ex.Message, "数据导出", MessageBoxButton.OK, MessageBoxImage.Warning); } } /// /// 数学统计计算 /// private void DoDataStatistic() { if (PlotViewModel.PlotView.vertical_Line1.X1 == null || PlotViewModel.PlotView.vertical_Line2.X1 == null) return; //defaut show the vertical lines System.Diagnostics.Debug.WriteLine("Calc Statistic Data"); StatisticDataList.Clear(); StatisticDataBeginTime = DateTime.MinValue.ToString("yyyy/MM/dd HH:mm:ss"); StatisticDataEndTime = DateTime.MinValue.ToString("yyyy/MM/dd HH:mm:ss"); StatisticDataTimeSpan = "00:00:00"; var commonViewModel = CommonViewModel.Instance; var minT1 = PlotViewModel.PlotView.vertical_Line1.X1 == null ? DateTime.Now : (DateTime)PlotViewModel.PlotView.vertical_Line1.X1; var maxT1 = PlotViewModel.PlotView.vertical_Line2.X1 == null ? DateTime.Now : (DateTime)PlotViewModel.PlotView.vertical_Line2.X1; if (minT1 >= maxT1) { var temp = minT1; minT1 = maxT1; maxT1 = temp; } foreach (MyLineSeries series in commonViewModel.RenderableSeries) { if (series == null || !series.IsVisible || series.DataSource == null) continue; var minT = minT1 - series.DataSource.TimeMove; var maxT = maxT1 - series.DataSource.TimeMove; double factor = series.Factor; double offset = series.Offset; DataItem datas = series.Points; //do statistic calculation here List tempList = new List(); tempList.Clear(); double min = double.MaxValue; double max = double.MinValue; double sum = 0; double ave = 0; double dev = 0; int totalNum = 0; DateTime curX = DateTime.MinValue; double curY = 0; if (factor == 0) factor = 1; for (int i = 0; i < datas.RawData.Count; i++) { curX = datas.TimeStamp[i]; curY = datas.RawData[i]; if (curX > minT && curX < maxT) { if (curY < min) min = curY; if (curY > max) max = curY; sum += curY; totalNum++; tempList.Add(curY); } } if (totalNum > 0) { ave = sum / totalNum; for (int i = 0; i < tempList.Count; i++) { var temp1 = tempList[i] - ave; dev += temp1 * temp1; } dev = dev / totalNum; } if (min == double.MaxValue) min = 0; if (max == double.MinValue) max = 0; StatisticDataList.Add(new ChartingDataStatisticResult() { SourceName = series.DataSourceName, DataName = series.SeriesDisplayName,//.SeriesName, UserDefinedName = series.DisplayName, Average = Math.Round(ave, 3), Deviation = Math.Round(dev, 3), Max = Math.Round(max, 3), Min = Math.Round(min, 3), TotalNum = totalNum }); } StatisticDataBeginTime = minT1.ToString("yyyy/MM/dd HH:mm:ss"); StatisticDataEndTime = maxT1.ToString("yyyy/MM/dd HH:mm:ss"); var tSpan = maxT1 - minT1; StatisticDataTimeSpan = string.Format("{0}小时{1}分{2}秒", ((int)tSpan.TotalHours).ToString("00"), tSpan.Minutes, tSpan.Seconds); InvokePropertyChanged("StatisticDataBeginTime"); InvokePropertyChanged("StatisticDataEndTime"); InvokePropertyChanged("StatisticDataTimeSpan"); InvokePropertyChanged("StatisticDataList"); } //public ICommand DoDataStatistic { get; set; } public ICommand Export2File { get; set; } public ObservableCollection StatisticDataList { get; set; } public string StatisticDataBeginTime { get; set; } public string StatisticDataEndTime { get; set; } public string StatisticDataTimeSpan { get; set; } /// /// Charting中变量的统计值 /// public class ChartingDataStatisticResult { public string SourceName { get; set; } public string DataName { get; set; } public string UserDefinedName { get; set; } public double Average { get; set; } public double Min { get; set; } public double Max { get; set; } public double Deviation { get; set; } public double TotalNum { get; set; } public string UniqueName { get; set; } } } }