Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
// Use Collision force -----------------------------------------------------------------
forceCollide.initialize(graph.nodes);
forceCollide(0.1); // alpha
// Link ================================================================================
// create Link force --------------------------------------------------------------
let forceLink: d3Force.ForceLink;
// without link data
forceLink = d3Force.forceLink();
// with link data
forceLink = d3Force.forceLink(graph.links);
// Configure Link force -----------------------------------------------------------
let linkNumberAccessor: (link: SimLink, i: number, links: SimLink[]) => number;
// let nodeIdAccessor: (node: SimNode, i: number, nodes: SimNode[]) => number | string;
// links
forceLink = forceLink.links(graph.links);
simLinks = forceLink.links();
simLink = simLinks[0];
simNode = (typeof simLink.source !== 'number' && typeof simLink.source !== 'string') ? simLink.source : undefined;
simNode = (typeof simLink.target !== 'number' && typeof simLink.target !== 'string') ? simLink.target : undefined;
static initSimulation(hosts, links) {
const linkForce = forceLink(links)
.id(l => l.id)
.strength(0.2);
const gravityXForce = forceX().strength(0.03);
const gravityYForce = forceY().strength(0.03);
const simulation = forceSimulation(hosts)
.stop()
.force('link', linkForce)
.force('charge', forceManyBody().strength(-20))
.force('gravityX', gravityXForce)
.force('gravityY', gravityYForce)
.alphaMin(0.1)
.alphaDecay(0.02276278); // alphaMin and alphaDecay result in ~100 ticks
return {simulation, linkForce};
if (sourceKey) {
this.sourceKey = sourceKey;
}
if (targetKey) {
this.targetKey = targetKey;
}
if (velocityDecay) {
this.simulation.velocityDecay(velocityDecay)
}
if (alphaMin) {
this.simulation.alphaMin(alphaMin);
}
if (alphaDecay) {
this.simulation.alphaDecay(alphaDecay);
}
const _forceLink = forceLink();
if (nodeIdKey) {
_forceLink.id(d => d[nodeIdKey]);
}
if (linkDistance) {
_forceLink.distance(linkDistance);
}
this.simulation.force('link', _forceLink);
// this.simulation.force('center', forceCenter());
if (collideRadius || collideStrength) {
const _forceCollide = forceCollide();
if (collideRadius) {
_forceCollide.radius(typeof collideRadius === 'function' ? (d) => {
return collideRadius(d);
} : collideRadius);
}
node.radius = node.r = Math.max(
(node.textHeight / 4) * yMod,
(node.textWidth / 4) * xMod
)
// node.textHeight = projectionScaleY(node.textHeight)
// node.textWidth = projectionScaleY(node.textWidth)
})
} else if (networkSettings.type === "force") {
const {
iterations = 500,
edgeStrength = 0.1,
distanceMax = Infinity,
edgeDistance
} = networkSettings
const linkForce = forceLink().strength(d =>
Math.min(2.5, d.weight ? d.weight * edgeStrength : edgeStrength)
)
if (edgeDistance) {
linkForce.distance(edgeDistance)
}
const simulation =
networkSettings.simulation ||
forceSimulation().force(
"charge",
forceManyBody()
.distanceMax(distanceMax)
.strength(
networkSettings.forceManyBody ||
(d => -25 * nodeSizeAccessor(d))
const clusterSk = this.querySelector('svg')!;
// This force acts as a repulsion force between digest nodes. This acts a lot like charged
// particles repelling one another. The main purpose here is to keep nodes from overlapping.
// See https://github.com/d3/d3-force#forceManyBody
const chargeForce = d3Force.forceManyBody()
.strength(-this.nodeRepulsion)
// Given our nodes have a radius of 12, if two nodes are 60 pixels apart, they are definitely
// not overlapping, so we can stop counting their "charge". This should help performance by
// reducing computation needs.
.distanceMax(60);
// This force acts as a spring force between digest nodes. More similar digests pull more
// tightly and should be closer together.
// See https://github.com/d3/d3-force#links
const linkForce = d3Force.forceLink(this.links)
.distance((d) => d.value / this.linkTightness);
// This force keeps the diagram centered in the SVG.
// See https://github.com/d3/d3-force#centering
const centerForce = d3Force.forceCenter(this.width / 2, this.height / 2);
// These forces help keep the nodes in the visible area.
const xForce = d3Force.forceX(this.width / 2);
xForce.strength(0.1);
const yForce = d3Force.forceY(this.height / 2);
yForce.strength(0.2); // slightly stronger force down since we have more width to draw into
// This starts a simulation that will render over the next few seconds as the nodes are
// simulated into place.
// See https://github.com/d3/d3-force#forceSimulation
d3Force.forceSimulation(this.nodes)
.strength(0.4)
.x(n => {
const centerPoint = dimensions.svg.w / 4 * 3; // 'center is 3/4 to the right'
const downstreams = n.downstreams || [];
const minXs = _.flatMap(downstreams, d => {
return d.fx
? [d.fx, d.x]
: [d.x];
});
const minX = _.min(minXs);
return (minX || centerPoint) - 100;
}))
.force('y', forceY(dimensions.svg.h / 2))
.force('link', forceLink()
.id(f => f.id)
.distance(150))
;
function drawFlows(holder, flows = []) {
const flowSelection = holder
.selectAll(mkClassSelector(Styles.FLOW))
.data(flows, f => f.id);
const newFlows = flowSelection
.enter()
.append('path')
.classed(Styles.FLOW, true);
flowSelection
_graphForcesConfig() {
this.state.simulation.nodes(this.state.d3Nodes).on('tick', this._tick);
const forceLink = d3ForceLink(this.state.d3Links)
.id(l => l.id)
.distance(this.state.config.d3.linkLength)
.strength(this.state.config.d3.linkStrength);
this.state.simulation.force(CONST.LINK_CLASS_NAME, forceLink);
const customNodeDrag = d3Drag()
.on('start', this._onDragStart)
.on('drag', this._onDragMove)
.on('end', this._onDragEnd);
d3Select(`#${this.state.id}-${CONST.GRAPH_WRAPPER_ID}`)
.selectAll('.node')
.call(customNodeDrag);
}
const topLevelSource = !source.data.nested ? source as ExtendedNodeDatum : source.data.nested.parent;
const topLevelTarget = !target.data.nested ? target as ExtendedNodeDatum : target.data.nested.parent;
topLevelSource.data.topLevelLinked.push(topLevelTarget);
topLevelTarget.data.topLevelLinked.push(topLevelSource);
return {
data: {
svgLink: svgLinksByKey[r.from + '-' + r.to]
},
source,
target
};
});
(d3.forceSimulation(d3Nodes)
.force('link',
d3.forceLink>()
.links(d3Links)
.strength(l => (l.source as ExtendedNodeDatum).data.node.isStack ? 5 : 2)
)
.force('heap-boundary', forceRepealBoundary(n => this.getNodeRect(n), heapBoundary))
.force('intersections', forceRepealNodeIntersections(n => this.getNodeRect(n, { margin: nodeLayoutMargin })))
.force('nested', forceBindNested())
.tick(400) as unknown as d3.Simulation)
.stop();
for (const node of d3Nodes) {
const { element, isDomLayout, width, height } = node.data;
if (isDomLayout)
continue;
element.style.transform = `translate(${node.x - (width / 2)}px, ${node.y - (height / 2)}px)`;
}