///|
pub fn normalize_run(g : Graph) -> Unit {
let dummy_chains : Array[String] = []
g.graph().set_strings("dummyChains", dummy_chains)
let edges = g.edges()
for edge in edges {
normalize_long_edge(g, edge, dummy_chains)
}
}
///|
fn normalize_long_edge(
g : Graph,
e : EdgeObj,
dummy_chains : Array[String],
) -> Unit {
let mut v = e.v
let mut v_rank = g.node(v).get_int_or("rank", 0)
let w = e.w
let w_rank = g.node(w).get_int_or("rank", 0)
let name = e.name
let edge_label = edge_label_attrs(g.edge_obj(e))
let label_rank = edge_label.get_int("labelRank")
if w_rank == v_rank + 1 {
return
}
g.remove_edge_obj(e)
let mut i = 0
v_rank = v_rank + 1
while v_rank < w_rank {
edge_label.set_points("points", [])
let attrs = empty_attrs()
attrs.set_float("width", 0.0)
attrs.set_float("height", 0.0)
attrs.set_value("edgeLabel", attrs_value(edge_label))
attrs.set_edge("edgeObj", e)
attrs.set_int("rank", v_rank)
let dummy = add_dummy_node(g, "edge", attrs, "_d")
if label_rank is Some(rank) {
if v_rank == rank {
attrs.set_float("width", edge_label.get_float_or("width", 0.0))
attrs.set_float("height", edge_label.get_float_or("height", 0.0))
attrs.set_string("dummy", "edge-label")
attrs.set_string("labelpos", edge_label.get_string_or("labelpos", "r"))
g.set_node(dummy, label=attrs)
}
}
let weighted = empty_attrs()
weighted.set_float("weight", edge_label.get_float_or("weight", 1.0))
g.set_edge(v, dummy, label=attrs_value(weighted), name?)
if i == 0 {
dummy_chains.push(dummy)
}
v = dummy
i = i + 1
v_rank = v_rank + 1
}
let weighted = empty_attrs()
weighted.set_float("weight", edge_label.get_float_or("weight", 1.0))
g.set_edge(v, w, label=attrs_value(weighted), name?)
}
///|
pub fn normalize_undo(g : Graph) -> Unit {
let chains = if g.graph().get_strings("dummyChains") is Some(chains) {
chains.copy()
} else {
[]
}
for start in chains {
let mut v = start
let mut node = g.node(v)
let orig_label = if node.get_value("edgeLabel") is Some(label) {
label
} else {
attrs_value(empty_attrs())
}
if node.get_edge("edgeObj") is Some(edge_obj) {
g.set_edge_obj(edge_obj, label=orig_label)
let orig_attrs = edge_label_attrs(Some(orig_label))
while node.get_string("dummy") is Some(dummy_type) {
let successors = g.successors(v)
if successors.is_empty() {
break
}
let w = successors[0]
let x = node.get_float_or("x", 0.0)
let y = node.get_float_or("y", 0.0)
let width = node.get_float_or("width", 0.0)
let height = node.get_float_or("height", 0.0)
g.remove_node(v)
let points = if orig_attrs.get_points("points") is Some(points) {
points
} else {
[]
}
points.push(point(x, y))
orig_attrs.set_points("points", points)
if dummy_type == "edge-label" {
orig_attrs.set_float("x", x)
orig_attrs.set_float("y", y)
orig_attrs.set_float("width", width)
orig_attrs.set_float("height", height)
}
v = w
node = g.node(v)
}
g.set_edge_obj(edge_obj, label=attrs_value(orig_attrs))
}
}
}
///|
fn edge_label_attrs(label : Value?) -> Attrs {
if value_as_attrs(label) is Some(attrs) {
attrs
} else if value_as_float(label) is Some(weight) {
let attrs = empty_attrs()
attrs.set_float("weight", weight)
attrs
} else if value_as_int(label) is Some(weight) {
let attrs = empty_attrs()
attrs.set_int("weight", weight)
attrs
} else {
empty_attrs()
}
}