我正在使用d3.v4.min.js
在下面的代码段中生成条形图。
由于某些未知原因,transition().delay()
函数表现得很奇怪。
我将函数(d,i)=>{return i*100}
作为参数传递,以使每列在开始动画之前等待100毫秒的倍数。至少,这是我预期会发生的事情,因为i
的值应为0,1,2,...etc
。
但是,所有列都会立即启动动画,并且我已将根本原因追溯到i
函数中的dealy()
。它在所有迭代中都固定为零。
我做错了什么?
//jshint esnext:true
const margin = {top: 30, bottom: 70, left: 40, right: 10};
const width = 600, height=200;
const color = d3.scaleOrdinal(d3.schemeCategory20);
const data = [{name:'ahmad',age:22},
{name:'saleh',age:15},
{name:'fulan',age:35},
{name:'fazil',age:48},
{name:'majid',age:50}
];
const svg = d3.select("body").append("svg")
.attr("width",width)
.attr("height",height)
.style("background-color","beige");
const max = d3.max(data,d=>{return d.age;});
const min = 0; //1 || d3.min(data,d=>{return d.age;});
const y = d3.scaleLinear().domain([min,max]).range([height-margin.bottom,margin.top]);
const yAxis = d3.axisLeft().scale(y);
const x = d3.scaleBand()
.domain(data.map(d=>{return d.name;}))
.range([margin.left,width-margin.right])
.padding(0.4);
const xAxis = d3.axisBottom().scale(x);
svg.append("g").attr("class","y axis").attr("transform","translate("+margin.left+",0)").call(yAxis);
svg.append("g").attr("class","x axis").attr("transform","translate(0,"+(height-margin.bottom)+")").call(xAxis);
const selection = svg.selectAll(".name").data(data);
const enter = selection.enter().append("g").attr("class","name");
const exit = selection.exit();
enter.append("rect").attr("x",d=>{return x(d.name);}).attr("y",y(0)).attr("width",x.bandwidth()).attr("height",0).attr("fill",d=>{return color(d.name);});
// here is the problem. I can't figure out why animation is not delayed per iteration.
enter.selectAll("rect")
.transition()
.delay((d,i)=>{
/*console.log(i);*/ // this prints 0 for all iterations. Why?
return 100*i;
})
.duration(1000)
.ease(d3.easeElastic)
.attr("y",d=>{return y(d.age);})
.attr("height",d=>{return y(0)-y(d.age);});
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.2.3/d3.min.js"></script>
答案 0 :(得分:2)
在您的代码中,enter
是一系列<g>
个元素,每个元素只有一个<rect>
。因此,请使用select
代替selectAll
:
enter.select("rect")
//etc...
以下是您修改后的代码:
//jshint esnext:true
const margin = {top: 30, bottom: 70, left: 40, right: 10};
const width = 600, height=200;
const color = d3.scaleOrdinal(d3.schemeCategory20);
const data = [{name:'ahmad',age:22},
{name:'saleh',age:15},
{name:'fulan',age:35},
{name:'fazil',age:48},
{name:'majid',age:50}
];
const svg = d3.select("body").append("svg")
.attr("width",width)
.attr("height",height)
.style("background-color","beige");
const max = d3.max(data,d=>{return d.age;});
const min = 0; //1 || d3.min(data,d=>{return d.age;});
const y = d3.scaleLinear().domain([min,max]).range([height-margin.bottom,margin.top]);
const yAxis = d3.axisLeft().scale(y);
const x = d3.scaleBand()
.domain(data.map(d=>{return d.name;}))
.range([margin.left,width-margin.right])
.padding(0.4);
const xAxis = d3.axisBottom().scale(x);
svg.append("g").attr("class","y axis").attr("transform","translate("+margin.left+",0)").call(yAxis);
svg.append("g").attr("class","x axis").attr("transform","translate(0,"+(height-margin.bottom)+")").call(xAxis);
const selection = svg.selectAll(".name").data(data);
const enter = selection.enter().append("g").attr("class","name");
const exit = selection.exit();
enter.append("rect").attr("x",d=>{return x(d.name);}).attr("y",y(0)).attr("width",x.bandwidth()).attr("height",0).attr("fill",d=>{return color(d.name);});
// here is the problem. I can't figure out why animation is not delayed per iteration.
enter.select("rect")
.transition()
.delay((d,i)=>{
/*console.log(i);*/ // this prints 0 for all iterations. Why?
return 100*i;
})
.duration(1000)
.ease(d3.easeElastic)
.attr("y",d=>{return y(d.age);})
.attr("height",d=>{return y(0)-y(d.age);});
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.2.3/d3.min.js"></script>
&#13;
只是为了让您了解select
和selectAll
之间的差异(下表中有更多内容),您可以使用selectAll
,但不能使用enter
选项。例如:
svg.selectAll("rect")
//etc...
这是:
const margin = {top: 30, bottom: 70, left: 40, right: 10};
const width = 600, height=200;
const color = d3.scaleOrdinal(d3.schemeCategory20);
const data = [{name:'ahmad',age:22},
{name:'saleh',age:15},
{name:'fulan',age:35},
{name:'fazil',age:48},
{name:'majid',age:50}
];
const svg = d3.select("body").append("svg")
.attr("width",width)
.attr("height",height)
.style("background-color","beige");
const max = d3.max(data,d=>{return d.age;});
const min = 0; //1 || d3.min(data,d=>{return d.age;});
const y = d3.scaleLinear().domain([min,max]).range([height-margin.bottom,margin.top]);
const yAxis = d3.axisLeft().scale(y);
const x = d3.scaleBand()
.domain(data.map(d=>{return d.name;}))
.range([margin.left,width-margin.right])
.padding(0.4);
const xAxis = d3.axisBottom().scale(x);
svg.append("g").attr("class","y axis").attr("transform","translate("+margin.left+",0)").call(yAxis);
svg.append("g").attr("class","x axis").attr("transform","translate(0,"+(height-margin.bottom)+")").call(xAxis);
const selection = svg.selectAll(".name").data(data);
const enter = selection.enter().append("g").attr("class","name");
const exit = selection.exit();
enter.append("rect").attr("x",d=>{return x(d.name);}).attr("y",y(0)).attr("width",x.bandwidth()).attr("height",0).attr("fill",d=>{return color(d.name);});
// here is the problem. I can't figure out why animation is not delayed per iteration.
svg.selectAll("rect")
.transition()
.delay((d,i)=>{
/*console.log(i);*/ // this prints 0 for all iterations. Why?
return 100*i;
})
.duration(1000)
.ease(d3.easeElastic)
.attr("y",d=>{return y(d.age);})
.attr("height",d=>{return y(0)-y(d.age);});
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.2.3/d3.min.js"></script>
&#13;
表格:select
与selectAll
之间的差异。
+--------------------+----------------------------------+----------------------------+
| Method | select() | selectAll() |
+--------------------+----------------------------------+----------------------------+
| Selection | selects the first element | selects all elements that |
| | that matches the selector string | match the selector string |
+--------------------+----------------------------------+----------------------------+
| Grouping | Does not affect grouping | Affects grouping |
+--------------------+----------------------------------+----------------------------+
| Data propagation | Propagates data | Doesn't propagate data |
+--------------------+----------------------------------+----------------------------+