【问题标题】:Charts are not getting displayed on different slides图表没有显示在不同的幻灯片上
【发布时间】:2018-07-25 03:39:24
【问题描述】:

我尝试在不同幻灯片中显示的 d3js 图表的幻灯片放映有一点问题。问题是我的两个图表都显示在一张幻灯片中,而不是显示在不同的幻灯片中。我仔细检查了所有 div 标签以确保它们是否都已关闭。不确定我在这里缺少什么?

附:我知道脚本是重复的,但我会在修复幻灯片问题后进行代码清理。请多多包涵!

【问题讨论】:

    标签: javascript html d3.js


    【解决方案1】:

    您在这里面临的问题与我针对您的previous question 的解决方案不同,d3.csv异步。因此,您的方法(选择脚本所在的 div)将不起作用:全局范围内将存在污染和冲突。

    一个非常简单的解决方法是使用 IIFE,如下所示:

    (function foo(){
        //your code here
    }());
    

    让我们看看。这是你的 HTML 和我制作的一个愚蠢的条形图,没有 IIFE。蓝色图表应该出现在第 3 个 div 中,红色图表应该出现在第 4 个 div 中,但您可以看到,这两个图表都显示在最后一个 div 中:

    <!DOCTYPE html>
    <html>
    
      <head>
        <title>Slides</title>
        <!-- Required stylesheet -->
        <link rel="stylesheet" type="text/css" href="stylesheet.css">
      </head>
    
      <body>
        <div class="slideshow-container">
          <div class="mySlides fade">
            <div class="numbertext">1 / 4</div>
          </div>
          <div class="mySlides fade">
            <div class="numbertext">2 / 4</div>
          </div>
          <script src="https://d3js.org/d3.v4.min.js"></script>
          <div class="mySlides fade">
            <div class="numbertext">3 / 4</div>
            <div id="filter"><b>States:</b></div>
            <script>
                var container = document.currentScript.parentNode;
                var svg = d3.select(container)
                  .append("svg");
                d3.json("https://api.myjson.com/bins/xv0yy", function(data) {
                  var scale = d3.scaleBand()
                    .domain(data)
                    .range([0, 300])
                    .padding(0.4);
                  var bars = svg.selectAll(null)
                    .data(data)
                    .enter()
                    .append("rect")
                    .style("fill", "steelblue")
                    .attr("x", d => scale(d))
                    .attr("width", scale.bandwidth())
                    .attr("height", d => 150 - d)
                    .attr("y", Number)
                })
             
            </script>
          </div>
          <div class="mySlides fade">
            <div class="numbertext">4 / 4</div>
            <script>
                var container = document.currentScript.parentNode;
                var svg = d3.select(container)
                  .append("svg");
                d3.json("https://api.myjson.com/bins/zgway", function(data) {
                  var scale = d3.scaleBand()
                    .domain(data)
                    .range([0, 300])
                    .padding(0.4);
                  var bars = svg.selectAll(null)
                    .data(data)
                    .enter()
                    .append("rect")
                    .style("fill", "tomato")
                    .attr("x", d => scale(d) + 10)
                    .attr("width", scale.bandwidth())
                    .attr("height", d => 150 - d)
                    .attr("y", Number)
                })
              
            </script>
          </div>
          <!-- Next and previous buttons -->
          <a class="prev" onclick="plusSlides(-1)">&#10094;</a>
          <a class="next" onclick="plusSlides(1)">&#10095;</a>
        </div>
        <br>
        <div style="text-align:center">
          <span class="dot" onclick="currentSlide(1)"></span>
          <span class="dot" onclick="currentSlide(2)"></span>
          <span class="dot" onclick="currentSlide(3)"></span>
          <span class="dot" onclick="currentSlide(4)"></span>
        </div>
        <script>
          var slideIndex = 1;
          showSlides(slideIndex);
    
          function plusSlides(n) {
            showSlides(slideIndex += n);
          }
    
          function currentSlide(n) {
            showSlides(slideIndex = n);
          }
    
          function showSlides(n) {
            var i;
            var slides = document.getElementsByClassName("mySlides");
            var dots = document.getElementsByClassName("dot");
            if (n > slides.length) {
              slideIndex = 1
            }
            if (n < 1) {
              slideIndex = slides.length
            }
            for (i = 0; i < slides.length; i++) {
              slides[i].style.display = "none";
            }
            for (i = 0; i < dots.length; i++) {
              dots[i].className = dots[i].className.replace(" active", "");
            }
            slides[slideIndex - 1].style.display = "block";
            dots[slideIndex - 1].className += " active";
          }
    
        </script>
      </body>
    
    </html>

    现在相同的代码,但使用 IIFE,一切都显示在正确的位置:

    <!DOCTYPE html>
    <html>
    
      <head>
        <title>Slides</title>
        <!-- Required stylesheet -->
        <link rel="stylesheet" type="text/css" href="stylesheet.css">
      </head>
    
      <body>
        <div class="slideshow-container">
          <div class="mySlides fade">
            <div class="numbertext">1 / 4</div>
          </div>
          <div class="mySlides fade">
            <div class="numbertext">2 / 4</div>
          </div>
          <script src="https://d3js.org/d3.v4.min.js"></script>
          <div class="mySlides fade">
            <div class="numbertext">3 / 4</div>
            <div id="filter"><b>States:</b></div>
            <script>
              (function iife() {
                var container = document.currentScript.parentNode;
                var svg = d3.select(container)
                  .append("svg");
                d3.json("https://api.myjson.com/bins/xv0yy", function(data) {
                  var scale = d3.scaleBand()
                    .domain(data)
                    .range([0, 300])
                    .padding(0.4);
                  var bars = svg.selectAll(null)
                    .data(data)
                    .enter()
                    .append("rect")
                    .style("fill", "steelblue")
                    .attr("x", d => scale(d))
                    .attr("width", scale.bandwidth())
                    .attr("height", d => 150 - d)
                    .attr("y", Number)
                })
              }())
            </script>
          </div>
          <div class="mySlides fade">
            <div class="numbertext">4 / 4</div>
            <script>
              (function iife() {
                var container = document.currentScript.parentNode;
                var svg = d3.select(container)
                  .append("svg");
                d3.json("https://api.myjson.com/bins/zgway", function(data) {
                  var scale = d3.scaleBand()
                    .domain(data)
                    .range([0, 300])
                    .padding(0.4);
                  var bars = svg.selectAll(null)
                    .data(data)
                    .enter()
                    .append("rect")
                    .style("fill", "tomato")
                    .attr("x", d => scale(d))
                    .attr("width", scale.bandwidth())
                    .attr("height", d => 150 - d)
                    .attr("y", Number)
                })
              }())
            </script>
          </div>
          <!-- Next and previous buttons -->
          <a class="prev" onclick="plusSlides(-1)">&#10094;</a>
          <a class="next" onclick="plusSlides(1)">&#10095;</a>
        </div>
        <br>
        <div style="text-align:center">
          <span class="dot" onclick="currentSlide(1)"></span>
          <span class="dot" onclick="currentSlide(2)"></span>
          <span class="dot" onclick="currentSlide(3)"></span>
          <span class="dot" onclick="currentSlide(4)"></span>
        </div>
        <script>
          var slideIndex = 1;
          showSlides(slideIndex);
    
          function plusSlides(n) {
            showSlides(slideIndex += n);
          }
    
          function currentSlide(n) {
            showSlides(slideIndex = n);
          }
    
          function showSlides(n) {
            var i;
            var slides = document.getElementsByClassName("mySlides");
            var dots = document.getElementsByClassName("dot");
            if (n > slides.length) {
              slideIndex = 1
            }
            if (n < 1) {
              slideIndex = slides.length
            }
            for (i = 0; i < slides.length; i++) {
              slides[i].style.display = "none";
            }
            for (i = 0; i < dots.length; i++) {
              dots[i].className = dots[i].className.replace(" active", "");
            }
            slides[slideIndex - 1].style.display = "block";
            dots[slideIndex - 1].className += " active";
          }
    
        </script>
      </body>
    
    </html>

    在那些sn-ps中我用的是d3.json,不是d3.csv,但是原理是一样的。


    PS:这一点我怎么强调都不为过:可以这么说,我对您的previous question 的回答只是好奇心。不要遵循您在此处遵循的方法(使用document.currentScript)。这可能是未来维护/调试的噩梦。

    【讨论】:

    • 我在第二次剪断时尝试了解决方案,它按预期工作。有一个小问题,因为在第一个图表中 x 轴线消失了。要调查它为什么会发生?感谢您在这方面与我在一起。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-30
    • 2017-08-05
    相关资源
    最近更新 更多