using Arction.Wpf.Charting;
using Arction.Wpf.Charting.Axes;
using Arction.Wpf.Charting.SeriesXY;
using Arction.Wpf.Charting.Views.ViewXY;
using Microsoft.Win32;
using mseedChart.Core;
using mseedChart.MainModule.Models;
using Prism.Commands;
using Prism.Events;
using Prism.Mvvm;
using SharpDX.Direct2D1;
using SharpDX.DirectWrite;
using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.ComponentModel.Design.Serialization;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net.Http.Headers;
using System.Reflection;
using System.Security.Cryptography;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
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
{
    public class ChartPlotViewModel : BindableBase
    {

        public ChartPlotViewModel()
        {
            _dispatcher = Application.Current.Dispatcher;
            _wavesModel = new WavesModel();
            CreateChart();
            (Application.Current.MainWindow as System.Windows.Window).Closing += ApplicationClosingDispose;

            string fileName = "2023-03-28T05:14:59.108464";
           // fileName = "2023-03-24T04:53:46.199584";
            bool multFlies = false;
            string eventTimeStr = fileName;
            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 jsonStr = ".json";
            string mseedStr = ".mseed";
            string asciiSavePath = RegionNames.TxtFilePath + "\\" + datePath + "\\";
            if (!multFlies)
            {
                CurrentEventTime = _wavesModel.mseedJsonResolve(dataFilePath + dataFileName + jsonStr);
            }
            ShowWave(dataFilePath + dataFileName + mseedStr, asciiSavePath + dataFileName + ".txt" , multFlies);

            YaxisItems.Add("SHZ");
            YaxisItems.Add("SHN");
            YaxisItems.Add("SHE");
        }

        #region 字段
        Dispatcher _dispatcher;
        public int CurPoints;

        int _channelCount = 0;         
        int _samplingFrequency = 500;  // 采样频率 (Hz).
        WavesModel _wavesModel;
        private int _lChartCount = 1;
        public ConcurrentQueue<StationModel> smList;
        #endregion

        #region 属性

        private List<string> _yaxisItems=new List<string>();

        public List<string> YaxisItems
        {
            get { return _yaxisItems; }
            set { _yaxisItems = value; }
        }

        private int _selectIndex=1;

        public int SelectIndex
        {
            get { return _selectIndex; }
            set
            {
                SetProperty(ref _selectIndex, value);
            }
        }

        private bool _isMultFiles;

        public bool IsMultFiles
        {
            get { return _isMultFiles; }
            set 
            {
                SetProperty(ref _isMultFiles, value);
            }
        }
        private int _xaisInterval;

        public int XaisInterval
        {
            get { return _xaisInterval; }
            set
            {
                SetProperty(ref _xaisInterval, value);
            }
        }
        /// <summary>
        /// 波形控件数量
        /// </summary>
        public int LChartCount
        {
            get { return _lChartCount; }
            set { _lChartCount = value; }
        }
        private LightningChart _lChartAll;
        /// <summary>
        /// 所有波形
        /// </summary>
        public LightningChart LChartALL
        {
            get { return _lChartAll; }
            set { _lChartAll = 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; }
        }
        private StationEventJson _currentEventTime;

        public StationEventJson CurrentEventTime    
        {

            get { return _currentEventTime; }
            set { _currentEventTime = value; }
        }

        private List<string> _stationYaxis;

        public List<string> StationYaxis
        {
            get { return _stationYaxis; }
            set {

                SetProperty(ref _stationYaxis, value);
            }
        }

        private int _selectStationYaxisIndex;

        public int SelectStationYaxisIndex
        {
            get { return _selectStationYaxisIndex; }
            set {

                SetProperty(ref _selectStationYaxisIndex, value);
            }
        }
        private bool _stationYaxisIsChecked;

        public bool StationYaxisIsChecked
        {
            get { return _stationYaxisIsChecked; }
            set {
                StationYaxisVisible(value);
                SetProperty(ref _stationYaxisIsChecked, value);
            }
        }
        #endregion

        #region 事件
        public DelegateCommand<object> AxesYVisibleCommand => new DelegateCommand<object>(AxesYVisible);
        public DelegateCommand FileSelectorCommand => new DelegateCommand(FileSelector);
        public DelegateCommand<object> OtimeSortCommand => new DelegateCommand<object>(OtimeSort);
        public DelegateCommand<object> YasixZENVisibleCommand => new DelegateCommand<object>(YasixZENVisible);
        public DelegateCommand IntervalSureCommand => new DelegateCommand(IntervalSure);

        public DelegateCommand<object> RealTimeDataCommand => new DelegateCommand<object>(RealTimeData);

        private void AxesYVisible(object isCheck)
        {
            if (_lChartAll != null)
            {
                bool yAxesVisible = ((bool)isCheck == true);
                _lChartAll.BeginUpdate();

                AxisY lastYAxis = _lChartAll.ViewXY.YAxes.Last();

                _lChartAll.ViewXY.AxisLayout.AutoAdjustMargins = false;

                foreach (AxisY yAxis in _lChartAll.ViewXY.YAxes)
                {
                    if (yAxis != lastYAxis)
                    {
                        yAxis.Visible = yAxesVisible;
                    }
                    else
                    {
                        yAxis.Visible = true;
                        yAxis.LabelsVisible = yAxesVisible;
                        //yAxis.MajorDivTickStyle.Visible = yAxesVisible;
                        //yAxis.MinorDivTickStyle.Visible = yAxesVisible;
                        yAxis.Title.Visible = yAxesVisible;
                        if (yAxesVisible)
                        {
                            yAxis.AxisThickness = 3;
                        }
                        else
                        {
                            yAxis.AxisThickness = 0;
                        }
                        //  lastYAxis.MiniScale.Visible = !yAxesVisible;
                    }
                }
                _lChartAll.EndUpdate();

            }
        }

        private void FileSelector()
        {
            OpenFileDialog openFileDialog = new OpenFileDialog
            {
                RestoreDirectory = true,
                Filter = ".mseed|*.mseed|.json|*.json|.txt|*.txt",
            };
            if (openFileDialog.ShowDialog() == true)
            {
                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;
                IOrderedEnumerable<LineCollection> lines;
                if (yAxesVisible)
                {
                    lines = v.LineCollections.Where(a => a.Tag != null && a.Tag.ToString().Contains("SHZ")).OrderBy(a => a.Lines[0].AX);
                }
                else
                {
                    lines = v.LineCollections.Where(a => a.Tag != null && a.Tag.ToString().Contains("SHZ")).OrderByDescending(b => b.Lines[0].AX); ;
                }
                foreach (var item in lines)
                {
                    var a = item.Tag.ToString().Contains("SHZ");
                }
                foreach (var item in lines.Reverse())
                {
                    int index = item.AssignYAxisIndex;
                    for (int i = 0; i < 3; i++)
                    {
                        AxisY axisY = v.YAxes[index + i];
                        v.YAxes.RemoveAt(index + i);
                        v.YAxes.Insert(i, axisY);
                    }
                }
                LChartALL.EndUpdate();

            }
        }
        private void YasixZENVisible(object isCheck)
        {
            if (_lChartAll != null)
            {
                _lChartAll.BeginUpdate();
                bool yAxesVisible = ((bool)isCheck == true);
                ViewXY v = _lChartAll.ViewXY;
                List<bool> indexs = new List<bool>();
                switch (SelectIndex)
                {
                    case 0:
                        indexs = v.YAxes.Select(a => a.Title.Text.Contains(".Z")).ToList();
                        break;
                    case 1:
                        indexs = v.YAxes.Select(a => a.Title.Text.Contains(".N")).ToList();
                        break;
                    case 2:
                        indexs = v.YAxes.Select(a => a.Title.Text.Contains(".E")).ToList();
                        break;
                    default:
                        break;
                }
                for (int i = 0; i < indexs.Count; i++)
                {
                    if (indexs[i] == true)
                    {
                        AxisY axisY = v.YAxes[i];
                        axisY.Visible = !yAxesVisible;
                        v.SampleDataSeries[i].Visible = !yAxesVisible;
                        int index = v.LineCollections.FindIndex(a => a.AssignYAxisIndex == i);
                        if (index != -1)
                        {
                            v.LineCollections[index].Visible = !yAxesVisible;
                        }
                    }
                }
                _lChartAll.EndUpdate();
            }
        }

        private void IntervalSure()
        {
            if (_lChartAll != null)
            {
                _lChartAll.BeginUpdate();

                if (XaisInterval >= 2)
                {
                    _lChartAll.ViewXY.XAxes[0].MajorDivCount = XaisInterval;
                }
                _lChartAll.EndUpdate();

            }
        }

        private void StationYaxisVisible(bool visible)
        {
            if (_lChartAll != null)
            {
                _lChartAll.BeginUpdate();
                bool yAxesVisible = ((bool)visible == true);
                ViewXY v = _lChartAll.ViewXY;
                for (int i = 0; i < v.YAxes.Count; i++)
                {
                     AxisY axisY = v.YAxes[i];
                    if (axisY.Title.Text.Contains(StationYaxis[SelectStationYaxisIndex]))
                    {
                        axisY.Visible = !yAxesVisible;
                        v.SampleDataSeries[i].Visible = !yAxesVisible;
                        int index = v.LineCollections.FindIndex(a => a.AssignYAxisIndex == i);
                        if (index != -1)
                        {
                            v.LineCollections[index].Visible = !yAxesVisible;
                        }
                    }
                }

                _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<StationModel> UpdateWavesFromTxt(string fn)
        {
            string allStr;
            List<StationModel> temSM = new List<StationModel>();
            using (StreamReader streamReader = new StreamReader(fn))
            {
                allStr = streamReader.ReadToEnd();
            }
            if (allStr.Length > 0)
            {
                string[] strLines = allStr.Trim().Split(new char[] { '\n' });
                List<string> strList = strLines.ToList();
                int cnt = strList.Count;
                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;

                int channelFlag = 0;

                for (int i = 0; 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);
                        string stationName = rowStr[0].Substring(14, 3);
                        if (!temSM.Any(name => name.Name == stationName))
                        {
                            station = new StationModel();
                            station.Name = stationName;
                            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);
                        }
                        if (chnStr1 == "SHZ")
                        {
                           
                            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;
                        }
                    }
                }
               // temSM.Add(station);
                temSM.Reverse();
            }
            return temSM;
        }
        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.StartInfo.CreateNoWindow = true;
                compiler.Start();
                compiler.WaitForExit();
            }
        }
      
        private void CreateChart()
        {
            if (LChartALL != null)
            {
                LChartALL = null;
            }
            LChartALL = new LightningChart();
            LChartALL.Title.Align = ChartTitleAlignment.TopCenter;
            LChartALL.ChartRenderOptions.DeviceType = RendererDeviceType.AutoPreferD11;
            LChartALL.ChartRenderOptions.LineAAType2D = LineAntiAliasingType.QLAA;

            LChartALL.Title.Text = "事件波形";
            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.AxisLayout.YAxisAutoPlacement = YAxisAutoPlacement.AllLeft;
            LChartALL.ViewXY.AxisLayout.YAxisTitleAutoPlacement = true;
            LChartALL.ViewXY.AxisLayout.AutoAdjustMargins = false;

            LChartALL.ViewXY.ZoomPanOptions.DevicePrimaryButtonAction = UserInteractiveDeviceButtonAction.None;
            LChartALL.ViewXY.ZoomPanOptions.DeviceSecondaryButtonAction = UserInteractiveDeviceButtonAction.None;
            LChartALL.ViewXY.ZoomPanOptions.WheelZooming = WheelZooming.Off;
            // 反锯齿系数。值0和1都不会应用反锯齿
            LChartALL.ChartRenderOptions.AntiAliasLevel = 0;
            //X轴设置
            LChartALL.ViewXY.XAxes[0].AllowScrolling = false;
            LChartALL.ViewXY.XAxes[0].PanningEnabled = false;
            LChartALL.ViewXY.XAxes[0].MajorGrid.Pattern = LinePattern.Solid;
            LChartALL.ViewXY.XAxes[0].ValueType = AxisValueType.DateTime;
            LChartALL.ViewXY.XAxes[0].KeepDivCountOnRangeChange = true;
            //LChartALL.ViewXY.XAxes[0].MajorDiv =6;
            LChartALL.ViewXY.XAxes[0].LabelsColor = Colors.Black;
            LChartALL.ViewXY.XAxes[0].AutoDivSpacing = false;
            LChartALL.ViewXY.XAxes[0].MajorDivCount = 5;
            XaisInterval = 5;

            //图表背景颜色
            LChartALL.ViewXY.GraphBackground.Color = Colors.White;
            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;
        }
        private void ShowWave(string dataFilePath, string asciiSavePath, bool isMultFile = false)
        {
            if (!Directory.Exists(Path.GetDirectoryName(dataFilePath)))
            {
                Directory.CreateDirectory(Path.GetDirectoryName(dataFilePath));
            }
            if (!Directory.Exists(Path.GetDirectoryName(asciiSavePath)))
            {
                Directory.CreateDirectory(Path.GetDirectoryName(asciiSavePath));
            }
            smList = new ConcurrentQueue<StationModel>();
            if (isMultFile)
            {
                var filePath = new DirectoryInfo(Path.GetDirectoryName(dataFilePath));
                FileInfo[] files = filePath.GetFiles();
                var mseedFiles = files.Where(i => i.Extension == ".mseed");

                var asciiFiles = new DirectoryInfo(Path.GetDirectoryName(asciiSavePath));
                var asciifile = asciiFiles.GetFiles();
                if (asciifile.Count() == 0)
                {
                    // 并行运算
                    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);
                }
                // 并行运算
                Parallel.ForEach(asciiFiles.GetFiles(), (item) =>
                {
                    var list = UpdateWavesFromTxt(item.FullName);
                    list.ForEach(i => smList.Enqueue(i));
                });
            }
            else
            {
                if (!File.Exists(asciiSavePath))
                {
                    MSeed2Asc(dataFilePath, asciiSavePath);
                }
                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;
            DisposeAllAndClear(v.YAxes);
            DisposeAllAndClear(v.SampleDataSeries);
            DisposeAllAndClear(v.LineCollections);

            v.YAxes.AddRange(_wavesModel.CreateYAxisChart(smList.ToList(), LChartALL));
            v.LegendBoxes[0].Position = LegendBoxPositionXY.RightCenter;
            v.LegendBoxes[0].Offset.SetValues(-10, 180);
            v.LegendBoxes[0].Layout = LegendBoxLayout.Vertical;
            v.LegendBoxes[0].Visible = false;
            v.AutoSpaceLegendBoxes = true;
            v.AxisLayout.SegmentsGap = 3;
            v.LegendBoxes[0].Shadow.Visible = false;

            StationModel stationModel = smList.ElementAt(0);
            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 = CurrentEventTime.otime.Year;
                v.XAxes[0].DateOriginDay = CurrentEventTime.otime.Day;
                v.XAxes[0].DateOriginMonth = CurrentEventTime.otime.Month;

                DateTime MaxDateTime = CurrentEventTime.otime.AddSeconds(_samplingFrequency == 500 ? 30 : 60);
                v.XAxes[0].SetRange(v.XAxes[0].DateTimeToAxisValue(CurrentEventTime.otime), v.XAxes[0].DateTimeToAxisValue(MaxDateTime));
            }

            double firstSampleTimeStamp = v.XAxes[0].DateTimeToAxisValue(CurrentEventTime.otime);
            for (int i = 0; i < smList.Count; i++)
            {
                for (int k = 0; k < smList.ElementAt(i).Dzne.Count; k++)
                {
                    int seriesIndex = i * 3 + k;
                    AxisY axisY = v.YAxes[seriesIndex];
                    axisY.LabelsColor = Colors.Black;
                    axisY.Title.Shadow.DropColor = Colors.Transparent;
                    axisY.Title.Shadow.ContrastColor = Colors.Transparent;
                    axisY.AllowAutoYFit = false;
                    axisY.Units.Visible = false;
                    axisY.LabelsAngle = 0;
                    axisY.LabelsFont.Size = 8;
                    axisY.Title.Angle = 0;
                    axisY.MajorGrid.Visible = true;
                    axisY.MinorGrid.Visible = false;
                    axisY.MajorGrid.Pattern = LinePattern.Solid;
                    axisY.AutoDivSpacing = false;
                    //  axisY.AutoDivSeparationPercent = 100;
                    axisY.Visible = true;
                    axisY.MajorDivCount = 2;
                    axisY.MajorDivTickStyle.Visible = true;
                    axisY.MinorDivTickStyle.Visible = false;
                    axisY.MajorDivTickStyle.Alignment = seriesIndex % 2 == 0 ? Alignment.Near : Alignment.Far;
                    axisY.MajorDivTickStyle.LineLength = 6;
                    axisY.MajorDivTickStyle.Color = Colors.Black;
                    axisY.Title.Color = Colors.Black;
                    axisY.Title.Font = new WpfFont("Segoe UI", 10, false, false);
                    axisY.PanningEnabled = false;
                    axisY.AllowScrolling = false;
                    axisY.AllowScaling = false;

                    SampleDataSeries series = new SampleDataSeries(v, v.XAxes[0], axisY);
                    series.ShowInLegendBox = true;
                    series.FirstSampleTimeStamp = firstSampleTimeStamp;
                    series.SamplingFrequency = _samplingFrequency;
                    series.Title.Text = axisY.Title.Text;
                    series.SampleFormat = SampleFormat.DoubleFloat;
                    if (k % 3 == 0)
                    {
                        series.LineStyle.Color = System.Windows.Media.Colors.Blue;
                    }
                    else if (k % 3 == 1)
                    {
                        series.LineStyle.Color = System.Windows.Media.Colors.Red;
                    }
                    else if (k % 3 == 2)
                    {
                        series.LineStyle.Color = System.Windows.Media.Colors.Green;
                    }
                    series.LineStyle.Width = 0.5;
                    series.LineStyle.AntiAliasing = LineAntialias.None;
                    series.ScrollModePointsKeepLevel = 1;
                    series.ScrollingStabilizing = true;
                    series.AllowUserInteraction = false;
                    v.SampleDataSeries.Add(series);
                }
            }
        }
        private void UpdateChartData()
        {
            double[][] multiChannelData = new double[smList.Count * 3][];
            try
            {
                for (int channelIndex = 0; channelIndex < smList.Count; channelIndex++)
                {
                    multiChannelData[channelIndex * 3] = smList.ElementAt(channelIndex).dz.ToArray();
                    multiChannelData[channelIndex * 3 + 1] = smList.ElementAt(channelIndex).dn.ToArray();
                    multiChannelData[channelIndex * 3 + 2] = smList.ElementAt(channelIndex).de.ToArray();
                }
                _data = multiChannelData;
                // Invoke FeedNewDataToChart.
                _dispatcher.Invoke(() =>
                {
                    FeedNewDataToChar(multiChannelData);
                });
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        private void ApplicationClosingDispose(object sender, CancelEventArgs e)
        {
            if (LChartALL != null)
            {
                LChartALL.Dispose();
                LChartALL = null;
            }
        }

        private void DisposeAllAndClear<T>(List<T> list) where T : IDisposable
        {
            if (list == null)
            {
                return;
            }

            while (list.Count > 0)
            {
                int lastInd = list.Count - 1;
                T item = list[lastInd]; // take item ref from list. 
                list.RemoveAt(lastInd); // remove item first
                if (item != null)
                {
                    (item as IDisposable).Dispose();     // then dispose it. 
                }
            }
        }
        public void Dispose()
        {
            gridChart.Children.Clear();

            if (LChartALL != null)
            {
                LChartALL.Dispose();
                LChartALL = null;
            }
        }

        private void FeedNewDataToChar(double[][] data)
        {
            LChartALL.BeginUpdate();
            _wavesModel.CreateAxisYEventTime(CurrentEventTime, LChartALL.ViewXY, smList.ToList());
            for (int channelIndex = 0; channelIndex < _channelCount; channelIndex++)
            {
                LChartALL.ViewXY.SampleDataSeries[channelIndex].AddSamples(data[channelIndex], true);
            }
            LChartALL.EndUpdate();

        }


        #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
    }
}
