Skip to content

Instantly share code, notes, and snippets.

@fabiovalse
Last active May 4, 2017 13:00
Show Gist options
  • Save fabiovalse/64d6fdf0912d82149d051da80a86b2d1 to your computer and use it in GitHub Desktop.
Save fabiovalse/64d6fdf0912d82149d051da80a86b2d1 to your computer and use it in GitHub Desktop.
Isolario powergraph II

This gist, as the previous one, aims to analyze the outcome of power graph analysis tool.

The scatterplot shows on the x-axis the leaf count of the power nodes while on the y-axis their maximum level of depth.

(We talk about "node depth" since every power node is actually a tree.)

svg = d3.select 'body'
.append 'svg'
width = d3.select('svg').node().getBoundingClientRect().width - 50
height = d3.select('svg').node().getBoundingClientRect().height - 50
by_value = (a,b) ->
if a.value < b.value
return -1
else if a.value > b.value
return 1
else
return 0
d3.csv 'links.csv', (error, data) ->
# adding dummy root since d3 stratify does not handle multiple roots
data.forEach (d) ->
if d.parent is ""
d.parent = "root"
data.push {name: "root", parent: ""}
# tree construction
root = (d3.stratify()
.id((d) -> d.name)
.parentId((d) -> d.parent)
)(data)
root.count()
### Vis
###
vis = svg.append 'g'
margin_left = 40
data = root.children
.map (child) -> {id: child.id, value: child.value, height: child.height}
.sort by_value
x = d3.scaleLinear()
.domain [2,8500]
.range [0, width]
y = d3.scaleLinear()
.domain [1,19]
.range [height, 0]
# x-axis
vis.append 'g'
.attrs
transform: "translate(#{margin_left}, #{height})"
.call(d3.axisBottom(x))
.append 'text'
.attrs
fill: '#000'
transform: "translate(#{width}, 30)"
'text-anchor': 'end'
.text "Power Node Leaf Count"
# y-axis
vis.append 'g'
.attrs
transform: "translate(#{margin_left}, 0)"
.call(d3.axisLeft(y))
.append 'text'
.attrs
fill: '#000'
transform: 'rotate(-90)'
y: 6
dy: '0.71em'
'text-anchor': 'end'
.text "Power Node Depth"
# points
point_group = vis.append 'g'
.attrs
transform: "translate(#{margin_left}, 0)"
points = point_group.selectAll '.point'
.data data
points.enter().append 'circle'
.attrs
class: 'point'
r: 2
cx: (d) -> x d.value
cy: (d) -> y d.height
.on 'mouseover', (d) ->
d3.select(this)
.attrs
r: 5
d3.select '.info'
.attrs
transform: "translate(#{x d.value}, #{y d.height})"
d3.select '.info text'
.text "#{d.id} #{d.value} #{d.height}"
.on 'mouseout', (d) ->
d3.select(this)
.attrs
r: 2
d3.select '.info text'
.text ''
node_info = vis.append 'g'
.attrs
class: 'info'
node_info.append 'text'
.attrs
y: -10
.text ''
body, html {
width: 100%;
height: 100%;
padding: 0;
margin: 0;
}
body {
display: flex;
justify-content: center;
align-items: center;
}
svg {
width: 98%;
height: 98%;
}
.point {
fill: brown;
stroke: #303030;
stroke-width: 0.1px;
}
.info text {
pointer-events: none;
font-size: 12px;
font-family: sans-serif;
}
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Isolario Powergraph II</title>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script src="https://d3js.org/d3-selection-multi.v0.4.min.js"></script>
<link rel="stylesheet" href="index.css">
</head>
<body>
<script src="index.js"></script>
</body>
</html>
// Generated by CoffeeScript 1.10.0
(function() {
var by_value, height, svg, width;
svg = d3.select('body').append('svg');
width = d3.select('svg').node().getBoundingClientRect().width - 50;
height = d3.select('svg').node().getBoundingClientRect().height - 50;
by_value = function(a, b) {
if (a.value < b.value) {
return -1;
} else if (a.value > b.value) {
return 1;
} else {
return 0;
}
};
d3.csv('links.csv', function(error, data) {
var margin_left, node_info, point_group, points, root, vis, x, y;
data.forEach(function(d) {
if (d.parent === "") {
return d.parent = "root";
}
});
data.push({
name: "root",
parent: ""
});
root = (d3.stratify().id(function(d) {
return d.name;
}).parentId(function(d) {
return d.parent;
}))(data);
root.count();
/* Vis
*/
vis = svg.append('g');
margin_left = 40;
data = root.children.map(function(child) {
return {
id: child.id,
value: child.value,
height: child.height
};
}).sort(by_value);
x = d3.scaleLinear().domain([2, 8500]).range([0, width]);
y = d3.scaleLinear().domain([1, 19]).range([height, 0]);
vis.append('g').attrs({
transform: "translate(" + margin_left + ", " + height + ")"
}).call(d3.axisBottom(x)).append('text').attrs({
fill: '#000',
transform: "translate(" + width + ", 30)",
'text-anchor': 'end'
}).text("Power Node Leaf Count");
vis.append('g').attrs({
transform: "translate(" + margin_left + ", 0)"
}).call(d3.axisLeft(y)).append('text').attrs({
fill: '#000',
transform: 'rotate(-90)',
y: 6,
dy: '0.71em',
'text-anchor': 'end'
}).text("Power Node Depth");
point_group = vis.append('g').attrs({
transform: "translate(" + margin_left + ", 0)"
});
points = point_group.selectAll('.point').data(data);
points.enter().append('circle').attrs({
"class": 'point',
r: 2,
cx: function(d) {
return x(d.value);
},
cy: function(d) {
return y(d.height);
}
}).on('mouseover', function(d) {
d3.select(this).attrs({
r: 5
});
d3.select('.info').attrs({
transform: "translate(" + (x(d.value)) + ", " + (y(d.height)) + ")"
});
return d3.select('.info text').text(d.id + " " + d.value + " " + d.height);
}).on('mouseout', function(d) {
d3.select(this).attrs({
r: 2
});
return d3.select('.info text').text('');
});
node_info = vis.append('g').attrs({
"class": 'info'
});
return node_info.append('text').attrs({
y: -10
}).text('');
});
}).call(this);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment