Wiki source code of JSON Graph Format
Last modified by Richard Kreissig on 2023/09/14 10:36
Show last authors
author | version | line-number | content |
---|---|---|---|
1 | = The JSON Graph Format = | ||
2 | |||
3 | JSON (JavaScript Object Notation) is an open standard format that is widely used and accepted as interchange format on the web. JSON consists of arbitrary key-value pairs. We specify some conventions to represent a graph within this format. | ||
4 | |||
5 | We specify positions of nodes and edges relative to parent nodes, see our [[doc:KIELER.Discontinued Projects.Infrastructure for Meta Layout (KIML).KLayoutData Meta Model.WebHome]] documentation for further information. | ||
6 | |||
7 | (% style="color: rgb(51,51,51);" %)The JSON graph format comprises of four basic elements - //Nodes, Ports, Labels, and Edges//. | ||
8 | |||
9 | * Each element has an '**id**' that identifies it uniquely. | ||
10 | * The first three elements can hold a **position** and **dimension**. | ||
11 | * Edges on the contrary can hold **bend points** specifying where the edge changes direction. | ||
12 | * Nodes can contain **child nodes** and hold **ports** that specify attachment points of edges. | ||
13 | * Nodes holding child nodes can specify a **padding**. | ||
14 | * Multiple edges can be attached to the same port, the port is attached to the node itself. | ||
15 | * All elements can hold **labels** (despite the label itself). | ||
16 | * All elements can hold **properties** which represent additional information to the layout algorithm. | ||
17 | |||
18 | == Examples == | ||
19 | |||
20 | (% style="color: rgb(51,51,51);" %)Below are some example graphs in the JSON graph format. You can hop to the (%%)[[Live>>url:http://localhost:9444/Live.html||style="text-decoration: none;" shape="rect"]](% style="color: rgb(51,51,51);" %) section of our web service and try them! If you use SVG as output format the graph will be rendered as an SVG image directly within your browser. | ||
21 | |||
22 | === Minimal === | ||
23 | |||
24 | (% style="color: rgb(0,0,0);" %) (%%)The following example shows a very simple graph consisting of two nodes connected by one edge. Each node owns a //width// and //height// as well as a //label//. | ||
25 | |||
26 | {{code title="Small graph with one edge" language="js" collapse="true"}} | ||
27 | { | ||
28 | id: "root", // root node | ||
29 | children: [{ | ||
30 | id: "n1", // node n1 | ||
31 | labels: [ { text: "n1" } ], | ||
32 | width: 100, | ||
33 | height: 100, | ||
34 | },{ | ||
35 | id: "n2", // node n2 | ||
36 | labels: [ { text: "n2" } ], | ||
37 | width: 100, | ||
38 | height: 50 | ||
39 | }], | ||
40 | edges: [{ | ||
41 | id: "e1", // edge n1 -> n2 | ||
42 | source: "n1", | ||
43 | target: "n2" | ||
44 | }] | ||
45 | } | ||
46 | {{/code}} | ||
47 | |||
48 | |||
49 | |||
50 | |||
51 | |||
52 | |||
53 | |||
54 | [[image:attach:minimal.png]] | ||
55 | |||
56 | === (% style="color: rgb(0,0,0);" %)Hierarchy and Ports(%%) === | ||
57 | |||
58 | This example illustrates nesting of nodes to establish hierarchy. The node {{code language="none"}}n2{{/code}} serves as parent node for nodes {{code language="none"}}n3{{/code}} and {{code language="none"}}n4{{/code}}. The latter two nodes are connected via edge {{code language="none"}}e2{{/code}}. Furthermore, edge {{code language="none"}}e1{{/code}} is connected to port {{code language="none"}}n2_p1{{/code}} of node {{code language="none"}}n2{{/code}}. | ||
59 | |||
60 | {{code title="Small graph with a port and hierarchy" language="js" collapse="true"}} | ||
61 | { | ||
62 | id: "root", | ||
63 | children: [{ | ||
64 | id: "n1", | ||
65 | labels: [ { text: "n1" } ], | ||
66 | width: 100, | ||
67 | height: 100 | ||
68 | },{ | ||
69 | id: "n2", | ||
70 | labels: [ { text: "n2" } ], | ||
71 | width: 100, | ||
72 | height: 50, | ||
73 | ports: [{ | ||
74 | id: "n2_p1", | ||
75 | width: 10, | ||
76 | height: 10 | ||
77 | }], | ||
78 | children: [{ | ||
79 | id: "n3", | ||
80 | labels: [ { text: "n3" } ], | ||
81 | width: 40, | ||
82 | height: 40 | ||
83 | },{ | ||
84 | id: "n4", | ||
85 | labels: [ { text: "n4" } ], | ||
86 | width: 40, | ||
87 | height: 40} | ||
88 | ], | ||
89 | edges: [{ | ||
90 | id: "e4", | ||
91 | source: "n3", | ||
92 | target: "n4" | ||
93 | }] | ||
94 | }], | ||
95 | edges: [{ | ||
96 | id: "e1", | ||
97 | labels: [ { text: "e1" } ], | ||
98 | source: "n1", | ||
99 | target: "n2", | ||
100 | targetPort: "n2_p1" | ||
101 | }] | ||
102 | } | ||
103 | {{/code}} | ||
104 | |||
105 | (% style="text-align: left;" %) | ||
106 | |||
107 | |||
108 | (% style="text-align: left;" %) | ||
109 | |||
110 | |||
111 | (% style="text-align: left;" %) | ||
112 | |||
113 | |||
114 | (% style="text-align: left;" %) | ||
115 | [[image:attach:hierarchyAndPort.png]] | ||
116 | |||
117 | === Element Properties === | ||
118 | |||
119 | All graph elements can hold further //properties// that specify certain behavior. In the example below, the both nodes have //FIXED_SIDE// {{code language="none"}}portConstraints{{/code}}, indicating that the ports may also be moved on their respective side. The side of each port is specified using the {{code language="none"}}portSide{{/code}} property. | ||
120 | |||
121 | Note that properties might be coupled with a certain layout algorithm and hence are not always available. The two properties used in this example are only available for our[[ Klay Layered>>doc:KIELER.Discontinued Projects.Layout Algorithms (KLay).KLay Layered.WebHome]] algorithm. | ||
122 | |||
123 | {{code title="Port Constraints and Port Sides" language="js" collapse="true"}} | ||
124 | { | ||
125 | id: "root", // root node | ||
126 | children: [{ | ||
127 | id: "n1", // node n1 | ||
128 | labels: [ { text: "n1" } ], | ||
129 | // node n1 has fixed port constraints | ||
130 | properties: {"de.cau.cs.kieler.portConstraints": "FIXED_SIDE"}, | ||
131 | width: 100, | ||
132 | height: 100, | ||
133 | ports: [{ | ||
134 | id: "p1", | ||
135 | width: 10, | ||
136 | height: 10, | ||
137 | // port p1 should be located on the north side | ||
138 | properties: {"de.cau.cs.kieler.portSide": "NORTH"} | ||
139 | }] | ||
140 | },{ | ||
141 | id: "n2", // node n2 | ||
142 | labels: [ { text: "n2" } ], | ||
143 | properties: {"de.cau.cs.kieler.portConstraints": "FIXED_SIDE"}, | ||
144 | width: 100, | ||
145 | height: 50, | ||
146 | ports: [{ | ||
147 | id: "p2", | ||
148 | width: 10, | ||
149 | height: 10, | ||
150 | properties: {"de.cau.cs.kieler.portSide": "SOUTH"} | ||
151 | }] | ||
152 | }], | ||
153 | // children end | ||
154 | edges: [{ | ||
155 | id: "e1", // edge n1 -> n2 | ||
156 | source: "n1", | ||
157 | target: "n2", | ||
158 | sourcePort: "p1", // p1 -> p2 | ||
159 | targetPort: "p2" | ||
160 | }] | ||
161 | } | ||
162 | {{/code}} | ||
163 | |||
164 | |||
165 | |||
166 | |||
167 | |||
168 | |||
169 | |||
170 | |||
171 | |||
172 | [[image:attach:properties.png]] | ||
173 | |||
174 | === Padding === | ||
175 | |||
176 | One can assign {{code language="none"}}padding{{/code}} to compound nodes. In the following example the node {{code language="none"}}n2{{/code}} contains four different padding values for the each side. | ||
177 | |||
178 | Note, that positions of child nodes are relative to the parent nodes (0,0) **plus** the left and top padding. Refer to the documentation of [[KLayoutData >>doc:KIELER.Discontinued Projects.Infrastructure for Meta Layout (KIML).KLayoutData Meta Model.WebHome]]for further information on relative positioning. | ||
179 | |||
180 | {{code title="Padding" language="js" collapse="true"}} | ||
181 | { | ||
182 | id: "root", | ||
183 | children: [{ | ||
184 | id: "n1", | ||
185 | labels: [ { text: "n1" } ], | ||
186 | width: 100, | ||
187 | height: 100 | ||
188 | },{ | ||
189 | id: "n2", | ||
190 | labels: [ { text: "n2" } ], | ||
191 | width: 100, | ||
192 | height: 50, | ||
193 | padding: { | ||
194 | left: 40, | ||
195 | top: 20, | ||
196 | right: 50, | ||
197 | bottom: 10 | ||
198 | }, | ||
199 | ports: [{ | ||
200 | id: "n2_p1", | ||
201 | width: 10, | ||
202 | height: 10 | ||
203 | }], | ||
204 | children: [{ | ||
205 | id: "n3", | ||
206 | labels: [ { text: "n3" } ], | ||
207 | width: 40, | ||
208 | height: 40 | ||
209 | },{ | ||
210 | id: "n4", | ||
211 | labels: [ { text: "n4" } ], | ||
212 | width: 40, | ||
213 | height: 40} | ||
214 | ], | ||
215 | edges: [{ | ||
216 | id: "e4", | ||
217 | source: "n3", | ||
218 | target: "n4" | ||
219 | }] | ||
220 | }], | ||
221 | edges: [{ | ||
222 | id: "e1", | ||
223 | labels: [ { text: "e1" } ], | ||
224 | source: "n1", | ||
225 | target: "n2", | ||
226 | targetPort: "n2_p1" | ||
227 | }] | ||
228 | } | ||
229 | {{/code}} | ||
230 | |||
231 | |||
232 | |||
233 | |||
234 | |||
235 | |||
236 | |||
237 | [[image:attach:padding.png]] | ||
238 | |||
239 | === Fixed Layout === | ||
240 | |||
241 | The example below shows how to mix existing positions with automatic layout. To activate this the {{code language="none"}}de.cau.cs.kieler.fixed{{/code}} algorithm can be used, see the properties specification of the {{code language="none"}}n2{{/code}} node. | ||
242 | |||
243 | Fixed positions are specified for the two child nodes of the compound node {{code language="none"}}n2{{/code}} and the edge that connects them. Positions can either be directly set to {{code language="none"}}x{{/code}} and {{code language="none"}}y{{/code}} or specified via the {{code language="none"}}position{{/code}} property. Bendpoints are specified via {{code language="none"}}bendPoints{{/code}}, where the first and the last pair of coordinates determines the attachment positions at the node or port and any further pair represents a bendpoint. | ||
244 | |||
245 | {{code title="Fixed Layout" language="js" collapse="true"}} | ||
246 | { | ||
247 | id : "root", | ||
248 | children : [ { | ||
249 | id : "n1", | ||
250 | width : 50, | ||
251 | height : 50 | ||
252 | }, { | ||
253 | id : "n2", | ||
254 | width : 100, | ||
255 | height : 50, | ||
256 | properties : { | ||
257 | algorithm : "de.cau.cs.kieler.fixed" | ||
258 | }, | ||
259 | ports : [ { | ||
260 | id : "n2_p1", | ||
261 | width : 10, | ||
262 | height : 10 | ||
263 | } ], | ||
264 | children : [ { | ||
265 | id : "n3", | ||
266 | labels : [ { | ||
267 | text : "n3" | ||
268 | } ], | ||
269 | width : 40, | ||
270 | height : 40, | ||
271 | properties : { | ||
272 | position : "20, 40" | ||
273 | } | ||
274 | }, { | ||
275 | id : "n4", | ||
276 | labels : [ { | ||
277 | text : "n4" | ||
278 | } ], | ||
279 | width : 40, | ||
280 | height : 40, | ||
281 | properties : { | ||
282 | position : "140, 95" | ||
283 | } | ||
284 | } ], | ||
285 | edges : [ { | ||
286 | id : "e4", | ||
287 | source : "n3", | ||
288 | target : "n4", | ||
289 | properties : { | ||
290 | // first and last are src and target | ||
291 | bendPoints : "60, 60, 80, 10, 140, 115" | ||
292 | } | ||
293 | } ] | ||
294 | } ], | ||
295 | edges : [ { | ||
296 | id : "e1", | ||
297 | labels : [ { | ||
298 | text : "e1" | ||
299 | } ], | ||
300 | source : "n1", | ||
301 | target : "n2", | ||
302 | targetPort : "n2_p1" | ||
303 | } ] | ||
304 | }; | ||
305 | {{/code}} | ||
306 | |||
307 | |||
308 | |||
309 | |||
310 | [[image:attach:fixed_pos.png]] |