2

我正在学习 D3,以及如何使用 D3 的数据绑定机制将元素嵌套或附加到页面。

我修改了http://www.recursion.org/d3-for-mere-mortals/上的代码。我了解如何设置 svg 画布,也了解将数据绑定到矩形、文本和线条元素的循环。

我不明白的是selectAll('Anything1/2/3/4')下面的电话。它们显然是必要的,但我究竟选择了什么,它们如何适应数据绑定机制?谢谢你。

    <html>
    <head>
        <title>D3 Test</title>
        <script type="text/javascript" src="d3/d3.v2.js"></script>
    </head>
    <body>

        <script type="text/javascript">

var dat = [ { title:"A", subtitle:"a", year: 2006, books: 54, avg:10 },
            { title:"B", subtitle:"b", year: 2007, books: 43, avg:10 },
            { title:"C", subtitle:"c", year: 2008, books: 41, avg:10 },
            { title:"D", subtitle:"d", year: 2009, books: 44, avg:10 },
            { title:"E", subtitle:"e", year: 2010, books: 35, avg:10 } ];

var width    = 560,
    height   = 500,
    margin   = 20,
    innerBarWidth =  20,
    outerBarWidth =  40;


var x = d3.scale.linear().domain([0, dat.length]).range([0, width]);
var y = d3.scale.linear()
    .range([0, height - 2 * margin])
    .domain([ 0 , 100 ]);

var z = d3.scale.category10();

var n = d3.format(",d"),
    p = d3.format("%");

var canvas = d3.select("body").append("svg")
    .attr("width", width)
    .attr("height", height)
    .append("g")
    .attr("transform", "translate(" + 2 * margin + "," + margin + ")");

// outerbars
var outerBars = d3.select("svg")
  .selectAll("Anything1").data(dat).enter().append("rect")
  .attr("x", function(datum, index) { return x(index); })
  .attr("y", function(datum) { return height - y(datum.books); })
  .attr("height", function(datum) { return y(datum.books); })
  .attr("width", outerBarWidth)
  .attr("fill", "blue")

// innerbars
var innterBars = d3.select("svg")
  .selectAll("Anything2").data(dat).enter().append("rect")
  .attr("x", function(datum, index) { return x(index)+innerBarWidth/2; })
  .attr("y", function(datum) { return height - y(datum.books)/2; })
  .attr("height", function(datum) { return y(datum.books); })
  .attr("width", innerBarWidth)
  .attr("fill", "red");

// avg references
var barlabels = d3.select("svg")
  .selectAll("Anything3").data(dat).enter().append("line")
  .attr("x1", function(datum, index) { return x(index); })
  .attr("x2", function(datum, index) { return x(index)+outerBarWidth; })
  .attr("y1", function(datum) { return height - y(datum.books)/2; })
  .attr("y2", function(datum) { return height - y(datum.books)/2; })
  .style("stroke", "#ccc");

// titles
var barlabels = d3.select("svg")
  .selectAll("Anything4").data(dat).enter().append("text")
  .attr("x", function(datum, index) { return x(index)+innerBarWidth/2; })
  .attr("y", height )
  .attr("text-anchor", "end")
  .text(function (d) {return d.title} );

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

2 回答 2

3

也许 d3 中最重要但最难理解的概念是选择(我强烈建议您添加书签并熟悉 API)。从表面上看,选择提供了与许多其他 JavaScript 库类似的功能,例如 jQuery:

jQuery:

var paragraphs = $("p");

d3:

var paragraphs = d3.selectAll("p");

这两行都创建了“选择对象”,它们本质上是 DOM 元素,它们被组合成一个对象,让您可以更好地控制元素。与其他库一样,您可以使用库中提供的函数在 d3 中操作这些“选定”元素。

jQuery:

var paragraphs = $("p").css("color", "red");

d3:

var paragraphs = d3.selectAll("p").style("color", "red");

同样,从表面上看,这很容易理解。d3 如此强大的原因在于,它允许您将任意数据绑定到所选元素,从而让您更进一步。

假设您有一个空白文档,并且想要添加几段文本 - 并且您将每段文本存储在数组中的单个元素中:

var text = ["First", "Second", "Third", "Fourth"];

由于我们尚未创建这些段落,因此以下调用将返回一个空选择

var paragraphs = d3.selectAll("p");
console.log(paragraphs.empty()); // true

请注意,这paragraphs仍然是一个选择,它只是空的。这是 d3 的一个基本点。您可以将数据绑定到空选择,然后使用输入的选择使用数据添加新元素。让我们从之前的示例重新开始,并逐步完成这个过程。首先,创建您的空选择并将text数组绑定到它:

var paragraphs = d3.select("body").selectAll("p").data(text);

然后,使用输入选择,将元素附加<p>到正文:

paragraphs.enter().append("p").text(function(d) { return d; });

您的 DOM 现在将具有:

<body>
    <p>First</p>
    <p>Second</p>
    <p>Third</p>
    <p>Fourth</p>
</body>

在这一点上肯定有很多事情会让你感到困惑,但我认为这应该会给你一个好的开始。

另请参阅:使用联接思考

于 2012-09-24T21:37:16.027 回答
1

以下是一些帮助您入门的读物:

理解 selectAll、data、enter、append 序列
绑定数据:Scott Murray D3 Tutorials

从第二个链接它解释:

答案在于 enter(),一个真正神奇的方法。这是此示例的最终代码,我将对其进行解释:

d3.select("body").selectAll("p")
    .data(dataset)
    .enter()
    .append("p")
    .text("New paragraph!");

.selectAll("p")— 选择 DOM 中的所有段落。由于尚不存在,因此这将返回一个空选择。将此空选择视为表示即将存在的段落。

基本上,您正在选择尚不存在的 DOM 元素,然后将数据附加到这些不存在的元素,然后在绑定数据后附加它们。

于 2012-09-24T00:49:46.333 回答