gioser-graph: edge colors blend from connected node caminos
- Each edge color is a 50/50 blend of its two nodes' camino colors - Extra brightness proportional to weight (higher weight = closer to white) - Edge opacity/width also varies by weight - Edges drawn before nodes in SVG (already behind them)
This commit is contained in:
+2
-2
@@ -9,11 +9,11 @@ export interface InitOutput {
|
|||||||
readonly memory: WebAssembly.Memory;
|
readonly memory: WebAssembly.Memory;
|
||||||
readonly boot: () => void;
|
readonly boot: () => void;
|
||||||
readonly __wasm_bindgen_func_elem_216: (a: number, b: number, c: number) => void;
|
readonly __wasm_bindgen_func_elem_216: (a: number, b: number, c: number) => void;
|
||||||
readonly __wasm_bindgen_func_elem_1404: (a: number, b: number, c: number, d: number) => void;
|
readonly __wasm_bindgen_func_elem_1408: (a: number, b: number, c: number, d: number) => void;
|
||||||
readonly __wasm_bindgen_func_elem_215: (a: number, b: number, c: number) => void;
|
readonly __wasm_bindgen_func_elem_215: (a: number, b: number, c: number) => void;
|
||||||
readonly __wasm_bindgen_func_elem_215_3: (a: number, b: number, c: number) => void;
|
readonly __wasm_bindgen_func_elem_215_3: (a: number, b: number, c: number) => void;
|
||||||
readonly __wasm_bindgen_func_elem_492: (a: number, b: number, c: number) => void;
|
readonly __wasm_bindgen_func_elem_492: (a: number, b: number, c: number) => void;
|
||||||
readonly __wasm_bindgen_func_elem_598: (a: number, b: number, c: number) => void;
|
readonly __wasm_bindgen_func_elem_602: (a: number, b: number, c: number) => void;
|
||||||
readonly __wasm_bindgen_func_elem_285: (a: number, b: number, c: number) => void;
|
readonly __wasm_bindgen_func_elem_285: (a: number, b: number, c: number) => void;
|
||||||
readonly __wasm_bindgen_func_elem_284: (a: number, b: number) => void;
|
readonly __wasm_bindgen_func_elem_284: (a: number, b: number) => void;
|
||||||
readonly __wbindgen_export: (a: number, b: number) => number;
|
readonly __wbindgen_export: (a: number, b: number) => number;
|
||||||
|
|||||||
@@ -570,8 +570,8 @@ function __wbg_get_imports() {
|
|||||||
return ret;
|
return ret;
|
||||||
},
|
},
|
||||||
__wbindgen_cast_0000000000000001: function(arg0, arg1) {
|
__wbindgen_cast_0000000000000001: function(arg0, arg1) {
|
||||||
// Cast intrinsic for `Closure(Closure { owned: true, function: Function { arguments: [Externref], shim_idx: 179, ret: Result(Unit), inner_ret: Some(Result(Unit)) }, mutable: true }) -> Externref`.
|
// Cast intrinsic for `Closure(Closure { owned: true, function: Function { arguments: [Externref], shim_idx: 180, ret: Result(Unit), inner_ret: Some(Result(Unit)) }, mutable: true }) -> Externref`.
|
||||||
const ret = makeMutClosure(arg0, arg1, __wasm_bindgen_func_elem_1404);
|
const ret = makeMutClosure(arg0, arg1, __wasm_bindgen_func_elem_1408);
|
||||||
return addHeapObject(ret);
|
return addHeapObject(ret);
|
||||||
},
|
},
|
||||||
__wbindgen_cast_0000000000000002: function(arg0, arg1) {
|
__wbindgen_cast_0000000000000002: function(arg0, arg1) {
|
||||||
@@ -595,8 +595,8 @@ function __wbg_get_imports() {
|
|||||||
return addHeapObject(ret);
|
return addHeapObject(ret);
|
||||||
},
|
},
|
||||||
__wbindgen_cast_0000000000000006: function(arg0, arg1) {
|
__wbindgen_cast_0000000000000006: function(arg0, arg1) {
|
||||||
// Cast intrinsic for `Closure(Closure { owned: true, function: Function { arguments: [NamedExternref("MouseEvent")], shim_idx: 173, ret: Unit, inner_ret: Some(Unit) }, mutable: true }) -> Externref`.
|
// Cast intrinsic for `Closure(Closure { owned: true, function: Function { arguments: [NamedExternref("MouseEvent")], shim_idx: 174, ret: Unit, inner_ret: Some(Unit) }, mutable: true }) -> Externref`.
|
||||||
const ret = makeMutClosure(arg0, arg1, __wasm_bindgen_func_elem_598);
|
const ret = makeMutClosure(arg0, arg1, __wasm_bindgen_func_elem_602);
|
||||||
return addHeapObject(ret);
|
return addHeapObject(ret);
|
||||||
},
|
},
|
||||||
__wbindgen_cast_0000000000000007: function(arg0, arg1) {
|
__wbindgen_cast_0000000000000007: function(arg0, arg1) {
|
||||||
@@ -649,18 +649,18 @@ function __wasm_bindgen_func_elem_492(arg0, arg1, arg2) {
|
|||||||
wasm.__wasm_bindgen_func_elem_492(arg0, arg1, addHeapObject(arg2));
|
wasm.__wasm_bindgen_func_elem_492(arg0, arg1, addHeapObject(arg2));
|
||||||
}
|
}
|
||||||
|
|
||||||
function __wasm_bindgen_func_elem_598(arg0, arg1, arg2) {
|
function __wasm_bindgen_func_elem_602(arg0, arg1, arg2) {
|
||||||
wasm.__wasm_bindgen_func_elem_598(arg0, arg1, addHeapObject(arg2));
|
wasm.__wasm_bindgen_func_elem_602(arg0, arg1, addHeapObject(arg2));
|
||||||
}
|
}
|
||||||
|
|
||||||
function __wasm_bindgen_func_elem_285(arg0, arg1, arg2) {
|
function __wasm_bindgen_func_elem_285(arg0, arg1, arg2) {
|
||||||
wasm.__wasm_bindgen_func_elem_285(arg0, arg1, addHeapObject(arg2));
|
wasm.__wasm_bindgen_func_elem_285(arg0, arg1, addHeapObject(arg2));
|
||||||
}
|
}
|
||||||
|
|
||||||
function __wasm_bindgen_func_elem_1404(arg0, arg1, arg2) {
|
function __wasm_bindgen_func_elem_1408(arg0, arg1, arg2) {
|
||||||
try {
|
try {
|
||||||
const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
|
const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
|
||||||
wasm.__wasm_bindgen_func_elem_1404(retptr, arg0, arg1, addHeapObject(arg2));
|
wasm.__wasm_bindgen_func_elem_1408(retptr, arg0, arg1, addHeapObject(arg2));
|
||||||
var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
|
var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
|
||||||
var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
|
var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
|
||||||
if (r1) {
|
if (r1) {
|
||||||
|
|||||||
Binary file not shown.
+2
-2
@@ -3,11 +3,11 @@
|
|||||||
export const memory: WebAssembly.Memory;
|
export const memory: WebAssembly.Memory;
|
||||||
export const boot: () => void;
|
export const boot: () => void;
|
||||||
export const __wasm_bindgen_func_elem_216: (a: number, b: number, c: number) => void;
|
export const __wasm_bindgen_func_elem_216: (a: number, b: number, c: number) => void;
|
||||||
export const __wasm_bindgen_func_elem_1404: (a: number, b: number, c: number, d: number) => void;
|
export const __wasm_bindgen_func_elem_1408: (a: number, b: number, c: number, d: number) => void;
|
||||||
export const __wasm_bindgen_func_elem_215: (a: number, b: number, c: number) => void;
|
export const __wasm_bindgen_func_elem_215: (a: number, b: number, c: number) => void;
|
||||||
export const __wasm_bindgen_func_elem_215_3: (a: number, b: number, c: number) => void;
|
export const __wasm_bindgen_func_elem_215_3: (a: number, b: number, c: number) => void;
|
||||||
export const __wasm_bindgen_func_elem_492: (a: number, b: number, c: number) => void;
|
export const __wasm_bindgen_func_elem_492: (a: number, b: number, c: number) => void;
|
||||||
export const __wasm_bindgen_func_elem_598: (a: number, b: number, c: number) => void;
|
export const __wasm_bindgen_func_elem_602: (a: number, b: number, c: number) => void;
|
||||||
export const __wasm_bindgen_func_elem_285: (a: number, b: number, c: number) => void;
|
export const __wasm_bindgen_func_elem_285: (a: number, b: number, c: number) => void;
|
||||||
export const __wasm_bindgen_func_elem_284: (a: number, b: number) => void;
|
export const __wasm_bindgen_func_elem_284: (a: number, b: number) => void;
|
||||||
export const __wbindgen_export: (a: number, b: number) => number;
|
export const __wbindgen_export: (a: number, b: number) => number;
|
||||||
|
|||||||
@@ -92,6 +92,27 @@ fn camino_color(camino: &str) -> &str {
|
|||||||
"#888888"
|
"#888888"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn parse_hex(hex: &str) -> (u8, u8, u8) {
|
||||||
|
let h = hex.trim_start_matches('#');
|
||||||
|
if h.len() == 6 {
|
||||||
|
let r = u8::from_str_radix(&h[0..2], 16).unwrap_or(128);
|
||||||
|
let g = u8::from_str_radix(&h[2..4], 16).unwrap_or(128);
|
||||||
|
let b = u8::from_str_radix(&h[4..6], 16).unwrap_or(128);
|
||||||
|
(r, g, b)
|
||||||
|
} else {
|
||||||
|
(136, 136, 136)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn blend_colors(c1: &str, c2: &str, t: f64) -> String {
|
||||||
|
let (r1, g1, b1) = parse_hex(c1);
|
||||||
|
let (r2, g2, b2) = parse_hex(c2);
|
||||||
|
let r = (r1 as f64 * (1.0 - t) + r2 as f64 * t) as u32;
|
||||||
|
let g = (g1 as f64 * (1.0 - t) + g2 as f64 * t) as u32;
|
||||||
|
let b = (b1 as f64 * (1.0 - t) + b2 as f64 * t) as u32;
|
||||||
|
format!("#{:02x}{:02x}{:02x}", r, g, b)
|
||||||
|
}
|
||||||
|
|
||||||
pub struct GraphWidget {
|
pub struct GraphWidget {
|
||||||
container: HtmlElement,
|
container: HtmlElement,
|
||||||
api_url: String,
|
api_url: String,
|
||||||
@@ -194,18 +215,22 @@ impl GraphWidget {
|
|||||||
.unwrap();
|
.unwrap();
|
||||||
breathe_group.set_attribute("class", "gb-svg").ok();
|
breathe_group.set_attribute("class", "gb-svg").ok();
|
||||||
|
|
||||||
// Mapa: node.id → (x, y) — usamos UUID, no doc_id
|
// Mapas: UUID → posición y color
|
||||||
let pos_map: std::collections::HashMap<&str, (f64, f64)> = positions
|
let pos_map: std::collections::HashMap<&str, (f64, f64)> = positions
|
||||||
.iter()
|
.iter()
|
||||||
.map(|(id, p)| (id.as_str(), *p))
|
.map(|(id, p)| (id.as_str(), *p))
|
||||||
.collect();
|
.collect();
|
||||||
|
let color_map: std::collections::HashMap<&str, &str> = self.nodes
|
||||||
|
.iter()
|
||||||
|
.map(|n| (n.id.as_str(), camino_color(&n.camino)))
|
||||||
|
.collect();
|
||||||
|
|
||||||
let max_w = self.edges.iter()
|
let max_w = self.edges.iter()
|
||||||
.filter_map(|e| e.weight)
|
.filter_map(|e| e.weight)
|
||||||
.fold(0.0_f64, f64::max)
|
.fold(0.0_f64, f64::max)
|
||||||
.max(0.5);
|
.max(0.5);
|
||||||
|
|
||||||
// ── Aristas ──
|
// ── Aristas: mezcla de colores de los nodos que conecta ──
|
||||||
let mut drawn = std::collections::HashSet::new();
|
let mut drawn = std::collections::HashSet::new();
|
||||||
for edge in &self.edges {
|
for edge in &self.edges {
|
||||||
let key = if edge.source < edge.target {
|
let key = if edge.source < edge.target {
|
||||||
@@ -218,13 +243,23 @@ impl GraphWidget {
|
|||||||
let Some((x1, y1)) = pos_map.get(edge.source.as_str()) else { continue; };
|
let Some((x1, y1)) = pos_map.get(edge.source.as_str()) else { continue; };
|
||||||
let Some((x2, y2)) = pos_map.get(edge.target.as_str()) else { continue; };
|
let Some((x2, y2)) = pos_map.get(edge.target.as_str()) else { continue; };
|
||||||
|
|
||||||
|
let c1 = color_map.get(edge.source.as_str()).copied().unwrap_or("#888");
|
||||||
|
let c2 = color_map.get(edge.target.as_str()).copied().unwrap_or("#888");
|
||||||
|
|
||||||
let w = edge.weight.unwrap_or(0.7);
|
let w = edge.weight.unwrap_or(0.7);
|
||||||
let norm_w = (w / max_w).clamp(0.0, 1.0);
|
let norm_w = (w / max_w).clamp(0.0, 1.0);
|
||||||
let alpha = 0.15 + norm_w * 0.70;
|
|
||||||
let sw = 1.0 + norm_w * 4.0;
|
// Mezclar colores: 50/50 + brillo según weight
|
||||||
let r = (255.0 - (1.0 - norm_w) * 80.0) as u32;
|
let blended = blend_colors(c1, c2, 0.5);
|
||||||
let g = (255.0 - (1.0 - norm_w) * 60.0) as u32;
|
|
||||||
let b = (255.0 - (1.0 - norm_w) * 40.0) as u32;
|
// Brillo extra según el peso (acercar a blanco)
|
||||||
|
let (br, bg, bb) = parse_hex(&blended);
|
||||||
|
let r = (br as f64 + (255.0 - br as f64) * norm_w * 0.4) as u32;
|
||||||
|
let g = (bg as f64 + (255.0 - bg as f64) * norm_w * 0.4) as u32;
|
||||||
|
let b = (bb as f64 + (255.0 - bb as f64) * norm_w * 0.4) as u32;
|
||||||
|
|
||||||
|
let alpha = 0.20 + norm_w * 0.65;
|
||||||
|
let sw = 1.0 + norm_w * 4.5;
|
||||||
|
|
||||||
let line: SvgLineElement = self
|
let line: SvgLineElement = self
|
||||||
.document
|
.document
|
||||||
|
|||||||
Reference in New Issue
Block a user