WPF Livecharts C# Column name change

FredGrit發表於2024-08-29
//xaml
<Window x:Class="WpfApp299.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:lvc="clr-namespace:LiveCharts.Wpf;assembly=LiveCharts.Wpf"
        xmlns:local="clr-namespace:WpfApp299"
        mc:Ignorable="d" WindowState="Maximized"
        Title="MainWindow">
    <Grid x:Name="gd">
        <!--<Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="200"/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>
        <ListBox Grid.Row="0" Grid.Column="0" Grid.RowSpan="2"
                 ItemsSource="{Binding FtNames,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}">            
        </ListBox>
        <Button HorizontalAlignment="Right" VerticalAlignment="Top" Width="200" Height="50" Click="Button_Click" 
                Panel.ZIndex="2" Content="Refresh" Grid.Row="0" Grid.Column="1"/>
        --><!--<Thumb x:Name="tb" Panel.ZIndex="10" Width="10" Grid.Row="1" Grid.Column="1"
               DragStarted="Thumb_DragStarted"
               DragDelta="Thumb_DragDelta"
               DragCompleted="Thumb_DragCompleted"
               Height="{Binding Path=ActualHeight,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=Window}}">
            <Thumb.Template>
                <ControlTemplate>
                    <Rectangle>
                        <Rectangle.Fill>Red</Rectangle.Fill>
                    </Rectangle>
                </ControlTemplate>
            </Thumb.Template>
        </Thumb>--><!--
        
        <lvc:CartesianChart x:Name="chart" Grid.Row="0" Grid.RowSpan="2" Grid.Column="1" Series="{Binding BooksCollection,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" 
                            LegendLocation="Right"
                            MouseDown="CartesianChart_MouseDown" Panel.ZIndex="1">
            <lvc:CartesianChart.AxisX>
                <lvc:Axis  Labels="{Binding Labels,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"/>
            </lvc:CartesianChart.AxisX>
            <lvc:CartesianChart.AxisY>
                <lvc:Axis Title="Score" LabelFormatter="{Binding Formatter}"/>
            </lvc:CartesianChart.AxisY>
        </lvc:CartesianChart>-->
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="100"/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>
        <ListBox Grid.Column="0" ItemsSource="{Binding FtNames,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
                 SelectionChanged="ListBox_SelectionChanged"/>
        <Button HorizontalAlignment="Right" VerticalAlignment="Top" Width="200" Height="50" Click="Button_Click" 
         Panel.ZIndex="2" Content="Refresh" Grid.Row="0" Grid.Column="1" />
        <lvc:CartesianChart x:Name="chart" Grid.Column="1" Series="{Binding BooksCollection,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" 
                     LegendLocation="Right"
                     MouseDown="CartesianChart_MouseDown" Panel.ZIndex="1">
            <lvc:CartesianChart.AxisX>
                <lvc:Axis  Labels="{Binding Labels,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"/>
            </lvc:CartesianChart.AxisX>
            <lvc:CartesianChart.AxisY>
                <lvc:Axis Title="Score" LabelFormatter="{Binding Formatter}"/>
            </lvc:CartesianChart.AxisY>
        </lvc:CartesianChart>
    </Grid>
</Window>




//cs
using System;
using System.CodeDom;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using LiveCharts;
using LiveCharts.Wpf;
using Newtonsoft.Json;

namespace WpfApp299
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window, INotifyPropertyChanged
    {

        private int idx = 0;
        public MainWindow()
        {
            InitializeComponent();
            rnd = new Random();
            this.DataContext = this;
            InitData();
        }


        private void InitData()
        {
            FtNames = new ObservableCollection<string>();
            var bkPis = typeof(Book).GetProperties().Where(x => x.PropertyType == typeof(double)).ToList();
            if (bkPis != null && bkPis.Any())
            {
                bkPis.ForEach(x =>
                {
                    ftNames.Add(x.Name);
                });
            }

            BooksCollection = new SeriesCollection();
            //BooksCollection.Add(new ColumnSeries
            //{
            //    Title = "2015",
            //    Values = new ChartValues<double> { rnd.Next(1, 1000), rnd.Next(1, 1000), rnd.Next(1, 1000), rnd.Next(1, 1000), rnd.Next(1, 1000) }
            //});

            //BooksCollection.Add(new ColumnSeries
            //{
            //    Title = "2016",
            //    Values = new ChartValues<double> { rnd.Next(1, 1000), rnd.Next(1, 1000), rnd.Next(1, 1000), rnd.Next(1, 1000), rnd.Next(1, 1000) }
            //});

            //BooksCollection.Add(new ColumnSeries
            //{
            //    Title = "2017",
            //    Values = new ChartValues<double> { rnd.Next(1, 1000), rnd.Next(1, 1000), rnd.Next(1, 1000), rnd.Next(1, 1000), rnd.Next(1, 1000) }
            //});

            //BooksCollection.Add(new ColumnSeries
            //{
            //    Title = "2018",
            //    Values = new ChartValues<double> { rnd.Next(1, 1000), rnd.Next(1, 1000), rnd.Next(1, 1000), rnd.Next(1, 1000), rnd.Next(1, 1000) }
            //});

            //BooksCollection.Add(new ColumnSeries
            //{
            //    Title = "2019",
            //    Values = new ChartValues<double> { rnd.Next(1, 1000), rnd.Next(1, 1000), rnd.Next(1, 1000), rnd.Next(1, 1000), rnd.Next(1, 1000) }
            //});

            //Labels = new List<string>();
            //for (int i = 0; i < 5; i++)
            //{
            //    Labels.Add($"SalesMan_{rnd.Next(1, 100)}");
            //}


            BooksList = new List<Book>();

            for (int i = 0; i < 10; i++)
            {
                BooksList.Add(new Book()
                {
                    Id = i,
                    Name = $"Name_{i + 1}",
                    MathScore = rnd.Next(1, 100),
                    CSScore = rnd.Next(1, 100),
                    PhysicsScore = rnd.Next(1, 100),
                    EngScore = rnd.Next(1, 100),
                    Class = rnd.Next(1, 200),
                    Grade = rnd.Next(1, 200),
                });
            }
            BooksCollection = new SeriesCollection();
            BooksCollection.Add(new ColumnSeries()
            {
                Title = "CSScore",
                Values = new ChartValues<double>(BooksList.Select(x => x.CSScore).ToList())
            });

            BooksCollection.Add(new ColumnSeries()
            {
                Title = "Class",
                Values = new ChartValues<double>(BooksList.Select(x => (double)x.Class).ToList())
            });

            BooksCollection.Add(new ColumnSeries()
            {
                Title = "Grade",
                Values = new ChartValues<double>(BooksList.Select(x => (double)x.Grade).ToList())
            });

            Labels = new List<string>();
            for (int i = 0; i < 10; i++)
            {
                Labels.Add($"{BooksList[i].Name}");
            }
        }

        private Random rnd { get; set; }

        private SeriesCollection booksCollection;
        public SeriesCollection BooksCollection
        {
            get
            {
                return booksCollection;
            }
            set
            {
                booksCollection = value;
                OnPropertyChanged(nameof(BooksCollection));
            }
        }

        private List<Book> booksList;
        public List<Book> BooksList
        {
            get
            {
                return booksList;
            }
            set
            {
                if (value != booksList)
                {
                    booksList = value;
                    OnPropertyChanged(nameof(BooksList));
                }
            }
        }

        public int MyProperty { get; set; }

        private List<string> labels;
        public List<string> Labels
        {
            get
            {
                return labels;
            }
            set
            {
                if (value != labels)
                {
                    labels = value;
                    OnPropertyChanged(nameof(Labels));
                }
            }
        }

        private ObservableCollection<string> ftNames;
        public ObservableCollection<string> FtNames
        {
            get
            {
                return ftNames;
            }
            set
            {
                if (value != ftNames)
                {
                    ftNames = value;
                    OnPropertyChanged(nameof(FtNames));
                }
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        private void OnPropertyChanged(string propName)
        {
            var handler = PropertyChanged;
            if (handler != null)
            {
                handler?.Invoke(this, new PropertyChangedEventArgs(propName));
            }
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            var thumbsList = gd.Children.OfType<Thumb>()?.ToList();
            if (thumbsList != null && thumbsList.Any())
            {
                thumbsList.ForEach(x =>
                {
                    gd.Children.Remove(x);
                });
            }
            Application.Current.Dispatcher.BeginInvoke(new Action(() =>
            {
                InitData();
            }));
            //Task.Run(() =>
            //{
            //    InitData();
            //});
        }

        private void Thumb_DragStarted(object sender, System.Windows.Controls.Primitives.DragStartedEventArgs e)
        {

        }

        private void Thumb_DragDelta(object sender, System.Windows.Controls.Primitives.DragDeltaEventArgs e)
        {

        }

        //private void Thumb_DragCompleted(object sender, System.Windows.Controls.Primitives.DragCompletedEventArgs e)
        //{
        //    var margin = tb.Margin.Left;
        //    var xDelta = e.HorizontalChange;
        //    tb.Margin = new Thickness(tb.Margin.Left + xDelta, 0, 0, 0);
        //}

        int zIndex = 20;
        private void CartesianChart_MouseDown(object sender, MouseButtonEventArgs e)
        {
            var pt = e.GetPosition(this);
            Thumb newTb = new Thumb();
            newTb.Width = 10;
            newTb.Height = this.ActualHeight;
            newTb.Background = new SolidColorBrush(Colors.Red);
            newTb.BorderBrush = new SolidColorBrush(Colors.Red);
            newTb.Margin = new Thickness(rnd.Next(500, 1000), 0, 0, 0);
            chart.Width = this.ActualWidth;
            Grid.SetZIndex(newTb, 10);
            gd.Children.Add(newTb);
        }

        private void ListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if(e.AddedItems!=null && e.AddedItems.Count>0)
            {
                var selectedName = e?.AddedItems[0]?.ToString();
                if (!string.IsNullOrEmpty(selectedName))
                {
                    BooksCollection = new SeriesCollection();
                    var pis = typeof(Book).GetProperties().Where(x => x.PropertyType == typeof(double)).ToList();
                    var selectedPi = pis.Where(x => x.Name == selectedName).FirstOrDefault();
                    List<double> scoresList = new List<double>();
                    foreach (var bk in BooksList)
                    {
                        var objValue = selectedPi.GetValue(bk);
                        double d = 0;
                        if (double.TryParse(objValue.ToString(), out d))
                        {
                            scoresList.Add(d);
                        }
                    }
                    BooksCollection.Add(new ColumnSeries()
                    {
                        Title = selectedName,
                        Values = new ChartValues<double>(scoresList)
                    });
                    BooksCollection.Add(new ColumnSeries()
                    {
                        Title = "Class",
                        Values = new ChartValues<double>(BooksList.Select(x => (double)x.Class).ToList())
                    });
                    BooksCollection.Add(new ColumnSeries()
                    {
                        Title = "Grade",
                        Values = new ChartValues<double>(BooksList.Select(x => (double)x.Grade).ToList())
                    });
                }
            } 
        }
    }

    public class Book
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public double MathScore { get; set; }
        public double CSScore { get; set; }
        public double PhysicsScore { get; set; }
        public double EngScore { get; set; }
        public int Class { get; set; }
        public int Grade { get; set; }
    }
}

相關文章