【應用】SVG餅狀圖


<!DOCTYPE html>
<html>
<head>
    <title></title>
</head>
<body onload="document.body.appendChild(
    pieChart([12,23,34,45],640,400,200,200,150,
    ['red','blue','yellow','green'],
    ['North','South','East','West'],400,100)
)">
<script>
    /*創建一個<svg>元素,並在其中繪制一個餅狀圖
    * 參數
    *   data:用於繪制的數字類型的數組,數組每一項都有表示餅狀圖的一個
    *   width,height:SVG圖形的大小,單位像素
    *   cx,cy,r:餅狀圖的圓心及半徑
    *   colors:一個包含HTML顏色信息的數組,每種顏色代表餅狀圖每個楔的顏色
    *   lables一個標簽數組,該信息說明餅狀圖中每個楔代表的含義
    *   lx,ly:餅狀圖的左上角
    * 返回:
    *   一個保存餅狀圖的<svg>元素
    *   調用者必須返回的元素插入到文檔中
    *   */
    function pieChart(data,width,height,cx,cy,r,colors,labels,lx,ly){
        //這個表示svg元素的xml命名空間
        var svgns="http://www.w3.org/2000/svg";

        //創建一個<svg>元素,同時指定像素大小和用戶坐標
        var chart=document.createElementNS(svgns,"svg:svg");
        chart.setAttribute("width",width);
        chart.setAttribute("height",height);
        chart.setAttribute("viewBox","0 0 "+width+" "+height);

        //累加data值,以便於知道餅狀圖的大小
        var total=0;
        for(var i=0;i<data.length;i++){
            total+=data[i];
        }

        //現在計算出餅狀圖每個分片的大小,其中角度以弧度制計算
        var angles=[];
        for(var i=0;i<data.length;i++)
            angles[i]=data[i]/total*Math.PI*2;


        //遍歷病狀圖的每個分片
        starttangle=0;
        for(var i=0;i<data.length;i++){
            //這里表示楔的結束為止
            var endangle=starttangle+angles[i];

            //計算出楔和園橡膠的兩個點
            //這些計算公式都是以12點鍾方向為0°
            //順時針方向角度遞增
            var x1=cx+r*Math.sin(starttangle);
            var y1=cy-r*Math.cos(starttangle);
            var x2=cx+r*Math.sin(endangle);
            var y2=cy-r*Math.cos(endangle);

            //這個標記表示角度大於半圓
            //此標記在繪制SBG弧形組件的時候需要
            var big=0;
            if(endangle-starttangle>Math.PI) big=1;

            //使用<svg:path>元素來描述楔
            //要注意的是,使用ctreateElementNS()來創建該元素
            var path=document.createElementNS(svgns,"path");

            //下面的字符串包含路徑的詳細信息
            var d="M "+cx+","+cy+ //從圓心開始
                " L "+x1+","+y1+   //畫一條到(x1,y1)的線段
                " A "+r+","+r+     //再畫一條半徑為r的弧
                " 0 "+big+" 1 "+    // 弧的詳細信息
                x2+","+y2+    //弧到(x2,y2)結束
                " Z";   //d當前路徑到(cx,cy)結束

            //設置<svg:path>元素的屬性
            path.setAttribute("d",d);   //設置路徑
            path.setAttribute("fill",colors[i]); //設置楔的顏色
            path.setAttribute("stroke","black");  //楔的外邊框為黑色
            path.setAttribute("stroke-width","2"); //兩個單位
            chart.appendChild(path); //將楔加入到餅狀圖中

            //當前楔的結束就是下一個楔的開始
            starttangle=endangle;

            //繪制小方塊表示圖例
            var icon=document.createElementNS(svgns,"rect");
            icon.setAttribute("x",lx);  //定位小方塊
            icon.setAttribute("y",ly+30*i);
            icon.setAttribute("width",20);
            icon.setAttribute("height",20);
            icon.setAttribute("fill",colors[i]); //填充小方塊顏色和對應楔的顏色也相同
            icon.setAttribute("stroke","black");  //子外邊框顏色也相同
            icon.setAttribute("stroke-width","2");
            chart.appendChild(icon);

            //在小方塊的右邊添加標簽
            var label=document.createElementNS(svgns,"text");
            label.setAttribute("x",lx+30); //定位標簽文本
            label.setAttribute("y",ly+30*i+18);
            label.setAttribute("font-family","sans-serif");
            label.setAttribute("font-size","16");
            label.appendChild(document.createTextNode(labels[i]));
            chart.appendChild(label); //將文本添加到餅狀圖
        }
        return chart;
    }

</script>
</body>
</html>

效果:


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM