From d0cfc72f62e88a1b7fde3c119ff888ed0310e926 Mon Sep 17 00:00:00 2001 From: ambam0123 <35744721+ambam0123@users.noreply.github.com> Date: Wed, 1 Jul 2026 21:40:45 +0200 Subject: [PATCH 1/8] Add files via upload --- core/models/config.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/core/models/config.js b/core/models/config.js index f513387..9c169c1 100644 --- a/core/models/config.js +++ b/core/models/config.js @@ -57,6 +57,7 @@ import Joi from 'joi'; * @property {boolean} graph_highlight_on_hover * @property {number} graph_text_size * @property {boolean} graph_arrows + * @property {boolean} graph_arrows_reversed * @property {'unique'|'degree'} node_size_method * @property {number} node_size * @property {number} [node_size_max] @@ -183,6 +184,7 @@ const optionsSchema = Joi.object({ graph_highlight_on_hover: Joi.boolean(), graph_text_size: Joi.number(), graph_arrows: Joi.boolean(), + graph_arrows_reversed: Joi.boolean(), node_size_method: Joi.string().valid('unique', 'degree'), node_size: Joi.number().integer().min(0), node_size_max: Joi.number().integer().min(0).optional(), @@ -254,6 +256,7 @@ class Config { graph_highlight_on_hover: true, graph_text_size: 10, graph_arrows: true, + graph_arrows_reversed: false, node_size_method: 'degree', node_size: 10, node_size_max: 20, From 304e1e578b17ae8bc7d5a1c2583e53f71929ba4e Mon Sep 17 00:00:00 2001 From: ambam0123 <35744721+ambam0123@users.noreply.github.com> Date: Wed, 1 Jul 2026 21:41:46 +0200 Subject: [PATCH 2/8] Add files via upload --- core/frontend/graph.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/core/frontend/graph.js b/core/frontend/graph.js index 370fb55..4abbe96 100644 --- a/core/frontend/graph.js +++ b/core/frontend/graph.js @@ -128,9 +128,14 @@ elts.links = svgSub }); if (graphProperties.graph_arrows === true) { - elts.links.attr('marker-end', 'url(#arrow)'); + if (graphProperties.graph_arrows_reversed === true) { + elts.links.attr('marker-start', 'url(#arrow-reversed)'); + } else { + elts.links.attr('marker-end', 'url(#arrow)'); + } } + const strokeWidth = 2; /** @type {d3.Selection} */ From 1291faad560c06b03450318b98342fd66dc6bba9 Mon Sep 17 00:00:00 2001 From: ambam0123 <35744721+ambam0123@users.noreply.github.com> Date: Wed, 1 Jul 2026 21:42:50 +0200 Subject: [PATCH 3/8] Add files via upload --- static/template/cosmoscope.njk | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/static/template/cosmoscope.njk b/static/template/cosmoscope.njk index e0e414f..1cf9772 100644 --- a/static/template/cosmoscope.njk +++ b/static/template/cosmoscope.njk @@ -269,8 +269,11 @@ - - + + + + + @@ -612,4 +615,4 @@ - \ No newline at end of file + From 964be98899982834a48e1b1b6a4b908157f6a27e Mon Sep 17 00:00:00 2001 From: ambam0123 <35744721+ambam0123@users.noreply.github.com> Date: Wed, 1 Jul 2026 21:44:20 +0200 Subject: [PATCH 4/8] Add files via upload feat: add graph_arrows_reversed config option --- core/i18n.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/core/i18n.yml b/core/i18n.yml index 762c93c..f78256f 100644 --- a/core/i18n.yml +++ b/core/i18n.yml @@ -397,6 +397,9 @@ config: graph_arrows: fr: La commande de fléchage des liens est invalide en: Invalid link arrow command + graph_arrows_reversed: + fr: La commande d'inversion des flèches est invalide + en: Invalid reverse arrow command devtools: fr: La commande d'activation des outils de développement est invalide en: Invalid devtools activation command From 2aa6ab48803db4b164c59ab3d2f79c7b3b564b5f Mon Sep 17 00:00:00 2001 From: ambam0123 <35744721+ambam0123@users.noreply.github.com> Date: Thu, 2 Jul 2026 09:53:30 +0200 Subject: [PATCH 5/8] Add files via upload --- core/frontend/styles.css | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/frontend/styles.css b/core/frontend/styles.css index 70d5e07..f0e3f31 100644 --- a/core/frontend/styles.css +++ b/core/frontend/styles.css @@ -714,8 +714,8 @@ text { /* arrows */ marker { /* set into config.yml file by 'undefined' link type */ - stroke: var(--l_undefined); - fill: var(--l_undefined); + stroke: context-stroke; + fill: context-stroke; } /* --- From cdb4d3643166aae4f2cb594f693a37e6e5c3d4fd Mon Sep 17 00:00:00 2001 From: ambam0123 <35744721+ambam0123@users.noreply.github.com> Date: Thu, 2 Jul 2026 09:54:15 +0200 Subject: [PATCH 6/8] Add files via upload --- static/template/cosmoscope.njk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/static/template/cosmoscope.njk b/static/template/cosmoscope.njk index 1cf9772..f2be964 100644 --- a/static/template/cosmoscope.njk +++ b/static/template/cosmoscope.njk @@ -269,10 +269,10 @@ - + - + From d27e6ac2b6436d6e7615b120380c30499586e32d Mon Sep 17 00:00:00 2001 From: ambam0123 <35744721+ambam0123@users.noreply.github.com> Date: Thu, 2 Jul 2026 21:15:40 +0200 Subject: [PATCH 7/8] Add files via upload when a--> b and b-->a, then both arrows are slightly curved such that they both are visible --- core/frontend/graph.js | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/core/frontend/graph.js b/core/frontend/graph.js index 4abbe96..01f63d4 100644 --- a/core/frontend/graph.js +++ b/core/frontend/graph.js @@ -85,12 +85,25 @@ hotkeys('space', (e) => { const elts = {}; const imageFileValidExtnames = new Set(['jpg', 'jpeg', 'png']); +// Precompute bidirectional edges +const edgeSet = new Set(data.edges.map((e) => `${e.source.key}--${e.target.key}`)); +const bidirectionalEdges = new Set( + data.edges + .filter((e) => edgeSet.has(`${e.target.key}--${e.source.key}`)) + .map((e) => e.key) +); + simulation.on('tick', () => { elts.links - .attr('x1', (d) => d.source.x) - .attr('y1', (d) => d.source.y) - .attr('x2', (d) => d.target.x) - .attr('y2', (d) => d.target.y); + .attr('d', (d) => { + const dx = d.target.x - d.source.x; + const dy = d.target.y - d.source.y; + const dr = Math.sqrt(dx * dx + dy * dy); + if (bidirectionalEdges.has(d.key)) { + return `M ${d.source.x},${d.source.y} A ${dr},${dr} 0 0,1 ${d.target.x},${d.target.y}`; + } + return `M ${d.source.x},${d.source.y} L ${d.target.x},${d.target.y}`; + }); elts.nodes.attr('transform', (d) => 'translate(' + d.x + ',' + d.y + ')'); @@ -105,10 +118,11 @@ simulation.on('tick', () => { /** @type {d3.Selection} */ elts.links = svgSub .append('g') - .selectAll('line') + .selectAll('path') .data(data.edges) .enter() - .append('line') + .append('path') + .attr('fill', 'none') .attr('stroke', (d) => `var(--l_${d.attributes.type})`) .attr('title', (d) => d.attributes.title) .attr('data-link', (d) => d.key) From db618d1f970783eef0b1d7dc3e50bdd090823f3b Mon Sep 17 00:00:00 2001 From: ambam0123 <35744721+ambam0123@users.noreply.github.com> Date: Thu, 2 Jul 2026 22:07:26 +0200 Subject: [PATCH 8/8] Add files via upload changed highlight, just for me. now it only higlights the selected node and nothing else. dont know if you guys want this change --- core/frontend/graph.js | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/core/frontend/graph.js b/core/frontend/graph.js index 01f63d4..4ae0733 100644 --- a/core/frontend/graph.js +++ b/core/frontend/graph.js @@ -503,9 +503,8 @@ function highlightNodes(nodeIds) { nodeIds .filter((nodeId) => graph.hasNode(nodeId)) .forEach((nodeId) => { - const { links, node } = getNodeNetwork(nodeId); + const { node } = getNodeNetwork(nodeId); node.node().classList.add('highlight'); - links.nodes().forEach((elt) => elt.classList.add('highlight')); }); highlightedNodes = highlightedNodes.concat(nodeIds); @@ -520,14 +519,7 @@ function unlightNodes() { return; } - highlightedNodes - .filter((nodeId) => graph.hasNode(nodeId)) - .forEach((nodeId) => { - const { links, node } = getNodeNetwork(nodeId); - node.node().classList.remove('highlight'); - links.nodes().forEach((elt) => elt.classList.remove('highlight')); - }); - + elts.nodes.nodes().forEach((elt) => elt.classList.remove('highlight')); highlightedNodes = []; }