Visual Graph Playground – A Python Desktop App for Dragging, Connecting, and Editing Graphs
Visual Graph Playground – A Python Desktop App for Dragging, Connecting, and Editing Graphs
Graph theory becomes much easier to understand when you can interact directly with nodes and edges. That is exactly what the Visual Graph Playground desktop app provides — a clean, interactive environment where you can drag nodes, connect edges, delete elements, and visually build graphs in real time.
This Python-powered desktop tool is perfect for:
-
Students learning graph theory
-
Teachers demonstrating concepts
-
Researchers modeling networks
-
Developers prototyping algorithms
-
Anyone who wants a visual and interactive graph editor
In this blog, we explore the features, working, and benefits of the Visual Graph Playground so you can start using it immediately.
🌟 What is the Visual Graph Playground?
The Visual Graph Playground is a desktop application built in Python using Tkinter, which allows users to create and manipulate graphs using an intuitive visual interface. Whether you want to design a small network or create complex graph structures, the app offers all the essential features needed for hands-on learning.
Unlike static drawing tools, this app updates the graph dynamically as you drag or connect nodes, making it ideal for experimenting and understanding how real graphs behave.
✨ Key Features of the App
✔ 1. Drag-and-Drop Nodes
You can move any node by simply clicking and dragging it.
The graph updates instantly, allowing you to rearrange your layout effortlessly.
✔ 2. Add Nodes Anywhere
Click anywhere on the canvas or use the Add Node button to create new nodes.
Each node is automatically labeled and positioned cleanly.
✔ 3. Connect Nodes by Dragging
To create an edge, just drag one node onto another.
The app draws a smooth line representing the connection.
✔ 4. Delete Nodes & Edges Easily
-
Right-click a node → it is deleted
-
Right-click an edge → it gets removed
This makes it easy to clean or reorganize the graph at any stage.
✔ 5. Real-Time Graph Visualization
Every change — adding, moving, or deleting nodes/edges — instantly updates the drawing.
This helps users clearly understand how graph structures evolve.
✔ 6. Save Your Graphs
With the Save Graph option, the entire graph (nodes + edges) is exported into a JSON file.
You can open it later for editing or reuse.
✔ 7. Load Previously Saved Graphs
Use the Load Graph button to import a saved JSON file and continue working on your project.
✔ 8. Clean and User-Friendly Interface
The app window includes:
-
A large canvas for drawing
-
Buttons for common features
-
Smooth movement and interaction
-
A helpful pop-up explaining all controls
This makes learning graph theory fun, visual, and intuitive.
🧠 How the Graph Playground Works
The entire graph is modeled using two main structures:
-
Nodes → A dictionary storing each node’s label and coordinates
-
Edges → A list of node-to-node connections
When you drag, connect, delete, or rearrange nodes, the system updates these structures and redraws the visual layout instantly.
It uses basic geometry and Tkinter’s drawing tools to create:
-
Circles for nodes
-
Lines for edges
-
Labels for node IDs
This makes the graph clear and easy to understand.
🖥️ Technologies Used
The app is built using:
-
Python
-
Tkinter (for GUI)
-
JSON (for saving files)
-
Math utilities (for collision detection & drag interactions)
No external libraries are required, making it easy to run on any computer with Python installed.
📌 How to Run the App
Step 1 — Install Python
Make sure Python 3.x is installed.
Step 2 — Save the App File
Create a Python file in Visual Studio Code named:
Paste the complete code.
Step 3 — Run the App
Inside VS Code terminal:
The app window will open immediately.
🎯 Who Should Use This Tool?
This app is perfect for:
👨🎓 Students
Practice graph concepts like nodes, edges, connectivity, and network design.
👩🏫 Teachers
Demonstrate graph theory visually to make learning easier.
👨💻 Developers
Prototype graph layouts before writing algorithms.
🔬 Researchers
Model network problems visually before running experiments.
🚀 Future Feature Possibilities
If you want additional features, they can be added easily:
-
Shortest path highlighting
-
Weighted edges
-
Graph coloring
-
Export as image
-
NetworkX compatibility
-
Algorithm visualization (DFS, BFS, Dijkstra)
-
Undo / Redo functionality
Just let me know, and I can upgrade your app.
🎉 Final Thoughts
The Visual Graph Playground is a powerful yet simple desktop tool that makes graph theory interactive and enjoyable. Whether you are learning, teaching, researching, or experimenting, this app provides a hands-on way to build and understand graphs visually.
import tkinter as tk
from tkinter import messagebox, filedialog
import json
import math
class VisualGraphPlayground:
def __init__(self, root):
self.root = root
self.root.title("Visual Graph Playground – Drag & Connect Nodes")
# Canvas
self.canvas = tk.Canvas(root, width=900, height=600, bg="white")
self.canvas.pack(fill="both", expand=True)
# Graph data
self.nodes = {} # node_id : (x, y)
self.edges = [] # list of (node1, node2)
self.node_radius = 22
# Dragging variables
self.dragging_node = None
# UI Buttons
frame = tk.Frame(root)
frame.pack()
tk.Button(frame, text="Add Node", command=self.add_node).grid(row=0, column=0)
tk.Button(frame, text="Clear All", command=self.clear_graph).grid(row=0, column=1)
tk.Button(frame, text="Save Graph", command=self.save_graph).grid(row=0, column=2)
tk.Button(frame, text="Load Graph", command=self.load_graph).grid(row=0, column=3)
# Canvas Events
self.canvas.bind("<Button-1>", self.canvas_click)
self.canvas.bind("<B1-Motion>", self.drag_node)
self.canvas.bind("<ButtonRelease-1>", self.release_node)
# Show help popup ONCE
self.show_help_popup()
# ---------------------------- HELP POPUP ----------------------------
def show_help_popup(self):
messagebox.showinfo(
"How to Use",
"Left Click = Select / Move Node\n"
"Click empty area = Add Node (or use button)\n"
"Drag Node = Move it\n"
"Drag from one node to another = Connect Edge\n"
"Right Click Node = Delete Node\n"
"Right Click Edge line = Delete Edge\n"
"Use Save / Load buttons to save or restore graphs"
)
# ---------------------------- NODE MANAGEMENT ----------------------------
def add_node(self, x=None, y=None):
if x is None or y is None:
x = 100 + len(self.nodes) * 40
y = 100 + len(self.nodes) * 20
node_id = f"N{len(self.nodes)+1}"
self.nodes[node_id] = (x, y)
self.draw_graph()
def delete_node(self, node_id):
self.nodes.pop(node_id)
self.edges = [
(u, v) for (u, v) in self.edges if u != node_id and v != node_id
]
self.draw_graph()
# ---------------------------- EDGE MANAGEMENT ----------------------------
def add_edge(self, n1, n2):
if n1 != n2 and (n1, n2) not in self.edges and (n2, n1) not in self.edges:
self.edges.append((n1, n2))
self.draw_graph()
def delete_edge(self, edge):
self.edges.remove(edge)
self.draw_graph()
# ---------------------------- GRAPH DRAWING ----------------------------
def draw_graph(self):
self.canvas.delete("all")
# Draw Edges First
for (u, v) in self.edges:
x1, y1 = self.nodes[u]
x2, y2 = self.nodes[v]
line = self.canvas.create_line(x1, y1, x2, y2, width=3, fill="gray")
self.canvas.tag_bind(line, "<Button-3>", lambda e, edge=(u, v): self.delete_edge(edge))
# Draw Nodes
for node_id, (x, y) in self.nodes.items():
oval = self.canvas.create_oval(
x - self.node_radius, y - self.node_radius,
x + self.node_radius, y + self.node_radius,
fill="skyblue", outline="black", width=2
)
text = self.canvas.create_text(x, y, text=node_id)
# Bind right-click to delete node
self.canvas.tag_bind(oval, "<Button-3>", lambda e, nid=node_id: self.delete_node(nid))
self.canvas.tag_bind(text, "<Button-3>", lambda e, nid=node_id: self.delete_node(nid))
# ---------------------------- INTERACTION ----------------------------
def canvas_click(self, event):
clicked_node = self.get_node_at(event.x, event.y)
if clicked_node:
self.dragging_node = clicked_node
else:
self.add_node(event.x, event.y)
def drag_node(self, event):
if self.dragging_node:
self.nodes[self.dragging_node] = (event.x, event.y)
self.draw_graph()
def release_node(self, event):
if not self.dragging_node:
return
release_on = self.get_node_at(event.x, event.y)
if release_on and release_on != self.dragging_node:
self.add_edge(self.dragging_node, release_on)
self.dragging_node = None
# ---------------------------- NODE DETECTION ----------------------------
def get_node_at(self, x, y):
for node_id, (nx, ny) in self.nodes.items():
if math.dist((x, y), (nx, ny)) <= self.node_radius:
return node_id
return None
# ---------------------------- SAVE / LOAD ----------------------------
def save_graph(self):
file_path = filedialog.asksaveasfilename(defaultextension=".json")
if not file_path:
return
data = {"nodes": self.nodes, "edges": self.edges}
with open(file_path, "w") as f:
json.dump(data, f)
messagebox.showinfo("Saved", "Graph saved successfully!")
def load_graph(self):
file_path = filedialog.askopenfilename(filetypes=[("JSON Files", "*.json")])
if not file_path:
return
with open(file_path, "r") as f:
data = json.load(f)
self.nodes = {k: tuple(v) for k, v in data["nodes"].items()}
self.edges = data["edges"]
self.draw_graph()
# ---------------------------- CLEAR GRAPH ----------------------------
def clear_graph(self):
self.nodes.clear()
self.edges.clear()
self.draw_graph()
# ---------------------------- MAIN ----------------------------
def main():
root = tk.Tk()
app = VisualGraphPlayground(root)
root.mainloop()
if __name__ == "__main__":
main()
Comments
Post a Comment