You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
This repo is archived. You can view files and clone it, but cannot push or open issues/pull-requests.

62 lines
1.6 KiB

import type { SimulationLinkDatum, SimulationNodeDatum } from "d3";
import type { TaskDescriptor, TasksFile } from "./task-loader";
import { createTaskMap } from "./task-loader";
export type TaskId = {
id: string;
task: TaskDescriptor;
} & SimulationNodeDatum;
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;
}
function createNodes(tasks: TasksFile, old?: TaskId[]): TaskId[] {
let m = (old == undefined) ? new Map<string, TaskId>() : toMapById(old);
let res = tasks.tasks.map((t) => {
return { id: t.id, task: t };
});
for (let t of res) {
if (m.has(t.id)) {
Object.assign(t, m.get(t.id))
}
}
return res;
}
export function createNodesAndEdges(tasks: TasksFile, oldNodes?: TaskId[], oldEdges?: SimulationLinkDatum<TaskId>[]): [TaskId[], SimulationLinkDatum<TaskId>[]] {
let nodes = createNodes(tasks, oldNodes);
// create mapping from ID to node
let nodeMap = toMapById(nodes);
let links: SimulationLinkDatum<TaskId>[] = [];
for (const task of tasks.tasks) {
const src = nodeMap.get(task.id)!;
for (const id of task.requires) {
const t = nodeMap.get(id);
if (t === undefined) throw `missing task with id ${id}`;
const l: SimulationLinkDatum<TaskId> =
{
source: src,
target: t
};
links.push(l);
}
}
return [nodes, links];
}