为什么 d3.js 可重复图表上的点击事件会导致创建问题?
2018-12-28
37
我使用了 Mike Bostock 描述的可重复使用图表模式。我面临一个问题。
饼图功能
:-
1. 当我单击饼图的选项卡时,它应该旋转并将我单击的颜色放在顶部。
问题
:-
1. 当我单击第一个图表时。该功能已实现,但它是在第二个图表上实现的。
我认为问题与全局声明有关。但我没有全局声明任何东西。
请有人帮助我完成这个非常基本的任务。
这是我的 js fiddle 链接,您可以在其中检查此异常。 https://jsfiddle.net/a0u2nk47/
<html>
<head>
<script type="text/javascript" src="d3.v4.min.js"></script>
<script type="text/javascript" src="d3-path.v1.min.js"></script>
<script type="text/javascript" src="d3-shape.v1.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<style>
body{
height: 100%;
width: 100%;
/*background-image: url("Computer.png");*/
}
p{
float:left;
}
</style>
</head>
<!-- <img src=Computer.png width="70%" height="100%"> -->
<p id="chart1"></p>
<p id="chart2"></p>
<body >
<script>
function piechart(){
var width = 400;
var height = 400;
var colors = ['red','green','blue']
var innerRadius = 40;
var outerRadius = 60;
var index = 0;
var pie = d3.pie()
.sort(null);
var arc = d3.arc().innerRadius(innerRadius).outerRadius(outerRadius).cornerRadius(5).padAngle(0.05);
function chart(selection){
selection.each(function() {
svg = d3.select(this)
.append('svg')
.attr('width',width)
.attr('height',height)
.append('g')
.attr('transform','translate('+width/2+','+height/2+')')
path = svg.selectAll("path")
.data(pie(data))
.enter()
.append('path')
.attr('d',function(d){return arc(d)})
.style('fill',function(d,i){return colors[i]})
.style('stroke','black')
.each(function(d) { this._current = d; });
updateData = function(){
path.data(pie(data))
path.transition().duration(2000).attrTween("d", arcTween);
}
updateWidth = function(){
innerRadius = width*0.6
outerRadius = width*0.8
arc.innerRadius(innerRadius).outerRadius(outerRadius);
path.transition().duration(1000).attr('d',function(d){return arc(d)});
}
path.on("click",chart.click);
})
}
function arcTween(a) {
var i = d3.interpolate(this._current, a);
this._current = i(0);
return function(t) {
return arc(i(t));
};
}
chart.data = function(value){
if(!arguments.length) return data;
data = value;
if(typeof updateData === 'function') updateData();
return chart;
}
chart.width = function(value){
if(!arguments.length) return width;
width = value;
if(typeof updateWidth === 'function') updateWidth();
return chart;
}
chart.click = function(value){
debugger;
index = this.__data__.index
console.log(index)
var rotate = 0-(value.startAngle + value.endAngle)/2 / Math.PI * 180;
// Transition the pie chart
svg.transition()
.attr("transform", "translate("+width/2+","+height/2+") rotate(" + rotate + ")")
.duration(1000);
}
return chart
}
data = [1,5,8];
var piechart1 = piechart().data(data);
d3.select('#chart1').call(piechart1);
var piechart2 = piechart().data(data);
d3.select('#chart2').call(piechart2);
</script>
</body>
1个回答
当您转换/变换
<g>
元素(该元素是您单击的
path
的父元素)时,您只需使用
this.parentNode
来转换它即可。
例如,在
click
处理程序中,更改以下内容:
svg.transition().attr('....
至
d3.select(this.parentNode).transition().attr('...
虽然我建议您为每个图表分配一个 ID,以便在可重复使用的图表逻辑的情况下将它们分开,并将这个新创建的 ID 用于所有其他功能,而不是依赖于全局变量。例如:
var piechart1 = piechart(1).data(data); // pass an ID here
并按以下方式分配它:
svg.append('g').attr('id', 'container_' + id) // assign the ID
这是一个带有小提琴分叉的代码片段:
function piechart(id){
var width = 300;
var height = 300;
var colors = ['red','green','blue']
var innerRadius = 40;
var outerRadius = 60;
var index = 0;
var pie = d3.pie()
.sort(null);
var arc = d3.arc().innerRadius(innerRadius).outerRadius(outerRadius).cornerRadius(5).padAngle(0.05);
function chart(selection){
selection.each(function() {
svg = d3.select(this)
.append('svg')
.attr('width',width)
.attr('height',height)
.append('g').attr('id', 'container_' + id)
.attr('transform','translate('+width/2+','+height/2+')')
path = svg.selectAll("path")
.data(pie(data))
.enter()
.append('path')
.attr('d',function(d){return arc(d)})
.style('fill',function(d,i){return colors[i]})
.style('stroke','black')
.each(function(d) { this._current = d; });
path.on("click",chart.click);
})
}
chart.data = function(value){
if(!arguments.length) return data;
data = value;
if(typeof updateData === 'function') updateData();
return chart;
}
chart.click = function(value){
index = this.__data__.index
var rotate = 0-(value.startAngle + value.endAngle)/2 / Math.PI * 180;
// Transition the pie chart
d3.select(this.parentNode).transition()
.attr("transform", "translate("+width/2+","+height/2+") rotate(" + rotate + ")")
.duration(1000);
}
return chart
}
data = [1,5,8];
var piechart1 = piechart(1).data(data);
d3.select('#chart1').call(piechart1);
var piechart2 = piechart(2).data(data);
d3.select('#chart2').call(piechart2);
<html>
<head>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script src="https://d3js.org/d3-path.v1.min.js"></script>
<script src="https://d3js.org/d3-shape.v1.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<style>
body{
height: 100%;
width: 100%;
/*background-image: url("Computer.png");*/
}
p{
float:left;
}
</style>
</head>
<!-- <img src=Computer.png width="70%" height="100%"> -->
<p id="chart1"></p>
<p id="chart2"></p>
<body >
</body>
</html>
https://jsfiddle.net/rL96uv4g/
希望这对您有所帮助。
Shashank
2018-12-28