让鼠标事件在 d3.js 中始终如一地工作
getting mouse event to work consistently in d3.js
我正在开发一个简单的程序,当单击“工厂”图标时创建圆形节点,然后在单击时删除节点。我的问题是为什么当我 运行 页面加载后的脚本时 d3 selectAll 语句(在 createNode 函数之上)不起作用,尽管当我将相同的语句剪切并粘贴到浏览器控制台。我怀疑这是因为我没有正确链接方法调用,但希望得到一些建议。谢谢。
var w=5000,h=400,ctr=0; //define bounds of svg
var ND=[]; //holder of all node data
var svg = d3.select('body').append('svg') //base svg element
.attr('width',w)
.attr('height',h);
function random(p,q) { return p+Math.floor(Math.random()*(q-p)); }
var factory=svg.append('circle') //draw the factory widget
.attr('class','perms') //one of the perm objects
.attr('cx',50)
.attr('cy',50)
.attr('r',30)
.attr('stroke','black')
.attr('fill','teal');
factory.on('click',createNode); //create a new node when factory is clicked
d3.selectAll('.nodes').on('click',function(e,d){ var did=this.id; console.log(did);
d3.select(this).transition().delay(1000).style('fill','orange').remove();});
function createNode(x,y) //create a new node and render on screen
{ var r=30; var lx=random(100+r,w-r); var ly=random(0+r,h-r);
var rx=svg.append('circle').attr('class','nodes').attr('id',ctr)
.attr('cx',lx).attr('cy',ly).attr('r',r)
.attr('stroke','red').attr('fill','yellow');
var rn={id:ctr++, x:lx, y:ly, r:30, clr:'yellow',lnk:[],ptr:0};
ND.push(rn);
return rn;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/7.0.0/d3.min.js"></script>
我也尝试了下面的方法,但同样,它只执行 createNode 分支。另一个分支只有在我将完整的函数体粘贴到控制台时才有效。我有一种预感,这可能是因为我没有正确使用输入、更新和退出,但对 d3 的了解还不足以修复它。已经阅读了一些教程和 SO 示例,但仍然卡住了。感谢您的帮助。
d3.selectAll('circle').on('click',function(d)
{ k=d3.select(this); console.log(k.classed('perms')); console.log(k.attr('class'));
if (k.classed('perms')) { createNode();}
if (k.classed('nodes')) { did=this.id; console.log(did);
for(var i=0;i<ND.length;i++){if (ND[i].id==did){ND.splice(i--,1);}}
d3.select(this).transition().delay(1000).style('fill','orange').remove();
}});
My question is why the d3 selectAll statement (above the createNode function) does not work when I run the script after page load, though it all runs fine when I cut and paste that same statement into the browser console.
目前您附加了一个工厂节点,该节点在单击时创建新节点。
然后你 select 所有 现有 圈子 class 节点。此时有none.
然后你可以点击工厂节点,新建一个,但是你不要重新运行 select所有语句。 select所有圈子的离子没有更新,因为之后创建了一个新圈子。
你可以做的是 运行 添加一个节点后再次 selectAll 语句,但是你一次只添加一个节点,而且你已经有一个 select createNode
函数中该节点的离子。所以你可以在这里添加事件监听器:
function createNode(x,y) {
var r=30; var lx=random(100+r,w-r); var ly=random(0+r,h-r);
var rx=svg.append('circle')
.attr('class','nodes')
...
.on(...
...
}
var w=500,h=400,ctr=0; //define bounds of svg
var ND=[]; //holder of all node data
var svg = d3.select('body').append('svg') //base svg element
.attr('width',w)
.attr('height',h);
function random(p,q) { return p+Math.floor(Math.random()*(q-p)); }
var factory=svg.append('circle') //draw the factory widget
.attr('class','perms') //one of the perm objects
.attr('cx',50)
.attr('cy',50)
.attr('r',30)
.attr('stroke','black')
.attr('fill','teal');
factory.on('click',createNode); //create a new node when factory is clicked
function createNode(x,y) //create a new node and render on screen
{ var r=30; var lx=random(100+r,w-r); var ly=random(0+r,h-r);
var rx=svg.append('circle').attr('class','nodes').attr('id',ctr)
.attr('cx',lx).attr('cy',ly).attr('r',r)
.attr('stroke','red').attr('fill','yellow')
.on('click',function(e,d){ var did=this.id; console.log(did);
d3.select(this).transition().delay(1000).style('fill','orange').remove();});
var rn={id:ctr++, x:lx, y:ly, r:30, clr:'yellow',lnk:[],ptr:0};
ND.push(rn);
return rn;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/7.0.0/d3.min.js"></script>
添加圆圈后,select所有代码都在控制台中运行,因为现在有圆圈指向 select - 否则你有一个空的 selection。检查您是否确实 select 任何东西的一种方法是使用 selection.size()
到 return 有多少元素被 select 编辑。
我正在开发一个简单的程序,当单击“工厂”图标时创建圆形节点,然后在单击时删除节点。我的问题是为什么当我 运行 页面加载后的脚本时 d3 selectAll 语句(在 createNode 函数之上)不起作用,尽管当我将相同的语句剪切并粘贴到浏览器控制台。我怀疑这是因为我没有正确链接方法调用,但希望得到一些建议。谢谢。
var w=5000,h=400,ctr=0; //define bounds of svg
var ND=[]; //holder of all node data
var svg = d3.select('body').append('svg') //base svg element
.attr('width',w)
.attr('height',h);
function random(p,q) { return p+Math.floor(Math.random()*(q-p)); }
var factory=svg.append('circle') //draw the factory widget
.attr('class','perms') //one of the perm objects
.attr('cx',50)
.attr('cy',50)
.attr('r',30)
.attr('stroke','black')
.attr('fill','teal');
factory.on('click',createNode); //create a new node when factory is clicked
d3.selectAll('.nodes').on('click',function(e,d){ var did=this.id; console.log(did);
d3.select(this).transition().delay(1000).style('fill','orange').remove();});
function createNode(x,y) //create a new node and render on screen
{ var r=30; var lx=random(100+r,w-r); var ly=random(0+r,h-r);
var rx=svg.append('circle').attr('class','nodes').attr('id',ctr)
.attr('cx',lx).attr('cy',ly).attr('r',r)
.attr('stroke','red').attr('fill','yellow');
var rn={id:ctr++, x:lx, y:ly, r:30, clr:'yellow',lnk:[],ptr:0};
ND.push(rn);
return rn;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/7.0.0/d3.min.js"></script>
我也尝试了下面的方法,但同样,它只执行 createNode 分支。另一个分支只有在我将完整的函数体粘贴到控制台时才有效。我有一种预感,这可能是因为我没有正确使用输入、更新和退出,但对 d3 的了解还不足以修复它。已经阅读了一些教程和 SO 示例,但仍然卡住了。感谢您的帮助。
d3.selectAll('circle').on('click',function(d)
{ k=d3.select(this); console.log(k.classed('perms')); console.log(k.attr('class'));
if (k.classed('perms')) { createNode();}
if (k.classed('nodes')) { did=this.id; console.log(did);
for(var i=0;i<ND.length;i++){if (ND[i].id==did){ND.splice(i--,1);}}
d3.select(this).transition().delay(1000).style('fill','orange').remove();
}});
My question is why the d3 selectAll statement (above the createNode function) does not work when I run the script after page load, though it all runs fine when I cut and paste that same statement into the browser console.
目前您附加了一个工厂节点,该节点在单击时创建新节点。
然后你 select 所有 现有 圈子 class 节点。此时有none.
然后你可以点击工厂节点,新建一个,但是你不要重新运行 select所有语句。 select所有圈子的离子没有更新,因为之后创建了一个新圈子。
你可以做的是 运行 添加一个节点后再次 selectAll 语句,但是你一次只添加一个节点,而且你已经有一个 select createNode
函数中该节点的离子。所以你可以在这里添加事件监听器:
function createNode(x,y) {
var r=30; var lx=random(100+r,w-r); var ly=random(0+r,h-r);
var rx=svg.append('circle')
.attr('class','nodes')
...
.on(...
...
}
var w=500,h=400,ctr=0; //define bounds of svg
var ND=[]; //holder of all node data
var svg = d3.select('body').append('svg') //base svg element
.attr('width',w)
.attr('height',h);
function random(p,q) { return p+Math.floor(Math.random()*(q-p)); }
var factory=svg.append('circle') //draw the factory widget
.attr('class','perms') //one of the perm objects
.attr('cx',50)
.attr('cy',50)
.attr('r',30)
.attr('stroke','black')
.attr('fill','teal');
factory.on('click',createNode); //create a new node when factory is clicked
function createNode(x,y) //create a new node and render on screen
{ var r=30; var lx=random(100+r,w-r); var ly=random(0+r,h-r);
var rx=svg.append('circle').attr('class','nodes').attr('id',ctr)
.attr('cx',lx).attr('cy',ly).attr('r',r)
.attr('stroke','red').attr('fill','yellow')
.on('click',function(e,d){ var did=this.id; console.log(did);
d3.select(this).transition().delay(1000).style('fill','orange').remove();});
var rn={id:ctr++, x:lx, y:ly, r:30, clr:'yellow',lnk:[],ptr:0};
ND.push(rn);
return rn;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/7.0.0/d3.min.js"></script>
添加圆圈后,select所有代码都在控制台中运行,因为现在有圆圈指向 select - 否则你有一个空的 selection。检查您是否确实 select 任何东西的一种方法是使用 selection.size()
到 return 有多少元素被 select 编辑。