java生成饼图svg及JFreeChart生成svg图表

Jfreechart本身不能生成SVG图形,但是可以借助另外一个东西,辅助生成.好像是这个:batik ,具体代码请看下文

一:Java生成svg饼图,附带了一个标签显示各个颜色代表的部分

package com.tellhow.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(percents[i]!=0){//当一个类型为0时,饼图展示
   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(percents[i]!=0){//当一个类型为0时,饼图展示
   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) {
 int[] data= {3,64,0,284,10};
 String[] names={"主变:"+data[0]+"个","断路器:"+data[1]+"个","线路:"+data[2]+"个","刀闸:"+data[3]+"个","母线:"+data[4]+"个"};
 create(data,names);
 }
 private static void create(int[] data,String[] names) {
 try {
 createSVG("d:/a.svg",getPercent(data),names);
 } catch (Exception e) {
 e.printStackTrace();
 }
 }
 private static double[] getPercent(int 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 ,这个查看器就是支持中文的.

以上内容就是java生成饼图svg及JFreeChart生成svg图表的全部内容,希望大家喜欢。

(0)

相关推荐

  • Javaweb开发中通过Servlet生成验证码图片

    一.BufferedImage类介绍 生成验证码图片主要用到了一个BufferedImage类,如下: 创建一个DrawImage Servlet,用来生成验证码图片 package gacl.response.study; import java.awt.Color; import java.awt.Font; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.image.BufferedImage; i

  • java中ZXing 生成、解析二维码图片的小示例

    概述 ZXing 是一个开源 Java 类库用于解析多种格式的 1D/2D 条形码.目标是能够对QR编码.Data Matrix.UPC的1D条形码进行解码. 其提供了多种平台下的客户端包括:J2ME.J2SE和Android. 官网:ZXing github仓库 实战 本例演示如何在一个非 android 的 Java 项目中使用 ZXing 来生成.解析二维码图片. 安装 maven项目只需引入依赖: <dependency> <groupId>com.google.zxing

  • java实现创建缩略图、伸缩图片比例生成的方法

    本文实例讲述了java实现创建缩略图.伸缩图片比例生成的方法.分享给大家供大家参考.具体实现方法如下: 该实例支持将Image的宽度.高度缩放到指定width.height,并保存在指定目录 通过目标对象的大小和标准(指定)大小计算出图片缩小的比例,可以设置图片缩放质量,并且可以根据指定的宽高缩放图片. 具体代码如下所示: 复制代码 代码如下: package com.hoo.util;   import java.awt.Image; import java.awt.image.Buffere

  • Java缩略图生成库之Thumbnailator应用说明

    Thumbnailator 是一个为Java界面更流畅的缩略图生成库.从API提供现有的图像文件和图像对象的缩略图中简化了缩略过程,两三行代码就能够从现有图片生成缩略图,且允许微调缩略图生成,同时保持了需要写入到最低限度的代码量.同时还支持根据一个目录批量生成缩略图. 版本:thumbnailator-0.4.2.jar 原图如下: 1.指定大小进行缩放 复制代码 代码如下: //size(宽度, 高度) /* * 若图片横比200小,高比300小,不变 * 若图片横比200小,高比300大,高

  • Windows中使用Java生成Excel文件并插入图片的方法

    生成简单的Excel文件  在现实的办公中,我们常常会有这样一个要求:要求把报表直接用excel打开.在实习中有这样一个需求.根据所选择的资源查询用户所提供附件的全部信息并生成excel供下载.但是在查询的时候我们需要来检测用户所提供的附件里面的信息是否有错误(身份证).有错误的生成错误信息excel.      Apache的POI项目,是目前比较成熟的HSSF接口,用来处理Excel对象.其实POI不仅仅只能处理excel,它还可以处理word.PowerPoint.Visio.甚至Outl

  • Java图片裁剪和生成缩略图的实例方法

    一.缩略图 在浏览相册的时候,可能需要生成相应的缩略图. 直接上代码: public class ImageUtil { private Logger log = LoggerFactory.getLogger(getClass()); private static String DEFAULT_PREVFIX = "thumb_"; private static Boolean DEFAULT_FORCE = false;//建议该值为false /** * <p>Tit

  • java生成缩略图的方法示例

    本文实例讲述了java生成缩略图的方法.分享给大家供大家参考,具体如下: package com.util; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import javax.imageio.ImageIO; /** * 生成压缩图 * */ public class ImageScale { private int width; private int heigh

  • java/word+fusionchart生成图表深入分析

    一个朋友的项目里用到了fusionchart,同时需要提供多个报表的word下载功能. 毫无疑问,只是一个很棘手的问题. fusionchart提供了服务端和客户端生成图片的功能,都是基于client端展示了flash以后做的. 朋友的项目是基于linux的,office本身的那套com机制是没办法通过jacob调用了. 纯java的操作word,POI和docx4j,可以生成word文档,table,插入图片. 一个可行的思路是点击下载报表时,先在一个新页面打开各个flash的图表,再依次调用

  • 用java实现的获取优酷等视频缩略图的实现代码

    想要php版的朋友可以到这里下载测试 http://www.jb51.net/codes/83179.html 复制代码 代码如下: import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.net.MalformedURLException; import java.net.URL; import net.sf.json.*; public c

  • java根据url抓取并生成缩略图的示例

    java根据url抓取并生成缩略图 复制代码 代码如下: public static Bitmap loadImageFromUrl(String url, int sc) {        URL m;        InputStream i = null;        BufferedInputStream bis = null;        ByteArrayOutputStream out = null;        byte isBuffer[] = new byte[1024

  • java生成图片验证码示例程序

    复制代码 代码如下: <%@ page language="java" contentType="text/html; charset=UTF-8"    pageEncoding="UTF-8"%><html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">&l

随机推荐