diff --git a/stanzas/chord-diagram/drawChordDiagram.ts b/stanzas/chord-diagram/drawChordDiagram.ts index f15983b8..38c93f1d 100644 --- a/stanzas/chord-diagram/drawChordDiagram.ts +++ b/stanzas/chord-diagram/drawChordDiagram.ts @@ -59,21 +59,7 @@ export function drawChordDiagram(svg, nodes, edges, { symbols, ...params }) { }); // Nodes (arcs) - chords.groups.forEach((node) => { - // edgeSym, - // edgeWidthSym, - // sourceNodeSym, - // targetNodeSym, - // nodeSizeSym, - // nodeColorSym, - // groupSym, - // edgeColorSym, - // nodeLabelSym, - // idSym, - // nodeBorderColorSym, - // isPairEdge, - node.id = nodes[node.index][params.nodeLabelParams.dataKey]; node[symbols.nodeColorSym] = edgeColorScale("" + node.index); @@ -102,8 +88,6 @@ export function drawChordDiagram(svg, nodes, edges, { symbols, ...params }) { .classed("chord", true) .style("fill", (d) => chords.groups[d.source.index][symbols.nodeColorSym]); - console.log("ribbons", ribbons); - const arcsG = rootGroup .append("g") .classed("arcs", true) diff --git a/stanzas/force-graph/drawForceLayout.js b/stanzas/force-graph/drawForceLayout.js index a6940e27..7af5c3a8 100644 --- a/stanzas/force-graph/drawForceLayout.js +++ b/stanzas/force-graph/drawForceLayout.js @@ -1,4 +1,5 @@ import * as d3 from "d3"; +import { addHighlightOnHover } from "../../lib/graphHighlight"; function straightLink(d) { const start = { x: d.source.x, y: d.source.y }; @@ -181,7 +182,7 @@ export default function ( .data(nodes) .enter() .append("g") - .attr("class", "node-group") + .attr("class", "node") .attr("transform", (d) => { return `translate(${d.x},${d.y})`; }) @@ -189,7 +190,7 @@ export default function ( const nodeCircles = nodeGroups .append("circle") - .attr("class", "node") + .attr("cx", 0) .attr("cy", 0) .attr("r", (d) => d[symbols.nodeSizeSym]) @@ -210,14 +211,12 @@ export default function ( .text((d) => d[nodeLabelParams.dataKey]); } - let isDragging = false; - function drag(simulation) { function dragstarted(event) { if (!event.active) { simulation.alphaTarget(0.3).restart(); } - isDragging = true; + event.subject.fx = event.subject.x; event.subject.fy = event.subject.y; } @@ -228,7 +227,6 @@ export default function ( } function dragended(event) { - isDragging = false; if (!event.active) { simulation.alphaTarget(0); } @@ -244,44 +242,6 @@ export default function ( } if (highlightAdjEdges) { - nodeGroups.on("mouseover", function (e, d) { - if (isDragging) { - return; - } - // highlight current node - d3.select(this).classed("active", true); - // fade out all other nodes, highlight a little connected ones - nodeGroups - .classed("fadeout", (p) => d !== p) - .classed("half-active", (p) => { - return ( - p !== d && - d[symbols.edgeSym].some( - (edge) => - edge[symbols.sourceNodeSym] === p || - edge[symbols.targetNodeSym] === p - ) - ); - }); - - // fadeout not connected edges, highlight connected ones - links - .classed("fadeout", (p) => !d[symbols.edgeSym].includes(p)) - .classed("active", (p) => d[symbols.edgeSym].includes(p)); - }); - - nodeGroups.on("mouseleave", function () { - if (isDragging) { - return; - } - links - .classed("active", false) - .classed("fadeout", false) - .classed("half-active", false); - nodeGroups - .classed("active", false) - .classed("fadeout", false) - .classed("half-active", false); - }); + addHighlightOnHover(symbols, nodes, nodeGroups, links); } } diff --git a/stanzas/force-graph/index.js b/stanzas/force-graph/index.js index b8ba92b3..31bbfe25 100644 --- a/stanzas/force-graph/index.js +++ b/stanzas/force-graph/index.js @@ -5,6 +5,8 @@ import MetaStanza from "../../lib/MetaStanza"; import { handleApiError } from "../../lib/apiError"; import drawForceLayout from "./drawForceLayout"; +import { getMarginsFromCSSString } from "@/lib/utils"; + import { appendCustomCss, downloadCSVMenuItem, @@ -22,7 +24,7 @@ import { export default class ForceGraph extends MetaStanza { _graphArea; selectedEventParams = { - targetElementSelector: ".node-group", + targetElementSelector: ".node", selectedElementClassName: "-selected", selectedElementSelector: ".-selected", idPath: "id", @@ -175,25 +177,27 @@ export default class ForceGraph extends MetaStanza { symbols, }); - this._graphArea.selectAll("circle.node").on("click", (_, d) => { - toggleSelectIds({ - selectedIds: this.selectedIds, - targetId: d.id, - }); - updateSelectedElementClassNameForD3({ - drawing: this._graphArea, - selectedIds: this.selectedIds, - ...this.selectedEventParams, - }); - if (this.params["event-outgoing_change_selected_nodes"]) { - emitSelectedEvent({ - rootElement: this.element, + if (this.params["event-outgoing_change_selected_nodes"]) { + this._graphArea.selectAll(".node").on("click", (_, d) => { + toggleSelectIds({ + selectedIds: this.selectedIds, targetId: d.id, + }); + updateSelectedElementClassNameForD3({ + drawing: this._graphArea, selectedIds: this.selectedIds, - dataUrl: this.params["data-url"], + ...this.selectedEventParams, }); - } - }); + if (this.params["event-outgoing_change_selected_nodes"]) { + emitSelectedEvent({ + rootElement: this.element, + targetId: d.id, + selectedIds: this.selectedIds, + dataUrl: this.params["data-url"], + }); + } + }); + } }; handleApiError({ @@ -219,39 +223,3 @@ export default class ForceGraph extends MetaStanza { } } } - -function getMarginsFromCSSString(str) { - const splitted = str.trim().split(/\W+/); - - const res = { - TOP: 0, - RIGHT: 0, - BOTTOM: 0, - LEFT: 0, - }; - - switch (splitted.length) { - case 1: - res.TOP = res.RIGHT = res.BOTTOM = res.LEFT = parseInt(splitted[0]); - break; - case 2: - res.TOP = res.BOTTOM = parseInt(splitted[0]); - res.LEFT = res.RIGHT = parseInt(splitted[1]); - break; - case 3: - res.TOP = parseInt(splitted[0]); - res.LEFT = res.RIGHT = parseInt(splitted[1]); - res.BOTTOM = parseInt(splitted[2]); - break; - case 4: - res.TOP = parseInt(splitted[0]); - res.RIGHT = parseInt(splitted[1]); - res.BOTTOM = parseInt(splitted[2]); - res.LEFT = parseInt(splitted[3]); - break; - default: - break; - } - - return res; -} diff --git a/stanzas/force-graph/metadata.json b/stanzas/force-graph/metadata.json index eaa4bba2..024f4ae3 100644 --- a/stanzas/force-graph/metadata.json +++ b/stanzas/force-graph/metadata.json @@ -185,7 +185,7 @@ "stanza:description": "Color applied to the selected item" }, { - "stanza:key": "--togostanza-edge-default_color", + "stanza:key": "--togostanza-edge-color", "stanza:type": "color", "stanza:default": "#bdbdbd", "stanza:description": "Egdes default color" diff --git a/stanzas/force-graph/style.scss b/stanzas/force-graph/style.scss index 2c940910..1fcc16dd 100644 --- a/stanzas/force-graph/style.scss +++ b/stanzas/force-graph/style.scss @@ -1,16 +1,12 @@ // Load the repository-wide global style here. The actual file is located at ../common.scss for details. @use "@/common.scss"; -svg > defs > marker > path { - fill: var(--togostanza-edge-default_color); -} - .label, .node, .link, -.active, -.fadeout, -.half-active { +.-active, +.-fadeout, +.-half-active { transition: all 0.1s ease-in-out; transition-property: opacity, stroke-width, stroke-opacity; } @@ -24,51 +20,49 @@ svg > defs > marker > path { stroke: var(--togostanza-border-color); stroke-width: var(--togostanza-border-width); cursor: pointer; -} -.node-group { &.-selected { - text { - fill: var(--togostanza-theme-selected_border_color); - } + opacity: 1 !important; } -} -.link { - stroke-opacity: var(--togostanza-edge-opacity); - stroke-linecap: round; - fill: none; - stroke: var(--togostanza-edge-default_color); -} - -.active { - > .node { + &.-active { + opacity: 1; stroke-width: calc(var(--togostanza-border-width) * 2.5px); stroke-opacity: 1; } - > .link { - stroke-opacity: 1; + + &.-half-active { + opacity: calc(var(--togostanza-fadeout-opacity) + 0.3); + stroke-width: calc(var(--togostanza-border-width) * 1.6px); } - > .label { - opacity: 1; + + &.-fadeout { + opacity: var(--togostanza-fadeout-opacity); } } -.fadeout { - opacity: 0.05; - > .link { - stroke-opacity: 0.05; +.link { + stroke: var(--togostanza-edge-color); + opacity: var(--togostanza-edge-opacity); + + &.-fadeout { + opacity: calc( + var(--togostanza-fadeout-opacity) * var(--togostanza-edge-opacity) + ); } } -.half-active { - opacity: 0.8; - > .node { - stroke-width: calc(var(--togostanza-border-width) * 1.6px); - stroke-opacity: 0.8; +svg { + & > defs > marker > path { + fill: var(--togostanza-edge-color); } - > .label { - opacity: 0.6; + &:has(.-selected) { + .node { + opacity: var(--togostanza-fadeout-opacity); + } + .link { + opacity: var(--togostanza-fadeout-opacity); + } } }