【问题标题】:D3.js code in Reveal.js slideReveal.js 幻灯片中的 D3.js 代码
【发布时间】:2014-02-02 15:40:05
【问题描述】:

我正在尝试让 D3.js 在 Reveal.js 幻灯片上运行,但即使是最基本的 sn-p,我也无法让它运行:

<section>
    <h2>Title</h2>
    <div id="placeholder"></div>
    <script type="text/javascript">
        d3.select("#placeholder").append("p").text("TEST");
    </script>
</section>

不显示“TEST”字样。我做错了什么?

【问题讨论】:

    标签: javascript d3.js reveal.js


    【解决方案1】:

    好的,我们开始吧。

    我用 Reveal.jsD3.js 做了一个基本示例,效果很好。

    • 有两张幻灯片
    • 第一张幻灯片包含条形图
    • 第二张幻灯片通过从 json 输入文件中获取数据来呈现 气泡图

    如果您的代码位于底部部分外部,您的代码可以正常工作。我已将所有 D3.js 代码放在 html 页面的末尾,然后再靠近正文。

    文件夹结构如下所示(快照中)

    我将我的 JS 放在 HTML 中(为了更容易阅读/理解)

    <!doctype html>
    <html lang="en">
    <head>
            <meta charset="utf-8">
            <title>Reveal.js with D3 JS</title>
            <link rel="stylesheet" href="css/reveal.min.css">
            <link rel="stylesheet" href="css/theme/default.css" id="theme">
            <style>
                .chart rect {
                  fill: #63b6db;
                }
    
                .chart text {
                  fill: white;
                  font: 10px sans-serif;
                  text-anchor: end;
                }
    
                text {
                  font: 10px sans-serif;
                }
            </style>
    </head>
    <body>
            <div class="reveal">
                <div class="slides">
                    <section>
                        <h2>Barebones Presentation</h2>
                        <p>This example contains the bare minimum includes and markup required to run a reveal.js presentation.</p>
                        <svg class="chart"></svg>
                    </section>
    
                    <section id="sect2">
                        <h2>No Theme</h2>
                        <p>There's no theme included, so it will fall back on browser defaults.</p>
                        <svg class="bubleCharts"></svg>
                    </section>
                </div>
            </div>
    
            <script src="js/reveal.min.js"></script>
            <script>
                Reveal.initialize();
            </script>
    
            <script src="js/d3.min.js"></script>
            <script type="text/javascript">
                //------ code to show D3 Bar Chart on First Slide-------
                var data = [44, 28, 15, 16, 23, 5];
                var width = 420,
                    barHeight = 20;
    
                var x = d3.scale.linear()
                    .domain([0, d3.max(data)])
                    .range([0, width]);
    
                var chart = d3.select(".chart")
                    .attr("width", width)
                    .attr("height", barHeight * data.length);
    
                var bar = chart.selectAll("g")
                    .data(data)
                  .enter().append("g")
                    .attr("transform", function(d, i) { return "translate(0," + i * barHeight + ")"; });
    
                bar.append("rect")
                    .attr("width", x)
                    .attr("height", barHeight - 1);
    
                bar.append("text")
                    .attr("x", function(d) { return x(d) - 3; })
                    .attr("y", barHeight / 2)
                    .attr("dy", ".35em")
                    .text(function(d) { return d; });
    
    
                //---Code below will show Bubble Charts on the secon Slide -------
                var diameter = 560,
                    format = d3.format(",d"),
                    color = d3.scale.category20c();
    
                var bubble = d3.layout.pack()
                    .sort(null)
                    .size([diameter, diameter])
                    .padding(1.5);
    
                var svg = d3.select(".bubleCharts")
                    .attr("width", diameter)
                    .attr("height", diameter)
                    .attr("class", "bubble");
    
                d3.json("flare.json", function(error, root) {
                  var node = svg.selectAll(".node")
                      .data(bubble.nodes(classes(root))
                      .filter(function(d) { return !d.children; }))
                    .enter().append("g")
                      .attr("class", "node")
                      .attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; });
    
                  node.append("title")
                      .text(function(d) { return d.className + ": " + format(d.value); });
    
                  node.append("circle")
                      .attr("r", function(d) { return d.r; })
                      .style("fill", function(d) { return color(d.packageName); });
    
                  node.append("text")
                      .attr("dy", ".3em")
                      .style("text-anchor", "middle")
                      .text(function(d) { return d.className.substring(0, d.r / 3); });
                });
    
                // Returns a flattened hierarchy containing all leaf nodes under the root.
                function classes(root) {
                  var classes = [];
                  function recurse(name, node) {
                    if (node.children) node.children.forEach(function(child) { recurse(node.name, child); });
                    else classes.push({packageName: name, className: node.name, value: node.size});
                  }
                  recurse(null, root);
                  return {children: classes};
                }
    
                d3.select(self.frameElement).style("height", diameter + "px");
            </script>
    </body>
    </html>
    

    输出/结果

    幻灯片 1

    幻灯片 2

    下载完整代码 https://github.com/aahad/D3.js/tree/master/Reveal JS with D3 JS

    要详细了解条形图或气泡图代码的工作原理:请查看以下内容:

    【讨论】:

      【解决方案2】:

      现有的两个答案都很好,但我想指出第三种方法对我有用并且有一些优势。

      Reveal.js 有一个事件系统,它也适用于per-slide data states

      这意味着您可以为每张幻灯片设置一个单独的 javascript 块,并使其仅在加载该幻灯片时执行。这使您可以在加载幻灯片时制作基于 D3 的动画,并且具有将幻灯片的代码放置在更靠近其文本/标记的位置的进一步优势。

      例如,您可以这样设置幻灯片。注意data-state 属性:

      <section data-state="myslide1">
          <h2>Blah Blah</h2>
          <div id="slide1d3container"></div>
      </section>
      

      然后有一个关联的脚本块:

      <script type="text/javascript">
      Reveal.addEventListener( 'myslide1', function() {
      
          var svg = d3.select("#slide1d3container").append("svg")
          // do more d3 stuff
      
      } );
      </script>
      

      以下是使用此技术的演示文稿示例: http://explunit.github.io/d3_cposc_2014.html

      【讨论】:

      • 你也可以看这里github.com/hakimel/reveal.js/issues/456这个问题给出了同样的答案。
      • 最终,如果您有许多大型 svg 图形的动画,这仍然可能会使客户端超载。在离开当前幻灯片时来回更改幻灯片时,有没有办法清除 svg?
      【解决方案3】:

      我自己发现的。当然,我无法匹配尚未加载的 id:如果我将 d3 javascript 代码放在 index.html 文件末尾的 Reveal.initialize 脚本块之后,它就可以工作。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-03-13
        • 1970-01-01
        • 1970-01-01
        • 2016-08-15
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多