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图表的全部内容,希望大家喜欢。