estoy anidación una gran cantidad de elementos en el interior de un elemento g de este modo:d3 clic y evento de arrastre anidación
<g>
<rect></rect>
<text></text>
...
</g>
Sin embargo, hay algunas rectas que quiero ser capaz de tener eventos de arrastre de su propia cuenta. El problema es que cuando colocas cosas dentro de una etiqueta g, su tamaño se expande para contener esas etiquetas. Así que, aunque puedo asignar eventos, no hay forma de que puedan activarse porque el evento de la etiqueta g es de alguna manera más importante, aunque el rect esté encima de él.
¿Hay algún tipo de solución que ustedes conozcan?
EDITAR: Aquí está a simple complete case en su totalidad. Un rect y un círculo dentro de un g. El g es arrastrable y el círculo debería ser también arrastrable pero no lo es.
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: He aquí algunos de los códigos
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'
}
Estoy adjuntando el comportamiento de arrastre al elemento g en sí, de modo que todo en el cuerpo del g se moverá. El problema es que los elementos dentro de la etiqueta g no se llamaban en absoluto. No estoy seguro de cuál es el problema, pero no tengo un control sobre el evento. ¿Cómo puedo llamar a StopPropagation? – ballaw
@ballaw Esa es una buena (pero esperada) información. No cambia mi respuesta. – Phrogz
OK, pero no tengo un control sobre el evento. ¿Cómo puedo llamar a StopPropagation? – ballaw