Skip to content
Snippets Groups Projects
Commit 288b9693 authored by Paul-Winpenny's avatar Paul-Winpenny
Browse files

The graphs actually look quite clean right now, the scaling aspect will need...

The graphs actually look quite clean right now, the scaling aspect will need to be made independent from the other axis (e.g. shrinking the horizontal shoulnd't affect the length of the graph, just the width).
parent b6bc2d59
No related branches found
No related tags found
No related merge requests found
...@@ -19,7 +19,16 @@ public partial class App : Application ...@@ -19,7 +19,16 @@ public partial class App : Application
MainPage = new AppShell(); MainPage = new AppShell();
} }
protected override Window CreateWindow(IActivationState activationState)
{
var window = base.CreateWindow(activationState);
window.MinimumWidth = 800;
window.MinimumHeight = 650;
return window;
}
private void ConfigureLogging() private void ConfigureLogging()
{ {
var loggerFactory = LoggerFactory.Create(builder => var loggerFactory = LoggerFactory.Create(builder =>
......
...@@ -22,11 +22,19 @@ namespace Robobin.Models ...@@ -22,11 +22,19 @@ namespace Robobin.Models
public class Graph public class Graph
{ {
public string Name { get; set; }
public List<Node> Nodes { get; set; } public List<Node> Nodes { get; set; }
public (float magnitude, float angle)[,] AdjacencyMatrix { get; set; } public (float magnitude, float angle)[,] AdjacencyMatrix { get; set; }
public Graph(string name, List<Node> nodes, (float, float)[,] adjacencyMatrix)
{
Name = name;
Nodes = nodes;
AdjacencyMatrix = adjacencyMatrix;
}
public Graph( List<Node> nodes, (float, float)[,] adjacencyMatrix) public Graph( List<Node> nodes, (float, float)[,] adjacencyMatrix)
{ {
Name = "Graph";
Nodes = nodes; Nodes = nodes;
AdjacencyMatrix = adjacencyMatrix; AdjacencyMatrix = adjacencyMatrix;
} }
......
using System.Collections.ObjectModel;
using System.ComponentModel; using System.ComponentModel;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using System.Windows.Input; using System.Windows.Input;
...@@ -14,31 +15,120 @@ namespace RobobinApp.ViewModels ...@@ -14,31 +15,120 @@ namespace RobobinApp.ViewModels
{ {
private bool _isBusy; private bool _isBusy;
private string _statusMessage; private string _statusMessage;
public Graph Graph { get; private set; }
public ICommand ConnectToRobobinCommand { get; } public ICommand ConnectToRobobinCommand { get; }
private Graph _selectedGraph;
public ObservableCollection<Graph> Graphs { get; }
public ICommand SelectGraphCommand { get; }
public Graph Graph
{
get => _selectedGraph;
set
{
_selectedGraph = value;
OnPropertyChanged();
}
}
public ObservableCollection<string> GraphNames { get; }
public MainPageViewModel() public MainPageViewModel()
{ {
ConnectToRobobinCommand = new Command(async () => await OnConnectToRobobin()); ConnectToRobobinCommand = new Command(async () => await OnConnectToRobobin());
SelectGraphCommand = new Command<int>(OnSelectGraph);
var graphNodes1 = new List<Node>
{
new Node("A", 50, 50),
new Node("B", 150, 50),
new Node("C", 250, 50),
new Node("Home", 350, 50),
new Node("E", 50, 150),
new Node("F", 150, 150),
new Node("G", 250, 150),
new Node("H", 350, 150),
new Node("I", 50, 250),
new Node("J", 150, 250),
new Node("K", 250, 250),
new Node("L", 350, 250),
new Node("M", 50, 350),
new Node("N", 150, 350),
new Node("O", 350, 350)
};
// Create nodes with X and Y coordinates var graphMatrix1 = CalculatePolarConnections(graphNodes1, new bool[,]
var nodes = new List<Node>
{ {
new Node("N1", 100, 100), // Example coordinates { false, true, false, false, true, false, false, false, false, false, false, false, false, false, false },
new Node("N2", 200, 100), { true, false, true, false, false, true, false, false, false, false, false, false, false, false, false },
new Node("N3", 150, 200), { false, true, false, true, false, false, true, false, false, false, false, false, false, false, false },
{ false, false, true, false, false, false, false, true, false, false, false, false, false, false, true },
{ true, false, false, false, false, true, false, false, true, false, false, false, false, false, false },
{ false, true, false, false, true, false, true, false, false, true, false, false, false, false, false },
{ false, false, true, false, false, true, false, true, false, false, true, false, false, false, false },
{ false, false, false, true, false, false, true, false, false, false, false, true, false, false, false },
{ false, false, false, false, true, false, false, false, false, true, false, false, true, false, false },
{ false, false, false, false, false, true, false, false, true, false, true, false, false, true, false },
{ false, false, false, false, false, false, true, false, false, true, false, true, false, false, false },
{ false, false, false, false, false, false, false, true, false, false, true, false, false, false, true },
{ false, false, false, false, false, false, false, false, true, false, false, false, false, true, false },
{ false, false, false, false, false, false, false, false, false, true, false, false, true, false, true },
{ false, false, false, true, false, false, false, false, false, false, false, true, false, true, false }
});
var graph1 = new Graph("Lab 1", graphNodes1, graphMatrix1);
var graph2Nodes = new List<Node>
{
new Node("Home", 50, 50),
new Node("B", 250, 50),
new Node("C", 150, 150),
new Node("D", 150, 300)
}; };
var graph2Matrix = CalculatePolarConnections(graph2Nodes, new bool[,]
{
{ false, true, true, false },
{ true, false, true, true },
{ true, true, false, true },
{ false, true, true, false }
});
var graph2 = new Graph("Lab 2",graph2Nodes, graph2Matrix);
// Create an empty adjacency matrix for three nodes var graph3Nodes = new List<Node>
var adjacencyMatrix = new (float, float)[,]
{ {
{ (0, 0), (100, 0), (111.80f, 63.44f) }, new Node("X", 75, 75),
{ (100, 180), (0, 0), (111.80f, 116.57f) }, new Node("Home", 300, 75),
{ (111.80f, -116.56f), (111.80f, -63.43f), (0, 0) } new Node("Z", 200, 250)
}; };
var graph3Matrix = CalculatePolarConnections(graph3Nodes, new bool[,]
{
{ false, true, true },
{ true, false, true },
{ true, true, false }
});
var graph3 = new Graph("Lab3", graph3Nodes, graph3Matrix);
// Create graph
Graph = new Graph(nodes, adjacencyMatrix);
// Add graphs to collection
Graphs = new ObservableCollection<Graph> { graph1, graph2, graph3 };
GraphNames = new ObservableCollection<string>(Graphs.Select(g => g.Name)); // Create list of names
Graph = Graphs.First();
}
private void OnSelectGraph(int graphIndex)
{
if (graphIndex >= 0 && graphIndex < Graphs.Count)
{
Graph = Graphs[graphIndex];
}
} }
public static (float magnitude, float angle)[,] CalculatePolarConnections(List<Node> nodes, bool[,] connections) public static (float magnitude, float angle)[,] CalculatePolarConnections(List<Node> nodes, bool[,] connections)
{ {
......
...@@ -8,7 +8,6 @@ namespace RobobinApp.Views ...@@ -8,7 +8,6 @@ namespace RobobinApp.Views
{ {
private Graph _graph; private Graph _graph;
// Method to set the graph data
public void SetGraph(Graph graph) public void SetGraph(Graph graph)
{ {
_graph = graph; _graph = graph;
...@@ -18,39 +17,67 @@ namespace RobobinApp.Views ...@@ -18,39 +17,67 @@ namespace RobobinApp.Views
{ {
if (_graph == null) return; if (_graph == null) return;
// Set the background color
canvas.FillColor = Colors.LightPink; canvas.FillColor = Color.FromHex("#2C2F33");
canvas.FillRectangle(dirtyRect); canvas.FillRectangle(dirtyRect);
// Draw nodes and edges
const float nodeRadius = 10; // Radius for nodes float minX = _graph.Nodes.Min(node => node.X);
float minY = _graph.Nodes.Min(node => node.Y);
float maxX = _graph.Nodes.Max(node => node.X);
float maxY = _graph.Nodes.Max(node => node.Y);
float graphWidth = maxX - minX;
float graphHeight = maxY - minY;
float scaleX = dirtyRect.Width / graphWidth;
float scaleY = dirtyRect.Height / graphHeight;
float scale = Math.Min(scaleX, scaleY) * 0.8f;
float offsetX = dirtyRect.Center.X - ((minX + maxX) * 0.5f) * scale;
float offsetY = dirtyRect.Center.Y - ((minY + maxY) * 0.5f) * scale;
const float baseNodeRadius = 5;
float nodeRadius = baseNodeRadius * scale;
foreach (var node in _graph.Nodes) foreach (var node in _graph.Nodes)
{ {
// Draw the node
canvas.FillColor = Colors.Red;
canvas.FillCircle(node.X, node.Y, nodeRadius);
canvas.DrawString(node.Name, node.X + 12, node.Y - 5, HorizontalAlignment.Left);
// Draw edges based on the adjacency matrix
for (int j = 0; j < _graph.Nodes.Count; j++) for (int j = 0; j < _graph.Nodes.Count; j++)
{ {
var (magnitude, angle) = _graph.AdjacencyMatrix[_graph.Nodes.IndexOf(node), j]; var (magnitude, angle) = _graph.AdjacencyMatrix[_graph.Nodes.IndexOf(node), j];
// Only draw if there's a valid connection (magnitude > 0)
if (magnitude > 0) if (magnitude > 0)
{ {
// Calculate the target node's coordinates based on the angle and magnitude
float targetX = node.X + magnitude * MathF.Cos(MathF.PI * (angle / 180));
float targetY = node.Y + magnitude * MathF.Sin(MathF.PI * (angle / 180));
// Draw edge float targetX = (node.X + magnitude * MathF.Cos(MathF.PI * angle / 180)) * scale + offsetX;
canvas.StrokeColor = Colors.Black; float targetY = (node.Y + magnitude * MathF.Sin(MathF.PI * angle / 180)) * scale + offsetY;
canvas.StrokeColor = Colors.Grey;
canvas.StrokeSize = 2; canvas.StrokeSize = 2;
canvas.DrawLine(node.X, node.Y, targetX, targetY); // Draw edge canvas.DrawLine(node.X * scale + offsetX, node.Y * scale + offsetY, targetX, targetY);
} }
} }
} }
// Draw nodes
foreach (var node in _graph.Nodes)
{
float scaledX = node.X * scale + offsetX;
float scaledY = node.Y * scale + offsetY;
canvas.FillColor = Colors.Red;
if (node.Name == "Home")
{
canvas.FillColor = Colors.Green;
}
canvas.FillCircle(scaledX, scaledY, nodeRadius);
canvas.FontColor = Colors.White;
canvas.DrawString(node.Name, scaledX + nodeRadius + 2, scaledY - nodeRadius, HorizontalAlignment.Left);
} }
} }
}
} }
...@@ -44,9 +44,8 @@ ...@@ -44,9 +44,8 @@
HorizontalOptions="FillAndExpand" HorizontalOptions="FillAndExpand"
VerticalOptions="FillAndExpand" VerticalOptions="FillAndExpand"
Grid.Column="1" Grid.Row="0"> Grid.Column="1" Grid.Row="0">
<GraphicsView Drawable="{StaticResource drawable}" <GraphicsView x:Name="GraphicsView"
HeightRequest="300" Drawable="{StaticResource drawable}" />
WidthRequest="400" />
</Frame> </Frame>
<VerticalStackLayout StyleClass="sideFrame" <VerticalStackLayout StyleClass="sideFrame"
...@@ -55,6 +54,12 @@ ...@@ -55,6 +54,12 @@
Grid.Column="2" Grid.Row="0"> Grid.Column="2" Grid.Row="0">
<HorizontalStackLayout HorizontalOptions="Start" VerticalOptions="End"> <HorizontalStackLayout HorizontalOptions="Start" VerticalOptions="End">
<Button Text="Info" /> <Button Text="Info" />
<Picker Title="Select Graph"
ItemsSource="{Binding GraphNames}"
SelectedIndexChanged="OnGraphSelected"
HorizontalOptions="Center" />
</HorizontalStackLayout> </HorizontalStackLayout>
<local:SideBox HeaderTitle="Mode:" /> <local:SideBox HeaderTitle="Mode:" />
<local:SideBox HeaderTitle="Admin:" /> <local:SideBox HeaderTitle="Admin:" />
......
using Microsoft.Maui.Controls; using Microsoft.Maui.Controls;
using RobobinApp.ViewModels; using RobobinApp.ViewModels;
using RobobinApp.Models; using RobobinApp.Models;
using System.Diagnostics;
namespace RobobinApp.Views namespace RobobinApp.Views
{ {
...@@ -19,5 +20,24 @@ namespace RobobinApp.Views ...@@ -19,5 +20,24 @@ namespace RobobinApp.Views
drawable.SetGraph(viewModel.Graph); drawable.SetGraph(viewModel.Graph);
} }
} }
private void OnGraphSelected(object sender, EventArgs e)
{
if (sender is Picker picker && BindingContext is MainPageViewModel viewModel)
{
// Update the selected graph
viewModel.SelectGraphCommand.Execute(picker.SelectedIndex);
// Refresh the drawable with the new graph
var drawable = (GraphicsDrawable)Resources["drawable"];
var newGraph = viewModel.Graphs.FirstOrDefault(g => g.Name == viewModel.Graph.Name);
drawable.SetGraph(newGraph);
// Invalidate the GraphicsView to redraw the updated graph
GraphicsView.Invalidate();
Debug.WriteLine("New Graph picked and drawn");
}
}
} }
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment