I have been trying to learn how to use Live charts for a School project where I need to be able to graph Large amounts of data. My code gets the data from a file and puts it into a linked list(points) where it is then copied into the Chartvalues Data Structure. using a resource dictionary I have filled the area under the line with white so I could test whether it graphed or not
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();
}
}
}
}
}
and the Main window 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>
and 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>
And 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;
}
}
}
and 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;
}
}
}