Skip to content

Instantly share code, notes, and snippets.

@davo
Last active May 2, 2016 02:51
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 davo/72e0c76ca0952ee9b05a764942183bd8 to your computer and use it in GitHub Desktop.
Save davo/72e0c76ca0952ee9b05a764942183bd8 to your computer and use it in GitHub Desktop.
Sparkline
(function(root, factory) {
if (typeof module !== 'undefined' && module.exports) {
module.exports = factory(require('d3'));
} else if (typeof define === 'function' && define.amd) {
define(['d3'], factory);
} else {
root.d3 = factory(root.d3);
}
}(this, function(d3) {
d3.selection.prototype.translate = function(xy) {
return this.attr('transform', function(d,i) {
return 'translate('+[typeof xy == 'function' ? xy.call(this, d,i) : xy]+')';
});
};
d3.transition.prototype.translate = function(xy) {
return this.attr('transform', function(d,i) {
return 'translate('+[typeof xy == 'function' ? xy.call(this, 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', function(d,i) { return i ? lh || 15 : 0; });
};
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;
};
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.f = function(){
var functions = arguments;
//convert all string arguments into field accessors
var i = 0, l = functions.length;
while (i < l) {
if (typeof(functions[i]) === 'string' || typeof(functions[i]) === 'number'){
functions[i] = (function(str){ return function(d){ return d[str] }; })(functions[i])
}
i++;
}
//return composition of functions
return function(d) {
var i=0, l = functions.length;
while (i++ < l) d = functions[i-1].call(this, d);
return d;
};
};
// store d3.f as convenient unicode character function (alt-f on macs)
if (typeof window !== 'undefined' && !window.hasOwnProperty('ƒ')) window.ƒ = d3.f;
// this tweak allows setting a listener for multiple events, jquery style
var d3_selection_on = d3.selection.prototype.on;
d3.selection.prototype.on = function(type, listener, capture) {
if (typeof type == 'string' && type.indexOf(' ') > -1) {
type = type.split(' ');
for (var i = 0; i<type.length; i++) {
d3_selection_on.apply(this, [type[i], listener, capture]);
}
} else {
d3_selection_on.apply(this, [type, listener, capture]);
}
return this;
};
// for everyone's sake, let's add prop as alias for property
d3.selection.prototype.prop = d3.selection.prototype.property;
return d3;
}));
<!DOCTYPE html>
<head>
<meta charset="utf-8">
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"></script>
<script src="d3-jetpack.js"></script>
<style>
body { margin:20px;position:fixed;top:0;right:0;bottom:0;left:0; }
svg { width:100%; height: 100% }
</style>
</head>
<body>
<script>
var dataset = [
{
"Month": 1,
"Tweets": 461
},
{
"Month": 2,
"Tweets": 389
},
{
"Month": 3,
"Tweets": 535
},
{
"Month": 4,
"Tweets": 515
},
{
"Month": 5,
"Tweets": 379
},
{
"Month": 6,
"Tweets": 338
},
{
"Month": 7,
"Tweets": 384
},
{
"Month": 8,
"Tweets": 400
},
{
"Month": 9,
"Tweets": 455
},
{
"Month": 10,
"Tweets": 327
},
{
"Month": 11,
"Tweets": 418
},
{
"Month": 12,
"Tweets": 374
}
];
var width = 200,
height = 40;
//Add a quarter-year property to each object in the dataset
for (var i in dataset) {
dataset[i].Month = dataset[i].Month + "/2015";
}
//Append an SVG to the document body
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height)
.append("g");
var x = d3.scale.ordinal()
.domain(dataset.map(function(d) { return d.Month; }))
.rangeRoundBands([0, width], .04);
var y = d3.scale.linear()
.domain([0, d3.max(dataset, function(d) { return d.Tweets; })])
.range([height, 0]);
//Draw the line graph
var line = d3.svg.line()
.interpolate("basis")
.x(function(d) { return x(d.Month); })
.y(function(d) { return y(d.Tweets); })
//Append a path to the SVG
svg.append("path")
.attr("d", line(dataset))
.attr("class", "linePath")
.attr("fill", "none")
.attr("stroke", "#000000")
.attr("stroke-width", 1.5);
</script>
</body>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment