纯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='/2000/svg'");
sfile.append("\n");
sfile.append("xmlns='/2000/svg'");
sfile.append("\n");
sfile.append("xmlns:xlink='/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='/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>");
String();
}
public static String creatPath(double x0,double y0,double r,double[]fenshu){
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 = und(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='"+(s(sita)*lineLen)+"' y2='"+(middleY-(Math.sin(sita)*lineLen))+"' stroke='#0000 sfile.append("\n");
sfile.append("<text x='"+(s(sita)*textLen)+"' y='"+(middleY-(Math.sin(sita)*textLen))+"' space='preserve' font-family='Tahoma' font-size=' }else if ((textRadian>(Math.PI/2)&&textRadian<Math.PI)){
sfile.append("<line x1='"+middleX+"' y1='"+middleY+"' x2='"+(s(sita)*lineLen)+"' y2='"+(middleY-(Math.sin(sita)*lineLen))+"' stroke='#0000 sfile.append("\n");
sfile.append("<text x='"+(s(sita)*textLen)+"' y='"+(middleY-(Math.sin(sita)*textLen))+"' space='preserve' font-family='Tahoma' font-size='2 }else if ((textRadian>(Math.PI)&&textRadian<(Math.PI*3/2))){
sfile.append("<line x1='"+middleX+"' y1='"+middleY+"' x2='"+(s(sita)*lineLen)+"' y2='"+(middleY+(Math.sin(sita)*lineLen))+"' stroke='#0000 sfile.append("\n");
sfile.append("<text x='"+(s(sita)*textLen)+"' y='"+(middleY+(Math.sin(sita)*textLen))+"' space='preserve' font-family='Tahoma' font-size='2 }else if((textRadian>(Math.PI*3/2)&&textRadian<(Math.PI*2))){
sfile.append("<line x1='"+middleX+"' y1='"+middleY+"' x2='"+(s(sita)*lineLen)+"' y2='"+(middleY+Math.sin(sita)*lineLen)+"' stroke='#0000 sfile.append("\n");
sfile.append("<text x='"+(s(sita)*textLen)+"' y='"+(middleY+(Math.sin(sita)*textLen))+"' space='preserve' font-family='Tahoma' font-size=' }
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 = und(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='"+(s(sita)*lineLen)+"' y2='"+(middleY-(Math.sin(sita)*lineLen))+"' stroke
sfile.append("\n");
sfile.append("<text x='"+(s(sita)*textLen)+"' y='"+(middleY-(Math.sin(sita)*textLen))+"' space='preserve' font-family='Tahoma' font-size=' }else if ((textRadian>(Math.PI/2)&&textRadian<Math.PI)){
sfile.append("<line x1='"+middleX+"' y1='"+middleY+"' x2='"+(s(sita)*lineLen)+"' y2='"+(middleY-(Math.sin(sita)*lineLen))+"' stroke='#0000 sfile.append("\n");
sfile.append("<text x='"+(s(sita)*textLen)+"' y='"+(middleY-(Math.sin(sita)*textLen))+"' space='preserve' font-family='Tahoma' font-size='2 }else if ((textRadian>(Math.PI)&&textRadian<(Math.PI*3/2))){
sfile.append("<line x1='"+middleX+"' y1='"+middleY+"' x2='"+(s(sita)*lineLen)+"' y2='"+(middleY+(Math.sin(sita)*lineLen))+"' stroke='#0000 sfile.append("\n");
sfile.append("<text x='"+(s(sita)*textLen)+"' y='"+(middleY+(Math.sin(sita)*textLen))+"' space='preserve' font-family='Tahoma' font-size='2 }else if((textRadian>(Math.PI*3/2)&&textRadian<(Math.PI*2))){
sfile.append("<line x1='"+middleX+"' y1='"+middleY+"' x2='"+(s(sita)*lineLen)+"' y2='"+(middleY+Math.sin(sita)*lineLen)+"' stroke='#0000 sfile.append("\n");
sfile.append("<text x='"+(s(sita)*textLen)+"' y='"+(middleY+(Math.sin(sita)*textLen))+"' space='preserve' font-family='Tahoma' font-size=' }
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= }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' }
sfile.append("\n");
}
}
String();
}
//返回弧度
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){
s(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 = Bytes("UTF-8");
File svgFile = new File(fileRealPath);
if (ists()) {
svgFile.delete();
}
FileOutputStream fos = new FileOutputStream(svgFile);
fos.write(byteFil);
fos.close();
} catch (Exception ex) {
System.out.Message());
}
}
}
⼆、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='/2000/svg'");
sfile.append("\n");
sfile.append("xmlns='/2000/svg'");
sfile.append("\n");
sfile.append("xmlns:xlink='/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='/2000/svg'>"); sfile.append("\n");
//循环创造path标签.
String path =creatPath(502, 300, 300, fenshu);
String path =creatPath(502, 300, 300, fenshu);
sfile.append(path);
sfile.append("</g>");
sfile.append("\n");
sfile.append("</svg>");
String();
}
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 = und(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='"+(s(sita)*lineLen)+"' y2='"+(middleY-(Math.sin(sita)*lineLen))+"' stroke='#0000 sfile.append("\n");
sfile.append("<text x='"+(s(sita)*textLen)+"' y='"+(middleY-(Math.sin(sita)*textLen))+"' space='preserve' font-family='Tahoma' font-size=' }else if ((textRadian>(Math.PI/2)&&textRadian<Math.PI)){
sfile.append("<line x1='"+middleX+"' y1='"+middleY+"' x2='"+(s(sita)*lineLen)+"' y2='"+(middleY-(Math.sin(sita)*lineLen))+"' stroke='#0000 sfile.append("\n");
sfile.append("<text x='"+(s(sita)*textLen)+"' y='"+(middleY-(Math.sin(sita)*textLen))+"' space='preserve' font-family='Tahoma' font-size='2 }else if ((textRadian>(Math.PI)&&textRadian<(Math.PI*3/2))){
sfile.append("<line x1='"+middleX+"' y1='"+middleY+"' x2='"+(s(sita)*lineLen)+"' y2='"+(middleY+(Math.sin(sita)*lineLen))+"' stroke='#0000 sfile.append("\n");
sfile.append("<text x='"+(s(sita)*textLen)+"' y='"+(middleY+(Math.sin(sita)*textLen))+"' space='preserve' font-family='Tahoma' font-size='2 }else if((textRadian>(Math.PI*3/2)&&textRadian<(Math.PI*2))){
sfile.append("<line x1='"+middleX+"' y1='"+middleY+"' x2='"+(s(sita)*lineLen)+"' y2='"+(middleY+Math.sin(sita)*lineLen)+"' stroke='#0000 sfile.append("\n");
sfile.append("<text x='"+(s(sita)*textLen)+"' y='"+(middleY+(Math.sin(sita)*textLen))+"' space='preserve' font-family='Tahoma' font-size=' }
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]+"' οnmοuseοver='ccolor(evt) }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]+"' οnmοuseοver='ccolor(evt) }
sfile.append("\n");svg图形
}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 = und(fenshu[i]*100)/100.0;
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论