From 63938129e6b5e4371877e12db4a9b78c25c77660 Mon Sep 17 00:00:00 2001 From: Alistair Jones Date: Wed, 23 Feb 2022 23:07:53 +0000 Subject: [PATCH 1/2] New rectangle-shaped force. Makes better use of screen area. Currently the aspect ratio is fixed, but should be chosen more intelligently. Also, the strength parameter will need some tuning. --- .../visualization/ForceSimulation.ts | 10 ++--- .../visualization/rectangleForce.ts | 45 +++++++++++++++++++ 2 files changed, 48 insertions(+), 7 deletions(-) create mode 100644 src/graphVisualization/visualization/rectangleForce.ts diff --git a/src/graphVisualization/visualization/ForceSimulation.ts b/src/graphVisualization/visualization/ForceSimulation.ts index f03c7b58b9a..ee8de822330 100644 --- a/src/graphVisualization/visualization/ForceSimulation.ts +++ b/src/graphVisualization/visualization/ForceSimulation.ts @@ -22,16 +22,12 @@ import { forceCollide, forceLink, forceManyBody, - forceSimulation, - forceX, - forceY + forceSimulation } from 'd3-force' import { DEFAULT_ALPHA, DEFAULT_ALPHA_MIN, - FORCE_CENTER_X, - FORCE_CENTER_Y, FORCE_CHARGE, FORCE_COLLIDE_RADIUS, FORCE_LINK_DISTANCE, @@ -44,6 +40,7 @@ import { GraphModel } from '../models/Graph' import { NodeModel } from '../models/Node' import { RelationshipModel } from '../models/Relationship' import circularLayout from '../utils/circularLayout' +import { rectangleForce } from './rectangleForce' const oneRelationshipPerPairOfNodes = (graph: GraphModel) => Array.from(graph.groupedRelationships()).map(pair => pair.relationships[0]) @@ -56,8 +53,7 @@ export class ForceSimulation { this.simulation = forceSimulation() .velocityDecay(VELOCITY_DECAY) .force('charge', forceManyBody().strength(FORCE_CHARGE)) - .force('centerX', forceX(0).strength(FORCE_CENTER_X)) - .force('centerY', forceY(0).strength(FORCE_CENTER_Y)) + .force('gravity', rectangleForce()) .on('tick', () => { this.simulation.tick(TICKS_PER_RENDER) render() diff --git a/src/graphVisualization/visualization/rectangleForce.ts b/src/graphVisualization/visualization/rectangleForce.ts new file mode 100644 index 00000000000..2a5d211868d --- /dev/null +++ b/src/graphVisualization/visualization/rectangleForce.ts @@ -0,0 +1,45 @@ +const aspectRatio = 3 +const gravityStrength = 0.1 + +const sq = (d: number) => d * d +const integral = (a: number, b: number) => + (b * Math.log(sq(a) + sq(b))) / 2 + a * Math.atan(b / a) + +export const rectangleForce = () => { + let nodes: any + + const force = (alpha: number) => { + const targetRatio = + aspectRatio < 0 ? 1 / (1 - aspectRatio) : aspectRatio + 1 + const strength = gravityStrength * alpha + + for (const node of nodes) { + const actualRatio = Math.abs(node.x / node.y) + const width = actualRatio > targetRatio ? node.x : node.y * targetRatio + const height = actualRatio < targetRatio ? node.y : node.x / targetRatio + const maxX = width - node.x + const minX = -width - node.x + const maxY = height - node.y + const minY = -height - node.y + + const vx = + integral(maxX, maxY) - + integral(maxX, minY) - + integral(minX, maxY) + + integral(minX, minY) + const vy = + integral(maxY, maxX) - + integral(minY, maxX) - + integral(maxY, minX) + + integral(minY, minX) + node.x += vx * strength + node.y += vy * strength + } + } + + force.initialize = (_: any) => { + nodes = _ + } + + return force +} From f7372f019326c55ef90f3352e01ac3689c4cbf03 Mon Sep 17 00:00:00 2001 From: Alistair Jones Date: Fri, 25 Feb 2022 13:49:09 +0000 Subject: [PATCH 2/2] Reduce gravity strength. --- src/graphVisualization/visualization/rectangleForce.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/graphVisualization/visualization/rectangleForce.ts b/src/graphVisualization/visualization/rectangleForce.ts index 2a5d211868d..00b8da57f8d 100644 --- a/src/graphVisualization/visualization/rectangleForce.ts +++ b/src/graphVisualization/visualization/rectangleForce.ts @@ -1,5 +1,5 @@ const aspectRatio = 3 -const gravityStrength = 0.1 +const gravityStrength = 0.05 const sq = (d: number) => d * d const integral = (a: number, b: number) =>