正确渲染数据表中的迷你图

时间:2014-01-02 01:25:15

标签: jquery datatables sparklines

在我下面发布的示例中,我尝试将jquery.sparkline库中的迷你图作为jquery.dataTables表中的数据列进行渲染。加载下面的示例工作得很好但仅适用于第一页。如果我单击“下一步”而不是将数据渲染为迷你图,则只需渲染数字。如果我单击“上一个”,则会显示初始设置的迷你图。如果我排序,我会得到两者的组合。

我是这两个图书馆的新手,我试图在这个论坛以及其他人寻找解决方案,到目前为止,我的研究结果都没有解决我的问题。谁知道我做错了什么?

感谢您的任何建议!

<!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>

5 个答案:

答案 0 :(得分:6)

您的回答对我不起作用,但以下情况确实如此,我相信它更清晰。

不要改变sparkline jquery插件,而是每次都不要在fnDrawCallback中调用.sparkline()。这可以通过简单地将选择器更改为:

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

选择器选择具有spark类的所有元素,不包括内部带有canvas元素的元素。

答案 1 :(得分:5)

花了一些时间调试库我发现问题的一部分是我不应该初始化'fnInitComplete'中的迷你图。这仅在第一页上触发,文档仅包含可见行。我应该在'fnDrawCallback'中这样做。所以代码是:

<!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>

这仍然会导致问题,因为迷你图库会在第二次查看页面时使用错误的数据重新初始化迷你图,因为我们在fnDrawCallback中调用'sparkline',每次点击'next'时都会调用它'previous'用适当的数据重新绘制表格。如果单击“下一步”然后单击“上一步”,则会重新初始化迷你图,但使用第一次调用时DOM中的画布数据。为了解决这个最后的问题,我只是简单地修改了迷你线渲染方法,如果我们已经这样做了就跳过渲染。我这样做的方式可能不是最好的,只是看看标签的val是否包含'canvas',但它确实解决了我的问题。我将向sparkline库维护者发布一个问题,看看他们是否有更好的方法来处理这个问题。

这是我在jquery.sparkline.js中进行的代码修改。我修改了约947行的渲染功能,包括检查'画布'并返回它是否已经存在。

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

答案 2 :(得分:3)

发现这是为了做到这一点。将3个堆积的条形图一起包含在数据表中作为迷你图。

BackEnd数据:

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

DataTables代码

"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>'
        }
    });
}

答案 3 :(得分:1)

我遇到了同样的问题,我发现最新版本的DataTables的解决方案已经过时了。 对于DataTables 1.10。我们需要做这样的事情:

$('#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
        });
    }
});

我没有看到重新渲染火花线的问题。 我花了一些时间才能使它工作,所以我只是发布了我在这里想出来帮助那些可能遇到同样问题的人。感谢。

答案 4 :(得分:1)

分页和重新渲染迷你图在我的jqgrid表中丢失第一个渲染的迷你图的问题相同。 在我的情况下通过删除一旦呈现的sparkline选择器类解决它,所以我可以通过jqgrid事件loadComplete

为所有其他加载的表调用sparkline

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