1 | using System;
|
---|
2 | using System.Diagnostics;
|
---|
3 | using System.Xml;
|
---|
4 | using Netron.GraphLib.UI;
|
---|
5 | namespace Netron.GraphLib.IO.SVG
|
---|
6 | {
|
---|
7 | /// <summary>
|
---|
8 | /// Exports a diagram to SVG
|
---|
9 | /// </summary>
|
---|
10 | public class SVGSerializer
|
---|
11 | {
|
---|
12 | #region Fields
|
---|
13 | private GraphControl site;
|
---|
14 | #endregion
|
---|
15 |
|
---|
16 | #region Constructor
|
---|
17 | /// <summary>
|
---|
18 | /// Defautl constructor
|
---|
19 | /// </summary>
|
---|
20 | /// <param name="site"></param>
|
---|
21 | public SVGSerializer(GraphControl site)
|
---|
22 | {
|
---|
23 | this.site = site;
|
---|
24 | }
|
---|
25 |
|
---|
26 | #endregion
|
---|
27 |
|
---|
28 | #region Methods
|
---|
29 | /// <summary>
|
---|
30 | /// Serializes the given graph abstract to XML with the given XmlWriter
|
---|
31 | /// </summary>
|
---|
32 | /// <param name="writer"></param>
|
---|
33 | /// <param name="g"></param>
|
---|
34 | public static void Serialize(XmlWriter writer, GraphAbstract g )
|
---|
35 | {
|
---|
36 | writer.WriteStartElement("svg");
|
---|
37 | writer.WriteAttributeString("xmlns","http://www.w3.org/2000/svg");
|
---|
38 | WriteDefinitions(writer);
|
---|
39 | WriteFilters(writer);
|
---|
40 | WriteMetadata(writer, g);
|
---|
41 |
|
---|
42 | WriteConnections(writer, g);
|
---|
43 | WriteShapes(writer, g);
|
---|
44 |
|
---|
45 | writer.WriteEndElement();
|
---|
46 | }
|
---|
47 |
|
---|
48 | private static void WriteShapes(XmlWriter writer, GraphAbstract g)
|
---|
49 | {
|
---|
50 | writer.WriteStartElement("g");
|
---|
51 | for(int k=0; k<g.Shapes.Count; k++) //<rect x="1140" y="30" width="100" height="20" style="fill: url(#two_hues); stroke: black;"/>
|
---|
52 | {
|
---|
53 | writer.WriteStartElement("rect");
|
---|
54 | writer.WriteAttributeString("x", g.Shapes[k].X.ToString());
|
---|
55 | writer.WriteAttributeString("y", g.Shapes[k].Y.ToString());
|
---|
56 | writer.WriteAttributeString("width", g.Shapes[k].Width.ToString());
|
---|
57 | writer.WriteAttributeString("height", g.Shapes[k].Height.ToString());
|
---|
58 | writer.WriteAttributeString("rx", "2");//rounded rectangle
|
---|
59 |
|
---|
60 | //writer.WriteAttributeString("style", "fill: url(#two_hues); stroke: black;");
|
---|
61 | writer.WriteAttributeString("fill", string.Concat("#", (g.Shapes[k].ShapeColor.ToArgb() & 0x00FFFFFF).ToString("X6")) );
|
---|
62 | writer.WriteEndElement();
|
---|
63 |
|
---|
64 | //<text text-anchor="middle" x="{$x+50}" y="{$y+15}">
|
---|
65 | writer.WriteStartElement("text");
|
---|
66 | writer.WriteAttributeString("x", Convert.ToString(g.Shapes[k].X + 10));
|
---|
67 | writer.WriteAttributeString("y", Convert.ToString(g.Shapes[k].Y + 15));
|
---|
68 | writer.WriteAttributeString("text-anchor", "start");
|
---|
69 | writer.WriteAttributeString("font-size", "9");
|
---|
70 | writer.WriteString(g.Shapes[k].Text);
|
---|
71 | writer.WriteEndElement();
|
---|
72 |
|
---|
73 | }
|
---|
74 | writer.WriteEndElement();
|
---|
75 | }
|
---|
76 |
|
---|
77 | private static void WriteConnections(XmlWriter writer, GraphAbstract g)
|
---|
78 | {
|
---|
79 | /*
|
---|
80 | <line class="edge" x1="{$x1}" y1="{$y1}" x2="{$x}" y2="{$y+50}">
|
---|
81 | <xsl:attribute name="style">marker-end:url(#arrow)</xsl:attribute>
|
---|
82 | </line>
|
---|
83 | */
|
---|
84 | writer.WriteStartElement("g");
|
---|
85 | for(int k=0; k<g.Connections.Count; k++)
|
---|
86 | {
|
---|
87 | writer.WriteStartElement("line");
|
---|
88 | writer.WriteAttributeString("x1", g.Connections[k].From.Location.X.ToString());
|
---|
89 | writer.WriteAttributeString("y1", g.Connections[k].From.Location.Y.ToString());
|
---|
90 | writer.WriteAttributeString("x2", g.Connections[k].To.Location.X.ToString());
|
---|
91 | writer.WriteAttributeString("y2", g.Connections[k].To.Location.Y.ToString());
|
---|
92 | //writer.WriteAttributeString("style", "fill: url(#two_hues); stroke: black;");
|
---|
93 | writer.WriteEndElement();
|
---|
94 | }
|
---|
95 | writer.WriteEndElement();
|
---|
96 | }
|
---|
97 |
|
---|
98 | private static void WriteMetadata(XmlWriter writer, GraphAbstract g)
|
---|
99 | {
|
---|
100 | writer.WriteStartElement("title");
|
---|
101 | writer.WriteString(g.GraphInformation.Title);
|
---|
102 | writer.WriteEndElement();
|
---|
103 | writer.WriteStartElement("desc");
|
---|
104 | writer.WriteString(g.GraphInformation.Description);
|
---|
105 | writer.WriteEndElement();
|
---|
106 | }
|
---|
107 |
|
---|
108 | private static void WriteDefinitions(XmlWriter writer)
|
---|
109 | {
|
---|
110 | writer.WriteRaw(@"<defs>
|
---|
111 | <linearGradient id=""two_hues"">
|
---|
112 | <stop offset=""0%"" style=""stop-color: #ffffff;""/>
|
---|
113 | <stop offset=""100%"" style=""stop-color: #4682B4;""/>
|
---|
114 | </linearGradient>
|
---|
115 | </defs>"
|
---|
116 | );
|
---|
117 | // writer.WriteStartElement("defs");
|
---|
118 | // writer.WriteStartElement("linearGradient");
|
---|
119 | // writer.WriteAttributeString("id", "two_hues");
|
---|
120 | // writer.WriteStartElement("stop");
|
---|
121 | // writer.WriteAttributeString("offset", "0%");
|
---|
122 | // writer.WriteAttributeString("style","stop-color: #ffffff");
|
---|
123 | // writer.WriteEndElement();//stop
|
---|
124 | // writer.WriteStartElement("stop");
|
---|
125 | // writer.WriteAttributeString("offset", "100%");
|
---|
126 | // writer.WriteAttributeString("style","stop-color: #4682B4");
|
---|
127 | // writer.WriteEndElement();//stop
|
---|
128 | // writer.WriteEndElement();//linearGradient
|
---|
129 | // writer.WriteEndElement();//defs
|
---|
130 |
|
---|
131 |
|
---|
132 | }
|
---|
133 |
|
---|
134 | private static void WriteFilters(XmlWriter writer)
|
---|
135 | {
|
---|
136 |
|
---|
137 | writer.WriteRaw(@"<filter id=""drop-shadow"">
|
---|
138 | <feGaussianBlur in=""SourceAlpha"" stdDeviation=""2"" result=""blur""/>
|
---|
139 | <feOffset in=""blur"" dx=""4"" dy=""4"" result=""offsetBlur""/>
|
---|
140 | <feMerge>
|
---|
141 | <feMergeNode in=""offsetBlur""/>
|
---|
142 | <feMergeNode in=""SourceGraphic""/>
|
---|
143 | </feMerge>
|
---|
144 | </filter>"
|
---|
145 | );
|
---|
146 |
|
---|
147 | // writer.WriteStartElement("filter");
|
---|
148 | // writer.WriteAttributeString("id","dropShadow");
|
---|
149 | // writer.WriteStartElement("feGaussianBlur");
|
---|
150 | // writer.WriteAttributeString("in", "SourceAlpha");
|
---|
151 | // writer.WriteAttributeString("stdDeviation","2");
|
---|
152 | // writer.WriteAttributeString("result","blur");
|
---|
153 | // writer.WriteEndElement();//feGaussianBlur
|
---|
154 | // writer.WriteEndElement();//filter
|
---|
155 |
|
---|
156 |
|
---|
157 | }
|
---|
158 | /// <summary>
|
---|
159 | /// Saves the diagram to SVG format
|
---|
160 | /// </summary>
|
---|
161 | /// <param name="fileName">the file-path</param>
|
---|
162 | /// <param name="site">the graph-control instance to be serialized</param>
|
---|
163 | /// <returns></returns>
|
---|
164 | public static bool SaveAs(string fileName, GraphControl site)
|
---|
165 | {
|
---|
166 | XmlTextWriter tw = null;
|
---|
167 | try
|
---|
168 | {
|
---|
169 |
|
---|
170 | tw = new XmlTextWriter(fileName,System.Text.Encoding.Unicode); |
---|
171 | tw.Formatting = System.Xml.Formatting.Indented; |
---|
172 | Serialize(tw,site.Abstract); |
---|
173 |
|
---|
174 | return true;
|
---|
175 | }
|
---|
176 | catch(Exception exc)
|
---|
177 | {
|
---|
178 | //TODO: more specific exception handling here
|
---|
179 | Trace.WriteLine(exc.Message, "SVGSerializer.SaveAs");
|
---|
180 | }
|
---|
181 | catch
|
---|
182 | {
|
---|
183 | Trace.WriteLine("Non-CLS exception caught.","BinarySerializer.SaveAs");
|
---|
184 | }
|
---|
185 | finally
|
---|
186 | {
|
---|
187 | if(tw!=null) tw.Close();
|
---|
188 | }
|
---|
189 | return false;
|
---|
190 |
|
---|
191 | }
|
---|
192 | #endregion
|
---|
193 | }
|
---|
194 | }
|
---|