获取水平堆栈栏示例以使用d3.js显示

时间:2013-12-19 21:13:56

标签: javascript html svg d3.js

我在Stack Exchange上查看了如何创建水平堆叠条形图示例,并找到了:http://tributary.io/inlet/4966973

基于:http://bl.ocks.org/mbostock/3943967

为了更好地理解这段代码是如何工作的,我在我的机器上运行了Bostock的示例(通过SimpleHTTPServer等)。

但是,我无法获得gelicia的支流示例。我复制了gelicia的Tributary示例,并添加了Bostock的html代码(导致脚本),另外还有下面的功能,其中Tributary示例结束,但svg主体和结果栏rects不会被创建。但是没有明显的错误信息可以解决问题。

我尝试在Bostock的函数中切换xs和ys,因为我读到这是从垂直到水平堆叠条形图的主要转换问题,但这没有帮助,再次没有出现错误。

有人可以向我解释如何运行水平条形图示例,以及在尝试使其在html文档中工作时我做错了什么?

<!DOCTYPE html>
<meta charset="utf-8">
<style>

body {
  font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
  margin: auto;
  position: relative;
  width: 960px;
}

text {
  font: 10px sans-serif;
}

.axis path,
.axis line {
  fill: none;
  stroke: #000;
  shape-rendering: crispEdges;
}

form {
  position: absolute;
  right: 10px;
  top: 10px;
}

</style>
<form>
  <label><input type="radio" name="mode" value="grouped"> Grouped</label>
  <label><input type="radio" name="mode" value="stacked" checked> Stacked</label>
</form>
<script type="text/javascript" src="d3.v3.js"></script>
<script>
        //modified from Mike Bostock at http://bl.ocks.org/3943967 */

        var data = [
        {"key":"FL", "pop1":3000, "pop2":4000, "pop3":5000},
        {"key":"CA", "pop1":3000, "pop2":3000, "pop3":3000},
        {"key":"NY", "pop1":12000, "pop2":5000, "pop3":13000},
        {"key":"NC", "pop1":8000, "pop2":21000, "pop3":11000},
        {"key":"SC", "pop1":30000, "pop2":12000, "pop3":8000},
        {"key":"AZ", "pop1":26614, "pop2":6944, "pop3":30778},
        {"key":"TX", "pop1":8000, "pop2":12088, "pop3":20000}
        ];

        var n = 3, // number of layers
            m = data.length, // number of samples per layer
            stack = d3.layout.stack(),
            labels = data.map(function(d) {return d.key;}),

            //go through each layer (pop1, pop2 etc, that's the range(n) part)
            //then go through each object in data and pull out that objects's population data
            //and put it into an array where x is the index and y is the number
            layers = stack(d3.range(n).map(function(d) { 
                        var a = [];
                        for (var i = 0; i < m; ++i) {
                            a[i] = {x: i, y: data[i]['pop' + (d+1)]};  
                        }
                        return a;
                     })),

            //the largest single layer
            yGroupMax = d3.max(layers, function(layer) { return d3.max(layer, function(d) { return d.y; }); }),
            //the largest stack
            yStackMax = d3.max(layers, function(layer) { return d3.max(layer, function(d) { return d.y0 + d.y; }); });

        var margin = {top: 40, right: 10, bottom: 20, left: 50},
            width = 677 - margin.left - margin.right,
            height = 533 - margin.top - margin.bottom;

        var y = d3.scale.ordinal()
            .domain(d3.range(m))
            .rangeRoundBands([2, height], .08);

        var x = d3.scale.linear()
            .domain([0, yStackMax])
            .range([0, width]);

        var color = d3.scale.linear()
            .domain([0, n - 1])
            .range(["#aad", "#556"]);

        var svg = d3.select("svg")
            .attr("width", width + margin.left + margin.right)
            .attr("height", height + margin.top + margin.bottom)
          .append("g")
            .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

        var layer = svg.selectAll(".layer")
            .data(layers)
          .enter().append("g")
            .attr("class", "layer")
            .style("fill", function(d, i) { return color(i); });

        layer.selectAll("rect")
            .data(function(d) { return d; })
            .enter().append("rect")
            .attr("y", function(d) { return y(d.x); })
            .attr("x", function(d) { return x(d.y0); })
            .attr("height", y.rangeBand())
            .attr("width", function(d) { return x(d.y); });

        var yAxis = d3.svg.axis()
            .scale(y)
            .tickSize(1)
            .tickPadding(6)
            .tickValues(labels)
            .orient("left");

        svg.append("g")
            .attr("class", "y axis")
            .call(yAxis);



        //ADD IN BOSTOCK CODE -- replace xs with ys and vice versa

        d3.selectAll("input").on("change", change);

        var timeout = setTimeout(function() {
          d3.select("input[value=\"grouped\"]").property("checked", true).each(change);
        }, 2000);

        function change() {
          clearTimeout(timeout);
          if (this.value === "grouped") transitionGrouped();
          else transitionStacked();
        }

        function transitionGrouped() {
          x.domain([0, xGroupMax]);

          rect.transition()
              .duration(500)
              .delay(function(d, i) { return i * 10; })
              .attr("y", function(d, i, j) { return y(d.y) + y.rangeBand() / n * j; })
              .attr("width", y.rangeBand() / n)
            .transition()
              .attr("x", function(d) { return x(d.x); })
              .attr("height", function(d) { return height - x(d.x); });
        }

        function transitionStacked() {
          x.domain([0, xStackMax]);

          rect.transition()
              .duration(500)
              .delay(function(d, i) { return i * 10; })
              .attr("x", function(d) { return x(d.x0 + d.x); })
              .attr("height", function(d) { return x(d.x0) - x(d.x0 + d.x); })
            .transition()
              .attr("y", function(d) { return y(d.y); })
              .attr("width", y.rangeBand());
        }

        // Inspired by Lee Byron's test data generator.
        function bumpLayer(n, o) {

          function bump(a) {
            var y = 1 / (.1 + Math.random()),
                x = 2 * Math.random() - .5,
                z = 10 / (.1 + Math.random());
            for (var i = 0; i < n; i++) {
              var w = (i / n - x) * z;
              a[i] += y * Math.exp(-w * w);
            }
          }

          var a = [], i;
          for (i = 0; i < n; ++i) a[i] = o + o * Math.random();
          for (i = 0; i < 5; ++i) bump(a);
          return a.map(function(d, i) { return {y: i, x: Math.max(0, d)}; });

          }

        </script>   
    </body>
</html>

2 个答案:

答案 0 :(得分:0)

您的网页上看起来没有svg元素。您可以简单地添加您的身体(在您的表单上方或下方),它应该可以工作。

(支流默认为你创建一个svg元素,这是代码在那里运行而不在你的例子中)

答案 1 :(得分:0)

是的,就像enjalot说的那样,你需要一个svg元素,然后你需要将javascript包装在一个函数中并在你的html中添加一个onload,这样它就会在加载页面时执行该函数。像<body onLoad="loadChart()">

这样的东西