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("");
 sfile.append("\n");
 sfile.append("");
  sfile.append("\n");
  sfile.append("");
  sfile.append("\n");
  sfile.append("");
  sfile.append("\n");
  //循环创造path标签.
  String path =creatPath(502, 300, 300, percents,names);//中心点式503,300.
  sfile.append(path);
  sfile.append("");
  sfile.append("\n");
  sfile.append("");
 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");
    sfile.append("\n");
    sfile.append(""+percent+"%");
   }else if ((textRadian>(Math.PI/2)&&textRadian");
    sfile.append("\n");
    sfile.append(""+percent+"%");
   }else if ((textRadian>(Math.PI)&&textRadian<(Math.PI*3/2))){
    sfile.append("");
    sfile.append("\n");
    sfile.append(""+percent+"%");
   }else if((textRadian>(Math.PI*3/2)&&textRadian<(Math.PI*2))){
    sfile.append("");
    sfile.append("\n");
    sfile.append(""+percent+"%");
   }
   sfile.append("\n"); 
   if(getRadian(percents[0])>Math.PI){
   sfile.append("");
   }else{
   sfile.append("");
   }
   sfile.append("\n");
   }
   sfile.append("");
   sfile.append("\n"); 
   sfile.append(""+names[0]+"");
   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("");
    sfile.append("\n");
    sfile.append(""+percent+"%");
   }else if ((textRadian>(Math.PI/2)&&textRadian");
    sfile.append("\n");
    sfile.append(""+percent+"%");
   }else if ((textRadian>(Math.PI)&&textRadian<(Math.PI*3/2))){
    sfile.append("");
    sfile.append("\n");
    sfile.append(""+percent+"%");
   }else if((textRadian>(Math.PI*3/2)&&textRadian<(Math.PI*2))){
    sfile.append("");
    sfile.append("\n");
    sfile.append(""+percent+"%");
   }
  sfile.append("\n");
  // 参数 1 表示 画大于180的弧, 0 表示画小于180的弧 (这个地方比较重要)
  if(getRadian(percents[i])>Math.PI){
   sfile.append("");
  }else{
    sfile.append("");
  }
  sfile.append("\n");
  }
  N+=50;
   sfile.append("");
   sfile.append("\n"); 
   sfile.append(""+names[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) {
 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 
 

二.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(""); 
  sfile.append("\n"); 
  sfile.append(""); 
  sfile.append("\n"); 
  sfile.append(""); 
  sfile.append("\n"); 
  String path = createPath(502, 300,300, 150, percents); 
  sfile.append(path); 
  sfile.append(""); 
  sfile.append("\n"); 
  sfile.append(""); 
  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(""); 
  sfile.append("\n"); 
  for(int i=0;iMath.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&&radianMath.PI*3/2&&radianMath.PI){//大于 PI 弧度,即百分比超过50% 
     sfile.append(""); 
     sfile.append("\n"); 
     sfile.append(""); 
     sfile.append("\n"); 
     sfile.append(""); 
     sfile.append("\n"); 
     sfile.append(""); 
     sfile.append("\n"); 
     sfile.append(""); 
     sfile.append("\n"); 
    }else{ 
     sfile.append(""); 
     sfile.append("\n"); 
     sfile.append(""); 
     sfile.append("\n"); 
     sfile.append(""); 
     sfile.append("\n"); 
     sfile.append(""); 
     sfile.append("\n"); 
     sfile.append(""); 
     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(radianMath.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&&radianMath.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(""); 
     sfile.append("\n"); 
     sfile.append(""); 
     sfile.append("\n"); 
     sfile.append(""); 
     sfile.append("\n"); 
     sfile.append(""); 
     sfile.append("\n"); 
     sfile.append(""); 
     sfile.append("\n"); 
    }else{ 
     System.out.println("小于pi"); 
     sfile.append(""); 
     sfile.append("\n"); 
     sfile.append(""); 
     sfile.append("\n"); 
     sfile.append(""); 
     sfile.append("\n"); 
     sfile.append(""); 
     sfile.append("\n"); 
     sfile.append(""); 
     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 
  

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

你可能感兴趣的:(java生成饼图svg及JFreeChart生成svg图表)