Properly rendering sparklines in a datatable

大兔子大兔子 提交于 2019-12-10 04:24:51

问题


In my example posted below I am attempting to render a sparkline from the jquery.sparkline library as a column of data in a jquery.dataTables table. Loading the example below works just fine but only for the first page. If I click on 'next' instead of having the data render as a sparkline it simply renders the numbers. If I click 'previous' the sparklines show up for the initial set. If I sort I get a combination of the two.

I'm new to both of these libraries and I have tried to look on this forum as well as others for solutions and so far none of my findings have solved my problem. Anyone know what I'm doing wrong?

Thanks for any suggestions!

<!DOCTYPE html>
<html>
<head>
    <title></title>
    <style type="text/css" title="currentStyle">
    @import "http://datatables.net/release-datatables/media/css/demo_page.css";
    @import "http://datatables.net/release-datatables/media/css/jquery.dataTables.css";

        td.right {
            text-align: right;
        }
    </style>

<script type="text/javascript" src="http://code.jquery.com/jquery-2.0.3.js"></script>
<script type="text/javascript" src="http://datatables.net/release-datatables/media/js/jquery.dataTables.js"></script>
<script type="text/javascript" src="http://omnipotent.net/jquery.sparkline/2.1.2/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>');
            $('#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"]
                ],
                "aoColumns": [
                    { "sTitle": "Sparkline", "sClass": "center" }
                ],
                "aoColumnDefs": [
                    {
                        "aTargets": [0],
                        "mRender": function (data, type, full) {
                            return '<span class="spark">' + data + '</span>'
                        }
                    }
                ],
                "fnInitComplete": function (oSettings, json) {
                    $('.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 class="spacer"></div>
</div>

</body>
</html>

回答1:


Your answer did not work for me, but the following did, and I believe it is a lot cleaner.

Instead of changing the sparkline jquery plugin, just don't call .sparkline() in the fnDrawCallback every time. This can be managed by simply changing your selector to this:

"fnDrawCallback": function (oSettings) {
    $('.spark:not(:has(canvas))').sparkline('html', {
        type: 'line',
        minSpotColor: 'red',
        maxSpotColor: 'green',
        spotColor: false
    });
}

The selectors selects all elements with the spark class, excluding the ones with a canvas element inside.




回答2:


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;
        }



回答3:


Found this to do the trick. Including 3 stacked bar charts together as sparkline in data tables.

BackEnd Data:

<span class="mysparkline" linevalues="1,2,3,4,5,6" barvalues="1,6,2,3,4,5" ></span>

DataTables Code

"fnDrawCallback": function(oSettings) {
    $('.mysparkline').sparkline('html', {
        type: 'bar',
        tagValuesAttribute: 'linevalues',
        barWidth: 6,
        barSpacing: 3,
        barColor: '#fb8072',
        width: '350px',
        tooltipFormatter: function(sp, options, fields) {
            return '<div class="jqsfield"><span style="color: ' + fields[0].color + '">&#9679;</span> Perp, New Term: ' + fields[0].value + '</div>'
        }
    });
    $('.mysparkline').sparkline('html', {
        type: 'bar',
        tagValuesAttribute: 'barvalues',
        barWidth: 6,
        barSpacing: 3,
        barColor: '#36C',
        composite: true,
        tooltipFormatter: function(sp, options, fields) {
            return '<div class="jqsfield"><span style="color: ' + fields[0].color + '">&#9679;</span> Maint, Term Renew: ' + fields[0].value + '</div>'
        }
    });
}



回答4:


I came with the same problem and I found the solution is outdated for the newest version of DataTables. For DataTables 1.10. We need to do something like this:

$('#example').dataTable( {
    "rowCallback": function( row, data ) {
        $('td:eq(0)', row).html('<span class="spark">' + data + '</span>');
    },
    "drawCallback": function (Settings) {
        $('.spark').sparkline('html', {
            type: 'line',
            minSpotColor: 'red',
            maxSpotColor: 'green',
            spotColor: false
        });
    }
});

I don't see the problem of re-rendering the spark-line though. It has taken me some time to make it work, so I am just posting what I figured out here to help anyone who might have the same problem. Thanks.




回答5:


Same Problem with paging and rerendering sparkline losing the first rendered sparklines in my jqgrid table. Solved it in my case by removing the sparkline selector class once rendered so I can call sparkline for all additional loaded tables via the jqgrid event loadComplete

$('.inlinesparkline').sparkline('html', {type: 'line' ,disableHiddenCheck: true, height: '20px', width: '90px'}).removeClass('inlinesparkline');



来源:https://stackoverflow.com/questions/20875081/properly-rendering-sparklines-in-a-datatable

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!