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
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()
{
var loggerFactory = LoggerFactory.Create(builder =>
......
......@@ -22,11 +22,19 @@ namespace Robobin.Models
public class Graph
{
public string Name { get; set; }
public List<Node> Nodes { get; set; }
public (float magnitude, float angle)[,] AdjacencyMatrix { get; set; }
public Graph(List<Node> nodes, (float, float)[,] adjacencyMatrix)
public Graph(string name, List<Node> nodes, (float, float)[,] adjacencyMatrix)
{
Name = name;
Nodes = nodes;
AdjacencyMatrix = adjacencyMatrix;
}
public Graph( List<Node> nodes, (float, float)[,] adjacencyMatrix)
{
Name = "Graph";
Nodes = nodes;
AdjacencyMatrix = adjacencyMatrix;
}
......
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Windows.Input;
......@@ -14,31 +15,120 @@ namespace RobobinApp.ViewModels
{
private bool _isBusy;
private string _statusMessage;
public Graph Graph { get; private set; }
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()
{
ConnectToRobobinCommand = new Command(async () => await OnConnectToRobobin());
SelectGraphCommand = new Command<int>(OnSelectGraph);
// Create nodes with X and Y coordinates
var nodes = new List<Node>
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)
};
var graphMatrix1 = CalculatePolarConnections(graphNodes1, new bool[,]
{
new Node("N1", 100, 100), // Example coordinates
new Node("N2", 200, 100),
new Node("N3", 150, 200),
};
{ false, true, false, false, true, false, false, false, false, false, false, false, false, false, false },
{ true, false, true, false, false, true, false, false, false, false, false, false, false, false, false },
{ 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);
// Create an empty adjacency matrix for three nodes
var adjacencyMatrix = new (float, float)[,]
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);
var graph3Nodes = new List<Node>
{
new Node("X", 75, 75),
new Node("Home", 300, 75),
new Node("Z", 200, 250)
};
var graph3Matrix = CalculatePolarConnections(graph3Nodes, new bool[,]
{
{ (0, 0), (100, 0), (111.80f, 63.44f) },
{ (100, 180), (0, 0), (111.80f, 116.57f) },
{ (111.80f, -116.56f), (111.80f, -63.43f), (0, 0) }
};
{ 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)
{
......
......@@ -8,7 +8,6 @@ namespace RobobinApp.Views
{
private Graph _graph;
// Method to set the graph data
public void SetGraph(Graph graph)
{
_graph = graph;
......@@ -18,39 +17,67 @@ namespace RobobinApp.Views
{
if (_graph == null) return;
// Set the background color
canvas.FillColor = Colors.LightPink;
canvas.FillColor = Color.FromHex("#2C2F33");
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)
{
// 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++)
{
var (magnitude, angle) = _graph.AdjacencyMatrix[_graph.Nodes.IndexOf(node), j];
// Only draw if there's a valid connection (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
canvas.StrokeColor = Colors.Black;
float targetX = (node.X + magnitude * MathF.Cos(MathF.PI * angle / 180)) * scale + offsetX;
float targetY = (node.Y + magnitude * MathF.Sin(MathF.PI * angle / 180)) * scale + offsetY;
canvas.StrokeColor = Colors.Grey;
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 @@
HorizontalOptions="FillAndExpand"
VerticalOptions="FillAndExpand"
Grid.Column="1" Grid.Row="0">
<GraphicsView Drawable="{StaticResource drawable}"
HeightRequest="300"
WidthRequest="400" />
<GraphicsView x:Name="GraphicsView"
Drawable="{StaticResource drawable}" />
</Frame>
<VerticalStackLayout StyleClass="sideFrame"
......@@ -55,6 +54,12 @@
Grid.Column="2" Grid.Row="0">
<HorizontalStackLayout HorizontalOptions="Start" VerticalOptions="End">
<Button Text="Info" />
<Picker Title="Select Graph"
ItemsSource="{Binding GraphNames}"
SelectedIndexChanged="OnGraphSelected"
HorizontalOptions="Center" />
</HorizontalStackLayout>
<local:SideBox HeaderTitle="Mode:" />
<local:SideBox HeaderTitle="Admin:" />
......
using Microsoft.Maui.Controls;
using RobobinApp.ViewModels;
using RobobinApp.Models;
using RobobinApp.Models;
using System.Diagnostics;
namespace RobobinApp.Views
{
......@@ -19,5 +20,24 @@ namespace RobobinApp.Views
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.
Finish editing this message first!
Please register or to comment