1 |
1 |
package org.txm.chartsengine.svgbatik.rcp.swt;
|
|
2 |
|
2 |
3 |
import java.awt.Graphics2D;
|
3 |
4 |
import java.awt.image.BufferedImage;
|
4 |
5 |
import java.io.BufferedOutputStream;
|
... | ... | |
40 |
41 |
* @author sjacquot
|
41 |
42 |
*
|
42 |
43 |
*/
|
43 |
|
public class SVGChartComposite extends SwingChartComposite {
|
44 |
|
|
|
44 |
public class SVGChartComposite extends SwingChartComposite {
|
45 |
45 |
|
|
46 |
|
46 |
47 |
/**
|
47 |
48 |
* The chart SVG file.
|
48 |
49 |
*/
|
... | ... | |
51 |
52 |
|
52 |
53 |
/**
|
53 |
54 |
* Creates a Batik SVG composite.
|
|
55 |
*
|
54 |
56 |
* @param parent
|
55 |
57 |
* @param style
|
56 |
58 |
*/
|
... | ... | |
58 |
60 |
super(chartEditor, parent, SWT.EMBEDDED | SWT.NO_BACKGROUND);
|
59 |
61 |
this.file = null;
|
60 |
62 |
}
|
61 |
|
|
62 |
63 |
|
|
64 |
|
63 |
65 |
@Override
|
64 |
66 |
public void loadChart(Object chart) {
|
65 |
67 |
this.loadSVGDocument((File) chart);
|
66 |
68 |
}
|
67 |
|
|
68 |
69 |
|
69 |
|
|
|
70 |
|
|
71 |
|
70 |
72 |
/**
|
71 |
73 |
* Loads a SVG document from the specified file.
|
|
74 |
*
|
72 |
75 |
* @param file the file to load
|
73 |
76 |
*/
|
74 |
77 |
// FIXME: SJ: we should use Batik listener system to check if the file has been well loaded
|
... | ... | |
84 |
87 |
|
85 |
88 |
this.file = file;
|
86 |
89 |
|
87 |
|
Log.fine(TXMCoreMessages.bind("Loading SVG document from file: {0}...", file.getAbsolutePath()));
|
88 |
|
|
|
90 |
|
89 |
91 |
SwingUtilities.invokeLater(new Runnable() {
|
90 |
|
|
|
92 |
|
91 |
93 |
@Override
|
92 |
94 |
public void run() {
|
93 |
|
|
|
95 |
|
94 |
96 |
try {
|
|
97 |
Log.fine(TXMCoreMessages.bind("Loading SVG document from file: {0}...", file.getAbsolutePath()));
|
|
98 |
|
95 |
99 |
getSVGCanvas().loadSVGDocument(file.toURL().toExternalForm());
|
|
100 |
|
|
101 |
Log.fine(TXMCoreMessages.bind("File {0} loaded.", file.getAbsolutePath()));
|
|
102 |
|
96 |
103 |
}
|
97 |
104 |
catch (Exception e) {
|
98 |
105 |
Log.severe(TXMCoreMessages.bind("Can't load SVG document from file {0}.", file));
|
99 |
106 |
Log.printStackTrace(e);
|
100 |
107 |
}
|
101 |
|
|
|
108 |
|
102 |
109 |
}
|
103 |
110 |
});
|
104 |
111 |
}
|
105 |
|
|
106 |
112 |
|
|
113 |
|
107 |
114 |
/**
|
108 |
115 |
* Gets the SVG document.
|
|
116 |
*
|
109 |
117 |
* @return
|
110 |
118 |
*/
|
111 |
|
public SVGDocument getSVGDocument() {
|
|
119 |
public SVGDocument getSVGDocument() {
|
112 |
120 |
return this.getSVGCanvas().getSVGDocument();
|
113 |
121 |
}
|
114 |
|
|
|
122 |
|
115 |
123 |
/**
|
116 |
124 |
* Gets the SVG canvas chart component.
|
117 |
125 |
* Convenience method for getChartComponent().
|
... | ... | |
121 |
129 |
public SVGCanvas getSVGCanvas() {
|
122 |
130 |
return (SVGCanvas) this.chartComponent;
|
123 |
131 |
}
|
124 |
|
|
125 |
132 |
|
126 |
|
|
|
133 |
|
|
134 |
|
127 |
135 |
@Override
|
128 |
136 |
public void clearChartItemsSelection() {
|
129 |
137 |
Log.severe("SVGChartComposite.clearChartItemsSelection(): not implemented.");
|
130 |
138 |
}
|
131 |
|
|
132 |
|
|
|
139 |
|
|
140 |
|
133 |
141 |
@Override
|
134 |
142 |
protected IChartComponent _createChartComponent() {
|
135 |
143 |
return new SVGCanvas();
|
136 |
144 |
}
|
137 |
|
|
138 |
|
|
|
145 |
|
|
146 |
|
139 |
147 |
@Override
|
140 |
148 |
public File exportView(File file, String fileFormat) {
|
141 |
149 |
// SVG
|
142 |
|
if(fileFormat == ChartsEngine.OUTPUT_FORMAT_SVG) {
|
143 |
|
|
144 |
|
|
145 |
|
|
|
150 |
if (fileFormat == ChartsEngine.OUTPUT_FORMAT_SVG) {
|
|
151 |
|
|
152 |
|
|
153 |
|
146 |
154 |
// FIXME : Batik transcoder version
|
147 |
155 |
// FIXME : the cropping to match view in SVG doesn't work
|
148 |
156 |
try {
|
149 |
|
//AbstractTranscoder imageTranscoder = this.getImageTranscoder(fileFormat);
|
150 |
|
AbstractTranscoder imageTranscoder = new SVGTranscoder();
|
151 |
|
|
152 |
|
|
|
157 |
// AbstractTranscoder imageTranscoder = this.getImageTranscoder(fileFormat);
|
|
158 |
AbstractTranscoder imageTranscoder = new SVGTranscoder();
|
|
159 |
|
|
160 |
|
153 |
161 |
// Transcoder configuration
|
154 |
|
//imageTranscoder.addTranscodingHint(ImageTranscoder.KEY_WIDTH, new Integer(300));
|
155 |
|
|
156 |
|
|
|
162 |
// imageTranscoder.addTranscodingHint(ImageTranscoder.KEY_WIDTH, new Integer(300));
|
|
163 |
|
|
164 |
|
157 |
165 |
// SVG Cropping tests
|
158 |
|
// Rectangle area = new Rectangle(200, 200, 300, 500); // FIXME : how to get the correct area after the charts has been zoomed or moved ?
|
159 |
|
//// imageTranscoder.addTranscodingHint(JPEGTranscoder.KEY_WIDTH, new Float(this.composite.getPanel().getWidth()));
|
160 |
|
//// imageTranscoder.addTranscodingHint(JPEGTranscoder.KEY_HEIGHT, new Float(this.composite.getPanel().getHeight()));
|
161 |
|
// imageTranscoder.addTranscodingHint(JPEGTranscoder.KEY_WIDTH, new Float(20));
|
162 |
|
// imageTranscoder.addTranscodingHint(JPEGTranscoder.KEY_HEIGHT, new Float(20));
|
163 |
|
// imageTranscoder.addTranscodingHint(JPEGTranscoder.KEY_AOI, area);
|
164 |
|
|
165 |
|
|
|
166 |
// Rectangle area = new Rectangle(200, 200, 300, 500); // FIXME : how to get the correct area after the charts has been zoomed or moved ?
|
|
167 |
//// imageTranscoder.addTranscodingHint(JPEGTranscoder.KEY_WIDTH, new Float(this.composite.getPanel().getWidth()));
|
|
168 |
//// imageTranscoder.addTranscodingHint(JPEGTranscoder.KEY_HEIGHT, new Float(this.composite.getPanel().getHeight()));
|
|
169 |
// imageTranscoder.addTranscodingHint(JPEGTranscoder.KEY_WIDTH, new Float(20));
|
|
170 |
// imageTranscoder.addTranscodingHint(JPEGTranscoder.KEY_HEIGHT, new Float(20));
|
|
171 |
// imageTranscoder.addTranscodingHint(JPEGTranscoder.KEY_AOI, area);
|
|
172 |
|
|
173 |
|
166 |
174 |
// Add a viewbox attribute
|
167 |
|
//((Element)this.composite.getSVGDocument().getFirstChild()).setAttribute("viewBox", "20 20 400 350"); // FIXME : how to get the correct area after the charts has been zoomed or moved ?
|
168 |
|
|
|
175 |
// ((Element)this.composite.getSVGDocument().getFirstChild()).setAttribute("viewBox", "20 20 400 350"); // FIXME : how to get the correct area after the charts has been zoomed or moved
|
|
176 |
// ?
|
|
177 |
|
169 |
178 |
// Adjust dimensions from component
|
170 |
|
((Element)this.getSVGDocument().getFirstChild()).setAttribute("width", String.valueOf(this.getSVGCanvas().getWidth()));
|
171 |
|
((Element)this.getSVGDocument().getFirstChild()).setAttribute("height", String.valueOf(this.getSVGCanvas().getHeight()));
|
172 |
|
|
173 |
|
|
|
179 |
((Element) this.getSVGDocument().getFirstChild()).setAttribute("width", String.valueOf(this.getSVGCanvas().getWidth()));
|
|
180 |
((Element) this.getSVGDocument().getFirstChild()).setAttribute("height", String.valueOf(this.getSVGCanvas().getHeight()));
|
|
181 |
|
|
182 |
|
174 |
183 |
TranscoderInput input = new TranscoderInput(this.getSVGDocument());
|
175 |
|
|
|
184 |
|
176 |
185 |
// SVGTranscoder needs an OutputStreamWriter, not an OutputStream
|
177 |
|
if(imageTranscoder instanceof SVGTranscoder) {
|
178 |
|
|
|
186 |
if (imageTranscoder instanceof SVGTranscoder) {
|
|
187 |
|
179 |
188 |
FileWriter outputStreamWriter = new FileWriter(file);
|
180 |
189 |
imageTranscoder.transcode(input, new TranscoderOutput(outputStreamWriter));
|
181 |
|
|
|
190 |
|
182 |
191 |
outputStreamWriter.flush();
|
183 |
192 |
outputStreamWriter.close();
|
184 |
193 |
}
|
185 |
|
// else {
|
186 |
|
// OutputStream outputStream = new FileOutputStream(file);
|
187 |
|
// TranscoderOutput output = new TranscoderOutput(outputStream);
|
188 |
|
//
|
189 |
|
// imageTranscoder.transcode(input, output);
|
190 |
|
//
|
191 |
|
// outputStream.flush();
|
192 |
|
// outputStream.close();
|
193 |
|
// }
|
|
194 |
// else {
|
|
195 |
// OutputStream outputStream = new FileOutputStream(file);
|
|
196 |
// TranscoderOutput output = new TranscoderOutput(outputStream);
|
|
197 |
//
|
|
198 |
// imageTranscoder.transcode(input, output);
|
|
199 |
//
|
|
200 |
// outputStream.flush();
|
|
201 |
// outputStream.close();
|
|
202 |
// }
|
194 |
203 |
}
|
195 |
|
catch(FileNotFoundException e) {
|
|
204 |
catch (FileNotFoundException e) {
|
196 |
205 |
// TODO Auto-generated catch block
|
197 |
206 |
e.printStackTrace();
|
198 |
207 |
}
|
199 |
|
catch(TranscoderException e) {
|
|
208 |
catch (TranscoderException e) {
|
200 |
209 |
// TODO Auto-generated catch block
|
201 |
210 |
e.printStackTrace();
|
202 |
211 |
}
|
203 |
|
catch(IOException e) {
|
|
212 |
catch (IOException e) {
|
204 |
213 |
// TODO Auto-generated catch block
|
205 |
214 |
e.printStackTrace();
|
206 |
215 |
}
|
207 |
|
|
208 |
|
|
209 |
|
|
|
216 |
|
|
217 |
|
|
218 |
|
210 |
219 |
// FIXME : SVG via Batik
|
211 |
|
// FIXME : it saves the JPanel content as image raster tag in the SVG instead of creating real SVG shapes tag
|
212 |
|
|
213 |
|
// // Get a DOMImplementation
|
214 |
|
// DOMImplementation domImpl = GenericDOMImplementation.getDOMImplementation();
|
215 |
|
//
|
216 |
|
// String svgNS = "http://www.w3.org/2000/svg";
|
217 |
|
// Document document = domImpl.createDocument(svgNS, "svg", null);
|
218 |
|
//
|
219 |
|
// SVGGraphics2D svgGenerator = new SVGGraphics2D(document);
|
220 |
|
//
|
221 |
|
// // Paint in the SVGGraphics2D implementation
|
222 |
|
// //this.composite.getPanel().getSVGCanvas().paint(svgGenerator);
|
223 |
|
// this.composite.getPanel().paint(svgGenerator);
|
224 |
|
//
|
225 |
|
// boolean useCSS = true;
|
226 |
|
//
|
227 |
|
// try {
|
228 |
|
// Writer out = new FileWriter(file);
|
229 |
|
// svgGenerator.stream(out, useCSS);
|
230 |
|
// }
|
231 |
|
// catch(UnsupportedEncodingException e) {
|
232 |
|
// // TODO Auto-generated catch block
|
233 |
|
// e.printStackTrace();
|
234 |
|
// }
|
235 |
|
// catch(SVGGraphics2DIOException e) {
|
236 |
|
// // TODO Auto-generated catch block
|
237 |
|
// e.printStackTrace();
|
238 |
|
// }
|
239 |
|
// catch(IOException e) {
|
240 |
|
// // TODO Auto-generated catch block
|
241 |
|
// e.printStackTrace();
|
242 |
|
// }
|
243 |
|
//
|
244 |
|
|
245 |
|
|
246 |
|
|
|
220 |
// FIXME : it saves the JPanel content as image raster tag in the SVG instead of creating real SVG shapes tag
|
|
221 |
|
|
222 |
// // Get a DOMImplementation
|
|
223 |
// DOMImplementation domImpl = GenericDOMImplementation.getDOMImplementation();
|
|
224 |
//
|
|
225 |
// String svgNS = "http://www.w3.org/2000/svg";
|
|
226 |
// Document document = domImpl.createDocument(svgNS, "svg", null);
|
|
227 |
//
|
|
228 |
// SVGGraphics2D svgGenerator = new SVGGraphics2D(document);
|
|
229 |
//
|
|
230 |
// // Paint in the SVGGraphics2D implementation
|
|
231 |
// //this.composite.getPanel().getSVGCanvas().paint(svgGenerator);
|
|
232 |
// this.composite.getPanel().paint(svgGenerator);
|
|
233 |
//
|
|
234 |
// boolean useCSS = true;
|
|
235 |
//
|
|
236 |
// try {
|
|
237 |
// Writer out = new FileWriter(file);
|
|
238 |
// svgGenerator.stream(out, useCSS);
|
|
239 |
// }
|
|
240 |
// catch(UnsupportedEncodingException e) {
|
|
241 |
// // TODO Auto-generated catch block
|
|
242 |
// e.printStackTrace();
|
|
243 |
// }
|
|
244 |
// catch(SVGGraphics2DIOException e) {
|
|
245 |
// // TODO Auto-generated catch block
|
|
246 |
// e.printStackTrace();
|
|
247 |
// }
|
|
248 |
// catch(IOException e) {
|
|
249 |
// // TODO Auto-generated catch block
|
|
250 |
// e.printStackTrace();
|
|
251 |
// }
|
|
252 |
//
|
|
253 |
|
|
254 |
|
|
255 |
|
247 |
256 |
// FIXME : SVG via JFreeSVG : doesn't work
|
248 |
|
// SVGGraphics2D g2 = new SVGGraphics2D(this.composite.getPanel().getWidth(), this.composite.getPanel().getHeight());
|
249 |
|
//
|
250 |
|
// // suppress shadow generation, because SVG is a vector format and
|
251 |
|
// // the shadow effect is applied via bitmap effects...
|
252 |
|
// g2.setRenderingHint(JFreeChart.KEY_SUPPRESS_SHADOW_GENERATION, true);
|
253 |
|
// String svg = null;
|
254 |
|
// this.composite.
|
255 |
|
// getPanel().
|
256 |
|
// paintAll(g2);
|
257 |
|
// svg = g2.getSVGElement();
|
258 |
|
//
|
259 |
|
// if (file != null) {
|
260 |
|
// BufferedWriter writer = null;
|
261 |
|
// try {
|
262 |
|
// writer = new BufferedWriter(new FileWriter(file));
|
263 |
|
// writer.write("<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n");
|
264 |
|
// writer.write(svg + "\n");
|
265 |
|
// writer.flush();
|
266 |
|
// }
|
267 |
|
// catch(IOException e) {
|
268 |
|
// // TODO Auto-generated catch block
|
269 |
|
// e.printStackTrace();
|
270 |
|
// }
|
271 |
|
// finally {
|
272 |
|
// try {
|
273 |
|
// if (writer != null) {
|
274 |
|
// writer.close();
|
275 |
|
// }
|
276 |
|
// }
|
277 |
|
// catch (IOException ex) {
|
278 |
|
// throw new RuntimeException(ex);
|
279 |
|
// }
|
280 |
|
// }
|
281 |
|
//
|
282 |
|
// }
|
283 |
|
|
284 |
|
|
285 |
|
|
286 |
|
|
|
257 |
// SVGGraphics2D g2 = new SVGGraphics2D(this.composite.getPanel().getWidth(), this.composite.getPanel().getHeight());
|
|
258 |
//
|
|
259 |
// // suppress shadow generation, because SVG is a vector format and
|
|
260 |
// // the shadow effect is applied via bitmap effects...
|
|
261 |
// g2.setRenderingHint(JFreeChart.KEY_SUPPRESS_SHADOW_GENERATION, true);
|
|
262 |
// String svg = null;
|
|
263 |
// this.composite.
|
|
264 |
// getPanel().
|
|
265 |
// paintAll(g2);
|
|
266 |
// svg = g2.getSVGElement();
|
|
267 |
//
|
|
268 |
// if (file != null) {
|
|
269 |
// BufferedWriter writer = null;
|
|
270 |
// try {
|
|
271 |
// writer = new BufferedWriter(new FileWriter(file));
|
|
272 |
// writer.write("<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n");
|
|
273 |
// writer.write(svg + "\n");
|
|
274 |
// writer.flush();
|
|
275 |
// }
|
|
276 |
// catch(IOException e) {
|
|
277 |
// // TODO Auto-generated catch block
|
|
278 |
// e.printStackTrace();
|
|
279 |
// }
|
|
280 |
// finally {
|
|
281 |
// try {
|
|
282 |
// if (writer != null) {
|
|
283 |
// writer.close();
|
|
284 |
// }
|
|
285 |
// }
|
|
286 |
// catch (IOException ex) {
|
|
287 |
// throw new RuntimeException(ex);
|
|
288 |
// }
|
|
289 |
// }
|
|
290 |
//
|
|
291 |
// }
|
|
292 |
|
|
293 |
|
|
294 |
|
|
295 |
|
287 |
296 |
}
|
288 |
297 |
// PDF (using Lowagie iTtext lib)
|
289 |
|
else if(fileFormat == ChartsEngine.OUTPUT_FORMAT_PDF) {
|
290 |
|
|
|
298 |
else if (fileFormat == ChartsEngine.OUTPUT_FORMAT_PDF) {
|
|
299 |
|
291 |
300 |
Document document = new Document(new Rectangle(0, 0, this.getSVGCanvas().getWidth(), this.getSVGCanvas().getHeight()));
|
292 |
301 |
try {
|
293 |
|
|
|
302 |
|
294 |
303 |
PdfWriter writer = PdfWriter.getInstance(document, new BufferedOutputStream(new FileOutputStream(file)));
|
295 |
304 |
document.open();
|
296 |
305 |
PdfContentByte cb = writer.getDirectContent();
|
297 |
|
|
|
306 |
|
298 |
307 |
Graphics2D g = cb.createGraphics(this.getSVGCanvas().getWidth(), this.getSVGCanvas().getHeight());
|
299 |
308 |
this.getSVGCanvas().printAll(g);
|
300 |
309 |
g.dispose();
|
301 |
|
}
|
302 |
|
catch (Exception e) {
|
303 |
|
e.printStackTrace();
|
304 |
|
}
|
305 |
|
document.close();
|
|
310 |
}
|
|
311 |
catch (Exception e) {
|
|
312 |
e.printStackTrace();
|
|
313 |
}
|
|
314 |
document.close();
|
306 |
315 |
}
|
307 |
|
// FIXME: SJ: this code should be moved to parent class SwingChartComposite
|
|
316 |
// FIXME: SJ: this code should be moved to parent class SwingChartComposite
|
308 |
317 |
// Raster (using AWT/Swing methods)
|
309 |
318 |
else {
|
310 |
319 |
BufferedImage image = new BufferedImage(this.getSVGCanvas().getWidth(), this.getSVGCanvas().getHeight(), BufferedImage.TYPE_INT_RGB);
|
... | ... | |
318 |
327 |
e.printStackTrace();
|
319 |
328 |
}
|
320 |
329 |
}
|
321 |
|
|
|
330 |
|
322 |
331 |
return file;
|
323 |
332 |
}
|
324 |
|
|
325 |
|
|
|
333 |
|
|
334 |
|
326 |
335 |
@Override
|
327 |
|
public ArrayList<String> getEditorSupportedExportFileFormats() {
|
328 |
|
|
329 |
|
ArrayList<String> supportedExportFileFormats = new ArrayList<String>(5);
|
330 |
|
|
|
336 |
public ArrayList<String> getEditorSupportedExportFileFormats() {
|
|
337 |
|
|
338 |
ArrayList<String> supportedExportFileFormats = new ArrayList<>(5);
|
|
339 |
|
331 |
340 |
supportedExportFileFormats.add(ChartsEngine.OUTPUT_FORMAT_SVG); // Default format
|
332 |
341 |
supportedExportFileFormats.add(ChartsEngine.OUTPUT_FORMAT_PDF);
|
333 |
|
|
|
342 |
|
334 |
343 |
// Auto-populate supported output file raster formats from available image writers
|
335 |
344 |
ChartsEngine.populateSupportedOutputRasterFileFormats(supportedExportFileFormats);
|
336 |
|
|
337 |
|
|
|
345 |
|
|
346 |
|
338 |
347 |
return supportedExportFileFormats;
|
339 |
|
|
|
348 |
|
340 |
349 |
}
|
341 |
350 |
|
342 |
351 |
}
|