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="//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>