- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个词云,可以按日期范围和情绪进行过滤。有时数据会多,有时数据会少。当我删除数据,更新 dom,然后添加数据时,被删除的元素将不会回来。使用d3js版本3.4.13
<小时/> var width = 600, height = 200;
var words = ["Hello", "world", "Wonderful"];
//inserting text
var wcwords = d3.select("#wordcloud")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")")
.selectAll("text")
.data(words)
.enter()
.append("text");
wcwords
.attr("transform", function(d,i) {
return "translate(" + [5, 20*i] + ")";
})
.text(function(d) { return d; });
//changing data and updating dom (in this change there are less items)
wcwords.data(words.slice(0,2)).exit().remove();
//changing data and updating dom (in this change there are more items)
wcwords.data(words.concat(["No"])).enter().append('text')
.attr("transform", function(d,i) {
return "translate(" + [5, 20*i] + ")";
})
.text(function(d) { return d; });
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<svg id='wordcloud'></svg>
原始代码不起作用,用满足我需要的代码更新了我的帖子。新的、删除的和更新的项目的动画效果不同。我可以更改现有项目、删除项目并再次退回项目。
诀窍是使用正确的选择parent.selectAll(children)
并传递更新对象(.data(newData)
返回的对象)
这是“工作”代码,希望我做得正确:
var width = 600;
var height = 200;
var words = ["Hello", "world", "Wonderful"];
var when=1000;
var step=1;
//this function sets the data and passes the update object
// to exit, update and enter
function change(data){
var update = d3.select('#wccontainer')
.selectAll('text')
.data(data);
exitWords(update);
updateWords(update);
enterWords(update);
}
//existing items move to the right
function updateWords(update){
update
//this is an existing item, no need for append
.text(function(d) { return d; })
.transition()
.duration(when-100)
.attr("transform", function(d,i) {
this.left=this.left+25;
return "translate(" + [this.left, 20*i] + ")";
})
.style('opacity',1);
}
//new items fade in
function enterWords(update){
update
.enter()
.append("text")
.attr("transform", function(d,i) {
this.left=0;
return "translate(" + [5, 20*i] + ")";
})
.text(function(d) { return d; })
.style('opacity',0)
.transition()
.duration(when-100)
.attr("transform", function(d,i) {
return "translate(" + [5, 20*i] + ")";
})
.style('opacity',1);
}
//removed words fade out
function exitWords(update){
var removeItems = update
.exit()
removeItems
.transition()
.duration(when-800)
.style('opacity',0)
.each('end',function(){
removeItems.remove();
});
}
function later(when,fn,parms){
setTimeout(function(){
fn.apply(null,parms);
},when);
}
//create the g container and set svg width/height
d3.select("#wordcloud")
.attr("width", width)
.attr("height", height)
.append("g")
.attr('id','wccontainer')
.attr("transform", "translate(" + width / 2
+ "," + height / 2 + ")")
//set the text labels
change(words);
//in 1000ms (value of when) set the text lables with changed data
later(when,change,[words.slice(0,2)]);
//in 2000ms set the text lables with changed data
later(when*++step,change,[["CHANGED"]
.concat(words.slice(1,2))
.concat(["ONE","TWO","THREE","FOUR"])]);
//in 3000ms set the text lables with the original values
later(when*++step,change,[words]);
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<svg id='wordcloud'></svg>
最佳答案
我先解释一下发生了什么......
var width = 600, height = 200;
var words = ["Hello", "world", "Wonderful"];
var wcwords = d3.select("#wordcloud")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")")
.selectAll("text")
.data(words);
.enter()
.append("text");
wcwords 现在是一个输入选择,它恰好具有与更新集合相同的结构,因为所有元素都是新的。由于使用了 selectAll
,因此选择内容嵌套在 g
节点下:这是选择内容的父对象。
wcwords
.attr("transform", function(d,i) {
return "translate(" + [5, 20*i] + ")";
})
.text(function(d) { return d; });
wcwords.data(words.slice(0,2)).exit().remove();
这一切都是使用 data
方法作为选择器来删除一个 DOM 元素。新选择(仅包含两个元素)未在范围内引用,并且 wcwords
未更改,因此实际上 DOM 现在与选择不同步。 p>
wcwords.data(words.concat(["No"])).enter().append('text')
.attr("transform", function(d,i) {
return "translate(" + [5, 20*i] + ")";
})
.text(function(d) { return d; });
创建了一个新的选择,并且 wcwords
对象再次保持不变。将 wcwords
的节点结构(不是 DOM 结构)与新的数据结构进行比较,因为前者有 3 个节点,后者有 4 个节点,并且因为 data
保留索引时,输入选择将由一组 4 个元素组成,前三个元素 null
,最后一个元素是新节点的数据对象。然后,通过 append
语句将新的文本节点添加到 wcwords
父节点(g
)的末尾。由于第三个元素不在 enetr 选择中,因此不会重新插入。
基本原则是
data
不会更改调用它的对象,它返回对新选择的引用(此处被忽略)data
语句在构造进入、更新和退出选择时将选择结构与数据结构进行比较。它不与 DOM 结构进行比较。我猜测您期望的顺序,因为您尚未共享该顺序,但也许您想要类似以下的内容。
var width = 70, height = 100;
var words = ["Hello", "world", "Wonderful"];
var outputLog = OutputLog("#output-log");
var transitionLog = OutputLog("#transition-log");
var wcwords = d3.select("#wordcloud").style("display", "inline-block")
.attr("width", width)
.attr("height", height)
.append("g")
.style("font-size", "10px")
.attr("transform", "translate(" + 10 + "," + 20 + ")")
.selectAll("text")
.data(words)
.enter()
.append("text")
.style("opacity", 0);
wcwords
.text(function(d) { return d; })
.attr("transform", function(d,i) {
return "translate(" + [5, 20*i] + ")";
})
.call(step, 0, "in")
.call(log, "wcwords.data(words) enter");
// bind a new data set to the selection and return the update selection
var wcwords = wcwords.data(words.slice(0,2))
.call(log, "wcwords.data(words.slice(0,2)) update");
// merge the enter selection into the update selection and update the DOM
wcwords.enter()
.append("text")
.style("opacity", 0);
wcwords.exit().transition().call(step, 1, "out").remove()
.call(log, "exit");
// modify the selection by rebinding the original data
// but with an extra element concatenated
// and return the update selection
var wcwords = wcwords.data(words.concat(["No"]))
.call(log, "wcwords.data(words.concat(['No'])) update");
// update the DOM and merge the exit selection into the update selection
wcwords.enter().append('text')
.attr("transform", function(d,i) {
return "translate(" + [5, 20*i] + ")";
})
.text(function(d) { return d; })
.style("opacity", 0)
.call(step, 2, "in")
.call(log, "enter");
function datum(n){
return n ? d3.select(n).datum() : "";
}
function step (selection, s, type) {
var id = Date.now(),
opacity = {in: 1, out: 0},
t = 1000,
w = 0, b = "";
selection.each(function(d){w = Math.max(w, d.length) });
b = new Array(w+4).join('_')
this.transition(Date.now()).delay(s * t).duration(t)
.each("start." + id, function(d, i, j){
var n = this, node = d3.select(n),
DOM_node = d3.select(selection[0].parentNode)
.selectAll(this.nodeName).filter(function(d){return node.datum() === d});
DOM_node = DOM_node.length ? DOM_node[0][0] : null;
transitionLog.writeLine(["start ", (""+id).slice(-4), s, type, (d+b).slice(0,w), style(this, "opacity") || "null", DOM_node === n].join("\t"))
})
.each("interrupt." + id, function(d){
console.log(["\tinterrupt ", id, type, style(this, "opacity"), s].join("\t"))
})
.each("end." + id, function(d){
var n = this, node = d3.select(n),
DOM_node = d3.select(selection[0].parentNode)
.selectAll(this.nodeName).filter(function(d){return node.datum() === d});
DOM_node = DOM_node.length ? DOM_node[0][0] : null;
transitionLog.writeLine(["end", (""+id).slice(-4), s, type, (d+b).slice(0,w), style(this, "opacity") || "null", DOM_node === n].join("\t"))
})
.style("opacity", opacity[type]);
function style(n, a){return d3.select(n).style(a)}
}
function log(selection, title){
outputLog.writeLine(title);
outputLog.writeLine(this[0].map(datum), 1);
}
function OutputLog(selector) {
var outputLog = d3.select(selector)
.style({
"display" : "inline-block",
"font-size" : "10px",
"margin-left": "10px",
padding : "1em",
"white-space": "pre",
"background" : "#fd9801",
});
outputLog.writeLine = (function() {
var s = "";
return function(l, indent) {
this.text((s += ((indent ? " " : "") + l + "\n")));
}
})();
return outputLog
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.6/d3.min.js" charset="UTF-8"></script>
<svg id='wordcloud'></svg>
<div id="output-log"></div>
<div id="transition-log"></div>
关于javascript - d3js Enter().exit().remove()后追加,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32368401/
我已经禁用了回车键,以便可以执行 ajax 提交,但我想确保如果用户在服务器响应返回之前按两次回车键,则表单不会提交两次。 这里我禁用了回车键并为其分配了一个名为 submitForm() 的函数:
我正在尝试将 $animate 服务合并到我自己的指令中。我无法进入并离开以实际设置动画。 奇怪的是,使用$animate.enter,元素附加到DOM,回调函数触发。但似乎从未添加 ng-anima
如果 ,我如何检查 Bash输入 键被按下了? 我正在使用读取命令: read -p "Please press ENTER" var 最佳答案 首先检查退出状态是否正常($?应该为0)。 其次,检查
在我的 PreviewKeyDown() handler 如何区分数字键盘上的 ENTER 键和主板上的 ENTER 键? 两个键返回相同的值 Key.Enter为 KeyEventArgs.Key
这个问题已经有答案了: How do I detect "shift+enter" and generate a new line in Textarea? (19 个回答) 已关闭10 年前。 我正
我的问题与这个 question 有点相关.但是,我没有奢侈去监听 submit 事件,所以这个问题的答案对我来说不起作用。 我的问题:是否可以在 Javascript 中检测日文/中文建议菜单何时打
我希望能够在不需要实现新类的情况下修改 wpf 文本框的行为。 我想要一个类似 Enter/Alt+Enter 行为的 Excel,当用户点击“Enter”时,文本框被验证(movefocus ...
在 Chrome 中的 contenteditable 中按 Enter 时,会插入一个 div。这会干扰我的标记,我需要它成为 br。 我知道shift-enter是一个br。解决问题的最佳方法是什
我正在使用$('.inputs').keydown(function (e) { if (e.which === 13) {到达下一个输入字段。但是每次我按 enter/return 转到下一个输入字
我有一个 textarea ,其中当您单独按 Enter 时,jquery ajax 会启动,但我想添加一个功能,即当您按 Enter + Shift 时仅转到新行并且不启动ajax。你能指导一下吗?
场景如下: 有一个密码字段,我可以在其中输入文本(这是使用 sendKeys 完成的) 现在,没有提交/输入按钮 所以我必须按 Enter 键并登录应用程序 以下是我搜索并尝试但没有成功的几种方法:
这是我尝试过的,但显然失败了: ed.on('keyup', function(e){ console.log(e.keyCode) if(e.keyCode == 13 && !e.
所以我有一个带有 jQuery 的表单,可以阻止用户使用 Enter 键提交表单。 这是代码: $(document).ready(function() { // code prevent
有人知道如何在Javascript中检测按键代码“+1 Enter”和“-1 Enter”吗?我想检测何时一一按下键码而不是一次按下键码。 但是当我编写以下代码时,没有给出任何效果。 // +1 en
我想添加 shift + enter 键转到下一行,只需 enter 键 即可使用 JAVASCRIPT 触发提交按钮仅。 如何实现? 我也想提交多行文本......提前致谢 function typ
int DisplaySchedule() { int nDisplaySchedule_Choice; system("cls"); printf("----- DISPLA
在 textarea 中,当用户按下 Shift+Enter 时,它应该在下一个新行继续,当他简单地按下 Enter 时,它应该提交表单而不使用提交按钮。 这是 Fiddle!! 我浏览了很多但对我没
我有以下简单的 我还有以下 jQuery/JavaScript 代码块: $('textarea#streamWriter').keydown(function (e) { if (e.k
我有许多将转换为HTML的Word文档。要求单词文档中的段落应转换为元素。 在使用Microsoft Office API的SaveAs方法进行了一些测试以将文档转换为HTML之后,我意识到带有手动换
终端是否可以检测 ⇧ Shift+Enter↵ 或 Ctrl+Enter↵ 按键? 我正在尝试配置 vim 来执行使用这些序列的键映射,虽然它们在 gvim 中工作正常,但它们似乎在任何终端控制台中都
我是一名优秀的程序员,十分优秀!