Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 9 additions & 5 deletions svelte/src/scripts/draw/drag-and-drop.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,18 +25,23 @@ export function addDragAndDrop(
d3
// eslint-disable-next-line @typescript-eslint/no-explicit-any
.drag<any, any>()
.on('drag', e => {
.on('drag', (e,d) => {
// Typing
const source = e.sourceEvent as MouseEvent;
const node = e.subject as GraphDataNode;

// Calculate node movement, keeping the transformation (specifically the scaling) in mind.
const xt = node.x! + source.movementX * (1 / (drawSettings.transformation?.k ?? 1));
const yt = node.y! + source.movementY * (1 / (drawSettings.transformation?.k ?? 1));
const deltaX = source.movementX * (1 / ((drawSettings.transformation?.k ?? 1) * (d.level + 1)));
const deltaY = source.movementY * (1 / ((drawSettings.transformation?.k ?? 1) * (d.level + 1)));
const xt = node.x! + deltaX;
const yt = node.y! + deltaY;

// For now, we are not going to resize or move the parent node
// Hence, the coordinates should be clamped to a range
if (node.parent) {
// Increase parent size and move it if it's starting to move outside the boundary
node.parent.x! = notNaN(node.parent.x! + deltaX);
node.parent.y! = notNaN(node.parent.y! + deltaY);
node.x = clamp(
xt,
-0.5 * node.parent.width! + 0.5 * node.width!,
Expand All @@ -51,9 +56,8 @@ export function addDragAndDrop(
node.x = notNaN(xt);
node.y = notNaN(yt);
}

// Rerender nodes
updateNodePosition(node, svgElement);
updateNodePosition(node, deltaX, deltaY);

renderLinks(links, nodesDictionary, linkCanvas, drawSettings);
}),
Expand Down
82 changes: 63 additions & 19 deletions svelte/src/scripts/draw/nodes-render.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import * as d3 from 'd3';
import {toHTMLToken} from '$helper';
import {clamp, notNaN, toHTMLToken} from '$helper';
import type {DrawSettingsInterface, GraphDataNode} from '$types';
import { NormalizeWeight } from './helper/normalize-weight';
import { renderInfoBox } from './helper/info-box';
import {NormalizeWeight} from './helper/normalize-weight';
import {renderInfoBox} from './helper/info-box';

/**
* Adds lift and collapse buttons to all groups with id .nodes (generated by renderNodes)
Expand Down Expand Up @@ -75,15 +75,49 @@ export function renderNodeLabels(svgElement: Element, drawSettings: DrawSettings
* @param svgElement
*/

export function updateNodePosition(node: GraphDataNode, svgElement: Element) {
(
d3.select(svgElement).selectAll(`#group-${toHTMLToken(node.id)}`) as d3.Selection<
d3.BaseType,
GraphDataNode,
Element,
unknown
>
).attr('transform', n => `translate(${n.x} ${n.y})`);
export function updateNodePosition(node: GraphDataNode, deltaX: number, deltaY: number) {
// Update the graphical node position
const nodeSvg = d3.select(`#group-${toHTMLToken(node.id)}`) as d3.Selection<
d3.BaseType,
GraphDataNode,
Element,
unknown
>;
nodeSvg.attr('transform', function (n) {
return `translate(${n.x} ${n.y})`;
});
const xt = node.x! + deltaX;
const yt = node.y! + deltaY;

// Update the parent data
if (node.parent) {
node.x = clamp(
xt,
-0.5 * node.parent.width! + 0.5 * node.width!,
+0.5 * node.parent.width! - 0.5 * node.width!,
);
node.y = clamp(
yt,
-0.5 * node.parent.height! + 0.5 * node.height!,
+0.5 * node.parent.height! - 0.5 * node.height!,
);
node.parent.x! = notNaN(node.parent.x! + deltaX);
node.parent.y! = notNaN(node.parent.y! + deltaY);
// const nodeRect = d3.select(`#rect-${toHTMLToken(node.parent.id)}`) as d3.Selection<
// d3.BaseType,
// GraphDataNode,
// Element,
// unknown
// >;
// const newX = Number(nodeRect.attr("x")) + deltaX
// const newY = Number(nodeRect.attr("y")) + deltaY
// // console.log(newX)
// nodeRect
// .attr("x", newX)
// .attr("y", newY)

updateNodePosition(node.parent, deltaX, deltaY);
}
}
/**
* Render given nodes onto given svgElement.
Expand Down Expand Up @@ -129,11 +163,17 @@ export function renderNodes(
.on('mouseover', function (event, data) {
d3.select(this).attr('fill-opacity', '0.2');
data.outgoingLinks.forEach(link => {
d3.select(`#line-${toHTMLToken(link.id)}`).style('stroke-width', NormalizeWeight(link.weight) + 4);
d3.select(`#line-${toHTMLToken(link.id)}`).style(
'stroke-width',
NormalizeWeight(link.weight) + 4,
);
});
data.incomingLinks.forEach(link => {
// hightlight
d3.select(`#line-${toHTMLToken(link.id)}`).style('stroke-width', NormalizeWeight(link.weight) + 4);
d3.select(`#line-${toHTMLToken(link.id)}`).style(
'stroke-width',
NormalizeWeight(link.weight) + 4,
);
});

// render info box
Expand All @@ -142,14 +182,18 @@ export function renderNodes(
.on('mouseout', function (event, data) {
d3.select(this).attr('fill-opacity', '0.1');
data.outgoingLinks.forEach(link => {
d3.select(`#line-${toHTMLToken(link.id)}`).style('stroke-width', NormalizeWeight(link.weight));
d3.select(`#line-${toHTMLToken(link.id)}`).style(
'stroke-width',
NormalizeWeight(link.weight),
);
});
data.incomingLinks.forEach(link => {
d3.select(`#line-${toHTMLToken(link.id)}`).style('stroke-width', NormalizeWeight(link.weight));
d3.select(`#line-${toHTMLToken(link.id)}`).style(
'stroke-width',
NormalizeWeight(link.weight),
);
});
})


});

nodes.forEach(node => {
const element = document.getElementById(`group-${toHTMLToken(node.id)}`)!;
Expand Down