Simon Hunt

Added sample switch data, and augmented selection logic to fetch the detail data from the server.

Also used styled table for displaying properties.
......@@ -14,37 +14,37 @@
"devices": [
{
"id": "of:0000000000000001",
"labels": ["00:00:00:00:00:00:00:01", "of/::01", "opt-1"],
"labels": ["00:00:00:00:00:00:00:01", "SFO-W10", "opt-1"],
"type": "roadm"
},
{
"id": "of:0000000000000002",
"labels": ["00:00:00:00:00:00:00:02", "of/::02", "opt-2"],
"labels": ["00:00:00:00:00:00:00:02", "SJC-W10", "opt-2"],
"type": "roadm"
},
{
"id": "of:0000000000000003",
"labels": ["00:00:00:00:00:00:00:03", "of/::03", "opt-3"],
"labels": ["00:00:00:00:00:00:00:03", "LAX-W10", "opt-3"],
"type": "roadm"
},
{
"id": "of:0000000000000004",
"labels": ["00:00:00:00:00:00:00:04", "of/::04", "opt-4"],
"labels": ["00:00:00:00:00:00:00:04", "SDG-W10", "opt-4"],
"type": "roadm"
},
{
"id": "of:0000000000000011",
"labels": ["00:00:00:00:00:00:00:11", "of/::11", "pkt-11"],
"labels": ["00:00:00:00:00:00:00:11", "SFO-pkt", "pkt-11"],
"type": "switch"
},
{
"id": "of:0000000000000012",
"labels": ["00:00:00:00:00:00:00:12", "of/::12", "pkt-12"],
"labels": ["00:00:00:00:00:00:00:12", "SJC-pkt", "pkt-12"],
"type": "switch"
},
{
"id": "of:0000000000000013",
"labels": ["00:00:00:00:00:00:00:13", "of/::13", "pkt-13"],
"labels": ["00:00:00:00:00:00:00:13", "LAX-pkt", "pkt-13"],
"type": "switch"
}
],
......
{
"comment": "sample device properties",
"id": "of:0000000000000001",
"propOrder": [ "name", "type", "dpid", "latitude", "longitude", "allowed" ],
"props": {
"allowed": true,
"latitude": 37.6,
"longitude": 122.3,
"name": "SFO-W10",
"dpid": "00:00:00:00:00:00:00:01",
"type": "Roadm"
}
}
{
"comment": "sample device properties",
"id": "of:0000000000000002",
"propOrder": [ "name", "type", "dpid", "latitude", "longitude", "allowed" ],
"props": {
"allowed": true,
"latitude": 37.3,
"longitude": 121.9,
"name": "SJC-W10",
"dpid": "00:00:00:00:00:00:00:02",
"type": "Roadm"
}
}
{
"comment": "sample device properties",
"id": "of:0000000000000003",
"propOrder": [ "name", "type", "dpid", "latitude", "longitude", "allowed" ],
"props": {
"allowed": true,
"latitude": 33.9,
"longitude": 118.4,
"name": "LAX-W10",
"dpid": "00:00:00:00:00:00:00:03",
"type": "Roadm"
}
}
{
"comment": "sample device properties",
"id": "of:0000000000000004",
"propOrder": [ "name", "type", "dpid", "latitude", "longitude", "allowed" ],
"props": {
"allowed": true,
"latitude": 32.8,
"longitude": 117.1,
"name": "SDG-W10",
"dpid": "00:00:00:00:00:00:00:04",
"type": "Roadm"
}
}
{
"comment": "sample device properties",
"id": "of:0000000000000011",
"propOrder": [ "name", "type", "dpid", "optLink" ],
"props": {
"name": "SFO-pkt",
"dpid": "00:00:00:00:00:00:00:11",
"type": "SwitchX",
"optLink": "SFO-W10"
}
}
{
"comment": "sample device properties",
"id": "of:0000000000000012",
"propOrder": [ "name", "type", "dpid", "optLink" ],
"props": {
"name": "SJC-pkt",
"dpid": "00:00:00:00:00:00:00:12",
"type": "SwitchX",
"optLink": "SJC-W10"
}
}
{
"comment": "sample device properties",
"id": "of:0000000000000013",
"propOrder": [ "name", "type", "dpid", "optLink" ],
"props": {
"name": "LAX-pkt",
"dpid": "00:00:00:00:00:00:00:13",
"type": "SwitchX",
"optLink": "LAX-W10"
}
}
......@@ -38,7 +38,8 @@
collisionPrevention: true
},
XjsonUrl: 'rs/topology/graph',
jsonUrl: 'network.json',
jsonUrl: 'json/network.json',
jsonPrefix: 'json/',
iconUrl: {
device: 'img/device.png',
host: 'img/host.png',
......@@ -873,10 +874,6 @@
node.classed('selected', true);
flyinPane(obj);
// TODO animate incoming info pane
// resize(true);
// TODO: check bounds of selected node and scroll into view if needed
}
function deselectObject(doResize) {
......@@ -891,23 +888,69 @@
flyinPane(null);
}
function detailUrl(id) {
var safeId = id.replace(/[^a-z0-9]/gi, '_');
return config.jsonPrefix + safeId + '.json';
}
function flyinPane(obj) {
var pane = d3.select('#flyout'),
right = (obj ? '20px' : '-320px'), // TODO: parameterize
opac = (obj ? 1.0 : 0.0);
url;
if (obj) {
$('#flyout').empty();
pane.append('h2').text(obj.id);
pane.append('p').text('class: ' + obj.class);
if (obj.type) {
pane.append('p').text('type: ' + obj.type);
}
// go get details of the selected object from the server...
url = detailUrl(obj.id);
d3.json(url, function (err, data) {
if (err) {
alert('Oops! Error reading JSON...\n\n' +
'URL: ' + url + '\n\n' +
'Error: ' + err.message);
return;
}
// console.log("JSON data... " + url);
// console.log(data);
displayDetails(data, pane);
});
} else {
// hide pane
pane.transition().duration(750)
.style('right', '-320px')
.style('opacity', 0.0);
}
}
function displayDetails(data, pane) {
$('#flyout').empty();
pane.append('h2').text(data.id);
var table = pane.append("table"),
tbody = table.append("tbody");
// TODO: consider using d3 data bind to TR/TD
data.propOrder.forEach(function(p) {
addProp(tbody, p, data.props[p]);
});
function addProp(tbody, label, value) {
var tr = tbody.append('tr');
tr.append('td')
.attr('class', 'label')
.text(label + ' :');
tr.append('td')
.attr('class', 'value')
.text(value);
}
// show pane
pane.transition().duration(750)
.style('right', right)
.style('opacity', opac);
.style('right', '20px')
.style('opacity', 1.0);
}
function highlightObject(obj) {
......
......@@ -189,6 +189,13 @@ svg .legend .category text {
* Specific structural elements
*/
/* This is to ensure that the body does not expand to account for the
flyout details pane, that is positioned "off screen".
*/
body {
overflow: hidden;
}
#mast {
height: 36px;
padding: 4px;
......@@ -214,6 +221,7 @@ svg .legend .category text {
background-color: rgba(0,0,0,0.5);
padding: 10px;
color: white;
font-size: 10pt;
}
#flyout h2 {
......@@ -221,7 +229,17 @@ svg .legend .category text {
color: yellow;
}
#flyout p {
#flyout p, table {
margin: 4px 4px;
}
#flyout td.label {
font-style: italic;
color: #ccf;
padding-right: 12px;
}
#flyout td.value {
}
......