jHeatmap Javascript库选项卡行为奇怪

jHeatmap Javascript library tab behaves strangely

本文关键字:Javascript 选项 jHeatmap      更新时间:2023-09-26

我已经为这个问题挣扎了好几天了,它真的把我难住了。希望有精通JQuery的人能帮上忙。

这与一个非常强大和漂亮的javascript库有关,用于创建交互式热图。http://jheatmap.github.io/jheatmap/。为了在一个页面上显示多个热图,我正在修改其中一个示例——快速开始。这个想法是把热图放在单独的标签上,并通过点击一个特定的标签来激活热图。这个工具不能自然地做到这一点,而是在每个html页面上只显示一个热图。开发者提出了一个解决方案,但问题就在这里。

在这个示例代码中,我打算在三个选项卡上显示三个热图(分别称为heatmap1、heatmap2和heatmap3)。目前的情况是,我必须先单击heatmap1的选项卡,然后再单击heatmap2或heatmap3的选项卡。由于默认情况下显示的是heatmap1,所以当页面初始化时,我可以继续单击heatmap2的选项卡,这很好。但现在如果我想要显示heatmap3,我必须返回点击heatmap1的标签,然后点击heatmap3的标签。在我设法使用这个技巧看到heatmap3之后,我需要再次单击heatmap1的选项卡以显示heatmap2。似乎必须在显示任何其他热图之前显示热图1。

由于我的帐户不允许我附加文件,所以我把代码放在下面。这是对Jheatmap的快速入门步骤4代码的直接修改。您将无法运行它,因为脚本在文本文件中加载/读取。但是如果你能看一下这三个热图周围的javascript和渲染对象的html代码,我会非常感激。我想有精通JQuery的人可以给我一些建议,告诉我如何修复这个bug。

谢谢你的帮助。

<!DOCTYPE html>
<html>
<head>
    <title>jHeatmap</title>
    <link href="//netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.css" rel="stylesheet">
    <link href="//netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/css/bootstrap-combined.min.css" rel="stylesheet">
    <link href="prettify.css" rel="stylesheet" type="text/css">
    <link href="../../styles/jheatmap-1.0.0.css" rel="stylesheet" type="text/css"/>
    <style>
            /* To center the heatmap */
        table.heatmap {
            margin: 0px auto;
        }
    </style>
    <script type="text/javascript" src="http://code.jquery.com/jquery-1.10.1.js"></script>
    <script src="../../scripts/jheatmap-1.0.0.js" type="text/javascript"></script>
    <script>
        $(document).ready(function () {
         /* heatmap1 */
         $('#heatmap1').heatmap(
            {
                data: {
                    rows: new jheatmap.readers.AnnotationReader({ url: "quickstart-rows.tsv" }),
                    cols: new jheatmap.readers.AnnotationReader({ url: "quickstart-cols.tsv" }),
                    values: new jheatmap.readers.TableHeatmapReader({ url: "quickstart-data.tsv" })
                },
                init: function (heatmap) {
                    // Column annotations
                    heatmap.cols.decorators["subtype2"] = new jheatmap.decorators.CategoricalRandom();
                    heatmap.cols.annotations = ["subtype"];
                    // Rows annotations
                    heatmap.rows.decorators["fm-bias"] = new jheatmap.decorators.PValue({ cutoff: 0.05 });
                    heatmap.rows.annotations = ["fm-bias"];
                    // Aggregators
                    heatmap.cells.aggregators["Mutation"] = new jheatmap.aggregators.AbsoluteAddition();
                    heatmap.cells.aggregators["CNA Status"] = new jheatmap.aggregators.AbsoluteAddition();
                    heatmap.cells.aggregators["Expression"] = new jheatmap.aggregators.Median();
                    // Decorators
                    heatmap.cells.decorators["Mutation"] = new jheatmap.decorators.Categorical({
                                    values: ["0","1"],
                                    colors : ["white","green"]
                    });
                    heatmap.cells.decorators["CNA Status"] = new jheatmap.decorators.Categorical({
                                    values: ["-2","2"],
                                    colors : ["blue","red"]
                    });
                    heatmap.cells.decorators["Expression"] = new jheatmap.decorators.Heat({
                                    minValue: -2,
                                    midValue: 0,
                                    maxValue: 2,
                                    minColor: [85, 0, 136],
                                    nullColor: [255,255,255],
                                    maxColor: [255, 204, 0],
                                    midColor: [240,240,240]
                    });
                }
            });
         /* heatmap2 */
         $('#myTab a').click(function (e) {
                e.preventDefault();
                $(this).tab('show');
                // Load Heatmap2 
                if ($(this).tab()[0].hash == '#heatmap2Tab') {
                    $('#heatmap-loader').show();
                    $('#heatmap2').width($('#heatmap').width());
                    $('#heatmap2').heatmap(
                    {
                        data: {
                            rows: new jheatmap.readers.AnnotationReader({ url: "quickstart-rows.tsv" }),
                            cols: new jheatmap.readers.AnnotationReader({ url: "quickstart-cols.tsv" }),
                            values: new jheatmap.readers.TableHeatmapReader({ url: "quickstart-data.tsv" })
                        },
                        init: function (heatmap) {
                            // Column annotations
                            heatmap.cols.decorators["subtype"] = new jheatmap.decorators.CategoricalRandom();
                            heatmap.cols.annotations = ["subtype"];
                            // Rows annotations
                            heatmap.rows.decorators["fm-bias"] = new jheatmap.decorators.PValue({ cutoff: 0.05 });
                            heatmap.rows.annotations = ["fm-bias"];
                            // Aggregators
                            heatmap.cells.aggregators["Mutation"] = new jheatmap.aggregators.AbsoluteAddition();
                            heatmap.cells.aggregators["CNA Status"] = new jheatmap.aggregators.AbsoluteAddition();
                            heatmap.cells.aggregators["Expression"] = new jheatmap.aggregators.Median();
                            // Decorators
                            heatmap.cells.decorators["Mutation"] = new jheatmap.decorators.Categorical({
                                            values: ["0","1"],
                                            colors : ["white","green"]
                            });
                            heatmap.cells.decorators["CNA Status"] = new jheatmap.decorators.Categorical({
                                            values: ["-2","2"],
                                            colors : ["blue","red"]
                            });
                            heatmap.cells.decorators["Expression"] = new jheatmap.decorators.Heat({
                                            minValue: -2,
                                            midValue: 0,
                                            maxValue: 2,
                                            minColor: [85, 0, 136],
                                            nullColor: [255,255,255],
                                            maxColor: [255, 204, 0],
                                            midColor: [240,240,240]
                            });
                        }
                    });
                }
          })
         /* heatmap3 */
         $('#myTab a').click(function (e) {
             e.preventDefault();
             $(this).tab('show');
             // Load Heatmap2 
             if ($(this).tab()[0].hash == '#heatmap3Tab') {
                 $('#heatmap-loader').show();
                 $('#heatmap3').width($('#heatmap').width());
                 $('#heatmap3').heatmap(
                 {
                     data: {
                         rows: new jheatmap.readers.AnnotationReader({ url: "quickstart-rows.tsv" }),
                         cols: new jheatmap.readers.AnnotationReader({ url: "quickstart-cols.tsv" }),
                         values: new jheatmap.readers.TableHeatmapReader({ url: "quickstart-data.tsv" })
                     },
                     init: function (heatmap) {
                         // Column annotations
                         heatmap.cols.decorators["subtype"] = new jheatmap.decorators.CategoricalRandom();
                         heatmap.cols.annotations = ["subtype"];
                         // Rows annotations
                         heatmap.rows.decorators["fm-bias"] = new jheatmap.decorators.PValue({ cutoff: 0.05 });
                         heatmap.rows.annotations = ["fm-bias"];
                         // Aggregators
                         heatmap.cells.aggregators["Mutation"] = new jheatmap.aggregators.AbsoluteAddition();
                         heatmap.cells.aggregators["CNA Status"] = new jheatmap.aggregators.AbsoluteAddition();
                         heatmap.cells.aggregators["Expression"] = new jheatmap.aggregators.Median();
                         // Decorators
                         heatmap.cells.decorators["Mutation"] = new jheatmap.decorators.Categorical({
                             values: ["0", "1"],
                             colors: ["white", "green"]
                         });
                         heatmap.cells.decorators["CNA Status"] = new jheatmap.decorators.Categorical({
                             values: ["-2", "2"],
                             colors: ["blue", "red"]
                         });
                         heatmap.cells.decorators["Expression"] = new jheatmap.decorators.Heat({
                             minValue: -2,
                             midValue: 0,
                             maxValue: 2,
                             minColor: [85, 0, 136],
                             nullColor: [255, 255, 255],
                             maxColor: [255, 204, 0],
                             midColor: [240, 240, 240]
                         });
                     }
                 });
             }
         })

    });</script>
</head>
<body>
<div class="container">
    <div class="row">
        <ul class="nav nav-pills">
            <li><a href="step0.html">Step 0</a></li>
            <li><a href="step1.html">Step 1</a></li>
            <li><a href="step2.html">Step 2</a></li>
            <li><a href="step3.html">Step 3</a></li>
            <li class="active"><a href="step4.html">Step 4</a></li>
            <li><a href="step5.html">Step 5</a></li>
        </ul>
        <p>
           Add column and row annotation headers.
        </p>
    </div>
    <div class="row">
        <div id="heatmap-loader">
            <div class="background"></div>
            <div class="loader">
                <img src="../../images/loading.gif">
            </div>
        </div>
        <ul id="myTab" class="nav nav-tabs">
            <li class="active"><a href="#heatmap1Tab" data-toggle="tab">Heatmap1</a></li>
            <li><a href="#heatmap2Tab" data-toggle="tab">Heatmap2</a></li>
            <li><a href="#heatmap3Tab" data-toggle="tab">Heatmap3</a></li>
            <li><a href="#javascriptTab" data-toggle="tab">Javascript</a></li>
            <li><a href="#dataTab" data-toggle="tab">quickstart-data.tsv</a></li>
            <li><a href="#cdataTab" data-toggle="tab">quickstart-cols.tsv</a></li>
            <li><a href="#rdataTab" data-toggle="tab">quickstart-rows.tsv</a></li>
        </ul>
        <div id="myTabContent" class="tab-content">
            <div class="tab-pane fade in active" id="heatmap1Tab" style="">
                <div id="heatmap1"></div>
            </div>
            <div class="tab-pane fade" id="heatmap2Tab" style="">
                <div id="heatmap2" style="width:100%;"></div>
            </div>
            <div class="tab-pane fade" id="heatmap3Tab" style="">
                <div id="heatmap3" style="width:100%;"></div>
            </div>
            <div class="tab-pane fade" id="javascriptTab">
                <pre id="source" class="prettyprint linenums"></pre>
            </div>
            <div class="tab-pane fade" id="dataTab">
                <pre id="data" class="prettyprint"></pre>
            </div>
            <div class="tab-pane fade" id="cdataTab">
                <pre id="cdata" class="prettyprint"></pre>
            </div>
            <div class="tab-pane fade" id="rdataTab">
                <pre id="rdata" class="prettyprint"></pre>
            </div>
        </div>
    </div>
</div>
<script type="text/javascript" src="prettify.js"></script>
<script src="//netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/js/bootstrap.min.js"></script>
<script>
    var source = document.getElementsByTagName('script')[2].innerHTML;
    source = source.replace(/</g, "&lt;").replace(/>/g, "&gt;");
    $('#source').html(source);
    window.prettyPrint && prettyPrint();
    $('#source ol.linenums li').each(function(idx, li) {
        if ((idx > 3 && idx < 6) || (idx > 10 && idx < 18)) {
            $(li).css("background-color", "#FFFFB3");
        }
    });
    jQuery.ajax({
        url: "quickstart-data.tsv",
        dataType: "text",
        success: function (file) {
            $('#data').html(file);
        }
    });
    jQuery.ajax({
        url: "quickstart-cols.tsv",
        dataType: "text",
        success: function (file) {
            $('#cdata').html(file);
        }
    });
    jQuery.ajax({
        url: "quickstart-rows.tsv",
        dataType: "text",
        success: function (file) {
            $('#rdata').html(file);
        }
    });
</script>
<script>
  (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
  (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
  m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
  })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
  ga('create', 'UA-7336589-2', 'jheatmap.github.io');
  ga('send', 'pageview');
</script>
</body>
</html>

我认为代码中的主要问题是您将两个函数绑定到所有单击选项卡事件。你只需要绑定一个函数,这个函数只会根据被点击的链接绘制一个热图。

这里有一个简化版本,在不同的选项卡上绘制三个热图:

<html>
 <head>
     <link href="http://netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/css/bootstrap-combined.min.css" rel="stylesheet">
     <link href="http://jheatmap.github.io/jheatmap/css/jheatmap-1.0.0-min.css" rel="stylesheet" type="text/css"/>
     <script src="http://code.jquery.com/jquery-1.10.1.js"></script>
     <script src="http://jheatmap.github.io/jheatmap/js/jheatmap-1.0.0-min.js"></script>
     <script src="http://netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/js/bootstrap.min.js"></script>
     <script>  
     var draw_heatmap = function (tag_id) {
                $('#'+tag_id).heatmap({
                data: {
                    values: new jheatmap.readers.TableHeatmapReader({ url: "http://jheatmap.github.io/jheatmap/examples/quickstart/quickstart-data.tsv" })
                }});        
     };
     $(document).ready(function () {
         /* Draw the default visible heatmap */
         draw_heatmap('heatmap1');
         /* Calculate the visible heatmap width */
         var heatmap_width = $('#heatmap1').width();
         /* Fix the width to all the heatmaps */
         $('#heatmap1').width(heatmap_width);
         $('#heatmap2').width(heatmap_width);
         $('#heatmap3').width(heatmap_width);
         /* Attach draw heatmap to tab click event */
         $('#myTab a').click(function (e) {
                e.preventDefault();
                /* Show the clicked tab */
                $(this).tab('show');
                /* Show the loader indicator */
                $('#heatmap-loader').show();
                /* Draw the correct heatmap */
                if ($(this).tab()[0].hash == '#heatmap1Tab') {
                    draw_heatmap('heatmap1');
                }
                if ($(this).tab()[0].hash == '#heatmap2Tab') {
                    draw_heatmap('heatmap2');
                }
                if ($(this).tab()[0].hash == '#heatmap3Tab') {
                    draw_heatmap('heatmap3');
                }
          });
    });
    </script>
 </head>
 <body>    
  <div class="container">
    <div class="row">
        <div id="heatmap-loader">
            <div class="background"></div>
            <div class="loader">
                <img src="http://jheatmap.github.io/jheatmap/images/loading.gif">
            </div>
        </div>
        <ul id="myTab" class="nav nav-tabs">
            <li class="active"><a href="#heatmap1Tab" data-toggle="tab">Heatmap1</a></li>
            <li><a href="#heatmap2Tab" data-toggle="tab">Heatmap2</a></li>
            <li><a href="#heatmap3Tab" data-toggle="tab">Heatmap3</a></li>           
        </ul>
        <div id="myTabContent" class="tab-content">
            <div class="tab-pane fade in active" id="heatmap1Tab">
                <div id="heatmap1"></div>
            </div>
            <div class="tab-pane fade" id="heatmap2Tab">
                <div id="heatmap2"></div>
            </div>
            <div class="tab-pane fade" id="heatmap3Tab">
                <div id="heatmap3"></div>
            </div>
        </div>
    </div>
  </div>
 </body>
</html>