我一直在一步一步地尝试在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);

07-28 02:50
查看更多