graf: sila tahnouci nody dolu, pokud maji hodne zavislosti
This commit is contained in:
parent
b926dd3526
commit
102c0677ed
4 changed files with 59 additions and 4 deletions
|
@ -7,7 +7,7 @@
|
|||
|
||||
export let tasks: TasksFile;
|
||||
|
||||
let repulsionForce: number = -600;
|
||||
let repulsionForce: number = -1000;
|
||||
let clicked: string[] = [];
|
||||
let graph: Graph;
|
||||
let currentTask: TaskDescriptor | null = null;
|
||||
|
|
|
@ -5,10 +5,11 @@
|
|||
import * as d3 from "d3";
|
||||
import type { TasksFile, TaskDescriptor } from "./task-loader";
|
||||
import { createNodesAndEdges } from "./graph-types";
|
||||
import { taskForce } from "./task-force";
|
||||
|
||||
export let tasks: TasksFile;
|
||||
let hoveredTask: null | string = null;
|
||||
export let repulsionForce: number = -600;
|
||||
export let repulsionForce: number = -1000;
|
||||
|
||||
// Svelte automatically fills these with a reference
|
||||
let container: HTMLElement;
|
||||
|
@ -61,7 +62,8 @@
|
|||
)
|
||||
.force("charge", d3.forceManyBody().strength(repulsionForce)) // This adds repulsion between nodes. Play with the -400 for the repulsion strength
|
||||
.force("x", d3.forceX()) // attracts elements to the zero X coord
|
||||
.force("y", d3.forceY()) // attracts elements to the zero Y coord
|
||||
.force("y", d3.forceY().strength(0.5)) // attracts elements to the zero Y coord
|
||||
.force("dependencies", taskForce())
|
||||
.on("tick", ticked)
|
||||
.on("end", ticked);
|
||||
|
||||
|
|
|
@ -10,5 +10,8 @@
|
|||
$: y2 = edge === undefined || edge.target === undefined || edge.target.y === undefined ? 0 : edge.target.y;
|
||||
</script>
|
||||
|
||||
<line {x1} {x2} {y1} {y2} style="stroke: #aaa" />
|
||||
<line x1={x1+10} y1={y1} {x2} {y2} style="stroke: #aaa" />
|
||||
<line x1={x1} y1={y1+10} {x2} {y2} style="stroke: #aaa" />
|
||||
<line x1={x1-10} y1={y1} {x2} {y2} style="stroke: #aaa" />
|
||||
<line x1={x1} y1={y1-10} {x2} {y2} style="stroke: #aaa" />
|
||||
|
50
frontend/src/task-force.ts
Normal file
50
frontend/src/task-force.ts
Normal file
|
@ -0,0 +1,50 @@
|
|||
import type { TaskId } from "./graph-types";
|
||||
|
||||
/* copied from graph-types.ts */
|
||||
function toMapById(nodes: TaskId[]): Map<string, TaskId> {
|
||||
let nodeMap = new Map<string, TaskId>();
|
||||
for (let task of nodes) {
|
||||
if (task.id in nodeMap)
|
||||
throw 'duplicate IDs';
|
||||
nodeMap.set(task.id, task);
|
||||
}
|
||||
return nodeMap;
|
||||
}
|
||||
|
||||
export function taskForce(): d3.Force<TaskId, undefined> {
|
||||
let myNodes: TaskId[] | null = null;
|
||||
let deps: Map<string, number> = new Map();
|
||||
let idMap: Map<string, TaskId> = new Map();
|
||||
|
||||
function getNumberOfDeps(task: TaskId): number {
|
||||
if (deps.has(task.id)) return deps.get(task.id)!;
|
||||
|
||||
if (task.task.requires.length == 0) return 0;
|
||||
|
||||
let res = 0;
|
||||
for (let r of task.task.requires) {
|
||||
res += getNumberOfDeps(idMap.get(r)!) + 1;
|
||||
}
|
||||
deps.set(task.id, res);
|
||||
return res;
|
||||
}
|
||||
|
||||
let force: d3.Force<TaskId, undefined> = function(alpha: number) {
|
||||
if (myNodes == null) throw 'nodes not initialized';
|
||||
|
||||
for (let task of myNodes) {
|
||||
if (task.vy == null) {
|
||||
task.vy = 0
|
||||
}
|
||||
|
||||
task.vy += getNumberOfDeps(task) * 25 * alpha;
|
||||
}
|
||||
}
|
||||
|
||||
force.initialize = function(nodes: TaskId[]) {
|
||||
myNodes = nodes;
|
||||
idMap = toMapById(myNodes);
|
||||
}
|
||||
|
||||
return force;
|
||||
}
|
Reference in a new issue