D3——力导向图

<script type="text/javascript" src="http://d3js.org/d3.v5.min.js"></script>
<script>
    var width = 800;
    var height = 800;
    var svg = d3.select("body")
        .append("svg")
        .attr("width",width)
        .attr("height",height);

    var marge = {top:10,bottom:10,left:10,right:10}

    var g = svg.append("g")
        .attr("transform","translate("+marge.top+","+marge.left+")");

    //准备数据
    var nodes = [//节点集
        {name:"陕西省",group:2.5},
        {name:"西安市",group:2},
        {name:"安康市",group:2},
        {name:"咸阳市",group:2},
        {name:"宝鸡市",group:2},
        {name:"铜川市",group:2},
        {name:"商洛市",group:2},
        {name:"汉中市",group:2},
        {name:"延安市",group:2},
        {name:"兴平市",group:2},
        {name:"碑林区",group:1.5},
        {name:"未央区",group:1.5},
        {name:"莲湖区",group:1.5},
        {name:"新城区",group:1.5},
        {name:"户县",group:1.5},
        {name:"祖庵镇",group:1},
        {name:"甘河镇",group:1},
        {name:"蒋村镇",group:1},
    ];
    var edges = [//边集
        {source:0,target:1,value:2},  //value控制线的长短
        {source:0,target:2,value:2},
        {source:0,target:3,value:2},
        {source:0,target:4,value:2},
        {source:0,target:5,value:2},
        {source:0,target:6,value:2},
        {source:0,target:7,value:2},
        {source:0,target:8,value:2},
        {source:0,target:9,value:2},
        {source:1,target:10,value:1.5},
        {source:1,target:11,value:1.5},
        {source:1,target:12,value:1.5},
        {source:1,target:13,value:1.5},
        {source:1,target:14,value:1.5},
        {source:14,target:15,value:1},
        {source:14,target:16,value:1},
        {source:14,target:17,value:1},
    ];
   
    //设置一个color的颜色比例尺,为了让不同的扇形呈现不同的颜色
    var colorScale = d3.scaleOrdinal()
        .domain(d3.range(nodes.length))
        .range(d3.schemeCategory10);


    var forceSimulation = d3.forceSimulation()
        .force("link",d3.forceLink())
        .force("charge",d3.forceManyBody())
        .force("center",d3.forceCenter());
    //生成节点数据
    forceSimulation.nodes(nodes)
        .on("tick",ticked);//这个函数很重要,后面给出具体实现和说明
    //生成边数据
    forceSimulation.force("link")
        .links(edges)
        .distance(function(d){//每一边的长度
            return d.value*100;
        })
    //设置图形的中心位置
    forceSimulation.force("center")
        .x(width/2)
        .y(height/2);
    //在浏览器的控制台输出
    console.log(nodes);
    console.log(edges);
    //绘制边
    var links = g.append("g")
        .selectAll("line")
        .data(edges)
        .enter()
        .append("line")
        .attr("stroke",function(d,i){
            return colorScale(d.value);   //边的颜色
            //return "#ccc";
        })
        .attr("stroke-width",1);
    //边上文字
    var linksText = g.append("g")
        .selectAll("text")
        .data(edges)
        .enter()
        .append("text")
        .text(function(d){
            return d.relation;
        })
    //建立用来放在每个节点和对应文字的分组<g>
    var gs = g.selectAll(".circleText")
        .data(nodes)
        .enter()
        .append("g")
        .attr("transform",function(d,i){
            var cirX = d.x;
            var cirY = d.y;
            return "translate("+cirX+","+cirY+")";
        })
        .call(d3.drag()
            .on("start",started)
            .on("drag",dragged)
            .on("end",ended)
        );

    //绘制节点
    gs.append("circle")
       // .attr("r",20)
        .attr("r",function (d,i) {    //圆圈半径
            return d.group*15;
        })
        .attr("fill",function(d,i){
            //return colorScale(i);
            return colorScale(d.group);
        })
    //文字
    gs.append("text")
        /*.attr("x",-10)
        .attr("y",-20)
        .attr("dy",10)*/
        .attr("x",-25)
        .attr("y",-5)
        .attr("dy",10)
        .text(function(d){
            return d.name;
        })
    function ticked(){
        links
            .attr("x1",function(d){return d.source.x;})
            .attr("y1",function(d){return d.source.y;})
            .attr("x2",function(d){return d.target.x;})
            .attr("y2",function(d){return d.target.y;});

        linksText
            .attr("x",function(d){
                return (d.source.x+d.target.x)/2;
            })
            .attr("y",function(d){
                return (d.source.y+d.target.y)/2;
            });

        gs
            .attr("transform",function(d) { return "translate(" + d.x + "," + d.y + ")"; });
    }
    //drag
    function started(d){
        if(!d3.event.active){
            forceSimulation.alphaTarget(0.8).restart();//设置衰减系数,对节点位置移动过程的模拟,数值越高移动越快,数值范围[0,1]
        }
        d.fx = d.x;
        d.fy = d.y;
    }
    function dragged(d){
        d.fx = d3.event.x;
        d.fy = d3.event.y;
    }
    function ended(d){
        if(!d3.event.active){
            forceSimulation.alphaTarget(0);
        }
        d.fx = null;
        d.fy = null;
    }

</script>

发布了45 篇原创文章 · 获赞 7 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/wang_NiFeng/article/details/85165452