Skip to content

Instantly share code, notes, and snippets.

@enjalot
Last active December 16, 2015 09:08
Show Gist options
  • Save enjalot/5410521 to your computer and use it in GitHub Desktop.
Save enjalot/5410521 to your computer and use it in GitHub Desktop.
phase change
{"editor_editor":{"coffee":false,"vim":false,"emacs":false,"width":511,"height":670,"hide":false},"endpoint":"","description":"phase change","display":"svg","public":true,"require":[],"fileconfigs":{"_.md":{"default":true,"vim":false,"emacs":false,"fontSize":12},"config.json":{"default":true,"vim":false,"emacs":false,"fontSize":12},"inlet.js":{"default":true,"vim":false,"emacs":false,"fontSize":12},"inlet.svg":{"default":true,"vim":false,"emacs":false,"fontSize":12}},"fullscreen":false,"play":false,"loop":false,"restart":false,"autoinit":true,"pause":true,"loop_type":"period","bv":false,"nclones":15,"clone_opacity":0.4,"duration":3000,"ease":"linear","dt":0.01,"thumbnail":"http://i.imgur.com/mrOTqz8.png","ajax-caching":true}
tributary.trace = false;
var cw = 500;
var ch = 400;
var cx = 50;
var cy = 100;
var dur = 9000;
var candcolor = "#000000";
var levelcs = d3.scale.category20();
var data = [
[{s:0,d:0}, {s:1,d:2}, {s:2,d:8}, {s:3,d:1}, {s:4,d:3}],
[{s:0,d:0}, {s:1,d:6}, {s:2,d:3}, {s:3,d:2}, {s:4,d:6}],
[{s:0,d:0}, {s:1,d:4}, {s:2,d:2}, {s:3,d:1}, {s:4,d:5}],
[{s:0,d:0}, {s:1,d:7}, {s:2,d:1}, {s:3,d:3}, {s:4,d:1}],
[{s:0,d:0}, {s:1,d:3}, {s:2,d:2}, {s:3,d:2}, {s:4,d:4}],
[{s:0,d:0}, {s:1,d:5}, {s:2,d:3}, {s:3,d:5}, {s:4,d:3}],
[{s:0,d:0}, {s:1,d:4}, {s:2,d:6}, {s:3,d:3}, {s:4,d:2}],
[{s:0,d:0}, {s:1,d:4}],
[{s:0,d:0}, {s:1,d:2}, {s:2,d:5}],
[{s:0,d:0}, {s:1,d:4}, {s:2,d:2}],
[{s:0,d:0}, {s:1,d:2}, {s:2,d:1}, {s:3,d:5}],
[{s:0,d:0}, {s:1,d:10}],
[{s:0,d:0}, {s:1,d:9}, {s:2,d:3}],
[{s:0,d:0}, {s:1,d:4}, {s:2,d:6}, {s:3,d:6}]
];
//accumulate # of days in each datum and store it in c attribute
var sum;
var maxsum = 0;
data.forEach(function(d) {
sum = 0;
d.forEach(function(v) {
sum += v.d;
v.c = sum;
})
if(sum > maxsum) { maxsum = sum; }
});
//add a point below each change to make "steps"
var linedata = []
var td;
data.forEach(function(d) {
td = [];
d.forEach(function(v,i) {
if(i > 0) {
//d.splice(i, 0, {s: v.s - 1, d:v.d, c:v.c})
td.push({s: v.s - 1, d:v.d, c:v.c})
}
td.push(v);
})
linedata.push(td);
});
//console.log(data)
var levels = ["one", "two", "three", "four", "five"];
var yscale = d3.scale.ordinal()
.domain(d3.range(levels.length))
.rangeBands([ch, 0], 0.1)
var xscale = d3.scale.linear()
.domain([0, maxsum])
.range([0, cw])
var line = d3.svg.line()
.x(function(d, i) {
return xscale(d.c);
})
.y(function(d,i) {
return yscale(d.s) + yscale.rangeBand()*.5// * Math.random();
})
.interpolate("basis")
var svg = d3.select("svg");
var chart = svg.append("g")
.attr("transform", "translate(" + [cx, cy] + ")")
chart.selectAll("rect.level")
.data(levels)
.enter()
.append("rect")
.attr({
x: 0,
y: function(d,i) {
return yscale(i)
},
width: cw,
height: yscale.rangeBand(),
fill: function(d,i) {
return levelcs(i)
},
"fill-opacity": 0.6
})
var cands = chart.selectAll("g.cand")
.data(linedata)
.enter()
.append("g")
.classed("cand", true);
cands
.append("path")
.attr({
d: line,
fill: "none",
stroke: candcolor,
"stroke-width": 4,
"stroke-opacity": 0.5,
"stroke-dasharray": function() {
var tracklength = this.getTotalLength();
return tracklength + " " + tracklength;
},
"stroke-dashoffset": function() {
return this.getTotalLength();
},
//visibility: "hidden"
})
var cp = svg.append("defs")
.append("clipPath")
.attr("id", "clipper")
cp.append("rect")
.attr({
x: 0,
y: 0,
width: 1,
height: ch
})
//TODO: use a symbol
cands
.append("circle")
.classed("cand", true)
.attr({
r: 5,
transform: function(d,i) {
var v = d[0];
var x = xscale(v.c);
var y = yscale(v.s) + yscale.rangeBand()*.5;
return "translate(" + [x,y] + ")";
},
fill: candcolor,
"fill-opacity": 1,
stroke: candcolor,
"stroke-width": 3,
"stroke-opacity": 0.6
})
svg.on("click", function() {
cp.select("rect")
.transition()
.duration(dur)
.ease("linear")
.attr({
width: cw
})
cands.each(function(d,i) {
var dis = d3.select(this);
dis.select("circle")
.transition()
.duration(dur)
.ease("linear")
.attrTween("transform", translateAlong(dis.select("path").node()))
dis.select("path")
.transition()
.duration(dur)
.ease("linear")
.attrTween("stroke-dashoffset", revealAlong)
// .attrTween("stroke-dashoffset", revealAlong(dis.select("path").node()))
})
})
function translateAlong(path) {
var l = path.getTotalLength();
return function(d, i, a) {
var v = d[d.length-1];
l *= maxsum / v.c;
return function(t) {
var p = path.getPointAtLength(t * l);
return "translate(" + p.x + "," + p.y + ")";
};
};
}
function revealAlong(d, i, a) {
var l = this.getTotalLength();
var v = d[d.length-1];
//l *= maxsum / v.c;
return function(t) {
t *= maxsum / v.c
if(t > 1) { t = 1}
return l * (1-t);
};
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment