Succinct graphing with d3-jetpack.
Compare to the original.
Succinct graphing with d3-jetpack.
Compare to the original.
function ƒ(){ | |
var functions = arguments | |
//convert all string arguments into field accessors | |
var i = functions.length | |
while (i--){ | |
if (typeof(functions[i]) === 'string'){ | |
functions[i] = (function(str){ | |
return function(d){ return d[str] } | |
})(functions[i]) | |
} | |
} | |
//return composition of functions | |
return function(d){ | |
var j = functions.length | |
while(j--) d = functions[j].call(this, d) | |
return d | |
} | |
} | |
(function() { | |
function jetpack(d3) { | |
d3.selection.prototype.translate = function(xy) { | |
return this.attr('transform', function(d,i) { | |
return 'translate('+[typeof xy == 'function' ? xy(d,i) : xy]+')'; | |
}); | |
}; | |
d3.transition.prototype.translate = function(xy) { | |
return this.attr('transform', function(d,i) { | |
return 'translate('+[typeof xy == 'function' ? xy(d,i) : xy]+')'; | |
}); | |
}; | |
d3.selection.prototype.tspans = function(lines, lh) { | |
return this.selectAll('tspan') | |
.data(lines) | |
.enter() | |
.append('tspan') | |
.text(function(d) { return d; }) | |
.attr('x', 0) | |
.attr('dy', lh || 15); | |
}; | |
d3.selection.prototype.append = | |
d3.selection.enter.prototype.append = function(name) { | |
var n = d3_parse_attributes(name), s; | |
//console.log(name, n); | |
name = n.attr ? n.tag : name; | |
name = d3_selection_creator(name); | |
s = this.select(function() { | |
return this.appendChild(name.apply(this, arguments)); | |
}); | |
return n.attr ? s.attr(n.attr) : s; | |
}; | |
d3.selection.prototype.insert = | |
d3.selection.enter.prototype.insert = function(name, before) { | |
var n = d3_parse_attributes(name), s; | |
name = n.attr ? n.tag : name; | |
name = d3_selection_creator(name); | |
before = d3_selection_selector(before); | |
s = this.select(function() { | |
return this.insertBefore(name.apply(this, arguments), before.apply(this, arguments) || null); | |
}); | |
return n.attr ? s.attr(n.attr) : s; | |
}; | |
d3.selection.prototype.appendData = function(name, data){ | |
return this.selectAll('#zzzzzz') | |
.data(data) | |
.enter() | |
.append(name) | |
} | |
var d3_parse_attributes_regex = /([\.#])/g; | |
function d3_parse_attributes(name) { | |
if (typeof name === "string") { | |
var attr = {}, | |
parts = name.split(d3_parse_attributes_regex), p; | |
name = parts.shift(); | |
while ((p = parts.shift())) { | |
if (p == '.') attr['class'] = attr['class'] ? attr['class'] + ' ' + parts.shift() : parts.shift(); | |
else if (p == '#') attr.id = parts.shift(); | |
} | |
return attr.id || attr['class'] ? { tag: name, attr: attr } : name; | |
} | |
return name; | |
} | |
function d3_selection_creator(name) { | |
return typeof name === "function" ? name : (name = d3.ns.qualify(name)).local ? function() { | |
return this.ownerDocument.createElementNS(name.space, name.local); | |
} : function() { | |
return this.ownerDocument.createElementNS(this.namespaceURI, name); | |
}; | |
} | |
function d3_selection_selector(selector) { | |
return typeof selector === "function" ? selector : function() { | |
return this.querySelector(selector); | |
}; | |
} | |
d3.wordwrap = function(line, maxCharactersPerLine) { | |
var w = line.split(' '), | |
lines = [], | |
words = [], | |
maxChars = maxCharactersPerLine || 40, | |
l = 0; | |
w.forEach(function(d) { | |
if (l+d.length > maxChars) { | |
lines.push(words.join(' ')); | |
words.length = 0; | |
l = 0; | |
} | |
l += d.length; | |
words.push(d); | |
}); | |
if (words.length) { | |
lines.push(words.join(' ')); | |
} | |
return lines; | |
}; | |
d3.ascendingKey = function(key) { | |
return typeof key == 'function' ? function (a, b) { | |
return key(a) < key(b) ? -1 : key(a) > key(b) ? 1 : key(a) >= key(b) ? 0 : NaN; | |
} : function (a, b) { | |
return a[key] < b[key] ? -1 : a[key] > b[key] ? 1 : a[key] >= b[key] ? 0 : NaN; | |
}; | |
}; | |
d3.descendingKey = function(key) { | |
return typeof key == 'function' ? function (a, b) { | |
return key(b) < key(a) ? -1 : key(b) > key(a) ? 1 : key(b) >= key(a) ? 0 : NaN; | |
} : function (a, b) { | |
return b[key] < a[key] ? -1 : b[key] > a[key] ? 1 : b[key] >= a[key] ? 0 : NaN; | |
}; | |
}; | |
d3.conventions = function(c){ | |
c = c || {} | |
c.margin = c.margin || {top: 30, right: 30, bottom: 30, left: 30} | |
c.width = c.width || 960 - c.margin.left - c.margin.right | |
c.height = c.height || 500 - c.margin.top - c.margin.bottom | |
c.parentSel = c.parentSel || d3.select('body') | |
c.svg = c.svg || c.parentSel.append("svg") | |
.attr("width", c.width + c.margin.left + c.margin.right) | |
.attr("height", c.height + c.margin.top + c.margin.bottom) | |
.append("g") | |
.attr("transform", "translate(" + c.margin.left + "," + c.margin.top + ")") | |
c.color = c.color || d3.scale.category10() | |
c.x = c.x || d3.scale.linear().range([0, c.width]) | |
c.y = c.y || d3.scale.linear().range([c.height, 0]) | |
c.rScale = c.rScale || d3.scale.sqrt().range([5, 20]) | |
c.line = c.line || d3.svg.line() | |
c.xAxis = c.xAxis || d3.svg.axis().scale(c.x).orient("bottom"); | |
c.yAxis = c.yAxis || d3.svg.axis().scale(c.y).orient("left") | |
c.drawAxis = function(){ | |
c.svg.append("g") | |
.attr("class", "x axis") | |
.attr("transform", "translate(0," + c.height + ")") | |
.call(c.xAxis); | |
c.svg.append("g") | |
.attr("class", "y axis") | |
.call(c.yAxis); | |
} | |
return c | |
} | |
d3.attachTooltip = function(sel, fieldFns){ | |
sel | |
.on('mouseover', ttDisplay) | |
.on('mousemove', ttMove) | |
.on('mouseout', ttHide) | |
fieldFns = fieldFns || d3.keys(sel.datum()).map(function(str){ | |
return function(d){ return str + ': <b>' + d[str] + '</b>'} }) | |
function ttDisplay(d){ | |
d3.select('.tooltip') | |
.classed('tooltip-hidden', false) | |
.html('') | |
.appendData('div', fieldFns) | |
.html(function(fn){ return fn(d) }) | |
d3.select(this).classed('tooltipped', true) | |
} | |
function ttMove(d){ | |
var tt = d3.select('.tooltip') | |
if (!tt.size()) return | |
var e = d3.event, | |
x = e.clientX, | |
y = e.clientY, | |
doctop = (window.scrollY)? window.scrollY : (document.documentElement && document.documentElement.scrollTop)? document.documentElement.scrollTop : document.body.scrollTop; | |
n = tt.node(), | |
nBB = n.getBoundingClientRect() | |
tt.style('top', (y+doctop-nBB.height-18)+"px"); | |
tt.style('left', Math.min(Math.max(0, (x-nBB.width/2)), window.innerWidth - nBB.width)+"px"); | |
} | |
function ttHide(d){ | |
d3.select('.tooltip').classed('tooltip-hidden', true); | |
d3.selectAll('.tooltipped').classed('tooltipped', false) | |
} | |
} | |
d3.compose = function(){ | |
var functions = arguments | |
return function(d){ | |
var i = functions.length | |
while(i--) d = functions[i].call(this, d) | |
return d | |
} | |
} | |
} | |
if (typeof d3 === 'object' && d3.version) jetpack(d3); | |
else if (typeof define === 'function' && define.amd) { | |
define(['d3'], jetpack); | |
} | |
})(); |
sepalLength | sepalWidth | petalLength | petalWidth | species | |
---|---|---|---|---|---|
5.1 | 3.5 | 1.4 | 0.2 | setosa | |
4.9 | 3.0 | 1.4 | 0.2 | setosa | |
4.7 | 3.2 | 1.3 | 0.2 | setosa | |
4.6 | 3.1 | 1.5 | 0.2 | setosa | |
5.0 | 3.6 | 1.4 | 0.2 | setosa | |
5.4 | 3.9 | 1.7 | 0.4 | setosa | |
4.6 | 3.4 | 1.4 | 0.3 | setosa | |
5.0 | 3.4 | 1.5 | 0.2 | setosa | |
4.4 | 2.9 | 1.4 | 0.2 | setosa | |
4.9 | 3.1 | 1.5 | 0.1 | setosa | |
5.4 | 3.7 | 1.5 | 0.2 | setosa | |
4.8 | 3.4 | 1.6 | 0.2 | setosa | |
4.8 | 3.0 | 1.4 | 0.1 | setosa | |
4.3 | 3.0 | 1.1 | 0.1 | setosa | |
5.8 | 4.0 | 1.2 | 0.2 | setosa | |
5.7 | 4.4 | 1.5 | 0.4 | setosa | |
5.4 | 3.9 | 1.3 | 0.4 | setosa | |
5.1 | 3.5 | 1.4 | 0.3 | setosa | |
5.7 | 3.8 | 1.7 | 0.3 | setosa | |
5.1 | 3.8 | 1.5 | 0.3 | setosa | |
5.4 | 3.4 | 1.7 | 0.2 | setosa | |
5.1 | 3.7 | 1.5 | 0.4 | setosa | |
4.6 | 3.6 | 1.0 | 0.2 | setosa | |
5.1 | 3.3 | 1.7 | 0.5 | setosa | |
4.8 | 3.4 | 1.9 | 0.2 | setosa | |
5.0 | 3.0 | 1.6 | 0.2 | setosa | |
5.0 | 3.4 | 1.6 | 0.4 | setosa | |
5.2 | 3.5 | 1.5 | 0.2 | setosa | |
5.2 | 3.4 | 1.4 | 0.2 | setosa | |
4.7 | 3.2 | 1.6 | 0.2 | setosa | |
4.8 | 3.1 | 1.6 | 0.2 | setosa | |
5.4 | 3.4 | 1.5 | 0.4 | setosa | |
5.2 | 4.1 | 1.5 | 0.1 | setosa | |
5.5 | 4.2 | 1.4 | 0.2 | setosa | |
4.9 | 3.1 | 1.5 | 0.2 | setosa | |
5.0 | 3.2 | 1.2 | 0.2 | setosa | |
5.5 | 3.5 | 1.3 | 0.2 | setosa | |
4.9 | 3.6 | 1.4 | 0.1 | setosa | |
4.4 | 3.0 | 1.3 | 0.2 | setosa | |
5.1 | 3.4 | 1.5 | 0.2 | setosa | |
5.0 | 3.5 | 1.3 | 0.3 | setosa | |
4.5 | 2.3 | 1.3 | 0.3 | setosa | |
4.4 | 3.2 | 1.3 | 0.2 | setosa | |
5.0 | 3.5 | 1.6 | 0.6 | setosa | |
5.1 | 3.8 | 1.9 | 0.4 | setosa | |
4.8 | 3.0 | 1.4 | 0.3 | setosa | |
5.1 | 3.8 | 1.6 | 0.2 | setosa | |
4.6 | 3.2 | 1.4 | 0.2 | setosa | |
5.3 | 3.7 | 1.5 | 0.2 | setosa | |
5.0 | 3.3 | 1.4 | 0.2 | setosa | |
7.0 | 3.2 | 4.7 | 1.4 | versicolor | |
6.4 | 3.2 | 4.5 | 1.5 | versicolor | |
6.9 | 3.1 | 4.9 | 1.5 | versicolor | |
5.5 | 2.3 | 4.0 | 1.3 | versicolor | |
6.5 | 2.8 | 4.6 | 1.5 | versicolor | |
5.7 | 2.8 | 4.5 | 1.3 | versicolor | |
6.3 | 3.3 | 4.7 | 1.6 | versicolor | |
4.9 | 2.4 | 3.3 | 1.0 | versicolor | |
6.6 | 2.9 | 4.6 | 1.3 | versicolor | |
5.2 | 2.7 | 3.9 | 1.4 | versicolor | |
5.0 | 2.0 | 3.5 | 1.0 | versicolor | |
5.9 | 3.0 | 4.2 | 1.5 | versicolor | |
6.0 | 2.2 | 4.0 | 1.0 | versicolor | |
6.1 | 2.9 | 4.7 | 1.4 | versicolor | |
5.6 | 2.9 | 3.6 | 1.3 | versicolor | |
6.7 | 3.1 | 4.4 | 1.4 | versicolor | |
5.6 | 3.0 | 4.5 | 1.5 | versicolor | |
5.8 | 2.7 | 4.1 | 1.0 | versicolor | |
6.2 | 2.2 | 4.5 | 1.5 | versicolor | |
5.6 | 2.5 | 3.9 | 1.1 | versicolor | |
5.9 | 3.2 | 4.8 | 1.8 | versicolor | |
6.1 | 2.8 | 4.0 | 1.3 | versicolor | |
6.3 | 2.5 | 4.9 | 1.5 | versicolor | |
6.1 | 2.8 | 4.7 | 1.2 | versicolor | |
6.4 | 2.9 | 4.3 | 1.3 | versicolor | |
6.6 | 3.0 | 4.4 | 1.4 | versicolor | |
6.8 | 2.8 | 4.8 | 1.4 | versicolor | |
6.7 | 3.0 | 5.0 | 1.7 | versicolor | |
6.0 | 2.9 | 4.5 | 1.5 | versicolor | |
5.7 | 2.6 | 3.5 | 1.0 | versicolor | |
5.5 | 2.4 | 3.8 | 1.1 | versicolor | |
5.5 | 2.4 | 3.7 | 1.0 | versicolor | |
5.8 | 2.7 | 3.9 | 1.2 | versicolor | |
6.0 | 2.7 | 5.1 | 1.6 | versicolor | |
5.4 | 3.0 | 4.5 | 1.5 | versicolor | |
6.0 | 3.4 | 4.5 | 1.6 | versicolor | |
6.7 | 3.1 | 4.7 | 1.5 | versicolor | |
6.3 | 2.3 | 4.4 | 1.3 | versicolor | |
5.6 | 3.0 | 4.1 | 1.3 | versicolor | |
5.5 | 2.5 | 4.0 | 1.3 | versicolor | |
5.5 | 2.6 | 4.4 | 1.2 | versicolor | |
6.1 | 3.0 | 4.6 | 1.4 | versicolor | |
5.8 | 2.6 | 4.0 | 1.2 | versicolor | |
5.0 | 2.3 | 3.3 | 1.0 | versicolor | |
5.6 | 2.7 | 4.2 | 1.3 | versicolor | |
5.7 | 3.0 | 4.2 | 1.2 | versicolor | |
5.7 | 2.9 | 4.2 | 1.3 | versicolor | |
6.2 | 2.9 | 4.3 | 1.3 | versicolor | |
5.1 | 2.5 | 3.0 | 1.1 | versicolor | |
5.7 | 2.8 | 4.1 | 1.3 | versicolor | |
6.3 | 3.3 | 6.0 | 2.5 | virginica | |
5.8 | 2.7 | 5.1 | 1.9 | virginica | |
7.1 | 3.0 | 5.9 | 2.1 | virginica | |
6.3 | 2.9 | 5.6 | 1.8 | virginica | |
6.5 | 3.0 | 5.8 | 2.2 | virginica | |
7.6 | 3.0 | 6.6 | 2.1 | virginica | |
4.9 | 2.5 | 4.5 | 1.7 | virginica | |
7.3 | 2.9 | 6.3 | 1.8 | virginica | |
6.7 | 2.5 | 5.8 | 1.8 | virginica | |
7.2 | 3.6 | 6.1 | 2.5 | virginica | |
6.5 | 3.2 | 5.1 | 2.0 | virginica | |
6.4 | 2.7 | 5.3 | 1.9 | virginica | |
6.8 | 3.0 | 5.5 | 2.1 | virginica | |
5.7 | 2.5 | 5.0 | 2.0 | virginica | |
5.8 | 2.8 | 5.1 | 2.4 | virginica | |
6.4 | 3.2 | 5.3 | 2.3 | virginica | |
6.5 | 3.0 | 5.5 | 1.8 | virginica | |
7.7 | 3.8 | 6.7 | 2.2 | virginica | |
7.7 | 2.6 | 6.9 | 2.3 | virginica | |
6.0 | 2.2 | 5.0 | 1.5 | virginica | |
6.9 | 3.2 | 5.7 | 2.3 | virginica | |
5.6 | 2.8 | 4.9 | 2.0 | virginica | |
7.7 | 2.8 | 6.7 | 2.0 | virginica | |
6.3 | 2.7 | 4.9 | 1.8 | virginica | |
6.7 | 3.3 | 5.7 | 2.1 | virginica | |
7.2 | 3.2 | 6.0 | 1.8 | virginica | |
6.2 | 2.8 | 4.8 | 1.8 | virginica | |
6.1 | 3.0 | 4.9 | 1.8 | virginica | |
6.4 | 2.8 | 5.6 | 2.1 | virginica | |
7.2 | 3.0 | 5.8 | 1.6 | virginica | |
7.4 | 2.8 | 6.1 | 1.9 | virginica | |
7.9 | 3.8 | 6.4 | 2.0 | virginica | |
6.4 | 2.8 | 5.6 | 2.2 | virginica | |
6.3 | 2.8 | 5.1 | 1.5 | virginica | |
6.1 | 2.6 | 5.6 | 1.4 | virginica | |
7.7 | 3.0 | 6.1 | 2.3 | virginica | |
6.3 | 3.4 | 5.6 | 2.4 | virginica | |
6.4 | 3.1 | 5.5 | 1.8 | virginica | |
6.0 | 3.0 | 4.8 | 1.8 | virginica | |
6.9 | 3.1 | 5.4 | 2.1 | virginica | |
6.7 | 3.1 | 5.6 | 2.4 | virginica | |
6.9 | 3.1 | 5.1 | 2.3 | virginica | |
5.8 | 2.7 | 5.1 | 1.9 | virginica | |
6.8 | 3.2 | 5.9 | 2.3 | virginica | |
6.7 | 3.3 | 5.7 | 2.5 | virginica | |
6.7 | 3.0 | 5.2 | 2.3 | virginica | |
6.3 | 2.5 | 5.0 | 1.9 | virginica | |
6.5 | 3.0 | 5.2 | 2.0 | virginica | |
6.2 | 3.4 | 5.4 | 2.3 | virginica | |
5.9 | 3.0 | 5.1 | 1.8 | virginica |
<!DOCTYPE html> | |
<meta charset="utf-8"> | |
<style> | |
.axis line, | |
.axis path { | |
fill: none; | |
stroke: #000; | |
shape-rendering: crispEdges; | |
} | |
div.tooltip { | |
top: -1000px; | |
position: absolute; | |
padding: 15px; | |
background: rgba(255, 255, 255, .90); | |
border: 1px solid lightgray; | |
pointer-events: none; | |
} | |
.tooltip-hidden{ | |
opacity: 0; | |
} | |
</style> | |
<body> | |
<div id='graph'></div> | |
<div class='tooltip'></div> | |
</body> | |
<script src="http://d3js.org/d3.v3.min.js"></script> | |
<script src='d3-jetpack.js'></script> | |
<script> | |
d3.tsv('data.tsv', function(data){ | |
c = d3.conventions({parentSel: d3.select('#graph')}) | |
c.x.domain(d3.extent(data, ƒ('sepalWidth')) ).nice() | |
c.y.domain(d3.extent(data, ƒ('sepalLength'))).nice() | |
c.drawAxis() | |
c.svg.appendData('circle', data) | |
.attr('cx', ƒ(c.x,'sepalWidth')) | |
.attr('cy', ƒ(c.y, 'sepalLength')) | |
.attr('fill', ƒ(c.color, 'species')) | |
.attr({r: 5, stroke: '#000'}) | |
.call(d3.attachTooltip) | |
var legend = c.svg.appendData('g.legend', c.color.domain()) | |
.translate(function(d, i){ return [0, i*20] }) | |
legend.append('rect') | |
.attr({x: c.width - 18, width: 18, height: 18}) | |
.style('fill', c.color) | |
legend.append('text') | |
.attr({x: c.width - 24, y: 9, dy: '.33em', 'text-anchor': 'end'}) | |
.text(ƒ()) | |
}) | |
</script> |