繁体   English   中英

如何使用数据对象中的值指定d3.js选择器?

[英]How can I specify a d3.js selector using values from a data object?

我在Web应用程序中使用d3.js。 描述我想做的最简单的方法是查看下面的Fiddle链接,但是基本设置是我有一个包含数据对象的数组。

my_data = [{
    id: "B",
    text: "I want this text in B"
}, {
    id: "C",
    text: "I want this text in C"
}];

我想将my_data中的“文本”值添加到DOM中的相应<div> ,这些值是由my_data中相应的“ id”指定的。 也就是说,DOM包含一个ID为“ B”的div,而my_data包含一个ID为“ B”的对象,因此我想将<div> text>属性的值添加到该<div> ,例如<p>元素。

现在的问题。

如何在不知道my_data将包含哪些值的情况下编写d3选择器以使用my_data中的“ id”属性? (即,我不想对其进行硬编码!)我正在使用动态数据源,并且my_data会经常更改。 我想使用d3将“文本”属性添加到适当的<div>中。 可以确保my_data中的“ id”属性将具有<div> ,该<div>具有DOM中已经存在的相同ID。

最小示例: http : //jsfiddle.net/3Skq3/1/

传递给d3.select的选择器只是字符串。 因此,您可以使用属性的值并将其与选择器的其他部分串联在一起 例如:

d3.select('#' + my_data[0].id)

这是D3的一种略微实现方法。 这个想法是用数据预填充div ,然后可以将数据数组与之匹配以“过滤”出所需的节点。 这有点做作,但是使您能够使用D3的数据匹配来完成工作。

d3.selectAll("div")
  .each(function() { this.__data__ = { id: this.id }; })
  .data(my_data, function(d) { return d.id; })
  .text(function(d) { return d.text; });

.each()通过获取元素的当前ID将数据“绑定”到元素。 通常可以通过D3中的.data()完成此操作,但是由于元素已经存在,因此我们必须在此处进行破解。 在那之后,这很简单。 这里完整的例子。

这类似于Lars的建议,但是如果页面上有很多<div>且将要操纵的数量很少,则效率可能更高。

首先,选择所有<div>元素,然后根据您的数据数组过滤该选择 然后,您只需要处理您拥有数据的元素。 使用key:value对象中的数据可以更快地工作,但是您也可以在过滤器测试中使用array.some()

var dataMap = {};
my_data.forEach(function(d){dataMap[d.id] = d;})

d3.selectAll("div")
  .filter(function(){ return !!dataMap[this.id]; }) 
      //returns true if the element's id is in the data
  .text(function(){ return dataMap[this.id].text; })

如果您要做的不仅仅是设置文本,还需要做更多复杂的事情,那么您将需要使用.datum(function(){ return dataMap[this.id]; })将数据绑定到元素。

我使用您的示例和位于http://bost.ocks.org/mike/bar/的教程创建了一个代码段

要仅更改文本,您可以随时拨打此电话。

d3.select('#B').text('Now I want to B');

但是,如果您需要更动态的解决方案,则此功能应该会有所帮助。

  function getObjByValue(myRoot, myType, myVal, newText){
    var d;
    console.log(typeof myRoot)
    if(typeof myRoot == "object"){
      for(d in myRoot){
        console.log(myRoot[d][myType])
        if(myRoot[d][myType] == myVal){
          d3.select('#'+myVal).text([newText]);
        }
      }
    }
  } 

getObjByValue(data, 'id', 'B', 'Now I want to B');

改编自https://gist.github.com/CrandellWS/79be3b8c9e8b74549af5

 data = [{ id: "A", text: "Hi From A", digit:12 }, { id: "B", text: "Hi From B", digit:8 }, { id: "C", text: "Hi From C", digit:15 }, { id: "D", text: "Hi From D", digit:42 }]; // I want to add the "text" values in my_data to the appropriate <divs>, which are the ones // specified by the corresponding "id" in my_data. // How can I write my d3 selector to use the "id" properties in my_data, without knowing // what values my_data will contain? (Ie, I don't want to hardcode them!) // I'm using a dynamic data source, and my_data will frequently be // changing. I'd like to add the "text" property to the appropriate <div> using d3. // It is guaranteed that the "id" properties in my_data will have a <div> with the same id // already present in the DOM. //From the tutorial at //http://bost.ocks.org/mike/bar/ //var data = [4, 8, 15, 16, 23, 42]; var x = d3.scale.linear() .domain([0, 4]) .range([0, 42]); d3.select(".chart") .selectAll("div") .data(data) .enter().append("div") .attr("id", function(d) {return d.id}) .attr("name", function(d) {return d.id}) .style("width", function(d) {return x(d.digit) + "px"; }) .text(function(d) { return d.text; }); //From the tutorial at //http://bost.ocks.org/mike/bar/ //var data = [4, 8, 15, 16, 23, 42]; var x = d3.scale.linear() .domain([0, 4]) .range([0, 42]); d3.select(".chart") .selectAll("div") .data(data) .enter().append("div") .attr("id", function(d) {return d.id}) .attr("name", function(d) {return d.id}) .style("width", function(d) {return x(d.digit) + "px"; }) .text(function(d) { return d.text; }); function getObjByValue(myRoot, myType, myVal, newText){ var d; console.log(typeof myRoot) if(typeof myRoot == "object"){ for(d in myRoot){ console.log(myRoot[d][myType]) if(myRoot[d][myType] == myVal){ d3.select('#'+myVal).text([newText]); } } } } getObjByValue(data, 'id', 'B', 'Now I want to B'); 
 #A { background-color: steelblue; } #B { background-color: red; } #C { background-color: green; } #D { background-color: orange; } #oldA { background-color: steelblue; } #oldB { background-color: red; } #oldC { background-color: green; } #oldD { background-color: orange; } .chart div { font: 10px sans-serif; background-color: steelblue; text-align: right; padding: 3px; margin: 1px; color: white; } 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script> <div id="oldA" class="my_div"> <p>Hi From A</p> </div> <div id="oldB" class="my_div"> <p>Hi From B</p> </div> <div id="oldC" class="my_div"> <p>Hi From C</p> </div> <div id="oldD" class="my_div"> <p>Hi From D</p> </div> <br> I want this text in B <div class="chart"></div> 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM