简体   繁体   English

d3js转换嵌套组图像

[英]d3js transforming nested group images

I am working on [this][1] d3 project. 我正在研究[这] [1] d3项目。 Basically I am trying to create a SQL like query builder. 基本上我正在尝试创建一个类似SQL的查询构建器。 I can drop boxes to the drawing area & other operators inside the box. 我可以将盒子放到绘图区域和盒子内的其他操作员。 Then I should be able to connect them all. 然后我应该能够将它们连接起来。 I am trying to translate 2 images which are nested in groups. 我试图翻译2个嵌套在组中的图像。 I want to move the small items inside the big box. 我想移动大盒子里的小物品。 I can transform the big box and small operators separately. 我可以分别改造大箱子和小型运营商。 Problem happens When I try to move the small operators first. 问题发生当我尝试先移动小型操作员时。 I want to move the small operators, then big boxes. 我想移动小型运营商,然后是大箱子。 meanwhile I want to keep the relative position of small operators and big box same. 同时我想保持小型运营商和大型箱子的相对位置相同。 But when I try to move the large box after moving one of the small box it resets its location. 但是当我在移动一个小盒子后尝试移动大盒子时,它会重置它的位置。 Here is a demo of my work in jsfiddle 这是我在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 : I connect two elements by dragging the circles and dropping into another circle. PS:我通过拖动圆圈并放入另一个圆圈来连接两个元素。

Can anyone point out my mistake? 谁能指出我的错误?

After all sort of troubles, I found my answer. 遇到各种各样的麻烦后,我找到了答案。 Actually it is all about the coordinate system and where to put stuff and how to organize it. 实际上,它完全是关于坐标系,放置东西以及如何组织它。 Once I fugured that out, Answer is pretty obvious. 一旦我把它弄出来,答案就很明显了。

<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>

From my experience developing visual editors, I can say that relative positions (such as x,y in Operator) can and shoud be managed as data. 根据我开发可视化编辑器的经验,我可以说相对位置(例如运算符中的x,y)可以作为数据进行管理。

Try changing that data (and not directly the x,y attributes of the svg element), and binding the data in a d3js way. 尝试更改该数据(而不是直接更改svg元素的x,y属性),并以d3js方式绑定数据。 It will be much more idiomatic and fast. 它将更加惯用和快速。

PS: I know about separation of model and view, and I know about the bad side of storing visual properties along the model, but if it will be only a view for that model, it is for sure the best approach. PS:我知道模型和视图的分离,我知道在模型中存储视觉属性的坏方面,但如果它只是该模型的视图,那肯定是最好的方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM