D3弦圖製作

弦圖主要是用來表示一組元素之間的聯繫,弦圖分爲兩部分,外部的節點和內部的弦。從一個元素到另外一個元素繪製弧,表示兩個元素相關,弧的寬度表示權重,這就是弦。弦圖的繪製,主要包括創建弦圖佈局對象、確定初始數據然後轉換數據、添加節點和絃、添加文字、添加交互效果等。
訪問地址:http://106.14.147.72/Graphtest/chord-interactive.html
1.初始化數據

    var continent = [ "亞洲" , "歐洲" , "非洲" , "美洲" , "大洋洲"  ];

        // 各州人口的來源,如
        //              亞洲      美洲
        //  亞洲      9000        1000
        //  美洲      7000        500
        // 該矩陣表示:
        // 1.亞洲的人口:有9000是本地人,有1000人是來自美洲的移民,總人口爲 9000 + 1000
        // 2.美洲的人口:有500是本地人,有7000人是來自亞洲的移民,總人口爲 500 + 7000

        var population = [
          [ 9000,  870  , 3000 , 1000 , 5200 ],
          [ 3400,  8000 , 2300 , 4922 , 374  ],
          [ 2000,  2000 , 7700 , 4881 , 1050 ],
          [ 3000,  8012  , 5531  , 500  , 400  ],
          [ 3540,  4310 , 1500  , 1900 , 300 ]
        ]; 

2.創建對象轉換數據

var width  = 1400;  //SVG繪製區域的寬度
        var height = 700;   //SVG繪製區域的高度

        var svg = d3.select("body")         //選擇<body>
                    .append("svg")          //在<body>中添加<svg>
                    .attr("width", width)   //設定<svg>的寬度屬性
                    .attr("height", height);//設定<svg>的高度屬性
        //2.轉換數據
        var chord = d3.layout.chord()
                       .padding(0.03)
                       .sortSubgroups(d3.ascending)
                       .matrix(population);
//3.繪製

        //弦圖的<g>元素
        var gChord = svg.append("g")
                        .attr("transform","translate(" + width/2 + "," + height/2 + ")");

        //節點的<g>元素
        var gOuter = gChord.append("g");

        //弦的<g>元素
        var gInner = gChord.append("g");

        //顏色比例尺
        var color20 = d3.scale.category20();

        //繪製節點
        var innerRadius = height/2 * 0.7;
        var outerRadius = innerRadius * 1.1;

        //弧生成器
        var arcOuter =  d3.svg.arc()
                     .innerRadius(innerRadius)
                     .outerRadius(outerRadius);

        gOuter.selectAll(".outerPath")
                            .data(chord.groups())
                            .enter()
                            .append("path")
                            .attr("class","outerPath")
                            .style("fill", function(d) { return color20(d.index); })
                            .attr("d", arcOuter );

        gOuter.selectAll(".outerText")
                            .data(chord.groups())
                            .enter()
                            .append("text")
                            .each( function(d,i) {
                                d.angle = (d.startAngle + d.endAngle)/2;
                                d.name = continent[i];
                            })
                            .attr("class","outerText")
                            .attr("dy",".35em")
                            .attr("transform", function(d){
                                var result = "rotate(" + ( d.angle * 180 / Math.PI ) + ")";

                                result += "translate(0,"+ -1.0 * ( outerRadius + 10 ) +")" ;

                                if( d.angle > Math.PI * 3 / 4 &&  d.angle < Math.PI * 5 / 4 )
                                    result += "rotate(180)";

                                return result;
                            })
                            .text(function(d){
                                return d.name;
                            });


        //繪製弦
        var arcInner =  d3.svg.chord()
                        .radius(innerRadius);

        gInner.selectAll(".innerPath")
                            .data(chord.chords())
                            .enter()
                            .append("path")
                            .attr("class","innerPath")
                            .attr("d", arcInner )
                            .style("fill", function(d) { return color20(d.source.index); });


        gOuter.selectAll(".outerPath")
            .on("mouseover",fade(0.0))      //鼠標放到節點上
            .on("mouseout",fade(1.0));      //鼠標從節點上移開

        function fade(opacity){
            //返回一個function(g, i)
            return function(g,i){

                gInner.selectAll(".innerPath")  //選擇所有的弦
                        .filter( function(d) {  //過濾器
                            //沒有連接到鼠標所在節點的弦才能通過
                            return d.source.index != i && d.target.index != i; 
                        })
                        .transition()   //過渡
                        .style("opacity", opacity); //透明度
            }

        }

效果圖:
這裏寫圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章