使用 d3 在现有 div 中更改数据集时替换文本值
Replace text value upon dataset change within an existing div using d3
我试图在选择新数据集时使用 d3.select 替换现有 div 中的文本,但每次选择新数据集时我所写的内容都会添加新的 div。用例是一个排行榜,它挑选出从某个 material(金牌、银牌、铜牌等)中创建对象的顶级人群 (d.Culture)。
有问题的页面:https://3milychu.github.io/whatmakesart/
加载需要整整一分钟(如果您看到条形图,则页面已加载)
我还尝试按照我查看过的其他建议添加 .remove() 和 .exit(),但未成功。
出于某种原因,即使目标 div 是 类,我也必须使用“.myDiv”而不是“#myDiv”来查看文本。
function origins(dataset) {
var totalRows = dataset.length;
console.log(totalRows);
var format = d3.format(".0%");
var origins = d3.nest()
.key(function(d) { return d.Culture; })
.rollup(function(v) { return v.length; })
.entries(dataset)
.sort(function(a,b) {return d3.descending(a.value,b.value);});
console.log(origins);
var culture1 = d3.select(".culture").selectAll(".culture1")
.data(origins)
.enter()
.append("div")
.attr("id", "culture1")
.filter(function (d, i) { return i === 0;})
.text(function(d) { return d.key + " " + format(d.value/totalRows); })
<--repeat for "culture2", "culture3", etc. -->
};
我要定位的 html div:
<!-- Origins -->
<div id ="origins">
<h1>Origins</h1>
<div class="culture" id="culture1"></div>
<div class="culture" id="culture2"></div>
<div class="culture" id="culture3"></div>
<div class="culture" id="culture4"></div>
<div class="culture" id="culture5"></div>
<div class="culture" id="culture6"></div>
<div class="culture" id="culture7"></div>
</div>
这里发生了几件有问题的事情。
首先,当您执行 .attr("id", "culture1")
时,您将附加许多具有相同 ID 的 div
。这可能会导致各种意外问题。
filter
功能并不像您预期的那样有效。当您执行 .filter(function (d, i) { return i === 0;})
时,您仍在为所有与过滤器不匹配的元素创建空的 div
。在 chrome 中使用 DOM 检查器,您会看到大量空的 div
。如果您只想从数组中获取第一个元素,我建议只将该数据传递给 data
函数。如果每次将 origins
传递给 data
函数时,origins
的大小都会不同,那么您将需要在退出时删除该元素。但是如果 origins
数组大小相同,则现有数据应该更新。
这应该有助于解决您所看到的行为。可能还有其他问题,但这些都是应该首先解决的明确问题。
我得到以下内容来替换 selection 变化时的行列:
function origins(dataset) {
var totalRows = dataset.length;
console.log(totalRows);
var format = d3.format(".0%");
var origins = d3.nest()
.key(function(d) { return d.Culture; })
.rollup(function(v) { return v.length; })
.entries(dataset)
.sort(function(a,b) {return d3.descending(a.value,b.value);});
// console.log(origins);
d3.select(".culture").selectAll("text").remove()
var culture1 = d3.select(".culture").selectAll("#ranks")
.data(origins.filter(function (d, i) { return i === 0;}))
.enter()
.append("text")
.attr("id", "culture1")
.text(function(d) { return d.key + " " + format(d.value/totalRows); })
.exit();
<--repeat for all ranks -->
};
将html改为:
<div id ="origins">
<h1>Origins</h1>
<div class="culture" id="ranks"></div>
</div>
关键是 select div 中的元素类型,并在声明变量和追加之前 .remove() 它们。同样根据 Jeff 的建议,通过 .data() 处的过滤器可以防止创建额外的元素。
我试图在选择新数据集时使用 d3.select 替换现有 div 中的文本,但每次选择新数据集时我所写的内容都会添加新的 div。用例是一个排行榜,它挑选出从某个 material(金牌、银牌、铜牌等)中创建对象的顶级人群 (d.Culture)。
有问题的页面:https://3milychu.github.io/whatmakesart/
加载需要整整一分钟(如果您看到条形图,则页面已加载)
我还尝试按照我查看过的其他建议添加 .remove() 和 .exit(),但未成功。
出于某种原因,即使目标 div 是 类,我也必须使用“.myDiv”而不是“#myDiv”来查看文本。
function origins(dataset) {
var totalRows = dataset.length;
console.log(totalRows);
var format = d3.format(".0%");
var origins = d3.nest()
.key(function(d) { return d.Culture; })
.rollup(function(v) { return v.length; })
.entries(dataset)
.sort(function(a,b) {return d3.descending(a.value,b.value);});
console.log(origins);
var culture1 = d3.select(".culture").selectAll(".culture1")
.data(origins)
.enter()
.append("div")
.attr("id", "culture1")
.filter(function (d, i) { return i === 0;})
.text(function(d) { return d.key + " " + format(d.value/totalRows); })
<--repeat for "culture2", "culture3", etc. -->
};
我要定位的 html div:
<!-- Origins -->
<div id ="origins">
<h1>Origins</h1>
<div class="culture" id="culture1"></div>
<div class="culture" id="culture2"></div>
<div class="culture" id="culture3"></div>
<div class="culture" id="culture4"></div>
<div class="culture" id="culture5"></div>
<div class="culture" id="culture6"></div>
<div class="culture" id="culture7"></div>
</div>
这里发生了几件有问题的事情。
首先,当您执行 .attr("id", "culture1")
时,您将附加许多具有相同 ID 的 div
。这可能会导致各种意外问题。
filter
功能并不像您预期的那样有效。当您执行 .filter(function (d, i) { return i === 0;})
时,您仍在为所有与过滤器不匹配的元素创建空的 div
。在 chrome 中使用 DOM 检查器,您会看到大量空的 div
。如果您只想从数组中获取第一个元素,我建议只将该数据传递给 data
函数。如果每次将 origins
传递给 data
函数时,origins
的大小都会不同,那么您将需要在退出时删除该元素。但是如果 origins
数组大小相同,则现有数据应该更新。
这应该有助于解决您所看到的行为。可能还有其他问题,但这些都是应该首先解决的明确问题。
我得到以下内容来替换 selection 变化时的行列:
function origins(dataset) {
var totalRows = dataset.length;
console.log(totalRows);
var format = d3.format(".0%");
var origins = d3.nest()
.key(function(d) { return d.Culture; })
.rollup(function(v) { return v.length; })
.entries(dataset)
.sort(function(a,b) {return d3.descending(a.value,b.value);});
// console.log(origins);
d3.select(".culture").selectAll("text").remove()
var culture1 = d3.select(".culture").selectAll("#ranks")
.data(origins.filter(function (d, i) { return i === 0;}))
.enter()
.append("text")
.attr("id", "culture1")
.text(function(d) { return d.key + " " + format(d.value/totalRows); })
.exit();
<--repeat for all ranks -->
};
将html改为:
<div id ="origins">
<h1>Origins</h1>
<div class="culture" id="ranks"></div>
</div>
关键是 select div 中的元素类型,并在声明变量和追加之前 .remove() 它们。同样根据 Jeff 的建议,通过 .data() 处的过滤器可以防止创建额外的元素。