剛用svg,感覺是挺方便的。雖然有些功能有待最佳化,但是一般的向量圖,它是足夠了。下面樣本繪圖的一則小程式
瀏覽器中直接存取test.svg即可
1.test.svg
<?xml version="1.0" encoding="UTF-8"?><svg width="100%" height="100%" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" onload = "init(evt)"><script type="text/javascript" xlink:href="test.js"></script></svg>
2.test.js的內容
var data = { facebook:{ total:2900, titan:800, fish:600, athena:400, bossv:500, dream:600 }, mixi:{ total:2200, titan:500, fish:400, athena:500, bossv:400, dream:400 }, kaixin:{ total:1900, titan:300, fish:400, athena:400, bossv:400, dream:400 }, renren:{ total:2300, titan:300, fish:400, athena:600, bossv:600, dream:400 }, netlog:{ total:2100, titan:300, fish:400, athena:500, bossv:500, dream:400 }, minik:{ total:1900, titan:300, fish:400, athena:500, bossv:300, dream:400 }, daum:{ total:1400, titan:300, fish:400, athena:600, bossv:500, dream:400 }, tencent:{ total:1900, titan:300, fish:400, athena:300, bossv:500, dream:400 }};var color = { facebook:{ stroke: "red", filledColor: "red" }, mixi:{ stroke: "#FF9FFF", filledColor: "#FF9FFF" }, kaixin:{ stroke: "#FFBF02", filledColor: "#FFBF02" }, renren:{ stroke: "#836FFF", filledColor: "#836FFF" }, netlog:{ stroke: "#48D1CC", filledColor: "#48D1CC" }, minik:{ stroke: "#00CED1", filledColor: "#00CED1" }, daum:{ stroke: "#008B00", filledColor: "#008B00" }, tencent:{ stroke: "#A4D3EE", filledColor: "#A4D3EE" }};var svgns = "http://www.w3.org/2000/svg";/* *根據相應的支付額,擷取應該顯示的圓的半徑大小 */function getRadius(payment){ var pay = parseInt(payment); return parseInt(Math.sqrt(pay));//待修改}function getMax(json){ var max = 0; for( var val in json ){ if(val > max){ max = val; } } return max;}var svgDocument;function getXY(preXY,space,radius,maxRadius){ return preXY + space * 2 + radius + maxRadius;}/* draw svg cicle and append it to the svgDom */function drawCircle(evt,rx,ry,radius,stroke,filledColor){ if ( window.svgDocument == null ){ svgDocument = evt.target.ownerDocument; } var shape = svgDocument.createElementNS(svgns, "circle"); shape.setAttributeNS(null,"cx",rx); shape.setAttributeNS(null,"cy",ry); shape.setAttributeNS(null,"r",radius); shape.setAttributeNS(null,"stroke",stroke); shape.setAttributeNS(null,"fill",filledColor); svgDocument.documentElement.appendChild(shape);}/* draw svg line and append it to the svgDom */function drawLine(evt,srcX,srcY,disX,disY,stroke){ if ( window.svgDocument == null ){ svgDocument = evt.target.ownerDocument; } var shape = svgDocument.createElementNS(svgns, "line"); shape.setAttributeNS(null,"x1",srcX); shape.setAttributeNS(null,"y1",srcY); shape.setAttributeNS(null,"x2",disX); shape.setAttributeNS(null,"y2",disY); shape.setAttributeNS(null,"stroke",stroke); svgDocument.documentElement.appendChild(shape);}/* draw svg textNode and append it to the svgDom */function drawText(evt,rx,ry,radius,content){ var fontSize = getFontSize(radius); if ( window.svgDocument == null ){ svgDocument = evt.target.ownerDocument; } var shape = svgDocument.createElementNS(svgns, "text"); shape.setAttributeNS(null,"x",rx); shape.setAttributeNS(null,"y",ry); //shape.setAttributeNS(null,"font-size",fontSize); shape.textContent = content; svgDocument.documentElement.appendChild(shape);}/* * 根據半徑和最大外圍半徑以及空隙space。求出可用的座標。為均勻分配,這裡採用平均分配的方式。 * result = [{"x":10,y:20},{"x":40,y:60},{"x":70,y:80},{"x":40,y:60}]; * */function getCorFromRadius(rx,ry,radius,space,maxRadius,sum){ var result = new Array(); var r = radius + space + maxRadius;//外部圓的最大半徑 var y0 = ry - r; result.push({"x":rx,"y":y0}); var step = (360/sum) * Math.PI /180;//弧度 var start = step; for(var i = 0;i < sum - 1;i++){ var rxi = parseInt(rx + r * Math.sin(start)); var ryi = parseInt(ry - r * Math.cos(start)); result.push({"x":rxi,"y":ryi}); start += step; } return result;} /* *根據半徑擷取相應的字型大小,待最佳化。 * */function getFontSize(radius){ return parseInt(radius/2);}/* draw the total platform Map circly */function drawPlatformCircle(evt,platCount,gameCount){ var rx = 900; var ry = 450; var radius0 = 200; var space = 30; var max0 = 70; var res = getCorFromRadius(rx, ry, radius0, space, max0, platCount); var i = 0; for(var platform in data){ var rx0 = res[i].x; var ry0 = res[i].y; var max = getMax(data[platform]); var stroke = color[platform].stroke; var filledColor = color[platform].filledColor; var radius = getRadius(data[platform].total);//平台圓半徑 drawCircle(evt,rx0, ry0, radius, stroke, filledColor); var j = 0; for (var obj in data[platform]) { if (obj != "total") { var rest = getCorFromRadius(rx0, ry0, radius, space, max, gameCount); var outerX = rest[j].x; var outerY = rest[j].y; var outerRadius = getRadius(data[platform][obj]); drawCircle(evt,outerX, outerY, outerRadius, stroke, filledColor); drawLine(evt,rx0,ry0,outerX,outerY,stroke); drawText(evt,outerX - outerRadius/2, outerY, outerRadius, obj); j++; } } drawText(evt,rx0 - radius/2, ry0, radius, platform); i++; }}/* draw the total platform Map in line */function drawLinePlatform(evt){ var rightIndex = 80; var top = 50; var space = 40; var count = 0; var maxTotalGame = 5; for( var platform in data ){ count ++; var stroke = color[platform].stroke; var filledColor = color[platform].filledColor; var max = getMax(data[platform]); var radius = getRadius(data[platform].total);//平台圓半徑 var rx = getXY(rightIndex,space,radius,max);//平台圓x軸座標 var ry = getXY(top,space,radius,max);//平台圓y軸座標 drawCircle(evt,rx,ry,radius,stroke,filledColor); var j = 0; for(var obj in data[platform]){ if(obj != "total"){ var res = getCorFromRadius(rx,ry,radius,space,max,maxTotalGame); var outerX = res[j].x; var outerY = res[j].y; var outerRadius = getRadius(data[platform][obj]); drawLine(evt,rx,ry,outerX,outerY,stroke); drawCircle(evt,outerX,outerY,outerRadius,stroke,filledColor); drawText(evt,outerX - outerRadius/2,outerY,outerRadius,obj); j++; } } drawText(evt,rx - radius/2,ry,radius,platform); rightIndex = (rx + radius + space * 2 + max); if(count % 5 == 0){ rightIndex = 120; top = (ry + radius + space + max)+50;//TODO:這個有問題,沒有考慮本身的高度 } }}function init(evt){ drawPlatformCircle(evt,8,5);}
產生的: