Last active
August 22, 2016 02:25
-
-
Save 1wheel/d8994223339c9b546bf0 to your computer and use it in GitHub Desktop.
tier-layout
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"tiers": [ | |
{"id": "TierI"}, | |
{"id": "TierII"}, | |
{"id": "TierIII"}, | |
{"id": "TierVI"} | |
], | |
"groups": [ | |
{"id": "gA", "tier": "TierI"}, | |
{"id": "gB", "tier": "TierI"}, | |
{"id": "gC", "tier": "TierII"}, | |
{"id": "gD", "tier": "TierIII"}, | |
{"id": "gE", "tier": "TierIII"}, | |
{"id": "gF", "tier": "TierIII"}, | |
{"id": "gG", "tier": "TierVI"}, | |
{"id": "gH", "tier": "TierVI"} | |
], | |
"nodes": [ | |
{"id": "n2", "group": "gA"}, | |
{"id": "n3", "group": "gA"}, | |
{"id": "n4", "group": "gA"}, | |
{"id": "n5", "group": "gB"}, | |
{"id": "n6", "group": "gB"}, | |
{"id": "n7", "group": "gC"}, | |
{"id": "n8", "group": "gC"}, | |
{"id": "n9", "group": "gC"}, | |
{"id": "n10", "group": "gC"}, | |
{"id": "n11", "group": "gD"}, | |
{"id": "n12", "group": "gD"}, | |
{"id": "n13", "group": "gD"}, | |
{"id": "n14", "group": "gD"}, | |
{"id": "n15", "group": "gD"}, | |
{"id": "n16", "group": "gD"}, | |
{"id": "n17", "group": "gD"}, | |
{"id": "n18", "group": "gD"}, | |
{"id": "n19", "group": "gD"}, | |
{"id": "n20", "group": "gE"}, | |
{"id": "n21", "group": "gF"}, | |
{"id": "n22", "group": "gF"}, | |
{"id": "n23", "group": "gF"}, | |
{"id": "n24", "group": "gF"}, | |
{"id": "n25", "group": "gG"}, | |
{"id": "n26", "group": "gG"}, | |
{"id": "n27", "group": "gG"}, | |
{"id": "n28", "group": "gH"}, | |
{"id": "n29", "group": "gH"} | |
], | |
"links":[ | |
{"source": "gA", "target": "gB"}, | |
{"source": "gA", "target": "gC"}, | |
{"source": "gB", "target": "gC"}, | |
{"source": "gH", "target": "gF"}, | |
{"source": "gH", "target": "gG"}, | |
{"source": "gH", "target": "gE"}, | |
{"source": "gD", "target": "gE"}, | |
{"source": "gD", "target": "gC"} | |
] | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<meta charset="utf-8"> | |
<style> | |
body { | |
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; | |
width: 960px; | |
position: relative; | |
margin: 0px auto; | |
color: rgb(105, 104, 104); | |
} | |
text{ | |
fill: rgb(61, 61, 61); | |
} | |
.group-circle{ | |
fill: white; | |
} | |
.node-circle{ | |
stroke: darkgrey; | |
fill: lightgrey; | |
} | |
.group-text{ | |
text-shadow: 0 3px 0 #fff, 3px 0 0 #fff, 0 -3px 0 #fff, -3px 0 0 #fff; | |
} | |
.link{ | |
fill: none; | |
stroke: black; | |
stroke-width: 3px; | |
} | |
</style> | |
<body></body> | |
<script src="http://d3js.org/d3.v3.min.js"></script> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/2.4.1/lodash.js"></script> | |
<script src="script.js"></script> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function f(str){ return function(obj){ return obj[str] }} | |
var width = 960, | |
height = 800 | |
var margin = {top: 50, right: 10, bottom: 20, left: 100} | |
var svg = d3.select("body").append("svg") | |
.attr("width", width + margin.left + margin.right) | |
.attr("height", height + margin.top + margin.bottom) | |
.append("g") | |
.attr("transform", "translate(" + margin.left + "," + margin.top + ")") | |
// svg.append('defs').append('marker') | |
// .attr({id: 'arrow', markerWidth: 13, marketHeight: 13, refx: 2, refy: 7, orient: 'auto'}) | |
// .append('path') | |
// .attr('d', "M2,2 L2,13 L8,7 L2,2") | |
var svgBB = svg.node().getBoundingClientRect() | |
var linkG = svg.append('g') | |
d3.json('data.json', function(data){ | |
var tiers = data.tiers, | |
groups = data.groups, | |
nodes = data.nodes, | |
links = data.links, | |
allIds = tiers.concat(groups).concat(nodes) | |
d3.nest() | |
.key(f('tier')) | |
.entries(groups) | |
.forEach(function(d){ | |
var tier = _.findWhere(tiers, {id: d.key}) | |
tier.values = d.values | |
tier.values.forEach(function(d){ d.tier = tier }) | |
}) | |
d3.nest() | |
.key(f('group')) | |
.entries(nodes) | |
.forEach(function(d){ | |
var group = _.findWhere(groups, {id: d.key}) | |
group.values = d.values | |
var root = Math.ceil(Math.sqrt(group.values.length)) | |
group.values.forEach(function(d, i){ | |
d.group = group | |
d.x = (i % root)*24 | |
d.y = Math.floor(i/root)*24 | |
}) | |
}) | |
links.forEach(function(d){ | |
d.src = _.findWhere(allIds, {id: d.source}) | |
d.tgt = _.findWhere(allIds, {id: d.target}) | |
}) | |
tiers.concat(groups).forEach(function(d){ if (!d.values) d.values = [] }) | |
var tierGs = svg.selectAll('.tier') | |
.data(tiers).enter() | |
.append('g') | |
.attr('transform', function(d, i){ | |
return 'translate(0,' + i/tiers.length*height + ')' }) | |
tierGs.append('text').classed('tier-text', true) | |
.text(f('id')) | |
.attr({'dy': '-1.3em', dx: '0', 'font-weight': 'bold', 'font-size': '120%'}) | |
.call(saveEl) | |
var groupGs = tierGs.selectAll('g') | |
.data(f('values')).enter() | |
.append('g') | |
.attr('transform', function(d, i){ | |
return 'translate(' + (1 + i)/(1 + d.tier.values.length)*width + ',0)' }) | |
groupGs.append('circle') | |
groupGs.append('text').classed('group-text', true) | |
.text(f('id')) | |
.attr({'dy': '-1.3em', dx: '-30'}) | |
.call(saveEl) | |
groupGs.selectAll('circle').classed('group-circle', true) | |
.attr('cx', function(d){ return d.sbb.x + d.sbb.width/2 }) | |
.attr('cy', function(d){ return d.sbb.y + d.sbb.height/2 }) | |
.attr('r', 18) | |
var nodeGs = groupGs.selectAll('g') | |
.data(f('values')).enter() | |
.append('g') | |
.attr('transform', function(d, i){ | |
return 'translate(' + d.x + ',' + d.y + ')' }) | |
nodeGs.append('circle').classed('node-circle', true) | |
.attr('r', 10) | |
nodeGs.append('text').classed('node-text', true) | |
.text(f('id')) | |
.attr({dy: '.33em', 'text-anchor': 'middle', 'font-size': '60%'}) | |
.call(saveEl) | |
var links = linkG.selectAll('path') | |
.data(links).enter() | |
.append('path').classed('link', true) | |
.attr('d', function(d){ | |
return ['M', d.src.p, 'L', d.tgt.p].join(' ') | |
//beziers? | |
// var yDiff = d.src.p[1] - d.tgt.p[1] | |
// var c1 = d.src.p.slice() | |
// var c2 = d.tgt.p.slice() | |
// c1[1] += yDiff/5; | |
// c2[1] -= yDiff/5*4; | |
// return ['M', d.src.p, 'C', c1, c2, d.tgt.p].join(' ') | |
}) | |
function saveEl(sel){ | |
sel.each(function(d){ | |
d.sel = d3.select(this) | |
d.sbb = d.sel.node().getBBox() | |
d.bb = offsetBB(d.sel.node().getBoundingClientRect()) | |
d.p = [d.bb.left + d.bb.width/2, d.bb.top + d.bb.height/2] | |
}) | |
} | |
}) | |
function offsetBB(bb){ | |
var obj = {width: bb.width, height: bb.height, left: bb.left, top : bb.top} | |
obj.left -= svgBB.left | |
obj.top -= svgBB.top | |
return obj | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment