Javascript D3中编码链式转换的紧凑方法
我必须应用两个长的链式转换序列,它们主要在某些元素的转换顺序上有所不同,我正在寻找一种紧凑的编码方式。 假设(仅作为玩具示例)我有两个圆,并且我必须将以下颜色应用于第一个圆:Javascript D3中编码链式转换的紧凑方法,javascript,d3.js,transition,Javascript,D3.js,Transition,我必须应用两个长的链式转换序列,它们主要在某些元素的转换顺序上有所不同,我正在寻找一种紧凑的编码方式。 假设(仅作为玩具示例)我有两个圆,并且我必须将以下颜色应用于第一个圆: 橙色->紫色->蓝色->黄色 将以下颜色添加到第二个颜色: 蓝色->黄色->橙色->紫色 我尝试过下面的代码(fiddle),但它不起作用。实现这一点最简单的方法是什么 var svg = d3.select('svg'); var dataSet = [20, 20]; var group=s
橙色
->紫色
->蓝色
->黄色
将以下颜色添加到第二个颜色:
蓝色
->黄色
->橙色
->紫色
我尝试过下面的代码(fiddle),但它不起作用。实现这一点最简单的方法是什么
var svg = d3.select('svg');
var dataSet = [20, 20];
var group=svg.append("g");
var circles = group.selectAll('circle')
.data(dataSet)
.enter()
.append('circle')
.attr("r",function(d){ return d })
.attr("cx",function(d, i){ return i * 100 + 50 })
.attr("cy",50)
.attr("fill",'black');
var t1 = d3
.transition()
.duration(1000)
.attr("fill","orange")
.transition()
.duration(1000)
.attr("fill","purple");
var t2 = d3
.transition()
.duration(1000)
.attr("fill","blue")
.transition()
.duration(1000)
.attr("fill","yellow");
group.select(":nth-child(1)")
.transition(t1).transition(t2);
group.select(":nth-child(2)")
.transition(t2).transition(t1);
如果创建一个函数来应用转换,则可以将代码压缩得相当紧凑:
/**
* Apply a transition with the appropriate delay to a selection
*
* @param sel: a d3 selection
* @param fill: the fill colour
* @param position: the position of the colour in the set of transitions
*/
function tr(sel, fill, position) {
sel.transition()
.duration(1000)
.delay(1000 * position)
.ease(d3.easeLinear)
.attr("fill", fill);
}
// example of use:
tr(group.select(":nth-child(1)"), 'blue', 0)
tr(group.select(":nth-child(2)"), 'red', 2)
在行动中:
功能tr(选择、填充、位置){
sel.transition()
.持续时间(1000)
.延迟(1000*pos)
.ease(d3.easeLinear)
.attr(“填充”,填充);
}
var svg=d3.select('svg');
var数据集=[20,20];
var group=svg.append(“g”);
var circles=group.selectAll('circle'))
.数据(数据集)
.输入()
.append('圆')
.attr(“r”,函数(d){返回d})
.attr(“cx”,函数(d,i){返回i*100+50})
.attr(“cy”,50)
.attr(“填充”、“黑色”);
变量颜色={
1:[“橙色”、“紫色”、“蓝色”、“黄色”],
2:[‘深蓝’、‘深粉红’、‘黄花’、‘洋红’]
};
对象。键(颜色)。forEach(函数(ix){
var el=组。选择(“:n个子项(+ix+”);
颜色[ix].forEach(函数(c,i){tr(el,c,i);});
})
实现这一点有多种方法。正如在另一个答案中所指出的那样,为此使用函数将保持代码紧凑。就我个人而言,我倾向于使用转换的结束事件从转换函数中触发下一个转换 这类函数的一般形式如下:
function transition() {
// .... optional logic here.
d3.select(this) // do transition:
.transition()
.attr("fill", ... )
.on("end", transition); // and repeat.
}
它可以通过选择调用。每个(转换)
管理循环中当前颜色/过渡的一种方法是使用自定义属性。下面我使用.attr(“I”)
跟踪:
var数据=[
[“橙色”、“紫色”、“蓝色”、“黄色”],
[“蓝色”、“黄色”、“橙色”、“紫色”]
];
var svg=d3.选择(“svg”);
var circles=svg.selectAll()
.数据(数据)
.输入()
.附加(“圆圈”)
.attr(“r”,20)
.attr(“cx”,函数(d,i){返回i*50+50;})
.attr(“cy”,50)
.attr(“fill”,函数(d){返回d[0];})
.attr(“i”,0)
.每次(过渡);
//无休止地循环:
函数转换(){
var选择=d3.选择(本);
//跟踪当前值:
var i=selection.attr(“i”)
选择
.attr(“i”,i=+i%4)
.transition()
.持续时间(1000)
.attr(“fill”,函数(d){返回d[i]})
.关于(“结束”,过渡);
}
Neat solution-我喜欢使用颜色对象来进行选择和设置过渡。我想问的问题比上面的问题更广泛。由于我的描述很差,所以被误解了。我写了一个新问题:够公平了。然而,要把这个概括起来,你应该考虑接受其中一个答案,因为它们是这个问题的可行解决方案。