After spending some time debugging the libraries I've found that part of the issue is I shouldn't be initializing the sparklines in 'fnInitComplete'. This is only triggered on the fist page and the document only contains the visible rows. I should be doing it in 'fnDrawCallback'. So the code would be:
<!DOCTYPE html>
<html>
<head>
<title></title>
<style type="text/css" title="currentStyle">
@import "/static/css/demo_page.css";
@import "/static/css/jquery.dataTables.css";
td.right {
text-align: right;
}
</style>
<script type="text/javascript" src="/static/js/jquery-2.0.3.js"></script>
<script type="text/javascript" src="/static/js/jquery.dataTables.js"></script>
<script type="text/javascript" src="/static/js/jquery.sparkline.js"></script>
<script type="text/javascript">
$(document).ready(function () {
$('#dynamic').html('<table cellpadding="0" cellspacing="0" border="0" class="display" id="example"></table>');
var table = $('#example').dataTable({
"aaSorting": [],
"aaData": [
["0,1,2,3,4"],
["4,3,2,1,0"],
["0,1,2,3,4"],
["4,3,2,1,0"],
["0,1,2,3,4"],
["4,3,2,1,0"],
["0,1,2,3,4"],
["4,3,2,1,0"],
["0,1,2,3,4"],
["4,3,2,1,0"],
["0,1,2,3,4"],
["4,3,2,1,0"],
["0,1,2,3,4"],
["4,3,2,1,0"],
["0,1,2,3,4"],
["4,3,2,1,0"]
],
"aoColumns": [
{ "sTitle": "Sparkline", "sClass": "center" }
],
"aoColumnDefs": [
{
"aTargets": [0],
"mRender": function (data, type, full) {
return '<span class="spark">' + data + '</span>';
}
},
],
"fnDrawCallback": function (oSettings) {
$('.spark').sparkline('html', {
type: 'line',
minSpotColor: 'red',
maxSpotColor: 'green',
spotColor: false
});
}
});
});
</script>
</head>
<body id="dt_example">
<div id="container">
<div id="dynamic"></div>
</div>
</body>
</html>
This still causes an issue because the sparkline library will re-initialize the sparkline with the wrong data on the second viewing of a page since we call 'sparkline' in the fnDrawCallback which gets called every time you click on 'next' or 'previous' to repaint the table with the proper data. If you click on 'next' and then 'previous' the sparkline will get re-initialized but with the canvas data that's in the DOM from our first call. To get around this final issue I simply modified the sparkline render method to skip rendering if we've already done so. My way of doing this is probably not the best, simply looking to see if the val of the tag contains 'canvas' but it does solve my issue. I'll post a question to the sparkline library maintainer and see if they have a better way of handling this.
Here's the code modification I made in jquery.sparkline.js. I modified the render function on approx line 947 to include the check for 'canvas' and return if it's already there.
render = function () {
var values, width, height, tmp, mhandler, sp, vals;
if (userValues === 'html' || userValues === undefined) {
vals = this.getAttribute(options.get('tagValuesAttribute'));
if (vals === undefined || vals === null) {
vals = $this.html();
}
# Don't re-render if we already have.
if (vals.indexOf('canvas') === 1) {
return;
}
values = vals.replace(/(^\s*<!--)|(-->\s*$)|\s+/g, '').split(',');
} else {
values = userValues;
}