Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/452.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中的SVG元素中动态居中过滤节点_Javascript_Jquery_Angularjs_D3.js_Svg - Fatal编程技术网

Javascript 在D3中的SVG元素中动态居中过滤节点

Javascript 在D3中的SVG元素中动态居中过滤节点,javascript,jquery,angularjs,d3.js,svg,Javascript,Jquery,Angularjs,D3.js,Svg,我正在努力将过滤器功能添加到我的d3图形中。当用户基于标签或id搜索特定节点时,我希望重新渲染图形并再次显示整个图形,但我希望过滤后的节点位于svg元素的中心 以下是我帮助it中心化的内容: // I get the width and height of the SVG element: var svgWidth = parseInt(svg.style("width").replace(/px/, ""), 10); var svgHeight = parseInt(svg.

我正在努力将过滤器功能添加到我的d3图形中。当用户基于标签或id搜索特定节点时,我希望重新渲染图形并再次显示整个图形,但我希望过滤后的节点位于svg元素的中心

以下是我帮助it中心化的内容:

 // I get the width and height of the SVG element:
   var svgWidth = parseInt(svg.style("width").replace(/px/, ""), 10);
   var svgHeight = parseInt(svg.style("height").replace(/px/, ""), 10);

 // I get the center of the svg:
    var centerX = svgWidth / 2;
    var centerY = svgHeight / 2;

     _.forEach(nodes, function(e) {
          // get the full node (with x and y coordinates) based on the id
           var nodeObject = g.node(nodeId); 

          // I look for matches between the nodeId or label and search word
           if (searchInput) {
                if (nodeObject.id === parseInt(searchInput, 10) || nodeObject.label.toUpperCase().indexOf(searchInput.toUpperCase()) > -1) {
                                    searchedNodes.push(nodeObject);
                                    console.log(searchedNodes);
                            }
                    }
              }

              // after looping through all the nodes rendered
              if (searchedNodes.length > 0) {
                    //var width = searchedNodes[0].elem.getBBox().width;
                    //var height =  searchedNodes[0].elem.getBBox().height;
                    ctrl.selectedNode = searchedNodes[0];
                    var offsetX = centerX - searchedNodes[0].x;
                    var offsetY = centerY - searchedNodes[0].y;
                    svgGroup.attr("transform", "translate(" + offsetX + "," + offsetY + ")" + "scale(" + 3 + ")");

                     // this line here is incorrect syntax and breaks the build, essentially stopping the script from running
                     // the graph renders correctly when this line is here
                    svgGroup.attr("transform", "translate(" + offsetX + "," + offsetY + ")").scale(2).event;
                 }
这是图形的外观,上面的线打断了包含的脚本

当我移除那条线时,它没有居中,几乎看起来像是在渲染图形。显然,我需要删除上面不正确的代码行,但是有人不知道为什么在这种情况下图形不能正确呈现吗

//获取用户输入并重新呈现图形
元素查找(“.search”).bind(“keyup”),函数(e:any){
var输入;
如果(e[“keyCode”]==13){
searchedNodes=[];
searchInput=范围[“searchInput”];
currentFilteredNode=null;
enterKeyPressed=true;
渲染图(搜索输入);
}
如果(e[“键码”]==8){
searchedNodes=[];
searchInput=范围[“searchInput”];
currentFilteredNode=null;
渲染图(搜索输入);
}
});
//如果存在searchInput且至少有一个匹配节点,则对节点进行排序
//按id,然后选择第一个匹配项并将其居中
if(searchInput&&searchedNodes.length>0){
searchedNodes.sort(函数(node1:any,node2:any){
返回node1.id-node2.id;
});
//如果有匹配的结果,请确保noResultsMessage不会显示在屏幕上
作用域$apply(函数(){
范围[“noResultsMessage”]=false;
});
ctrl.selectedNode=searchedNodes[0];
offsetX=centerX-searchedNodes[0].x;
offsetY=centerY-searchedNodes[0].y;
attr(“transform”、“translate”(+offsetX+)、“+offsetY+”)+“scale”(+3+”);
}
//唯一的其他缩放和这只运行在页面加载
zoom=d3.behavior.zoom();
zoom.on(“zoom”,function()){
svgGroup.attr(“transform”、“translate”(+(d3.event.translate+)”)+“scale”(+(d3.event.scale+)”);
//这将缩放图形-它在页面加载时运行,并且每当用户输入搜索输入时都会重新呈现整个图形
var scaleGraph=函数(useAnimation:any){
var graphWidth=g.graph().width+4;
var graphHeight=g.graph().高度+4;
var width=parseInt(svg.style(“width”).replace(/px/,“”),10);
var height=parseInt(svg.style(“height”).replace(/px/,“”),10);
var zoomScale=原始zoomScale;
//缩放以适应
如果(ctrl.autoResizeGraph==“已禁用”){
zoomScale=1;
}否则{
//如果设置为“填充”或“自动”(大于画布时),则始终缩放到画布
如果(ctrl.autoResizeGraph==“填充”| |(图形宽度>宽度| |图形高度>高度)){
zoomScale=Math.min(宽度/图形宽度、高度/图形高度);
}
}
var翻译;
if(direction.toUpperCase()=“TB”){
//水平居中+顶部对齐(偏移1px)
translate=[(宽度/2)-(图形宽度*缩放比例)/2)+2,1];
}else if(direction.toUpperCase()=“BT”){
//水平居中+顶部对齐(偏移1px)
translate=[(宽度/2)-(图形宽度*缩放比例)/4)+2,1];
}else if(direction.toUpperCase()=“LR”){
//中心垂直(偏移1px)
平移=[1,(高度/2)-(图形高度*缩放比例)/2];
}else if(direction.toUpperCase()=“RL”){
//中心垂直(偏移1px)
平移=[1,(高度/2)-(图形高度*缩放比例)/4];
}否则{
//中心水平和垂直
平移=[(宽度/2)-((图形宽度*缩放比例)/2),(高度/2)-((图形高度*缩放比例)/2)];
}
缩放。中心([宽度/2,高度/2]);
缩放。大小([宽度,高度]);
缩放。翻译(翻译);
缩放比例(缩放比例);
//如果是第一次渲染,则不要使用动画
事件(useAnimation?svg.transition()。持续时间(500):svg);
};
用于筛选节点的代码:

  // move to the left of the searchedNodes array when the left arrow is clicked
            scope["filterNodesLeft"] = function () {
                filterNodesIndex--;
                if (filterNodesIndex < 0) {
                    filterNodesIndex = searchedNodes.length - 1;
                }
                currentFilteredNode = searchedNodes[filterNodesIndex];
                runScaleGraph = true;
                number = 1;
                renderGraph();
            };

            // move to the right of the searchNodes array when the right arrow is clicked
            scope["filterNodesRight"] = function () {
                filterNodesIndex++;
                if (filterNodesIndex > searchedNodes.length - 1) {
                    filterNodesIndex = 0;
                }
                currentFilteredNode = searchedNodes[filterNodesIndex];
                runScaleGraph = true;
                number = 1;
                renderGraph();
            };

  // get the current filteredNode in the searchNodes array and center it
  // when the graph is re-rendered
  if (currentFilteredNode) {
                    ctrl.selectedNode = currentFilteredNode;
                    offsetX = centerX - currentFilteredNode.x;
                    offsetY = centerY - currentFilteredNode.y;
                    svgGroup.attr("transform", "translate(" + offsetX + "," + offsetY + ")");
                    runScaleGraph = false;
                }
//单击左箭头时移到searchedNodes数组的左侧
作用域[“filterNodesLeft”]=函数(){
过滤器节点索引--;
如果(过滤器节点索引<0){
filterNodesIndex=searchedNodes.length-1;
}
currentFilteredNode=searchedNodes[FilterNodeIndex];
runScaleGraph=true;
数字=1;
渲染图();
};
//单击向右箭头时,移动到searchNodes数组的右侧
作用域[“FilterNodeRight”]=函数(){
filterNodesIndex++;
如果(FilterNodeIndex>searchedNodes.length-1){
filterNodesIndex=0;
}
currentFilteredNode=searchedNodes[FilterNodeIndex];
运行规模
  // move to the left of the searchedNodes array when the left arrow is clicked
            scope["filterNodesLeft"] = function () {
                filterNodesIndex--;
                if (filterNodesIndex < 0) {
                    filterNodesIndex = searchedNodes.length - 1;
                }
                currentFilteredNode = searchedNodes[filterNodesIndex];
                runScaleGraph = true;
                number = 1;
                renderGraph();
            };

            // move to the right of the searchNodes array when the right arrow is clicked
            scope["filterNodesRight"] = function () {
                filterNodesIndex++;
                if (filterNodesIndex > searchedNodes.length - 1) {
                    filterNodesIndex = 0;
                }
                currentFilteredNode = searchedNodes[filterNodesIndex];
                runScaleGraph = true;
                number = 1;
                renderGraph();
            };

  // get the current filteredNode in the searchNodes array and center it
  // when the graph is re-rendered
  if (currentFilteredNode) {
                    ctrl.selectedNode = currentFilteredNode;
                    offsetX = centerX - currentFilteredNode.x;
                    offsetY = centerY - currentFilteredNode.y;
                    svgGroup.attr("transform", "translate(" + offsetX + "," + offsetY + ")");
                    runScaleGraph = false;
                }
//when diagram is initially displayed
var output = d3.select('.output');
var bbox = output.getBBox();
var centerX = bbox.width * .5;  
var centerY = bbox.height * .5;


//in your block where you find a node matches the filter
    if (node.label.toUpperCase().indexOf(searchString.toUpperCase()) > -1) {
       var offsetX = centerX - node.x;
       var offsetY = centerY - node.y;
       output.attr('transform', 'translate(' + offsetX + ',' + offsetY + ')');    
    }
svgGroup.attr("transform", "translate(" + offsetX + "," + offsetY + ")" + "scale(" + 3 + ")");
svgGroup.attr("transform", "translate(" + offsetX + "," + offsetY + ")");
"scale(" + 3 + ")"
             // zoom in on the searched or filtered node
              function zoomOnNode (node:any) {

                // get the width and height of the svg
                var svgWidth = parseInt(svg.style("width").replace(/px/, ""), 10);
                var svgHeight = parseInt(svg.style("height").replace(/px/, ""), 10);

                // loop through all the rendered nodes (these nodes have x and y coordinates)
                for (var i = 0; i < renderedNodes.length; i++) {

                    // if the first matching node passed into the function
                    // and the renderedNode's id match get the 
                    // x and y coordinates from that rendered node and use it to calculate the svg transition
                    if (node.id === renderedNodes[i].id) {
                            var translate = [svgWidth / 2 -  renderedNodes[i].x, svgHeight / 2 - renderedNodes[i].y];
                            var scale = 1;
                            svg.transition().duration(750).call(zoom.translate(translate).scale(scale).event);
                    }
                }
            }

     // listen for the enter key press, get all matching nodes and pass in the first matching node in the array to the zoomOnNode function
     elem.find(".search").bind("keyup", function (e:any) {
                var searchInput;
                if (e["keyCode"] === 13) {
                    searchedNodes = [];
                    searchInput = scope["searchInput"];
                    enterKeyPressed = true;
                    if (searchInput) {
                        // recursively get all matching nodes based on search input
                        getMatchingNodes(ctrl.nodes, searchInput);

                        scope.$apply(function() {
                            // show the toggle icons if searchedNodes.length is greater then 1
                            scope["matchingNodes"] = searchedNodes.length;
                            scope["noResultsMessage"] = false;

                            if (searchedNodes.length > 0) {
                                var firstNode = searchedNodes[0];
                                ctrl.selectedNode = firstNode;
                                zoomOnNode(firstNode);
                            } else if (searchedNodes.length === 0) {
                                    ctrl.selectedNode = null;
                                    // add the noResultsMessage to the screen
                                    scope["noResultsMessage"] = true;
                                }
                            });
                        }
                }
          }