Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/427.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 在力有向图上追加一条线并使用D3应用变换_Javascript_D3.js - Fatal编程技术网

Javascript 在力有向图上追加一条线并使用D3应用变换

Javascript 在力有向图上追加一条线并使用D3应用变换,javascript,d3.js,Javascript,D3.js,我在D3中有一个力定向图,它可以在web套接字加载时正确渲染。我的任务是根据后续的web套接字消息,在该图中添加或删除链接和节点。我遇到的问题是,当我平移或缩放图形时,会应用变换。我不知道如何将该转换应用于新添加的链接或节点。因此,添加的链路取决于源节点和目标节点的原始位置。下面是完整的代码。希望有人能告诉我如何将转换应用于新添加的链接 根据要求编辑代码以简化: var DataPlane = (function() { //This method gets called when a

我在D3中有一个力定向图,它可以在web套接字加载时正确渲染。我的任务是根据后续的web套接字消息,在该图中添加或删除链接和节点。我遇到的问题是,当我平移或缩放图形时,会应用变换。我不知道如何将该转换应用于新添加的链接或节点。因此,添加的链路取决于源节点和目标节点的原始位置。下面是完整的代码。希望有人能告诉我如何将转换应用于新添加的链接

根据要求编辑代码以简化:

    var DataPlane = (function() {

//This method gets called when a link is either added or removed from the svg via web socket.
var remapDataPlane = function(data) {
    var dpData = $.parseJSON(data);
    ...
    if (dpData.addedLinks.length > 0) {
        //get the svg
        var parentSvg = d3.select("#app_dataPlane svg").select("g")
        var svg = parentSvg.select("g");

        //this portion gets the transform that has been applied to the svg group element.
        var trans = svg.attr("transform");

        //get a list of switches from svg
        var svgSwitches = d3.selectAll(".switch");
        //Process unidirectional and bidirectional links -- BEGIN
        var bidLinks = [];
        var uniLinks = [];
        var pairs = [];
        var idx = 0;


        function hasMatchingNode(element, index, array) {
            return (element.src.dpid !== this.src.dpid && element.src.dpid === this.dst.dpid && element.dst.dpid === this.src.dpid);
        }

        function parseLinks(element, index, array) {
            var node = array.filter(hasMatchingNode, element);
            if (node.length > 0) {
                var match = array.indexOf(node.pop());
                array.splice(match, 1);
            } else {
                uniLinks.push(element);
                array.splice(index, 1);
            }
        }
        dpData.addedLinks.map(parseLinks);
        if (dpData.addedLinks != undefined) {
            dpData.addedLinks.forEach(function(item) {
                item["nature"] = "bidirectional";
            });
            uniLinks.forEach(function(item) {
                item["nature"] = "unidirectional";
            });

            //Links are added in pairs to represent bidirectional nature.  I elminate duplicate links from the data and merge them with unidirectional links here.
            $.merge(dpData.addedLinks, uniLinks);
        }

        //For each link being added to the graph 
        for (var i = 0; i <= dpData.addedLinks.length - 1; i++) {

            //Get the name of the source node for the link and it's corresponding coordinates
            var srcName = 'switch_' + dpData.addedLinks[i].src.dpid;
            var srcC = document.getElementById(srcName);
            var srcCx = +srcC.getAttribute('cx');
            var srcCy = +srcC.getAttribute('cy');
            var srcCtm = srcC.getCTM();
            var srcCoords = getScreenCoords(srcCx, srcCy, srcCtm);

            //Get the name of the destination node for the link and it's corresponding coordinates
            var dstName = 'switch_' + dpData.addedLinks[i].dst.dpid;
            var dstC = document.getElementById(dstName);
            var dstCx = +dstC.getAttribute('cx');
            var dstCy = +dstC.getAttribute('cy');
            var dstCtm = dstC.getCTM();
            var dstCoords = getScreenCoords(dstCx, dstCy, dstCtm);

            //Append the line to the graph using the coordinates derived from the Cx & Cy coordinates
            var link = svg.append("line")
                .attr("x1", srcCoords.x)
                .attr("y1", srcCoords.y)
                .attr("x2", dstCoords.x)
                .attr("y2", dstCoords.y)
                .attr("class", "link")
                .attr("id", function(d) {
                    return "name_" + dpData.addedLinks[i].dst.dpid + dpData.addedLinks[i].src.dpid;
                })
                .style("stroke-width", 2)
                //Set Style for unidirectional otherwise grey
                .style("stroke", function(d) {
                    if (d != undefined && d.nature == "unidirectional") {
                        return "green";
                    }
                })
                // **** This is where I try and apply the transform to the link ****
                .attr("transform", trans)                   
        }
    }

    function getScreenCoords(x, y, ctm) {
        var xn = ctm.e + x * ctm.a;
        var yn = ctm.f + y * ctm.d;
        return {
            x: xn,
            y: yn
        };
    }
};      

// Initial code omitted for brevity as requested

return {
    drawDataPlane: drawDataPlane,
    remapDataPlane: remapDataPlane
};
   })();

您能否发布一个svg元素当前的方式示例,以及哪些部分存在问题?这在代码方面有点多,如果您可以缩小问题范围或提供一些示例输出来更详细地显示问题,那就太好了。您的平移/缩放功能是什么样子的?
    <svg width="814" height="305" pointer-events="all">
<g>
    <g transform="translate(6.568073042618323,138.38858706474264) scale(0.8420541187522115)">
        <rect width="1628" height="610" fill="white"></rect>
        <line class="link" id="name_00:00:00:00:00:00:00:0100:00:00:00:00:00:00:03" x1="427.59429499296965" y1="125.07073054436019" x2="375.8732495447546" y2="138.7148361886131" style="stroke-width: 2px;"></line>
        <line class="link" id="name_00:00:00:00:00:00:00:0200:00:00:00:00:00:00:01" x1="375.8732495447546" y1="138.7148361886131" x2="400.55190412548484" y2="186.17410516927373" style="stroke-width: 2px;"></line>
        <circle r="6" id="switch_00:00:00:00:00:00:00:02" class="switch" fill="#15a9ff" cx="400.55190412548484" cy="186.17410516927373"></circle>
        <circle r="6" id="switch_00:00:00:00:00:00:00:03" class="switch" fill="#15a9ff" cx="427.59429499296965" cy="125.07073054436019"></circle>
        <circle r="6" id="switch_00:00:00:00:00:00:00:01" class="switch selectedSwitch" fill="#15a9ff" cx="375.8732495447546" cy="138.7148361886131"></circle>
    </g>
</g>
    function redraw() {
        svg.attr("transform",
            "translate(" + d3.event.translate + ")" + " scale(" + d3.event.scale + ")"); /* skewX(30) */
    }