Skip to content

Instantly share code, notes, and snippets.

@vicapow
Last active October 12, 2015 07:37
Show Gist options
  • Save vicapow/9904319 to your computer and use it in GitHub Desktop.
Save vicapow/9904319 to your computer and use it in GitHub Desktop.
Sparklines with Angular and D3

An example of how to create your own sparkline dirctive in AngularJS using replace and transclude

This is a code excerpt from the book D3 on Angular. http://leanpub.com/d3angularjs

<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.10/angular.min.js"></script>
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<style>
html, body{
width: 100%;
height: 100%;
font-size: 1em;
}
.sl {
display: inline-block;
width: 10em;
vertical-align: middle;
stroke: black;
stroke-width: 1;
}
.sl path{
fill: none;
}
.sl circle{
fill: red;
}
.large{
margin: 0;
font-size: 3em;
}
</style>
</head>
<body ng-app="app">
<p>so this is a spark line <sl style="stroke: red; width: 2em">[10,40,20,50,80]</sl>. Pretty cool, right?</p>
<p>here's another <sl r="1" style="stroke:blue; width: 2em">[10,20,30]</sl></p>
<p>here's a longer example <sl r="1" style="stroke:blue; width:3em">[20,24,20,27,29,50,90]</sl></p>
<p>an even longer example <sl r="1" style="stroke:green;">[20,24,20,500,29,50,90, 20, 10, 40]</sl></p>
<p> lets look at a few in a row. </p>
<p>
<sl r="1" style="stroke:green">[20,24,20,500,29,50,90, 20, 10, 40]</sl><br>
<sl r="1" style="stroke:green">[20,24,30,400,29,50,90, 20, 10, 40]</sl><br>
<sl r="1" style="stroke:green">[20,24,25,300,29,50,90, 20, 10, 40]</sl><br>
<sl r="1" style="stroke:green">[20,24,21,200,29,50,90, 20, 10, 40]</sl><br>
<sl r="1" style="stroke:green">[20,24,23,100,29,50,90, 20, 10, 40]</sl>
</p>
<p> here's the same data but with consistent scales. </p>
<p>
<sl r="1" style="stroke:green" min="0" max="500">[20,24,20,500,29,50,90, 20, 10, 40]</sl><br>
<sl r="1" style="stroke:green" min="0" max="500">[20,24,30,400,29,50,90, 20, 10, 40]</sl><br>
<sl r="1" style="stroke:green" min="0" max="500">[20,24,25,300,29,50,90, 20, 10, 40]</sl><br>
<sl r="1" style="stroke:green" min="0" max="500">[20,24,21,200,29,50,90, 20, 10, 40]</sl><br>
<sl r="1" style="stroke:green" min="0" max="500">[20,24,23,100,29,50,90, 20, 10, 40]</sl>
</p>
<p class="large">
"But what if my font is big?"<sl style="stroke-width:2px; width:2em">[1, 2, 3, 5, 6, 9, 20, 30, 40, 20, 10]</sl> you ask?
</p>
</body>
<script>
var app = angular.module('app', []);
app.directive('sl', function(){
function link(scope, el, attr){
el = d3.select(el[0]);
var svg = el;
var data = JSON.parse(el.text());
var min = attr.min !== undefined ? +attr.min : d3.min(data);
var max = attr.max !== undefined ? +attr.max : d3.max(data);
el.text(''); // remove the original data text
var r = attr.r || 0;
var m = r;
var w = svg.node().clientWidth;
var h = +getComputedStyle(el.node())['font-size'].replace('px','');
svg.attr({width: w, height: h});
var x = d3.scale.linear().domain([0, data.length - 1]).range([m, w - m]);
var y = d3.scale.linear().domain([min, max]).range([h - m, m]);
var lines = svg.append('path').data(data)
.attr('d', 'M' + data.map(function(d, i){ return [x(i),y(d)] }).join('L'));
var circles = svg.selectAll('circle').data(data).enter().append('circle')
.attr('r', r)
.attr('cx', function(d, i){ return x(i) })
.attr('cy', function(d){ return y(d) });
}
return {
link: link
, restrict: 'E'
, replace: true
, template: '<svg ng-transclude class="sl"></svg>'
, transclude: true
};
});
</script>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment