在一个小应用中,要用图标的方式表示房间内的人数,基本的想法是用三角形表示房间内有三人,四边形表示房间内有四人,依此类推。用d3.js结合svg来实现图标的绘制功能。
图形效果
html文件
drawIcon.html
<!DOCTYPE html>
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
<head>
<title>绘制房间图标</title>
<script src="d3.v3.min.js" charset="utf-8"></script>
</head>
<body>
<h2>绘制房间图标</h2>
<div id="stage" width="800" height="800"></div>
<script type="text/javascript">
// 设置svg
var svg = d3.select("#stage").append("svg")
.attr("width", 800)
.attr("height", 800);
//绘制房间图标
var myRooms = svg.selectAll(".roomIcon")
//.data([16,15,14,13,12,11,10,9,8,7,6,5,4,3])
.data([{cx:100,cy:100,r:80,n:1},{cx:300,cy:100,r:80,n:2},{cx:500,cy:100,r:80,n:3},{cx:700,cy:100,r:80,n:4},
{cx:100,cy:300,r:80,n:5},{cx:300,cy:300,r:80,n:6},{cx:500,cy:300,r:80,n:7},{cx:700,cy:300,r:80,n:8}])
.enter()
.append("g");
//画代表房间人数的多边形
myRooms.append("polygon")
.attr("points", function (d, i) { return polygonPoints(d.cx,d.cy,d.r,d.n); } )
.style("fill", "lime")
.style("stroke", "purple")
.style("stroke-width", "2");
//房间人数为3的向下移动,与其它图标底边对齐
myRooms.filter(function(d,i){return d.n==3;})
.attr("transform", function (d, i) { return "translate(0,"+d.r*0.2+")"; })
//房间人数为2或4的加画一条垂线
myRooms.filter(function(d,i){return d.n==2||d.n==4;})
.append("polyline")
.attr("points", function (d, i) { return vLine(d.cx,d.cy,d.r); })
.style("fill", "lime")
.style("stroke", "purple")
.style("stroke-width", "2");
//房间人数为4的加画一条水平线
myRooms.filter(function(d,i){return d.n==4;})
.append("polyline")
.attr("points", function (d, i) { return hLine(d.cx,d.cy,d.r); })
.style("fill", "lime")
.style("stroke", "purple")
.style("stroke-width", "2");
/*
*圆内接正多边形的顶点坐标串,形如x1,y1,x2,y2,...xn,yn
*cx,cy为圆心,r为半径,n为边数,正多边形底边与X轴平行
*/
function polygonPoints(cx,cy,r,n){
if (n==1||n==2)
n=4;
var alpha=2*Math.PI/n;
var a=Math.PI/2+alpha/2;
var points="";
for(var i=0;i<n;i++){
x=cx+r*Math.cos(a);
y=cy+r*Math.sin(a);
points+=x+","+y+",";
a+=alpha;
}
return points.substring(0,points.length-1);
}
//水平线顶点串
function hLine(cx,cy,r){
r=r*Math.sin(Math.PI/4);
x1=cx-r;
y1=y2=cy;
x2=cx+r;
return x1+","+y1+","+ x2+","+y2;
}
//垂直线顶点串
function vLine(cx,cy,r){
r=r*Math.sin(Math.PI/4);
x1=x2=cx;
y1=cy-r;
y2=cy+r;
return x1+","+y1+","+ x2+","+y2;
}
</script>
</body>
</html>