Skip to content

Instantly share code, notes, and snippets.

@tcjr
Created April 25, 2012 21:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tcjr/12d053afef31e18ac50a to your computer and use it in GitHub Desktop.
Save tcjr/12d053afef31e18ac50a to your computer and use it in GitHub Desktop.
dojo and d3 (wip)
define([
'dojo/ready',
'../data/songs',
'../nav',
'raw/d3.v2.min' // Non-AMD. This Defines the global variable d3
],function(ready, songStore){
var thePage = {};
var color = d3.scale.category20c();
function maxY(d) {
return d.children ? Math.max.apply(Math, d.children.map(maxY)) : d.y + d.dy;
}
// http://www.w3.org/WAI/ER/WD-AERT/#color-contrast
function brightness(rgb) {
return rgb.r * .299 + rgb.g * .587 + rgb.b * .114;
}
function isParentOf(p, c) {
//console.debug("iPO called with %o,%o",p,c)
if (p === c) return true;
if (p.values) {
return p.values.some(function(d) {
return isParentOf(d, c);
});
}
return false;
}
console.debug("d3 = %o", d3);
ready(function(){
var nested = d3.nest()
.key(function(d) { return d['Genre']; }).sortKeys(d3.ascending)
.key(function(d) { return d['Artist']; }).sortKeys(d3.ascending)
.entries(songStore.data)
console.debug("nested songStore is %o", nested);
var w = 840,
h = w,
r = w / 2,
x = d3.scale.linear().range([0, 2 * Math.PI]),
y = d3.scale.pow().exponent(1.3).domain([0, 1]).range([0, r]),
p = 5,
duration = 1000;
var div = d3.select('#vis');
var vis = div.append("svg")
.attr("width", w + p * 2)
.attr("height", h + p * 2)
.append("g")
.attr("transform", "translate(" + (r + p) + "," + (r + p) + ")");
div.append("p")
.attr("id", "intro")
.text("Click to zoom!");
var partition = d3.layout.partition()
.value(function(d) { console.debug("value called; d=%o; returning %o",d, 5.8-d.depth); return 5.8-d.depth; }); //?????
var arc = d3.svg.arc()
.startAngle(function(d) { return Math.max(0, Math.min(2 * Math.PI, x(d.x))); })
.endAngle(function(d) { return Math.max(0, Math.min(2 * Math.PI, x(d.x + d.dx))); })
.innerRadius(function(d) { return Math.max(0, d.y ? y(d.y) : d.y); })
.outerRadius(function(d) { return Math.max(0, y(d.y + d.dy)); });
var nodes = partition
.children(function(n){ return n.values; })
.nodes({key:"Genres", values:nested})
console.debug("nodes = %o", nodes)
var path = vis.selectAll("path").data(nodes);
path.enter().append("path")
.attr("id", function(d, i) { return "path-" + i; })
.attr("d", arc)
.attr("fill-rule", "evenodd")
//.style("fill", function(d) { return color((d.children ? d : d.parent).Key); })
.style("fill", function(d) {
return color( d.key ? d.key : d.parent.key );
})
.on("click", click);
var text = vis.selectAll("text").data(nodes);
var textEnter = text.enter().append("text")
.style("opacity", 1)
// .style("fill", function(d) {
// return brightness(d3.rgb(colour(d))) < 125 ? "#eee" : "#000";
// })
.attr("text-anchor", function(d) {
return x(d.x + d.dx / 2) > Math.PI ? "end" : "start";
})
.attr("dy", ".2em")
.attr("transform", function(d) {
var multiline = (d.name || "").split(" ").length > 1,
angle = x(d.x + d.dx / 2) * 180 / Math.PI - 90,
rotate = angle + (multiline ? -.5 : 0);
return "rotate(" + rotate + ")translate(" + (y(d.y) + p) + ")rotate(" + (angle > 90 ? -180 : 0) + ")";
})
.on("click", click);
textEnter.append("tspan")
.attr("x", 0)
.text(function(d) {
// quick and dirty for now
return (d.depth==3) ? d['Name'] :
(d.depth==1 || d.depth==2) ? d.key : '';
});
// textEnter.append("tspan")
// .attr("x", 0)
// .attr("dy", "1em")
// .text(function(d) { return d.depth ? d.name.split(" ")[1] || "" : ""; });
//
function click(d) {
path.transition()
.duration(duration)
.attrTween("d", arcTween(d));
// Somewhat of a hack as we rely on arcTween updating the scales.
text
.style("visibility", function(e) {
return isParentOf(d, e) ? null : d3.select(this).style("visibility");
})
.transition().duration(duration)
.attrTween("text-anchor", function(d) {
return function() {
return x(d.x + d.dx / 2) > Math.PI ? "end" : "start";
};
})
.attrTween("transform", function(d) {
var multiline = (d.name || "").split(" ").length > 1;
return function() {
var angle = x(d.x + d.dx / 2) * 180 / Math.PI - 90,
rotate = angle + (multiline ? -.5 : 0);
return "rotate(" + rotate + ")translate(" + (y(d.y) + p) + ")rotate(" + (angle > 90 ? -180 : 0) + ")";
};
})
.style("opacity", function(e) { return isParentOf(d, e) ? 1 : 1e-6; })
.each("end", function(e) {
d3.select(this).style("visibility", isParentOf(d, e) ? null : "hidden");
});
}
// Interpolate the scales!
function arcTween(d) {
var my = maxY(d),
xd = d3.interpolate(x.domain(), [d.x, d.x + d.dx]),
yd = d3.interpolate(y.domain(), [d.y, my]),
yr = d3.interpolate(y.range(), [d.y ? 20 : 0, r]);
return function(d) {
return function(t) { x.domain(xd(t)); y.domain(yd(t)).range(yr(t)); return arc(d); };
};
}
});
return thePage;
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment