Skip to content

Commit cb4f7e8

Browse files
committed
Add project files.
1 parent 511de6e commit cb4f7e8

File tree

8 files changed

+926
-0
lines changed

8 files changed

+926
-0
lines changed

AlgorithmGUI.csproj

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<OutputType>Exe</OutputType>
5+
<TargetFramework>net7.0-windows</TargetFramework>
6+
<Nullable>enable</Nullable>
7+
<UseWPF>true</UseWPF>
8+
<StartupObject>AlgorithmGUI.Program</StartupObject>
9+
</PropertyGroup>
10+
11+
<ItemGroup>
12+
<PackageReference Include="OxyPlot.Core" Version="2.1.2" />
13+
<PackageReference Include="OxyPlot.Wpf" Version="2.1.2" />
14+
</ItemGroup>
15+
16+
</Project>

AlgorithmGUI.sln

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
2+
Microsoft Visual Studio Solution File, Format Version 12.00
3+
# Visual Studio Version 17
4+
VisualStudioVersion = 17.5.33414.496
5+
MinimumVisualStudioVersion = 10.0.40219.1
6+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AlgorithmGUI", "AlgorithmGUI.csproj", "{35A9262E-6472-4184-AADA-9A72DE59EC36}"
7+
EndProject
8+
Global
9+
GlobalSection(SolutionConfigurationPlatforms) = preSolution
10+
Debug|Any CPU = Debug|Any CPU
11+
Release|Any CPU = Release|Any CPU
12+
EndGlobalSection
13+
GlobalSection(ProjectConfigurationPlatforms) = postSolution
14+
{35A9262E-6472-4184-AADA-9A72DE59EC36}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
15+
{35A9262E-6472-4184-AADA-9A72DE59EC36}.Debug|Any CPU.Build.0 = Debug|Any CPU
16+
{35A9262E-6472-4184-AADA-9A72DE59EC36}.Release|Any CPU.ActiveCfg = Release|Any CPU
17+
{35A9262E-6472-4184-AADA-9A72DE59EC36}.Release|Any CPU.Build.0 = Release|Any CPU
18+
EndGlobalSection
19+
GlobalSection(SolutionProperties) = preSolution
20+
HideSolutionNode = FALSE
21+
EndGlobalSection
22+
GlobalSection(ExtensibilityGlobals) = postSolution
23+
SolutionGuid = {5165AE66-D850-4920-979A-070DA2900A98}
24+
EndGlobalSection
25+
EndGlobal

App.xaml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<Application x:Class="AlgorithmGUI.App"
2+
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
3+
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
4+
xmlns:local="clr-namespace:AlgorithmGUI"
5+
StartupUri="MainWindow.xaml">
6+
<Application.Resources>
7+
8+
</Application.Resources>
9+
</Application>

App.xaml.cs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Configuration;
4+
using System.Data;
5+
using System.Linq;
6+
using System.Threading.Tasks;
7+
using System.Windows;
8+
9+
namespace AlgorithmGUI
10+
{
11+
/// <summary>
12+
/// Interaction logic for App.xaml
13+
/// </summary>
14+
public partial class App : Application
15+
{
16+
}
17+
}

AssemblyInfo.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
using System.Windows;
2+
3+
[assembly: ThemeInfo(
4+
ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
5+
//(used if a resource is not found in the page,
6+
// or application resource dictionaries)
7+
ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
8+
//(used if a resource is not found in the page,
9+
// app, or any theme specific resource dictionaries)
10+
)]

MainWindow.xaml

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
<Window
2+
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
3+
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
4+
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
5+
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
6+
xmlns:local="clr-namespace:AlgorithmGUI"
7+
xmlns:oxy="http://oxyplot.org/wpf"
8+
x:Class="AlgorithmGUI.MainWindow"
9+
mc:Ignorable="d"
10+
Title="MainWindow" Height="450" Width="800">
11+
12+
<TabControl TabStripPlacement="Top">
13+
<TabItem Name="deviation" Header="Deviations from Target">
14+
<Grid>
15+
<oxy:PlotView x:Name="deviationGraph"/>
16+
</Grid>
17+
</TabItem>
18+
19+
<TabItem Name="runningTime" Header="Runtime length">
20+
<Grid>
21+
<oxy:PlotView x:Name="runtimeGraph"/>
22+
</Grid>
23+
</TabItem>
24+
<TabItem Name="dataView" Header="Raw Data">
25+
<Grid>
26+
<Grid.RowDefinitions>
27+
<RowDefinition Height="Auto"/>
28+
<RowDefinition Height="*"/>
29+
</Grid.RowDefinitions>
30+
<Button Content="Export Data" Click="SaveButtonClick"/>
31+
<ScrollViewer Grid.Row="1" VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto">
32+
<DataGrid x:Name="Data" IsReadOnly="True"/>
33+
</ScrollViewer>
34+
</Grid>
35+
</TabItem>
36+
<TabItem Header="Controls">
37+
<Grid>
38+
<TextBlock x:Name ="TextBoxInfo" TextAlignment="Center" TextWrapping="Wrap" FontSize="18"/>
39+
</Grid>
40+
</TabItem>
41+
42+
</TabControl>
43+
44+
45+
</Window>

MainWindow.xaml.cs

Lines changed: 200 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,200 @@
1+
using OxyPlot.Series;
2+
using OxyPlot;
3+
using System.Windows;
4+
using OxyPlot.Axes;
5+
using OxyPlot.Legends;
6+
using System;
7+
using System.Text;
8+
using System.Data;
9+
using Microsoft.Win32;
10+
using System.IO;
11+
using System.Threading.Tasks;
12+
using System.Windows.Interop;
13+
using System.Windows.Media;
14+
15+
namespace AlgorithmGUI
16+
{
17+
/// <summary>
18+
/// Interaction logic for MainWindow.xaml
19+
/// </summary>
20+
public partial class MainWindow : Window
21+
{
22+
public static string dataString;
23+
//9 questions, 8 iterations, 3 values (run times, averages, standard deviation)
24+
public MainWindow(double[,,] array)
25+
{
26+
InitializeComponent();
27+
RenderOptions.ProcessRenderMode = RenderMode.Default;
28+
populateRichTextBox(this);
29+
//Plots the graphs
30+
PlotGraphs(array, this);
31+
//Loads the data to a csv format
32+
dataString = dataToCSV(array);
33+
//Polulates the datagrid with the csv format data
34+
makeDataTable(this);
35+
}
36+
37+
private static void populateRichTextBox(MainWindow mainWindow)
38+
{
39+
mainWindow.TextBoxInfo.Text = "Graph Controls!\nMouse Wheel: Zoom\nRight Click: Move\nHide Elements: Click the Question Number at the bottom!\n\nQ: Graph showing an error?\nA: Just rerun D)!\n\nQ: Why is Algorithm H not running completely?\nA: Because it would take way too long otherwise, trust me.\n\nQ: Why are there 2 entries for 1 algorithm in the legend?\nA: So you can choose to hide the points or the line. This was the only way I was able to get a line with error bars.\n\nMade by Nove for Algorithm Analysis and Data Structures, 2023";
40+
}
41+
42+
private static void PlotGraphs(double[,,] array, MainWindow mainWindow)
43+
{
44+
//Plot the graphs
45+
var devGraph = new PlotModel();
46+
var timeGraph = new PlotModel();
47+
48+
int[] sizes = new int[] { 8, 16, 32, 64, 128, 256, 512, 1024 };
49+
50+
//add the axis labels
51+
devGraph.Axes.Add(new LinearAxis { Position = AxisPosition.Bottom, Title = "Cardinality of S" });
52+
devGraph.Axes.Add(new LinearAxis { Position = AxisPosition.Left, Title = "Average Deviation from ideal" });
53+
timeGraph.Axes.Add(new LinearAxis { Position = AxisPosition.Bottom, Title = "Cardinality of S" });
54+
timeGraph.Axes.Add(new LinearAxis { Position = AxisPosition.Left, Title = "Average Execution time (ms)" });
55+
56+
//add a legend
57+
var devLegend = new Legend { LegendTitle = "Question Number", LegendPosition = LegendPosition.BottomCenter, LegendPlacement = LegendPlacement.Outside, LegendOrientation = LegendOrientation.Horizontal };
58+
var timeLegend = new Legend { LegendPosition = LegendPosition.BottomCenter, LegendPlacement = LegendPlacement.Outside, LegendOrientation = LegendOrientation.Horizontal };
59+
60+
devGraph.Legends.Add(devLegend);
61+
timeGraph.Legends.Add(timeLegend);
62+
63+
//Synchronises the colours
64+
var customColors = new[]
65+
{
66+
OxyColors.Red,
67+
OxyColors.Orange,
68+
OxyColors.Yellow,
69+
OxyColors.LightGreen,
70+
OxyColors.Green,
71+
OxyColors.LightBlue,
72+
OxyColors.Blue,
73+
OxyColors.DarkBlue,
74+
OxyColors.Purple
75+
};
76+
77+
//populate the data into the graph
78+
79+
for (int question = 1; question < 10; question++)
80+
{
81+
var devScatterPoints = new ScatterErrorSeries { Title = $"Question {(char)(question + 64)}", DataFieldX = "Array Length", DataFieldY = "Deviation from ideal", DataFieldErrorY = "Standard Deviation" };
82+
var devLine = new LineSeries { Title = $"Question {(char)(question + 64)}", DataFieldX = "Array Length", DataFieldY = "Deviation from ideal" };
83+
var timeSeries = new LineSeries { Title = $"Question {(char)(question + 64)}", DataFieldX = "Array Length", DataFieldY = "Runtime (ms)" };
84+
85+
//Sets the colours
86+
devLine.Color = customColors[question - 1];
87+
devScatterPoints.MarkerFill = customColors[question - 1];
88+
timeSeries.Color = customColors[question - 1];
89+
90+
for (int arrayLength = 0; arrayLength < 8; arrayLength++)
91+
{
92+
double devAverageValue = array[question - 1, arrayLength, 1];
93+
double timeAverageValue = array[question - 1, arrayLength, 0];
94+
95+
devLine.Points.Add(new DataPoint(sizes[arrayLength], devAverageValue));
96+
devScatterPoints.Points.Add(new ScatterErrorPoint(sizes[arrayLength], devAverageValue, 0, array[question - 1, arrayLength, 2]));
97+
timeSeries.Points.Add(new DataPoint(sizes[arrayLength], timeAverageValue));
98+
}
99+
100+
//Add the lines to the graph models
101+
devGraph.Series.Add(devLine);
102+
devGraph.Series.Add(devScatterPoints);
103+
timeGraph.Series.Add(timeSeries);
104+
}
105+
106+
//assign the data to the graph views
107+
mainWindow.deviationGraph.Model = devGraph;
108+
mainWindow.runtimeGraph.Model = timeGraph;
109+
}
110+
111+
private static void makeDataTable(MainWindow mainWindow)
112+
{
113+
string[] rows = dataString.Split(new char[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);
114+
string[] columns = rows[0].Split(new char[] { ',' });
115+
116+
DataTable rawInfo = new();
117+
118+
// Add the columns to the DataTable
119+
foreach (string column in columns)
120+
{
121+
rawInfo.Columns.Add(column);
122+
}
123+
124+
// Add the rows to the DataTable
125+
for (int i = 1; i < rows.Length; i++)
126+
{
127+
string[] rowValues = rows[i].Split(new char[] { ',' });
128+
DataRow dataRow = rawInfo.NewRow();
129+
for (int j = 0; j < rowValues.Length; j++)
130+
{
131+
dataRow[j] = rowValues[j];
132+
}
133+
rawInfo.Rows.Add(dataRow);
134+
}
135+
136+
// Bind the DataTable to the DataGrid
137+
rawInfo.DefaultView.Sort = "Question ASC";
138+
mainWindow.Data.ItemsSource = rawInfo.DefaultView;
139+
140+
}
141+
142+
public static string dataToCSV(double[,,] array)
143+
{
144+
StringBuilder csvBuilder = new();
145+
string[] types = { "Runtime (ms)", "Average", "S.D" };
146+
147+
csvBuilder.Append("Question,Type,8,16,32,64,128,256,512,1024\n");
148+
149+
Parallel.For(1, 10, question =>
150+
{
151+
for (int rowNum = 0; rowNum < 3; rowNum++)
152+
{
153+
var row = new StringBuilder();
154+
row.Append((char)(question + 64) + "," + types[rowNum]);
155+
156+
for (int arraySize = 0; arraySize < 8; arraySize++)
157+
{
158+
row.Append("," + array[question - 1, arraySize, rowNum]);
159+
}
160+
161+
row.Append('\n');
162+
lock (csvBuilder) // prevent multiple threads from writing to the CSV string at the same time
163+
{
164+
csvBuilder.Append(row);
165+
}
166+
}
167+
});
168+
169+
return csvBuilder.ToString();
170+
171+
172+
}
173+
174+
private void SaveButtonClick(object sender, RoutedEventArgs e)
175+
{
176+
// Create a SaveFileDialog object
177+
SaveFileDialog saveFileDialog = new();
178+
saveFileDialog.Filter = "Comma Separated File (*.csv)|*.csv|Text File (*.txt)|*.txt|All files|*.*";
179+
saveFileDialog.Title = "Save as a CSV file!";
180+
181+
// Show the dialog and get the result
182+
bool? result = saveFileDialog.ShowDialog();
183+
184+
if (result == true)
185+
{
186+
// Get the selected file name and path
187+
string filePath = saveFileDialog.FileName;
188+
189+
// Writes the data to the file, meaning it only needs to be processed once.
190+
File.WriteAllText(filePath, dataString);
191+
}
192+
193+
}
194+
195+
private void Data_Sorting(object sender, System.Windows.Controls.DataGridSortingEventArgs e)
196+
{
197+
198+
}
199+
}
200+
}

0 commit comments

Comments
 (0)