Skip to content

Instantly share code, notes, and snippets.

@twedl
Last active May 23, 2016 13:49
Show Gist options
  • Save twedl/f57503effc1ad40be3c791fe31caac2c to your computer and use it in GitHub Desktop.
Save twedl/f57503effc1ad40be3c791fe31caac2c to your computer and use it in GitHub Desktop.
Production network example
  • Production network example.
<!DOCTYPE html>
<meta charset="utf-8">
<head>
<!-- <script src="d3/d3.v4.0.0-alpha.29.min.js" charset="utf-8"></script>-->
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.16/d3.min.js" charset="utf-8"></script>
<!-- <script src="d3.min.js" charset="utf-8"></script>-->
<!--<script type="text/javascript" src="https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>-->
<style>
body {
font-family: 'Lucida Console', 'sans-serif';
text-align: center;
margin: 0;
padding: 0;
}
svg {
border: 0px solid black;
display: inline-block;
}
</style>
</head>
<body>
<!--
<p>
When $$a \ne 0$$, there are two solutions to \(ax^2 + bx + c = 0\) and they are
$$x = {-b \pm \sqrt{b^2-4ac} \over 2a}.$$
</p>
-->
<script>
'use strict';
var length = 6;
var fontsize = 12;
var network = 1, // 1=circle, 2=star
gran = 0;
// beamer is 4:3
var width=300,
height=225;
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height);
var marker = svg.append('defs')
.append('marker')
.attr("id", "Triangle")
.attr("refX", 6)
.attr("refY", 3)
.attr("markerUnits", 'userSpaceOnUse')
.attr("markerWidth", 6)
.attr("markerHeight", 9)
.attr("orient", 'auto')
.append('path')
.style("fill", "#000")
.attr("d", 'M 0 0 6 3 0 6 1.5 3');
var force = d3.layout.force()
.charge(-500)
.gravity(0.2)
.linkDistance(25)
.size([width, height]);
var position = [
{'x': 150, 'y': 112.5},
{'x': 196.755506964783, 'y': 42.8617358447538},
{'x': 229.92103967012258, 'y': 138.1027810461985},
{'x': 69.51114790124912, 'y': 135.33271180414886},
{'x': 100.16329326816928, 'y': 44.953756997444565},
{'x': 143.30268635651302, 'y': 195.8686044271658}
];
var nodes = [],
links = [];
for (var i=0; i<length; i++) {
// nodes.push({'name': i, 'radius': 10, 'x': position[i].x, 'y': position[i].y, 'fixed': false});
nodes.push({'name': i, 'radius': 10, 'fixed': false});
}
/*
var nt = letters.map(function(d) {
return {'name': d};
});
*/
var ft = svg.selectAll("text.hidden")
.data(nodes)
.enter().append("text")
.attr("class", "hidden")
.attr("visibility", "hidden")
.style("font-size", function(d,i) {
return i===0 && gran===1 ? Math.ceil(fontsize*1.2) + "px" : fontsize + "px";
})
.attr("x", function(d) { return d.x; })
.attr("y", function(d) { return d.y; })
.text(function(d) { return d.name; });
var box = ft[0].map(function(d) {
return {
'width': d.getBoundingClientRect().width,
'height': d.getBoundingClientRect().height};
}
); //return {'textWidth': d.offsetWidth, 'textHeight': d.offsetHeight}; });
/* var nodes = letters.map(function(d, i) {
return {'name': d, 'box': box[i]};
});*/
/*
nodes[0].fixed=true;
nodes[0].x=width/2;
nodes[0].y=height/2;
*/
nodes.forEach(function(d,i) {
d.box = box[i];
});
// Network asymmetry
if (network === 1) {
for (var i=0; i<length; i++) {
links.push({'source': i, 'target': (i+1)%(length)});
}
}
else if (network === 2) {
nodes[0].radius=12.5;
for (var i=1; i<length; i++) {
links.push({'source': 0, 'target': i});
}
}
// Granularity
if (gran) {
nodes[0].radius = 25;
}
var drag = force.drag()
.on("dragstart", dragstart);
force
.nodes(nodes)
.links(links)
.start();
var link = svg.selectAll(".link")
.data(links)
.enter().append("line")
.attr("class", "link")
.style("stroke-width", 1.5)
.style("stroke", "#000")
.attr("marker-end", "url(#Triangle)");
var node = svg.selectAll(".node")
.data(nodes)
.enter().append("circle")
.attr("class", "node")
.attr("r", function(d) {
return d.radius;
})
.on("dblclick", dblclick)
.style("stroke", function(d,i) {
return i===0 && (gran===1 || network===2) ? "#F00" : "#000";
})
.style("fill", function(d,i) {
return i===0 && (gran===1 || network===2) ? "#F00" : "#000";
})
.style("stroke-width", 1.5)
.style("fill", "#fff")
.call(force.drag);
var text = svg.selectAll("text.letter")
.data(nodes)
.enter().append("text")
.attr("class", "letter")
.attr("pointer-events", "none")
.style("font-size", function(d,i) {
return i===0 && gran===1 ? Math.ceil(fontsize*1.2) + "px" : fontsize + "px";
})
.style("stroke-width", function(d,i) {
return 0.3; //i===0 ? "#F00" : "#000";
})// .style("font-weight", 600)
.style("stroke", function(d,i) {
return i===0 && (gran===1 || network===2) ? "#F00" : "#000";
})
.style("fill", function(d,i) {
return i===0 && (gran===1 || network===2) ? "#F00" : "#000";
})
.attr("x", function(d) { return d.x - d.box.width/2; })
.attr("y", function(d) { return d.y + d.box.height/3; }) // /4 centers vertically, reason: total mystery.
.text(function(d) { return d.name; });
force.on("tick", function() {
link.attr("x1", function(d) { return d.source.x; })
.attr("y1", function(d) { return d.source.y; })
.attr("x2", function(d) {
var deltaX = d.target.x - d.source.x;
var deltaY = d.target.y - d.source.y;
return d.target.x - ((deltaX * d.target.radius) / Math.sqrt((deltaX * deltaX) + (deltaY * deltaY))); }) //return d.target.x; })
.attr("y2", function(d) {
var deltaX = d.target.x - d.source.x;
var deltaY = d.target.y - d.source.y;
return d.target.y - ((deltaY * d.target.radius) / Math.sqrt((deltaX * deltaX) + (deltaY * deltaY))); }); //return d.target.y; });
node.attr("cx", function(d) { return d.x; })
.attr("cy", function(d) { return d.y; });
text.attr("x", function(d) { return d.x - d.box.width/2; })
.attr("y", function(d) { return d.y + d.box.height/3; });
});
function dblclick(d) {
// d3.select(this).classed("fixed", d.fixed = false);
//console.log(nodes.map(function(d) { return [d.x, d.y]}));
//nodes.forEach(function(d) {
// console.log(d.x + "," + d.y);
//});
var position = nodes.map(function(d) {
return {'x': d.x, 'y': d.y}
})
console.log("var position = " + JSON.stringify(position));
}
function dragstart(d) {
d3.select(this).classed("fixed", d.fixed = true);
}
</script>
</body>
(function() {
'use strict';
var width=960,
height=600;
var svg = d3.select("#slide-two").append("svg")
.attr("width", width)
.attr("height", height);
var marker = d3.select("svg").append('defs')
.append('marker')
.attr("id", "Triangle")
.attr("refX", 6)
.attr("refY", 3)
.attr("markerUnits", 'userSpaceOnUse')
.attr("markerWidth", 6)
.attr("markerHeight", 9)
.attr("orient", 'auto')
.append('path')
.style("fill", "#000")
.attr("d", 'M 0 0 6 3 0 6 1.5 3');
var force = d3.layout.force()
.charge(-750)
.gravity(0.25)
.friction(0.7)
.linkStrength(1)
.linkDistance(100)
.size([width, height]);
var rad=10;
var nodes = [],
links = [],
length = 3,
i;
for (i=0; i<length; i++) {
nodes.push({'name': i, 'radius': rad * (i===0 ? 2 : 1), 'x': width/2, 'y': height/2, 'fixed': (i===0 ? true : false)});
}
for (var x=1; x<length; x++) {
links.push({'source': 0, 'target': x});
}
force
.nodes(nodes)
.links(links)
.start();
var link = svg.selectAll(".link");
var node = svg.selectAll(".node");
function nodeStart() {
// nodes.push({"id": i, "degree": 0});
nodes.push({'name': i, 'radius': rad * (i===0 ? 2 : 1), 'x': width/2, 'y': height/2, 'fixed': (i===0 ? true : false)});
node = node.data(force.nodes());
node.enter().append("circle")
.attr("class", "node")
.attr("r", function(d) { return d.radius; })
.style("stroke", "#444")
.style("fill", "#bcbcbc")
.call(force.drag);
// node.exit().remove();
force.start();
}
function linkStart() {
force.links().push({"source": 0, "target": i}); // need to add nodes too.
link = link.data(force.links()); //, function(d) { return d.source.id + "-" + d.target.id; });
link.enter().append("line")
.attr("class","link")
.style("stroke-width", 2)
.style("stroke", "#000")
.attr("marker-end", "url(#Triangle)");
link.exit().remove();
force.start();
}
//function update() {
// nodeStart();
// force.nodes()[0].degree
/*
var totalDegree=0;
for (var a=0; a<i; a++) {
totalDegree+=force.nodes()[a].degree;
}
// hmm. [0, 1*degree[1]] is 1, [1*degree[1], 1*degree[1]+2*degree[2]] is 2, etc.
for (var a=0; a<m; a++) {
j=Math.floor(Math.random()*i); // but probability that i is picked depends on degree i relative to the rest.
force.nodes()[j].degree++;
linkStart();
}
i++;
if (i>=N) {
force.stop();
// clearInterval(int);
}
*/
// console.log('(i,j): (' + i + ',' + j + ')');
//}
/*
var link = svg.selectAll(".link")
.data(links)
.enter().append("line")
.attr("class", "link")
.style("stroke-width", 2)
.style("stroke", "#000")
// .style("opacity", 0)
.attr("marker-end", "url(#Triangle)");;
var node = svg.selectAll(".node")
.data(nodes)
.enter().append("circle")
.attr("class", "node")
.attr("r", function(d) { return d.radius; })
.style("stroke", "#444")
.style("fill", "#bcbcbc")
.call(force.drag);
*/
force.on("tick", function() {
link.attr("x1", function(d) { return d.source.x; })
.attr("y1", function(d) { return d.source.y; })
.attr("x2", function(d) {
var deltaX = d.target.x - d.source.x;
var deltaY = d.target.y - d.source.y;
return d.target.x - ((deltaX * d.target.radius) / Math.sqrt((deltaX * deltaX) + (deltaY * deltaY))); }) //return d.target.x; })
.attr("y2", function(d) {
var deltaX = d.target.x - d.source.x;
var deltaY = d.target.y - d.source.y;
return d.target.y - ((deltaY * d.target.radius) / Math.sqrt((deltaX * deltaX) + (deltaY * deltaY))); }); //return d.target.y; });
node.attr("cx", function(d) { return d.x; })
.attr("cy", function(d) { return d.y; });
});
/*
var t = d3.timer(function(elapsed) {
console.log(elapsed);
// console.log(t);
if (elapsed > 200) t.stop();
}, 150);
*/
//var i=1;
change();
var t = d3_timer.interval(change, 500);
function change() {
i = i < 7 ? i+1 : 1 ;
// for j=0 to i, opacity = 1, otherwise 0.
node.transition()
// .attr("opacity", function(d,j) { return j<i ? 1 : 0 })
.attr("r", function(d,j) { return j===0 ? d.radius*(1/1) : d.radius; });
// link.transition()
// .attr("opacity", function(d,j) { return j<i-1 ? 1 : 0});
nodeStart();
linkStart();
// now all i gotta do is transition opacity?
// might add them to node list instead like other graphs.
// force.linkDistance(100*Math.sqrt(i));
//force.start();
if (i > 5) t.stop();
}
/*
function(elapsed) {
console.log(elapsed);
if (elapsed > 2000) t.stop();
}, 150);
1. Two things. Productivity and IO network. Two examples. Same slide or no?
2. Network: circle and star? Connect them to examples in paper?
2.5 Transitions?
3. Then "islands".
4. Symmetric network.
5. Show problem: you have skewed size distribution -> automatically observe skewed IO network.
6. Question is why: true requirements? or productivity + substitution?
2. Then: you observe skewed IO network no matter what. Using standard methods, if you have skewed size dist,
then you have skewed outdegree. So: question is: is it productivity or IO?
*/
})();
(function() {
'use strict';
var width=350,
height=200;
var starsvg = d3.select(".star").append("svg")
.attr("width", width)
.attr("height", height);
var circlesvg = d3.select(".circle").append("svg")
.attr("width", width)
.attr("height", height);
var starforce = d3.layout.force()
.charge(-500)
.gravity(0.1)
.linkDistance(50)
.size([width, height]);
var circleforce = d3.layout.force()
.charge(-500)
.gravity(0.1)
.linkDistance(50)
.size([width, height]);
var circle = [
{'name': 'c0'},
{'name': 'c1'},
{'name': 'c2'},
{'name': 'c3'},
{'name': 'c4'},
{'name': 'c5'}
];
var star = [
{'name': 's0.6'},
{'name': 's1.7'},
{'name': 's2.8'},
{'name': 's3.9'},
{'name': 's4.10'},
{'name': 's5.11'},
{'name': 's6'},
{'name': 's7'}
]
var starlinks = [
{'source': 0, 'target': 1},
{'source': 0, 'target': 2},
{'source': 0, 'target': 3},
{'source': 0, 'target': 4},
{'source': 0, 'target': 5},
{'source': 0, 'target': 6},
{'source': 0, 'target': 7}
];
var circlelinks = [
{'source': 0, 'target': 1},
{'source': 1, 'target': 2},
{'source': 2, 'target': 3},
{'source': 3, 'target': 4},
{'source': 4, 'target': 5},
{'source': 5, 'target': 0}
]
starforce
.nodes(star)
.links(starlinks)
.start();
circleforce
.nodes(circle)
.links(circlelinks)
.start();
var starlink = starsvg.selectAll(".link")
.data(starlinks)
.enter().append("line")
.attr("class", "link")
.style("stroke-width", 2)
.style("stroke", "#000");
var circlelink = circlesvg.selectAll(".link")
.data(circlelinks)
.enter().append("line")
.attr("class", "link")
.style("stroke-width", 2)
.style("stroke", "#000");
var starnode = starsvg.selectAll(".node")
.data(star)
.enter().append("circle")
.attr("class", "node")
.attr("r", 10)
.style("stroke", "#000")
.style("fill", "#fff")
.call(starforce.drag);
var circlenode = circlesvg.selectAll(".node")
.data(circle)
.enter().append("circle")
.attr("class", "node")
.attr("r", 10)
.style("stroke", "#000")
.style("fill", "#fff")
.call(circleforce.drag);
starforce.on("tick", function() {
starlink.attr("x1", function(d) { return d.source.x; })
.attr("y1", function(d) { return d.source.y; })
.attr("x2", function(d) { return d.target.x; })
.attr("y2", function(d) { return d.target.y; });
starnode.attr("cx", function(d) { return d.x; })
.attr("cy", function(d) { return d.y; });
});
circleforce.on("tick", function() {
circlelink.attr("x1", function(d) { return d.source.x; })
.attr("y1", function(d) { return d.source.y; })
.attr("x2", function(d) { return d.target.x; })
.attr("y2", function(d) { return d.target.y; });
circlenode.attr("cx", function(d) { return d.x; })
.attr("cy", function(d) { return d.y; });
});
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment