Add stack chart, line chart, circle packing and tree
Change-Id: I20092ff35377b4005644c69726d63e501ac9b310
This commit is contained in:
parent
5f6e0118b0
commit
713efa67a3
59
v2/assets/css/chart.css
Normal file
59
v2/assets/css/chart.css
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
/* circle packing */
|
||||||
|
text {
|
||||||
|
font-size: 14px !important;
|
||||||
|
font-family: "Arial, Helvetica, sans-serif";
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
text.parent {
|
||||||
|
fill: #1f77b4;
|
||||||
|
}
|
||||||
|
circle {
|
||||||
|
fill: #ccc;
|
||||||
|
stroke: #999;
|
||||||
|
fill-opacity: .8;
|
||||||
|
pointer-events: all;
|
||||||
|
}
|
||||||
|
circle.parent {
|
||||||
|
fill: #1f77b4;
|
||||||
|
fill-opacity: .3;
|
||||||
|
stroke: steelblue;
|
||||||
|
}
|
||||||
|
circle.parent:hover {
|
||||||
|
stroke: #ff7f0e;
|
||||||
|
stroke-width: 5px;
|
||||||
|
}
|
||||||
|
circle.child {
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
circle[depth='0'] {
|
||||||
|
fill: #428bca;
|
||||||
|
}
|
||||||
|
circle[depth='1'] {
|
||||||
|
fill: #ffb752;
|
||||||
|
}
|
||||||
|
circle[depth='2'] {
|
||||||
|
fill: #d6487e;
|
||||||
|
}
|
||||||
|
circle[depth='3'] {
|
||||||
|
fill: #fee188;
|
||||||
|
}
|
||||||
|
circle[depth='4'] {
|
||||||
|
fill: #9585bf;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* tree */
|
||||||
|
.node circle {
|
||||||
|
cursor: pointer;
|
||||||
|
fill: #fff;
|
||||||
|
stroke: steelblue;
|
||||||
|
stroke-width: 1.5px;
|
||||||
|
}
|
||||||
|
.node text {
|
||||||
|
font-size: 11px;
|
||||||
|
}
|
||||||
|
path.link {
|
||||||
|
fill: none;
|
||||||
|
stroke: #ccc;
|
||||||
|
stroke-width: 1.5px;
|
||||||
|
}
|
BIN
v2/assets/img/router.png
Normal file
BIN
v2/assets/img/router.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.8 KiB |
BIN
v2/assets/img/server.png
Normal file
BIN
v2/assets/img/server.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.6 KiB |
BIN
v2/assets/img/switch.png
Normal file
BIN
v2/assets/img/switch.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.6 KiB |
@ -1,4 +1,10 @@
|
|||||||
[{
|
[{
|
||||||
|
"name": "cluster.monitoring.overview",
|
||||||
|
"url": "/overview",
|
||||||
|
"display": "Overview",
|
||||||
|
"controller": "",
|
||||||
|
"templateUrl": ""
|
||||||
|
}, {
|
||||||
"name": "cluster.monitoring.hostgroups",
|
"name": "cluster.monitoring.hostgroups",
|
||||||
"url": "/hostgroups",
|
"url": "/hostgroups",
|
||||||
"display": "Host Groups",
|
"display": "Host Groups",
|
||||||
|
@ -8,11 +8,13 @@
|
|||||||
<link rel="stylesheet" type="text/css" href="vendor/bootstrap/css/bootstrap.css">
|
<link rel="stylesheet" type="text/css" href="vendor/bootstrap/css/bootstrap.css">
|
||||||
<link rel="stylesheet" type="text/css" href="vendor/font-awesome/css/font-awesome.min.css" />
|
<link rel="stylesheet" type="text/css" href="vendor/font-awesome/css/font-awesome.min.css" />
|
||||||
<link rel="stylesheet" type="text/css" href="vendor/rickshaw/rickshaw.min.css" />
|
<link rel="stylesheet" type="text/css" href="vendor/rickshaw/rickshaw.min.css" />
|
||||||
|
<link rel="stylesheet" type="text/css" href="vendor/nvd3/nv.d3.min.css">
|
||||||
|
|
||||||
<link rel="stylesheet" type="text/css" href="assets/css/ace.min.css">
|
<link rel="stylesheet" type="text/css" href="assets/css/ace.min.css">
|
||||||
<link rel="stylesheet" type="text/css" href="assets/css/ace-skins.min.css">
|
<link rel="stylesheet" type="text/css" href="assets/css/ace-skins.min.css">
|
||||||
<link rel="stylesheet" type="text/css" href="assets/css/ace-fonts.css" />
|
<link rel="stylesheet" type="text/css" href="assets/css/ace-fonts.css" />
|
||||||
<link rel="stylesheet" type="text/css" href="assets/css/style.css">
|
<link rel="stylesheet" type="text/css" href="assets/css/style.css">
|
||||||
|
<link rel="stylesheet" type="text/css" href="assets/css/chart.css">
|
||||||
|
|
||||||
<script type="text/javascript" src="vendor/jquery/jquery-1.11.1.min.js"></script>
|
<script type="text/javascript" src="vendor/jquery/jquery-1.11.1.min.js"></script>
|
||||||
<script type="text/javascript" src="vendor/bootstrap/js/bootstrap.min.js"></script>
|
<script type="text/javascript" src="vendor/bootstrap/js/bootstrap.min.js"></script>
|
||||||
@ -29,13 +31,15 @@
|
|||||||
<script type="text/javascript" src="vendor/angular-dragdrop/draganddrop.js"></script>
|
<script type="text/javascript" src="vendor/angular-dragdrop/draganddrop.js"></script>
|
||||||
<script type="text/javascript" src="vendor/ng-table/ng-table.min.js"></script>
|
<script type="text/javascript" src="vendor/ng-table/ng-table.min.js"></script>
|
||||||
<script type="text/javascript" src="vendor/d3/d3.min.js"></script>
|
<script type="text/javascript" src="vendor/d3/d3.min.js"></script>
|
||||||
|
<script type="text/javascript" src="vendor/nvd3/nv.d3.min.js"></script>
|
||||||
|
<script type="text/javascript" src="vendor/angular-nvd3/angularjs-nvd3-directives.min.js"></script>
|
||||||
|
|
||||||
<script type="text/javascript" src="vendor/rickshaw/rickshaw.min.js"></script>
|
<script type="text/javascript" src="vendor/rickshaw/rickshaw.min.js"></script>
|
||||||
<script type="text/javascript" src="vendor/angular-rickshaw/rickshaw.min.js"></script>
|
<script type="text/javascript" src="vendor/angular-rickshaw/rickshaw.min.js"></script>
|
||||||
|
|
||||||
<script type="text/javascript" src="vendor/angular-spinner/spin.min.js"></script>
|
<script type="text/javascript" src="vendor/angular-spinner/spin.min.js"></script>
|
||||||
<script type="text/javascript" src="vendor/angular-spinner/angular-spinner.min.js"></script>
|
<script type="text/javascript" src="vendor/angular-spinner/angular-spinner.min.js"></script>
|
||||||
|
|
||||||
|
|
||||||
<script type="text/javascript" src="src/app/app.js"></script>
|
<script type="text/javascript" src="src/app/app.js"></script>
|
||||||
<script type="text/javascript" src="src/app/appDev.js"></script>
|
<script type="text/javascript" src="src/app/appDev.js"></script>
|
||||||
<script type="text/javascript" src="src/app/login/login.js"></script>
|
<script type="text/javascript" src="src/app/login/login.js"></script>
|
||||||
|
@ -1,3 +1,7 @@
|
|||||||
charts
|
<div class="page-header">
|
||||||
<rickshaw rickshaw-options="options2" rickshaw-features="features2" rickshaw-series="series2">
|
<h1>
|
||||||
</rickshaw>
|
Charts
|
||||||
|
</h1>
|
||||||
|
</div>
|
||||||
|
<div class="row side-padding-10 padding-top-30">
|
||||||
|
</div>
|
||||||
|
@ -3,7 +3,8 @@ angular.module('compass.monitoring', [
|
|||||||
'ui.bootstrap',
|
'ui.bootstrap',
|
||||||
'compass.charts',
|
'compass.charts',
|
||||||
'ngAnimate',
|
'ngAnimate',
|
||||||
'angular-rickshaw'
|
'angular-rickshaw',
|
||||||
|
'nvd3ChartDirectives'
|
||||||
])
|
])
|
||||||
|
|
||||||
.config(function($stateProvider, $urlRouterProvider) {
|
.config(function($stateProvider, $urlRouterProvider) {
|
||||||
@ -124,3 +125,190 @@ angular.module('compass.monitoring', [
|
|||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
])
|
])
|
||||||
|
|
||||||
|
.controller('moniOverviewCtrl', function($scope) {
|
||||||
|
$scope.logicalTopoData = {
|
||||||
|
"name": "cluster1",
|
||||||
|
"children": [{
|
||||||
|
"name": "compute",
|
||||||
|
"state": "error",
|
||||||
|
"children": [{
|
||||||
|
"name": "host1",
|
||||||
|
"state": "error",
|
||||||
|
"children": [{
|
||||||
|
"name": "service1"
|
||||||
|
}, {
|
||||||
|
"name": "service2"
|
||||||
|
}, {
|
||||||
|
"name": "service3"
|
||||||
|
}, {
|
||||||
|
"name": "service4"
|
||||||
|
}]
|
||||||
|
}, {
|
||||||
|
"name": "host2",
|
||||||
|
"state": "error",
|
||||||
|
"children": [{
|
||||||
|
"name": "service1"
|
||||||
|
}, {
|
||||||
|
"name": "service2"
|
||||||
|
}]
|
||||||
|
}, {
|
||||||
|
"name": "host3",
|
||||||
|
"state": "error",
|
||||||
|
"children": [{
|
||||||
|
"name": "service1",
|
||||||
|
"children": [{
|
||||||
|
"name": "metric1"
|
||||||
|
}, {
|
||||||
|
"name": "metric2"
|
||||||
|
}]
|
||||||
|
}]
|
||||||
|
}]
|
||||||
|
}, {
|
||||||
|
"name": "storage",
|
||||||
|
"state": "ok",
|
||||||
|
"children": [{
|
||||||
|
"name": "host7",
|
||||||
|
"state": "ok",
|
||||||
|
"children": [{
|
||||||
|
"name": "service5",
|
||||||
|
"state": "ok",
|
||||||
|
"children": [{
|
||||||
|
"name": "metric1"
|
||||||
|
}, {
|
||||||
|
"name": "metric2"
|
||||||
|
}]
|
||||||
|
}, {
|
||||||
|
"name": "service6",
|
||||||
|
"state": "ok",
|
||||||
|
"children": [{
|
||||||
|
"name": "metric1"
|
||||||
|
}, {
|
||||||
|
"name": "metric2"
|
||||||
|
}]
|
||||||
|
}]
|
||||||
|
}, {
|
||||||
|
"name": "host8",
|
||||||
|
"state": "ok",
|
||||||
|
"children": [{
|
||||||
|
"name": "service7",
|
||||||
|
"state": "ok",
|
||||||
|
"children": [{
|
||||||
|
"name": "metric1"
|
||||||
|
}]
|
||||||
|
}, {
|
||||||
|
"name": "service8"
|
||||||
|
}]
|
||||||
|
}]
|
||||||
|
}, {
|
||||||
|
"name": "network",
|
||||||
|
"state": "warning",
|
||||||
|
"children": [{
|
||||||
|
"name": "host10",
|
||||||
|
"state": "warning",
|
||||||
|
"children": []
|
||||||
|
}, {
|
||||||
|
"name": "host11",
|
||||||
|
"state": "warning",
|
||||||
|
"children": []
|
||||||
|
}]
|
||||||
|
}, {
|
||||||
|
"name": "controller",
|
||||||
|
"state": "warning",
|
||||||
|
"children": [{
|
||||||
|
"name": "host12",
|
||||||
|
"state": "warning",
|
||||||
|
"children": []
|
||||||
|
}, {
|
||||||
|
"name": "host13",
|
||||||
|
"state": "warning",
|
||||||
|
"children": []
|
||||||
|
}]
|
||||||
|
}, {
|
||||||
|
"name": "database",
|
||||||
|
"state": "warning",
|
||||||
|
"children": [{
|
||||||
|
"name": "host14",
|
||||||
|
"children": []
|
||||||
|
}, {
|
||||||
|
"name": "host15",
|
||||||
|
"children": []
|
||||||
|
}]
|
||||||
|
}, {
|
||||||
|
"name": "image",
|
||||||
|
"state": "ok",
|
||||||
|
"children": [{
|
||||||
|
"name": "host16",
|
||||||
|
"children": []
|
||||||
|
}, {
|
||||||
|
"name": "host17",
|
||||||
|
"children": []
|
||||||
|
}]
|
||||||
|
}]
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.physicalTopoData = angular.copy($scope.logicalTopoData);
|
||||||
|
|
||||||
|
$scope.exampleData = [{
|
||||||
|
"key": "Series 1",
|
||||||
|
"values": [
|
||||||
|
[1, 0],
|
||||||
|
[2, 6],
|
||||||
|
[3, 5],
|
||||||
|
[4, 11],
|
||||||
|
[5, 5]
|
||||||
|
]
|
||||||
|
}, {
|
||||||
|
"key": "Series 2",
|
||||||
|
"values": [
|
||||||
|
[1, 0],
|
||||||
|
[2, 10],
|
||||||
|
[3, 5],
|
||||||
|
[4, 5],
|
||||||
|
[5, 0]
|
||||||
|
]
|
||||||
|
}, {
|
||||||
|
"key": "Series 3",
|
||||||
|
"values": [
|
||||||
|
[1, 0],
|
||||||
|
[2, 6],
|
||||||
|
[3, 5],
|
||||||
|
[4, 11],
|
||||||
|
[5, 5]
|
||||||
|
]
|
||||||
|
}, {
|
||||||
|
"key": "Series 4",
|
||||||
|
"values": [
|
||||||
|
[1, 7],
|
||||||
|
[2, 14],
|
||||||
|
[3, 14],
|
||||||
|
[4, 23],
|
||||||
|
[5, 16]
|
||||||
|
]
|
||||||
|
}];
|
||||||
|
|
||||||
|
$scope.xAxisTickFormat = function() {
|
||||||
|
return function(d) {
|
||||||
|
return d3.time.format('%x')(new Date(d));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.toolTipContentFunction = function() {
|
||||||
|
return function(key, x, y, e, graph) {
|
||||||
|
console.log('tooltip content');
|
||||||
|
return 'Super New Tooltip' +
|
||||||
|
'<h1>' + key + '</h1>' +
|
||||||
|
'<p>' + y + ' at ' + x + '</p>'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/* // customize stack/line chart colors
|
||||||
|
$scope.colorFunction = function() {
|
||||||
|
var colors = ["#68bc31", "#2091cf", "#6fb3e0", "#fee074", "#f89406", "#af4e96"];
|
||||||
|
return function(d, i) {
|
||||||
|
return colors[i%6];
|
||||||
|
};
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
})
|
61
v2/src/app/monitoring/overview.tpl.html
Normal file
61
v2/src/app/monitoring/overview.tpl.html
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
<div class="page-header">
|
||||||
|
<h1>
|
||||||
|
Monitoring Overview
|
||||||
|
</h1>
|
||||||
|
</div>
|
||||||
|
<div class="row side-padding-10 top-padding-10" ng-controller="moniOverviewCtrl">
|
||||||
|
<div class="col-xs-12">
|
||||||
|
<div ng-repeat="role in logicalTopoData.children" class="well pull-left">
|
||||||
|
<span>{{role.name}}</span>
|
||||||
|
<span>{{role.children.length}}</span>
|
||||||
|
<span>{{role.state}}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-xs-12 top-padding-10" style="height: 300px">
|
||||||
|
<nvd3-stacked-area-chart
|
||||||
|
data="exampleData"
|
||||||
|
id="exampleId"
|
||||||
|
showXAxis="true"
|
||||||
|
showYAxis="true"
|
||||||
|
tooltips="true"
|
||||||
|
interactive="true"
|
||||||
|
useInteractiveGuideline="true"
|
||||||
|
toolTipContent="toolTipContentFunction()"
|
||||||
|
forceY="[0]">
|
||||||
|
<svg></svg>
|
||||||
|
</nvd3-stacked-area-chart>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-xs-12 top-padding-10">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-lg-7">
|
||||||
|
<circlepacking data="logicalTopoData"></circlepacking>
|
||||||
|
</div>
|
||||||
|
<div class="col-lg-5">
|
||||||
|
<nvd3-line-chart
|
||||||
|
data="exampleData"
|
||||||
|
id="exampleId2"
|
||||||
|
showXAxis="true"
|
||||||
|
showYAxis="true"
|
||||||
|
tooltips="true"
|
||||||
|
interactive="true"
|
||||||
|
useInteractiveGuideline="true"
|
||||||
|
toolTipContent="toolTipContentFunction()"
|
||||||
|
margin="{left:50,top:50,bottom:50,right:50}"
|
||||||
|
forceY="[0]"
|
||||||
|
showLegend="true"
|
||||||
|
legendWidth="200"
|
||||||
|
legendHeight="100">
|
||||||
|
<svg></svg>
|
||||||
|
</nvd3-line-chart>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="col-xs-12 top-padding-10">
|
||||||
|
<tree data="logicalTopoData"></tree>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
@ -119,3 +119,330 @@ angular.module('compass.charts', [])
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
.directive('circlepacking', function() {
|
||||||
|
return {
|
||||||
|
restrict: 'EAC',
|
||||||
|
scope: {
|
||||||
|
data: '='
|
||||||
|
},
|
||||||
|
link: function(scope, elem, attrs) {
|
||||||
|
//console.log(scope, elem, attrs)
|
||||||
|
var data = scope.data;
|
||||||
|
|
||||||
|
var w = 600,
|
||||||
|
h = 600,
|
||||||
|
r = 550,
|
||||||
|
x = d3.scale.linear().range([0, r]),
|
||||||
|
y = d3.scale.linear().range([0, r]),
|
||||||
|
node,
|
||||||
|
root;
|
||||||
|
|
||||||
|
var pack = d3.layout.pack()
|
||||||
|
.size([r, r])
|
||||||
|
.value(function(d) {
|
||||||
|
if (d.children === undefined || d.children.length == 0) {
|
||||||
|
return 500;
|
||||||
|
} else {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
var vis = d3.select("circlepacking").append("svg:svg", "h2") //("svg:svg", "h2")
|
||||||
|
.attr("width", w)
|
||||||
|
.attr("height", h)
|
||||||
|
.append("svg:g")
|
||||||
|
.attr("transform", "translate(" + (w - r) / 2 + "," + (h - r) / 2 + ")");
|
||||||
|
|
||||||
|
node = root = data;
|
||||||
|
|
||||||
|
var nodes = pack.nodes(root);
|
||||||
|
|
||||||
|
vis.selectAll("circle")
|
||||||
|
.data(nodes)
|
||||||
|
.enter().append("svg:circle")
|
||||||
|
.attr("class", function(d) {
|
||||||
|
return d.children ? "parent" : "child";
|
||||||
|
})
|
||||||
|
.attr("cx", function(d) {
|
||||||
|
return d.x;
|
||||||
|
})
|
||||||
|
.attr("cy", function(d) {
|
||||||
|
return d.y;
|
||||||
|
})
|
||||||
|
.attr("r", function(d) {
|
||||||
|
return d.r;
|
||||||
|
})
|
||||||
|
.attr("depth", function(d) {
|
||||||
|
return d.depth;
|
||||||
|
})
|
||||||
|
.on("click", function(d) {
|
||||||
|
return zoom(node == d ? root : d);
|
||||||
|
})
|
||||||
|
.on("mouseover", function(d) {
|
||||||
|
//console.log("mouseover ", d)
|
||||||
|
});
|
||||||
|
|
||||||
|
vis.selectAll("text")
|
||||||
|
.data(nodes)
|
||||||
|
.enter().append("svg:text")
|
||||||
|
.attr("class", function(d) {
|
||||||
|
return d.children ? "parent" : "child";
|
||||||
|
})
|
||||||
|
.attr("x", function(d) {
|
||||||
|
return d.x;
|
||||||
|
})
|
||||||
|
.attr("y", function(d) {
|
||||||
|
return d.children ? d.y + d.r + 10 : d.y;
|
||||||
|
})
|
||||||
|
.attr("dy", ".35em")
|
||||||
|
.attr("text-anchor", "middle")
|
||||||
|
.style("opacity", function(d) {
|
||||||
|
return d.r > 20 ? 1 : 0;
|
||||||
|
})
|
||||||
|
.text(function(d) {
|
||||||
|
return d.name;
|
||||||
|
});
|
||||||
|
|
||||||
|
d3.select(window).on("click", function() {
|
||||||
|
zoom(root);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
function zoom(d, i) {
|
||||||
|
var k = r / d.r / 2;
|
||||||
|
x.domain([d.x - d.r, d.x + d.r]);
|
||||||
|
y.domain([d.y - d.r, d.y + d.r]);
|
||||||
|
|
||||||
|
var t = vis.transition()
|
||||||
|
.duration(d3.event.altKey ? 7500 : 750);
|
||||||
|
|
||||||
|
t.selectAll("circle")
|
||||||
|
.attr("cx", function(d) {
|
||||||
|
return x(d.x);
|
||||||
|
})
|
||||||
|
.attr("cy", function(d) {
|
||||||
|
return y(d.y);
|
||||||
|
})
|
||||||
|
.attr("r", function(d) {
|
||||||
|
return k * d.r;
|
||||||
|
});
|
||||||
|
|
||||||
|
t.selectAll("text")
|
||||||
|
.attr("x", function(d) {
|
||||||
|
return x(d.x);
|
||||||
|
})
|
||||||
|
.attr("y", function(d) {
|
||||||
|
return d.children ? y(d.y + d.r + 10) : y(d.y);
|
||||||
|
})
|
||||||
|
.style("opacity", function(d) {
|
||||||
|
return k * d.r > 20 ? 1 : 0;
|
||||||
|
});
|
||||||
|
|
||||||
|
node = d;
|
||||||
|
d3.event.stopPropagation();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
};
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
.directive('tree', function() {
|
||||||
|
return {
|
||||||
|
restrict: 'EAC',
|
||||||
|
scope: {
|
||||||
|
data: '='
|
||||||
|
},
|
||||||
|
link: function(scope, elem, attrs) {
|
||||||
|
//console.log(scope, elem, attrs);
|
||||||
|
|
||||||
|
var json = scope.data;
|
||||||
|
var imgWidth = 163;
|
||||||
|
var imgHeight = 32;
|
||||||
|
|
||||||
|
var m = [20, 50, 20, 50],
|
||||||
|
w = 1280 - m[1] - m[3],
|
||||||
|
h = 800 - m[0] - m[2],
|
||||||
|
i = 0,
|
||||||
|
root;
|
||||||
|
|
||||||
|
var tree = d3.layout.tree()
|
||||||
|
.size([h, w]);
|
||||||
|
|
||||||
|
var diagonal = d3.svg.diagonal()
|
||||||
|
.projection(function(d) {
|
||||||
|
return [d.y, d.x];
|
||||||
|
});
|
||||||
|
|
||||||
|
var vis = d3.select("tree").append("svg:svg")
|
||||||
|
.attr("width", w + m[1] + m[3])
|
||||||
|
.attr("height", h + m[0] + m[2])
|
||||||
|
.append("svg:g")
|
||||||
|
.attr("transform", "translate(" + m[3] + "," + m[0] + ")");
|
||||||
|
|
||||||
|
root = json;
|
||||||
|
root.x0 = h / 2;
|
||||||
|
root.y0 = 0;
|
||||||
|
|
||||||
|
function toggleAll(d) {
|
||||||
|
if (d.children) {
|
||||||
|
d.children.forEach(toggleAll);
|
||||||
|
toggle(d);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
root.children.forEach(toggleAll);
|
||||||
|
|
||||||
|
update(root);
|
||||||
|
|
||||||
|
function update(source) {
|
||||||
|
var duration = d3.event && d3.event.altKey ? 5000 : 500;
|
||||||
|
|
||||||
|
// Compute the new tree layout.
|
||||||
|
var nodes = tree.nodes(root).reverse();
|
||||||
|
|
||||||
|
// Normalize for fixed-depth.
|
||||||
|
nodes.forEach(function(d) {
|
||||||
|
d.y = d.depth * 180;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Update the nodes…
|
||||||
|
var node = vis.selectAll("g.node")
|
||||||
|
.data(nodes, function(d) {
|
||||||
|
return d.id || (d.id = ++i);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Enter any new nodes at the parent's previous position.
|
||||||
|
var nodeEnter = node.enter().append("svg:g")
|
||||||
|
.attr("class", "node")
|
||||||
|
.attr("transform", function(d) {
|
||||||
|
return "translate(" + source.y0 + "," + source.x0 + ")";
|
||||||
|
})
|
||||||
|
.on("click", function(d) {
|
||||||
|
toggle(d);
|
||||||
|
update(d);
|
||||||
|
});
|
||||||
|
|
||||||
|
nodeEnter.append("image")
|
||||||
|
.attr("xlink:href", function(d) {
|
||||||
|
if (d.depth == 0)
|
||||||
|
return "assets/img/router.png";
|
||||||
|
else if (d.depth == 1)
|
||||||
|
return "assets/img/switch.png";
|
||||||
|
else
|
||||||
|
return "assets/img/server.png";
|
||||||
|
})
|
||||||
|
//.attr("class", function(d) {
|
||||||
|
// return d.type;
|
||||||
|
//})
|
||||||
|
.attr("width", imgWidth)
|
||||||
|
.attr("height", imgHeight);
|
||||||
|
|
||||||
|
|
||||||
|
nodeEnter.append("svg:text")
|
||||||
|
.attr("x", function(d) {
|
||||||
|
return d.children || d._children ? -10 : 10;
|
||||||
|
})
|
||||||
|
.attr("dy", ".35em")
|
||||||
|
.attr("text-anchor", function(d) {
|
||||||
|
return d.children || d._children ? "end" : "start";
|
||||||
|
})
|
||||||
|
.text(function(d) {
|
||||||
|
return d.name;
|
||||||
|
})
|
||||||
|
.style("fill-opacity", 1e-6);
|
||||||
|
|
||||||
|
// Transition nodes to their new position.
|
||||||
|
var nodeUpdate = node.transition()
|
||||||
|
.duration(duration)
|
||||||
|
.attr("transform", function(d) {
|
||||||
|
return "translate(" + d.y + "," + d.x + ")";
|
||||||
|
});
|
||||||
|
|
||||||
|
nodeUpdate.select("circle")
|
||||||
|
.attr("r", 4.5)
|
||||||
|
.style("fill", function(d) {
|
||||||
|
return d._children ? "lightsteelblue" : "#fff";
|
||||||
|
});
|
||||||
|
|
||||||
|
nodeUpdate.select("text")
|
||||||
|
.style("fill-opacity", 1);
|
||||||
|
|
||||||
|
// Transition exiting nodes to the parent's new position.
|
||||||
|
var nodeExit = node.exit().transition()
|
||||||
|
.duration(duration)
|
||||||
|
.attr("transform", function(d) {
|
||||||
|
return "translate(" + source.y + "," + source.x + ")";
|
||||||
|
})
|
||||||
|
.remove();
|
||||||
|
|
||||||
|
nodeExit.select("circle")
|
||||||
|
.attr("r", 1e-6);
|
||||||
|
|
||||||
|
nodeExit.select("text")
|
||||||
|
.style("fill-opacity", 1e-6);
|
||||||
|
|
||||||
|
// Update the links…
|
||||||
|
var link = vis.selectAll("path.link")
|
||||||
|
.data(tree.links(nodes), function(d) {
|
||||||
|
return d.target.id;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Enter any new links at the parent's previous position.
|
||||||
|
link.enter().insert("svg:path", "g")
|
||||||
|
.attr("class", "link")
|
||||||
|
.attr("d", function(d) {
|
||||||
|
var o = {
|
||||||
|
x: source.x0,
|
||||||
|
y: source.y0
|
||||||
|
};
|
||||||
|
return diagonal({
|
||||||
|
source: o,
|
||||||
|
target: o
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.transition()
|
||||||
|
.duration(duration)
|
||||||
|
.attr("d", diagonal);
|
||||||
|
|
||||||
|
// Transition links to their new position.
|
||||||
|
link.transition()
|
||||||
|
.duration(duration)
|
||||||
|
.attr("d", diagonal);
|
||||||
|
|
||||||
|
// Transition exiting nodes to the parent's new position.
|
||||||
|
link.exit().transition()
|
||||||
|
.duration(duration)
|
||||||
|
.attr("d", function(d) {
|
||||||
|
var o = {
|
||||||
|
x: source.x,
|
||||||
|
y: source.y
|
||||||
|
};
|
||||||
|
return diagonal({
|
||||||
|
source: o,
|
||||||
|
target: o
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.remove();
|
||||||
|
|
||||||
|
// Stash the old positions for transition.
|
||||||
|
nodes.forEach(function(d) {
|
||||||
|
d.x0 = d.x;
|
||||||
|
d.y0 = d.y;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Toggle children.
|
||||||
|
function toggle(d) {
|
||||||
|
if (d.children) {
|
||||||
|
d._children = d.children;
|
||||||
|
d.children = null;
|
||||||
|
} else {
|
||||||
|
d.children = d._children;
|
||||||
|
d._children = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
3
v2/vendor/angular-nvd3/angularjs-nvd3-directives.min.js
vendored
Normal file
3
v2/vendor/angular-nvd3/angularjs-nvd3-directives.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
v2/vendor/nvd3/nv.d3.min.css
vendored
Normal file
1
v2/vendor/nvd3/nv.d3.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
6
v2/vendor/nvd3/nv.d3.min.js
vendored
Normal file
6
v2/vendor/nvd3/nv.d3.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
Loading…
x
Reference in New Issue
Block a user