Simon Hunt

GUI - reworked to allow for event-based topology building, in preparation for we…

…b-socket connection to the server.
 - device nodes will enter in a fixed location, if metaUi data is included in the addDevice event.
 - device nodes now adjust their bounds to fit the text (and show an icon).
 - added cycle labels function (press the 'L' key).
 - links now appear with "transition" animation.
 NOTE: this is still WIP.

Change-Id: I3adbe9895e189e482316e86384dd53fd27781cd3
Showing 42 changed files with 918 additions and 2035 deletions
{
"event": "addDevice",
"payload": {
"id": "of:0000ffffffffff08",
"type": "roadm",
"online": false,
"labels": [
"0000ffffffffff08",
"FF:FF:FF:FF:FF:08",
"?"
],
"metaUi": {
"x": 539,
"y": 186
}
}
}
{
"event": "addDevice",
"payload": {
"id": "of:0000ffffffffff04",
"type": "roadm",
"online": false,
"labels": [
"0000ffffffffff04",
"FF:FF:FF:FF:FF:04",
"?"
],
"metaUi": {
"x": 322,
"y": 138
}
}
}
{
"event": "addDevice",
"payload": {
"id": "of:0000ffffffff000A",
"type": "switch",
"online": false,
"labels": [
"0000ffffffff000A",
"FF:FF:FF:FF:00:0A",
"?"
],
"metaUi": {
"x": 832,
"y": 223
}
}
}
{
"event": "addDevice",
"payload": {
"id": "of:0000ffffffff0001",
"type": "switch",
"online": false,
"labels": [
"0000ffffffff0001",
"FF:FF:FF:FF:00:01",
"?"
],
"metaUi": {
"x": 167,
"y": 403
}
}
}
{
"event": "addDevice",
"payload": {
"id": "of:0000ffffffffff01",
"type": "roadm",
"online": false,
"labels": [
"0000ffffffffff01",
"FF:FF:FF:FF:FF:01",
"?"
],
"metaUi": {
"x": 227,
"y": 460
}
}
}
{
"event": "addDevice",
"payload": {
"id": "of:0000ffffffff0004",
"type": "switch",
"online": false,
"labels": [
"0000ffffffff0004",
"FF:FF:FF:FF:00:04",
"?"
],
"metaUi": {
"x": 317,
"y": 73
}
}
}
{
"event": "addDevice",
"payload": {
"id": "of:0000ffffffffff0A",
"type": "roadm",
"online": false,
"labels": [
"0000ffffffffff0A",
"FF:FF:FF:FF:FF:0A",
"?"
],
"metaUi": {
"x": 840,
"y": 290
}
}
}
{
"event": "addDevice",
"payload": {
"id": "of:0000ffffffffff09",
"type": "roadm",
"online": false,
"labels": [
"0000ffffffffff09",
"FF:FF:FF:FF:FF:09",
"?"
],
"metaUi": {
"x": 1010,
"y": 229
}
}
}
{
"event": "addLink",
"payload": {
"src": "of:0000ffffffffff02",
"srcPort": "20",
"dst": "of:0000ffffffffff05",
"dstPort": "10",
"type": "optical",
"linkWidth": 2,
"props" : {
"BW": "80 G"
}
}
}
{
"event": "addLink",
"payload": {
"src": "of:0000ffffffff000A",
"srcPort": "2",
"dst": "of:0000ffffffffff0A",
"dstPort": "1",
"type": "optical",
"linkWidth": 2,
"props" : {
"BW": "100 G"
}
}
}
{
"event": "addLink",
"payload": {
"src": "of:0000ffffffffff03",
"srcPort": "10",
"dst": "of:0000ffffffffff02",
"dstPort": "10",
"type": "optical",
"linkWidth": 2,
"props" : {
"BW": "70 G"
}
}
}
{
"event": "addDevice",
"payload": {
"id": "of:0000ffffffffff03",
"type": "roadm",
"online": false,
"labels": [
"0000ffffffffff03",
"FF:FF:FF:FF:FF:03",
"?"
],
"metaUi": {
"x": 95,
"y": 225
}
}
}
{
"event": "addLink",
"payload": {
"src": "of:0000ffffffffff07",
"srcPort": "21",
"dst": "of:0000ffffffffff05",
"dstPort": "20",
"type": "optical",
"linkWidth": 2,
"props" : {
"BW": "70 G"
}
}
}
{
"event": "addLink",
"payload": {
"src": "of:0000ffffffff0001",
"srcPort": "2",
"dst": "of:0000ffffffffff01",
"dstPort": "1",
"type": "optical",
"linkWidth": 2,
"props" : {
"BW": "70 G"
}
}
}
{
"event": "addLink",
"payload": {
"src": "of:0000ffffffffff09",
"srcPort": "20",
"dst": "of:0000ffffffffff0A",
"dstPort": "20",
"type": "optical",
"linkWidth": 2,
"props" : {
"BW": "70 G"
}
}
}
{
"event": "addLink",
"payload": {
"src": "of:0000ffffffffff06",
"srcPort": "20",
"dst": "of:0000ffffffffff05",
"dstPort": "30",
"type": "optical",
"linkWidth": 2,
"props" : {
"BW": "70 G"
}
}
}
{
"event": "addLink",
"payload": {
"src": "of:0000ffffffffff07",
"srcPort": "30",
"dst": "of:0000ffffffffff08",
"dstPort": "20",
"type": "optical",
"linkWidth": 2,
"props" : {
"BW": "70 G"
}
}
}
{
"event": "addLink",
"payload": {
"src": "of:0000ffffffffff03",
"srcPort": "20",
"dst": "of:0000ffffffffff06",
"dstPort": "10",
"type": "optical",
"linkWidth": 2,
"props" : {
"BW": "70 G"
}
}
}
{
"event": "addLink",
"payload": {
"src": "of:0000ffffffffff02",
"srcPort": "10",
"dst": "of:0000ffffffffff01",
"dstPort": "10",
"type": "optical",
"linkWidth": 2,
"props" : {
"BW": "70 G"
}
}
}
{
"event": "addLink",
"payload": {
"src": "of:0000ffffffffff09",
"srcPort": "1",
"dst": "of:0000ffffffff0009",
"dstPort": "2",
"type": "optical",
"linkWidth": 2,
"props" : {
"BW": "70 G"
}
}
}
{
"event": "addLink",
"payload": {
"src": "of:0000ffffffffff03",
"srcPort": "30",
"dst": "of:0000ffffffffff04",
"dstPort": "10",
"type": "optical",
"linkWidth": 2,
"props" : {
"BW": "70 G"
}
}
}
{
"event": "addLink",
"payload": {
"src": "of:0000ffffffffff07",
"srcPort": "20",
"dst": "of:0000ffffffffff09",
"dstPort": "10",
"type": "optical",
"linkWidth": 2,
"props" : {
"BW": "70 G"
}
}
}
{
"event": "addDevice",
"payload": {
"id": "of:0000ffffffff0007",
"type": "switch",
"online": false,
"labels": [
"0000ffffffff0007",
"FF:FF:FF:FF:00:07",
"?"
],
"metaUi": {
"x": 890,
"y": 375
}
}
}
{
"event": "addLink",
"payload": {
"src": "of:0000ffffffffff0A",
"srcPort": "10",
"dst": "of:0000ffffffffff08",
"dstPort": "30",
"type": "optical",
"linkWidth": 2,
"props" : {
"BW": "70 G"
}
}
}
{
"event": "addLink",
"payload": {
"src": "of:0000ffffffff0004",
"srcPort": "2",
"dst": "of:0000ffffffffff04",
"dstPort": "1",
"type": "optical",
"linkWidth": 2,
"props" : {
"BW": "70 G"
}
}
}
{
"event": "addLink",
"payload": {
"src": "of:0000ffffffffff07",
"srcPort": "1",
"dst": "of:0000ffffffff0007",
"dstPort": "2",
"type": "optical",
"linkWidth": 2,
"props" : {
"BW": "70 G"
}
}
}
{
"event": "addLink",
"payload": {
"src": "of:0000ffffffff0003",
"srcPort": "2",
"dst": "of:0000ffffffffff03",
"dstPort": "1",
"type": "optical",
"linkWidth": 2,
"props" : {
"BW": "70 G"
}
}
}
{
"event": "addLink",
"payload": {
"src": "of:0000ffffffffff06",
"srcPort": "30",
"dst": "of:0000ffffffffff08",
"dstPort": "10",
"type": "optical",
"linkWidth": 2,
"props" : {
"BW": "70 G"
}
}
}
{
"event": "addDevice",
"payload": {
"id": "of:0000ffffffff0009",
"type": "switch",
"online": false,
"labels": [
"0000ffffffff0009",
"FF:FF:FF:FF:00:09",
"?"
],
"metaUi": {
"x": 1004,
"y": 163
}
}
}
{
"event": "addDevice",
"payload": {
"id": "of:0000ffffffffff02",
"type": "roadm",
"online": false,
"labels": [
"0000ffffffffff02",
"FF:FF:FF:FF:FF:02",
"?"
],
"metaUi": {
"x": 211,
"y": 307
}
}
}
{
"event": "addDevice",
"payload": {
"id": "of:0000ffffffff0003",
"type": "switch",
"online": false,
"labels": [
"0000ffffffff0003",
"FF:FF:FF:FF:00:03",
"?"
],
"metaUi": {
"x": 114,
"y": 158
}
}
}
{
"event": "addDevice",
"payload": {
"id": "of:0000ffffffffff07",
"type": "roadm",
"online": false,
"labels": [
"0000ffffffffff07",
"FF:FF:FF:FF:FF:07",
"?"
],
"metaUi": {
"x": 925,
"y": 446
}
}
}
{
"event": "addDevice",
"payload": {
"id": "of:0000ffffffffff06",
"type": "roadm",
"online": false,
"labels": [
"0000ffffffffff06",
"FF:FF:FF:FF:FF:06",
"?"
],
"metaUi": {
"x": 336,
"y": 254
}
}
}
{
"event": "addDevice",
"payload": {
"id": "of:0000ffffffffff05",
"type": "roadm",
"online": false,
"labels": [
"0000ffffffffff05",
"FF:FF:FF:FF:FF:05",
"?"
],
"metaUi": {
"x": 539,
"y": 524
}
}
}
{
"comment": [
"2 links removed from base",
" ff07 - ff09 ",
" ff01 - 0001 "
],
"devices": [
{
"id": "of:0000ffffffffff08",
"type": "roadm",
"online": false,
"labels": [
"0000ffffffffff08",
"FF:FF:FF:FF:FF:08",
"?"
]
},
{
"id": "of:0000ffffffffff03",
"type": "roadm",
"online": false,
"labels": [
"0000ffffffffff03",
"FF:FF:FF:FF:FF:03",
"?"
]
},
{
"id": "of:0000ffffffffff02",
"type": "roadm",
"online": false,
"labels": [
"0000ffffffffff02",
"FF:FF:FF:FF:FF:02",
"?"
]
},
{
"id": "of:0000ffffffff0003",
"type": "switch",
"online": false,
"labels": [
"0000ffffffff0003",
"FF:FF:FF:FF:00:03",
"?"
]
},
{
"id": "of:0000ffffffffff07",
"type": "roadm",
"online": false,
"labels": [
"0000ffffffffff07",
"FF:FF:FF:FF:FF:07",
"?"
]
},
{
"id": "of:0000ffffffffff06",
"type": "roadm",
"online": false,
"labels": [
"0000ffffffffff06",
"FF:FF:FF:FF:FF:06",
"?"
]
},
{
"id": "of:0000ffffffff0007",
"type": "switch",
"online": false,
"labels": [
"0000ffffffff0007",
"FF:FF:FF:FF:00:07",
"?"
]
},
{
"id": "of:0000ffffffffff05",
"type": "roadm",
"online": false,
"labels": [
"0000ffffffffff05",
"FF:FF:FF:FF:FF:05",
"?"
]
},
{
"id": "of:0000ffffffff0009",
"type": "switch",
"online": false,
"labels": [
"0000ffffffff0009",
"FF:FF:FF:FF:00:09",
"?"
]
},
{
"id": "of:0000ffffffffff04",
"type": "roadm",
"online": false,
"labels": [
"0000ffffffffff04",
"FF:FF:FF:FF:FF:04",
"?"
]
},
{
"id": "of:0000ffffffff000A",
"type": "switch",
"online": false,
"labels": [
"0000ffffffff000A",
"FF:FF:FF:FF:00:0A",
"?"
]
},
{
"id": "of:0000ffffffff0001",
"type": "switch",
"online": false,
"labels": [
"0000ffffffff0001",
"FF:FF:FF:FF:00:01",
"?"
]
},
{
"id": "of:0000ffffffffff01",
"type": "roadm",
"online": false,
"labels": [
"0000ffffffffff01",
"FF:FF:FF:FF:FF:01",
"?"
]
},
{
"id": "of:0000ffffffff0004",
"type": "switch",
"online": false,
"labels": [
"0000ffffffff0004",
"FF:FF:FF:FF:00:04",
"?"
]
},
{
"id": "of:0000ffffffffff0A",
"type": "roadm",
"online": false,
"labels": [
"0000ffffffffff0A",
"FF:FF:FF:FF:FF:0A",
"?"
]
},
{
"id": "of:0000ffffffffff09",
"type": "roadm",
"online": false,
"labels": [
"0000ffffffffff09",
"FF:FF:FF:FF:FF:09",
"?"
]
}
],
"links": [
{
"src": "of:0000ffffffffff02",
"srcPort": "20",
"dst": "of:0000ffffffffff05",
"dstPort": "10",
"type": "optical",
"linkWidth": 2
},
{
"src": "of:0000ffffffff000A",
"srcPort": "2",
"dst": "of:0000ffffffffff0A",
"dstPort": "1",
"type": "optical",
"linkWidth": 2
},
{
"src": "of:0000ffffffffff03",
"srcPort": "10",
"dst": "of:0000ffffffffff02",
"dstPort": "10",
"type": "optical",
"linkWidth": 2
},
{
"src": "of:0000ffffffffff07",
"srcPort": "21",
"dst": "of:0000ffffffffff05",
"dstPort": "20",
"type": "optical",
"linkWidth": 2
},
{
"src": "of:0000ffffffffff09",
"srcPort": "20",
"dst": "of:0000ffffffffff0A",
"dstPort": "20",
"type": "optical",
"linkWidth": 2
},
{
"src": "of:0000ffffffffff06",
"srcPort": "20",
"dst": "of:0000ffffffffff05",
"dstPort": "30",
"type": "optical",
"linkWidth": 2
},
{
"src": "of:0000ffffffffff07",
"srcPort": "30",
"dst": "of:0000ffffffffff08",
"dstPort": "20",
"type": "optical",
"linkWidth": 2
},
{
"src": "of:0000ffffffffff03",
"srcPort": "20",
"dst": "of:0000ffffffffff06",
"dstPort": "10",
"type": "optical",
"linkWidth": 2
},
{
"src": "of:0000ffffffffff02",
"srcPort": "10",
"dst": "of:0000ffffffffff01",
"dstPort": "10",
"type": "optical",
"linkWidth": 2
},
{
"src": "of:0000ffffffffff09",
"srcPort": "1",
"dst": "of:0000ffffffff0009",
"dstPort": "2",
"type": "optical",
"linkWidth": 2
},
{
"src": "of:0000ffffffffff03",
"srcPort": "30",
"dst": "of:0000ffffffffff04",
"dstPort": "10",
"type": "optical",
"linkWidth": 2
},
{
"src": "of:0000ffffffffff0A",
"srcPort": "10",
"dst": "of:0000ffffffffff08",
"dstPort": "30",
"type": "optical",
"linkWidth": 2
},
{
"src": "of:0000ffffffff0004",
"srcPort": "2",
"dst": "of:0000ffffffffff04",
"dstPort": "1",
"type": "optical",
"linkWidth": 2
},
{
"src": "of:0000ffffffffff07",
"srcPort": "1",
"dst": "of:0000ffffffff0007",
"dstPort": "2",
"type": "optical",
"linkWidth": 2
},
{
"src": "of:0000ffffffff0003",
"srcPort": "2",
"dst": "of:0000ffffffffff03",
"dstPort": "1",
"type": "optical",
"linkWidth": 2
},
{
"src": "of:0000ffffffffff06",
"srcPort": "30",
"dst": "of:0000ffffffffff08",
"dstPort": "10",
"type": "optical",
"linkWidth": 2
}
],
"hosts": [
{
"id": "00:00:00:00:00:03/-1",
"cp": {
"device": "of:0000ffffffff0003",
"port": 1
},
"labels": [
"10.0.0.3",
"00:00:00:00:00:03"
]
},
{
"id": "00:00:00:00:00:04/-1",
"cp": {
"device": "of:0000ffffffff0004",
"port": 1
},
"labels": [
"10.0.0.4",
"00:00:00:00:00:04"
]
},
{
"id": "00:00:00:00:00:0A/-1",
"cp": {
"device": "of:0000ffffffff000A",
"port": 1
},
"labels": [
"10.0.0.10",
"00:00:00:00:00:0A"
]
},
{
"id": "00:00:00:00:00:09/-1",
"cp": {
"device": "of:0000ffffffff0009",
"port": 1
},
"labels": [
"10.0.0.9",
"00:00:00:00:00:09"
]
},
{
"id": "00:00:00:00:00:07/-1",
"cp": {
"device": "of:0000ffffffff0007",
"port": 1
},
"labels": [
"10.0.0.7",
"00:00:00:00:00:07"
]
},
{
"id": "00:00:00:00:00:01/-1",
"cp": {
"device": "of:0000ffffffff0001",
"port": 1
},
"labels": [
"10.0.0.1",
"00:00:00:00:00:01"
]
}
]
}
{
"comment": [
"1 packet switch removed from base",
" 0007 "
],
"devices": [
{
"id": "of:0000ffffffffff08",
"type": "roadm",
"online": false,
"labels": [
"0000ffffffffff08",
"FF:FF:FF:FF:FF:08",
"?"
]
},
{
"id": "of:0000ffffffffff03",
"type": "roadm",
"online": false,
"labels": [
"0000ffffffffff03",
"FF:FF:FF:FF:FF:03",
"?"
]
},
{
"id": "of:0000ffffffffff02",
"type": "roadm",
"online": false,
"labels": [
"0000ffffffffff02",
"FF:FF:FF:FF:FF:02",
"?"
]
},
{
"id": "of:0000ffffffff0003",
"type": "switch",
"online": false,
"labels": [
"0000ffffffff0003",
"FF:FF:FF:FF:00:03",
"?"
]
},
{
"id": "of:0000ffffffffff07",
"type": "roadm",
"online": false,
"labels": [
"0000ffffffffff07",
"FF:FF:FF:FF:FF:07",
"?"
]
},
{
"id": "of:0000ffffffffff06",
"type": "roadm",
"online": false,
"labels": [
"0000ffffffffff06",
"FF:FF:FF:FF:FF:06",
"?"
]
},
{
"id": "of:0000ffffffffff05",
"type": "roadm",
"online": false,
"labels": [
"0000ffffffffff05",
"FF:FF:FF:FF:FF:05",
"?"
]
},
{
"id": "of:0000ffffffff0009",
"type": "switch",
"online": false,
"labels": [
"0000ffffffff0009",
"FF:FF:FF:FF:00:09",
"?"
]
},
{
"id": "of:0000ffffffffff04",
"type": "roadm",
"online": false,
"labels": [
"0000ffffffffff04",
"FF:FF:FF:FF:FF:04",
"?"
]
},
{
"id": "of:0000ffffffff000A",
"type": "switch",
"online": false,
"labels": [
"0000ffffffff000A",
"FF:FF:FF:FF:00:0A",
"?"
]
},
{
"id": "of:0000ffffffff0001",
"type": "switch",
"online": false,
"labels": [
"0000ffffffff0001",
"FF:FF:FF:FF:00:01",
"?"
]
},
{
"id": "of:0000ffffffffff01",
"type": "roadm",
"online": false,
"labels": [
"0000ffffffffff01",
"FF:FF:FF:FF:FF:01",
"?"
]
},
{
"id": "of:0000ffffffff0004",
"type": "switch",
"online": false,
"labels": [
"0000ffffffff0004",
"FF:FF:FF:FF:00:04",
"?"
]
},
{
"id": "of:0000ffffffffff0A",
"type": "roadm",
"online": false,
"labels": [
"0000ffffffffff0A",
"FF:FF:FF:FF:FF:0A",
"?"
]
},
{
"id": "of:0000ffffffffff09",
"type": "roadm",
"online": false,
"labels": [
"0000ffffffffff09",
"FF:FF:FF:FF:FF:09",
"?"
]
}
],
"links": [
{
"src": "of:0000ffffffffff02",
"srcPort": "20",
"dst": "of:0000ffffffffff05",
"dstPort": "10",
"type": "optical",
"linkWidth": 2
},
{
"src": "of:0000ffffffff000A",
"srcPort": "2",
"dst": "of:0000ffffffffff0A",
"dstPort": "1",
"type": "optical",
"linkWidth": 2
},
{
"src": "of:0000ffffffffff03",
"srcPort": "10",
"dst": "of:0000ffffffffff02",
"dstPort": "10",
"type": "optical",
"linkWidth": 2
},
{
"src": "of:0000ffffffffff07",
"srcPort": "21",
"dst": "of:0000ffffffffff05",
"dstPort": "20",
"type": "optical",
"linkWidth": 2
},
{
"src": "of:0000ffffffff0001",
"srcPort": "2",
"dst": "of:0000ffffffffff01",
"dstPort": "1",
"type": "optical",
"linkWidth": 2
},
{
"src": "of:0000ffffffffff09",
"srcPort": "20",
"dst": "of:0000ffffffffff0A",
"dstPort": "20",
"type": "optical",
"linkWidth": 2
},
{
"src": "of:0000ffffffffff06",
"srcPort": "20",
"dst": "of:0000ffffffffff05",
"dstPort": "30",
"type": "optical",
"linkWidth": 2
},
{
"src": "of:0000ffffffffff07",
"srcPort": "30",
"dst": "of:0000ffffffffff08",
"dstPort": "20",
"type": "optical",
"linkWidth": 2
},
{
"src": "of:0000ffffffffff03",
"srcPort": "20",
"dst": "of:0000ffffffffff06",
"dstPort": "10",
"type": "optical",
"linkWidth": 2
},
{
"src": "of:0000ffffffffff02",
"srcPort": "10",
"dst": "of:0000ffffffffff01",
"dstPort": "10",
"type": "optical",
"linkWidth": 2
},
{
"src": "of:0000ffffffffff09",
"srcPort": "1",
"dst": "of:0000ffffffff0009",
"dstPort": "2",
"type": "optical",
"linkWidth": 2
},
{
"src": "of:0000ffffffffff03",
"srcPort": "30",
"dst": "of:0000ffffffffff04",
"dstPort": "10",
"type": "optical",
"linkWidth": 2
},
{
"src": "of:0000ffffffffff07",
"srcPort": "20",
"dst": "of:0000ffffffffff09",
"dstPort": "10",
"type": "optical",
"linkWidth": 2
},
{
"src": "of:0000ffffffffff0A",
"srcPort": "10",
"dst": "of:0000ffffffffff08",
"dstPort": "30",
"type": "optical",
"linkWidth": 2
},
{
"src": "of:0000ffffffff0004",
"srcPort": "2",
"dst": "of:0000ffffffffff04",
"dstPort": "1",
"type": "optical",
"linkWidth": 2
},
{
"src": "of:0000ffffffffff07",
"srcPort": "1",
"dst": "of:0000ffffffff0007",
"dstPort": "2",
"type": "optical",
"linkWidth": 2
},
{
"src": "of:0000ffffffff0003",
"srcPort": "2",
"dst": "of:0000ffffffffff03",
"dstPort": "1",
"type": "optical",
"linkWidth": 2
},
{
"src": "of:0000ffffffffff06",
"srcPort": "30",
"dst": "of:0000ffffffffff08",
"dstPort": "10",
"type": "optical",
"linkWidth": 2
}
],
"hosts": [
{
"id": "00:00:00:00:00:03/-1",
"cp": {
"device": "of:0000ffffffff0003",
"port": 1
},
"labels": [
"10.0.0.3",
"00:00:00:00:00:03"
]
},
{
"id": "00:00:00:00:00:04/-1",
"cp": {
"device": "of:0000ffffffff0004",
"port": 1
},
"labels": [
"10.0.0.4",
"00:00:00:00:00:04"
]
},
{
"id": "00:00:00:00:00:0A/-1",
"cp": {
"device": "of:0000ffffffff000A",
"port": 1
},
"labels": [
"10.0.0.10",
"00:00:00:00:00:0A"
]
},
{
"id": "00:00:00:00:00:09/-1",
"cp": {
"device": "of:0000ffffffff0009",
"port": 1
},
"labels": [
"10.0.0.9",
"00:00:00:00:00:09"
]
},
{
"id": "00:00:00:00:00:07/-1",
"cp": {
"device": "of:0000ffffffff0007",
"port": 1
},
"labels": [
"10.0.0.7",
"00:00:00:00:00:07"
]
},
{
"id": "00:00:00:00:00:01/-1",
"cp": {
"device": "of:0000ffffffff0001",
"port": 1
},
"labels": [
"10.0.0.1",
"00:00:00:00:00:01"
]
}
]
}
{
"comment": [
"1 optical switch removed from base",
" ff07 "
],
"devices": [
{
"id": "of:0000ffffffffff08",
"type": "roadm",
"online": false,
"labels": [
"0000ffffffffff08",
"FF:FF:FF:FF:FF:08",
"?"
]
},
{
"id": "of:0000ffffffffff03",
"type": "roadm",
"online": false,
"labels": [
"0000ffffffffff03",
"FF:FF:FF:FF:FF:03",
"?"
]
},
{
"id": "of:0000ffffffffff02",
"type": "roadm",
"online": false,
"labels": [
"0000ffffffffff02",
"FF:FF:FF:FF:FF:02",
"?"
]
},
{
"id": "of:0000ffffffff0003",
"type": "switch",
"online": false,
"labels": [
"0000ffffffff0003",
"FF:FF:FF:FF:00:03",
"?"
]
},
{
"id": "of:0000ffffffffff06",
"type": "roadm",
"online": false,
"labels": [
"0000ffffffffff06",
"FF:FF:FF:FF:FF:06",
"?"
]
},
{
"id": "of:0000ffffffff0007",
"type": "switch",
"online": false,
"labels": [
"0000ffffffff0007",
"FF:FF:FF:FF:00:07",
"?"
]
},
{
"id": "of:0000ffffffffff05",
"type": "roadm",
"online": false,
"labels": [
"0000ffffffffff05",
"FF:FF:FF:FF:FF:05",
"?"
]
},
{
"id": "of:0000ffffffff0009",
"type": "switch",
"online": false,
"labels": [
"0000ffffffff0009",
"FF:FF:FF:FF:00:09",
"?"
]
},
{
"id": "of:0000ffffffffff04",
"type": "roadm",
"online": false,
"labels": [
"0000ffffffffff04",
"FF:FF:FF:FF:FF:04",
"?"
]
},
{
"id": "of:0000ffffffff000A",
"type": "switch",
"online": false,
"labels": [
"0000ffffffff000A",
"FF:FF:FF:FF:00:0A",
"?"
]
},
{
"id": "of:0000ffffffff0001",
"type": "switch",
"online": false,
"labels": [
"0000ffffffff0001",
"FF:FF:FF:FF:00:01",
"?"
]
},
{
"id": "of:0000ffffffffff01",
"type": "roadm",
"online": false,
"labels": [
"0000ffffffffff01",
"FF:FF:FF:FF:FF:01",
"?"
]
},
{
"id": "of:0000ffffffff0004",
"type": "switch",
"online": false,
"labels": [
"0000ffffffff0004",
"FF:FF:FF:FF:00:04",
"?"
]
},
{
"id": "of:0000ffffffffff0A",
"type": "roadm",
"online": false,
"labels": [
"0000ffffffffff0A",
"FF:FF:FF:FF:FF:0A",
"?"
]
},
{
"id": "of:0000ffffffffff09",
"type": "roadm",
"online": false,
"labels": [
"0000ffffffffff09",
"FF:FF:FF:FF:FF:09",
"?"
]
}
],
"links": [
{
"src": "of:0000ffffffffff02",
"srcPort": "20",
"dst": "of:0000ffffffffff05",
"dstPort": "10",
"type": "optical",
"linkWidth": 2
},
{
"src": "of:0000ffffffff000A",
"srcPort": "2",
"dst": "of:0000ffffffffff0A",
"dstPort": "1",
"type": "optical",
"linkWidth": 2
},
{
"src": "of:0000ffffffffff03",
"srcPort": "10",
"dst": "of:0000ffffffffff02",
"dstPort": "10",
"type": "optical",
"linkWidth": 2
},
{
"src": "of:0000ffffffffff07",
"srcPort": "21",
"dst": "of:0000ffffffffff05",
"dstPort": "20",
"type": "optical",
"linkWidth": 2
},
{
"src": "of:0000ffffffff0001",
"srcPort": "2",
"dst": "of:0000ffffffffff01",
"dstPort": "1",
"type": "optical",
"linkWidth": 2
},
{
"src": "of:0000ffffffffff09",
"srcPort": "20",
"dst": "of:0000ffffffffff0A",
"dstPort": "20",
"type": "optical",
"linkWidth": 2
},
{
"src": "of:0000ffffffffff06",
"srcPort": "20",
"dst": "of:0000ffffffffff05",
"dstPort": "30",
"type": "optical",
"linkWidth": 2
},
{
"src": "of:0000ffffffffff07",
"srcPort": "30",
"dst": "of:0000ffffffffff08",
"dstPort": "20",
"type": "optical",
"linkWidth": 2
},
{
"src": "of:0000ffffffffff03",
"srcPort": "20",
"dst": "of:0000ffffffffff06",
"dstPort": "10",
"type": "optical",
"linkWidth": 2
},
{
"src": "of:0000ffffffffff02",
"srcPort": "10",
"dst": "of:0000ffffffffff01",
"dstPort": "10",
"type": "optical",
"linkWidth": 2
},
{
"src": "of:0000ffffffffff09",
"srcPort": "1",
"dst": "of:0000ffffffff0009",
"dstPort": "2",
"type": "optical",
"linkWidth": 2
},
{
"src": "of:0000ffffffffff03",
"srcPort": "30",
"dst": "of:0000ffffffffff04",
"dstPort": "10",
"type": "optical",
"linkWidth": 2
},
{
"src": "of:0000ffffffffff07",
"srcPort": "20",
"dst": "of:0000ffffffffff09",
"dstPort": "10",
"type": "optical",
"linkWidth": 2
},
{
"src": "of:0000ffffffffff0A",
"srcPort": "10",
"dst": "of:0000ffffffffff08",
"dstPort": "30",
"type": "optical",
"linkWidth": 2
},
{
"src": "of:0000ffffffff0004",
"srcPort": "2",
"dst": "of:0000ffffffffff04",
"dstPort": "1",
"type": "optical",
"linkWidth": 2
},
{
"src": "of:0000ffffffffff07",
"srcPort": "1",
"dst": "of:0000ffffffff0007",
"dstPort": "2",
"type": "optical",
"linkWidth": 2
},
{
"src": "of:0000ffffffff0003",
"srcPort": "2",
"dst": "of:0000ffffffffff03",
"dstPort": "1",
"type": "optical",
"linkWidth": 2
},
{
"src": "of:0000ffffffffff06",
"srcPort": "30",
"dst": "of:0000ffffffffff08",
"dstPort": "10",
"type": "optical",
"linkWidth": 2
}
],
"hosts": [
{
"id": "00:00:00:00:00:03/-1",
"cp": {
"device": "of:0000ffffffff0003",
"port": 1
},
"labels": [
"10.0.0.3",
"00:00:00:00:00:03"
]
},
{
"id": "00:00:00:00:00:04/-1",
"cp": {
"device": "of:0000ffffffff0004",
"port": 1
},
"labels": [
"10.0.0.4",
"00:00:00:00:00:04"
]
},
{
"id": "00:00:00:00:00:0A/-1",
"cp": {
"device": "of:0000ffffffff000A",
"port": 1
},
"labels": [
"10.0.0.10",
"00:00:00:00:00:0A"
]
},
{
"id": "00:00:00:00:00:09/-1",
"cp": {
"device": "of:0000ffffffff0009",
"port": 1
},
"labels": [
"10.0.0.9",
"00:00:00:00:00:09"
]
},
{
"id": "00:00:00:00:00:07/-1",
"cp": {
"device": "of:0000ffffffff0007",
"port": 1
},
"labels": [
"10.0.0.7",
"00:00:00:00:00:07"
]
},
{
"id": "00:00:00:00:00:01/-1",
"cp": {
"device": "of:0000ffffffff0001",
"port": 1
},
"labels": [
"10.0.0.1",
"00:00:00:00:00:01"
]
}
]
}
{
"comment": [
"3 hosts added to base",
" 2 to 000A, 1 to 0007 "
],
"devices": [
{
"id": "of:0000ffffffffff08",
"type": "roadm",
"online": false,
"labels": [
"0000ffffffffff08",
"FF:FF:FF:FF:FF:08",
"?"
]
},
{
"id": "of:0000ffffffffff03",
"type": "roadm",
"online": false,
"labels": [
"0000ffffffffff03",
"FF:FF:FF:FF:FF:03",
"?"
]
},
{
"id": "of:0000ffffffffff02",
"type": "roadm",
"online": false,
"labels": [
"0000ffffffffff02",
"FF:FF:FF:FF:FF:02",
"?"
]
},
{
"id": "of:0000ffffffff0003",
"type": "switch",
"online": false,
"labels": [
"0000ffffffff0003",
"FF:FF:FF:FF:00:03",
"?"
]
},
{
"id": "of:0000ffffffffff07",
"type": "roadm",
"online": false,
"labels": [
"0000ffffffffff07",
"FF:FF:FF:FF:FF:07",
"?"
]
},
{
"id": "of:0000ffffffffff06",
"type": "roadm",
"online": false,
"labels": [
"0000ffffffffff06",
"FF:FF:FF:FF:FF:06",
"?"
]
},
{
"id": "of:0000ffffffff0007",
"type": "switch",
"online": false,
"labels": [
"0000ffffffff0007",
"FF:FF:FF:FF:00:07",
"?"
]
},
{
"id": "of:0000ffffffffff05",
"type": "roadm",
"online": false,
"labels": [
"0000ffffffffff05",
"FF:FF:FF:FF:FF:05",
"?"
]
},
{
"id": "of:0000ffffffff0009",
"type": "switch",
"online": false,
"labels": [
"0000ffffffff0009",
"FF:FF:FF:FF:00:09",
"?"
]
},
{
"id": "of:0000ffffffffff04",
"type": "roadm",
"online": false,
"labels": [
"0000ffffffffff04",
"FF:FF:FF:FF:FF:04",
"?"
]
},
{
"id": "of:0000ffffffff000A",
"type": "switch",
"online": false,
"labels": [
"0000ffffffff000A",
"FF:FF:FF:FF:00:0A",
"?"
]
},
{
"id": "of:0000ffffffff0001",
"type": "switch",
"online": false,
"labels": [
"0000ffffffff0001",
"FF:FF:FF:FF:00:01",
"?"
]
},
{
"id": "of:0000ffffffffff01",
"type": "roadm",
"online": false,
"labels": [
"0000ffffffffff01",
"FF:FF:FF:FF:FF:01",
"?"
]
},
{
"id": "of:0000ffffffff0004",
"type": "switch",
"online": false,
"labels": [
"0000ffffffff0004",
"FF:FF:FF:FF:00:04",
"?"
]
},
{
"id": "of:0000ffffffffff0A",
"type": "roadm",
"online": false,
"labels": [
"0000ffffffffff0A",
"FF:FF:FF:FF:FF:0A",
"?"
]
},
{
"id": "of:0000ffffffffff09",
"type": "roadm",
"online": false,
"labels": [
"0000ffffffffff09",
"FF:FF:FF:FF:FF:09",
"?"
]
}
],
"links": [
{
"src": "of:0000ffffffffff02",
"srcPort": "20",
"dst": "of:0000ffffffffff05",
"dstPort": "10",
"type": "optical",
"linkWidth": 2
},
{
"src": "of:0000ffffffff000A",
"srcPort": "2",
"dst": "of:0000ffffffffff0A",
"dstPort": "1",
"type": "optical",
"linkWidth": 2
},
{
"src": "of:0000ffffffffff03",
"srcPort": "10",
"dst": "of:0000ffffffffff02",
"dstPort": "10",
"type": "optical",
"linkWidth": 2
},
{
"src": "of:0000ffffffffff07",
"srcPort": "21",
"dst": "of:0000ffffffffff05",
"dstPort": "20",
"type": "optical",
"linkWidth": 2
},
{
"src": "of:0000ffffffff0001",
"srcPort": "2",
"dst": "of:0000ffffffffff01",
"dstPort": "1",
"type": "optical",
"linkWidth": 2
},
{
"src": "of:0000ffffffffff09",
"srcPort": "20",
"dst": "of:0000ffffffffff0A",
"dstPort": "20",
"type": "optical",
"linkWidth": 2
},
{
"src": "of:0000ffffffffff06",
"srcPort": "20",
"dst": "of:0000ffffffffff05",
"dstPort": "30",
"type": "optical",
"linkWidth": 2
},
{
"src": "of:0000ffffffffff07",
"srcPort": "30",
"dst": "of:0000ffffffffff08",
"dstPort": "20",
"type": "optical",
"linkWidth": 2
},
{
"src": "of:0000ffffffffff03",
"srcPort": "20",
"dst": "of:0000ffffffffff06",
"dstPort": "10",
"type": "optical",
"linkWidth": 2
},
{
"src": "of:0000ffffffffff02",
"srcPort": "10",
"dst": "of:0000ffffffffff01",
"dstPort": "10",
"type": "optical",
"linkWidth": 2
},
{
"src": "of:0000ffffffffff09",
"srcPort": "1",
"dst": "of:0000ffffffff0009",
"dstPort": "2",
"type": "optical",
"linkWidth": 2
},
{
"src": "of:0000ffffffffff03",
"srcPort": "30",
"dst": "of:0000ffffffffff04",
"dstPort": "10",
"type": "optical",
"linkWidth": 2
},
{
"src": "of:0000ffffffffff07",
"srcPort": "20",
"dst": "of:0000ffffffffff09",
"dstPort": "10",
"type": "optical",
"linkWidth": 2
},
{
"src": "of:0000ffffffffff0A",
"srcPort": "10",
"dst": "of:0000ffffffffff08",
"dstPort": "30",
"type": "optical",
"linkWidth": 2
},
{
"src": "of:0000ffffffff0004",
"srcPort": "2",
"dst": "of:0000ffffffffff04",
"dstPort": "1",
"type": "optical",
"linkWidth": 2
},
{
"src": "of:0000ffffffffff07",
"srcPort": "1",
"dst": "of:0000ffffffff0007",
"dstPort": "2",
"type": "optical",
"linkWidth": 2
},
{
"src": "of:0000ffffffff0003",
"srcPort": "2",
"dst": "of:0000ffffffffff03",
"dstPort": "1",
"type": "optical",
"linkWidth": 2
},
{
"src": "of:0000ffffffffff06",
"srcPort": "30",
"dst": "of:0000ffffffffff08",
"dstPort": "10",
"type": "optical",
"linkWidth": 2
}
],
"hosts": [
{
"id": "00:00:00:00:00:03/-1",
"cp": {
"device": "of:0000ffffffff0003",
"port": 1
},
"labels": [
"10.0.0.3",
"00:00:00:00:00:03"
]
},
{
"id": "00:00:00:00:00:04/-1",
"cp": {
"device": "of:0000ffffffff0004",
"port": 1
},
"labels": [
"10.0.0.4",
"00:00:00:00:00:04"
]
},
{
"id": "00:00:00:00:00:0A/-1",
"cp": {
"device": "of:0000ffffffff000A",
"port": 1
},
"labels": [
"10.0.0.10",
"00:00:00:00:00:0A"
]
},
{
"id": "00:00:00:00:65:0A/-1",
"cp": {
"device": "of:0000ffffffff000A",
"port": 101
},
"labels": [
"10.0.0.101",
"00:00:00:00:65:0A"
]
},
{
"id": "00:00:00:00:66:0A/-1",
"cp": {
"device": "of:0000ffffffff000A",
"port": 102
},
"labels": [
"10.0.0.102",
"00:00:00:00:66:0A"
]
},
{
"id": "00:00:00:00:00:09/-1",
"cp": {
"device": "of:0000ffffffff0009",
"port": 1
},
"labels": [
"10.0.0.9",
"00:00:00:00:00:09"
]
},
{
"id": "00:00:00:00:00:07/-1",
"cp": {
"device": "of:0000ffffffff0007",
"port": 1
},
"labels": [
"10.0.0.7",
"00:00:00:00:00:07"
]
},
{
"id": "00:00:00:00:67:07/-1",
"cp": {
"device": "of:0000ffffffff0007",
"port": 103
},
"labels": [
"10.0.0.73",
"00:00:00:00:67:07"
]
},
{
"id": "00:00:00:00:00:01/-1",
"cp": {
"device": "of:0000ffffffff0001",
"port": 1
},
"labels": [
"10.0.0.1",
"00:00:00:00:00:01"
]
}
]
}
{
"devices": [
{
"id": "of:0000ffffffffff08",
"type": "roadm",
"online": false,
"labels": [
"0000ffffffffff08",
"FF:FF:FF:FF:FF:08",
"?"
]
},
{
"id": "of:0000ffffffffff03",
"type": "roadm",
"online": false,
"labels": [
"0000ffffffffff03",
"FF:FF:FF:FF:FF:03",
"?"
]
},
{
"id": "of:0000ffffffffff02",
"type": "roadm",
"online": false,
"labels": [
"0000ffffffffff02",
"FF:FF:FF:FF:FF:02",
"?"
]
},
{
"id": "of:0000ffffffff0003",
"type": "switch",
"online": false,
"labels": [
"0000ffffffff0003",
"FF:FF:FF:FF:00:03",
"?"
]
},
{
"id": "of:0000ffffffffff07",
"type": "roadm",
"online": false,
"labels": [
"0000ffffffffff07",
"FF:FF:FF:FF:FF:07",
"?"
]
},
{
"id": "of:0000ffffffffff06",
"type": "roadm",
"online": false,
"labels": [
"0000ffffffffff06",
"FF:FF:FF:FF:FF:06",
"?"
]
},
{
"id": "of:0000ffffffff0007",
"type": "switch",
"online": false,
"labels": [
"0000ffffffff0007",
"FF:FF:FF:FF:00:07",
"?"
]
},
{
"id": "of:0000ffffffffff05",
"type": "roadm",
"online": false,
"labels": [
"0000ffffffffff05",
"FF:FF:FF:FF:FF:05",
"?"
]
},
{
"id": "of:0000ffffffff0009",
"type": "switch",
"online": false,
"labels": [
"0000ffffffff0009",
"FF:FF:FF:FF:00:09",
"?"
]
},
{
"id": "of:0000ffffffffff04",
"type": "roadm",
"online": false,
"labels": [
"0000ffffffffff04",
"FF:FF:FF:FF:FF:04",
"?"
]
},
{
"id": "of:0000ffffffff000A",
"type": "switch",
"online": false,
"labels": [
"0000ffffffff000A",
"FF:FF:FF:FF:00:0A",
"?"
]
},
{
"id": "of:0000ffffffff0001",
"type": "switch",
"online": false,
"labels": [
"0000ffffffff0001",
"FF:FF:FF:FF:00:01",
"?"
]
},
{
"id": "of:0000ffffffffff01",
"type": "roadm",
"online": false,
"labels": [
"0000ffffffffff01",
"FF:FF:FF:FF:FF:01",
"?"
]
},
{
"id": "of:0000ffffffff0004",
"type": "switch",
"online": false,
"labels": [
"0000ffffffff0004",
"FF:FF:FF:FF:00:04",
"?"
]
},
{
"id": "of:0000ffffffffff0A",
"type": "roadm",
"online": false,
"labels": [
"0000ffffffffff0A",
"FF:FF:FF:FF:FF:0A",
"?"
]
},
{
"id": "of:0000ffffffffff09",
"type": "roadm",
"online": false,
"labels": [
"0000ffffffffff09",
"FF:FF:FF:FF:FF:09",
"?"
]
}
],
"links": [
{
"src": "of:0000ffffffffff02",
"srcPort": "20",
"dst": "of:0000ffffffffff05",
"dstPort": "10",
"type": "optical",
"linkWidth": 2
},
{
"src": "of:0000ffffffff000A",
"srcPort": "2",
"dst": "of:0000ffffffffff0A",
"dstPort": "1",
"type": "optical",
"linkWidth": 2
},
{
"src": "of:0000ffffffffff03",
"srcPort": "10",
"dst": "of:0000ffffffffff02",
"dstPort": "10",
"type": "optical",
"linkWidth": 2
},
{
"src": "of:0000ffffffffff07",
"srcPort": "21",
"dst": "of:0000ffffffffff05",
"dstPort": "20",
"type": "optical",
"linkWidth": 2
},
{
"src": "of:0000ffffffff0001",
"srcPort": "2",
"dst": "of:0000ffffffffff01",
"dstPort": "1",
"type": "optical",
"linkWidth": 2
},
{
"src": "of:0000ffffffffff09",
"srcPort": "20",
"dst": "of:0000ffffffffff0A",
"dstPort": "20",
"type": "optical",
"linkWidth": 2
},
{
"src": "of:0000ffffffffff06",
"srcPort": "20",
"dst": "of:0000ffffffffff05",
"dstPort": "30",
"type": "optical",
"linkWidth": 2
},
{
"src": "of:0000ffffffffff07",
"srcPort": "30",
"dst": "of:0000ffffffffff08",
"dstPort": "20",
"type": "optical",
"linkWidth": 2
},
{
"src": "of:0000ffffffffff03",
"srcPort": "20",
"dst": "of:0000ffffffffff06",
"dstPort": "10",
"type": "optical",
"linkWidth": 2
},
{
"src": "of:0000ffffffffff02",
"srcPort": "10",
"dst": "of:0000ffffffffff01",
"dstPort": "10",
"type": "optical",
"linkWidth": 2
},
{
"src": "of:0000ffffffffff09",
"srcPort": "1",
"dst": "of:0000ffffffff0009",
"dstPort": "2",
"type": "optical",
"linkWidth": 2
},
{
"src": "of:0000ffffffffff03",
"srcPort": "30",
"dst": "of:0000ffffffffff04",
"dstPort": "10",
"type": "optical",
"linkWidth": 2
},
{
"src": "of:0000ffffffffff07",
"srcPort": "20",
"dst": "of:0000ffffffffff09",
"dstPort": "10",
"type": "optical",
"linkWidth": 2
},
{
"src": "of:0000ffffffffff0A",
"srcPort": "10",
"dst": "of:0000ffffffffff08",
"dstPort": "30",
"type": "optical",
"linkWidth": 2
},
{
"src": "of:0000ffffffff0004",
"srcPort": "2",
"dst": "of:0000ffffffffff04",
"dstPort": "1",
"type": "optical",
"linkWidth": 2
},
{
"src": "of:0000ffffffffff07",
"srcPort": "1",
"dst": "of:0000ffffffff0007",
"dstPort": "2",
"type": "optical",
"linkWidth": 2
},
{
"src": "of:0000ffffffff0003",
"srcPort": "2",
"dst": "of:0000ffffffffff03",
"dstPort": "1",
"type": "optical",
"linkWidth": 2
},
{
"src": "of:0000ffffffffff06",
"srcPort": "30",
"dst": "of:0000ffffffffff08",
"dstPort": "10",
"type": "optical",
"linkWidth": 2
}
],
"hosts": [
{
"id": "00:00:00:00:00:03/-1",
"cp": {
"device": "of:0000ffffffff0003",
"port": 1
},
"labels": [
"10.0.0.3",
"00:00:00:00:00:03"
]
},
{
"id": "00:00:00:00:00:04/-1",
"cp": {
"device": "of:0000ffffffff0004",
"port": 1
},
"labels": [
"10.0.0.4",
"00:00:00:00:00:04"
]
},
{
"id": "00:00:00:00:00:0A/-1",
"cp": {
"device": "of:0000ffffffff000A",
"port": 1
},
"labels": [
"10.0.0.10",
"00:00:00:00:00:0A"
]
},
{
"id": "00:00:00:00:00:09/-1",
"cp": {
"device": "of:0000ffffffff0009",
"port": 1
},
"labels": [
"10.0.0.9",
"00:00:00:00:00:09"
]
},
{
"id": "00:00:00:00:00:07/-1",
"cp": {
"device": "of:0000ffffffff0007",
"port": 1
},
"labels": [
"10.0.0.7",
"00:00:00:00:00:07"
]
},
{
"id": "00:00:00:00:00:01/-1",
"cp": {
"device": "of:0000ffffffff0001",
"port": 1
},
"labels": [
"10.0.0.1",
"00:00:00:00:00:01"
]
}
]
}
......@@ -55,19 +55,10 @@ svg #bg {
*/
svg .link {
fill: none;
stroke: #666;
stroke-width: 2.0px;
opacity: .7;
transition: opacity 250ms;
-webkit-transition: opacity 250ms;
-moz-transition: opacity 250ms;
}
svg .link.host {
stroke: #666;
stroke-width: 1px;
}
svg g.portLayer rect.port {
......@@ -81,10 +72,6 @@ svg g.portLayer text {
svg .node.device rect {
stroke-width: 1.5px;
transition: opacity 250ms;
-webkit-transition: opacity 250ms;
-moz-transition: opacity 250ms;
}
svg .node.device.fixed rect {
......
......@@ -24,6 +24,34 @@ svg #topo-bg {
opacity: 0.5;
}
svg .node {
svg .node.device {
stroke: none;
stroke-width: 1.5px;
cursor: pointer;
}
svg .node.device.fixed rect {
stroke-width: 1.5;
stroke: #ccc;
}
svg .node.device.switch {
fill: #17f;
}
svg .node.device.roadm {
fill: #03c;
}
svg .node text {
stroke: none;
fill: white;
font: 10pt sans-serif;
pointer-events: none;
}
/* for debugging */
svg .node circle.debug {
fill: white;
stroke: red;
}
......
......@@ -25,11 +25,11 @@
// configuration data
var config = {
useLiveData: true,
useLiveData: false,
debugOn: false,
debug: {
showNodeXY: false,
showKeyHandler: true
showNodeXY: true,
showKeyHandler: false
},
options: {
layering: true,
......@@ -49,6 +49,24 @@
detailSuffix: '.json'
}
},
labels: {
imgPad: 16,
padLR: 4,
padTB: 3,
marginLR: 3,
marginTB: 2,
port: {
gap: 3,
width: 18,
height: 14
}
},
icons: {
w: 28,
h: 28,
xoff: -12,
yoff: -8
},
iconUrl: {
device: 'img/device.png',
host: 'img/host.png',
......@@ -87,7 +105,9 @@
// key bindings
var keyDispatch = {
Q: getUpdatedNetworkData,
space: injectTestEvent, // TODO: remove (testing only)
// M: testMe, // TODO: remove (testing only)
B: toggleBg,
G: toggleLayout,
L: cycleLabels,
......@@ -96,7 +116,12 @@
};
// state variables
var network = {},
var network = {
nodes: [],
links: [],
lookup: {}
},
labelIdx = 0,
selected = {},
highlighted = null,
hovered = null,
......@@ -115,32 +140,51 @@
// ==============================
// For Debugging / Development
var topoPrefix = 'json/topoTest_',
lastFlavor = 4,
topoBase = true,
topoFlavor = 1;
var eventPrefix = 'json/eventTest_',
eventNumber = 0;
function nextTopo() {
if (topoBase) {
topoBase = false;
} else {
topoBase = true;
topoFlavor = (topoFlavor === lastFlavor) ? 1 : topoFlavor + 1
}
function note(label, msg) {
console.log('NOTE: ' + label + ': ' + msg);
}
// TODO change this to return the live data URL
function getTopoUrl() {
var suffix = topoBase ? 'base' : topoFlavor;
return topoPrefix + suffix + '.json';
function debug(what) {
return config.debugOn && config.debug[what];
}
// ==============================
// Key Callbacks
function getUpdatedNetworkData(view) {
nextTopo();
getNetworkData(view);
function testMe(view) {
svg.append('line')
.attr({
x1: 100,
y1: 100,
x2: 500,
y2: 400,
stroke: '#2f3',
'stroke-width': 8
})
.transition()
.duration(1200)
.attr({
stroke: '#666',
'stroke-width': 6
});
}
function injectTestEvent(view) {
eventNumber++;
var eventUrl = eventPrefix + eventNumber + '.json';
console.log('Fetching JSON: ' + eventUrl);
d3.json(eventUrl, function(err, data) {
if (err) {
view.dataLoadError(err, eventUrl);
} else {
handleServerEvent(data);
}
});
}
function toggleBg() {
......@@ -152,8 +196,30 @@
}
function cycleLabels(view) {
function cycleLabels() {
labelIdx = (labelIdx === network.deviceLabelCount - 1) ? 0 : labelIdx + 1;
network.nodes.forEach(function (d) {
var idx = (labelIdx < d.labels.length) ? labelIdx : 0,
node = d3.select('#' + safeId(d.id)),
box;
node.select('text')
.text(d.labels[idx])
.style('opacity', 0)
.transition()
.style('opacity', 1);
box = adjustRectToFitText(node);
node.select('rect')
.transition()
.attr(box);
node.select('image')
.transition()
.attr('x', box.x + config.icons.xoff)
.attr('y', box.y + config.icons.yoff);
});
}
function togglePorts(view) {
......@@ -191,6 +257,10 @@
// ==============================
// Private functions
function safeId(s) {
return s.replace(/[^a-z0-9]/gi, '-');
}
// set the size of the given element to that of the view (reduced if padded)
function setSize(el, view, pad) {
var padding = pad ? pad * 2 : 0;
......@@ -200,127 +270,288 @@
});
}
function getNetworkData(view) {
var url = getTopoUrl();
function establishWebSocket() {
// TODO: establish a real web-socket
// NOTE, for now, we are using the 'Q' key to artificially inject
// "events" from the server.
}
console.log('Fetching JSON: ' + url);
d3.json(url, function(err, data) {
if (err) {
view.dataLoadError(err, url);
} else {
network.data = data;
drawNetwork(view);
// ==============================
// Event handlers for server-pushed events
var eventDispatch = {
addDevice: addDevice,
updateDevice: updateDevice,
removeDevice: removeDevice,
addLink: addLink
};
function addDevice(data) {
var device = data.payload,
node = createDeviceNode(device);
note('addDevice', device.id);
network.nodes.push(node);
network.lookup[node.id] = node;
updateNodes();
network.force.start();
}
});
function updateDevice(data) {
var device = data.payload;
note('updateDevice', device.id);
}
function drawNetwork(view) {
preprocessData(view);
updateLayout(view);
function removeDevice(data) {
var device = data.payload;
note('removeDevice', device.id);
}
function preprocessData(view) {
var w = view.width(),
h = view.height(),
hDevice = h * 0.6,
hHost = h * 0.3,
data = network.data,
deviceLayout = computeInitLayout(w, hDevice, data.devices.length),
hostLayout = computeInitLayout(w, hHost, data.hosts.length);
network.lookup = {};
network.nodes = [];
network.links = [];
// we created new arrays, so need to set the refs in the force layout
network.force.nodes(network.nodes);
network.force.links(network.links);
// let's just start with the nodes
// note that both 'devices' and 'hosts' get mapped into the nodes array
function makeNode(d, cls, layout) {
var node = {
id: d.id,
labels: d.labels,
class: cls,
icon: cls,
type: d.type,
x: layout.x(),
y: layout.y()
function addLink(data) {
var link = data.payload,
lnk = createLink(link);
if (lnk) {
note('addLink', lnk.id);
network.links.push(lnk);
updateLinks();
network.force.start();
}
}
// ....
function unknownEvent(data) {
// TODO: use dialog, not alert
alert('Unknown event type: "' + data.event + '"');
}
function handleServerEvent(data) {
var fn = eventDispatch[data.event] || unknownEvent;
fn(data);
}
// ==============================
// force layout modification functions
function translate(x, y) {
return 'translate(' + x + ',' + y + ')';
}
function createLink(link) {
var type = link.type,
src = link.src,
dst = link.dst,
w = link.linkWidth,
srcNode = network.lookup[src],
dstNode = network.lookup[dst],
lnk;
if (!(srcNode && dstNode)) {
alert('nodes not on map');
return null;
}
lnk = {
id: safeId(src) + '~' + safeId(dst),
source: srcNode,
target: dstNode,
class: 'link',
svgClass: type ? 'link ' + type : 'link',
x1: srcNode.x,
y1: srcNode.y,
x2: dstNode.x,
y2: dstNode.y,
width: w
};
network.lookup[d.id] = node;
network.nodes.push(node);
return lnk;
}
// first the devices...
network.data.devices.forEach(function (d) {
makeNode(d, 'device', deviceLayout);
});
function updateLinks() {
link = linkG.selectAll('.link')
.data(network.links, function (d) { return d.id; });
// then the hosts...
network.data.hosts.forEach(function (d) {
makeNode(d, 'host', hostLayout);
// operate on existing links, if necessary
// link .foo() .bar() ...
// operate on entering links:
var entering = link.enter()
.append('line')
.attr({
id: function (d) { return d.id; },
class: function (d) { return d.svgClass; },
x1: function (d) { return d.x1; },
y1: function (d) { return d.y1; },
x2: function (d) { return d.x2; },
y2: function (d) { return d.y2; },
stroke: '#66f',
'stroke-width': 10
})
.transition().duration(1000)
.attr({
'stroke-width': function (d) { return d.width; },
stroke: '#666' // TODO: remove explicit stroke, rather...
});
// TODO: process links
// augment links
// TODO: add src/dst port labels etc.
}
function computeInitLayout(w, h, n) {
var maxdw = 60,
compdw, dw, ox, layout;
function createDeviceNode(device) {
// start with the object as is
var node = device,
type = device.type;
if (n < 2) {
layout = { ox: w/2, dw: 0 }
} else {
compdw = (0.8 * w) / (n - 1);
dw = Math.min(maxdw, compdw);
ox = w/2 - ((n - 1)/2 * dw);
layout = { ox: ox, dw: dw }
// Augment as needed...
node.class = 'device';
node.svgClass = type ? 'node device ' + type : 'node device';
positionNode(node);
// cache label array length
network.deviceLabelCount = device.labels.length;
return node;
}
layout.i = 0;
function positionNode(node) {
var meta = node.metaUi,
x = 0,
y = 0;
layout.x = function () {
var x = layout.ox + layout.i*layout.dw;
layout.i++;
return x;
};
if (meta) {
x = meta.x;
y = meta.y;
}
if (x && y) {
node.fixed = true;
}
node.x = x || network.view.width() / 2;
node.y = y || network.view.height() / 2;
}
layout.y = function () {
return h;
};
return layout;
function iconUrl(d) {
return 'img/' + d.type + '.png';
}
// returns the newly computed bounding box of the rectangle
function adjustRectToFitText(n) {
var text = n.select('text'),
box = text.node().getBBox(),
lab = config.labels;
text.attr('text-anchor', 'middle')
.attr('y', '-0.8em')
.attr('x', lab.imgPad/2);
// translate the bbox so that it is centered on [x,y]
box.x = -box.width / 2;
box.y = -box.height / 2;
// add padding
box.x -= (lab.padLR + lab.imgPad/2);
box.width += lab.padLR * 2 + lab.imgPad;
box.y -= lab.padTB;
box.height += lab.padTB * 2;
return box;
}
function linkId(d) {
return d.source.id + '~' + d.target.id;
function updateNodes() {
node = nodeG.selectAll('.node')
.data(network.nodes, function (d) { return d.id; });
// operate on existing nodes, if necessary
//node .foo() .bar() ...
// operate on entering nodes:
var entering = node.enter()
.append('g')
.attr({
id: function (d) { return safeId(d.id); },
class: function (d) { return d.svgClass; },
transform: function (d) { return translate(d.x, d.y); },
opacity: 0
})
//.call(network.drag)
//.on('mouseover', function (d) {})
//.on('mouseover', function (d) {})
.transition()
.attr('opacity', 1);
// augment device nodes...
entering.filter('.device').each(function (d) {
var node = d3.select(this),
icon = iconUrl(d),
idx = (labelIdx < d.labels.length) ? labelIdx : 0,
box;
node.append('rect')
.attr({
'rx': 5,
'ry': 5
});
node.append('text')
.text(d.labels[idx])
.attr('dy', '1.1em');
box = adjustRectToFitText(node);
node.select('rect')
.attr(box);
if (icon) {
var cfg = config.icons;
node.append('svg:image')
.attr({
x: box.x + config.icons.xoff,
y: box.y + config.icons.yoff,
width: cfg.w,
height: cfg.h,
'xlink:href': icon
});
}
function nodeId(d) {
return d.id;
// debug function to show the modelled x,y coordinates of nodes...
if (debug('showNodeXY')) {
node.select('rect').attr('fill-opacity', 0.5);
node.append('circle')
.attr({
class: 'debug',
cx: 0,
cy: 0,
r: '3px'
});
}
});
function updateLayout(view) {
link = link.data(network.force.links(), linkId);
link.enter().append('line')
.attr('class', 'link');
link.exit().remove();
node = node.data(network.force.nodes(), nodeId);
node.enter().append('circle')
.attr('id', function (d) { return 'nodeId-' + d.id; })
.attr('class', function (d) { return 'node'; })
.attr('r', 12);
// operate on both existing and new nodes, if necessary
//node .foo() .bar() ...
network.force.start();
// operate on exiting nodes:
// TODO: figure out how to remove the node 'g' AND its children
node.exit()
.transition()
.duration(750)
.attr({
opacity: 0,
cx: 0,
cy: 0,
r: 0
})
.remove();
}
function tick() {
node.attr({
cx: function(d) { return d.x; },
cy: function(d) { return d.y; }
transform: function (d) { return translate(d.x, d.y); }
});
link.attr({
......@@ -371,28 +602,45 @@
link = linkG.selectAll('.link');
node = nodeG.selectAll('.node');
function ldist(d) {
return fcfg.linkDistance[d.class] || 150;
}
function lstrg(d) {
return fcfg.linkStrength[d.class] || 1;
}
function lchrg(d) {
return fcfg.charge[d.class] || -200;
}
// set up the force layout
network.force = d3.layout.force()
.size(forceDim)
.nodes(network.nodes)
.links(network.links)
.charge(function (d) { return fcfg.charge[d.class]; })
.linkDistance(function (d) { return fcfg.linkDistance[d.class]; })
.linkStrength(function (d) { return fcfg.linkStrength[d.class]; })
.charge(lchrg)
.linkDistance(ldist)
.linkStrength(lstrg)
.on('tick', tick);
}
function load(view, ctx) {
// cache the view token, so network topo functions can access it
network.view = view;
// set our radio buttons and key bindings
view.setRadio(btnSet);
view.setKeys(keyDispatch);
getNetworkData(view);
establishWebSocket();
}
function resize(view, ctx) {
setSize(svg, view);
setSize(bgImg, view);
// TODO: hook to recompute layout, perhaps? work with zoom/pan code
// adjust force layout size
}
......