A discussion forum for JFreeChart (a 2D chart library for the Java platform).
-
Zappo
- Posts: 9
- Joined: Thu Jan 31, 2008 8:53 pm
Post
by Zappo » Wed Feb 13, 2008 11:15 am
Hi all!
I'd like to be able to export a chart to some kind of vector image format, such as WMF or EPS.
I've searched the forums and I've found several ways to create vector files, but all of them actually still result in a bitmap; what I'm trying to do is a "real" vector export, containing the actual lines and whatnot, that can be arbitrarily zoomed.
Has anyone done any work to this purpose? Are there any libraries I could use? Any help would be useful.

-
Zappo
- Posts: 9
- Joined: Thu Jan 31, 2008 8:53 pm
Post
by Zappo » Wed Feb 13, 2008 12:34 pm
I haven't tried anything specific yet, I'm still looking around for the best solution. Unfortunately, while I've seen several ways to create images in a vector format, none of them create actual vector images. They're all bitmaps embedded in a vector format, which kinda defeats the purpose. I'm really interested in seeing your sample code.

-
mhilpert
- Posts: 497
- Joined: Wed Apr 02, 2003 1:57 pm
- Location: Germany
Post
by mhilpert » Wed Feb 13, 2008 1:31 pm
Code: Select all
/**
* Save chart as SVG file.
* Required libs: Apache Batik (batik-svggen.jar, batik-dom.jar, dom.jar).
*
* @param chart JFreeChart to save.
* @param fileName Name of file to save chart in.
* @param width Width of chart graphic.
* @param height Height of chart graphic.
* @return Final file name used.
* @throws IOException if failed.
*/
static public final String saveChartToSVG(final JFreeChart chart, String fileName, final int width, final int height) throws IOException {
String result = null;
if (chart != null) {
if (fileName == null) {
final String chartTitle = chart.getTitle().getText();
if (chartTitle != null) {
fileName = chartTitle;
} else {
fileName = "chart";
}
}
result = fileName + ".svg";
final DOMImplementation domImpl = GenericDOMImplementation.getDOMImplementation();
final Document document = domImpl.createDocument(null, "svg", null);
final SVGGraphics2D svgGenerator = new SVGGraphics2D(document);
// svgGenerator.getGeneratorContext().setEmbeddedFontsOn(true); //embed fonts
//set anti-aliasing bug fix for SVG generator:
//setting rendering hints of svgGenerator doesn't help as it seems to use the rendering hints from the chart
final boolean antiAlias = isAntiAliasOn(chart);
final RenderingHints rh = chart.getRenderingHints();
if (antiAlias) {
rh.put(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
rh.put(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_OFF); //fix
} else {
rh.put(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF);
rh.put(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON); //fix
}
// svgGenerator.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
// svgGenerator.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_OFF);
// svgGenerator.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
// svgGenerator.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_QUALITY);
// svgGenerator.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
// svgGenerator.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
chart.draw(svgGenerator, new Rectangle2D.Double(0, 0, width, height), new ChartRenderingInfo());
//undo anti-aliasing bugfix settings for chart to use correct settings:
if (antiAlias) {
rh.put(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
rh.put(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
} else {
rh.put(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF);
rh.put(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_OFF);
}
final boolean useCSS = true;
Writer out = null;
try {
out = new OutputStreamWriter(new BufferedOutputStream(new FileOutputStream(new File(result), false)),"iso-8859-1"); //UTF-8
svgGenerator.stream(out, useCSS);
} finally {
svgGenerator.dispose();
IOUtils.close(out);
}
}//else: input unavailable
return result;
}//saveChartToSVG()
Java 11, JFreeChart 1.0.15, JFreeSVG 4.0
-
Zappo
- Posts: 9
- Joined: Thu Jan 31, 2008 8:53 pm
Post
by Zappo » Wed Feb 13, 2008 5:14 pm
Thanks mhilpert, that's exactly the sort of thing I'm looking for.
I'll also keep looking for something to export to other formats (WMF/EMF and EPS have been specifically required by my client), but this is a nicely working solution.
-
Taqua
- JFreeReport Project Leader
- Posts: 698
- Joined: Fri Mar 14, 2003 3:34 pm
-
Contact:
Post
by Taqua » Wed Feb 13, 2008 8:00 pm
EPS might be supported by using
FreeHEP.
However, I doubt that you will find a WMF exporter out there - as the WMF format is 100% undocumented and a living nightmare to work with. No sane developer would volunteer to write a WMF generator in Java, I guess
If you are working on Windows anyway, you might have more luck using a native SVG to WMF converter or so. If you feel very adventerous, you could even try to use the OpenOffice-SDK to convert from SVG into WMF. By using the UNO-Interfaces this should be relatively easy - but you will pay for it with a 400+ MB dependency to that office package.
-
paradoxoff
- Posts: 1634
- Joined: Sat Feb 17, 2007 1:51 pm
Post
by paradoxoff » Wed Feb 13, 2008 8:48 pm
As announced....
Code: Select all
import org.apache.xmlgraphics.java2d.ps.EPSDocumentGraphics2D;
import org.freehep.graphicsio.emf.EMFGraphics2D;
public void saveAsEPS(JFreeChart chart,File outfile) throws Exception{
OutputStream out = new java.io.FileOutputStream(outfile);
EPSDocumentGraphics2D g2d = new EPSDocumentGraphics2D(false);
g2d.setGraphicContext(new org.apache.xmlgraphics.java2d.GraphicContext());
int width = 600;
int height = 400;
g2d.setupDocument(out,width, height); //400pt x 200pt
chart.draw(g2d,new Rectangle(width,height));
g2d.finish();
out.flush();
out.close();
}
public void saveAsEMF(JFreeChart chart,File outfile) throws Exception{
OutputStream out = new java.io.FileOutputStream(outfile);
int width = 600;
int height = 400;
EMFGraphics2D g2d = new EMFGraphics2D(out,new Dimension(width,height));
g2d.startExport();
chart.draw((Graphics2D)g2d.create(),new Rectangle(width,height));
g2d.endExport();
g2d.closeStream();
}
Required jars:
xmlgraphics-commons-1.2.jar (apache xml graphics common)
and several freehep-XXX- Jars. I am not sure which jars are the minimum requirement.
I have used the EMF export several times, and the files looked really like vector graphics. They can be imported into MSOffice and zoomed without loosing quality.
Regards, Paradoxoff
-
Zappo
- Posts: 9
- Joined: Thu Jan 31, 2008 8:53 pm
Post
by Zappo » Fri Feb 15, 2008 12:37 pm
Thanks paradoxoff!

That works nice, and the same libraries also support a bunch of other formats. No transparency - I've tried setting up rendering hints, but they don't seem to change anything. No problem, it's not essential.
-
vimal
- Posts: 8
- Joined: Sat Jul 24, 2010 3:38 pm
- antibot: No, of course not.
Post
by vimal » Sun Jul 25, 2010 11:28 am
saveAsEMF method throwing 'java.lang.ArrayIndexOutOfBoundsException: 4'.
Please help me.