`
xiejin2008
  • 浏览: 123831 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

纯Java动态生成SVG饼图与JFreeChart超强功能生成SVG图表.

阅读更多

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 ,这个查看器就是支持中文的.

分享到:
评论
6 楼 joknm 2009-12-26  
还没看完就晕了。这些标识完全不用搞到代码里面去。这样子做美工的就人死给你看。
5 楼 xiejin2008 2009-12-16  
不是我喜欢这个代码,我也觉得这个很烂,真的,没什么含量.
呵呵.初步了解了个svg.
谢谢各位的提示,我去研究研究birt...
4 楼 illu 2009-12-16  
强力代码党。。 建议用birt
3 楼 yewen0125 2009-12-15  
这么烂的代码也有啊,我的都是在后台封装的  前台只是负责显示
2 楼 Craft 2009-12-15  
这样太累了,用birt直接画出需要的图形就能导出svg
1 楼 ziyu_1 2009-12-15  
这个页面上居然有恐怖的脚本

相关推荐

Global site tag (gtag.js) - Google Analytics