1   /****************************************************************************
2    **
3    ** This file is part of the yFiles extension package ySVG-2.3.
4    ** 
5    ** yWorks proprietary/confidential. Use is subject to license terms.
6    **
7    ** Redistribution of this file or of an unauthorized byte-code version
8    ** of this file is strictly forbidden.
9    **
10   ** Copyright (c) 2002-2010 by yWorks GmbH, Vor dem Kreuzberg 28,
11   ** 72070 Tuebingen, Germany. All rights reserved.
12   **
13   ***************************************************************************/
14  package demo.yext.svg;
15  
16  import yext.svg.io.SVGIOHandler;
17  import yext.svg.io.SVGZIOHandler;
18  
19  import y.io.SuffixFileFilter;
20  import y.option.ConstraintManager;
21  import y.option.OptionGroup;
22  import y.option.OptionHandler;
23  import y.util.D;
24  import y.view.Arrow;
25  import y.view.DefaultBackgroundRenderer;
26  import y.view.Graph2D;
27  import y.view.Graph2DView;
28  
29  import java.awt.EventQueue;
30  import java.awt.Point;
31  import java.awt.Rectangle;
32  import java.awt.event.ActionEvent;
33  import java.io.IOException;
34  import javax.swing.AbstractAction;
35  import javax.swing.Action;
36  import javax.swing.JFileChooser;
37  import javax.swing.JToolBar;
38  
39  /** 
40   *  Demonstrates how to export a graph to SVG or SVGZ. 
41   */
42  public class SVGExportDemo extends ViewActionDemo
43  {
44    /**
45     * Initializes this demo.
46     */
47    public SVGExportDemo() {
48      view.getGraph2D().getDefaultEdgeRealizer().setTargetArrow(Arrow.STANDARD);
49    }
50  
51    /**
52     * Creates a toolbar for this demo.
53     */
54    protected JToolBar createToolBar()
55    {
56      JToolBar jtb = super.createToolBar();
57      jtb.addSeparator();
58      jtb.add(new ExportAction(createSVGIOHandler(false), createSVGIOHandler(true)));
59      return jtb;
60    }
61    
62    /**
63     * Creates and configures the SVG output handlers to be used.
64     * @param svgz  <code>true</code> if the returned ouput handler should
65     * compress the generated SVG documents; <code>false</code> otherwise.
66     * @return an output handler that generates SVG documents.
67     */
68    protected SVGIOHandler createSVGIOHandler(boolean svgz)
69    {
70      return svgz ? new SVGZIOHandler() : new SVGIOHandler();
71    }
72      
73    /**
74     * Action that exports the given graph to SVG format
75     */
76    class ExportAction extends AbstractAction
77    {
78      SVGIOHandler svg;
79      SVGIOHandler svgz;
80      OptionHandler options;
81  
82      ExportAction( SVGIOHandler svg, SVGIOHandler svgz ) {
83        final String name = "SVG Export";
84        putValue(Action.NAME, name);
85        putValue(Action.SHORT_DESCRIPTION, "Exports the displayed graph to a SVG document.");
86  
87        this.svg  = svg;
88        this.svgz = svgz;
89  
90        options = new OptionHandler(name);
91        final OptionGroup group = new OptionGroup();
92        group.setAttribute(OptionGroup.ATTRIBUTE_TITLE, name + " Options");
93        group.addItem(options.addBool("Compressed Output (SVGZ)", false));
94        group.addItem(options.addEnum("Size", new String[]{"Use Original Size", "Use Custom Width", "Use Custom Height"}, 0));
95        group.addItem(options.addInt("Custom Width",  500));
96        group.addItem(options.addInt("Custom Height", 500));
97        group.addItem(options.addInt("Empty Border Width", 10));
98        group.addItem(options.addEnum("Clip Region", new String[]{"Graph","View"}, 0));
99        group.addItem(options.addBool("Transparent Background", true));
100 
101       final ConstraintManager cm = new ConstraintManager(options);
102       cm.setEnabledOnValueEquals("Size", "Use Custom Width", "Custom Width");
103       cm.setEnabledOnValueEquals("Size", "Use Custom Height", "Custom Height");
104     }
105 
106 
107     void configureViewPort(Graph2DView viewPort)
108     {
109       Graph2D graph = view.getGraph2D();
110       
111       double width  = options.getInt("Custom Width");
112       double height = options.getInt("Custom Height");
113       Point viewPoint = viewPort.getViewPoint();
114       double zoom = 1.0;
115       
116       if ("Graph".equals(options.get("Clip Region")))
117       {       
118         Rectangle box = graph.getBoundingBox();
119         int border = options.getInt("Empty Border Width");
120         box.width  += 2*border;
121         box.height += 2*border;
122         box.x -= border;
123         box.y -= border;
124         
125         if ("Use Custom Height".equals(options.get("Size")))
126         {
127           width = height*box.getWidth()/box.getHeight();
128         }
129         else if ("Use Custom Width".equals(options.get("Size")))
130         {
131           height = width*box.getHeight()/box.getWidth();
132         }
133         else
134         {
135           width =  box.getWidth();
136           height = box.getHeight();
137         }
138         zoom = width/box.getWidth();
139         viewPoint = new Point(box.x, box.y);
140       }
141       else if ("View".equals(options.get("Clip Region")))
142       {
143         if ("Use Custom Height".equals(options.get("Size")))
144         {
145           width = height*view.getWidth()/view.getHeight();
146         }
147         else if ("Use Custom Width".equals(options.get("Size")))
148         {
149           height = width*view.getHeight()/view.getWidth();
150         }
151         else
152         {
153           width =  view.getWidth();
154           height = view.getHeight();
155         }
156         viewPoint = view.getViewPoint();
157         zoom = view.getZoom()*width/view.getWidth();
158       }
159       
160       viewPort.setZoom(zoom);
161       viewPort.setSize((int)width, (int)height);
162       viewPort.setViewPoint(viewPoint.x, viewPoint.y);
163     }
164     
165     public void actionPerformed(ActionEvent e)
166     {
167       if (!options.showEditor()) {
168         return;
169       }
170       
171       SVGIOHandler ioh = options.getBool("Compressed Output (SVGZ)") ? svgz : svg;
172       Graph2D graph = view.getGraph2D();
173       Graph2DView viewPort = ioh.createDefaultGraph2DView(graph);
174       configureViewPort(viewPort);
175       if (options.getBool("Transparent Background")) {
176         DefaultBackgroundRenderer dbr = new DefaultBackgroundRenderer(viewPort);
177         dbr.setColor(null);
178         viewPort.setBackgroundRenderer(dbr);
179       }
180       graph.setCurrentView(viewPort);
181       
182       export(ioh);
183       
184       graph.removeView(viewPort); //unregister viewport as view 
185     }
186     
187     void export(SVGIOHandler ioh)
188     {
189       JFileChooser chooser = new JFileChooser();
190       chooser.setAcceptAllFileFilterUsed(false);
191       String fne = ioh.getFileNameExtension(); 
192       chooser.setFileFilter(new SuffixFileFilter(
193         fne, ioh.getFileFormatString()));
194       
195       if (chooser.showSaveDialog(SVGExportDemo.this) == JFileChooser.APPROVE_OPTION)
196       {
197         String name = chooser.getSelectedFile().toString();
198         if (!name.endsWith(fne)) {
199           name = name + '.' + fne;
200         }
201         
202         try {
203           double pdt = view.getPaintDetailThreshold();
204           view.setPaintDetailThreshold(0.0);
205           ioh.write( view.getGraph2D(), name );
206           view.setPaintDetailThreshold(pdt);
207         }
208         catch(IOException ex) 
209         {
210           D.show(ex);
211         }
212       }
213     }
214   }
215   
216   /**
217    * Launches this demo.
218    * @param args ignored.
219    */
220   public static void main(String[] args) {
221     EventQueue.invokeLater(new Runnable() {
222       public void run() {
223         initLnF();
224         (new SVGExportDemo()).start();
225       }
226     });
227   }
228 }