Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/351.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
D3.js 将不同组的圆节点连接到线强制布局_D3.js_Force Layout - Fatal编程技术网

D3.js 将不同组的圆节点连接到线强制布局

D3.js 将不同组的圆节点连接到线强制布局,d3.js,force-layout,D3.js,Force Layout,我已经创建了3组圆,每个圆具有不同的力布局: (function () { /****** Functions ******* ************************/ var rand = function (min, max) { return Math.floor(Math.random() * (max - min + 1)) + min; }; /****** Variables ******* *****

我已经创建了3组圆,每个圆具有不同的力布局:

(function () {
    /****** Functions *******
     ************************/
    var rand = function (min, max) {
        return Math.floor(Math.random() * (max - min + 1)) + min;
    };

    /****** Variables *******
     ************************/
    var i,
        color,
        width  = 400,
        height = 400,
        forces = [],
        coords,
        _linksData, _nodesData,
        mainContainer;

    /** Coordinates of groups **/
    coords = [
        [0, 0],
        [width, 0],
        [width * 2, 0],
    ];

    color = d3.scale.category10();

    /****** Main SVG container *******
     *********************************/
    mainContainer = d3.select("#main-container").append("svg")
        .attr("width", 1165)
        .attr("height", 650)
        .append("g");

    for (i = 0; i < 3; i++) {
        forces[i] = d3.layout.force();

        (function () {
            /****** Generate Random Data for one Group *******
             *************************************************/

            /** Random amount of circles with random radius **/
            _nodesData = d3.range(rand(25, 45)).map(function (d, i) {
                return {
                    id     : i,
                    radius : rand(6, 18)
                }
            });

            /**
             Add children to group with 0 radius in order to have d3
             position it in center and put all other circles in its orbit
             **/
            _nodesData.push({
                children : d3.range(_nodesData.length),
                radius   : 0
            });

            /** Add links **/
            _linksData = d3.layout.tree().links(_nodesData);


            /****** Create Group Container *******
             *************************************/
            var groupContainer = mainContainer.append("g")
                .attr('class', 'group')
                .attr('id', 'group' + i)
                .attr('transform', 'translate(' + coords[i][0] + ',' + coords[i][1] + ')')
                .on('mouseenter', function () {
                    var index = d3.select(this).attr('id').replace('group', '');
                    // console.log(index);
                    forces[index].alpha(.25);
                });

            var nodesObjects = groupContainer.selectAll(".node");
            var linksObjects = groupContainer.selectAll(".link")

            /****** Force Layout ******/
            forces[i].linkDistance(function () {
                    return rand(110, 130)
                })
                .charge(function () {
                    return -rand(150, 200)
                })
                .gravity(0.1 + 1 / rand(10, 50))
                .size([width, height])
                .on("tick", tick)
                .nodes(_nodesData)
                .links(_linksData)
                .start();

            /****** links ******/
            // linksObjects = linksObjects.data(_linksData)
            //     .enter()
            //     .append("line").attr('class', 'link')
            //
            // ;

            /****** Create nodes ******/
            nodesObjects = nodesObjects.data(_nodesData, function (d) {
                    return d.id;
                })
                .enter().append("g")
                .attr("class", "node")
                .on('mouseover', function () {
                    d3.select(this).moveToFront();
                });


            /****** Create circles ******/
            nodesObjects.append("circle")
                .attr("r", function (d) {
                    return d.radius;
                }).style("fill", color(i));


            function tick() {
                linksObjects.attr({
                    x1 : function (d) {
                        return d.source.x;
                    },
                    y1 : function (d) {
                        return d.source.y;
                    },
                    x2 : function (d) {
                        return d.target.x;
                    },
                    y2 : function (d) {
                        return d.target.y;
                    }
                });

                nodesObjects.attr("transform", function (d) {
                    return "translate(" + d.x + "," + d.y + ")";
                });
            }

        })();
    }
}())
(函数(){
/******功能*******
************************/
var rand=函数(最小值、最大值){
返回Math.floor(Math.random()*(max-min+1))+min;
};
/******变数*******
************************/
var i,
颜色
宽度=400,
高度=400,
力=[],
coords,
_链接数据,节点数据,
主容器;
/**群坐标**/
坐标=[
[0, 0],
[宽度,0],
[宽度*2,0],
];
颜色=d3.scale.category10();
/******主SVG容器*******
*********************************/
mainContainer=d3。选择(#mainContainer”)。追加(“svg”)
.attr(“宽度”,1165)
.attr(“高度”,650)
.附加(“g”);
对于(i=0;i<3;i++){
forces[i]=d3.layout.force();
(功能(){
/******为一个组生成随机数据*******
*************************************************/
/**具有随机半径的圆的随机数量**/
_nodesData=d3.range(rand(25,45)).map(函数(d,i){
返回{
id:我,
半径:兰特(6,18)
}
});
/**
将子对象添加到半径为0的组中,以获得d3
把它放在中心,把所有其他的圆放在它的轨道上
**/
_nodesData.push({
子项:d3.范围(_nodesData.长度),
半径:0
});
/**添加链接**/
_linksData=d3.layout.tree().links(_nodesData);
/******创建组容器*******
*************************************/
var groupContainer=maincainer.append(“g”)
.attr('类','组')
.attr('id','group'+i)
.attr('transform','translate('+coords[i][0]+','+coords[i][1]+'))
.on('mouseenter',函数(){
var index=d3。选择(this.attr('id')。替换('group','');
//控制台日志(索引);
力[index].alpha(.25);
});
var nodesObjects=groupContainer.selectAll(“.node”);
var linksObjects=groupContainer.selectAll(“.link”)
/******部队布局******/
力[i]。链接距离(函数(){
返回兰特(110130)
})
.充电(功能){
退货-兰特(150200)
})
.重力(0.1+1/兰特(10,50))
.尺寸([宽度、高度])
.on(“滴答”,滴答)
.nodes(_nodesData)
.links(_linksData)
.start();
/******链接******/
//linksObjects=linksObjects.data(_linksData)
//.输入()
//.append(“line”).attr('class','link'))
//
// ;
/******创建节点******/
nodesObjects=nodesObjects.data(_nodesData,函数(d){
返回d.id;
})
.enter().append(“g”)
.attr(“类”、“节点”)
.on('mouseover',函数(){
d3.选择(this).moveToFront();
});
/******创建圆圈******/
nodesObjects.append(“圆”)
.attr(“r”,函数(d){
返回d.radius;
}).样式(“填充”,颜色(i));
函数tick(){
linksObjects.attr({
x1:功能(d){
返回d.source.x;
},
y1:功能(d){
返回d.source.y;
},
x2:功能(d){
返回d.target.x;
},
y2:功能(d){
返回d.target.y;
}
});
属性(“转换”,函数(d){
返回“translate”(“+d.x+”,“+d.y+”);
});
}
})();
}
}())

结果:

问题

有没有办法添加连接圆的线并保持圆在其位置上?

说明:直线应连接到圆,即当圆移动时更新其位置

更新


通过添加线条布局并更新其在勾号事件上的位置来实现,以防止圆圈移动:

您可以调用
force.alpha(0)
在一段时间后停止移动,然后
resume()
鼠标输出上的布局。根据你想做什么,这可能对你有用:


如果鼠标移出在超时过期之前发生,您还应清除超时。

关于您的问题,以防止圆圈移动:

您可以调用
force.alpha(0)
在一段时间后停止移动,然后
resume()
鼠标输出上的布局。根据你想做什么,这可能对你有用:


如果在超时过期之前发生鼠标移出,则还应清除超时。

绝对正确。我会给每一行一个类,您可以从唯一标识它的源和目标节点的数据中派生,以便只知道源或目标就可以选择它。然后你需要做的就是在相应的力布局的
tick
handler函数中更新两端的坐标。这正是我刚才所做的,解决了这个问题。非常感谢。我会
            var groupContainer = mainContainer.append("g")
                .attr('class', 'group')
                .attr('id', 'group' + i)
                .attr('transform',
                'translate(' + coords[i][0] + ',' + coords[i][1] + ')')
                .on('mouseenter', function () {
                    var index = d3.select(this).attr('id').replace('group', '');
                    // console.log(index);
                    forces[index].alpha(0.25);
                    setTimeout(function () {
                        forces[index].alpha(0);
                    }, 1000);
                })
                .on('mouseout', function () {
                    var index = d3.select(this).attr('id').replace('group', '');
                    // console.log(index);
                    forces[index].resume();
                });