d3 cliquez et faites glisser les cas de nidification
Je suis de nidification beaucoup d'éléments à l'intérieur d'un élément g de la sorte:
<g>
<rect></rect>
<text></text>
...
</g>
Cependant, il y a quelques rectangles que je veux être en mesure de faire glisser des événements de leur propre. Le problème est que quand vous mettez des choses à l'intérieur d'une balise g, sa taille s'élargit pour contenir ces balises. Donc, même si je peux attribuer des événements il n'y a aucun moyen qu'ils peuvent être déclenchés parce que la g de la balise d'événement est en quelque sorte plus important, même si le rectangle est sur le dessus de cela.
Est-il une sorte de solution de contournement que les gars, vous connaissez?
EDIT: Voici un simple dossier complet dans son intégralité. Un rectangle et un cercle à l'intérieur d'un g. Le g est déplaçable et le cercle doit être déplaçable aussi, mais ne l'est pas.
var gDragBehav = d3.behavior.drag()
.on('drag', gDragDrag)
function gDragDrag(d,i) {
d.x += d3.event.dx;
d.y += d3.event.dy;
d3.select(this)
.attr('x', d.x)
.attr('y', d.y)
.attr("transform", "translate(" + d.x + "," + d.y + ")");
}
var circleDragBehav = d3.behavior.drag()
.on('drag', circleDragDrag);
function circleDragDrag(d,i) {
console.log('dragging a circle')
d.cx += d3.event.dx;
d.cy += d3.event.dy;
d3.select(this)
.attr('cx', d.cx)
.attr('cy', d.cy)
}
var svg = d3.select('body').append('svg')
var g = svg.selectAll('g').data([{x: 10, y:10}])
.enter().append('g').call( gDragBehav )
g.append( 'rect' ).attr('width', 100 ).attr('height', 100 )
g.selectAll( 'circle' ).data([{cx: 0, cy:0}])
.enter().append( 'circle' )
.attr('cx', function(d) { return d.cx } ).attr('cy', function(d) { return d.cy } )
.attr('r', 40 )
.call( circleDragBehav )
EDIT: Voici une partie du code
var group = this.d3svg.selectAll('g' + '.' + this.className)
.attr('x', this.drawFuncs['x'] )
.attr('y', this.drawFuncs['y'] )
.attr("transform", this.drawFuncs['translate'] )
.attr('class', this.className )
.call(gDragBehav)
.on( 'click', blockClickMenu )
ports = ['AtomicPort']
for ( port in ports ) {
drawPort.call( this, group, ports[port] )
}
function drawPort( d3svg, portName, redraw ) {
d3svg.selectAll('rect.' + portName)
.data( function(d) { return d.ports[ portName ] } )
.enter().append('rect')
.attr('x', this.drawFuncs['x'] )
.attr('y', this.drawFuncs['y'] )
.attr('width', this.drawFuncs['width'] )
.attr('height', this.drawFuncs['height'] )
.attr('class', portName )
.call(portDragBehav)
var portDragBehav = d3.behavior.drag()
.on('drag', portDragDrag);
function portDragDrag(d,i) {
d.x += d3.event.dx;
d.y += d3.event.dy;
d3.select(this)
.attr('x', d.x)
.attr('y', d.y)
d3.event.stopPropagation();
}
var gDragBehav = d3.behavior.drag()
.on('dragstart', gDragStart)
function gDragDrag(d,i) {
d.x += d3.event.dx;
d.y += d3.event.dy;
d3.select(this)
.attr('x', d.x)
.attr('y', d.y)
.attr("transform", "translate(" + d.x + "," + d.y + ")");
d3.event.stopPropagation(); //Uncaught TypeError: Object #<Object> has no method 'stopPropagation'
}
Vous devez vous connecter pour publier un commentaire.
Un SVG
<g>
élément n'a pas de taille ou de la région; il est un récipient transparent pour l'ensemble de ses descendants, et ne peut pas intercepter les événements pour les autres éléments (sauf si vous ajoutez un écouteur d'événement pour être déclenchée lors de la "phase de capture').Comme un élément parent, les événements de la bulle jusqu'à elle; il est probable que ce que vous voyez est celui que vous utilisez pour déclencher le début de glissement (mousedown?) sur le
<rect>
est également de remonter dans le<g>
et de départ en même temps une traînée de que.Pour résoudre ce problème, vous voulez arrêter de votre événement à partir de bulles. Dans votre gestionnaire d'événement pour les événements mousedown (ou autre) sur le
<rect>
ajouter:Sans votre code (ou mieux, un nouveau cas de test), il est difficile de le savoir, ou vous aider davantage.
Modifier Voici une version de travail de votre exemple simple: http://jsfiddle.net/ZrCQE/2/
Plus précisément, apparemment
d3.event
n'est pas l'événement lui-même, mais un objet avec unsourceEvent
propriété qui fait référence à l'événement.<g>
et<rect>
.J'en ai un similaire sorte de question (http://jsfiddle.net/j8RZN/1/), à l'exception de la solution de contournement proposée ne semble pas être l'aider.