d3 學習記錄-----network實現

題記: d3學習交流。

本個例子技術點重點和難點:
1. 箭頭如何顯示在節點相連的直線上
2. 箭頭與節點圓之間的距離因爲縮放的動態緣由如何控制,使箭頭一直保持在圓外圍
3. 鼠標中間鍵滾動帶動圖像縮放(此點若知事件則較易)
4. 鼠標拖拽控制條實現圖像縮放。
5. 第3,4兩個控件結合交替使用實現縮放效果(關鍵是兩個事件的縮放數值倍數範圍和在圖中縮放距離範圍要保持一致。javascript

因爲這個模型是從我在作的項目中抽取的模型例子,因此,界面比較醜,旁邊的圖拽條的 「+」,「-"圖片我也沒加上去。請輸入圖片描述html

<!DOCTYPE html>
<html>
  <head>
        <meta charset="utf-8">
        <title>network </title>
        <script type="text/javascript" src="d3.v3.min.js"></script> 
  </head>
  <body>
        <script type="text/javascript">
        var h=500;
        var w=800;

        var scale_max = 2.3;
        var scale_min = 0.2;
        var current_scale = 1.1; 
        var bar_len = 100;
        var border_len = 20 ; 
        var colors = d3.scale.category20() 
        //(1)定義節點和聯繫對象數組
        var dataset = {
        nodes:[//節點
                { name:"Peter",r:16},
                { name:"Bob",r:21},
                { name:"Tony",r:31},
                { name:"Davir",r:25},
                { name:"Edward",r:27},
                { name:"Army",r:19},
                { name:"Jonn",r:35},
                { name:"Hannah",r:33},
                { name:"Jack",r:29},
                { name:"Jerry",r:32} 
            ],
        edges:[//邊
                { source:0,target:1,weight:1,color:1},
                { source:0,target:2,weight:3,color:4},
                { source:0,target:3,weight:4,color:6},
                { source:0,target:4,weight:6,color:65},
                { source:1,target:5,weight:3,color:76},
                { source:2,target:5,weight:8,color:879},
                { source:2,target:5,weight:7,color:989},
                { source:3,target:4,weight:9,color:643},
                { source:5,target:8,weight:1,color:54},
                { source:5,target:9,weight:3,color:54}, 
                { source:6,target:7,weight:4,color:45},
                { source:7,target:8,weight:0,color:43},
                { source:2,target:8,weight:8,color:243},
                { source:3,target:8,weight:1,color:43},
                { source:5,target:8,weight:5,color:13},
                { source:6,target:8,weight:3,color:351},
                { source:8,target:9,weight:1,color:1}
            ]
        }; 

        //(2)轉化數據爲適合生成力導向圖的對象數組
        var force=d3.layout.force()
                    .nodes(dataset.nodes)//加載節點數據
                    .links(dataset.edges)//加載邊數據
                    .size([w,h])//設置有效空間的大小
                    .linkDistance(150)//連線的長度
                    .charge(-500)  
                    .start();//設置生效
        var svg = d3.select("body")
                .append("svg")
                .attr("width",w)
                .attr("height",h)
                .attr("pointer-events","all")     .call(d3.behavior.zoom().on("zoom",redraw))//redraw
                .on("mousedown.zoom",null)
                .append('svg:g')
                .attr("cursor","pointer");

        var marker = d3.select("svg").append("svg:defs")
                       .selectAll("marker")
                       .data(dataset.nodes) //not edges
                       .enter()
                       .append("svg:marker");
                marker.attr({
                        id:function(d){
                            return "marker-" + d.r;
                        },
                        viewBox:"0 -5 10 10",
                        refX:function(d){
                            console.log("d.r:" + d.r);
                            return d.r ;
                        },
                        markerWidth:10,
                        markerHeight:10,
                        orient: "auto"
                       })
                       .append('svg:path')
                       .attr('d',"M0,-5L10,0L0,5")
                       .attr("fill",function(d){ 
                            return "black";
                       });
        var dtb = d3.select("svg")
                    .append("svg:g")
                    .attr({
                        heigth: bar_len,
                        width: 200 ,
                        x: 0,
                        y: 0 
                    });
            dtb.append('rect')//top
               .attr({
                    width:border_len,
                    height:border_len,
                    x: 10,
                    y: 10
               })
               .attr("fill",'black');
            dtb.append("rect") //bottom
               .attr({
                    width:border_len,
                    height:border_len,
                    x:10,
                    y:130
               })
               .attr("fill","black");
            dtb.append("rect")
                .attr({
                    width:4,
                    height:bar_len,
                    x:19,
                    y:30
                })
                .attr("fill","grey");

        var bar = dtb.append('rect')
                     .attr({
                        width:20,
                        height:5,
                        x: 10,
                        y: 82,
                        fill:"green",
                        cursor:"pointer"
                     })
                     .call(d3.behavior.drag().on("drag",dragmove));//dragmove


        //(3)建立做爲連線的svg直線
        var edges = svg.append('g')
                .attr('cursor','pointer')
                .selectAll(".link")
                .data(dataset.edges)
                .enter()
                .append("line")
                .attr("class","link")
                .style("stroke",function(d){//  設置線的顏色
                    return colors(d.color);
                })
                .style("stroke-width",function(d,i){//設置線的寬度
                    return 1.5;
                }) 
                .attr("marker-end",function(d){  
                    return "url(#marker-" + (d.target.r) + ")";
                });
        //(4) 建立做爲連線的svg圓形
        var nodes = svg.selectAll(".node")
                .data(dataset.nodes) 
                .enter().append('g')
                .attr('class','node')
                .call(force.drag);//能夠拖動 

            nodes.append("svg:circle")
                .attr("r",function(d){    
                    return d.r;//the r of circle
                })
                .style("fill",function(d){
                    return colors(d.r*d.r*d.r);
                });
           nodes.append('text')
                .attr("text-anchor", "middle")
                .attr("font-size", "10px")
                .attr('stroke', 'black')
                .attr('stroke-width', function (d) {
                    return 0;
                })
                .text(function (d) {
                    return d.name;
                });

           nodes.append("title")
            .text(function (d) {
                return d.name;
            });


        //(5)打點更新,沒有的話就顯示不出來了
         force.on('tick',function(){
            edges.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;
            });
        //(6)設置節點座標,節點先生成再肯定座標的
        nodes.attr("cx",function(d){//節點有座標屬性
                return d.x;
            })
            .attr("cy",function(d){
                return d.y;
            }).attr("transform", function (d) {
                    return "translate(" + d.x + "," + d.y + ")";
            }); 
        });

        var scale = 1.1;
        var currentY = 0;
        function redraw(){  //放大縮小 鼠標滑動   scale放大倍數,translate是轉變,轉換

            scale = d3.event.scale;
            if(scale > scale_max || scale < scale_min){  
                return ;
            }
            currentY = scale/(scale_max-scale_min)*bar_len + 18;
            bar.attr("y",currentY);
            console.log("scale:" + scale +",currentY:" + currentY); 
            svg.attr("transform","translate(" + d3.event.translate + ")" + "scale(" + scale + ")" ); 
        }        

        function dragmove(){ 
            var x = 0;   //not move in x axis
            var dy = d3.event.y; 
            var diffY = dy ;  //+currentY - 30 ; 

            if(diffY  > 130){//bar_len + border_len+ margin 
                diffY = 125;
                return ;
            }
            if(diffY < 30){ //border_len+ margin 
                diffY = 30;
                return ;
            }
            //console.log( "diffY:" + diffY + "dy:" + dy);
            scale = diffY /bar_len*(scale_max-scale_min);  
            //console.log("scale:" + scale); 
            bar.attr("y",diffY) 
            svg.attr("transform","translate(" + [(w/3)-(w*current_scale/3),(h/2) - (h*current_scale/2)] +")" + "scale(" + scale + ")" );
        } 

  </script>

    </body>
</html>
相關文章
相關標籤/搜索