java生成饼图svg及JFreeChart生成svg图表
Jfreechart本身不能生成SVG图形,但是可以借助另外一个东西,辅助生成.好像是这个:batik,具体代码请看下文
一:Java生成svg饼图,附带了一个标签显示各个颜色代表的部分
packagecom.tellhow.svg; importjava.io.File; importjava.io.FileOutputStream; /** * *@author风絮NO.1 * */ publicclassCakySvgWithLabel{ //定义不同的颜色 staticString[]colors={"#f2e692","#aa1111", "#799AE1","#3e941b", "#66cc00","#297110", "#d6a97b","#82522b", "#aaaaff","#1111aa", "#ff2222","#ffaaaa"}; staticStringinitialize(double[]percents,String[]names){ StringBuffersfile=newStringBuffer(); sfile.append("<?xmlversion='1.0'encoding='UTF-8'?>"); sfile.append("\n"); sfile.append("<svgxmlns: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='002024570'>"); sfile.append("\n"); sfile.append("<defs></defs>"); sfile.append("\n"); sfile.append("<gstroke-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标签. Stringpath=creatPath(502,300,300,percents,names);//中心点式503,300. sfile.append(path); sfile.append("</g>"); sfile.append("\n"); sfile.append("</svg>"); returnsfile.toString(); } /** * *@paramx0中心点横坐标 *@paramy0中心点纵坐标 *@paramr半径 *@parampercents百分比数组 *@paramnames显示颜色代表的名称 *@return */ publicstaticStringcreatPath(doublex0,doubley0,doubler,double[]percents,String[]names){ StringBuffersfile=newStringBuffer(); doublex1=0;//新扇形的x坐标 doubley1=0;//新扇形的y坐标 doublemiddleX=0;//文本显示的坐标,包括竖线显示的坐标 doublemiddleY=0; doubleradian=0;//弧度 doubletextRadian=0;//文本显示位置度弧度 doublek=0; intN=10; for(inti=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); doublepercent=Math.round(percents[0]*100)/100.0;//获得精确到两位小数点的坐标. k=Math.abs((middleY-y0)/(middleX-x0));//获得扇形终点的坐标,与中心点连成的直线的斜率.(取正值) doublesita=Math.atan(k);//求斜角 doublelineLen=50; doubletextLen=70; if(radian<6){ lineLen=90; textLen=110;//控制指示线的长度,与文字的位置 } if(percents[i]!=0){//当一个类型为0时,饼图展示 if((textRadian<(Math.PI/2))){ sfile.append("<linex1='"+middleX+"'y1='"+middleY+"'x2='"+(middleX+Math.cos(sita)*lineLen)+"'y2='"+(middleY-(Math.sin(sita)*lineLen))+"'stroke='#000000'/>"); sfile.append("\n"); sfile.append("<textx='"+(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>"); }elseif((textRadian>(Math.PI/2)&&textRadian<Math.PI)){ sfile.append("<linex1='"+middleX+"'y1='"+middleY+"'x2='"+(middleX-Math.cos(sita)*lineLen)+"'y2='"+(middleY-(Math.sin(sita)*lineLen))+"'stroke='#000000'/>"); sfile.append("\n"); sfile.append("<textx='"+(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>"); }elseif((textRadian>(Math.PI)&&textRadian<(Math.PI*3/2))){ sfile.append("<linex1='"+middleX+"'y1='"+middleY+"'x2='"+(middleX-Math.cos(sita)*lineLen)+"'y2='"+(middleY+(Math.sin(sita)*lineLen))+"'stroke='#000000'/>"); sfile.append("\n"); sfile.append("<textx='"+(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>"); }elseif((textRadian>(Math.PI*3/2)&&textRadian<(Math.PI*2))){ sfile.append("<linex1='"+middleX+"'y1='"+middleY+"'x2='"+(middleX+Math.cos(sita)*lineLen)+"'y2='"+(middleY+Math.sin(sita)*lineLen)+"'stroke='#000000'/>"); sfile.append("\n"); sfile.append("<textx='"+(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("<pathd='M"+x0+""+y0+"L"+(x0+r)+""+r+"A"+r+""+r+"010"+x1+""+y1+"L"+x0+""+y0+"z'fill='"+colors[0]+"'/>"); }else{ sfile.append("<pathd='M"+x0+""+y0+"L"+(x0+r)+""+r+"A"+r+""+r+"000"+x1+""+y1+"L"+x0+""+y0+"z'fill='"+colors[0]+"'/>"); } sfile.append("\n"); } sfile.append("<rectx='"+(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("<textx='"+(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); doublepercent=Math.round(percents[i]*100)/100.0; k=Math.abs((middleY-y0)/(middleX-x0)); doublelineLen=50; doubletextLen=70; if(radian<6){ lineLen=90; textLen=110; } doublesita=Math.atan(k); if(percents[i]!=0){//当一个类型为0时,饼图展示 if((textRadian<(Math.PI/2))){ sfile.append("<linex1='"+middleX+"'y1='"+middleY+"'x2='"+(middleX+Math.cos(sita)*lineLen)+"'y2='"+(middleY-(Math.sin(sita)*lineLen))+"'stroke='#000000'/>"); sfile.append("\n"); sfile.append("<textx='"+(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>"); }elseif((textRadian>(Math.PI/2)&&textRadian<Math.PI)){ sfile.append("<linex1='"+middleX+"'y1='"+middleY+"'x2='"+(middleX-Math.cos(sita)*lineLen)+"'y2='"+(middleY-(Math.sin(sita)*lineLen))+"'stroke='#000000'/>"); sfile.append("\n"); sfile.append("<textx='"+(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>"); }elseif((textRadian>(Math.PI)&&textRadian<(Math.PI*3/2))){ sfile.append("<linex1='"+middleX+"'y1='"+middleY+"'x2='"+(middleX-Math.cos(sita)*lineLen)+"'y2='"+(middleY+(Math.sin(sita)*lineLen))+"'stroke='#000000'/>"); sfile.append("\n"); sfile.append("<textx='"+(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>"); }elseif((textRadian>(Math.PI*3/2)&&textRadian<(Math.PI*2))){ sfile.append("<linex1='"+middleX+"'y1='"+middleY+"'x2='"+(middleX+Math.cos(sita)*lineLen)+"'y2='"+(middleY+Math.sin(sita)*lineLen)+"'stroke='#000000'/>"); sfile.append("\n"); sfile.append("<textx='"+(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("<pathd='M"+x0+""+y0+"L"+x1+""+y1+"A"+r+""+r+"010"+(x1=x0+getCos(radian)*r)+""+(y1=y0-getSin(radian)*r)+"L"+x0+""+y0+"z'fill='"+colors[i]+"'/>"); }else{ sfile.append("<pathd='M"+x0+""+y0+"L"+x1+""+y1+"A"+r+""+r+"000"+(x1=x0+getCos(radian)*r)+""+(y1=y0-getSin(radian)*r)+"L"+x0+""+y0+"z'fill='"+colors[i]+"'/>"); } sfile.append("\n"); } N+=50; sfile.append("<rectx='"+(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("<textx='"+(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"); } } returnsfile.toString(); } //返回弧度 publicstaticdoublegetRadian(doublefenshu){ return(fenshu*Math.PI)/50; } //返回正弦 publicstaticdoublegetSin(doubleradian){ returnMath.sin(radian); } //返回余弦 publicstaticdoublegetCos(doubleradian){ returnMath.cos(radian); } publicstaticvoidmain(String[]args){ int[]data={3,64,0,284,10}; String[]names={"主变:"+data[0]+"个","断路器:"+data[1]+"个","线路:"+data[2]+"个","刀闸:"+data[3]+"个","母线:"+data[4]+"个"}; create(data,names); } privatestaticvoidcreate(int[]data,String[]names){ try{ createSVG("d:/a.svg",getPercent(data),names); }catch(Exceptione){ e.printStackTrace(); } } privatestaticdouble[]getPercent(intdata[]){ doublesum=0; doublepercents[]=newdouble[data.length]; for(inti=0;i<data.length;i++){ sum+=data[i]; } for(inti=0;i<data.length;i++){ percents[i]=(data[i]/sum)*100; } returnpercents; } publicstaticvoidcreateSVG(StringfileRealPath,double[]percents,String[]names)throwsException{ StringsFile=initialize(percents,names); try{ byte[]byteFil=sFile.getBytes("UTF-8"); FilesvgFile=newFile(fileRealPath); if(svgFile.exists()){ svgFile.delete(); } FileOutputStreamfos=newFileOutputStream(svgFile); fos.write(byteFil); fos.close(); }catch(Exceptionex){ System.out.print(ex.getMessage()); } } }
二.java生成SVG3D饼图.
(这个可以生成图形,但是不完善,我没有再修改代码啦,因为觉得这个东西不值,用jfreechart可能更好.功能更强到,只是这几个程序,让我更加了解了svg这个东西,里面的一些标签都干什么用的.等等.)3D的这个,生成的效果图,会有断层的效果,主要是出现在第一现象和第四象限,即如果第一象限或第四象限,有两个扇形的话,就会出现断层,可以用这个工具进行调整:SVGDeveloper.用它打开svg图形,然后将断层的扇形的代码,重新倒序排列一下.
packagecom.xj.svg; importjava.io.File; importjava.io.FileOutputStream; publicclassCaky3DSVG{ staticString[]colors={"#d6a97b", "#22FF22","#aaffaa","#799AE1", "#9aabEe","#3e941b","#f2e692", "#66cc00","#297110","#d6a97b", "#82522b","#aaaaff","#1111aa", "#ff2222","#ffaaaa","#aa1111" }; publicstaticvoidmain(String[]args){ doubledata[]={20,20,50}; try{ createSVG("f:/f.svg",getPercent(data)); }catch(Exceptione){ e.printStackTrace(); } } staticStringinitialize(double[]percent){ doublepercents[]={10,15,5,20,40,10}; StringBuffersfile=newStringBuffer(); sfile.append("<?xmlversion='1.0'encoding='UTF-8'?>"); sfile.append("\n"); sfile.append("<svgxmlns: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='001024600'>"); sfile.append("\n"); sfile.append("<defs></defs>"); sfile.append("\n"); Stringpath=createPath(502,300,300,150,percents); sfile.append(path); sfile.append("</g>"); sfile.append("\n"); sfile.append("</svg>"); returnsfile.toString(); } /** * *@paramx0原点X *@paramy0原点Y *@paramlangR *@paramshortR *@paramfenshu *@return */ staticStringcreatePath(doublex0,doubley0,doublelangR,doubleshortR,doublepercents[]){ StringBuffersfile=newStringBuffer(); doublexBottom=0; doubleyBottom=0; doublexBottom1=0; doubleyBottom1=0; doubleradian=0; sfile.append("<gstroke-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(inti=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坐标 }elseif(radian==Math.PI*3/2){ xBottom=x0;//底面的x坐标 yBottom=y0+shortR;//底面的y坐标 }else{ doubletanRadian=Math.abs(Math.tan(radian)); doublesqValue=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坐标 } elseif(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); }elseif(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); }elseif(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("<gfill='"+colors[i]+"'>"); sfile.append("\n"); sfile.append("<pathd='M"+x0+""+y0+"L"+(x0+langR)+""+y0+"A"+langR+""+shortR+"010"+xBottom+""+yBottom+"z'/>"); sfile.append("\n"); sfile.append("<pathd='M"+(x0+langR)+""+(y0-50)+"A"+langR+""+shortR+"010"+xBottom+""+(yBottom-50)+"L"+xBottom+""+yBottom+"A"+langR+""+shortR+"011"+(x0+langR)+""+y0+"z'/>"); sfile.append("\n"); sfile.append("<pathd='M"+x0+""+(y0-50)+"L"+(x0+langR)+""+(y0-50)+"A"+langR+""+shortR+"010"+xBottom+""+(yBottom-50)+"z'/>"); sfile.append("\n"); sfile.append("</g>"); sfile.append("\n"); }else{ sfile.append("<gfill='"+colors[i]+"'>"); sfile.append("\n"); sfile.append("<pathd='M"+x0+""+y0+"L"+(x0+langR)+""+y0+"A"+langR+""+shortR+"000"+xBottom+""+yBottom+"z'/>"); sfile.append("\n"); sfile.append("<pathd='M"+(x0+langR)+""+(y0-50)+"A"+langR+""+shortR+"000"+xBottom+""+(yBottom-50)+"L"+xBottom+""+yBottom+"A"+langR+""+shortR+"001"+(x0+langR)+""+y0+"z'/>"); sfile.append("\n"); sfile.append("<pathd='M"+x0+""+(y0-50)+"L"+(x0+langR)+""+(y0-50)+"A"+langR+""+shortR+"000"+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坐标 }elseif(radian==Math.PI*3/2){ xBottom1=x0;//底面的x坐标 yBottom1=y0+shortR;//底面的y坐标 }else{ doubletanRadian=Math.abs(Math.tan(radian)); doublesqValue=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坐标 } elseif(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); }elseif(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); }elseif(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("<gfill='"+colors[i]+"'>"); sfile.append("\n"); sfile.append("<pathd='M"+x0+""+y0+"L"+xBottom+""+yBottom+"A"+langR+""+shortR+"010"+xBottom1+""+yBottom1+"z'/>"); sfile.append("\n"); sfile.append("<pathd='M"+(xBottom)+""+(yBottom-50)+"A"+langR+""+shortR+"010"+xBottom1+""+(yBottom1-50)+"L"+xBottom1+""+yBottom1+"A"+langR+""+shortR+"011"+xBottom+""+yBottom+"z'/>"); sfile.append("\n"); sfile.append("<pathd='M"+x0+""+(y0-50)+"L"+(xBottom)+""+(yBottom-50)+"A"+langR+""+shortR+"010"+xBottom1+""+(yBottom1-50)+"z'/>"); sfile.append("\n"); sfile.append("</g>"); sfile.append("\n"); }else{ System.out.println("小于pi"); sfile.append("<gfill='"+colors[i]+"'>"); sfile.append("\n"); sfile.append("<pathd='M"+x0+""+y0+"L"+xBottom+""+yBottom+"A"+langR+""+shortR+"000"+xBottom1+""+yBottom1+"z'/>"); sfile.append("\n"); sfile.append("<pathd='M"+(xBottom)+""+(yBottom-50)+"A"+langR+""+shortR+"000"+xBottom1+""+(yBottom1-50)+"L"+xBottom1+""+yBottom1+"A"+langR+""+shortR+"001"+xBottom+""+yBottom+"z'/>"); sfile.append("\n"); sfile.append("<pathd='M"+x0+""+(y0-50)+"L"+(xBottom)+""+(yBottom-50)+"A"+langR+""+shortR+"000"+xBottom1+""+(yBottom1-50)+"z'/>"); sfile.append("\n"); sfile.append("</g>"); sfile.append("\n"); } xBottom=xBottom1; yBottom=yBottom1; } } returnsfile.toString(); } //返回弧度 publicstaticdoublegetRadian(doublepercent){ return(percent*Math.PI)/50; } //返回正弦 publicstaticdoublegetSin(doubleradian){ returnMath.sin(radian); } //返回余弦 publicstaticdoublegetCos(doubleradian){ returnMath.cos(radian); } privatestaticdouble[]getPercent(doubledata[]){ doublesum=0; doublepercents[]=newdouble[data.length]; for(inti=0;i<data.length;i++){ sum+=data[i]; } for(inti=0;i<data.length;i++){ percents[i]=(data[i]/sum)*100; } returnpercents; } publicstaticvoidcreateSVG(StringfileRealPath,double[]percents)throwsException{ StringsFile=initialize(percents); try{ byte[]byteFil=sFile.getBytes("UTF-8"); FilesvgFile=newFile(fileRealPath); if(svgFile.exists()){ svgFile.delete(); } FileOutputStreamfos=newFileOutputStream(svgFile); fos.write(byteFil); fos.close(); }catch(Exceptionex){ System.out.print(ex.getMessage()); } } }
三.使用Jfreechart动态生成svg图形:
importjava.awt.Rectangle; importjava.io.*; importorg.jfree.chart.*; importorg.apache.batik.dom.GenericDOMImplementation; importorg.apache.batik.svggen.SVGGraphics2D; importorg.jfree.data.category.CategoryDataset; importorg.jfree.data.category.DefaultCategoryDataset; importorg.jfree.chart.plot.*; importorg.w3c.dom.DOMImplementation; importorg.w3c.dom.Document; /** *该类用于演示最简单的柱状图生成 */ publicclassBarChartDemo{ publicstaticvoidmain(String[]args)throwsIOException{ CategoryDatasetdataset=getDataSet(); //创建JFreeChart对象,在内存中间创建出对应的图像 JFreeChartchart=ChartFactory.createBarChart3D("水果产量图",//图表标题 "水果",//目录轴的显示标签 "产量",//数值轴的显示标签 dataset,//数据集 PlotOrientation.VERTICAL,//图表方向:水平、垂直 true,//是否显示图例(对于简单的柱状图必须是false) false,//是否生成工具 false//是否生成URL链接 ); Filefo_svg=newFile("D:\\fruit3.svg"); Rectanglebounds=newRectangle(0,0,400,300); exportChartAsSVG(chart,bounds,fo_svg); } privatestaticvoidexportChartAsJPG()throwsFileNotFoundException,IOException{ //得到数据Dataset CategoryDatasetdataset=getDataSet(); //创建JFreeChart对象,在内存中间创建出对应的图像 JFreeChartchart=ChartFactory.createBarChart3D("水果产量图",//图表标题 "水果",//目录轴的显示标签 "产量",//数值轴的显示标签 dataset,//数据集 PlotOrientation.VERTICAL,//图表方向:水平、垂直 true,//是否显示图例(对于简单的柱状图必须是false) false,//是否生成工具 false//是否生成URL链接 ); FileOutputStreamfos_jpg=null; try{ fos_jpg=newFileOutputStream("D:/fruit3.jpg"); ChartUtilities.writeChartAsJPEG(fos_jpg,1,chart,400,300,null); }finally{ try{ fos_jpg.close(); }catch(Exceptione){ } } } /** *获取一个演示用的简单数据集对象 * *@return */ privatestaticCategoryDatasetgetDataSet(){ DefaultCategoryDatasetdataset=newDefaultCategoryDataset(); dataset.addValue(100,"1","葡萄"); dataset.addValue(200,"1","梨子"); dataset.addValue(200,"1","荔枝"); dataset.addValue(300,"2","葡萄"); dataset.addValue(400,"2","梨子"); dataset.addValue(500,"2","荔枝"); returndataset; } /** *获取一个演示用的组合数据集对象 * *@return */ privatestaticCategoryDatasetgetDataSet2(){ DefaultCategoryDatasetdataset=newDefaultCategoryDataset(); 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,"广州","荔枝"); returndataset; } /** *ExportsaJFreeCharttoaSVGfile. * *@paramchartJFreeCharttoexport *@paramboundsthedimensionsoftheviewport *@paramsvgFiletheoutputfile. *@throwsIOExceptionifwritingthesvgFilefails. */ privatestaticvoidexportChartAsSVG(JFreeChartchart,Rectanglebounds,FilesvgFile)throwsIOException{ //GetaDOMImplementationandcreateanXMLdocument DOMImplementationdomImpl= GenericDOMImplementation.getDOMImplementation(); Documentdocument=domImpl.createDocument(null,"svg",null); //CreateaninstanceoftheSVGGenerator SVGGraphics2DsvgGenerator=newSVGGraphics2D(document); //drawthechartintheSVGgenerator chart.draw(svgGenerator,bounds); //Writesvgfile OutputStreamoutputStream=newFileOutputStream(svgFile); Writerout=newOutputStreamWriter(outputStream,"UTF-8"); svgGenerator.stream(out,true/*usecss*/); 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里面浏览的话好像是中文乱码,如果用另外一个叫做RenesisSVGPlayer,这个查看器就是支持中文的.
以上内容就是java生成饼图svg及JFreeChart生成svg图表的全部内容,希望大家喜欢。