Merge "Improve style of network topology"

This commit is contained in:
Jenkins
2013-03-06 23:05:23 +00:00
committed by Gerrit Code Review
6 changed files with 114 additions and 106 deletions

View File

@@ -2,6 +2,7 @@
horizon.network_topology = { horizon.network_topology = {
model: null, model: null,
network_margin: 270, network_margin: 270,
topologyCanvas_padding: 120,
min_network_height:500, min_network_height:500,
port_margin: 20, port_margin: 20,
device_initial_position : 40, device_initial_position : 40,
@@ -20,15 +21,16 @@ horizon.network_topology = {
var self = this; var self = this;
$("#topologyCanvas").spin(horizon.conf.spinner_options.modal); $("#topologyCanvas").spin(horizon.conf.spinner_options.modal);
self.retrieve_network_info(); self.retrieve_network_info();
setInterval(horizon.network_topology.retrieve_network_info, setInterval(function(){
horizon.network_topology.reload_duration); self.retrieve_network_info();
}, self.reload_duration);
}, },
retrieve_network_info: function(){ retrieve_network_info: function(){
var self = this; var self = this;
if($("#networktopology").length === 0) { if($("#networktopology").length === 0) {
return; return;
} }
$.getJSON($("#networktopology").data('networktopology'), $.getJSON($("#networktopology").data("networktopology"),
function(data) { function(data) {
self.draw_graph(data); self.draw_graph(data);
} }
@@ -40,19 +42,27 @@ horizon.network_topology = {
draw_graph: function(data){ draw_graph: function(data){
var canvas = $("#topologyCanvas"); var canvas = $("#topologyCanvas");
var networks = $("#topologyCanvas > .networks"); var networks = $("#topologyCanvas > .networks");
var nodata = $("#topologyCanvas > .nodata");
networks.show();
nodata.hide();
canvas.spin(false); canvas.spin(false);
networks.empty(); networks.empty();
this.model = data; this.model = data;
this.device_last_position = this.device_initial_position; this.device_last_position = this.device_initial_position;
this.draw_networks(); var network_elements = this.draw_networks();
this.draw_routers(); var router_elements = this.draw_routers();
this.draw_servers(); var server_elements = this.draw_servers();
canvas.height( if ((network_elements + router_elements + server_elements) <= 0){
Math.max(this.device_last_position,this.min_network_height) networks.hide();
); nodata.show();
networks.width( } else {
this.model.networks.length * this.network_margin canvas.height(
); Math.max(this.device_last_position + this.topologyCanvas_padding, this.min_network_height)
);
networks.width(
this.model.networks.length * this.network_margin
);
}
}, },
network_color: function(network_id){ network_color: function(network_id){
var max_hue = 360; var max_hue = 360;
@@ -115,18 +125,24 @@ horizon.network_topology = {
if(network['router:external']){ if(network['router:external']){
label += " (external) "; label += " (external) ";
} }
label += self.select_cidr(network.id);
self.network_index[network.id] = index; self.network_index[network.id] = index;
var network_html = $("<div class='network' />").attr("id", network.id); var network_html = $("<div class='network' />").attr("id", network.id);
var nicname_html = $("<div class='nicname'><h3>" + label + "</h3></div>"); var nicname_html = $("<div class='nicname'><h3>" + label +
"</h3><span class='ip'>" + self.select_cidr(network.id) + "</span></div>");
if (network.url == undefined) {
nicname_html.addClass("nourl");
} else {
nicname_html.click(function (){
window.location.href = network.url;
});
}
nicname_html nicname_html
.click(function (){
window.location.href = network.url;})
.css ( .css (
{'background-color':self.network_color(network.id)}) {'background-color':self.network_color(network.id)})
.appendTo(network_html); .appendTo(network_html);
networks.append(network_html); networks.append(network_html);
}); });
return self.model.networks.length;
}, },
select_cidr:function(network_id){ select_cidr:function(network_id){
var cidr = ""; var cidr = "";
@@ -134,13 +150,13 @@ horizon.network_topology = {
if(subnet.network_id != network_id){ if(subnet.network_id != network_id){
return; return;
} }
cidr += " <span class=\"ip\">[ " + subnet.cidr + " ]</span>"; cidr += subnet.cidr;
}); });
return cidr; return cidr;
}, },
draw_devices: function(type){ draw_devices: function(type){
var self = this; var self = this;
$.each(self.model[type + 's'], function(index, device){ $.each(self.model[type + 's'], function(index, device){
var id = device.id; var id = device.id;
var name = (device.name != "")? device.name : device.id; var name = (device.name != "")? device.name : device.id;
var ports = self.select_port(id); var ports = self.select_port(id);
@@ -176,6 +192,7 @@ horizon.network_topology = {
self.device_last_position += device_html.height() + self.device_margin; self.device_last_position += device_html.height() + self.device_margin;
$("#" + parent_network).append(device_html); $("#" + parent_network).append(device_html);
}); });
return self.model[type + 's'].length;
}, },
sum_port_length: function(network_id, ports){ sum_port_length: function(network_id, ports){
var self = this; var self = this;
@@ -200,10 +217,10 @@ horizon.network_topology = {
return ports[main_port_index]; return ports[main_port_index];
}, },
draw_routers: function(){ draw_routers: function(){
this.draw_devices('router'); return this.draw_devices('router');
}, },
draw_servers: function(){ draw_servers: function(){
this.draw_devices('server'); return this.draw_devices('server');
}, },
select_port: function(device_id){ select_port: function(device_id){
return $.map(this.model.ports,function(port, index){ return $.map(this.model.ports,function(port, index){

View File

@@ -20,7 +20,7 @@ div.network .device:hover div.port {
} }
</style> </style>
<noscript> <noscript>
{%trans "This pane needs javascript support." %} {% trans "This pane needs javascript support." %}
</noscript> </noscript>
<div class="launchButtons"> <div class="launchButtons">
<a href="{% url horizon:project:instances:launch %}" id="instances__action_launch" class="btn btn-small btn-launch ajax-modal">{%trans "Launch Instance" %}</a> <a href="{% url horizon:project:instances:launch %}" id="instances__action_launch" class="btn btn-small btn-launch ajax-modal">{%trans "Launch Instance" %}</a>
@@ -30,6 +30,7 @@ div.network .device:hover div.port {
<div id="topologyCanvas"> <div id="topologyCanvas">
<div class="networks"></div> <div class="networks"></div>
<div class="nodata">{% blocktrans %}There are no networks, routers, or connected instances to display. {% endblocktrans %}</div>
</div> </div>
<span data-networktopology="{% url horizon:project:network_topology:json %}" id="networktopology"></span> <span data-networktopology="{% url horizon:project:network_topology:json %}" id="networktopology"></span>
{% endblock %} {% endblock %}

View File

@@ -33,7 +33,11 @@ class NetworkTopology(TemplateView):
class JSONView(View): class JSONView(View):
def add_resource_url(self, view, resources): def add_resource_url(self, view, resources):
tenant_id = self.request.user.tenant_id
for resource in resources: for resource in resources:
if (resource.get('tenant_id')
and tenant_id != resource.get('tenant_id')):
continue
resource['url'] = reverse(view, None, [str(resource['id'])]) resource['url'] = reverse(view, None, [str(resource['id'])])
def _select_port_by_network_id(self, ports, network_id): def _select_port_by_network_id(self, ports, network_id):

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

@@ -1834,6 +1834,13 @@ label.log-length {
padding: 25px; padding: 25px;
padding-left: 50px; padding-left: 50px;
background: #efefef; background: #efefef;
div.nodata {
font-size: 150%;
font-weight: bold;
text-align: center;
padding-top: 200px;
display: none;
}
} }
div.networks { div.networks {
height: 100%; height: 100%;
@@ -1863,12 +1870,18 @@ div.network {
background-image: linear-gradient(rgba(0, 0, 0, 0.15), rgba(0, 0, 0, 0.15)); background-image: linear-gradient(rgba(0, 0, 0, 0.15), rgba(0, 0, 0, 0.15));
background-size: 10px 10px; background-size: 10px 10px;
} }
&.nourl {
cursor: auto;
&:hover {
background-image:none;
}
}
h3 { h3 {
font-size: 12px; font-size: 12px;
line-height: 1; line-height: 1;
position: relative; position: relative;
font-weight: normal; font-weight: normal;
top:60%; top:55%;
color:#fff; color:#fff;
left:-1px; left:-1px;
letter-spacing: 0.2em; letter-spacing: 0.2em;
@@ -1877,71 +1890,83 @@ div.network {
-ms-transform: rotate(-90deg); -ms-transform: rotate(-90deg);
-o-transform: rotate(-90deg); -o-transform: rotate(-90deg);
transform: rotate(-90deg); transform: rotate(-90deg);
white-space: nowrap; white-space: nowrap;
text-shadow: 0px 0px 5px #000; text-shadow: 0px 0px 5px #000;
span.ip { }
margin-left: 0.5em; span.ip {
color: #000; position: absolute;
font-weight: normal; bottom:-10px;
font-size: 90%; left:20px;
text-shadow: 0px 0px 0px #000; color: #000;
} display: block;
font-weight: normal;
font-size: 90%;
letter-spacing: 0.2em;
-webkit-transform: rotate(-90deg);
-moz-transform: rotate(-90deg);
-ms-transform: rotate(-90deg);
-o-transform: rotate(-90deg);
transform: rotate(-90deg);
-webkit-transform-origin: 0% 0%;
-moz-transform-origin: 0% 0%;
-ms-transform-origin: 0% 0%;
-o-transform-origin: 0% 0%;
transform-origin: 0% 0%;
white-space: nowrap;
text-shadow: 0px 0px 2px #fff,0px 0px 2px #fff;
} }
} }
.router, .server, .device { .router, .server, .device {
.box-sizing(); .box-sizing();
cursor: pointer; cursor: pointer;
width: 90px; width: 90px;
border: 3px solid #666; border: 3px solid #444;
position: absolute; position: absolute;
top:30px; top:30px;
left:90px; left:90px;
color:#fff;
padding: 0 3px; padding: 0 3px;
background: #666; background: #666;
margin-bottom: 20px; margin-bottom: 20px;
&:before,&:after { border-radius: 8px;
&:before {
content: ""; content: "";
width: 90px; width: 20px;
height: 34px; height: 20px;
text-align: center; border: 2px solid #444;
line-height: 1.2;
position: absolute; position: absolute;
border: 3px solid #666; border-radius: 20px;
.box-sizing(); top:-10px;
background: #fff; left:-10px;
border-radius:50%; background:#fff url(/static/dashboard/img/router.png) no-repeat center center;
top:-19px; background-size: 16px 16px;
left:-3px;
} }
&:after { &:after {
content:""; content: "";
width: 100%;
line-height: 1.2;
position: absolute;
text-align: center;
border-radius: 0;
background: #444;
color: #fff; color: #fff;
background:#666;
border-radius:50%;
top:auto;
bottom:-19px;
font-size: 11px; font-size: 11px;
line-height: 30px; height: 1.5em;
bottom:0px;
left: 0px;
} }
span.devicename { span.devicename {
position: absolute; position: absolute;
color: #fff; color: #fff;
bottom: -10px; bottom: 0px;
font-size: 12px; font-size: 12px;
line-height: 14px; line-height: 14px;
left:-4px;
width: 100%; width: 100%;
text-align: center; text-align: center;
z-index:300; z-index:300;
i { left:-2px;
display: inline-block;
width: 14px;
height:14px;
background: #fff url(/static/dashboard/img/router.png) no-repeat center center;
background-size: 12px 12px;
margin-right: 3px;
vertical-align: middle;
border-radius: 20px;
}
} }
span.name { span.name {
overflow: hidden; overflow: hidden;
@@ -1952,7 +1977,7 @@ div.network {
position: relative; position: relative;
z-index:10; z-index:10;
text-align: center; text-align: center;
top:-10px; top:4px;
padding: 0 3px; padding: 0 3px;
} }
div.port { div.port {
@@ -1972,6 +1997,7 @@ div.network {
z-index:100; z-index:100;
span.ip { span.ip {
.box-sizing(); .box-sizing();
color: #333;
font-size: 9px; font-size: 9px;
line-height: 1; line-height: 1;
text-shadow: 0px -1px #fff; text-shadow: 0px -1px #fff;
@@ -2010,14 +2036,10 @@ div.network {
animation: progress-bar-stripes 0.3s linear infinite; animation: progress-bar-stripes 0.3s linear infinite;
} }
} }
background-color: #444; border-color: #222;
border-color: #444;
&:before {
border-color: #444;
}
&:after { &:after {
background-color: #444; background-color: #222;
border-color: #444; border-color: #222;
} }
} }
} }
@@ -2026,48 +2048,12 @@ div.network {
background: transparent; background: transparent;
} }
.server { .server {
border-radius: 5px;
background: #fff;
span.devicename {
bottom: 0px;
font-size: 12px;
line-height: 14px;
left:-4px;
i {
display: inline-block;
width: 14px;
height:14px;
background: url(/static/dashboard/img/server.png) no-repeat center center;
background-size: 12px 12px;
margin-right: 3px;
vertical-align: middle;
}
}
span.name {
top:5px;
padding: 0 3px;
}
&:before { &:before {
border:none; background:#fff url(/static/dashboard/img/server.png) no-repeat center center;
background: transparent; background-size: 14px 14px;
}
&:after {
content: "";
width: 100%;
line-height: 1.2;
position: absolute;
text-align: center;
border-radius: 0;
background: #666;
color: #fff;
font-size: 11px;
height: 1.5em;
bottom:0px;
left: 0px;
}
&:hover {
background: #fff;
} }
background: #fff;
color:#333;
} }
} }