pub use crate::diagrams::util::{esc, fmt};
pub fn svg_root(id: &str, max_w: f64, vb_w: f64, vb_h: f64) -> String {
format!(
r##"<svg id="{id}" width="100%" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" class="flowchart" style="max-width: {max_w}px;" viewBox="0 0 {vb_w} {vb_h}" role="graphics-document document" aria-roledescription="flowchart-v2">"##,
)
}
pub fn drop_shadow_filter(id: &str) -> String {
format!(
"<defs><filter id=\"{id}-drop-shadow\" height=\"130%\" width=\"130%\"><feDropShadow dx=\"4\" dy=\"4\" stdDeviation=\"0\" flood-opacity=\"0.06\" flood-color=\"#000000\"></feDropShadow></filter></defs>",
)
}
pub fn drop_shadow_filter_small(id: &str) -> String {
format!(
"<defs><filter id=\"{id}-drop-shadow-small\" height=\"150%\" width=\"150%\"><feDropShadow dx=\"2\" dy=\"2\" stdDeviation=\"0\" flood-opacity=\"0.06\" flood-color=\"#000000\"></feDropShadow></filter></defs>",
)
}
pub fn all_markers(id: &str, color: &str) -> String {
let mut m = String::new();
m.push_str(&marker_point_end(id, color));
m.push_str(&marker_point_start(id, color));
m.push_str(&marker_point_end_margin(id, color));
m.push_str(&marker_point_start_margin(id, color));
m.push_str(&marker_circle_end(id, color));
m.push_str(&marker_circle_start(id, color));
m.push_str(&marker_circle_end_margin(id, color));
m.push_str(&marker_circle_start_margin(id, color));
m.push_str(&marker_cross_end(id, color));
m.push_str(&marker_cross_start(id, color));
m.push_str(&marker_cross_end_margin(id, color));
m.push_str(&marker_cross_start_margin(id, color));
m
}
pub fn marker_point_end(id: &str, color: &str) -> String {
format!(
r##"<marker id="{id}_flowchart-v2-pointEnd" class="marker flowchart-v2" viewBox="0 0 10 10" refX="5" refY="5" markerUnits="userSpaceOnUse" markerWidth="8" markerHeight="8" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowMarkerPath" fill="{color}" stroke="{color}" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker>"##
)
}
pub fn marker_point_start(id: &str, color: &str) -> String {
format!(
r##"<marker id="{id}_flowchart-v2-pointStart" class="marker flowchart-v2" viewBox="0 0 10 10" refX="4.5" refY="5" markerUnits="userSpaceOnUse" markerWidth="8" markerHeight="8" orient="auto"><path d="M 0 5 L 10 10 L 10 0 z" class="arrowMarkerPath" fill="{color}" stroke="{color}" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker>"##
)
}
pub fn marker_point_end_margin(id: &str, color: &str) -> String {
format!(
r##"<marker id="{id}_flowchart-v2-pointEnd-margin" class="marker flowchart-v2" viewBox="0 0 11.5 14" refX="11.5" refY="7" markerUnits="userSpaceOnUse" markerWidth="10.5" markerHeight="14" orient="auto"><path d="M 0 0 L 11.5 7 L 0 14 z" class="arrowMarkerPath" fill="{color}" stroke="{color}" style="stroke-width: 0; stroke-dasharray: 1, 0;"></path></marker>"##
)
}
pub fn marker_point_start_margin(id: &str, color: &str) -> String {
format!(
r##"<marker id="{id}_flowchart-v2-pointStart-margin" class="marker flowchart-v2" viewBox="0 0 11.5 14" refX="1" refY="7" markerUnits="userSpaceOnUse" markerWidth="11.5" markerHeight="14" orient="auto"><polygon points="0,7 11.5,14 11.5,0" class="arrowMarkerPath" fill="{color}" stroke="{color}" style="stroke-width: 0; stroke-dasharray: 1, 0;"></polygon></marker>"##
)
}
pub fn marker_circle_end(id: &str, color: &str) -> String {
format!(
r##"<marker id="{id}_flowchart-v2-circleEnd" class="marker flowchart-v2" viewBox="0 0 10 10" refX="11" refY="5" markerUnits="userSpaceOnUse" markerWidth="11" markerHeight="11" orient="auto"><circle cx="5" cy="5" r="5" class="arrowMarkerPath" fill="{color}" stroke="{color}" style="stroke-width: 1; stroke-dasharray: 1, 0;"></circle></marker>"##
)
}
pub fn marker_circle_start(id: &str, color: &str) -> String {
format!(
r##"<marker id="{id}_flowchart-v2-circleStart" class="marker flowchart-v2" viewBox="0 0 10 10" refX="-1" refY="5" markerUnits="userSpaceOnUse" markerWidth="11" markerHeight="11" orient="auto"><circle cx="5" cy="5" r="5" class="arrowMarkerPath" fill="{color}" stroke="{color}" style="stroke-width: 1; stroke-dasharray: 1, 0;"></circle></marker>"##
)
}
pub fn marker_circle_end_margin(id: &str, color: &str) -> String {
format!(
r##"<marker id="{id}_flowchart-v2-circleEnd-margin" class="marker flowchart-v2" viewBox="0 0 10 10" refY="5" refX="12.25" markerUnits="userSpaceOnUse" markerWidth="14" markerHeight="14" orient="auto"><circle cx="5" cy="5" r="5" class="arrowMarkerPath" fill="{color}" stroke="{color}" style="stroke-width: 0; stroke-dasharray: 1, 0;"></circle></marker>"##
)
}
pub fn marker_circle_start_margin(id: &str, color: &str) -> String {
format!(
r##"<marker id="{id}_flowchart-v2-circleStart-margin" class="marker flowchart-v2" viewBox="0 0 10 10" refX="-2" refY="5" markerUnits="userSpaceOnUse" markerWidth="14" markerHeight="14" orient="auto"><circle cx="5" cy="5" r="5" class="arrowMarkerPath" fill="{color}" stroke="{color}" style="stroke-width: 0; stroke-dasharray: 1, 0;"></circle></marker>"##
)
}
pub fn marker_cross_end(id: &str, color: &str) -> String {
format!(
r##"<marker id="{id}_flowchart-v2-crossEnd" class="marker cross flowchart-v2" viewBox="0 0 11 11" refX="12" refY="5.2" markerUnits="userSpaceOnUse" markerWidth="11" markerHeight="11" orient="auto"><path d="M 1,1 l 9,9 M 10,1 l -9,9" class="arrowMarkerPath" fill="{color}" stroke="{color}" style="stroke-width: 2; stroke-dasharray: 1, 0;"></path></marker>"##
)
}
pub fn marker_cross_start(id: &str, color: &str) -> String {
format!(
r##"<marker id="{id}_flowchart-v2-crossStart" class="marker cross flowchart-v2" viewBox="0 0 11 11" refX="-1" refY="5.2" markerUnits="userSpaceOnUse" markerWidth="11" markerHeight="11" orient="auto"><path d="M 1,1 l 9,9 M 10,1 l -9,9" class="arrowMarkerPath" fill="{color}" stroke="{color}" style="stroke-width: 2; stroke-dasharray: 1, 0;"></path></marker>"##
)
}
pub fn marker_cross_end_margin(id: &str, color: &str) -> String {
format!(
r##"<marker id="{id}_flowchart-v2-crossEnd-margin" class="marker cross flowchart-v2" viewBox="0 0 15 15" refX="17.7" refY="7.5" markerUnits="userSpaceOnUse" markerWidth="12" markerHeight="12" orient="auto"><path d="M 1,1 L 14,14 M 1,14 L 14,1" class="arrowMarkerPath" fill="{color}" stroke="{color}" style="stroke-width: 2.5;"></path></marker>"##
)
}
pub fn marker_cross_start_margin(id: &str, color: &str) -> String {
format!(
r##"<marker id="{id}_flowchart-v2-crossStart-margin" class="marker cross flowchart-v2" viewBox="0 0 15 15" refX="-3.5" refY="7.5" markerUnits="userSpaceOnUse" markerWidth="12" markerHeight="12" orient="auto"><path d="M 1,1 L 14,14 M 1,14 L 14,1" class="arrowMarkerPath" fill="{color}" stroke="{color}" style="stroke-width: 2.5; stroke-dasharray: 1, 0;"></path></marker>"##
)
}
pub fn marker_end_point(svg_id: &str) -> String {
format!(r##" marker-end="url(#{svg_id}_flowchart-v2-pointEnd)""##)
}
pub fn marker_end_cross(svg_id: &str) -> String {
format!(r##" marker-end="url(#{svg_id}_flowchart-v2-crossEnd)""##)
}
pub fn marker_end_circle(svg_id: &str) -> String {
format!(r##" marker-end="url(#{svg_id}_flowchart-v2-circleEnd)""##)
}
pub fn marker_start_point(svg_id: &str) -> String {
format!(r##" marker-start="url(#{svg_id}_flowchart-v2-pointStart)""##)
}
pub fn marker_start_cross(svg_id: &str) -> String {
format!(r##" marker-start="url(#{svg_id}_flowchart-v2-crossStart)""##)
}
pub fn marker_start_circle(svg_id: &str) -> String {
format!(r##" marker-start="url(#{svg_id}_flowchart-v2-circleStart)""##)
}
#[allow(clippy::too_many_arguments)]
pub fn edge_path_with_start(
path_d: &str,
edge_id: &str,
classes: &str,
stroke: &str,
stroke_width: &str,
stroke_dasharray: &str,
marker_start: &str,
marker_end: &str,
) -> String {
format!(
r##"<path d="{path_d}" id="{edge_id}" class="{classes}" fill="none" stroke="{stroke}" style="stroke-width:{stroke_width};stroke-dasharray:{stroke_dasharray};" data-edge="true" data-et="edge" data-id="{edge_id}" data-look="classic"{marker_start}{marker_end}></path>"##,
)
}
#[allow(dead_code)]
pub fn edge_path(
path_d: &str,
edge_id: &str,
classes: &str,
stroke: &str,
stroke_width: &str,
stroke_dasharray: &str,
marker_end: &str,
) -> String {
format!(
r##"<path d="{path_d}" id="{edge_id}" class="{classes}" fill="none" stroke="{stroke}" style="stroke-width:{stroke_width};stroke-dasharray:{stroke_dasharray};" data-edge="true" data-et="edge" data-id="{edge_id}" data-look="classic"{marker_end}></path>"##,
)
}
#[allow(clippy::too_many_arguments)]
pub fn edge_label_text(
mx: &str,
my: &str,
ox: &str,
fo_width: &str,
fo_height: f64,
_label_y_offset: i32,
_text_label_y: i32,
font_family: &str,
font_size: f64,
text: &str,
fill: &str,
bg: &str,
) -> String {
format!(
r##"<g class="edgeLabel" transform="translate({mx}, {my})"><g class="label" transform="translate(0, -10.5)"><rect x="{ox}" y="0" width="{fo_width}" height="{fo_height}" fill="{bg}" stroke="none"></rect><text y="-10.1" text-anchor="middle" font-family="{font_family}" font-size="{font_size}" fill="{fill}"><tspan x="0" y="-0.1em" dy="1.1em"><tspan>{text}</tspan></tspan></text></g></g>"##,
)
}
pub fn edge_label_empty() -> &'static str {
r##"<g class="edgeLabel"></g>"##
}
#[allow(clippy::too_many_arguments)]
pub fn cluster_group(
svg_id: &str,
sg_id: &str,
x: &str,
y: &str,
w: &str,
h: &str,
rect_fill: &str,
rect_stroke: &str,
label_html: &str,
) -> String {
format!(
r##"<g class="cluster " id="{svg_id}-{sg_id}" data-look="classic"><rect style="fill:{rect_fill};stroke:{rect_stroke};stroke-width:1px;" x="{x}" y="{y}" width="{w}" height="{h}"></rect>{label_html}</g>"##,
)
}
pub fn cluster_label_text(
cx: &str,
text_y: &str,
font_family: &str,
font_size: f64,
label_text: &str,
fill: &str,
) -> String {
format!(
r##"<text x="{cx}" y="{text_y}" text-anchor="middle" font-family="{font_family}" font-size="{font_size}" fill="{fill}">{label_text}</text>"##,
)
}
pub fn subgraph_root_group(ox: &str, oy: &str) -> String {
format!(r##"<g class="root" transform="translate({ox}, {oy})">"##)
}
pub fn node_group(dom_id: &str, cx: &str, cy: &str) -> String {
format!(
r##"<g class="node default " id="{dom_id}" data-look="classic" transform="translate({cx}, {cy})">"##,
)
}
pub fn node_rect(x: &str, w: &str, h: &str, y: &str, style: &str) -> String {
format!(
r##"<rect class="basic label-container" style="{style}" x="{x}" y="{y}" width="{w}" height="{h}"></rect>"##,
)
}
pub fn node_rounded_rect(x: &str, w: &str, h: &str, y: &str, style: &str) -> String {
format!(
r##"<rect class="basic label-container" style="{style}" rx="5" ry="5" x="{x}" y="{y}" width="{w}" height="{h}"></rect>"##,
)
}
pub fn node_stadium_rect(rx: &str, x: &str, y: &str, w: &str, h: &str, style: &str) -> String {
format!(
r##"<rect class="basic label-container" style="{style}" rx="{rx}" ry="{rx}" x="{x}" y="{y}" width="{w}" height="{h}"></rect>"##,
)
}
pub fn node_diamond(
hw: &str,
dim_w: &str,
neg_hh: &str,
neg_h: &str,
tx: &str,
ty: &str,
style: &str,
) -> String {
format!(
r##"<polygon points="{hw},0 {dim_w},{neg_hh} {hw},{neg_h} 0,{neg_hh}" class="label-container" style="{style}" transform="translate({tx},{ty})"></polygon>"##,
)
}
pub fn node_circle(r: &str, style: &str) -> String {
format!(r##"<circle class="label-container" style="{style}" cx="0" cy="0" r="{r}"></circle>"##,)
}
pub fn node_asymmetric(points: &str, style: &str) -> String {
format!(r##"<polygon points="{points}" class="label-container" style="{style}"></polygon>"##,)
}
pub fn node_hexagon(points: &str, style: &str) -> String {
format!(r##"<polygon points="{points}" class="label-container" style="{style}"></polygon>"##,)
}
pub fn node_polygon(points: &str, style: &str) -> String {
format!(r##"<polygon points="{points}" class="label-container" style="{style}"></polygon>"##,)
}
pub fn node_cylinder_body(path_d: &str, style: &str) -> String {
format!(r##"<path class="basic label-container" d="{path_d}" style="{style}"></path>"##,)
}
pub fn node_cylinder_top(path_d: &str, stroke: &str) -> String {
format!(r##"<path d="{path_d}" fill="none" stroke="{stroke}" style=""></path>"##,)
}
pub fn node_subroutine_rect(x: &str, y: &str, w: &str, h: &str, style: &str) -> String {
format!(
r##"<rect class="basic label-container" style="{style}" x="{x}" y="{y}" width="{w}" height="{h}"></rect>"##,
)
}
pub fn node_subroutine_line(x: &str, y1: &str, y2: &str, stroke: &str) -> String {
format!(
r##"<line x1="{x}" y1="{y1}" x2="{x}" y2="{y2}" style="stroke:{stroke};stroke-width:1px;"></line>"##,
)
}
#[allow(clippy::too_many_arguments)]
pub fn node_label_text_xy(
label_color_style: &str,
label_tx: i32,
text_label_y: i32,
font_family: &str,
font_size: f64,
text_fill: &str,
label_text: &str,
) -> String {
let lbl_g = crate::diagrams::util::label_tspan(
0.0,
text_label_y as f64,
label_text,
font_size,
"",
"middle",
&format!(" style=\"fill:{}\"", text_fill),
font_family,
);
format!(
r##"<g class="label" style="{label_color_style}" transform="translate({label_tx}, 0)">{lbl_g}</g>"##,
)
}