@zombie-mermaid/svg-renderer 3.1.0 → 3.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,626 @@
1
+ [
2
+ {
3
+ "name": "v00-context",
4
+ "source": "C4Context\n title System Context for Internet Banking\n Person(customer, \"Personal Banking Customer\", \"A customer of the bank\")\n Enterprise_Boundary(b0, \"Bank\") {\n System(banking, \"Internet Banking System\", \"Lets customers view accounts\")\n SystemDb(ledger, \"Ledger\", \"Stores transactions\")\n }\n System_Ext(mail, \"E-mail System\", \"Sends e-mails\")\n Rel(customer, banking, \"Uses\", \"HTTPS\")\n Rel(banking, ledger, \"Reads from and writes to\")\n Rel(banking, mail, \"Sends e-mail using\", \"SMTP\")\n Rel_Back(customer, mail, \"Sends e-mails to\")\n",
5
+ "width": 932,
6
+ "height": 888.4,
7
+ "elements": {
8
+ "customer": [263.8, 326.3],
9
+ "mail": [585.5, 281.1],
10
+ "banking": [308, 666.8],
11
+ "ledger": [624, 680.5]
12
+ },
13
+ "relationships": [
14
+ {
15
+ "line": [275.8, 415.9, 302.3, 622.6],
16
+ "label": [302.5, 519.2]
17
+ },
18
+ {
19
+ "line": [416, 671.5, 516, 675.8],
20
+ "label": [532.5, 673.7]
21
+ },
22
+ {
23
+ "line": [339.8, 622.6, 553.7, 325.3],
24
+ "label": [497.8, 474]
25
+ },
26
+ {
27
+ "line": [305.9, 321, 477.5, 296.3],
28
+ "label": [436.2, 308.6]
29
+ }
30
+ ]
31
+ },
32
+ {
33
+ "name": "v01-grid",
34
+ "source": "C4Context\n title Nine systems, three rows\n Person(p1, \"Alice\", \"Admin\")\n Person(p2, \"Bob\", \"Customer with a rather long description that has to wrap across lines\")\n System(s1, \"Alpha\")\n System_Ext(s2, \"Beta Payments Gateway\", \"Third party\")\n SystemDb(s3, \"Gamma Store\", \"Keeps data\")\n SystemQueue(s4, \"Delta Bus\", \"Moves events\")\n System(s5, \"Epsilon\")\n System(s6, \"Zeta\")\n System(s7, \"Eta\")\n Rel(p1, s1, \"Manages\")\n Rel(p2, s2, \"Pays with\")\n Rel(s1, s3, \"Reads from\", \"SQL\")\n Rel(s4, s5, \"Delivers to\")\n Rel(s6, p1, \"Notifies\")\n Rel(s7, s3, \"Backs up\")\n",
35
+ "width": 1487.8,
36
+ "height": 923.3,
37
+ "elements": {
38
+ "p1": [258, 324],
39
+ "p2": [574, 336.6],
40
+ "s1": [890, 272.6],
41
+ "s2": [1206, 281.1],
42
+ "s3": [258, 594.1],
43
+ "s4": [585.9, 565.4],
44
+ "s5": [913.8, 571.9],
45
+ "s6": [1229.8, 571.9],
46
+ "s7": [258, 787.7]
47
+ },
48
+ "relationships": [
49
+ {
50
+ "line": [293.8, 321.6, 782, 281.4],
51
+ "label": [562.4, 301.5]
52
+ },
53
+ {
54
+ "line": [664.8, 329.2, 1098, 290.6],
55
+ "label": [906.9, 309.9]
56
+ },
57
+ {
58
+ "line": [820, 308.3, 366, 555],
59
+ "label": [624, 431.6]
60
+ },
61
+ {
62
+ "line": [705.8, 567.8, 805.8, 569.8],
63
+ "label": [784.3, 568.8]
64
+ },
65
+ {
66
+ "line": [1121.8, 544.3, 365.2, 351.7],
67
+ "label": [763.5, 448]
68
+ },
69
+ {
70
+ "line": [258, 752, 258, 652],
71
+ "label": [282.5, 702]
72
+ }
73
+ ]
74
+ },
75
+ {
76
+ "name": "v02-person-targets",
77
+ "source": "C4Context\n Person(a, \"Ann\")\n Person_Ext(b, \"Ben\", \"Outside the company\")\n System(s, \"Portal\", \"The website\")\n Rel(s, a, \"Emails\")\n Rel(b, s, \"Visits\")\n Rel_Back(a, b, \"Replies to\")\n BiRel(a, s, \"Chats with\")\n",
78
+ "width": 1148,
79
+ "height": 451,
80
+ "elements": {
81
+ "a": [258, 255.5],
82
+ "b": [574, 264],
83
+ "s": [890, 221.1]
84
+ },
85
+ "relationships": [
86
+ {
87
+ "line": [782, 227, 300.1, 253.7],
88
+ "label": [559.1, 240.4]
89
+ },
90
+ {
91
+ "line": [611.7, 259.5, 782, 235.8],
92
+ "label": [710.8, 247.6]
93
+ },
94
+ {
95
+ "line": [297.8, 257.1, 525.1, 263.2],
96
+ "label": [438, 260.1]
97
+ },
98
+ {
99
+ "line": [300.1, 253.7, 782, 227],
100
+ "label": [569.1, 240.4]
101
+ }
102
+ ]
103
+ },
104
+ {
105
+ "name": "v03-directions",
106
+ "source": "C4Context\n System(c, \"Centre\")\n System(n, \"North\")\n System(e, \"East\")\n System(w, \"West\")\n System(s, \"South\")\n System(ne, \"North East\")\n Rel(c, n, \"to north\")\n Rel(c, e, \"to east\")\n Rel(c, w, \"to west\")\n Rel(c, s, \"to south\")\n Rel(ne, c, \"diagonal in\")\n Rel(w, e, \"across\")\n",
107
+ "width": 1464,
108
+ "height": 519.5,
109
+ "elements": {
110
+ "c": [258, 212.6],
111
+ "n": [574, 212.6],
112
+ "e": [890, 212.6],
113
+ "w": [1206, 212.6],
114
+ "s": [258, 383.9],
115
+ "ne": [574, 383.9]
116
+ },
117
+ "relationships": [
118
+ {
119
+ "line": [366, 212.6, 466, 212.6],
120
+ "label": [436.5, 212.6]
121
+ },
122
+ {
123
+ "line": [366, 212.6, 782, 212.6],
124
+ "label": [592, 212.6]
125
+ },
126
+ {
127
+ "line": [366, 212.6, 1098, 212.6],
128
+ "label": [751, 212.6]
129
+ },
130
+ {
131
+ "line": [258, 248.3, 258, 348.3],
132
+ "label": [279.5, 298.3]
133
+ },
134
+ {
135
+ "line": [508.3, 348.3, 323.7, 248.3],
136
+ "label": [445, 298.3]
137
+ },
138
+ {
139
+ "line": [1098, 212.6, 998, 212.6],
140
+ "label": [1065.5, 212.6]
141
+ }
142
+ ]
143
+ },
144
+ {
145
+ "name": "v04-nested",
146
+ "source": "C4Context\n Enterprise_Boundary(e1, \"Acme Corp\") {\n Person(p, \"Staff\")\n System_Boundary(sb1, \"Billing\") {\n System(b1, \"Invoices\", \"Makes invoices\")\n System(b2, \"Ledger\")\n }\n System_Boundary(sb2, \"Support\") {\n System(t1, \"Tickets\")\n System(t2, \"Chat\", \"Live chat widget\")\n System(t3, \"Knowledge base with a long name\")\n }\n }\n Enterprise_Boundary(e2, \"Partner Co\") {\n System_Ext(x, \"Partner API\")\n }\n Rel(p, b1, \"Raises\")\n Rel(b1, b2, \"Posts to\")\n Rel(t1, x, \"Escalates to\", \"HTTPS\")\n Rel(p, t2, \"Talks in\")\n",
147
+ "width": 1459.5,
148
+ "height": 1244.2,
149
+ "elements": {
150
+ "p": [308, 312.5],
151
+ "b1": [358, 642.1],
152
+ "b2": [358, 821.9],
153
+ "t1": [724, 633.6],
154
+ "t2": [724, 813.4],
155
+ "t3": [729.8, 1000.8],
156
+ "x": [1151.5, 269.6]
157
+ },
158
+ "relationships": [
159
+ {
160
+ "line": [320.4, 391.2, 351.3, 598],
161
+ "label": [354.3, 494.6]
162
+ },
163
+ {
164
+ "line": [358, 686.3, 358, 786.3],
165
+ "label": [379.5, 736.3]
166
+ },
167
+ {
168
+ "line": [765.8, 598, 1109.7, 305.3],
169
+ "label": [970.3, 451.6]
170
+ },
171
+ {
172
+ "line": [373.5, 391.2, 687.4, 769.3],
173
+ "label": [550.4, 580.3]
174
+ }
175
+ ]
176
+ },
177
+ {
178
+ "name": "v05-containers",
179
+ "source": "C4Container\n title Containers with every shape\n Person(u, \"Shopper\")\n System_Boundary(sys, \"Store\") {\n Container(web, \"Web App\", \"React\", \"Storefront and checkout flows for shoppers\")\n Container(api, \"API\", \"Node.js\", \"Business logic\")\n ContainerDb(db, \"Database\", \"Postgres\", \"Orders\")\n ContainerQueue(q, \"Events\", \"Kafka\", \"Domain events\")\n Container_Ext(m, \"Mailer\", \"SaaS\")\n ComponentDb(cdb, \"Cache\", \"Redis\")\n }\n Rel(u, web, \"Browses\", \"HTTPS\")\n Rel(web, api, \"Calls\", \"JSON\")\n Rel(api, db, \"Reads/writes\", \"SQL\")\n BiRel(api, q, \"Publishes/consumes\", \"AMQP\")\n Rel(q, m, \"Triggers\")\n Rel(api, cdb, \"Caches in\")\n Rel_Back(u, m, \"Sends mail to\")\n",
180
+ "width": 1587.8,
181
+ "height": 1065.5,
182
+ "elements": {
183
+ "u": [258, 315.5],
184
+ "web": [308, 651.4],
185
+ "api": [624, 645.1],
186
+ "db": [940, 658.9],
187
+ "q": [1267.9, 630],
188
+ "m": [308, 852.4],
189
+ "cdb": [624, 866.2]
190
+ },
191
+ "relationships": [
192
+ {
193
+ "line": [270.1, 394.2, 300.5, 601],
194
+ "label": [308.3, 497.6]
195
+ },
196
+ {
197
+ "line": [416, 649.2, 516, 647.3],
198
+ "label": [479.5, 648.2]
199
+ },
200
+ {
201
+ "line": [732, 649.8, 832, 654.2],
202
+ "label": [816.5, 652]
203
+ },
204
+ {
205
+ "line": [732, 642.6, 1148, 632.9],
206
+ "label": [995, 637.7]
207
+ },
208
+ {
209
+ "line": [1153.6, 657.8, 416, 827.4],
210
+ "label": [806.8, 742.6]
211
+ },
212
+ {
213
+ "line": [624, 689.2, 624, 816.8],
214
+ "label": [650.5, 753]
215
+ },
216
+ {
217
+ "line": [265.8, 394.2, 304.7, 816.8],
218
+ "label": [321.7, 605.5]
219
+ }
220
+ ]
221
+ },
222
+ {
223
+ "name": "v06-component",
224
+ "source": "C4Component\n Container_Boundary(api, \"API Application\") {\n Component(sign, \"Sign-in controller\", \"Spring MVC\", \"Lets users sign in\")\n Component(sec, \"Security component\", \"Spring Bean\", \"Checks credentials and rate-limits repeated attempts\")\n ComponentQueue(jobs, \"Jobs\", \"SQS\")\n Component_Ext(ext, \"Identity provider\", \"OIDC\")\n }\n ContainerDb(db, \"Database\", \"Oracle\")\n Rel(sign, sec, \"Uses\")\n Rel(sec, db, \"Reads from\", \"JDBC\")\n Rel(sec, ext, \"Delegates to\", \"HTTPS\")\n Rel(sign, jobs, \"Enqueues\")\n",
225
+ "width": 1582.6,
226
+ "height": 733.5,
227
+ "elements": {
228
+ "db": [258, 226.3],
229
+ "sign": [308, 526.8],
230
+ "sec": [624, 533.1],
231
+ "jobs": [949.3, 503.2],
232
+ "ext": [1274.6, 518.2]
233
+ },
234
+ "relationships": [
235
+ {
236
+ "line": [416, 528.9, 516, 530.9],
237
+ "label": [479.5, 529.9]
238
+ },
239
+ {
240
+ "line": [563.8, 482.6, 316.8, 273],
241
+ "label": [471.3, 377.8]
242
+ },
243
+ {
244
+ "line": [732, 530.6, 1166.6, 520.6],
245
+ "label": [982.8, 525.6]
246
+ },
247
+ {
248
+ "line": [416, 522.8, 832.1, 507.5],
249
+ "label": [651.1, 515.1]
250
+ }
251
+ ]
252
+ },
253
+ {
254
+ "name": "v07-dynamic",
255
+ "source": "C4Dynamic\n Person(c, \"Customer\")\n Container(w, \"Web\")\n Container(a, \"API\")\n ContainerDb(d, \"DB\")\n Rel(c, w, \"Opens\")\n Rel(w, a, \"Requests\", \"JSON\")\n Rel(a, d, \"Reads\")\n Rel_Back(w, a, \"Returns data\")\n",
256
+ "width": 1464,
257
+ "height": 434,
258
+ "elements": {
259
+ "c": [258, 255.5],
260
+ "w": [574, 212.5],
261
+ "a": [890, 212.5],
262
+ "d": [1206, 226.3]
263
+ },
264
+ "relationships": [
265
+ {
266
+ "line": [302.2, 250.1, 466, 227.2],
267
+ "label": [408.6, 238.6]
268
+ },
269
+ {
270
+ "line": [682, 212.5, 782, 212.5],
271
+ "label": [773, 212.5]
272
+ },
273
+ {
274
+ "line": [998, 217.2, 1098, 221.6],
275
+ "label": [1072, 219.4]
276
+ }
277
+ ]
278
+ },
279
+ {
280
+ "name": "v08-deployment",
281
+ "source": "C4Deployment\n Deployment_Node(dc, \"Data centre\", \"Linux\") {\n Deployment_Node(srv, \"Server\", \"Ubuntu 22.04\") {\n Container(app, \"App\", \"Java\", \"Serves requests\")\n }\n Deployment_Node(dbn, \"DB host\", \"Postgres 15\") {\n ContainerDb(db, \"Database\", \"SQL\")\n }\n }\n Rel(app, db, \"Reads from\", \"JDBC\")\n",
282
+ "width": 1082,
283
+ "height": 589.6,
284
+ "elements": {
285
+ "app": [358, 335],
286
+ "db": [724, 340.3]
287
+ },
288
+ "relationships": [
289
+ {
290
+ "line": [466, 336.6, 616, 338.7],
291
+ "label": [572, 337.7]
292
+ }
293
+ ]
294
+ },
295
+ {
296
+ "name": "v09-long",
297
+ "source": "C4Context\n Person(p, \"A person whose name is unusually long and needs wrapping\")\n System(s, \"Short\")\n System(t, \"Another system with a long name\", \"And a description that keeps going for several lines so the box has to grow taller than usual\")\n Rel(p, s, \"A relationship label that is very long indeed, longer than the gap between the boxes\", \"HTTPS/JSON over a long technology name\")\n Rel(s, t, \"\")\n Rel(t, p, \"Back\")\n",
298
+ "width": 1154.8,
299
+ "height": 464.9,
300
+ "elements": {
301
+ "p": [258, 270.9],
302
+ "s": [574, 212.6],
303
+ "t": [893.4, 241.5]
304
+ },
305
+ "relationships": [
306
+ {
307
+ "line": [303.2, 263.2, 466, 232.6],
308
+ "label": [605.6, 247.9]
309
+ },
310
+ {
311
+ "line": [682, 222.4, 782, 231.4],
312
+ "label": [732, 226.9]
313
+ },
314
+ {
315
+ "line": [782, 246.6, 345.5, 267.4],
316
+ "label": [577.3, 257]
317
+ }
318
+ ]
319
+ },
320
+ {
321
+ "name": "v10-many-rels",
322
+ "source": "C4Context\n System(a, \"A\")\n System(b, \"B\")\n System(c, \"C\")\n System(d, \"D\")\n System(e, \"E\")\n Rel(a, b, \"1\")\n Rel(a, c, \"2\")\n Rel(a, d, \"3\")\n Rel(a, e, \"4\")\n Rel(b, c, \"5\")\n Rel(b, d, \"6\")\n Rel(c, e, \"7\")\n Rel(e, a, \"8\")\n Rel(d, a, \"9\")\n",
323
+ "width": 1464,
324
+ "height": 519.5,
325
+ "elements": {
326
+ "a": [258, 212.6],
327
+ "b": [574, 212.6],
328
+ "c": [890, 212.6],
329
+ "d": [1206, 212.6],
330
+ "e": [258, 383.9]
331
+ },
332
+ "relationships": [
333
+ {
334
+ "line": [366, 212.6, 466, 212.6],
335
+ "label": [419.5, 212.6]
336
+ },
337
+ {
338
+ "line": [366, 212.6, 782, 212.6],
339
+ "label": [577.5, 212.6]
340
+ },
341
+ {
342
+ "line": [366, 212.6, 1098, 212.6],
343
+ "label": [735.5, 212.6]
344
+ },
345
+ {
346
+ "line": [258, 248.3, 258, 348.3],
347
+ "label": [261.5, 298.3]
348
+ },
349
+ {
350
+ "line": [682, 212.6, 782, 212.6],
351
+ "label": [735.5, 212.6]
352
+ },
353
+ {
354
+ "line": [682, 212.6, 1098, 212.6],
355
+ "label": [893.5, 212.6]
356
+ },
357
+ {
358
+ "line": [782, 241.9, 366, 354.6],
359
+ "label": [577.5, 298.3]
360
+ },
361
+ {
362
+ "line": [258, 348.3, 258, 248.3],
363
+ "label": [261.5, 298.3]
364
+ },
365
+ {
366
+ "line": [1098, 212.6, 366, 212.6],
367
+ "label": [735.5, 212.6]
368
+ }
369
+ ]
370
+ },
371
+ {
372
+ "name": "v11-mixed-ext",
373
+ "source": "C4Context\n Person_Ext(a, \"External person\")\n SystemDb_Ext(b, \"External DB\")\n SystemQueue_Ext(c, \"External queue\")\n SystemDb(d, \"Internal DB\")\n SystemQueue(e, \"Internal queue\")\n Person(f, \"Internal person\")\n Rel(a, b, \"x\")\n Rel(c, d, \"y\")\n Rel(e, f, \"z\")\n Rel(f, a, \"w\")\n",
374
+ "width": 1482.6,
375
+ "height": 691,
376
+ "elements": {
377
+ "a": [258, 255.5],
378
+ "b": [574, 226.4],
379
+ "c": [899.3, 197.6],
380
+ "d": [1224.6, 226.4],
381
+ "e": [267.3, 454.6],
382
+ "f": [592.6, 512.5]
383
+ },
384
+ "relationships": [
385
+ {
386
+ "line": [301, 252.1, 466, 236.3],
387
+ "label": [386.5, 244.2]
388
+ },
389
+ {
390
+ "line": [1015.8, 208, 1116.6, 216.8],
391
+ "label": [1069.2, 212.4]
392
+ },
393
+ {
394
+ "line": [377, 475.3, 548.3, 505],
395
+ "label": [465.7, 490.2]
396
+ },
397
+ {
398
+ "line": [544.3, 475.6, 352.8, 328.4],
399
+ "label": [453.1, 402]
400
+ }
401
+ ]
402
+ },
403
+ {
404
+ "name": "v12-boundary-rows",
405
+ "source": "C4Context\n System_Boundary(b1, \"One\") {\n System(a1, \"A1\")\n System(a2, \"A2\")\n }\n System_Boundary(b2, \"Two\") {\n System(c1, \"C1\")\n }\n System_Boundary(b3, \"Three\") {\n System(d1, \"D1\")\n System(d2, \"D2\")\n System(d3, \"D3\")\n System(d4, \"D4\")\n System(d5, \"D5\")\n }\n Person(p, \"Loose\")\n Rel(a1, c1, \"x\")\n Rel(d3, a2, \"y\")\n Rel(p, d1, \"z\")\n",
406
+ "width": 982,
407
+ "height": 1946.8,
408
+ "elements": {
409
+ "p": [258, 255.5],
410
+ "a1": [308, 576.6],
411
+ "a2": [308, 747.9],
412
+ "c1": [674, 576.6],
413
+ "d1": [308, 1076.1],
414
+ "d2": [308, 1247.4],
415
+ "d3": [308, 1418.6],
416
+ "d4": [308, 1589.9],
417
+ "d5": [308, 1761.1]
418
+ },
419
+ "relationships": [
420
+ {
421
+ "line": [416, 576.6, 566, 576.6],
422
+ "label": [494, 576.6]
423
+ },
424
+ {
425
+ "line": [308, 1383, 308, 783.5],
426
+ "label": [311, 1083.3]
427
+ },
428
+ {
429
+ "line": [263.3, 334.2, 305.8, 1040.5],
430
+ "label": [287.5, 687.4]
431
+ }
432
+ ]
433
+ },
434
+ {
435
+ "name": "v13-b1",
436
+ "source": "C4Context\n System_Boundary(b, \"B\") {\n System(a, \"A\")\n }\n",
437
+ "width": 616,
438
+ "height": 455.3,
439
+ "elements": {
440
+ "a": [308, 269.6]
441
+ },
442
+ "relationships": []
443
+ },
444
+ {
445
+ "name": "v14-b2",
446
+ "source": "C4Context\n Enterprise_Boundary(e, \"E\") {\n System_Boundary(b, \"B\") {\n System(a, \"A\")\n }\n }\n",
447
+ "width": 716,
448
+ "height": 562.3,
449
+ "elements": {
450
+ "a": [358, 326.6]
451
+ },
452
+ "relationships": []
453
+ },
454
+ {
455
+ "name": "v15-person-b",
456
+ "source": "C4Context\n Person(p, \"P\")\n System_Boundary(b, \"B\") {\n System(a, \"A\")\n }\n",
457
+ "width": 616,
458
+ "height": 762.3,
459
+ "elements": {
460
+ "p": [258, 255.5],
461
+ "a": [308, 576.6]
462
+ },
463
+ "relationships": []
464
+ },
465
+ {
466
+ "name": "v16-person-only",
467
+ "source": "C4Context\n Person(p, \"P\")\n",
468
+ "width": 516,
469
+ "height": 434,
470
+ "elements": {
471
+ "p": [258, 255.5]
472
+ },
473
+ "relationships": []
474
+ },
475
+ {
476
+ "name": "v17-db-only",
477
+ "source": "C4Context\n SystemDb(d, \"D\")\n",
478
+ "width": 516,
479
+ "height": 375.8,
480
+ "elements": {
481
+ "d": [258, 226.4]
482
+ },
483
+ "relationships": []
484
+ },
485
+ {
486
+ "name": "v18-queue-only",
487
+ "source": "C4Context\n SystemQueue(d, \"D\")\n",
488
+ "width": 534.6,
489
+ "height": 318.3,
490
+ "elements": {
491
+ "d": [267.3, 197.6]
492
+ },
493
+ "relationships": []
494
+ },
495
+ {
496
+ "name": "v19-person-descr",
497
+ "source": "C4Context\n Person(p, \"P\", \"Some description\")\n",
498
+ "width": 516,
499
+ "height": 451,
500
+ "elements": {
501
+ "p": [258, 264]
502
+ },
503
+ "relationships": []
504
+ },
505
+ {
506
+ "name": "v20-db-descr",
507
+ "source": "C4Context\n SystemDb(d, \"D\", \"Some description\")\n",
508
+ "width": 516,
509
+ "height": 392.8,
510
+ "elements": {
511
+ "d": [258, 234.9]
512
+ },
513
+ "relationships": []
514
+ },
515
+ {
516
+ "name": "v21-b-descr",
517
+ "source": "C4Context\n System_Boundary(b, \"B\", \"A description of the boundary\") {\n System(a, \"A\")\n }\n",
518
+ "width": 616,
519
+ "height": 455.3,
520
+ "elements": {
521
+ "a": [308, 269.6]
522
+ },
523
+ "relationships": []
524
+ },
525
+ {
526
+ "name": "v22-b-below",
527
+ "source": "C4Context\n System_Boundary(b, \"B\") {\n System(a, \"A\")\n }\n System(z, \"Z\")\n",
528
+ "width": 616,
529
+ "height": 676.5,
530
+ "elements": {
531
+ "z": [258, 212.6],
532
+ "a": [308, 490.9]
533
+ },
534
+ "relationships": []
535
+ },
536
+ {
537
+ "name": "v23-ent-B",
538
+ "source": "C4Context\n Enterprise_Boundary(b, \"B\") {\n System(a, \"A\")\n }\n",
539
+ "width": 616,
540
+ "height": 455.3,
541
+ "elements": {
542
+ "a": [308, 269.6]
543
+ },
544
+ "relationships": []
545
+ },
546
+ {
547
+ "name": "v24-sys-Bank",
548
+ "source": "C4Context\n System_Boundary(b, \"Bank\") {\n System(a, \"A\")\n }\n",
549
+ "width": 616,
550
+ "height": 455.3,
551
+ "elements": {
552
+ "a": [308, 269.6]
553
+ },
554
+ "relationships": []
555
+ },
556
+ {
557
+ "name": "v25-plain",
558
+ "source": "C4Context\n Boundary(b, \"B\") {\n System(a, \"A\")\n }\n",
559
+ "width": 616,
560
+ "height": 455.3,
561
+ "elements": {
562
+ "a": [308, 269.6]
563
+ },
564
+ "relationships": []
565
+ },
566
+ {
567
+ "name": "v26-cont",
568
+ "source": "C4Container\n Container_Boundary(b, \"B\") {\n Container(a, \"A\")\n }\n",
569
+ "width": 616,
570
+ "height": 455.1,
571
+ "elements": {
572
+ "a": [308, 269.5]
573
+ },
574
+ "relationships": []
575
+ },
576
+ {
577
+ "name": "v27-ent-Bank",
578
+ "source": "C4Context\n Enterprise_Boundary(b, \"Bank\") {\n System(a, \"A\")\n }\n",
579
+ "width": 616,
580
+ "height": 455.3,
581
+ "elements": {
582
+ "a": [308, 269.6]
583
+ },
584
+ "relationships": []
585
+ },
586
+ {
587
+ "name": "v28-person-2name",
588
+ "source": "C4Context\n Person(p, \"Personal Banking Customer\", \"A customer of the bank\")\n",
589
+ "width": 527.5,
590
+ "height": 455.6,
591
+ "elements": {
592
+ "p": [263.8, 266.3]
593
+ },
594
+ "relationships": []
595
+ },
596
+ {
597
+ "name": "v29-person-3name",
598
+ "source": "C4Context\n Person(p, \"A person whose name is unusually long and needs wrapping to lines\")\n",
599
+ "width": 516,
600
+ "height": 464.9,
601
+ "elements": {
602
+ "p": [258, 270.9]
603
+ },
604
+ "relationships": []
605
+ },
606
+ {
607
+ "name": "v30-person-wide",
608
+ "source": "C4Context\n Person(p, \"Customer\", \"A description that is long enough to wrap into three lines at the standard width of a shape\")\n",
609
+ "width": 516,
610
+ "height": 476.3,
611
+ "elements": {
612
+ "p": [258, 276.6]
613
+ },
614
+ "relationships": []
615
+ },
616
+ {
617
+ "name": "v31-sys-2name",
618
+ "source": "C4Context\n System(p, \"Personal Banking Customer\", \"A customer of the bank\")\n",
619
+ "width": 527.5,
620
+ "height": 365.3,
621
+ "elements": {
622
+ "p": [263.8, 221.1]
623
+ },
624
+ "relationships": []
625
+ }
626
+ ]
@@ -0,0 +1,42 @@
1
+ import { describe, it, expect } from 'vitest'
2
+ import { smoothCurvePath } from '../xychart/renderer.ts'
3
+
4
+ /** Every y coordinate in the path (Bezier control points bound the curve). */
5
+ function pathYs(d: string): number[] {
6
+ return [...d.matchAll(/(-?\d+(?:\.\d+)?),(-?\d+(?:\.\d+)?)/g)].map((m) =>
7
+ Number(m[2]),
8
+ )
9
+ }
10
+
11
+ function expectWithinRange(values: number[]) {
12
+ const points = values.map((y, i) => ({ x: i * 50, y }))
13
+ const ys = pathYs(smoothCurvePath(points))
14
+ const lo = Math.min(...values)
15
+ const hi = Math.max(...values)
16
+ for (const y of ys) {
17
+ expect(y).toBeGreaterThanOrEqual(lo - 0.01)
18
+ expect(y).toBeLessThanOrEqual(hi + 0.01)
19
+ }
20
+ }
21
+
22
+ describe('smoothCurvePath', () => {
23
+ it('stays within the data range on a sharp spike after a flat run', () => {
24
+ expectWithinRange([5, 12, 45, 380, 420, 250, 35, 8])
25
+ expectWithinRange([0, 0, 0, 100, 0, 0, 0])
26
+ })
27
+
28
+ it('stays within the data range on a flat run and alternating values', () => {
29
+ expectWithinRange([10, 10, 10, 10, 10])
30
+ expectWithinRange([0, 100, 0, 100, 0])
31
+ })
32
+
33
+ it('passes through every data point', () => {
34
+ const d = smoothCurvePath([
35
+ { x: 0, y: 10 },
36
+ { x: 50, y: 80 },
37
+ { x: 100, y: 20 },
38
+ ])
39
+ expect(d).toContain('50,80')
40
+ expect(d.endsWith('100,20')).toBe(true)
41
+ })
42
+ })