- 浏览: 125481 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
xiejin2008:
最近1-2年比较流行的树组件 ztree
Dtree+Jquery动态生成树节点例子《新手可参考》 -
xiejin2008:
cyl5753 写道按照上面的步骤,访问https://127 ...
WebLogic Server 10.3 SSL配置及SSL协议传输的WebSevice调用 -
cyl5753:
按照上面的步骤,访问https://127.0.0.1:700 ...
WebLogic Server 10.3 SSL配置及SSL协议传输的WebSevice调用 -
wang1248912822:
[size=large][/size] [b] ...
Ext3.0 动态数据 Chart 初探 -
fushun_test:
很不错,柱状的每个珠子颜色和饼状的每个部分的颜色可以自定义吗 ...
Ext3.0 动态数据 Chart 初探
SVG生成饼图,虽然代码实现,但是感觉太复杂,太耗费时间,还不如用JFreeChart,
但是听同事说,JfreeChart很多Bug,有时候还需要修改它的源代码,哎.网上找打了JfreeChart生成SVG图形方法,当然也作出了个Demo.我对JfreeChart研究不深,同事说道:这个东西,不是一会就能研究出来的,要学好,嘿嘿,也得2年吧.呜呜..
自我感觉没那么难吧,不就是学个他的API呀.慢慢摸索呗.况且开源的这东西,网上资源很多相关的.
网上看到有用JAVA生成SVG线条图的,还有一个是柱状图的.
自己写了个饼图的,感觉实在是麻烦.尤其我在生成饼图的立体效果时候,郁闷了好久.
Jfreechart本身不能生成SVG图形,但是可以借助另外一个东西,辅助生成.好像是这个:batik ,不会用网上用它做关键词,搜下即可
下面分别贴出一些代码:
一、java生成svg饼图.平面的.
package com.xj.svg; import java.io.File; import java.io.FileOutputStream; public class CakySvg { static String[] colors ={ "#f2e692", "#fef195", "#ce9a31", "#22FF22", "#aaffaa", "green", "#799AE1", "#9aabEe", "#3e941b", "#f2e692", "#66cc00", "#297110", "#d6a97b", "#82522b", "#aaaaff", "#ff2222", "#ffaaaa", "#aa1111" }; static String initialize(double [] fenshu){ StringBuffer sfile = new StringBuffer(); sfile.append("<?xml version='1.0' encoding='UTF-8'?>"); sfile.append("\n"); sfile.append("<svg xmlns:svg='http://www.w3.org/2000/svg'"); sfile.append("\n"); sfile.append("xmlns='http://www.w3.org/2000/svg'"); sfile.append("\n"); sfile.append("xmlns:xlink='http://www.w3.org/1999/xlink'"); sfile.append("\n"); sfile.append("xml:space='default'"); sfile.append("\n"); sfile.append("version='1.1' width='100%' height='100%' viewBox='0 0 2024 570'>"); sfile.append("\n"); sfile.append("<defs></defs>"); sfile.append("\n"); sfile.append("<g stroke-width='1' stroke='#FFFFFF' transform='matrix(1,0,0,1,16.384,-9.83)' xmlns='http://www.w3.org/2000/svg'>"); sfile.append("\n"); //循环创造path标签. String path =creatPath(502, 300, 300, fenshu); sfile.append(path); sfile.append("</g>"); sfile.append("\n"); sfile.append("</svg>"); return sfile.toString(); } public static String creatPath(double x0,double y0,double r,double[]fenshu){ StringBuffer sfile =new StringBuffer(); double x1=0; double y1=0; double middleX= 0; double middleY=0; double radian =0; double textRadian=0; double k=0; for(int i=0;i<fenshu.length;i++){ if(i==0){ radian =getRadian(fenshu[0]); textRadian=radian/2; x1 = (x0+getCos(radian)*r); y1 = (y0-getSin(radian)*r); middleX=(x0+getCos(textRadian)*r); middleY=(y0-getSin(textRadian)*r); double percent = Math.round(fenshu[0]*100)/100.0; k=Math.abs((middleY-y0)/(middleX-x0)); double sita= Math.atan(k); double lineLen=50; double textLen=70; if(radian<6){ lineLen=90; textLen=110; } if((textRadian<(Math.PI/2))){ sfile.append("<line x1='"+middleX+"' y1='"+middleY+"' x2='"+(middleX+Math.cos(sita)*lineLen)+"' y2='"+(middleY-(Math.sin(sita)*lineLen))+"' stroke='#000000'/>"); sfile.append("\n"); sfile.append("<text x='"+(middleX+Math.cos(sita)*textLen)+"' y='"+(middleY-(Math.sin(sita)*textLen))+"' space='preserve' font-family='Tahoma' font-size='21' fill='red' stroke='red' baseline-shift='baseline' >"+percent+"%</text>"); }else if ((textRadian>(Math.PI/2)&&textRadian<Math.PI)){ sfile.append("<line x1='"+middleX+"' y1='"+middleY+"' x2='"+(middleX-Math.cos(sita)*lineLen)+"' y2='"+(middleY-(Math.sin(sita)*lineLen))+"' stroke='#000000'/>"); sfile.append("\n"); sfile.append("<text x='"+(middleX-Math.cos(sita)*textLen)+"' y='"+(middleY-(Math.sin(sita)*textLen))+"' space='preserve' font-family='Tahoma' font-size='21' fill='red' stroke='red' baseline-shift='baseline' >"+percent+"%</text>"); }else if ((textRadian>(Math.PI)&&textRadian<(Math.PI*3/2))){ sfile.append("<line x1='"+middleX+"' y1='"+middleY+"' x2='"+(middleX-Math.cos(sita)*lineLen)+"' y2='"+(middleY+(Math.sin(sita)*lineLen))+"' stroke='#000000'/>"); sfile.append("\n"); sfile.append("<text x='"+(middleX-Math.cos(sita)*textLen)+"' y='"+(middleY+(Math.sin(sita)*textLen))+"' space='preserve' font-family='Tahoma' font-size='21' fill='red' stroke='red' baseline-shift='baseline' >"+percent+"%</text>"); }else if((textRadian>(Math.PI*3/2)&&textRadian<(Math.PI*2))){ sfile.append("<line x1='"+middleX+"' y1='"+middleY+"' x2='"+(middleX+Math.cos(sita)*lineLen)+"' y2='"+(middleY+Math.sin(sita)*lineLen)+"' stroke='#000000'/>"); sfile.append("\n"); sfile.append("<text x='"+(middleX+Math.cos(sita)*textLen)+"' y='"+(middleY+(Math.sin(sita)*textLen))+"' space='preserve' font-family='Tahoma' font-size='21' fill='red' stroke='red' baseline-shift='baseline' >"+percent+"%</text>"); } sfile.append("\n"); if(getRadian(fenshu[0])>Math.PI){ sfile.append("<path d='M "+x0+" "+y0+" L "+(x0+r)+" "+r+" A "+r+" "+r+" 0 1 0 "+x1+" "+y1+" L "+x0+" "+y0+" z' fill='"+colors[0]+"'/>"); }else{ sfile.append("<path d='M "+x0+" "+y0+" L "+(x0+r)+" "+r+" A "+r+" "+r+" 0 0 0 "+x1+" "+y1+" L "+x0+" "+y0+" z' fill='"+colors[0]+"'/>"); } sfile.append("\n"); }else{ textRadian = radian+(getRadian(fenshu[i])/2); radian =radian+getRadian(fenshu[i]);//弧度. System.out.println("弧度:"+radian); middleX=(x0+getCos(textRadian)*r); middleY=(y0-getSin(textRadian)*r); double percent = Math.round(fenshu[i]*100)/100.0; k=Math.abs((middleY-y0)/(middleX-x0)); double lineLen=50; double textLen=70; if(radian<6){ lineLen=90; textLen=110; } double sita= Math.atan(k); if((textRadian<(Math.PI/2))){ sfile.append("<line x1='"+middleX+"' y1='"+middleY+"' x2='"+(middleX+Math.cos(sita)*lineLen)+"' y2='"+(middleY-(Math.sin(sita)*lineLen))+"' stroke='#000000'/>"); sfile.append("\n"); sfile.append("<text x='"+(middleX+Math.cos(sita)*textLen)+"' y='"+(middleY-(Math.sin(sita)*textLen))+"' space='preserve' font-family='Tahoma' font-size='21' fill='red' stroke='red' baseline-shift='baseline' >"+percent+"%</text>"); }else if ((textRadian>(Math.PI/2)&&textRadian<Math.PI)){ sfile.append("<line x1='"+middleX+"' y1='"+middleY+"' x2='"+(middleX-Math.cos(sita)*lineLen)+"' y2='"+(middleY-(Math.sin(sita)*lineLen))+"' stroke='#000000'/>"); sfile.append("\n"); sfile.append("<text x='"+(middleX-Math.cos(sita)*textLen)+"' y='"+(middleY-(Math.sin(sita)*textLen))+"' space='preserve' font-family='Tahoma' font-size='21' fill='red' stroke='red' baseline-shift='baseline' >"+percent+"%</text>"); }else if ((textRadian>(Math.PI)&&textRadian<(Math.PI*3/2))){ sfile.append("<line x1='"+middleX+"' y1='"+middleY+"' x2='"+(middleX-Math.cos(sita)*lineLen)+"' y2='"+(middleY+(Math.sin(sita)*lineLen))+"' stroke='#000000'/>"); sfile.append("\n"); sfile.append("<text x='"+(middleX-Math.cos(sita)*textLen)+"' y='"+(middleY+(Math.sin(sita)*textLen))+"' space='preserve' font-family='Tahoma' font-size='21' fill='red' stroke='red' baseline-shift='baseline' >"+percent+"%</text>"); }else if((textRadian>(Math.PI*3/2)&&textRadian<(Math.PI*2))){ sfile.append("<line x1='"+middleX+"' y1='"+middleY+"' x2='"+(middleX+Math.cos(sita)*lineLen)+"' y2='"+(middleY+Math.sin(sita)*lineLen)+"' stroke='#000000'/>"); sfile.append("\n"); sfile.append("<text x='"+(middleX+Math.cos(sita)*textLen)+"' y='"+(middleY+(Math.sin(sita)*textLen))+"' space='preserve' font-family='Tahoma' font-size='21' fill='red' stroke='red' baseline-shift='baseline' >"+percent+"%</text>"); } sfile.append("\n"); // 参数 1 表示 画大于180的弧, 0 表示画小于180的弧 if(getRadian(fenshu[i])>Math.PI){ sfile.append("<path d='M "+x0+" "+y0+" L "+x1+" "+y1+" A "+r+" "+r+" 0 1 0 "+(x1=x0+getCos(radian)*r)+" "+(y1=y0-getSin(radian)*r)+" L "+x0+" "+y0+" z' fill='"+colors[i]+"'/>"); }else{ sfile.append("<path d='M "+x0+" "+y0+" L "+x1+" "+y1+" A "+r+" "+r+" 0 0 0 "+(x1=x0+getCos(radian)*r)+" "+(y1=y0-getSin(radian)*r)+" L "+x0+" "+y0+" z' fill='"+colors[i]+"'/>"); } sfile.append("\n"); } } return sfile.toString(); } //返回弧度 public static double getRadian(double fenshu){ return (fenshu*Math.PI)/50; } //返回正弦 public static double getSin(double radian){ return Math.sin(radian); } //返回余弦 public static double getCos(double radian){ return Math.cos(radian); } public static void main(String[] args) { double[] data= {1000,320,410,200,990,430,400,300,340,423,243,200,430,210}; create(data); } private static void create(double[] data) { try { createSVG("f:/a.svg",getPercent(data)); } catch (Exception e) { e.printStackTrace(); } } private static double[] getPercent(double data[]){ double sum=0; double percents[] = new double[data.length]; for(int i=0;i<data.length;i++){ sum+=data[i]; } for(int i=0;i<data.length;i++){ percents[i] =(data[i]/sum)*100; } return percents; } public static void createSVG(String fileRealPath, double[] percents) throws Exception { String sFile = initialize(percents); try { byte[] byteFil = sFile.getBytes("UTF-8"); File svgFile = new File(fileRealPath); if (svgFile.exists()) { svgFile.delete(); } FileOutputStream fos = new FileOutputStream(svgFile); fos.write(byteFil); fos.close(); } catch (Exception ex) { System.out.print(ex.getMessage()); } } }
二、java生成SVG,附带了一个javascript效果.
package com.xj.svg; import java.io.File; import java.io.FileOutputStream; public class CakySvgWithJavaScript { static String[] colors ={"#f2e692", "#fef195", "#ce9a31", "#22FF22", "#aaffaa", "green", "#799AE1", "#9aabEe", "#3e941b", "#f2e692", "#66cc00", "#297110", "#d6a97b", "#82522b", "#aaaaff", "#1111aa", "#ff2222", "#ffaaaa", "#aa1111" }; static String initialize(double [] fenshu){ StringBuffer sfile = new StringBuffer(); sfile.append("<?xml version='1.0' encoding='UTF-8'?>"); sfile.append("\n"); sfile.append("<svg xmlns:svg='http://www.w3.org/2000/svg'"); sfile.append("\n"); sfile.append("xmlns='http://www.w3.org/2000/svg'"); sfile.append("\n"); sfile.append("xmlns:xlink='http://www.w3.org/1999/xlink'"); sfile.append("\n"); sfile.append("xml:space='default'"); sfile.append("\n"); sfile.append("version='1.1' width='100%' height='100%' viewBox='0 0 2024 570'>"); sfile.append("\n"); sfile.append("<defs>"); sfile.append("<script type='text/javascript'>"); sfile.append("function ccolor(evt){"); sfile.append("evt.target.setAttribute('fill', 'white');"); sfile.append("}"); sfile.append("function bcolor(evt,color){evt.target.setAttribute('fill',color);}"); sfile.append("</script>"); sfile.append("</defs>"); sfile.append("\n"); sfile.append("<g stroke-width='1' stroke='#FFFFFF' transform='matrix(1,0,0,1,16.384,-9.83)' xmlns='http://www.w3.org/2000/svg'>"); sfile.append("\n"); //循环创造path标签. String path =creatPath(502, 300, 300, fenshu); sfile.append(path); sfile.append("</g>"); sfile.append("\n"); sfile.append("</svg>"); return sfile.toString(); } public static String creatPath(double x0,double y0,double r,double[]fenshu){ StringBuffer sfile =new StringBuffer(); String s="\""; double x1=0; double y1=0; double middleX= 0; double middleY=0; double radian =0; double textRadian=0; double k=0; for(int i=0;i<fenshu.length;i++){ if(i==0){ radian =getRadian(fenshu[0]); textRadian=radian/2; x1 = (x0+getCos(radian)*r); y1 = (y0-getSin(radian)*r); middleX=(x0+getCos(textRadian)*r); middleY=(y0-getSin(textRadian)*r); double percent = Math.round(fenshu[0]*100)/100.0; k=Math.abs((middleY-y0)/(middleX-x0)); double sita= Math.atan(k); double lineLen=50; double textLen=70; if(radian<6){ lineLen=90; textLen=110; } if((textRadian<(Math.PI/2))){ sfile.append("<line x1='"+middleX+"' y1='"+middleY+"' x2='"+(middleX+Math.cos(sita)*lineLen)+"' y2='"+(middleY-(Math.sin(sita)*lineLen))+"' stroke='#000000'/>"); sfile.append("\n"); sfile.append("<text x='"+(middleX+Math.cos(sita)*textLen)+"' y='"+(middleY-(Math.sin(sita)*textLen))+"' space='preserve' font-family='Tahoma' font-size='21' fill='red' stroke='red' baseline-shift='baseline' >"+percent+"%</text>"); }else if ((textRadian>(Math.PI/2)&&textRadian<Math.PI)){ sfile.append("<line x1='"+middleX+"' y1='"+middleY+"' x2='"+(middleX-Math.cos(sita)*lineLen)+"' y2='"+(middleY-(Math.sin(sita)*lineLen))+"' stroke='#000000'/>"); sfile.append("\n"); sfile.append("<text x='"+(middleX-Math.cos(sita)*textLen)+"' y='"+(middleY-(Math.sin(sita)*textLen))+"' space='preserve' font-family='Tahoma' font-size='21' fill='red' stroke='red' baseline-shift='baseline' >"+percent+"%</text>"); }else if ((textRadian>(Math.PI)&&textRadian<(Math.PI*3/2))){ sfile.append("<line x1='"+middleX+"' y1='"+middleY+"' x2='"+(middleX-Math.cos(sita)*lineLen)+"' y2='"+(middleY+(Math.sin(sita)*lineLen))+"' stroke='#000000'/>"); sfile.append("\n"); sfile.append("<text x='"+(middleX-Math.cos(sita)*textLen)+"' y='"+(middleY+(Math.sin(sita)*textLen))+"' space='preserve' font-family='Tahoma' font-size='21' fill='red' stroke='red' baseline-shift='baseline' >"+percent+"%</text>"); }else if((textRadian>(Math.PI*3/2)&&textRadian<(Math.PI*2))){ sfile.append("<line x1='"+middleX+"' y1='"+middleY+"' x2='"+(middleX+Math.cos(sita)*lineLen)+"' y2='"+(middleY+Math.sin(sita)*lineLen)+"' stroke='#000000'/>"); sfile.append("\n"); sfile.append("<text x='"+(middleX+Math.cos(sita)*textLen)+"' y='"+(middleY+(Math.sin(sita)*textLen))+"' space='preserve' font-family='Tahoma' font-size='21' fill='red' stroke='red' baseline-shift='baseline' >"+percent+"%</text>"); } sfile.append("\n"); if(getRadian(fenshu[0])>Math.PI){ sfile.append("<path d='M "+x0+" "+y0+" L "+(x0+r)+" "+r+" A "+r+" "+r+" 0 1 0 "+x1+" "+y1+" L "+x0+" "+y0+" z' fill='"+colors[0]+"' onmouseover='ccolor(evt)' onmouseout='bcolor(evt,"+s+colors[0]+s+")' />"); }else{ sfile.append("<path d='M "+x0+" "+y0+" L "+(x0+r)+" "+r+" A "+r+" "+r+" 0 0 0 "+x1+" "+y1+" L "+x0+" "+y0+" z' fill='"+colors[0]+"' onmouseover='ccolor(evt)' onmouseout='bcolor(evt,"+s+colors[0]+s+")' />"); } sfile.append("\n"); }else{ textRadian = radian+(getRadian(fenshu[i])/2); radian =radian+getRadian(fenshu[i]);//弧度. System.out.println("弧度:"+radian); middleX=(x0+getCos(textRadian)*r); middleY=(y0-getSin(textRadian)*r); double percent = Math.round(fenshu[i]*100)/100.0; k=Math.abs((middleY-y0)/(middleX-x0)); double lineLen=50; double textLen=70; if(radian<6){ lineLen=90; textLen=110; } double sita= Math.atan(k); if((textRadian<(Math.PI/2))){ sfile.append("<line x1='"+middleX+"' y1='"+middleY+"' x2='"+(middleX+Math.cos(sita)*lineLen)+"' y2='"+(middleY-(Math.sin(sita)*lineLen))+"' stroke='#000000'/>"); sfile.append("\n"); sfile.append("<text x='"+(middleX+Math.cos(sita)*textLen)+"' y='"+(middleY-(Math.sin(sita)*textLen))+"' space='preserve' font-family='Tahoma' font-size='21' fill='red' stroke='red' baseline-shift='baseline' >"+percent+"%</text>"); }else if ((textRadian>(Math.PI/2)&&textRadian<Math.PI)){ sfile.append("<line x1='"+middleX+"' y1='"+middleY+"' x2='"+(middleX-Math.cos(sita)*lineLen)+"' y2='"+(middleY-(Math.sin(sita)*lineLen))+"' stroke='#000000'/>"); sfile.append("\n"); sfile.append("<text x='"+(middleX-Math.cos(sita)*textLen)+"' y='"+(middleY-(Math.sin(sita)*textLen))+"' space='preserve' font-family='Tahoma' font-size='21' fill='red' stroke='red' baseline-shift='baseline' >"+percent+"%</text>"); }else if ((textRadian>(Math.PI)&&textRadian<(Math.PI*3/2))){ sfile.append("<line x1='"+middleX+"' y1='"+middleY+"' x2='"+(middleX-Math.cos(sita)*lineLen)+"' y2='"+(middleY+(Math.sin(sita)*lineLen))+"' stroke='#000000'/>"); sfile.append("\n"); sfile.append("<text x='"+(middleX-Math.cos(sita)*textLen)+"' y='"+(middleY+(Math.sin(sita)*textLen))+"' space='preserve' font-family='Tahoma' font-size='21' fill='red' stroke='red' baseline-shift='baseline' >"+percent+"%</text>"); }else if((textRadian>(Math.PI*3/2)&&textRadian<(Math.PI*2))){ sfile.append("<line x1='"+middleX+"' y1='"+middleY+"' x2='"+(middleX+Math.cos(sita)*lineLen)+"' y2='"+(middleY+Math.sin(sita)*lineLen)+"' stroke='#000000'/>"); sfile.append("\n"); sfile.append("<text x='"+(middleX+Math.cos(sita)*textLen)+"' y='"+(middleY+(Math.sin(sita)*textLen))+"' space='preserve' font-family='Tahoma' font-size='21' fill='red' stroke='red' baseline-shift='baseline' >"+percent+"%</text>"); } sfile.append("\n"); // 参数 1 表示 画大于180的弧, 0 表示画小于180的弧 if(getRadian(fenshu[i])>Math.PI){ sfile.append("<path d='M "+x0+" "+y0+" L "+x1+" "+y1+" A "+r+" "+r+" 0 1 0 "+(x1=x0+getCos(radian)*r)+" "+(y1=y0-getSin(radian)*r)+" L "+x0+" "+y0+" z' fill='"+colors[i]+"' onmouseover='ccolor(evt)' onmouseout='bcolor(evt,"+s+colors[i]+s+")'/>"); }else{ sfile.append("<path d='M "+x0+" "+y0+" L "+x1+" "+y1+" A "+r+" "+r+" 0 0 0 "+(x1=x0+getCos(radian)*r)+" "+(y1=y0-getSin(radian)*r)+" L "+x0+" "+y0+" z' fill='"+colors[i]+"' onmouseover='ccolor(evt)' onmouseout='bcolor(evt,"+s+colors[i]+s+")'/>"); } sfile.append("\n"); } } return sfile.toString(); } //返回弧度 public static double getRadian(double fenshu){ return (fenshu*Math.PI)/50; } //返回正弦 public static double getSin(double radian){ return Math.sin(radian); } //返回余弦 public static double getCos(double radian){ return Math.cos(radian); } public static void main(String[] args) { double[] data= {1000,320,410,200,990,430,400,300,340,423,243,200,430,210}; create(data); } private static void create(double[] data) { try { createSVG("f:/a.svg",getPercent(data)); } catch (Exception e) { e.printStackTrace(); } } private static double[] getPercent(double data[]){ double sum=0; double percents[] = new double[data.length]; for(int i=0;i<data.length;i++){ sum+=data[i]; } for(int i=0;i<data.length;i++){ percents[i] =(data[i]/sum)*100; } return percents; } public static void createSVG(String fileRealPath, double[] percents) throws Exception { String sFile = initialize(percents); try { byte[] byteFil = sFile.getBytes("UTF-8"); File svgFile = new File(fileRealPath); if (svgFile.exists()) { svgFile.delete(); } FileOutputStream fos = new FileOutputStream(svgFile); fos.write(byteFil); fos.close(); } catch (Exception ex) { System.out.print(ex.getMessage()); } } }
三、Java生成svg饼图,附带了一个标签显示各个颜色代表的部分:
package com.xj.svg; import java.io.File; import java.io.FileOutputStream; /** * * @author 风絮NO.1 * */ public class CakySvgWithLabel { //定义不同的颜色 static String[] colors ={"#f2e692", "#aa1111", "#799AE1", "#3e941b", "#66cc00", "#297110", "#d6a97b", "#82522b", "#aaaaff", "#1111aa", "#ff2222", "#ffaaaa"}; static String initialize(double [] percents,String[]names){ StringBuffer sfile = new StringBuffer(); sfile.append("<?xml version='1.0' encoding='UTF-8'?>"); sfile.append("\n"); sfile.append("<svg xmlns:svg='http://www.w3.org/2000/svg'"); sfile.append("\n"); sfile.append("xmlns='http://www.w3.org/2000/svg'"); sfile.append("\n"); sfile.append("xmlns:xlink='http://www.w3.org/1999/xlink'"); sfile.append("\n"); sfile.append("xml:space='default'"); sfile.append("\n"); sfile.append("version='1.1' width='100%' height='100%' viewBox='0 0 2024 570'>"); sfile.append("\n"); sfile.append("<defs></defs>"); sfile.append("\n"); sfile.append("<g stroke-width='1' stroke='#FFFFFF' transform='matrix(1,0,0,1,16.384,-9.83)' xmlns='http://www.w3.org/2000/svg'>"); sfile.append("\n"); //循环创造path标签. String path =creatPath(502, 300, 300, percents,names);//中心点式503,300. sfile.append(path); sfile.append("</g>"); sfile.append("\n"); sfile.append("</svg>"); return sfile.toString(); } /** * * @param x0 中心点横坐标 * @param y0 中心点纵坐标 * @param r 半径 * @param percents 百分比数组 * @param names 显示颜色代表的名称 * @return */ public static String creatPath(double x0,double y0,double r,double[]percents,String[]names){ StringBuffer sfile =new StringBuffer(); double x1=0; //新扇形的x坐标 double y1=0; //新扇形的y坐标 double middleX=0; //文本显示的坐标,包括竖线显示的坐标 double middleY=0; double radian =0; //弧度 double textRadian=0; //文本显示位置度弧度 double k=0; int N=10; for(int i=0;i<percents.length;i++){ if(i==0){ radian =getRadian(percents[0]); textRadian=radian/2; x1 = (x0+getCos(radian)*r); y1 = (y0-getSin(radian)*r); middleX=(x0+getCos(textRadian)*r); middleY=(y0-getSin(textRadian)*r); double percent = Math.round(percents[0]*100)/100.0;//获得精确到两位小数点的坐标. k=Math.abs((middleY-y0)/(middleX-x0));//获得扇形终点的坐标,与中心点连成的直线的斜率.(取正值) double sita= Math.atan(k);//求斜角 double lineLen=50; double textLen=70; if(radian<6){ lineLen=90; textLen=110;//控制指示线的长度,与文字的位置 } if((textRadian<(Math.PI/2))){ sfile.append("<line x1='"+middleX+"' y1='"+middleY+"' x2='"+(middleX+Math.cos(sita)*lineLen)+"' y2='"+(middleY-(Math.sin(sita)*lineLen))+"' stroke='#000000'/>"); sfile.append("\n"); sfile.append("<text x='"+(middleX+Math.cos(sita)*textLen)+"' y='"+(middleY-(Math.sin(sita)*textLen))+"' space='preserve' font-family='Tahoma' font-size='21' fill='red' stroke='red' baseline-shift='baseline' >"+percent+"%</text>"); }else if ((textRadian>(Math.PI/2)&&textRadian<Math.PI)){ sfile.append("<line x1='"+middleX+"' y1='"+middleY+"' x2='"+(middleX-Math.cos(sita)*lineLen)+"' y2='"+(middleY-(Math.sin(sita)*lineLen))+"' stroke='#000000'/>"); sfile.append("\n"); sfile.append("<text x='"+(middleX-Math.cos(sita)*textLen)+"' y='"+(middleY-(Math.sin(sita)*textLen))+"' space='preserve' font-family='Tahoma' font-size='21' fill='red' stroke='red' baseline-shift='baseline' >"+percent+"%</text>"); }else if ((textRadian>(Math.PI)&&textRadian<(Math.PI*3/2))){ sfile.append("<line x1='"+middleX+"' y1='"+middleY+"' x2='"+(middleX-Math.cos(sita)*lineLen)+"' y2='"+(middleY+(Math.sin(sita)*lineLen))+"' stroke='#000000'/>"); sfile.append("\n"); sfile.append("<text x='"+(middleX-Math.cos(sita)*textLen)+"' y='"+(middleY+(Math.sin(sita)*textLen))+"' space='preserve' font-family='Tahoma' font-size='21' fill='red' stroke='red' baseline-shift='baseline' >"+percent+"%</text>"); }else if((textRadian>(Math.PI*3/2)&&textRadian<(Math.PI*2))){ sfile.append("<line x1='"+middleX+"' y1='"+middleY+"' x2='"+(middleX+Math.cos(sita)*lineLen)+"' y2='"+(middleY+Math.sin(sita)*lineLen)+"' stroke='#000000'/>"); sfile.append("\n"); sfile.append("<text x='"+(middleX+Math.cos(sita)*textLen)+"' y='"+(middleY+(Math.sin(sita)*textLen))+"' space='preserve' font-family='Tahoma' font-size='21' fill='red' stroke='red' baseline-shift='baseline' >"+percent+"%</text>"); } sfile.append("\n"); if(getRadian(percents[0])>Math.PI){ sfile.append("<path d='M "+x0+" "+y0+" L "+(x0+r)+" "+r+" A "+r+" "+r+" 0 1 0 "+x1+" "+y1+" L "+x0+" "+y0+" z' fill='"+colors[0]+"'/>"); }else{ sfile.append("<path d='M "+x0+" "+y0+" L "+(x0+r)+" "+r+" A "+r+" "+r+" 0 0 0 "+x1+" "+y1+" L "+x0+" "+y0+" z' fill='"+colors[0]+"'/>"); } sfile.append("\n"); sfile.append("<rect x='"+(x0+2*r)+"' y='"+(y0-r/2.0+N)+"' width='60' height='30' fill='"+colors[i]+"' stroke='#FFFFFF' stroke-dasharray='1,1' />"); sfile.append("\n"); sfile.append("<text x='"+(x0+2*r+80)+"' y='"+(y0-r/2.0+N+25)+"' space='preserve' font-family='宋体' font-size='28' fill='"+colors[0]+"' stroke='#000000' stroke-dasharray='1,1' baseline-shift='baseline'>"+names[0]+"</text>"); sfile.append("\n"); }else{ textRadian = radian+(getRadian(percents[i])/2);//获取指示线与X轴的弧度. radian =radian+getRadian(percents[i]);//第i个扇形前面的弧度的总和 middleX=(x0+getCos(textRadian)*r); middleY=(y0-getSin(textRadian)*r); double percent = Math.round(percents[i]*100)/100.0; k=Math.abs((middleY-y0)/(middleX-x0)); double lineLen=50; double textLen=70; if(radian<6){ lineLen=90; textLen=110; } double sita= Math.atan(k); if((textRadian<(Math.PI/2))){ sfile.append("<line x1='"+middleX+"' y1='"+middleY+"' x2='"+(middleX+Math.cos(sita)*lineLen)+"' y2='"+(middleY-(Math.sin(sita)*lineLen))+"' stroke='#000000'/>"); sfile.append("\n"); sfile.append("<text x='"+(middleX+Math.cos(sita)*textLen)+"' y='"+(middleY-(Math.sin(sita)*textLen))+"' space='preserve' font-family='Tahoma' font-size='21' fill='red' stroke='red' baseline-shift='baseline' >"+percent+"%</text>"); }else if ((textRadian>(Math.PI/2)&&textRadian<Math.PI)){ sfile.append("<line x1='"+middleX+"' y1='"+middleY+"' x2='"+(middleX-Math.cos(sita)*lineLen)+"' y2='"+(middleY-(Math.sin(sita)*lineLen))+"' stroke='#000000'/>"); sfile.append("\n"); sfile.append("<text x='"+(middleX-Math.cos(sita)*textLen)+"' y='"+(middleY-(Math.sin(sita)*textLen))+"' space='preserve' font-family='Tahoma' font-size='21' fill='red' stroke='red' baseline-shift='baseline' >"+percent+"%</text>"); }else if ((textRadian>(Math.PI)&&textRadian<(Math.PI*3/2))){ sfile.append("<line x1='"+middleX+"' y1='"+middleY+"' x2='"+(middleX-Math.cos(sita)*lineLen)+"' y2='"+(middleY+(Math.sin(sita)*lineLen))+"' stroke='#000000'/>"); sfile.append("\n"); sfile.append("<text x='"+(middleX-Math.cos(sita)*textLen)+"' y='"+(middleY+(Math.sin(sita)*textLen))+"' space='preserve' font-family='Tahoma' font-size='21' fill='red' stroke='red' baseline-shift='baseline' >"+percent+"%</text>"); }else if((textRadian>(Math.PI*3/2)&&textRadian<(Math.PI*2))){ sfile.append("<line x1='"+middleX+"' y1='"+middleY+"' x2='"+(middleX+Math.cos(sita)*lineLen)+"' y2='"+(middleY+Math.sin(sita)*lineLen)+"' stroke='#000000'/>"); sfile.append("\n"); sfile.append("<text x='"+(middleX+Math.cos(sita)*textLen)+"' y='"+(middleY+(Math.sin(sita)*textLen))+"' space='preserve' font-family='Tahoma' font-size='21' fill='red' stroke='red' baseline-shift='baseline' >"+percent+"%</text>"); } sfile.append("\n"); // 参数 1 表示 画大于180的弧, 0 表示画小于180的弧 (这个地方比较重要) if(getRadian(percents[i])>Math.PI){ sfile.append("<path d='M "+x0+" "+y0+" L "+x1+" "+y1+" A "+r+" "+r+" 0 1 0 "+(x1=x0+getCos(radian)*r)+" "+(y1=y0-getSin(radian)*r)+" L "+x0+" "+y0+" z' fill='"+colors[i]+"'/>"); }else{ sfile.append("<path d='M "+x0+" "+y0+" L "+x1+" "+y1+" A "+r+" "+r+" 0 0 0 "+(x1=x0+getCos(radian)*r)+" "+(y1=y0-getSin(radian)*r)+" L "+x0+" "+y0+" z' fill='"+colors[i]+"'/>"); } sfile.append("\n"); N+=50; sfile.append("<rect x='"+(x0+2*r)+"' y='"+(y0-r/2.0+N)+"' width='60' height='30' fill='"+colors[i]+"' stroke='#FFFFFF' stroke-dasharray='1,1' />"); sfile.append("\n"); sfile.append("<text x='"+(x0+2*r+80)+"' y='"+(y0-r/2.0+N+25)+"' space='preserve' font-family='宋体' font-size='28' fill='"+colors[0]+"' stroke='#000000' stroke-dasharray='1,1' baseline-shift='baseline'>"+names[i]+"</text>"); sfile.append("\n"); } } return sfile.toString(); } //返回弧度 public static double getRadian(double fenshu){ return (fenshu*Math.PI)/50; } //返回正弦 public static double getSin(double radian){ return Math.sin(radian); } //返回余弦 public static double getCos(double radian){ return Math.cos(radian); } public static void main(String[] args) { double[] data= {1000,2000,3000,900,100,2100}; String[] names={"中国","美国","德国","法国","意大利","巴西"}; create(data,names); } private static void create(double[] data,String[] names) { try { createSVG("f:/a.svg",getPercent(data),names); } catch (Exception e) { e.printStackTrace(); } } private static double[] getPercent(double data[]){ double sum=0; double percents[] = new double[data.length]; for(int i=0;i<data.length;i++){ sum+=data[i]; } for(int i=0;i<data.length;i++){ percents[i] =(data[i]/sum)*100; } return percents; } public static void createSVG(String fileRealPath, double[] percents,String[] names) throws Exception { String sFile = initialize(percents,names); try { byte[] byteFil = sFile.getBytes("UTF-8"); File svgFile = new File(fileRealPath); if (svgFile.exists()) { svgFile.delete(); } FileOutputStream fos = new FileOutputStream(svgFile); fos.write(byteFil); fos.close(); } catch (Exception ex) { System.out.print(ex.getMessage()); } } }
四、java生成SVG 3D饼图.
(这个可以生成图形,但是不完善,我没有再修改代码啦,因为觉得这个东西不值,用jfreechart可能更好.功能更强到,只是这几个程序,让我更加了解了svg这个东西,里面的一些标签都干什么用的.等等.) 3D的这个,生成的效果图,会有断层的效果,主要是出现在第一现象和第四象限,即如果第一象限或第四象限,有两个扇形的话,就会出现断层,可以用这个工具进行调整:SVGDeveloper. 用它打开svg图形,然后将断层的扇形的代码,重新倒序排列一下.
package com.xj.svg; import java.io.File; import java.io.FileOutputStream; public class Caky3DSVG { static String[] colors ={"#d6a97b", "#22FF22", "#aaffaa", "#799AE1", "#9aabEe", "#3e941b", "#f2e692", "#66cc00", "#297110", "#d6a97b", "#82522b", "#aaaaff", "#1111aa", "#ff2222", "#ffaaaa", "#aa1111" }; public static void main(String[] args) { double data[] = {20,20,50}; try { createSVG("f:/f.svg",getPercent(data)); } catch (Exception e) { e.printStackTrace(); } } static String initialize(double [] percent){ double percents[] = {10,15,5,20,40,10}; StringBuffer sfile = new StringBuffer(); sfile.append("<?xml version='1.0' encoding='UTF-8'?>"); sfile.append("\n"); sfile.append("<svg xmlns:svg='http://www.w3.org/2000/svg'"); sfile.append("\n"); sfile.append("xmlns='http://www.w3.org/2000/svg'"); sfile.append("\n"); sfile.append("xmlns:xlink='http://www.w3.org/1999/xlink'"); sfile.append("\n"); sfile.append("xml:space='default'"); sfile.append("\n"); sfile.append("version='1.1' width='100%' height='100%' viewBox='0 0 1024 600'>"); sfile.append("\n"); sfile.append("<defs></defs>"); sfile.append("\n"); String path = createPath(502, 300,300, 150, percents); sfile.append(path); sfile.append("</g>"); sfile.append("\n"); sfile.append("</svg>"); return sfile.toString(); } /** * * @param x0 原点 X * @param y0 原点 Y * @param langR * @param shortR * @param fenshu * @return */ static String createPath(double x0,double y0,double langR,double shortR ,double percents[]){ StringBuffer sfile = new StringBuffer(); double xBottom =0; double yBottom =0; double xBottom1=0; double yBottom1=0; double radian =0; sfile.append("<g stroke-width='1' stroke='#000000' transform='matrix(1,0,0,1,1.638,-9.83)' xmlns='http://www.w3.org/2000/svg'>"); sfile.append("\n"); for(int i=0;i<percents.length;i++){ System.out.println("i:"+i); radian =radian+getRadian(percents[i]);//第i个扇形到 第一个扇形,弧度的总和. System.out.println("弧度2:"+radian); if (i==0){ System.out.println("弧度1:"+radian); if(radian==Math.PI/2){ xBottom = x0;//底面的x坐标 yBottom = y0-shortR;//底面的y坐标 }else if(radian==Math.PI*3/2){ xBottom = x0;//底面的x坐标 yBottom = y0+shortR;//底面的y坐标 } else{ double tanRadian = Math.abs(Math.tan(radian)); double sqValue=shortR*shortR+tanRadian*tanRadian*langR*langR; if(radian<Math.PI/2){ System.out.println("if1:"+radian); xBottom = x0+(langR*shortR)/Math.sqrt(sqValue);//底面的x坐标 yBottom = y0-(tanRadian*langR*shortR)/Math.sqrt(sqValue);//底面的y坐标 } else if (radian>Math.PI/2&&radian<=Math.PI){ System.out.println("if2:"+radian); xBottom =x0-(langR*shortR)/Math.sqrt(sqValue); yBottom =y0-(tanRadian*langR*shortR)/Math.sqrt(sqValue); }else if (radian>Math.PI&&radian<Math.PI*3/2){ System.out.println("if3:"+radian); xBottom =x0-(langR*shortR)/Math.sqrt(sqValue); yBottom =y0+(tanRadian*langR*shortR)/Math.sqrt(sqValue); }else if (radian>Math.PI*3/2&&radian<Math.PI*2){ System.out.println("if4:"+radian); xBottom = x0+(langR*shortR)/Math.sqrt(sqValue); yBottom = y0+(tanRadian*langR*shortR)/Math.sqrt(sqValue); } } if(getRadian(percents[0])>Math.PI){//大于 PI 弧度,即百分比超过50% sfile.append("<g fill='"+colors[i]+"' >"); sfile.append("\n"); sfile.append("<path d='M "+x0+" "+y0+" L "+(x0+langR)+" "+y0+" A "+langR+" "+shortR+" 0 1 0 "+xBottom+" "+yBottom+" z' />"); sfile.append("\n"); sfile.append("<path d='M "+(x0+langR)+" "+(y0-50)+" A "+langR+" "+shortR+" 0 1 0 "+xBottom+" "+(yBottom-50)+" L "+xBottom+" "+yBottom+" A "+langR+" "+shortR+" 0 1 1 "+(x0+langR)+" "+y0+" z' />"); sfile.append("\n"); sfile.append("<path d='M "+x0+" "+(y0-50)+" L "+(x0+langR)+" "+(y0-50)+" A "+langR+" "+shortR+" 0 1 0 "+xBottom+" "+(yBottom-50)+" z' />"); sfile.append("\n"); sfile.append("</g>"); sfile.append("\n"); }else{ sfile.append("<g fill='"+colors[i]+"' >"); sfile.append("\n"); sfile.append("<path d='M "+x0+" "+y0+" L "+(x0+langR)+" "+y0+" A "+langR+" "+shortR+" 0 0 0 "+xBottom+" "+yBottom+" z' />"); sfile.append("\n"); sfile.append("<path d='M "+(x0+langR)+" "+(y0-50)+" A "+langR+" "+shortR+" 0 0 0 "+xBottom+" "+(yBottom-50)+" L "+xBottom+" "+yBottom+" A "+langR+" "+shortR+" 0 0 1 "+(x0+langR)+" "+y0+" z' />"); sfile.append("\n"); sfile.append("<path d='M "+x0+" "+(y0-50)+" L "+(x0+langR)+" "+(y0-50)+" A "+langR+" "+shortR+" 0 0 0 "+xBottom+" "+(yBottom-50)+" z' />"); sfile.append("\n"); sfile.append("</g>"); sfile.append("\n"); } }else{ if(radian==Math.PI/2){ xBottom1= x0;//底面的x坐标 yBottom1= y0-shortR;//底面的y坐标 }else if(radian==Math.PI*3/2){ xBottom1 = x0;//底面的x坐标 yBottom1 = y0+shortR;//底面的y坐标 } else{ double tanRadian = Math.abs(Math.tan(radian)); double sqValue=shortR*shortR+tanRadian*tanRadian*langR*langR; if(radian<Math.PI/2){ System.out.println("if1:"+radian); xBottom1 = x0+(langR*shortR)/Math.sqrt(sqValue);//底面的x坐标 yBottom1 = y0-(tanRadian*langR*shortR)/Math.sqrt(sqValue);//底面的y坐标 } else if (radian>Math.PI/2&&radian<=Math.PI){ System.out.println("if2:"+radian); xBottom1 =x0-(langR*shortR)/Math.sqrt(sqValue); yBottom1 =y0-(tanRadian*langR*shortR)/Math.sqrt(sqValue); }else if (radian>Math.PI&&radian<Math.PI*3/2){ System.out.println("if3:"+radian); xBottom1 =x0-(langR*shortR)/Math.sqrt(sqValue); yBottom1 =y0+(tanRadian*langR*shortR)/Math.sqrt(sqValue); }else if (radian>Math.PI*3/2){ System.out.println("if4:"+radian); xBottom1 = x0+(langR*shortR)/Math.sqrt(sqValue); yBottom1 = y0+(tanRadian*langR*shortR)/Math.sqrt(sqValue); } } if(getRadian(percents[i])>Math.PI){//大于 PI 弧度,即百分比超过50% System.out.println("大于pi"); sfile.append("<g fill='"+colors[i]+"' >"); sfile.append("\n"); sfile.append("<path d='M "+x0+" "+y0+" L "+xBottom+" "+yBottom+" A "+langR+" "+shortR+" 0 1 0 "+xBottom1+" "+yBottom1+" z' />"); sfile.append("\n"); sfile.append("<path d='M "+(xBottom)+" "+(yBottom-50)+" A "+langR+" "+shortR+" 0 1 0 "+xBottom1+" "+(yBottom1-50)+" L "+xBottom1+" "+yBottom1+" A "+langR+" "+shortR+" 0 1 1 "+xBottom+" "+yBottom+" z' />"); sfile.append("\n"); sfile.append("<path d='M "+x0+" "+(y0-50)+" L "+(xBottom)+" "+(yBottom-50)+" A "+langR+" "+shortR+" 0 1 0 "+xBottom1+" "+(yBottom1-50)+" z' />"); sfile.append("\n"); sfile.append("</g>"); sfile.append("\n"); }else{ System.out.println("小于pi"); sfile.append("<g fill='"+colors[i]+"' >"); sfile.append("\n"); sfile.append("<path d='M "+x0+" "+y0+" L "+xBottom+" "+yBottom+" A "+langR+" "+shortR+" 0 0 0 "+xBottom1+" "+yBottom1+" z' />"); sfile.append("\n"); sfile.append("<path d='M "+(xBottom)+" "+(yBottom-50)+" A "+langR+" "+shortR+" 0 0 0 "+xBottom1+" "+(yBottom1-50)+" L "+xBottom1+" "+yBottom1+" A "+langR+" "+shortR+" 0 0 1 "+xBottom+" "+yBottom+" z' />"); sfile.append("\n"); sfile.append("<path d='M "+x0+" "+(y0-50)+" L "+(xBottom)+" "+(yBottom-50)+" A "+langR+" "+shortR+" 0 0 0 "+xBottom1+" "+(yBottom1-50)+" z' />"); sfile.append("\n"); sfile.append("</g>"); sfile.append("\n"); } xBottom=xBottom1; yBottom=yBottom1; } } return sfile.toString(); } //返回弧度 public static double getRadian(double percent){ return (percent*Math.PI)/50; } //返回正弦 public static double getSin(double radian){ return Math.sin(radian); } //返回余弦 public static double getCos(double radian){ return Math.cos(radian); } private static double[] getPercent(double data[]){ double sum=0; double percents[] = new double[data.length]; for(int i=0;i<data.length;i++){ sum+=data[i]; } for(int i=0;i<data.length;i++){ percents[i] =(data[i]/sum)*100; } return percents; } public static void createSVG(String fileRealPath, double[] percents) throws Exception { String sFile = initialize(percents); try { byte[] byteFil = sFile.getBytes("UTF-8"); File svgFile = new File(fileRealPath); if (svgFile.exists()) { svgFile.delete(); } FileOutputStream fos = new FileOutputStream(svgFile); fos.write(byteFil); fos.close(); } catch (Exception ex) { System.out.print(ex.getMessage()); } } }
五,使用Jfreechart动态生成svg图形:
import java.awt.Rectangle; import java.io.*; import org.jfree.chart.*; import org.apache.batik.dom.GenericDOMImplementation; import org.apache.batik.svggen.SVGGraphics2D; import org.jfree.data.category.CategoryDataset; import org.jfree.data.category.DefaultCategoryDataset; import org.jfree.chart.plot.*; import org.w3c.dom.DOMImplementation; import org.w3c.dom.Document; /** * 该类用于演示最简单的柱状图生成 */ public class BarChartDemo { public static void main(String[] args) throws IOException { CategoryDataset dataset = getDataSet(); // 创建JFreeChart对象,在内存中间创建出对应的图像 JFreeChart chart = ChartFactory.createBarChart3D("水果产量图", // 图表标题 "水果", // 目录轴的显示标签 "产量", // 数值轴的显示标签 dataset, // 数据集 PlotOrientation.VERTICAL, // 图表方向:水平、垂直 true, // 是否显示图例(对于简单的柱状图必须是false) false, // 是否生成工具 false // 是否生成URL链接 ); File fo_svg = new File("D:\\fruit3.svg"); Rectangle bounds = new Rectangle(0,0,400,300); exportChartAsSVG(chart,bounds,fo_svg); } private static void exportChartAsJPG() throws FileNotFoundException, IOException { // 得到数据Dataset CategoryDataset dataset = getDataSet(); // 创建JFreeChart对象,在内存中间创建出对应的图像 JFreeChart chart = ChartFactory.createBarChart3D("水果产量图", // 图表标题 "水果", // 目录轴的显示标签 "产量", // 数值轴的显示标签 dataset, // 数据集 PlotOrientation.VERTICAL, // 图表方向:水平、垂直 true, // 是否显示图例(对于简单的柱状图必须是false) false, // 是否生成工具 false // 是否生成URL链接 ); FileOutputStream fos_jpg = null; try { fos_jpg = new FileOutputStream("D:/fruit3.jpg"); ChartUtilities.writeChartAsJPEG(fos_jpg, 1, chart, 400, 300, null); } finally { try { fos_jpg.close(); } catch (Exception e) { } } } /** * 获取一个演示用的简单数据集对象 * * @return */ private static CategoryDataset getDataSet() { DefaultCategoryDataset dataset = new DefaultCategoryDataset(); dataset.addValue(100, "1", "葡萄"); dataset.addValue(200, "1", "梨子"); dataset.addValue(200, "1", "荔枝"); dataset.addValue(300, "2", "葡萄"); dataset.addValue(400, "2", "梨子"); dataset.addValue(500, "2", "荔枝"); return dataset; } /** * 获取一个演示用的组合数据集对象 * * @return */ private static CategoryDataset getDataSet2() { DefaultCategoryDataset dataset = new DefaultCategoryDataset(); dataset.addValue(100, "北京", "苹果"); dataset.addValue(100, "上海", "苹果"); dataset.addValue(100, "广州", "苹果"); dataset.addValue(200, "北京", "梨子"); dataset.addValue(200, "上海", "梨子"); dataset.addValue(200, "广州", "梨子"); dataset.addValue(300, "北京", "葡萄"); dataset.addValue(300, "上海", "葡萄"); dataset.addValue(300, "广州", "葡萄"); dataset.addValue(400, "北京", "香蕉"); dataset.addValue(400, "上海", "香蕉"); dataset.addValue(400, "广州", "香蕉"); dataset.addValue(500, "北京", "荔枝"); dataset.addValue(500, "上海", "荔枝"); dataset.addValue(500, "广州", "荔枝"); return dataset; } /** * Exports a JFreeChart to a SVG file. * * @param chart JFreeChart to export * @param bounds the dimensions of the viewport * @param svgFile the output file. * @throws IOException if writing the svgFile fails. */ private static void exportChartAsSVG(JFreeChart chart, Rectangle bounds, File svgFile) throws IOException { // Get a DOMImplementation and create an XML document DOMImplementation domImpl = GenericDOMImplementation.getDOMImplementation(); Document document = domImpl.createDocument(null, "svg", null); // Create an instance of the SVG Generator SVGGraphics2D svgGenerator = new SVGGraphics2D(document); // draw the chart in the SVG generator chart.draw(svgGenerator, bounds); // Write svg file OutputStream outputStream = new FileOutputStream(svgFile); Writer out = new OutputStreamWriter(outputStream, "UTF-8"); svgGenerator.stream(out, true /* use css */); outputStream.flush(); outputStream.close(); } }
用这个的时候需要注意两点:1 .jfreechart本身不能生成svg图形,需要用到batik .一个java工具包,apache的.
batik-awt-util.jar
batik-dom.jar
batik-svggen.jar
batik-util.jar
batik-xml.jar
jfreechart-1.0.0.jar
2.就是可能生成svg,当你查看的时候不支持中文. 我记得好像是如果是安装的adobe的那个查看器,在IE里面浏览的话好像是中文乱码,如果用另外一个叫做 Renesis SVG Player ,这个查看器就是支持中文的.
评论
呵呵.初步了解了个svg.
谢谢各位的提示,我去研究研究birt...
发表评论
-
Origin字段 Header 为了防止CSRF的攻击
2014-07-08 12:09 1841为了防止CSRF的攻击,我们建议修改浏览器在发送POST请 ... -
eval解析JSON中的注意点
2013-12-08 18:32 779eval解析JSON中的注意点 在JS中将JSON的 ... -
jQuery ajax返回parsererror错误的解决方法
2013-12-04 22:38 1574jQuery ajax返回parsererror错误的解决 ... -
Ext3.0 动态数据 Chart 初探
2010-05-06 10:56 10480学习了Ext的Chart,看了官方提供的Example,也搜索 ... -
非常不错的Jquery图像报表Javascript类库.
2010-04-13 17:51 6887http://www.highcharts.com/ ... -
AJAX的中文乱码解决方法整理
2009-03-31 21:43 1212encodeURIComponent(dudu赛车),它是将中 ... -
手机主题网站,征集中文名字!炫出你的创意吧!
2009-03-27 14:58 1500手机主题网站,征集中文名字..炫出你的创意吧!! 网 ... -
Dtree+Jquery动态生成树节点例子《新手可参考》
2009-03-16 22:18 15506Dtree+Jquery动态生成树节点. 最近有朋友问我一个 ... -
Dom4j笔记总结《入门总结》
2009-03-13 08:51 1367Parsing XML 或许你想要做的第一件事情就是 ... -
答复: 代码评审怎么做,做到什么程度合适?
2009-03-11 09:26 1582不知道.看帖的人,有没 ... -
大家一起来讨论讨论像56和优酷等哪些网站,里面的动感相册功能是怎样实现的!
2009-01-08 16:53 1182大家一起来讨论讨论 像56和优酷等哪些网站,里面的动感相册功能 ... -
手机主题网站开发
2009-01-08 13:43 1399工作一段时间了,一直在公司开发这个网站. http:// ... -
SmartUpload缺陷:不能上传大文件,占内存耗CPU
2009-01-07 10:03 4492最近我们的网站项目,有一段时间,服务器运行到一定的时候时,就会 ... -
最近我公司的网站,服务器时间长了.就会报内存溢出.找不到原因
2008-12-22 17:10 1144最近我公司的网站,服务器时间长了,访问量变大.就会报内存溢出. ... -
怎样让一个网站,在搜索引擎中得到更够的搜索率呢?
2008-11-27 09:44 1160我们公司最近在做一个网站,大家提点建议呢,通过哪些方式能够让网 ...
相关推荐
纯Java动态生成 SVG 饼图与 JFreeChart 超强功能生成 SVG 图表 在本文中,我们将探讨如何使用 Java 生成 SVG 饼图,并使用 JFreeChart 生成 SVG 图表。我们还将讨论 JFreeChart 的一些缺陷和解决方案。 一、Java ...
总结来说,虽然Java生成SVG饼图或使用JFreeChart结合Batik生成SVG图表可能涉及较多的代码和数学计算,但它提供了高度的定制性和灵活性。对于需要在Java应用程序中生成高质量、可缩放的图表的需求,这是一个值得考虑...
JFreeChart库正是这样一个强大的工具,它允许开发人员在Java应用程序中创建各种图表,如柱状图、饼图和折线图等。这个免费的库不仅功能丰富,而且易于学习和使用,使得数据展示变得更加直观和专业。 JFreeChart库的...
jFreeChart 是一款强大的 Java 图表库,专用于创建各种统计图表,如柱状图、饼图、线图、雷达图等。它以其开源、免费的特性受到许多开发者青睐,适用于构建 C/S(客户端/服务器)、B/S(浏览器/服务器)以及实时环境...
Java图表库JFreeChart是Java开发中用于创建各种复杂图表的开源库,广泛应用于数据分析、报表生成和可视化项目。这个压缩包"java源码:Java图表 JFreeChart.zip"包含了JFreeChart的1.0.14版本源代码,允许开发者深入...
4. 图表输出多样化:支持生成静态图像(如PNG、JPEG、SVG),也可用于动态Web应用(如JavaServer Pages, Applets)。 5. 兼容性好:兼容Java 2 Platform, Standard Edition (J2SE) 1.4+,以及JavaFX。 三、使用...
JFreeChart就是这样一个专门用于生成高质量图表的Java库,它支持多种图表类型,如柱状图、饼图、线图、散点图、甘特图等,且可高度定制化。 JFreeChart库的核心功能包括: 1. **多样化图表类型**:JFreeChart支持...
JFreeChart不仅支持静态图表,还支持动态和交互式图表,可以与Java Swing、JavaFX等图形界面库无缝集成。 **JFreeChart的核心功能** 1. **多种图表类型**:JFreeChart支持折线图、柱状图、饼图、散点图、甘特图、...
5. **导出功能**:JFreeChart 提供了将图表导出为 PNG、JPEG、SVG、PDF、EPS 等格式的功能,方便在报告、网页和打印中使用。 **JFreeChart 在 Web 开发中的应用** 在 Web 开发中,JFreeChart 主要通过 JavaServer ...
JFreeChart是Java社区中的一个开源库,专门用于生成高质量的2D图表,包括柱状图、饼图、线图、散点图、面积图等多种类型的图表。这个压缩包"基于Java的图表 JFreeChart.zip"包含的是JFreeChart的版本1.0.14。 ...
标题“JFreeChart与JSP动态图表”涉及的是在Java Web开发中利用JFreeChart库创建动态图表并与JSP(JavaServer Pages)结合的技术。JFreeChart是一个强大的开源Java库,用于生成高质量的2D图表,包括折线图、柱状图、...
JFreeChart是一款强大的Java图表库,它允许开发者在应用程序、Swing组件或Web应用中创建各种图表,如柱状图、饼图、折线图等。这个库支持丰富的定制选项,使得图表可以按照用户需求进行个性化设计。在这个...
JFreeChart是Java开发中不可或缺的图表库,它提供了丰富的功能,帮助开发者轻松创建专业级别的图表。无论是在桌面应用、Web应用还是数据分析项目中,都能发挥重要作用。通过熟练掌握JFreeChart,你可以为用户呈现更...
JFreeChart是一个流行的开源Java库,用于创建各种高质量的图表,包括折线图、柱状图、饼图、散点图、甘特图等。它在描述复杂数据集时提供了一种直观的方式,广泛应用于数据分析、报告生成和可视化应用中。JFreeChart...
"图表生成.rar"这个压缩包很可能包含了一系列用于在Java环境中创建图表的代码示例、库或者工具。以下是对这个主题的详细解释: 1. **JFreeChart**: JFreeChart 是一个流行的 Java 图表库,它提供了丰富的图表类型,...
Java统计图生成库JFreeChart是一个强大的开源工具,专为Java开发者设计,用于创建各种复杂的图表,如柱状图、饼图和折线图。它提供了丰富的功能和灵活性,使得在应用程序中集成可视化数据变得非常容易,而无需深入...
3. **动态图表**:JFreeChart不仅可以生成静态图表,还可以创建交互式图表,用户可以通过鼠标操作进行缩放、平移等操作,增强了用户体验。 4. **多平台兼容**:由于Java的跨平台特性,JFreeChart生成的图表可以在...
JFreeChart 是一个用于 Java 的开源图表库,它提供了一种简单的方法来创建各种复杂的图表,如折线图、柱状图、饼图、散点图以及更专业的图表类型,如甘特图和雷达图。在Java应用中,如果你需要生成动态或静态的图表...
4. **支持多种输出**:生成的图表可以导出为多种格式,如JPEG、PNG、PDF、SVG等,方便在不同平台上展示和打印。 5. **Web应用集成**:由于其Java的基础特性,JFreeChart可以轻松地与Servlets、JSP、JavaFX等Web技术...
### Java报表JFreeChart开发知识点总结 #### 1. 简介 ##### 1.1 什么是JFreeChart ...无论是简单的数据可视化还是复杂的动态图表,JFreeChart都能提供强大的支持。希望本文能帮助大家更好地利用这一强大的工具。