首页 > 解决方案 > 如何从 Livecharts 中的列表绘制图表

问题描述

我一直在尝试学习如何将实时图表用于需要能够绘制大量数据的学校项目。我的代码从文件中获取数据并将其放入链接列表(点)中,然后将其复制到 Chartvalues 数据结构中。使用资源字典,我用白色填充了线条下方的区域,这样我就可以测试它是否绘制了

using LiveCharts.Wpf;
using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime;
using System.Runtime.InteropServices.ComTypes;
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.Navigation;
using System.Windows.Shapes;
using LiveCharts;
using LiveCharts.Defaults;
using LiveCharts.Helpers;

namespace Flux_calibrator
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        LList<spec> points = new LList<spec>();
        LList<spec> pointr = new LList<spec>();
        OpenFileDialog ofd = new OpenFileDialog();
        SaveFileDialog sav = new SaveFileDialog();
        ChartValues<ObservablePoint> specg = new ChartValues<ObservablePoint>();
        ChartValues<ObservablePoint> refg = new ChartValues<ObservablePoint>();
        int caseswitch = 0;
        public MainWindow()
        {
            InitializeComponent();
            SeriesCollection SeriesCollection = new SeriesCollection
            {
                new LineSeries
                {
                    Title="Spectrum",
                    Values = specg,
                },
                new LineSeries
                {
                    Title="Refrence",
                    Values = refg,
                }
            };
        }

        private void Opr_Click(object senderl, RoutedEventArgs e)
        {

        }

        private void Sas_Click(object senderl, RoutedEventArgs e)
        {
            string[] f = new string[points.Length];
            sav.Filter = "Dat|*.dat";
            sav.ShowDialog();
            string path = sav.FileName;
            if (string.IsNullOrEmpty(path))
            {
                return;
            }
            else
            {
                var save = File.Create(path);
                int Length = points.Length;
                for (int i = 0; i < Length; i++)
                {
                    spec w = points.pop();
                    f[i] = Math.Round(w.WL, 6).ToString() + "       " + w.IT.ToString();
                }
                save.Close();
                File.WriteAllLines(path, f, Encoding.UTF8);
            }
        }

        private void Sar_Click(object senderl, RoutedEventArgs e)
        {
        }

        private void col_Click(object senderl, RoutedEventArgs e)
        {
            System.Windows.Application.Current.Shutdown();
        }

        private void fluxcal(LList<spec> spectrum, double zerop, double effective, double wavestep, double Counts, double mag)
        {
            double pow = (mag) * -1 / 2.5;
            double F = zerop * Math.Pow(10, pow);
            double max = effective + wavestep;
            double min = effective - wavestep;
            double count = Counts * (wavestep / (max - min));
            double scale = F / count;
            double distance = 1800000;
            int i = 0;
            while (Math.Abs(spectrum.getById(i).WL - effective) <= distance)
            {
                distance = Math.Abs(spectrum.getById(i).WL - effective);
                i++;
            }
            for (int j = 0; j < spectrum.Length; j++)
            {
                spectrum.getById(j).IT *= scale;
            }
        }

        private void button_Click(object sender, RoutedEventArgs e)
        {
            double mag;
            switch (caseswitch)
            {
                case 0:
                    MessageBox.Show("Please open a spectrum");
                    break;
                case 1:
                    if (!double.TryParse(MagT.Text, out mag))
                    {
                        MessageBox.Show("Please ensure that all inputs are numbers");
                    }
                    else if (VBand.IsChecked == true)
                    {
                        fluxcal(points, 363.1 * Math.Pow(10, -11), 5450, 850, findcounts(points, 5450, 850), mag);
                    }
                    else if (UBand.IsChecked == true)
                    {
                        fluxcal(points, 417.5 * Math.Pow(10, -11), 3600, 60, findcounts(points, 3600, 600), mag);
                    }
                    else if (BBand.IsChecked == true)
                    {
                        fluxcal(points, 632 * Math.Pow(10, -11), 4380, 90, findcounts(points, 4380, 900), mag);
                    }
                    else if (RBand.IsChecked == true)
                    {
                        fluxcal(points, 217.7 * Math.Pow(10, -11), 6410, 1500, findcounts(points, 6410, 1500), mag);
                    }
                    else if (IBand.IsChecked == true)
                    {
                        fluxcal(points, 112.6 * Math.Pow(10, -11), 7980, 1500, findcounts(points, 7980, 1500), mag);
                    }
                    else if (JBand.IsChecked == true)
                    {
                        fluxcal(points, 31.47 * Math.Pow(10, -11), 12000, 2600, findcounts(points, 12200, 2600), mag);
                    }
                    else if (HBand.IsChecked == true)
                    {
                        fluxcal(points, 11.38 * Math.Pow(10, -11), 16300, 2900, findcounts(points, 16300, 2900), mag);
                    }
                    else if (KBand.IsChecked == true)
                    {
                        fluxcal(points, 3.961 * Math.Pow(10, -11), 21900, 4100, findcounts(points, 21900, 4100), mag);
                    }
                    else
                    {
                        MessageBox.Show("What the fuck did you do");
                    }
                    break;
            }

        }
        private double findcounts(LList<spec> spectrum, double effective, double step)
        {
            double min = effective - step;
            double max = effective + step;
            int i = 0;
            int j = 0;
            double distance = 6742376432;
            double count = 0;
            while (Math.Abs(spectrum.getById(i).WL - max) <= distance)
            {
                distance = Math.Abs(spectrum.getById(i).WL - max);
                i++;
            }
            distance = 6742376432;
            while (Math.Abs(spectrum.getById(j).WL - min) <= distance)
            {
                distance = Math.Abs(spectrum.getById(j).WL - min);
                j++;
            }
            j = j - 1;
            i = i - 1;
            while ((j) < (i))
            {
                count += spectrum.getById(j).IT;
                j++;
            }
            return count;
        }

        private void R_Checked(object sender, RoutedEventArgs e)
        {

        }

        private void V_Checked(object sender, RoutedEventArgs e)
        {

        }

        private void B_Checked(object sender, RoutedEventArgs e)
        {

        }

        private void U_Checked(object sender, RoutedEventArgs e)
        {

        }

        private void I_Checked(object sender, RoutedEventArgs e)
        {

        }

        private void J_Checked(object sender, RoutedEventArgs e)
        {

        }

        private void H_Checked(object sender, RoutedEventArgs e)
        {

        }

        private void K_Checked(object sender, RoutedEventArgs e)
        {

        }

        private void open_Click(object sender, RoutedEventArgs e)
        {
            ofd.Filter = "Dat|*.dat";
            Nullable<bool> result = ofd.ShowDialog();
            if (result == true)
            {
                caseswitch = 1;
                string pathr = ofd.FileName;
                StreamReader re = new StreamReader(pathr);
                string p = re.ReadLine();
                while (p != null)
                {
                    string[] spec = p.Split('   ');
                    if (double.TryParse(spec[0], out double wv))
                    {
                    }
                    else
                    {
                        MessageBox.Show("The file contains non double characters");
                    }
                    if (double.TryParse(spec[1], out double it))
                    {
                    }
                    else
                    {
                        MessageBox.Show("The file contains non double characters");
                    }
                    points.addList(new spec(wv, it));
                    p = re.ReadLine();
                }
                for (int i = 0; i < points.Length; i++)
                {
                    specg.Add(new ObservablePoint(points.getById(i).WL, points.getById(i).IT));
                    /*{
                        X = points.getById(i).WL,
                        Y = points.getById(i).IT
                    });*/
                }
                
            }
            else
            {
                MessageBox.Show("File could not be found");
            }

        }

        private void openr_Click(object sender, RoutedEventArgs e)
        {
            ofd.Filter = "Dat|*.dat";
            Nullable<bool> result = ofd.ShowDialog();
            if (result == true)
            {
                string pathr = ofd.FileName;
                StreamReader re = new StreamReader(pathr);
                string p = re.ReadLine();
                while (p != null)
                {
                    string[] spec = p.Split('   ');
                    if (double.TryParse(spec[0], out double wv))
                    {
                    }
                    else
                    {
                        MessageBox.Show("The file contains non double characters");
                    }
                    if (double.TryParse(spec[1], out double it))
                    {
                    }
                    else
                    {
                        MessageBox.Show("The file contains non double characters");
                    }
                    pointr.addList(new spec(wv, it));
                    p = re.ReadLine();
                }
            }
        }
    }
}

和主窗口 Xaml

<Window x:Class="Flux_calibrator.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:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
        xmlns:lvc="clr-namespace:LiveCharts.Wpf;assembly=LiveCharts.Wpf"
        xmlns:local="clr-namespace:Flux_calibrator"
        mc:Ignorable="d"
        Title="MainWindow" Height="465" Width="800" WindowStartupLocation="CenterScreen" WindowStyle="None" ResizeMode="NoResize" Background="{x:Null}" AllowsTransparency="True">
    <Grid>
        <materialDesign:Card Margin="-1,0,1,0">
            <Grid>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="72"/>
                    <ColumnDefinition Width="44"/>
                </Grid.ColumnDefinitions>
                <Grid.Resources>
                    <Style TargetType="materialDesign:PackIcon">
                        <Setter Property="Width" Value="30"></Setter>
                        <Setter Property="Height" Value="30"></Setter>
                    </Style>
                </Grid.Resources>
                <Grid Grid.Column="0" Background="#2C2F33">
                    <ListView Margin="0 15">
                        <ListViewItem HorizontalAlignment="Center" Margin="0" Name="OpenFile">
                            <Button Style="{StaticResource MaterialDesignFloatingActionButton}" HorizontalAlignment="Left"
                                BorderBrush="{x:Null}" Background="#DC143C" Foreground="Black" Name="open" Click="open_Click" ToolTip="Open Spectrum">
                                <StackPanel Margin="-5">
                                    <materialDesign:PackIcon Kind="FileChart"/>
                                </StackPanel>
                            </Button>
                        </ListViewItem>
                        <ListViewItem HorizontalAlignment="Center" Margin="0" Name="openrefrence">
                            <Button Style="{StaticResource MaterialDesignFloatingActionButton}" HorizontalAlignment="Left"
                                BorderBrush="{x:Null}" Background="#DC143C" Foreground="Black" Name="openr" Click="openr_Click" ToolTip="Open Spectrum">
                                <StackPanel Margin="-5">
                                    <materialDesign:PackIcon Kind="file"/>
                                </StackPanel>
                            </Button>
                        </ListViewItem>
                        <ListViewItem HorizontalAlignment="Center" Margin="0">
                            <Button Style="{StaticResource MaterialDesignFloatingActionButton}" HorizontalAlignment="Left" x:Name="Save"
                                BorderBrush="{x:Null}" Background="#DC143C" Foreground="Black" Click="Sas_Click">
                                <StackPanel Margin="-5">
                                    <materialDesign:PackIcon Kind="ContentSave"/>
                                </StackPanel>
                            </Button>
                        </ListViewItem>
                        <ListViewItem HorizontalAlignment="Center" Margin="0">
                            <Button Style="{StaticResource MaterialDesignFloatingActionButton}" HorizontalAlignment="Left"
                                BorderBrush="{x:Null}" Background="#DC143C" Foreground="Black">
                                <StackPanel Margin="-5">
                                    <materialDesign:PackIcon Kind="Division"/>
                                </StackPanel>
                                
                            </Button>
                        </ListViewItem>
                        <ListViewItem HorizontalAlignment="Center" Margin="0 10" VerticalAlignment="Bottom">
                            <Button Style="{StaticResource MaterialDesignFloatingActionButton}" HorizontalAlignment="Left" Click="col_Click" 
                                BorderBrush="{x:Null}" Background="#DC143C" Foreground="Black">
                                <StackPanel Margin="-5">
                                    <materialDesign:PackIcon Kind="ExitToApp"/>
                                </StackPanel>
                            </Button>
                        </ListViewItem>
                    </ListView>
                </Grid>
                <Grid Grid.Column="1" Margin="0,0,-693,0" Background="#23272A" Name="RenderPages">
                    <lvc:CartesianChart Margin="10,10,9.8,109.8" Series="{Binding SeriesCollection}">
                        
                    </lvc:CartesianChart>
                    <Grid Margin="0,355,0,0" Background="#FF3E3E42" >
                        <Label x:Name="label" Content="Flux Calibartion" HorizontalAlignment="Left" Height="25" Margin="353,10,0,0" VerticalAlignment="Top" Width="90" Foreground="#DDFFFFFF"/>
                        <RadioButton Margin="13,33,639,50" RenderTransformOrigin="0.5,0.5" Content="U-Band" Name="UBand" Foreground="White" Background="Crimson" BorderBrush="Crimson">
                            <RadioButton.RenderTransform>
                                <TransformGroup>
                                    <ScaleTransform/>
                                    <SkewTransform AngleY="0.472"/>
                                    <RotateTransform/>
                                    <TranslateTransform Y="2.992"/>
                                </TransformGroup>
                            </RadioButton.RenderTransform>
                        </RadioButton>
                        <Label x:Name="label_Copy" Content="Spectral Bands" HorizontalAlignment="Left" Height="25" Margin="10,10,0,0" VerticalAlignment="Top" Width="90" Foreground="#DDFFFFFF"/>
                        <RadioButton Margin="13,58,639,25" RenderTransformOrigin="0.5,0.5" Content="B-Band" x:Name="BBand" Foreground="White" BorderBrush="Crimson" Background="Crimson">
                            <RadioButton.RenderTransform>
                                <TransformGroup>
                                    <ScaleTransform/>
                                    <SkewTransform AngleY="0.472"/>
                                    <RotateTransform/>
                                    <TranslateTransform Y="2.992"/>
                                </TransformGroup>
                            </RadioButton.RenderTransform>
                        </RadioButton>
                        <RadioButton Margin="83,33,569,48" RenderTransformOrigin="0.5,0.5" Content="V-Band" x:Name="VBand" Foreground="White" Background="Crimson" BorderBrush="Crimson" IsChecked="True">
                            <RadioButton.RenderTransform>
                                <TransformGroup>
                                    <ScaleTransform/>
                                    <SkewTransform AngleY="0.472"/>
                                    <RotateTransform/>
                                    <TranslateTransform Y="2.992"/>
                                </TransformGroup>
                            </RadioButton.RenderTransform>
                        </RadioButton>
                        <RadioButton Margin="83,58,569,25" RenderTransformOrigin="0.5,0.5" Content="R-Band" x:Name="RBand" Foreground="White" BorderBrush="Crimson" Background="Crimson">
                            <RadioButton.RenderTransform>
                                <TransformGroup>
                                    <ScaleTransform/>
                                    <SkewTransform AngleY="0.472"/>
                                    <RotateTransform/>
                                    <TranslateTransform Y="2.992"/>
                                </TransformGroup>
                            </RadioButton.RenderTransform>
                        </RadioButton>
                        <RadioButton Margin="153,33,499,48" RenderTransformOrigin="0.5,0.5" Content="I-Band" x:Name="IBand" Foreground="White" Background="Crimson" BorderBrush="Crimson">
                            <RadioButton.RenderTransform>
                                <TransformGroup>
                                    <ScaleTransform/>
                                    <SkewTransform AngleY="0.472"/>
                                    <RotateTransform/>
                                    <TranslateTransform Y="2.992"/>
                                </TransformGroup>
                            </RadioButton.RenderTransform>
                        </RadioButton>
                        <RadioButton Margin="153,60,499,23" RenderTransformOrigin="0.5,0.5" Content="J-Band" x:Name="JBand" Foreground="White" BorderBrush="Crimson" Background="Crimson">
                            <RadioButton.RenderTransform>
                                <TransformGroup>
                                    <ScaleTransform/>
                                    <SkewTransform AngleY="0.472"/>
                                    <RotateTransform/>
                                    <TranslateTransform Y="2.992"/>
                                </TransformGroup>
                            </RadioButton.RenderTransform>
                        </RadioButton>
                        <RadioButton Margin="218,33
                                     ,434,45" RenderTransformOrigin="0.5,0.5" Content="H-Band" x:Name="HBand" Foreground="White" Background="Crimson" BorderBrush="Crimson">
                            <RadioButton.RenderTransform>
                                <TransformGroup>
                                    <ScaleTransform/>
                                    <SkewTransform AngleY="0.472"/>
                                    <RotateTransform/>
                                    <TranslateTransform Y="2.992"/>
                                </TransformGroup>
                            </RadioButton.RenderTransform>
                        </RadioButton>
                        <RadioButton Margin="218,60,434,20" RenderTransformOrigin="0.5,0.5" Content="K-Band" x:Name="KBand" Foreground="White" Background="Crimson" BorderBrush="Crimson">
                            <RadioButton.RenderTransform>
                                <TransformGroup>
                                    <ScaleTransform/>
                                    <SkewTransform AngleY="0.472"/>
                                    <RotateTransform/>
                                    <TranslateTransform Y="2.992"/>
                                </TransformGroup>
                            </RadioButton.RenderTransform>
                        </RadioButton>
                        <TextBox x:Name="MagT" HorizontalAlignment="Left" Height="25" Margin="458,50,0,0" TextWrapping="Wrap" Text="" VerticalAlignment="Top" Width="90" CaretBrush="White" SelectionBrush="Crimson" Foreground="White"/>
                        <Button x:Name="button" Content="Calibrate" HorizontalAlignment="Left" Height="40" Margin="568,35,0,0" VerticalAlignment="Top" Width="115" BorderBrush="Crimson" Background="Crimson" Click="button_Click"/>
                        <Label x:Name="label1" Content="Vega Magnitude:" HorizontalAlignment="Left" Height="25" Margin="353,50,0,0" VerticalAlignment="Top" Width="105" Foreground="White"/>
                    </Grid>
                </Grid>
            </Grid>
        </materialDesign:Card>
    </Grid>
</Window>

和 App.xaml

<Application x:Class="Flux_calibrator.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:lvc="clr-namespace:LiveCharts.Wpf;assembly=LiveCharts.Wpf"
             xmlns:local="clr-namespace:Flux_calibrator"
             StartupUri="MainWindow.xaml">
    <Application.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Light.xaml" />
                <ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Defaults.xaml" />
                <ResourceDictionary Source="pack://application:,,,/MaterialDesignColors;component/Themes/Recommended/Primary/MaterialDesignColor.DeepPurple.xaml" />
                <ResourceDictionary Source="pack://application:,,,/MaterialDesignColors;component/Themes/Recommended/Accent/MaterialDesignColor.Lime.xaml" />
            </ResourceDictionary.MergedDictionaries>
            <Style TargetType="lvc:LineSeries">
                <Setter Property="StrokeThickness" Value="3"></Setter>
                <Setter Property="PointGeometrySize" Value="5"></Setter>
                <Setter Property="LineSmoothness" Value="0"></Setter>
                <Setter Property="Fill" Value="White"></Setter>
            </Style>
        </ResourceDictionary>
    </Application.Resources>
</Application>

和 LList

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Flux_calibrator
{
    public class LList<T>
    {
        private Node<T> LastNode;
        private Node<T> FirstNode;
        public int Length;
        public LList()
        {
            Length = 0;
        }

        public void push(T Data)
        {
            this.addList(Data);
        }

        public T pop()
        {
            if (LastNode != null)
            {
                T temp = this.getById(LastNode.index);
                this.Remove(LastNode.index);
                return temp;
            }
            return default;
        }

        public void Remove(int ID)
        {
            Node<T> currentNode = FirstNode;
            Node<T> Pos = null;
            while (currentNode != null)
            {
                if (currentNode.index == ID)
                {
                    if (currentNode.previous != null)
                    {
                        currentNode.previous.setNext(ref currentNode.next);
                    }
                    else
                    {
                        FirstNode = currentNode.next;
                    }
                    if (currentNode.next != null)
                    {
                        currentNode.next.setPrevious(ref currentNode.previous);
                    }
                    else
                    {
                        LastNode = currentNode.previous;
                    }
                    Pos = currentNode;
                }
                else if (currentNode.index > ID)
                {
                    currentNode.index--;
                }
                currentNode = currentNode.next;
            }
            if (Pos != null)
            {
                Pos.next = null;
                Pos.previous = null;
                Length--;
            }
        }

        public void addList(T Data)
        {
            Node<T> newNode = new Node<T>(Data, Length);
            if (FirstNode == null)
            {
                FirstNode = newNode;
            }
            if (LastNode != null)
            {
                LastNode.setNext(ref newNode);
                newNode.setPrevious(ref LastNode);
            }
            LastNode = newNode;
            Length++;
        }
        public T getById(int ID)
        {
            if (ID > Length / 2)
            {
                Node<T> currentNode = LastNode;
                Node<T> Pos = null;
                while (currentNode != null)
                {
                    if (currentNode.index == ID)
                    {
                        Pos = currentNode;
                    }
                    currentNode = currentNode.previous;
                }
                if (Pos != null)
                {
                    return Pos.data;
                }
            }
            else
            {
                Node<T> currentNode = FirstNode;
                Node<T> Pos = null;
                while (currentNode != null)
                {
                    if (currentNode.index == ID)
                    {
                        Pos = currentNode;
                    }
                    currentNode = currentNode.next;
                }
                if (Pos != null)
                {
                    return Pos.data;
                }
            }
            return default(T);
        }
    }
    class Node<T>
    {
        public T data;
        public Node<T> next;
        public Node<T> previous;
        public int index;
        public Node(T Data, int Index)
        {
            data = Data;
            index = Index;
        }
        public Node(T Data, ref Node<T> Next, int Index)
        {
            data = Data;
            next = Next;
            index = Index;
        }
        public Node(T Data, ref Node<T> Next)
        {
            data = Data;
            next = Next;
        }
        public Node(T Data)
        {
            data = Data;

        }
        public void setNext(ref Node<T> Next)
        {
            next = Next;
        }
        public void setPrevious(ref Node<T> Prev)
        {
            previous = Prev;
        }
    }
}

和spec.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Flux_calibrator
{
    public class spec
    {
        private double wl;
        private double it;

        public double WL
        {
            get { return wl; }
        }
        public double IT
        {
            get
            {
                return it;
            }
            set
            {
                it = value;
            }
        }
        public spec(double wl, double it)
        {
            this.it = it;
            this.wl = wl;
        }
    }
}

标签: c#wpflinechartlivecharts

解决方案


推荐阅读