[原创]SVG柱状图[histogram]代码生成器 
2008/11/15 23:29:16
阅读全文(7306) | 回复(6) | 编辑 | 精华
迟到的文章,其实早在9月中旬已经完成,只是忙于复习迎考,忘记贴到BLOG上了,今天翻阅U盘上的旧代码,发现本代码还没有贴上,补上。 自定义半径、颜色功能暂还没有来得及去实现,感兴趣的朋友可以补上去。 效果图:500)this.width=500'> SVG源码:500)this.width=500'>柱状图.rar <?xml version="1.0" encoding="utf-8"?><DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><!--****************************************作者:Qr(原创作品)博客:http://Qr.blogger.org.cn时间:09/18/2008功能:javascript生成SVG柱状图代码(自定义半径、颜色功能暂还没有来得及去实现)****************************************--><html xmlns="http://www.w3.org/1999/xhtml" lang="utf-8"> <head> <title>SVG柱状图[histogram]代码生成器</title> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <script type="text/javascript"> function Histogram(data){ if(data==""){ alert("请输入数据!"); document.getElementById("data").focus(); return; } var width = 1024; var height = 500; var data = data.split(","); var len = data.length; var maxVal = 0; var sumVal = 0; for(var i=0;i<len;i++){ data[i] = parseInt(data[i]); maxVal = (maxVal > data[i])?maxVal:data[i]; sumVal += data[i]; } var multiple = height/maxVal; var radius = width/(len*2+1); var str = ""; for(var i=0;i<len;i++){ R = Math.round(Math.random()*255); G = Math.round(Math.random()*255); B = Math.round(Math.random()*255); fill = "rgb(" + R + "," + G + "," + B + ")"; str += "\t\t\<g fill=\""+fill+"\"\>\n"; str += "\t\t\t\<rect x=\"" + (radius + (width - len*radius*2)/2 + i*radius*2) + "\" y=\"" + (height/2 + maxVal/2*multiple - data[i]*multiple + 50) + "\" width=\""+ radius + "\" height=\"" +data[i]*multiple+ "\" fill=\"" + fill + "\"/>\n"; str += "\t\t\t\<text x=\"" + (radius*1.25 + (width - len*radius*2)/2 + i*radius*2) + "\" y=\"" + (height/2 + maxVal/2*multiple - data[i]*multiple + 45) + "\">"+Math.round((data[i]/sumVal)*10000)/100+"%"+"\<\/text\>\n"; str += "\t\t\t\<text x=\"" + (radius*1.5 + (width - len*radius*2)/2 + i*radius*2) + "\" y=\"" + 570 + "\" text-anchor=\"middle\"\>"+data[i]+"\<\/text\>\n"; str += "\t\t\t\<path d=\"M " + (radius + (width - len*radius*2)/2 + i*radius*2) + " " + (height/2 + maxVal/2*multiple - data[i]*multiple + 50) +" L "+ (radius + (width - len*radius*2)/2 + i*radius*2 + radius) +" "+ (height/2 + maxVal/2*multiple - data[i]*multiple + 50) +" L "+(radius + (width - len*radius*2)/2 + i*radius*2 + radius) +" "+ 570 +" L "+ (radius + (width - len*radius*2)/2 + i*radius*2) +" "+570+" Z\" fill=\"url(#cylinder)\" stroke-width=\"0\" \/\>\n"; str += "\t\t\<\/g\>\n"; } var headstr = "\<?xml version=\"1.0\" encoding=\"UTF-8\"?\>\n"; headstr += "\<svg\n"; headstr += " xmlns\:svg=\"http\:\/\/www.w3.org\/2000\/svg\"\n"; headstr += " xmlns=\"http\:\/\/www.w3.org\/2000\/svg\"\n"; headstr += " xmlns\:xlink=\"http\:\/\/www.w3.org\/1999\/xlink\"\n"; headstr += " xml\:space=\"default\"\n"; headstr += " version=\"1.1\"\n"; headstr += " width=\"100%\"\n"; headstr += " height=\"100%\" viewBox=\"0 0 1024 600\"\>\n"; headstr += " \<defs\>\n"; headstr += "\t\t\<linearGradient id=\"background\" x1=\"0\" y1=\"1\" x2=\"0\" y2=\"0\"\>\n"; headstr += "\t\t\t\<stop offset=\"0\" stop-color=\"white\"/>\n"; headstr += "\t\t\t\<stop offset=\"1\" stop-color=\"blue\"\/\>\n"; headstr += "\t\t\<\/linearGradient\>\n"; headstr += "\t\t\<linearGradient id=\"cylinder\" gradientUnits=\"objectBoundingBox\"\>\n"; headstr += "\t\t\t\<stop offset=\"0%\" stop-color=\"white\" stop-opacity=\"0.3\"\/\>\n"; headstr += "\t\t\t\<stop offset=\"10%\" stop-color=\"white\" stop-opacity=\"0.1\"\/\>\n"; headstr += "\t\t\t\<stop offset=\"20%\" stop-color=\"white\" stop-opacity=\"0.2\"\/\>\n"; headstr += "\t\t\t\<stop offset=\"30%\" stop-color=\"white\" stop-opacity=\"0.5\"\/\>\n"; headstr += "\t\t\t\<stop offset=\"50%\" stop-color=\"white\" stop-opacity=\"0.2\"\/\>\n"; headstr += "\t\t\t\<stop offset=\"100%\" stop-color=\"white\" stop-opacity=\"0\"\/\>\n"; headstr += "\t\t\</linearGradient\>\n"; headstr += " \<\/defs\>\n"; headstr += "\t\<g stroke-width=\"0\" stroke=\"black\"\>\n"; headstr += "\t\t\<rect x=\"10\" y=\"10\" width=\"1004\" height=\"580\" fill=\"url(#background)\" stroke-width=\"2\" stroke=\"gray\"\/\>\n"; var footstr = "\t\<\/g\>\n\<\/svg\>"; document.getElementById("code").value=headstr+str+footstr; } </script> </head><body><h1 style="color:#e00">SVG柱状图[histogram]代码生成器</h1><div>半径:<input id="radius" width="25px"/></div><div>颜色:<textarea id="color" style="width:600px;height:23px"></textarea></div><div>数据:<textarea id="data" style="width:600px;height:23px">135,55,60,100,80,90,30,80</textarea></div><input type="button" value="Histogram" onclick="javascript :Histogram(data.value)"/><textarea id="code" style="width:100%;height:50%"></textarea></body></html>
Posted by Qr on 2008/11/15 23:29:16
回复:[原创]SVG柱状图[histogram]代码生成器
2008/11/25 10:15:57
个人主页 | 引用回复 | 主人回复 | 返回 | 编辑 | 删除
其实我觉得svg和vml比起服务器端直接生成图片输出最大的区别就是它们可以有脚本交互,假如只是单纯的图表没交互的大可以用画图类直接输出 以下为blog主人的回复: 遗憾的是,SVG不支持FORM,所以无法直接与SVG交互,而是以HTML方式进行交互,然后重写或改写SVG。
Posted by Kinogam on 2008/11/25 10:15:57
回复:[原创]SVG柱状图[histogram]代码生成器
2008/11/23 16:54:23
个人主页 | 引用回复 | 主人回复 | 返回 | 编辑 | 删除
关于vml和svg我们可以找个xml直接转换成SVG或者VML的xslt模板,之后xml从服务器段直接response出来的时候判断下客户端是什么,我们就采取那个转换的模板,这样我们只需要考虑图形方面的东西就ok了 以下为blog主人的回复: vml已经走向衰落,更何况Silverlight已经成为MS的主打产品,vml就不考虑那么多了。
Posted by Kinogam on 2008/11/23 16:54:23
回复:[原创]SVG柱状图[histogram]代码生成器
2008/11/21 13:05:52
个人主页 | 引用回复 | 主人回复 | 返回 | 编辑 | 删除
我是计算所有数值的最大和最小值的“最前2位的差”,根据这个差值来判断到底怎么设置刻度,或者你可以看下excel2007的图表,那个好像是vml做的 以下为blog主人的回复: 最大和最小值的“最前2位的差”?有创意,也很有道理,值得参考,改天偶试试看。 VML偶写过,好象是MS的东东,只有IE和MS的产品支持,而且开发难度比SVG大多了,不爽。
Posted by Kinogam on 2008/11/21 13:05:52
回复:[原创]SVG柱状图[histogram]代码生成器
2008/11/21 13:03:36
个人主页 | 引用回复 | 主人回复 | 返回 | 编辑 | 删除
我也不太清楚为什么…… 我现在没怎么关注blog了……
Posted by Kinogam on 2008/11/21 13:03:36
回复:[原创]SVG柱状图[histogram]代码生成器
2008/11/18 12:09:28
个人主页 | 引用回复 | 主人回复 | 返回 | 编辑 | 删除
是的,用最大值做轴的max值。如果不用最大值,不好计算比例,这样就加大了编程的难度,甚至影响美观。你有什么好的做法,贴出来交流一下,让偶也学两招
Posted by Qr on 2008/11/18 12:09:28
回复:[原创]SVG柱状图[histogram]代码生成器
2008/11/17 10:14:58
个人主页 | 引用回复 | 主人回复 | 返回 | 编辑 | 删除
其实我觉得轴线的算法也挺复杂的,我最初的时候做就是仿照excel的图表做的。你这里是用数据的最大值做轴的max吧,我觉得这样不够美观,有时候还考虑到数值相差的问题。 以下为blog主人的回复: 你的BLOG偶不能回复也不能留言。
Posted by Kinogam on 2008/11/17 10:14:58
发表评论: |