A dead branch of implementing the visualisation
We need more object-oriented approach to make this manageable. Keeping this for reference.visu_broken
parent
c500a97fa6
commit
b564a01e82
@ -0,0 +1,133 @@
|
||||
from birdvisu.maps import Topology, TopologyDifference
|
||||
|
||||
from PySide6 import QtCore, QtGui, QtWidgets
|
||||
|
||||
from dataclasses import dataclass
|
||||
from enum import Enum, auto
|
||||
|
||||
class NodeType(Enum):
|
||||
ROUTER = auto()
|
||||
NETWORK = auto()
|
||||
|
||||
class NodeStatus(Enum):
|
||||
NORMAL = auto()
|
||||
MISSING = auto()
|
||||
EXTRA = auto()
|
||||
DISCREPANCY = auto()
|
||||
|
||||
@dataclass
|
||||
class VisualisationNode:
|
||||
position: tuple[float, float]
|
||||
type: NodeType
|
||||
status: NodeStatus
|
||||
details: tuple[str, list]
|
||||
|
||||
def draw_on_scene(self, scene):
|
||||
# FIXME: Allow different styles
|
||||
# TODO: not everything is a QRectF…
|
||||
x, y = self.position
|
||||
fill = QtGui.QBrush(QtGui.QColor(
|
||||
{
|
||||
# Poor man's switch
|
||||
# Py 3.10 might be too new and this is probably more compact still.
|
||||
NodeStatus.NORMAL: 'black',
|
||||
NodeStatus.MISSING: 'red',
|
||||
NodeStatus.EXTRA: 'green',
|
||||
NodeStatus.DISCREPANCY: 'blue',
|
||||
}[self.status]
|
||||
))
|
||||
w, h = {
|
||||
NodeType.ROUTER: (40, 40),
|
||||
NodeType.NETWORK: (10, 10),
|
||||
}[self.type]
|
||||
return scene.addRect(
|
||||
QtCore.QRectF(x, y, w, h),
|
||||
brush = fill,
|
||||
)
|
||||
|
||||
|
||||
|
||||
def nodes_from_topodiff(topodiff, visu_style='default') -> list[VisualisationNode]:
|
||||
result = []
|
||||
|
||||
def get_node(dir_tuple, type):
|
||||
n, nd = dir_tuple
|
||||
visu_details = list(filter(lambda x: x[0] == ('visualisation '+visu_style), nd))
|
||||
if len(visu_details) > 1:
|
||||
visu_details = visu_details[0][1]
|
||||
det_dict = {}
|
||||
for det in visu_details:
|
||||
k, v = det.split(' ', maxxplit=1)
|
||||
det_dict[k] = v
|
||||
pos = det_dict['position']
|
||||
x, y = map(float, pos.strip('[]').split())
|
||||
else:
|
||||
# Probably an extra node
|
||||
# TODO: proper automatic placement
|
||||
import random
|
||||
x = random.randint(0, 2000) # FIXME: dimensions?
|
||||
y = random.randint(0, 2000)
|
||||
return VisualisationNode(
|
||||
position = (x, y),
|
||||
type = type,
|
||||
status = NodeStatus.NORMAL, # Will change in a while
|
||||
details = dir_tuple,
|
||||
)
|
||||
|
||||
for r in topodiff.reference.routers:
|
||||
node = get_node(r, type=NodeType.ROUTER)
|
||||
if r[0] in topodiff.routers_missing:
|
||||
node.status = NodeStatus.MISSING
|
||||
result.append(node)
|
||||
|
||||
for n in topodiff.reference.networks:
|
||||
node = get_node(n, type=NodeType.NETWORK)
|
||||
if n[0] in topodiff.networks_missing:
|
||||
node.status = NodeStatus.MISSING
|
||||
result.append(node)
|
||||
|
||||
for r in topodiff.actual.routers:
|
||||
if r[0] in topodiff.routers_extra:
|
||||
node = get_node(r, type=NodeType.ROUTER)
|
||||
node.status = NodeStatus.EXTRA
|
||||
result.append(node)
|
||||
|
||||
for n in topodiff.actual.networks:
|
||||
if n[0] in topodiff.networks_extra:
|
||||
node = get_node(n, type=NodeType.NETWORK)
|
||||
node.status = NodeStatus.EXTRA
|
||||
result.append(node)
|
||||
|
||||
return result
|
||||
|
||||
|
||||
class Visualisation(QtWidgets.QWidget):
|
||||
def __init__(self, topodiff=None):
|
||||
super().__init__()
|
||||
|
||||
# guard:
|
||||
self.scene = None
|
||||
self.view = None
|
||||
self.topodiff = None
|
||||
self.items_nodes = None
|
||||
self.items_edges = None
|
||||
|
||||
if topodiff is not None:
|
||||
self.set_topology_difference(topodiff)
|
||||
|
||||
def set_topology_difference(self, topodiff):
|
||||
self.topodiff = topodiff
|
||||
self.draw_scene()
|
||||
|
||||
def draw_scene(self):
|
||||
self.scene = QtWidgets.QGraphicsScene(self)
|
||||
self.view = QtWidgets.QGraphicsView(self.scene)
|
||||
|
||||
if self.topodiff is not None:
|
||||
nodes = nodes_from_topodiff(self.topodiff)
|
||||
# TODO: filtering (dependent on UI)
|
||||
if self.items_nodes is None:
|
||||
self.items_nodes = {} # dict: ident -> QGraphicsItem
|
||||
for n in nodes:
|
||||
assert n.details[0] not in self.items_nodes, f'{n.details} already in dictionary'
|
||||
self.items_nodes[n.details[0]] = n.draw_on_scene(self.scene)
|
Loading…
Reference in New Issue