gpt4 book ai didi

javascript - d3js 转换嵌套组图像

转载 作者:数据小太阳 更新时间:2023-10-29 03:56:26 26 4
gpt4 key购买 nike

我正在研究 [this][1] d3 项目。基本上我正在尝试创建一个类似 SQL 的查询生成器。我可以将框放到绘图区和框内的其他操作符。然后我应该能够将它们全部连接起来。我正在尝试翻译嵌套在组中的 2 个图像。我想把大箱子里的小东西搬走。我可以分别改造大盒子和小算子。当我尝试首先移动小型运算符(operator)时出现问题。我想移动小运算符(operator),然后是大箱子。同时我想保持小运营商和大盒子的相对位置不变。但是,当我在移动其中一个小盒子后尝试移动大盒子时,它会重置其位置。这是我在 jsfiddle 中的工作演示

<g id="draw">

<rect class="container" height="400" width="400" x="0" y="0" style="fill:gray"></rect>

<g class="qbox" id="qbox">

<line id="dummyLine" x1="0" x2="0" y1="0" y2="0" visibility="hidden"
style='stroke:red; stroke-width:4px'></line>

<image x="10" y="10" class="container" initial-x="10" initial-y="10" xlink:href="http://i60.tinypic.com/20ic9e.png"
width="110"
height="110"></image>
<circle class="left" id="qbox-left" initial-cx="10" initial-cy="65" cx="10" cy="65" r="5"
style="fill:red"></circle>
<circle class="right" id="qbox-right" initial-cx="120" initial-cy="65" cx="120" cy="65" r="5"
style="fill:red"></circle>

<g id="op1" class="op">
<image class="opim" x="10" y="10" class="container" initial-x="10" initial-y="10"
xlink:href="http://i58.tinypic.com/imlzs9.png" width="50"
height="50"></image>
<circle id="op1-left" class="left" initial-cx="10" initial-cy="35" cx="10" cy="35" r="5"
style="fill:red"></circle>
<circle id="op1-right" class="right" initial-cx="60" initial-cy="35" cx="60" cy="35" r="5"
style="fill:red"></circle>
</g>

<g id="op2" class="op">
<image class="opim" x="60" y="60" initial-x="60" initial-y="60"
xlink:href="http://i58.tinypic.com/imlzs9.png" width="50"
height="50"></image>
<circle id="op2-left" class="left" initial-cx="60" initial-cy="85" cx="60" cy="85" r="5"
style="fill:red"></circle>
<circle id="op2-right" class="right" initial-cx="110" initial-cy="85" cx="110" cy="85" r="5"
style="fill:red"></circle>
</g>

</g>

<g class="qbox" id="qbox2" >

<line id="dummyLine" x1="0" x2="0" y1="0" y2="0" visibility="hidden"
style='stroke:red; stroke-width:4px'></line>

<image x="110" y="110" class="container" initial-x="110" initial-y="110" xlink:href="http://i60.tinypic.com/20ic9e.png"
width="110"
height="110"></image>
<circle class="left" id="qbox-left" initial-cx="110" initial-cy="165" cx="110" cy="165" r="5"
style="fill:red"></circle>
<circle class="right" id="qbox-right" initial-cx="220" initial-cy="265" cx="220" cy="165" r="5"
style="fill:red"></circle>

<g id="op3" class="op">
<image class="opim" x="110" y="110" class="container" initial-x="110" initial-y="110"
xlink:href="http://i58.tinypic.com/imlzs9.png" width="50"
height="50"></image>
<circle id="op1-left" class="left" initial-cx="110" initial-cy="135" cx="110" cy="135" r="5"
style="fill:red"></circle>
<circle id="op1-right" class="right" initial-cx="160" initial-cy="135" cx="160" cy="135" r="5"
style="fill:red"></circle>
</g>
<g id="op4" class="op">
<image class="opim" x="160" y="160" initial-x="160" initial-y="160"
xlink:href="http://i58.tinypic.com/imlzs9.png" width="50"
height="50"></image>
<circle id="op2-left" class="left" initial-cx="160" initial-cy="185" cx="160" cy="185" r="5"
style="fill:red"></circle>
<circle id="op2-right" class="right" initial-cx="210" initial-cy="185" cx="210" cy="185" r="5"
style="fill:red"></circle>
</g>



</g>


</g>

    var qBox = d3.selectAll('.qbox')
.on('dblclick', function () {
var g = d3.select(this);
var scale = 'scale(1.2,1.2)';
g.attr('transform', g.attr('transform') + ' ' + scale);
});
var opBox = d3.selectAll('.op');
var circles = d3.selectAll('circle');


var cDrag = d3.behavior.drag()

.on('dragstart', function () {
d3.event.sourceEvent.stopPropagation();
})
.on('drag', function () {

var dummyLine = d3.select('#dummyLine');
var me = d3.select(this);

var transForm = me.node().getCTM();
var t2 = me.select(function () {
return this.parentNode;
}).select(function () {
return this.parentNode;
}).select('circle').node().getCTM();

var tC = d3.transform(d3.select(this).attr('transform')).translate;
var tP = d3.transform(d3.select(this).select(function () {
return this.parentNode;
}).attr('transform')).translate;

console.log(transForm);

var meX = t2['e'];
var meY = t2['f'];


dummyLine
.style('visibility', 'visible')
.attr('tx1', Number(me.attr('cx')))
.attr('x1', Number(me.attr('cx')) + (Number(transForm['e'] - Number(meX))))
.attr('ty1', Number(me.attr('cy')))
.attr('y1', Number(me.attr('cy')) + (Number(transForm['f'] - Number(meY))))
.attr('x2', Number(d3.event.x) )
.attr('tx2', Number(d3.event.x) + Number(tP[0]) - Number(tC[0]))
.attr('y2', Number(d3.event.y) )
.attr('ty2', Number(d3.event.y) + Number(tP[1]) - Number(tC[0]))
.attr('start', me.attr('id'))

;

})
.on('dragend', function () {

var g = d3.select(this).select(function () {
return this.parentNode;
}).select(function () {
return this.parentNode;
});


var dummyLine = d3.select('#dummyLine');

dummyLine.style('visibility', 'hidden');

d3.select('.qbox')
.append('line')
.attr('id', function () {
return dummyLine.attr('start') + '__' + circleID;
})

.attr('x1', dummyLine.attr('x1'))
.attr('ix1', dummyLine.attr('tx1'))
.attr('x2', dummyLine.attr('x2'))
.attr('ix2', d3.select('#' + circleID).attr('cx'))
.attr('y1', dummyLine.attr('y1'))
.attr('iy1', dummyLine.attr('ty1'))
.attr('y2', dummyLine.attr('y2'))
.attr('iy2', d3.select('#' + circleID).attr('cy'))
.attr('start', dummyLine.attr('start'))
.attr('end', circleID)
.style('stroke', 'green')
.style('stroke-width', '2px')

;
})
;

var svg = d3.select('svg').node();

var drag = d3.behavior.drag()
.origin(function () {
var t = d3.transform(d3.select(this).attr("transform")).translate;
return {x: t[0], y: t[1]};
}).on('dragstart', function () {
d3.event.sourceEvent.stopPropagation();
}).on('drag', function () {

var g = d3.select(this);

var mouse = {dx: d3.event.x, dy: d3.event.y};
var currentObj = {
x: g.select('image').attr('x'),
y: g.select('image').attr('y'),
width: g.select('image').attr('width'),
height: g.select('image').attr('height')
};
var parentObj = {
x: (Number(g.select(function () {
return this.parentNode;
}).select('.container').attr('x'))), // + Number(d3.transform(parent.attr('transform')).translate[0])),
y: (Number(g.select(function () {
return this.parentNode;
}).select('.container').attr('y'))), // + Number(d3.transform(parent.attr('transform')).translate[1])),
width: g.select(function () {
return this.parentNode;
}).select('.container').attr('width'),
height: g.select(function () {
return this.parentNode;
}).select('.container').attr('height')
};


var loc = getXY(mouse, currentObj, parentObj);
d3.select(this).attr('transform', 'translate(' + loc.x + ',' + loc.y + ')');
// d3.select(this).attr('transform', 'translate(' + d3.event.x + ',' + d3.event.y + ')');

var groupId = d3.select(this).attr('id');
var groupClass = d3.select(this).attr('class');

d3.selectAll('line')[0].forEach(function (e1) {

var line = d3.select(e1);
// console.log('groupId: ', groupId);


if (line.attr('id') != 'dummyLine' && groupClass != 'qbox') {

// console.log('--------------');
// console.log('lineId: ', line.attr('id'));

var lineStart = line.attr('start').split('-')[0];
var lineEnd = line.attr('end').split('-')[0];
// console.log('lineStatr : ', lineStart);
// console.log('lineEnd : ', lineEnd);

var t = d3.transform(d3.select('#' + groupId).attr('transform')).translate;
var t2 = d3.transform(d3.select('#' + groupId).select(function () {
return this.parentNode;
}).attr('transform')).translate;

console.log('groupID ', groupId);

if (lineStart == groupId) {
var t = d3.transform(d3.select('#' + lineStart).attr('transform')).translate;

line.attr('x1', Number(line.attr('ix1')) + (Number(t[0])));
line.attr('y1', Number(line.attr('iy1')) + Number(t[1]));
// line.attr('x1', Number(line.attr('ix1')) - (-Number(t[0])+Number(t2[0])));
// line.attr('y1', Number(line.attr('iy1')) - (-Number(t[1]+Number(t2[1]))));

}

if (lineEnd == groupId) {
var t = d3.transform(d3.select('#' + lineEnd).attr('transform')).translate;

line.attr('x2', Number(line.attr('ix2')) + Number(t[0]));
line.attr('y2', Number(line.attr('iy2')) + Number(t[1]));
// line.attr('x2', Number(line.attr('ix2')) - Number(t[0]));
// line.attr('y2', Number(line.attr('iy2')) - Number(t[1]));
// line.attr('x2', Number(line.attr('ix2')) - (Number(t[0]+Number(t2[0]))));
// line.attr('y2', Number(line.attr('iy2')) - (Number(t[1]+Number(t2[1]))));

}

}


});


})

;

opBox.call(drag);
qBox.call(drag);
circles.call(cDrag);

var circleID;

circles.on('mouseover', function () {
circleID = d3.select(this).attr('id');
}).on('mouseout', function () {
circleID = null;
})

PS:我通过拖动圆圈并放入另一个圆圈来连接两个元素。

谁能指出我的错误?

最佳答案

经过各种麻烦,我找到了答案。实际上,这全都与坐标系以及放置东西的位置以及如何组织它有关。一旦我弄明白了,答案就很明显了。

<svg width="500" height="500" style="background-color: blue">


<g id="draw">

<rect class="container" height="500" width="500" x="0" y="0" style="fill:yellow"></rect>

<line class="dummyLineOutsideQbox"></line>

<g class="qbox" id="qbox">

<line class="dummyLineInsideQbox"></line>


<image x="10" y="10" class="container" initial-x="10" initial-y="10" xlink:href="images/query.png"
width="110"
height="110"></image>
<circle class="left" id="qbox-left" initial-cx="10" initial-cy="65" cx="10" cy="65" r="5"
style="fill:red"></circle>
<circle class="right" id="qbox-right" initial-cx="120" initial-cy="65" cx="120" cy="65" r="5"
style="fill:red"></circle>

<g id="op1" class="op">
<image class="opim" x="10" y="10" class="container" initial-x="10" initial-y="10"
xlink:href="images/filter.png" width="50"
height="50"></image>
<circle id="op1-left" class="left" initial-cx="10" initial-cy="35" cx="10" cy="35" r="5"
style="fill:red"></circle>
<circle id="op1-right" class="right" initial-cx="60" initial-cy="35" cx="60" cy="35" r="5"
style="fill:red"></circle>
</g>

<g id="op2" class="op">
<image class="opim" x="60" y="60" initial-x="60" initial-y="60"
xlink:href="images/filter.png" width="50"
height="50"></image>
<circle id="op2-left" class="left" initial-cx="60" initial-cy="85" cx="60" cy="85" r="5"
style="fill:red"></circle>
<circle id="op2-right" class="right" initial-cx="110" initial-cy="85" cx="110" cy="85" r="5"
style="fill:red"></circle>
</g>

</g>

<g class="qbox" id="qbox2">

<line class="dummyLineInsideQbox"></line>

<image x="110" y="110" class="container" initial-x="110" initial-y="110" xlink:href="images/query.png"
width="110"
height="110"></image>
<circle class="left" id="qbox2-left" initial-cx="110" initial-cy="165" cx="110" cy="165" r="5"
style="fill:red"></circle>
<circle class="right" id="qbox2-right" initial-cx="220" initial-cy="265" cx="220" cy="165" r="5"
style="fill:red"></circle>

<g id="op3" class="op">
<image class="opim" x="110" y="110" class="container" initial-x="110" initial-y="110"
xlink:href="images/filter.png" width="50"
height="50"></image>
<circle id="op3-left" class="left" initial-cx="110" initial-cy="135" cx="110" cy="135" r="5"
style="fill:red"></circle>
<circle id="op3-right" class="right" initial-cx="160" initial-cy="135" cx="160" cy="135" r="5"
style="fill:red"></circle>
</g>
<g id="op4" class="op">
<image class="opim" x="160" y="160" initial-x="160" initial-y="160"
xlink:href="images/filter.png" width="50"
height="50"></image>
<circle id="op4-left" class="left" initial-cx="160" initial-cy="185" cx="160" cy="185" r="5"
style="fill:red"></circle>
<circle id="op4-right" class="right" initial-cx="210" initial-cy="185" cx="210" cy="185" r="5"
style="fill:red"></circle>
</g>


</g>


</g>

</svg>

<script>
var qBox = d3.selectAll('.qbox')
.on('dblclick', function () {
var g = d3.select(this);
var scale = 'scale(1.2,1.2)';
g.attr('transform', g.attr('transform') + ' ' + scale);
});
var opBox = d3.selectAll('.op');
var circles = d3.selectAll('circle');


var cDrag = d3.behavior.drag()

.on('dragstart', function () {
d3.event.sourceEvent.stopPropagation();
})
.on('drag', function () {

var thisCircle = d3.select(this);
var thisGroup = thisCircle.select(function () {
return this.parentNode;
});
var thisGroupTransform = d3.transform(thisGroup.attr('transform')).translate;

var thisGroupParent = d3.select(this).select(function () {
return this.parentNode;
}).select(function () {
return this.parentNode;
});

var thisGroupParentId = thisGroupParent.attr('id');
var thisGroupParentClass = thisGroupParent.attr('class');


if (thisGroupParentClass == 'qbox') {
dummyLine = d3.select('#' + thisGroupParentId).select('.dummyLineInsideQbox');
}
else {
dummyLine = d3.select('#' + thisGroupParentId).select('.dummyLineOutsideQbox');

}

console.log('dummyLine ', dummyLine.attr('class'));


dummyLine
.style('visibility', 'visible')
.style('stroke', 'red')
.style('stroke-width', '3px')
.attr('x1', Number(thisCircle.attr('cx')) + thisGroupTransform[0])
.attr('real-x1', thisCircle.attr('cx'))
.attr('y1', Number(thisCircle.attr('cy')) + thisGroupTransform[1])
.attr('real-y1', thisCircle.attr('cy'))
.attr('x2', d3.mouse(this)[0] + thisGroupTransform[0])
.attr('y2', d3.mouse(this)[1] + thisGroupTransform[1])
.attr('startGroup', thisGroup.attr('id'))
.attr('startCircleClass', thisCircle.attr('class'))
;


})
.on('dragend', function () {


var thisCircle = d3.select('#' + circleID);
var thisCircleClass = thisCircle.attr('class');
var thisGroup = thisCircle.select(function () {
return this.parentNode;
});

var thisGroupTransform = d3.transform(thisGroup.attr('transform')).translate;

var thisGroupParent = d3.select(this).select(function () {
return this.parentNode;
}).select(function () {
return this.parentNode;
});

var thisGroupParentId = thisGroupParent.attr('id');
var thisGroupParentClass = thisGroupParent.attr('class');


var sourceCircleClass = dummyLine.attr('startCircleClass');
var sourceGroup = d3.select('#' + dummyLine.attr('startGroup'));

console.log('SOURCE GROUP :', sourceGroup.attr('id'));

var targetLineGroup;
var lineClass;

var t = [0, 0];
var x1, x2, y1, y2;

if (( sourceGroup.attr('class') == 'op') || (thisGroup.attr('class') == 'op')) {

if (sourceGroup.attr('class') == 'op') {
targetLineGroup = sourceGroup.select(function () {
return this.parentNode;
});
// console.log('I am on line 185');
} else {
targetLineGroup = thisGroup.select(function () {
return this.parentNode;
});
// console.log('I am on line 190');

}
lineClass = 'in';
x1 = startCircle.attr('cx');
y1 = startCircle.attr('cy');
x2 = thisCircle.attr('cx');
y2 = thisCircle.attr('cy');

}

if ((sourceGroup.attr('class') == 'qbox') && (thisGroup.attr('class') == 'qbox')) {

targetLineGroup = sourceGroup.select(function () {
return this.parentNode;
});
lineClass = 'out';

x1 = dummyLine.attr('x1');
x2 = dummyLine.attr('x2');
y1 = dummyLine.attr('y1');
y2 = dummyLine.attr('y2');
}

targetLineGroup
.append('line')
.attr('class', lineClass)
.attr('id', function () {
return sourceCircleClass + '--' + sourceGroup.attr('id') + '__' + thisCircleClass + '--' + thisGroup.attr('id');
})
.attr('x1', dummyLine.attr('x1'))
.attr('real-x1', dummyLine.attr('x1'))
.attr('y1', dummyLine.attr('y1'))
.attr('real-y1', dummyLine.attr('y1'))
.attr('x2', dummyLine.attr('x2'))
.attr('real-x2', dummyLine.attr('x2'))
.attr('y2', dummyLine.attr('y2'))
.attr('real-y2', dummyLine.attr('y2'))
.attr('startGroup', dummyLine.attr('startGroup'))
.attr('endGroup', thisGroup.attr('id'))
.style('stroke', 'green')
.style('stroke-width', '3px')

;
dummyLine.style('visibility', 'hidden');


console.log('DRAWING LINE ON : ', targetLineGroup.attr('id'))

})
;

var svg = d3.select('svg').node();

var drag = d3.behavior.drag()
.origin(function () {
var t = d3.transform(d3.select(this).attr("transform")).translate;
return {x: t[0], y: t[1]};
}).on('dragstart', function () {
d3.event.sourceEvent.stopPropagation();
}).on('drag', function () {

var g = d3.select(this);

var mouse = {dx: d3.event.x, dy: d3.event.y};
var currentObj = {
x: g.select('image').attr('x'),
y: g.select('image').attr('y'),
width: g.select('image').attr('width'),
height: g.select('image').attr('height')
};
var parentObj = {
x: (Number(g.select(function () {
return this.parentNode;
}).select('.container').attr('x'))), // + Number(d3.transform(parent.attr('transform')).translate[0])),
y: (Number(g.select(function () {
return this.parentNode;
}).select('.container').attr('y'))), // + Number(d3.transform(parent.attr('transform')).translate[1])),
width: g.select(function () {
return this.parentNode;
}).select('.container').attr('width'),
height: g.select(function () {
return this.parentNode;
}).select('.container').attr('height')
};


var loc = getXY(mouse, currentObj, parentObj);
d3.select(this).attr('transform', 'translate(' + loc.x + ',' + loc.y + ')');
// d3.select(this).attr('transform', 'translate(' + d3.event.x + ',' + d3.event.y + ')');

var thisGroupId = d3.select(this).attr('id');
var groupClass = d3.select(this).attr('class');

var thisGroupClass = d3.select(this).attr('class');
var tLineClass;
if (thisGroupClass == 'qbox') {
tLineClass = 'out'
} else {
tLineClass = 'in'
}

d3.selectAll('line.' + tLineClass)[0].forEach(function (e1) {

var line = d3.select(e1);

var lineId = line.attr('id');




var lineStartGroup = lineId.split('__')[0].split('--')[1];
var lineStartSide = lineId.split('__')[0].split('--')[0];
var lineEndGroup = lineId.split('__')[1].split('--')[1];
var lineEndSide = lineId.split('__')[1].split('--')[0];

console.log('-------------------');
console.log(lineId);
console.log(lineStartGroup);
console.log(lineEndGroup);
console.log('-------------------');

var c;
var ctm;

if (thisGroupId == lineStartGroup) {
var t = d3.transform(d3.select('#' + thisGroupId).attr('transform')).translate;

if (lineStartSide == 'left') {
c = d3.select('#' + lineStartGroup).select('.left');
ctm = c.node().getCTM();
} else {
c = d3.select('#' + lineStartGroup).select('.right');
ctm = c.node().getCTM();
}

var x = d3.transform(c.select(function () {
return this.parentNode;
}).attr('transform')).translate;


console.log('START e'+ctm['e']);
console.log('START ex'+x[0]);
console.log('START f'+ctm['f']);
console.log('START fx'+x[0]);
line.attr('x1', Number(c.attr('cx')) + Number(x[0]));
line.attr('y1', Number(c.attr('cy')) + Number(x[1]));
}

if (thisGroupId == lineEndGroup) {
// var t = d3.transform(d3.select('#' + thisGroupId).attr('transform')).translate;
//
// line.attr('x2', Number(line.attr('real-x2')) + Number(t[0]));
// line.attr('y2', Number(line.attr('real-y2')) + Number(t[1]));

if (lineEndSide == 'left') {
c = d3.select('#' + lineEndGroup).select('.left');

} else {
c = d3.select('#' + lineEndGroup).select('.right');

}

var x = d3.transform(c.select(function () {
return this.parentNode;
}).attr('transform')).translate;

ctm = c.node().getCTM();
console.log('END circleId'+c.attr('id'));

line.attr('x2', Number(c.attr('cx')) + Number(x[0]));
line.attr('y2', Number(c.attr('cy')) + Number(x[1]));

}


});


})

;

opBox.call(drag);
qBox.call(drag);
circles.call(cDrag);

var circleID;

var dummyLine;

circles.on('mouseover', function () {
circleID = d3.select(this).attr('id');
}).on('mouseout', function () {
circleID = null;
})

function getXY(mouse, current, parent) {

var obj = {
x: 0,
y: 0
};

var dx = mouse.dx;
var dy = mouse.dy;

obj.x = dx;
obj.y = dy;

var xGap = current.x - parent.x;
var yGap = current.y - parent.y;

if (dx < 0) {
if ((dx + xGap) < 0) {
obj.x = -1 * xGap + 10;
}
} else {
if ((dx + xGap) > parent.width) {
obj.x = parent.width - xGap - current.width - 10;
}
}

if (dy < 0) {
if ((dy + yGap) < 0) {
obj.y = -1 * yGap + 10;
}

} else {
if ((dy + yGap) > parent.height) {
obj.y = parent.height - yGap - current.height - 10;
}
}


return obj;
}

</script>

关于javascript - d3js 转换嵌套组图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32085240/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com