gpt4 book ai didi

javascript - 如何在 D3 中重用两个(或更多)链式转换序列

转载 作者:塔克拉玛干 更新时间:2023-11-02 20:29:51 29 4
gpt4 key购买 nike

我必须应用两个非常长的链式转换序列,它们主要在转换顺序上有所不同,我正在寻找一种紧凑的编码方式。

作为玩具示例,考虑序列顺序应为 abcdefghef,g,h,a,b,c >,d。我试过下面的代码,但它不起作用。请注意,过渡可以具有不同的属性(delaydurationease 等),并且它们可以应用于不同的属性(x, y, width, heightcx, cyr 等)和样式。例如,转换 a 可以引用 width,转换 bheight,转换 cx,转换dy,转换etransform属性,将 f 转换为 color 样式,等等。

P.S.:这个问题和我的previous是同一个目的一个,但我使用了太多简单的编码案例,误导了答案。

有什么方法可以用紧凑的方式编写代码吗?

var t1 = d3
.transition() // transition "a" specifications
...
.transition() // transition "b" specifications
...
.transition() // transition "c" specifications
...
.transition() // transition "d" specifications
...
;
var t2 = d3
.transition() // transition "e" specifications
...
.transition() // transition "f" specifications
...
.transition() // transition "g" specifications
...
.transition() // transition "h" specifications
...
;
someelement1
.transition(t1).transition(t2);
someelement2
.transition(t2).transition(t1);

最佳答案

如评论中所述,此问题的回答原则与您上一个问题相同。在这种情况下,您有一组不同的转换,它们可以按不同键引用的任何顺序应用。让我们将它们存储在一个对象中:

var transitions = {
a: function(sel){ return sel.transition().duration(1000).delay(1000).attr('cy', 200) },
b: function(sel){ return sel.transition().duration(2000).delay(0).attr('r', 40) },
c: function(sel){ return sel.transition().duration(500).delay(1500).attr('fill', 'red') },
d: function(sel){ return sel.transition().duration(1500).delay(500).attr('opacity', 0.5) },
e: function(sel){ return sel.transition().duration(1000).delay(3000).attr('cy', 300) },
f: function(sel){ return sel.transition().duration(2000).delay(0).attr('r', 60) },
g: function(sel){ return sel.transition().duration(500).delay(1500).attr('fill', 'magenta') },
h: function(sel){ return sel.transition().duration(1500).delay(500).attr('opacity', 0.25) }
};

每个函数都接受一个 d3.selection 对象,并对其应用特定的转换参数和转换集。这些函数的长度和复杂程度都可以随您的喜好而定。本人比较懒惰,想像力不足,所以他们在这个版本中只做了一次改造。

这里已经有一些代码重复了,所以让我们把选择转换为过渡,并使用this而不是传递参数:

var transitions = {
a: function(){ return this.duration(1000).delay(1000).attr('cy', 200) },
b: function(){ return this.duration(2000).delay(0).attr('r', 40) },
c: function(){ return this.duration(500).delay(1500).attr('fill', 'red') },
d: function(){ return this.duration(1500).delay(500).attr('opacity', 0.5) },
e: function(){ return this.duration(1000).delay(3000).attr('cy', 300) },
f: function(){ return this.duration(2000).delay(0).attr('r', 60) },
g: function(){ return this.duration(500).delay(1500).attr('fill', 'magenta') },
h: function(){ return this.duration(1500).delay(500).attr('opacity', 0.25) }
};

现在我们可以通过调用如下代码来执行这些转换

transitions['a'].call( selection.transition() )
transitions.f.call( d3.select('circle').transition() )

你想指定一个过渡数组来应用到一个选择中,像这样:

apply_transitions( group.select(":nth-child(1)"), ['a','b','c','d'] );
apply_transitions( group.select(":nth-child(2)"), ['e','f','g','h'] );

这可以按如下方式实现:

/**
* apply a series of transitions to a selection
*
* @param selection - d3 selection
* @param tr_arr - array of transition identifiers, referring to functions in the `transitions` object
*/
function apply_transitions( selection, tr_arr ) {

// turn the current selection into a d3.transition
// call the transition function referred to by the first ID in the array
// with the d3.transition as the `this` context
// note that the function returns a transition object, so it can be chained
transitions[ tr_arr[0] ].call( selection.transition() )
// add a handler to be applied at the end of the transition
.on('end', function(){
// if there are more transitions to be applied, call
// apply_transitions again with tr_arr minus the first element
// note that the `this` context in the `on` function is a DOM element,
// so use `d3.select(this)` to turn it into a d3 selection
if ( tr_arr.length > 1 ) {
apply_transitions( d3.select(this), tr_arr.slice(1) );
}
})
}

真人 Action 示例:

    var svg = d3.select('svg').attr('width', 500).attr('height', 500);

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');

apply_transitions( group.select(":nth-child(1)"), ['a','b','c','d'] );

apply_transitions( group.select(":nth-child(2)"), ['e','f','g','h'] );

function apply_transitions( selection, tr_arr ) {

var transitions = {
a: function(){ return this.duration(1000).delay(1000).attr('cy', 200) },
b: function(){ return this.duration(2000).delay(0).attr('r', 40) },
c: function(){ return this.duration(500).delay(1500).attr('fill', 'red') },
d: function(){ return this.duration(1500).delay(500).attr('opacity', 0.5) },
e: function(){ return this.duration(1000).delay(3000).attr('cy', 300) },
f: function(){ return this.duration(2000).delay(0).attr('r', 60) },
g: function(){ return this.duration(500).delay(1500).attr('fill', 'magenta') },
h: function(){ return this.duration(1500).delay(500).attr('opacity', 0.25) }
};

transitions[ tr_arr[0] ].call( selection.transition() )
.on('end', function(){
if ( tr_arr.length > 1 ) {
apply_transitions( d3.select(this), tr_arr.slice(1) );
}
})
}
<script src="http://d3js.org/d3.v5.js"></script>
<svg></svg>

关于javascript - 如何在 D3 中重用两个(或更多)链式转换序列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52463487/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com