Skip to content

Instantly share code, notes, and snippets.

@enjalot
Created June 14, 2013 06:06
Show Gist options
  • Save enjalot/5779793 to your computer and use it in GitHub Desktop.
Save enjalot/5779793 to your computer and use it in GitHub Desktop.
scaler
{"description":"scaler","endpoint":"","display":"div","public":true,"require":[],"fileconfigs":{"inlet.js":{"default":true,"vim":false,"emacs":false,"fontSize":12},"style.css":{"default":true,"vim":false,"emacs":false,"fontSize":12},"scaler.js":{"default":true,"vim":false,"emacs":false,"fontSize":12},"_.md":{"default":true,"vim":false,"emacs":false,"fontSize":12},"config.json":{"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/FrUlLjS.png"}
var display = d3.select("#display");
var scale = d3.scale.linear()
.domain([0, 255])
.range(["a", "z"])
var scaler = d3.scaler()
.scale(scale);
var container = display.append("div")
.attr("id", "scaler");
container.call(scaler);
scaler.on("update", function() {
scale.interpolate(function(a,b) {
return function(t) {
return [a,b][Math.round(t)];
}
})
})
d3.scaler = function() {
var scale;
var height = 300;
var max;
var min;
var selection;
var dispatch = d3.dispatch("update");
var drag = d3.behavior.drag()
.on("drag", function(d,i) {
var y = getY(i);
if(!y && y !== 0) return;
var dy = d3.event.dy;
y += dy;
if(y > max) y = max;
if(y < min) y = min;
//move things around
setY(i, y);
//sort & reorder the domain and range
var domain = scale.domain();
var range = scale.range();
var zipped = d3.zip(domain, range);
zipped.sort(function(a,b) {
return a[0] - b[0];
})
domain = zipped.map(function(d) { return d[0] })
range = zipped.map(function(d) { return d[1] })
scaler.update();
})
var scaler = function(g) {
selection = g;
scaler._update();
}
dispatch.on("update.internal", function() {
scaler._update();
});
scaler._update = function() {
selection.each(function() {
var sel = d3.select(this);
var domain = scale.domain();
var range = scale.range();
//background. TODO: use svg?
var bg = sel.selectAll("div.background")
.data([0])
bg.enter().append("div").classed("background",true)
bg.style({
width: 10+"px",
height: height+ "px",
"background-color":"grey"
})
bg.on("dblclick", function() {
var domain = scale.domain();
var range = scale.range();
var y = d3.mouse(this)[1];
var i = d3.bisect(domain, y);
domain.splice(i, 0, y);
range.splice(i, 0, "");
scaler.update();
});
//handle things
var handles = sel.selectAll("div.handle")
.data(domain)
var handlesEnter = handles.enter().append("div").classed("handle", true);
//the input
handlesEnter.append("input").classed("ascii", true)
.on("mouseup", function() { this.select(); d3.event.cancelBubble = true; })
.on("keyup", function(d,i) {
setX(i, this.value);
scaler.update();
})
.attr("maxlength", 1);
//the number
handlesEnter.append("span.number")
.classed("number", true)
handlesEnter.call(drag)
handles.style("top", function(d,i) {
return getY(i) + "px";
})
handles.select(".number")
.text(function(d,i) {
return getY(i)
})
handles.select(".ascii")
.attr("value", function(d,i) {
return getX(i);
})
})
}
scaler.scale = function(_) {
if(!arguments.length) return scale;
scale = _;
max = d3.max(scale.domain());
min = d3.min(scale.domain());
return scaler;
}
function getY(i) {
var domain = scale.domain();
return domain[i];
}
function setY(i, v) {
var domain = scale.domain();
domain[i] = v;
}
function getX(i) {
var range = scale.range();
return range[i];
}
function setX(i, v) {
var range = scale.range();
range[i] = v;
}
d3.rebind(scaler, dispatch, "on", "update")
return scaler;
}
#scaler {
position:absolute;
top: 100px;
left: 100px;
width: 100px;
}
.background {
}
.handle {
position: absolute;
border: 1px solid black;
}
input.ascii {
width: 30px !important;
height: 20px;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment