Skip to content

Instantly share code, notes, and snippets.

@matt-bernhardt
Last active August 29, 2015 14:15
Show Gist options
  • Save matt-bernhardt/b91e72e6f1667e865b7e to your computer and use it in GitHub Desktop.
Save matt-bernhardt/b91e72e6f1667e865b7e to your computer and use it in GitHub Desktop.
Combination of list items
svg {
font: 10px sans-serif;
}
.cell,
.label {
opacity: 0.5;
}
.cell:hover,
.label:hover {
opacity: 1;
}
/*
svg text {
font-size: 20px;
}
*/
.active {
opacity: 1;
}
// Basic parameters
var i; // counters
var _s32 = (Math.sqrt(3)/2); // constant ratio of hexagon's internal to external radius
var nodeSize = 40; // size of an individual node - this may become auto calculated
var nodeText = 12;
// need to add a label size bsaed on data label lengths
var dx = nodeSize * 1.5; // column spacing value
var dy = nodeSize * _s32; // row spacing value
var w = 800; // total plot width
var h = 500; // total plot height
// need to refactor the margin calculations...
var margin = { // this is meant to provide a margin around the plot
top: nodeSize,
right: nodeSize * 1.5,
bottom: nodeSize * 1.5,
left: 200
};
var svgContainer; // overall plot container
var label, labels, labelText; // plot labels
var hexagon, hexagons; // plot data appears in hexagons
// create container
svgContainer = d3.select("#combinations")
.append("svg")
.attr("width", w)
.attr("height", h);
// load data, build visualization
d3.json("combinations.json", function(error, data) {
if(error) {
alert("Error loading json file:\n" + error.statusText);
console.log(error);
} else {
// build node labels
buildLabels(data.nodes);
// draw hexagon grid
buildHexagons(data.combinations);
buildListeners();
}
});
// Functions
buildHexagons = function(data) {
hexagons = svgContainer.append("g")
.attr("class","hexagons");
hexagon = hexagons.selectAll("path")
.data(data)
.enter()
.append("path")
.attr("data-combination",function(d,i) {
return d.source+" "+d.target;
})
.style("fill", "rgba(255,192,192,0.5)")
.attr("stroke","rgb(64,64,64)")
.attr("d", function(d,i) {
col = margin.left + ( Math.abs(d.source - d.target) * dx );
row = ((Math.abs(d.source-d.target)/2) + Math.min(d.source,d.target)) * Math.sqrt(3) * nodeSize + margin.top;
return setHexagonPoints(col,row,nodeSize);
})
.attr("class","cell");
};
buildLabels = function(data) {
labels = svgContainer.append("g")
.attr("class","labels");
labelText = labels.selectAll("g text")
.data(data)
.enter()
.append("text")
.attr("x",nodeText)
.attr("y",function(d,i){
return (i*dy*2) + dy + nodeText/2;
})
.attr("font-size",nodeText )
.text(function(d) {
return d.name;
}); // label text
label = labels.selectAll("path")
.data(data)
.enter()
.append("path") // label drawing
.style("fill", "rgba(255,192,192,0.5)")
.attr("stroke","rgb(64,64,64)")
.attr("class","label")
.attr("data-node",function(d,i){
return i;
})
.attr("d",function(d,i) {
var startY = i * nodeSize*_s32*2 + (margin.top - nodeSize*_s32);
var path = "M 0 " + startY + " ";
path += "H " + (margin.left + dx - nodeSize) + " ";
path += "L " + (margin.left + dx - nodeSize/2) + " " + (startY + ( _s32*nodeSize ) ) + " ";
path += "L " + (margin.left + dx - nodeSize) + " " + (startY + ( _s32*nodeSize * 2) ) + " ";
path += "H 0 ";
return path;
});
};
buildListeners = function() {
$("g.hexagons path").mouseout(function() {
// reset all labels
$("g.labels").children("path").each(function() {
$(this).attr("class","label");
});
});
$("g.labels path").mouseout(function() {
// reset all labels
$("g.hexagons").children("path").each(function() {
$(this).attr("class","cell");
});
});
$("g.hexagons path").mouseover(function() {
// highlight the labels for the relevant combined node
var cl = $(this).data("combination").split(" ").sort();
for(var x in cl){
// cl[x] = +cl[x];
var needle = $("g.labels").children("path")[+cl[x]];
$(needle).attr("class","label active");
}
});
$("g.labels path").mouseover(function() {
// highlight the labels for the relevant combined node
var needle = $(this).data("node");
var haystack = $("g.hexagons path");
console.log(haystack);
for (var x = 0; x < haystack.length; x++) {
var candidate = haystack[x].attributes["data-combination"].value.split(" ").map(Number);
console.log(needle);
console.log(candidate);
console.log(typeof(candidate));
// need to be able to read the candidate's data-combination attribute
if(candidate.indexOf(needle) >= 0) {
console.log("found");
haystack[x].attributes["class"].value = "cell active";
} else {
console.log("not here");
haystack[x].attributes["class"].value = "cell";
}
console.log("");
}
});
};
setHexagonPoints = function(x,y,size) {
var hexPoints = "";
hexPoints += "M " + (size + x ) + " " + (0 + y ) + " ";
hexPoints += "L " + (size/2 + x ) + " " + (size*_s32 + y ) + " " ;
hexPoints += "L " + (-size/2 + x) + " " + (size*_s32 + y ) + " " ;
hexPoints += "L " + (-size + x ) + " " + (0 + y ) + " " ;
hexPoints += "L " + (-size/2 + x) + " " + (-size*_s32 + y) + " " ;
hexPoints += "L " + (size/2 + x ) + " " + (-size*_s32 + y) + " " ;
hexPoints += "L " + (size + x ) + " " + (0 + y ) + " " ;
return hexPoints;
};
/*
setLabelShape = function(x,y,size) {
var labelPoints = [];
labelPoints.push([0 , 0 ]);
labelPoints.push([size/2 + x , 0 ]);
labelPoints.push([size + x , _s32*size / 2 ]);
labelPoints.push([size/2 + x , _s32*size ]);
labelPoints.push([0 , _s32*size ]);
return labelPoints;
};
*/
{
"nodes":[
{"name":"Architecture + Planning"},
{"name":"Engineering"},
{"name":"Humanities, Arts, and Social Sciences"},
{"name":"Management"},
{"name":"Science"}
],
"combinations":[
{"source":0,"target":1,"value":1},
{"source":0,"target":2,"value":2},
{"source":0,"target":3,"value":3},
{"source":0,"target":4,"value":4},
{"source":1,"target":2,"value":5},
{"source":1,"target":3,"value":6},
{"source":1,"target":4,"value":7},
{"source":2,"target":3,"value":8},
{"source":2,"target":4,"value":9},
{"source":3,"target":4,"value":10}
]
}
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8">
<title>Node Combinations Graph</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js" charset="utf-8"></script>
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<link href="combinations.css" rel="stylesheet" type='text/css' />
</head>
<body>
<div id="combinations"></div>
<script src="combinations.js" charset="utf-8"></script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment