我在网络应用程序中使用d3.js。描述我想要做的最简单的方法是查看下面链接的小提琴,但基本设置是我有一个包含数据对象的数组。
my_data = [{
id: "B",
text: "I want this text in B"
}, {
id: "C",
text: "I want this text in C"
}];
我想将my_data中的“text”值添加到DOM中相应的<div>
,这是my_data中相应“id”指定的值。也就是说,DOM包含一个id为“B”的div,而my_data包含一个id为“B”的对象,所以我想将“text”属性的值添加到<div>
,比如说一个<p>
元素。
现在问题。
如何在不知道的情况下编写我的d3选择器以使用my_data中的“id”属性
my_data包含哪些值? (即,我不想对它们进行硬编码!)
我正在使用动态数据源,my_data经常使用
改变。我想使用d3将“text”属性添加到相应的<div>
。
我们保证my_data中的“id”属性将具有相同ID的<div>
已存在于DOM中。
最小的例子: http://jsfiddle.net/3Skq3/1/
答案 0 :(得分:0)
传递给d3.select
的选择器只是字符串。因此,您可以使用属性的值,并将连接它与选择器的其他部分一起使用。例如:
d3.select('#' + my_data[0].id)
答案 1 :(得分:0)
这是一种稍微多一点的D3方式。我们的想法是使用您可以匹配数据阵列的数据预填充div
s,以“过滤”您想要的节点。这有点人为,但是你可以使用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()
来完成的,但我们必须在这里破解它,因为元素已经存在。在那之后,它很简单。完整示例here。
答案 2 :(得分:0)
这类似于Lars的建议,但如果你的页面上有很多<div>
并且只有少数人会被操纵,那么效率会更高。
首先,选择所有<div>
元素,然后根据您的数据数组选择filter that selection。然后,您只使用您拥有数据的元素。使用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]; })
将数据绑定到元素。
答案 3 :(得分:0)
我已使用您的示例和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? (I.e., 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');
&#13;
#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;
}
&#13;
<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>
&#13;