我一直在一步一步地尝试在d3.js可视化中将一些非常漂亮但静态且非d3的code转换为动态动画。
(尽管与该问题没有直接关系,但是原始代码“简单” -haha-接受用户提供的和弦名称(例如“Amaj7”),将其分解为组件音符并显示相关的波形。我正在尝试创建一个基于和弦名称数组的过渡驱动动画。)
就我而言,每次成功完成的代码更新(到d3.js友好版本)时,都会保存源代码以与下一个进行比较。
在当前的代码更新中,我遇到了尝试合并过渡的故障。过渡本身已得到充分证明,并且(通过记录)可以看到按预期触发。
在过渡期间,所需的属性值更改(要处理的下一个和弦名称以及立即过渡的目标)失败。将先前(工作)版本与当前版本进行比较:
初始创建,这两者都通用,但是在单独的文件中,因此只能通过DOM访问
var input = container
.append("input")
.attr("class", wavebase.animation_type + "_input")
.attr("id", "chordinput")
.attr("type", "text")
.attr("value","Amaj7");
旧
var input = document.getElementById('chordinput');
input.addEventListener('change', inputChanged, false);
inputChanged.call(input);
和(转换前):
input.setAttribute("value", (waveplot.chordname + "\x0A"));
inputChanged.call(input);
让我们清楚一点:上面的作品。
新
var input = container
.select("#chordinput")
input.on('change', inputChanged, false);
inputChanged.call(input);
后来,这都不是:
input
.transition()
.text(function() {
return (waveplot.chordname + "\x0A");
})
..也不是这样:
input
.transition()
.attr("value", function() {
return (waveplot.chordname + "\x0A");
});
..nor变量减去返回字符(“\ x0A”)会导致输入元素的value字段更新。顺便说一句,waveplot.chordname总是正确定义的。
鉴于新代码中甚至没有识别出原始的Amaj7,我的直觉是问题在于
input.on('change', inputChanged, false);
显然,在进行过渡时,我的目标是使用此行捕获多个事件。我做不到或做错了什么?例如,我是否必须使用其他触发器(“提交”或“单击”都没有影响),使用d3.dispatch()或什至将每个事件映射到它自己的(“change.n”)处理程序?
注意:就像我想用jsfiddle进行演示一样,整个过程都嵌入在框架中,这在当时是不切实际的。
谢谢
暴徒
最佳答案
这里发生了几件事情,都与d3没有直接关系。但是,在修复代码时,还有一些与d3相关的注意事项,因此我在下面用斜体表示。
首先,设置.text()
不适用于<input>
,因为它会更改.textContent
属性(将被忽略-输入元素为空)。
即使您在有效的文本容器元素上使用了transition().text()
,您也不会看到“过渡”-过渡延迟后,文本将立即发生变化。
其次,输入的value
属性为,而不是与value
属性(即element.value
)相同。该属性(这是您要包含在标记中的属性)在任何用户或脚本交互之前定义输入元素的初始值。加载页面后对其进行更改无效。相反,该属性定义字段的当前值,而不管您是否在脚本中更改它,还是用户是否通过键入对其进行更改。
请参见以下小提琴(仅使用纯Javascript,而不使用d3):
http://fiddle.jshell.net/FVF29/
var i = document.getElementById("i");
i = i;
i.setAttribute("value", "Stuff");
i.value="Good Stuff";
i.setAttribute("value", "Other Stuff");
setAttribute
调用都不会影响显示-文本框包含“Good Stuff”-尽管如果您检查DOM,则会看到该属性已更改。d3尽管不经常使用,但它有一种方法可以更改选择中的元素
selection.property(propertyName, valueOrFunction)
的元素属性。但是,没有等效的转换功能。您可以提出一个有效的功能请求,即应该有一个
transition.property()
函数。根据您的示例,我当然可以看到它的用途-也许您有数字滑块或颜色输入,并且希望显示的值平滑变化,而不是立即跳转到您要设置的值。但是,这仍然不适用于您的情况。假设属性转换功能的实现与属性或样式转换相同,则字符串值的默认转换会将字符串分为数字和非数字段。非数字段立即更改,数字过渡。如果您从“Cmin6”更改为“Amaj7”,那将是奇怪而随机的-您最终会得到类似“Amaj6.569087098608760760876”的和弦!
结论:我不知道您为什么要使用过渡来更改文本字段,或者您希望中间值是什么。如果您对如何计算中间值有清楚的了解,请使用直接设置
this.value
的自定义补间函数。 (有关如何执行此操作的示例,请参见我为this answer, which uses a custom tween to set this.textContent
创建的小提琴。)否则,跳过过渡并仅使用:input.property("value", waveplot.chordname);