using LiveCharts;
using LiveCharts.Configurations;
using LiveCharts.Defaults;
using LiveCharts.Wpf;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.Windows.Threading;

namespace WpfApp1
{
    /// <summary>
    /// Window1.xaml 的交互逻辑
    /// </summary>
    public partial class Column2Example : Window
    {
        Column2ExampleViewModel viewModel;
        public Column2Example()
        {
            InitializeComponent();
            viewModel = new Column2ExampleViewModel();
            viewModel.Init();
            this.DataContext = viewModel;
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            if (viewModel.IsRunning)
                viewModel.Stop();
            else
                viewModel.Start();
        }

        private void ButtonGC_Click(object sender, RoutedEventArgs e)
        {
            GC.Collect();
        }


        private void ButtonClear_Click(object sender, RoutedEventArgs e)
        {
            viewModel.Values.Clear();
        }
    }
    public class Column2ExampleViewModel : INotifyPropertyChanged
    {
        DispatcherTimer timer;


        public SeriesCollection SeriesCollection { get; set; }
        public Func<double, string> Formatter { get; set; }

        public double XMin { get; set; } = double.NaN;
        public double XMax { get; set; } = double.NaN;
        public bool IsRunning { get; private set; }
        List<double> datas = new List<double>();
        
        public ChartValues<double> Values = new ChartValues<double>();

        public void Update()
        {

            Random random = new Random();
            double[] datas2 = new double[datas.Count()];
            for (int i = 0; i < datas.Count(); i++)
            {
                datas2[i] = datas[i] + (random.NextDouble() - 0.5) * 1;
            }
            //把其中一部分数据变为无效
            int null_value_pos = random.Next(datas.Count());
            for (int i = 0; i < datas.Count()/10; i++)
            {
                int index = null_value_pos - datas.Count() / 20 + i;
                if (index < 0)
                    index += datas2.Count();
                else if (index >= datas2.Count())
                    index -= datas2.Count();

                datas2[index] = double.NaN;
            }



           // if (SeriesCollection.Count() > 0)
           //     SeriesCollection.Clear();


            Values.Clear();
            
            Values.AddRange(datas2);




        }
        public void Init()
        {
            //-----------------------------------------------------------
            //模拟数据
            double target = 150;
            double tolerance = 2;

            Random random = new Random();
            for (int i = 0; i < 100; i++)
            {
                double d = Math.Sin(Math.PI * 2 * i / 35) * tolerance + (random.NextDouble() - 0.5) * 0.3 + target;
                datas.Add(d);
            }



            SeriesCollection = new SeriesCollection();


            SeriesCollection.Add(
                new Column2Series
                {
                Title = "Column2",
                Values = Values,
                StrokeThickness = 1,
                Stroke = new SolidColorBrush(System.Windows.Media.Colors.DarkRed),
                Fill = new SolidColorBrush(System.Windows.Media.Color.FromArgb(0x80, 0xff, 0, 0)),
                
                YAxisCrossing = 150,
                Configuration = Mappers.Xy<double>()
                .X((v,index)=>index)
                .Y(v => v)
                });


            Formatter = value => value.ToString("N");
            XMin = 100;
            XMax = 900;

            //-----------------------------------------------------------
            //转显示数据
            Update();

            timer = new DispatcherTimer();
            timer.Interval = TimeSpan.FromSeconds(0.1);
            timer.Tick += Timer_Tick;
        }
        public void Start()
        {
            IsRunning = true;
            timer.Start();
        }
        public void Stop()
        {
            IsRunning = false;
            timer.Stop();
        }
        
        private void Timer_Tick(object sender, EventArgs e)
        {
            Update();
        }

        public event PropertyChangedEventHandler PropertyChanged;
    }

}
