Skip to main content

merman_render/
model.rs

1use merman_core::ParseMetadata;
2use rustc_hash::FxHashMap;
3use serde::{Deserialize, Serialize};
4use serde_json::Value;
5use std::sync::Arc;
6
7#[derive(Debug, Clone, Serialize, Deserialize)]
8pub struct LayoutMeta {
9    pub diagram_type: String,
10    pub title: Option<String>,
11    pub config: Value,
12    pub effective_config: Value,
13}
14
15impl LayoutMeta {
16    pub fn from_parse_metadata(meta: &ParseMetadata) -> Self {
17        Self {
18            diagram_type: meta.diagram_type.clone(),
19            title: meta.title.clone(),
20            config: meta.config.as_value().clone(),
21            effective_config: meta.effective_config.as_value().clone(),
22        }
23    }
24}
25
26#[derive(Debug, Clone, Serialize, Deserialize)]
27pub struct Bounds {
28    pub min_x: f64,
29    pub min_y: f64,
30    pub max_x: f64,
31    pub max_y: f64,
32}
33
34impl Bounds {
35    pub fn from_points(points: impl IntoIterator<Item = (f64, f64)>) -> Option<Self> {
36        let mut it = points.into_iter();
37        let (x0, y0) = it.next()?;
38        let mut b = Self {
39            min_x: x0,
40            min_y: y0,
41            max_x: x0,
42            max_y: y0,
43        };
44        for (x, y) in it {
45            b.min_x = b.min_x.min(x);
46            b.min_y = b.min_y.min(y);
47            b.max_x = b.max_x.max(x);
48            b.max_y = b.max_y.max(y);
49        }
50        Some(b)
51    }
52}
53
54#[derive(Debug, Clone, Serialize, Deserialize)]
55pub struct LayoutPoint {
56    pub x: f64,
57    pub y: f64,
58}
59
60#[derive(Debug, Clone, Serialize, Deserialize)]
61pub struct LayoutLabel {
62    pub x: f64,
63    pub y: f64,
64    pub width: f64,
65    pub height: f64,
66}
67
68#[derive(Debug, Clone)]
69pub struct ClassNodeRowMetrics {
70    pub members: Vec<crate::text::TextMetrics>,
71    pub methods: Vec<crate::text::TextMetrics>,
72}
73
74#[derive(Debug, Clone, Serialize, Deserialize)]
75pub struct LayoutNode {
76    pub id: String,
77    pub x: f64,
78    pub y: f64,
79    pub width: f64,
80    pub height: f64,
81    pub is_cluster: bool,
82    #[serde(skip)]
83    pub label_width: Option<f64>,
84    #[serde(skip)]
85    pub label_height: Option<f64>,
86}
87
88#[derive(Debug, Clone, Serialize, Deserialize)]
89pub struct LayoutCluster {
90    pub id: String,
91    pub x: f64,
92    pub y: f64,
93    pub width: f64,
94    pub height: f64,
95    /// Mermaid cluster "diff" value used during cluster positioning.
96    pub diff: f64,
97    /// Mermaid cluster "offsetY" value: title bbox height minus half padding.
98    pub offset_y: f64,
99    pub title: String,
100    pub title_label: LayoutLabel,
101    pub requested_dir: Option<String>,
102    pub effective_dir: String,
103    pub padding: f64,
104    pub title_margin_top: f64,
105    pub title_margin_bottom: f64,
106}
107
108#[derive(Debug, Clone, Serialize, Deserialize)]
109pub struct LayoutEdge {
110    pub id: String,
111    pub from: String,
112    pub to: String,
113    #[serde(default)]
114    pub from_cluster: Option<String>,
115    #[serde(default)]
116    pub to_cluster: Option<String>,
117    pub points: Vec<LayoutPoint>,
118    pub label: Option<LayoutLabel>,
119    #[serde(default)]
120    pub start_label_left: Option<LayoutLabel>,
121    #[serde(default)]
122    pub start_label_right: Option<LayoutLabel>,
123    #[serde(default)]
124    pub end_label_left: Option<LayoutLabel>,
125    #[serde(default)]
126    pub end_label_right: Option<LayoutLabel>,
127    /// Optional SVG marker id for marker-start (e.g. ER cardinality markers).
128    #[serde(default)]
129    pub start_marker: Option<String>,
130    /// Optional SVG marker id for marker-end (e.g. ER cardinality markers).
131    #[serde(default)]
132    pub end_marker: Option<String>,
133    /// Optional SVG dash pattern (e.g. identifying vs non-identifying ER relationships).
134    #[serde(default)]
135    pub stroke_dasharray: Option<String>,
136}
137
138#[derive(Debug, Clone, Serialize, Deserialize)]
139pub struct BlockDiagramLayout {
140    pub nodes: Vec<LayoutNode>,
141    pub edges: Vec<LayoutEdge>,
142    pub bounds: Option<Bounds>,
143}
144
145#[derive(Debug, Clone, Serialize, Deserialize)]
146pub struct RequirementDiagramLayout {
147    pub nodes: Vec<LayoutNode>,
148    pub edges: Vec<LayoutEdge>,
149    pub bounds: Option<Bounds>,
150}
151
152#[derive(Debug, Clone, Serialize, Deserialize)]
153pub struct ArchitectureDiagramLayout {
154    pub nodes: Vec<LayoutNode>,
155    pub edges: Vec<LayoutEdge>,
156    pub bounds: Option<Bounds>,
157}
158
159#[derive(Debug, Clone, Serialize, Deserialize)]
160pub struct MindmapDiagramLayout {
161    pub nodes: Vec<LayoutNode>,
162    pub edges: Vec<LayoutEdge>,
163    pub bounds: Option<Bounds>,
164}
165
166#[derive(Debug, Clone, Serialize, Deserialize)]
167pub struct SankeyNodeLayout {
168    pub id: String,
169    pub index: usize,
170    pub depth: usize,
171    pub height: usize,
172    pub layer: usize,
173    pub value: f64,
174    pub x0: f64,
175    pub x1: f64,
176    pub y0: f64,
177    pub y1: f64,
178}
179
180#[derive(Debug, Clone, Serialize, Deserialize)]
181pub struct SankeyLinkLayout {
182    pub index: usize,
183    pub source: String,
184    pub target: String,
185    pub value: f64,
186    pub width: f64,
187    pub y0: f64,
188    pub y1: f64,
189}
190
191#[derive(Debug, Clone, Serialize, Deserialize)]
192pub struct SankeyDiagramLayout {
193    pub bounds: Option<Bounds>,
194    pub width: f64,
195    pub height: f64,
196    pub node_width: f64,
197    pub node_padding: f64,
198    pub nodes: Vec<SankeyNodeLayout>,
199    pub links: Vec<SankeyLinkLayout>,
200}
201
202#[derive(Debug, Clone, Serialize, Deserialize)]
203pub struct RadarAxisLayout {
204    pub label: String,
205    pub angle: f64,
206    pub line_x2: f64,
207    pub line_y2: f64,
208    pub label_x: f64,
209    pub label_y: f64,
210}
211
212#[derive(Debug, Clone, Serialize, Deserialize)]
213pub struct RadarGraticuleShapeLayout {
214    pub kind: String,
215    pub r: Option<f64>,
216    #[serde(default)]
217    pub points: Vec<LayoutPoint>,
218}
219
220#[derive(Debug, Clone, Serialize, Deserialize)]
221pub struct RadarCurveLayout {
222    pub label: String,
223    pub class_index: i64,
224    #[serde(default)]
225    pub points: Vec<LayoutPoint>,
226    pub path_d: String,
227}
228
229#[derive(Debug, Clone, Serialize, Deserialize)]
230pub struct RadarLegendItemLayout {
231    pub label: String,
232    pub class_index: i64,
233    pub x: f64,
234    pub y: f64,
235}
236
237#[derive(Debug, Clone, Serialize, Deserialize)]
238pub struct RadarDiagramLayout {
239    pub bounds: Option<Bounds>,
240    pub svg_width: f64,
241    pub svg_height: f64,
242    pub center_x: f64,
243    pub center_y: f64,
244    pub radius: f64,
245    pub axis_label_factor: f64,
246    pub title_y: f64,
247    #[serde(default)]
248    pub axes: Vec<RadarAxisLayout>,
249    #[serde(default)]
250    pub graticules: Vec<RadarGraticuleShapeLayout>,
251    #[serde(default)]
252    pub curves: Vec<RadarCurveLayout>,
253    #[serde(default)]
254    pub legend_items: Vec<RadarLegendItemLayout>,
255}
256
257#[derive(Debug, Clone, Serialize, Deserialize)]
258pub struct TreemapSectionLayout {
259    pub name: String,
260    pub depth: i64,
261    pub value: f64,
262    pub x0: f64,
263    pub y0: f64,
264    pub x1: f64,
265    pub y1: f64,
266    #[serde(default)]
267    pub class_selector: Option<String>,
268    #[serde(default)]
269    pub css_compiled_styles: Option<Vec<String>>,
270}
271
272#[derive(Debug, Clone, Serialize, Deserialize)]
273pub struct TreemapLeafLayout {
274    pub name: String,
275    pub value: f64,
276    #[serde(default)]
277    pub parent_name: Option<String>,
278    pub x0: f64,
279    pub y0: f64,
280    pub x1: f64,
281    pub y1: f64,
282    #[serde(default)]
283    pub class_selector: Option<String>,
284    #[serde(default)]
285    pub css_compiled_styles: Option<Vec<String>>,
286}
287
288#[derive(Debug, Clone, Serialize, Deserialize)]
289pub struct TreemapDiagramLayout {
290    pub title_height: f64,
291    pub width: f64,
292    pub height: f64,
293    pub use_max_width: bool,
294    pub diagram_padding: f64,
295    pub show_values: bool,
296    pub value_format: String,
297    #[serde(default, rename = "accTitle")]
298    pub acc_title: Option<String>,
299    #[serde(default, rename = "accDescr")]
300    pub acc_descr: Option<String>,
301    #[serde(default)]
302    pub title: Option<String>,
303    #[serde(default)]
304    pub sections: Vec<TreemapSectionLayout>,
305    #[serde(default)]
306    pub leaves: Vec<TreemapLeafLayout>,
307}
308
309#[derive(Debug, Clone, Serialize, Deserialize)]
310pub struct XyChartRectData {
311    pub x: f64,
312    pub y: f64,
313    pub width: f64,
314    pub height: f64,
315    pub fill: String,
316    #[serde(rename = "strokeFill")]
317    pub stroke_fill: String,
318    #[serde(rename = "strokeWidth")]
319    pub stroke_width: f64,
320}
321
322#[derive(Debug, Clone, Serialize, Deserialize)]
323pub struct XyChartTextData {
324    pub text: String,
325    pub x: f64,
326    pub y: f64,
327    pub fill: String,
328    #[serde(rename = "fontSize")]
329    pub font_size: f64,
330    #[serde(default)]
331    pub rotation: f64,
332    #[serde(rename = "verticalPos")]
333    pub vertical_pos: String,
334    #[serde(rename = "horizontalPos")]
335    pub horizontal_pos: String,
336}
337
338#[derive(Debug, Clone, Serialize, Deserialize)]
339pub struct XyChartPathData {
340    pub path: String,
341    #[serde(default)]
342    pub fill: Option<String>,
343    #[serde(rename = "strokeFill")]
344    pub stroke_fill: String,
345    #[serde(rename = "strokeWidth")]
346    pub stroke_width: f64,
347}
348
349#[derive(Debug, Clone, Serialize, Deserialize)]
350#[serde(tag = "type")]
351pub enum XyChartDrawableElem {
352    #[serde(rename = "rect")]
353    Rect {
354        #[serde(rename = "groupTexts")]
355        group_texts: Vec<String>,
356        data: Vec<XyChartRectData>,
357    },
358    #[serde(rename = "text")]
359    Text {
360        #[serde(rename = "groupTexts")]
361        group_texts: Vec<String>,
362        data: Vec<XyChartTextData>,
363    },
364    #[serde(rename = "path")]
365    Path {
366        #[serde(rename = "groupTexts")]
367        group_texts: Vec<String>,
368        data: Vec<XyChartPathData>,
369    },
370}
371
372#[derive(Debug, Clone, Serialize, Deserialize)]
373pub struct XyChartDiagramLayout {
374    pub width: f64,
375    pub height: f64,
376    #[serde(rename = "chartOrientation")]
377    pub chart_orientation: String,
378    #[serde(rename = "showDataLabel")]
379    pub show_data_label: bool,
380    #[serde(rename = "backgroundColor")]
381    pub background_color: String,
382    #[serde(rename = "labelData")]
383    pub label_data: Vec<String>,
384    #[serde(default)]
385    pub drawables: Vec<XyChartDrawableElem>,
386}
387
388#[derive(Debug, Clone, Serialize, Deserialize)]
389pub struct QuadrantChartTextData {
390    pub text: String,
391    pub x: f64,
392    pub y: f64,
393    pub fill: String,
394    #[serde(rename = "fontSize")]
395    pub font_size: f64,
396    #[serde(default)]
397    pub rotation: f64,
398    #[serde(rename = "verticalPos")]
399    pub vertical_pos: String,
400    #[serde(rename = "horizontalPos")]
401    pub horizontal_pos: String,
402}
403
404pub type QuadrantChartAxisLabelData = QuadrantChartTextData;
405
406#[derive(Debug, Clone, Serialize, Deserialize)]
407pub struct QuadrantChartQuadrantData {
408    pub x: f64,
409    pub y: f64,
410    pub width: f64,
411    pub height: f64,
412    pub fill: String,
413    pub text: QuadrantChartTextData,
414}
415
416#[derive(Debug, Clone, Serialize, Deserialize)]
417pub struct QuadrantChartBorderLineData {
418    #[serde(rename = "strokeWidth")]
419    pub stroke_width: f64,
420    #[serde(rename = "strokeFill")]
421    pub stroke_fill: String,
422    pub x1: f64,
423    pub y1: f64,
424    pub x2: f64,
425    pub y2: f64,
426}
427
428#[derive(Debug, Clone, Serialize, Deserialize)]
429pub struct QuadrantChartPointData {
430    pub x: f64,
431    pub y: f64,
432    pub fill: String,
433    pub radius: f64,
434    #[serde(rename = "strokeColor")]
435    pub stroke_color: String,
436    #[serde(rename = "strokeWidth")]
437    pub stroke_width: String,
438    pub text: QuadrantChartTextData,
439}
440
441#[derive(Debug, Clone, Serialize, Deserialize)]
442pub struct QuadrantChartDiagramLayout {
443    pub width: f64,
444    pub height: f64,
445    #[serde(default)]
446    pub title: Option<QuadrantChartTextData>,
447    pub quadrants: Vec<QuadrantChartQuadrantData>,
448    #[serde(rename = "borderLines")]
449    pub border_lines: Vec<QuadrantChartBorderLineData>,
450    pub points: Vec<QuadrantChartPointData>,
451    #[serde(rename = "axisLabels")]
452    pub axis_labels: Vec<QuadrantChartAxisLabelData>,
453}
454
455#[derive(Debug, Clone, Serialize, Deserialize)]
456pub struct FlowchartV2Layout {
457    pub nodes: Vec<LayoutNode>,
458    pub edges: Vec<LayoutEdge>,
459    pub clusters: Vec<LayoutCluster>,
460    pub bounds: Option<Bounds>,
461    /// Mermaid's DOM insertion order for each extracted root graph (`""` = top-level root).
462    #[serde(skip)]
463    pub dom_node_order_by_root: std::collections::HashMap<String, Vec<String>>,
464}
465
466#[derive(Debug, Clone, Serialize, Deserialize)]
467pub struct StateDiagramV2Layout {
468    pub nodes: Vec<LayoutNode>,
469    pub edges: Vec<LayoutEdge>,
470    pub clusters: Vec<LayoutCluster>,
471    pub bounds: Option<Bounds>,
472}
473
474#[derive(Debug, Clone, Serialize, Deserialize)]
475pub struct ClassDiagramV2Layout {
476    pub nodes: Vec<LayoutNode>,
477    pub edges: Vec<LayoutEdge>,
478    pub clusters: Vec<LayoutCluster>,
479    pub bounds: Option<Bounds>,
480    #[serde(skip)]
481    pub class_row_metrics_by_id: FxHashMap<String, Arc<ClassNodeRowMetrics>>,
482}
483
484#[derive(Debug, Clone, Serialize, Deserialize)]
485pub struct ErDiagramLayout {
486    pub nodes: Vec<LayoutNode>,
487    pub edges: Vec<LayoutEdge>,
488    pub bounds: Option<Bounds>,
489}
490
491#[derive(Debug, Clone, Serialize, Deserialize)]
492pub struct SequenceDiagramLayout {
493    pub nodes: Vec<LayoutNode>,
494    pub edges: Vec<LayoutEdge>,
495    pub clusters: Vec<LayoutCluster>,
496    pub bounds: Option<Bounds>,
497}
498
499#[derive(Debug, Clone, Serialize, Deserialize)]
500pub struct InfoDiagramLayout {
501    pub bounds: Option<Bounds>,
502    pub version: String,
503}
504
505#[derive(Debug, Clone, Serialize, Deserialize)]
506pub struct PacketBlockLayout {
507    pub start: i64,
508    pub end: i64,
509    pub label: String,
510    pub x: f64,
511    pub y: f64,
512    pub width: f64,
513    pub height: f64,
514}
515
516#[derive(Debug, Clone, Serialize, Deserialize)]
517pub struct PacketWordLayout {
518    pub blocks: Vec<PacketBlockLayout>,
519}
520
521#[derive(Debug, Clone, Serialize, Deserialize)]
522pub struct PacketDiagramLayout {
523    pub bounds: Option<Bounds>,
524    pub width: f64,
525    pub height: f64,
526    pub row_height: f64,
527    pub padding_x: f64,
528    pub padding_y: f64,
529    pub bit_width: f64,
530    pub bits_per_row: i64,
531    pub show_bits: bool,
532    pub words: Vec<PacketWordLayout>,
533}
534
535#[derive(Debug, Clone, Serialize, Deserialize)]
536pub struct PieSliceLayout {
537    pub label: String,
538    pub value: f64,
539    pub start_angle: f64,
540    pub end_angle: f64,
541    pub is_full_circle: bool,
542    pub percent: i64,
543    pub text_x: f64,
544    pub text_y: f64,
545    pub fill: String,
546}
547
548#[derive(Debug, Clone, Serialize, Deserialize)]
549pub struct PieLegendItemLayout {
550    pub label: String,
551    pub value: f64,
552    pub fill: String,
553    pub y: f64,
554}
555
556#[derive(Debug, Clone, Serialize, Deserialize)]
557pub struct PieDiagramLayout {
558    pub bounds: Option<Bounds>,
559    pub center_x: f64,
560    pub center_y: f64,
561    pub radius: f64,
562    pub outer_radius: f64,
563    pub legend_x: f64,
564    pub legend_start_y: f64,
565    pub legend_step_y: f64,
566    pub slices: Vec<PieSliceLayout>,
567    pub legend_items: Vec<PieLegendItemLayout>,
568}
569
570#[derive(Debug, Clone, Serialize, Deserialize)]
571pub struct TimelineNodeLayout {
572    pub x: f64,
573    pub y: f64,
574    pub width: f64,
575    pub height: f64,
576    /// Width used for wrapping (excluding padding).
577    pub content_width: f64,
578    /// Padding used to compute `width` (Mermaid 11.12.2 uses 20).
579    pub padding: f64,
580    pub section_class: String,
581    pub label: String,
582    /// Wrapped lines as rendered into `<tspan>` nodes.
583    pub label_lines: Vec<String>,
584    pub kind: String,
585}
586
587#[derive(Debug, Clone, Serialize, Deserialize)]
588pub struct TimelineLineLayout {
589    pub kind: String,
590    pub x1: f64,
591    pub y1: f64,
592    pub x2: f64,
593    pub y2: f64,
594}
595
596#[derive(Debug, Clone, Serialize, Deserialize)]
597pub struct TimelineTaskLayout {
598    pub node: TimelineNodeLayout,
599    pub connector: TimelineLineLayout,
600    pub events: Vec<TimelineNodeLayout>,
601}
602
603#[derive(Debug, Clone, Serialize, Deserialize)]
604pub struct TimelineSectionLayout {
605    pub node: TimelineNodeLayout,
606    pub tasks: Vec<TimelineTaskLayout>,
607}
608
609#[derive(Debug, Clone, Serialize, Deserialize)]
610pub struct TimelineDiagramLayout {
611    pub bounds: Option<Bounds>,
612    pub left_margin: f64,
613    pub base_x: f64,
614    pub base_y: f64,
615    /// `svg.node().getBBox().width` computed *before* title/activity line are inserted.
616    pub pre_title_box_width: f64,
617    pub sections: Vec<TimelineSectionLayout>,
618    #[serde(default)]
619    pub orphan_tasks: Vec<TimelineTaskLayout>,
620    pub activity_line: TimelineLineLayout,
621    pub title: Option<String>,
622    pub title_x: f64,
623    pub title_y: f64,
624}
625
626#[derive(Debug, Clone, Serialize, Deserialize)]
627pub struct JourneyActorLegendLineLayout {
628    pub text: String,
629    pub x: f64,
630    pub y: f64,
631    pub tspan_x: f64,
632    pub text_margin: f64,
633}
634
635#[derive(Debug, Clone, Serialize, Deserialize)]
636pub struct JourneyActorLegendItemLayout {
637    pub actor: String,
638    pub pos: i64,
639    pub color: String,
640    pub circle_cx: f64,
641    pub circle_cy: f64,
642    pub circle_r: f64,
643    pub label_lines: Vec<JourneyActorLegendLineLayout>,
644}
645
646#[derive(Debug, Clone, Serialize, Deserialize)]
647pub enum JourneyMouthKind {
648    Smile,
649    Sad,
650    Ambivalent,
651}
652
653#[derive(Debug, Clone, Serialize, Deserialize)]
654pub struct JourneyTaskActorCircleLayout {
655    pub actor: String,
656    pub pos: i64,
657    pub color: String,
658    pub cx: f64,
659    pub cy: f64,
660    pub r: f64,
661}
662
663#[derive(Debug, Clone, Serialize, Deserialize)]
664pub struct JourneyTaskLayout {
665    pub index: i64,
666    pub section: String,
667    pub task: String,
668    pub score: i64,
669    pub x: f64,
670    pub y: f64,
671    pub width: f64,
672    pub height: f64,
673    pub fill: String,
674    pub num: i64,
675    pub people: Vec<String>,
676    pub actor_circles: Vec<JourneyTaskActorCircleLayout>,
677    pub line_id: String,
678    pub line_x1: f64,
679    pub line_y1: f64,
680    pub line_x2: f64,
681    pub line_y2: f64,
682    pub face_cx: f64,
683    pub face_cy: Option<f64>,
684    pub mouth: JourneyMouthKind,
685}
686
687#[derive(Debug, Clone, Serialize, Deserialize)]
688pub struct JourneySectionLayout {
689    pub section: String,
690    pub num: i64,
691    pub x: f64,
692    pub y: f64,
693    pub width: f64,
694    pub height: f64,
695    pub fill: String,
696    pub task_count: i64,
697}
698
699#[derive(Debug, Clone, Serialize, Deserialize)]
700pub struct JourneyLineLayout {
701    pub x1: f64,
702    pub y1: f64,
703    pub x2: f64,
704    pub y2: f64,
705}
706
707#[derive(Debug, Clone, Serialize, Deserialize)]
708pub struct JourneyDiagramLayout {
709    pub bounds: Option<Bounds>,
710    pub left_margin: f64,
711    pub max_actor_label_width: f64,
712    pub width: f64,
713    pub height: f64,
714    pub svg_height: f64,
715    pub title: Option<String>,
716    pub title_x: f64,
717    pub title_y: f64,
718    pub actor_legend: Vec<JourneyActorLegendItemLayout>,
719    pub sections: Vec<JourneySectionLayout>,
720    pub tasks: Vec<JourneyTaskLayout>,
721    pub activity_line: JourneyLineLayout,
722}
723
724#[derive(Debug, Clone, Serialize, Deserialize)]
725pub struct KanbanSectionLayout {
726    pub id: String,
727    pub label: String,
728    pub index: i64,
729    pub center_x: f64,
730    pub center_y: f64,
731    pub width: f64,
732    pub rect_y: f64,
733    pub rect_height: f64,
734    pub rx: f64,
735    pub ry: f64,
736    pub label_width: f64,
737}
738
739#[derive(Debug, Clone, Serialize, Deserialize)]
740pub struct KanbanItemLayout {
741    pub id: String,
742    pub label: String,
743    pub parent_id: String,
744    pub center_x: f64,
745    pub center_y: f64,
746    pub width: f64,
747    pub height: f64,
748    pub rx: f64,
749    pub ry: f64,
750    #[serde(default)]
751    pub ticket: Option<String>,
752    #[serde(default)]
753    pub assigned: Option<String>,
754    #[serde(default)]
755    pub priority: Option<String>,
756    #[serde(default)]
757    pub icon: Option<String>,
758}
759
760#[derive(Debug, Clone, Serialize, Deserialize)]
761pub struct KanbanDiagramLayout {
762    pub bounds: Option<Bounds>,
763    pub section_width: f64,
764    pub padding: f64,
765    pub max_label_height: f64,
766    pub viewbox_padding: f64,
767    pub sections: Vec<KanbanSectionLayout>,
768    pub items: Vec<KanbanItemLayout>,
769}
770
771#[derive(Debug, Clone, Serialize, Deserialize)]
772pub struct GitGraphBranchLayout {
773    pub name: String,
774    pub index: i64,
775    pub pos: f64,
776    pub bbox_width: f64,
777    pub bbox_height: f64,
778}
779
780#[derive(Debug, Clone, Serialize, Deserialize)]
781pub struct GitGraphCommitLayout {
782    pub id: String,
783    pub message: String,
784    pub seq: i64,
785    pub commit_type: i64,
786    #[serde(default)]
787    pub custom_type: Option<i64>,
788    #[serde(default)]
789    pub custom_id: Option<bool>,
790    #[serde(default)]
791    pub tags: Vec<String>,
792    #[serde(default)]
793    pub parents: Vec<String>,
794    pub branch: String,
795    pub pos: f64,
796    pub pos_with_offset: f64,
797    pub x: f64,
798    pub y: f64,
799}
800
801#[derive(Debug, Clone, Serialize, Deserialize)]
802pub struct GitGraphArrowLayout {
803    pub from: String,
804    pub to: String,
805    pub class_index: i64,
806    pub d: String,
807}
808
809#[derive(Debug, Clone, Serialize, Deserialize)]
810pub struct GitGraphDiagramLayout {
811    pub bounds: Option<Bounds>,
812    pub direction: String,
813    pub rotate_commit_label: bool,
814    pub show_branches: bool,
815    pub show_commit_label: bool,
816    pub parallel_commits: bool,
817    pub diagram_padding: f64,
818    pub max_pos: f64,
819    pub branches: Vec<GitGraphBranchLayout>,
820    pub commits: Vec<GitGraphCommitLayout>,
821    pub arrows: Vec<GitGraphArrowLayout>,
822}
823
824#[derive(Debug, Clone, Serialize, Deserialize)]
825pub struct GanttAxisTickLayout {
826    pub time_ms: i64,
827    pub x: f64,
828    pub label: String,
829}
830
831#[derive(Debug, Clone, Serialize, Deserialize)]
832pub struct GanttExcludeRangeLayout {
833    pub id: String,
834    pub start_ms: i64,
835    pub end_ms: i64,
836    pub x: f64,
837    pub y: f64,
838    pub width: f64,
839    pub height: f64,
840}
841
842#[derive(Debug, Clone, Serialize, Deserialize)]
843pub struct GanttSectionTitleLayout {
844    pub section: String,
845    pub index: i64,
846    pub x: f64,
847    pub y: f64,
848    pub dy_em: f64,
849    pub lines: Vec<String>,
850    pub class: String,
851}
852
853#[derive(Debug, Clone, Serialize, Deserialize)]
854pub struct GanttRowLayout {
855    pub index: i64,
856    pub x: f64,
857    pub y: f64,
858    pub width: f64,
859    pub height: f64,
860    pub class: String,
861}
862
863#[derive(Debug, Clone, Serialize, Deserialize)]
864pub struct GanttTaskLabelLayout {
865    pub id: String,
866    pub text: String,
867    pub font_size: f64,
868    pub width: f64,
869    pub x: f64,
870    pub y: f64,
871    pub class: String,
872}
873
874#[derive(Debug, Clone, Serialize, Deserialize)]
875pub struct GanttTaskBarLayout {
876    pub id: String,
877    pub x: f64,
878    pub y: f64,
879    pub width: f64,
880    pub height: f64,
881    pub rx: f64,
882    pub ry: f64,
883    pub class: String,
884}
885
886#[derive(Debug, Clone, Serialize, Deserialize)]
887pub struct GanttTaskLayout {
888    pub id: String,
889    pub task: String,
890    pub section: String,
891    pub task_type: String,
892    pub order: i64,
893    pub start_ms: i64,
894    pub end_ms: i64,
895    #[serde(default)]
896    pub render_end_ms: Option<i64>,
897    pub milestone: bool,
898    pub vert: bool,
899    pub bar: GanttTaskBarLayout,
900    pub label: GanttTaskLabelLayout,
901}
902
903#[derive(Debug, Clone, Serialize, Deserialize)]
904pub struct GanttDiagramLayout {
905    pub bounds: Option<Bounds>,
906    pub width: f64,
907    pub height: f64,
908    pub left_padding: f64,
909    pub right_padding: f64,
910    pub top_padding: f64,
911    pub grid_line_start_padding: f64,
912    pub bar_height: f64,
913    pub bar_gap: f64,
914    pub title_top_margin: f64,
915    pub font_size: f64,
916    pub section_font_size: f64,
917    pub number_section_styles: i64,
918    pub display_mode: String,
919    pub date_format: String,
920    pub axis_format: String,
921    #[serde(default)]
922    pub tick_interval: Option<String>,
923    pub top_axis: bool,
924    pub today_marker: String,
925    pub categories: Vec<String>,
926    pub rows: Vec<GanttRowLayout>,
927    pub section_titles: Vec<GanttSectionTitleLayout>,
928    pub tasks: Vec<GanttTaskLayout>,
929    pub excludes: Vec<GanttExcludeRangeLayout>,
930    #[serde(default)]
931    pub has_excludes_layer: bool,
932    pub bottom_ticks: Vec<GanttAxisTickLayout>,
933    #[serde(default)]
934    pub top_ticks: Vec<GanttAxisTickLayout>,
935    pub title: Option<String>,
936    pub title_x: f64,
937    pub title_y: f64,
938}
939
940#[derive(Debug, Clone, Serialize, Deserialize)]
941pub struct C4TextBlockLayout {
942    pub text: String,
943    pub y: f64,
944    pub width: f64,
945    pub height: f64,
946    pub line_count: usize,
947}
948
949#[derive(Debug, Clone, Serialize, Deserialize)]
950pub struct C4ImageLayout {
951    pub width: f64,
952    pub height: f64,
953    pub y: f64,
954}
955
956#[derive(Debug, Clone, Serialize, Deserialize)]
957pub struct C4ShapeLayout {
958    pub alias: String,
959    pub parent_boundary: String,
960    pub type_c4_shape: String,
961    pub x: f64,
962    pub y: f64,
963    pub width: f64,
964    pub height: f64,
965    pub margin: f64,
966    pub image: C4ImageLayout,
967    pub type_block: C4TextBlockLayout,
968    pub label: C4TextBlockLayout,
969    #[serde(default)]
970    pub ty: Option<C4TextBlockLayout>,
971    #[serde(default)]
972    pub techn: Option<C4TextBlockLayout>,
973    #[serde(default)]
974    pub descr: Option<C4TextBlockLayout>,
975}
976
977#[derive(Debug, Clone, Serialize, Deserialize)]
978pub struct C4BoundaryLayout {
979    pub alias: String,
980    pub parent_boundary: String,
981    pub x: f64,
982    pub y: f64,
983    pub width: f64,
984    pub height: f64,
985    pub image: C4ImageLayout,
986    pub label: C4TextBlockLayout,
987    #[serde(default)]
988    pub ty: Option<C4TextBlockLayout>,
989    #[serde(default)]
990    pub descr: Option<C4TextBlockLayout>,
991}
992
993#[derive(Debug, Clone, Serialize, Deserialize)]
994pub struct C4RelLayout {
995    pub from: String,
996    pub to: String,
997    pub rel_type: String,
998    pub start_point: LayoutPoint,
999    pub end_point: LayoutPoint,
1000    #[serde(default)]
1001    pub offset_x: Option<i64>,
1002    #[serde(default)]
1003    pub offset_y: Option<i64>,
1004    pub label: C4TextBlockLayout,
1005    #[serde(default)]
1006    pub techn: Option<C4TextBlockLayout>,
1007    #[serde(default)]
1008    pub descr: Option<C4TextBlockLayout>,
1009}
1010
1011#[derive(Debug, Clone, Serialize, Deserialize)]
1012pub struct C4DiagramLayout {
1013    pub bounds: Option<Bounds>,
1014    pub width: f64,
1015    pub height: f64,
1016    pub viewport_width: f64,
1017    pub viewport_height: f64,
1018    pub c4_type: String,
1019    pub title: Option<String>,
1020    pub boundaries: Vec<C4BoundaryLayout>,
1021    pub shapes: Vec<C4ShapeLayout>,
1022    pub rels: Vec<C4RelLayout>,
1023}
1024
1025#[derive(Debug, Clone, Serialize, Deserialize)]
1026pub struct ErrorDiagramLayout {
1027    pub viewbox_width: f64,
1028    pub viewbox_height: f64,
1029    pub max_width_px: f64,
1030}
1031
1032#[derive(Debug, Clone, Serialize, Deserialize)]
1033#[allow(clippy::large_enum_variant)]
1034pub enum LayoutDiagram {
1035    BlockDiagram(BlockDiagramLayout),
1036    RequirementDiagram(RequirementDiagramLayout),
1037    ArchitectureDiagram(ArchitectureDiagramLayout),
1038    MindmapDiagram(MindmapDiagramLayout),
1039    SankeyDiagram(SankeyDiagramLayout),
1040    RadarDiagram(RadarDiagramLayout),
1041    TreemapDiagram(TreemapDiagramLayout),
1042    XyChartDiagram(XyChartDiagramLayout),
1043    QuadrantChartDiagram(QuadrantChartDiagramLayout),
1044    FlowchartV2(FlowchartV2Layout),
1045    StateDiagramV2(StateDiagramV2Layout),
1046    ClassDiagramV2(ClassDiagramV2Layout),
1047    ErDiagram(ErDiagramLayout),
1048    SequenceDiagram(SequenceDiagramLayout),
1049    InfoDiagram(InfoDiagramLayout),
1050    PacketDiagram(PacketDiagramLayout),
1051    TimelineDiagram(TimelineDiagramLayout),
1052    PieDiagram(PieDiagramLayout),
1053    JourneyDiagram(JourneyDiagramLayout),
1054    KanbanDiagram(KanbanDiagramLayout),
1055    GitGraphDiagram(GitGraphDiagramLayout),
1056    GanttDiagram(GanttDiagramLayout),
1057    C4Diagram(C4DiagramLayout),
1058    ErrorDiagram(ErrorDiagramLayout),
1059}
1060
1061#[derive(Debug, Clone, Serialize, Deserialize)]
1062pub struct LayoutedDiagram {
1063    pub meta: LayoutMeta,
1064    pub semantic: Value,
1065    pub layout: LayoutDiagram,
1066}