import {FC, useMemo} from "react"; import {EnrichedEntity, Recipe} from "../../src/types"; import styles from './ProducingGraph.module.css' import {EntityIcon} from "../home/EntityIcon/EntityIcon"; import {sortByProperty} from "../../src/utils"; import Link from "next/link"; import {RecipeSpan} from "../home/Recipe/Recipe"; export interface ProducingNode { inputs: string[] outputs: string[] name: string icons?: (EnrichedEntity|string)[] linkOut?: string recipe?: Recipe } interface Props { nodes: ProducingNode[] inputs: string[] } export const ProducingGraph: FC = ({nodes, inputs}) => { const rows: ProducingNode[][] = useMemo(() => { const available = new Set(inputs) let todo = [...nodes] const result: ProducingNode[][] = [] while (todo.length) { const amount = todo.length const thisRow: string[] = [] result.push([]) todo = todo.filter((node) => { if (node.inputs.every(input => available.has(input))) { result[result.length - 1].push(node) thisRow.push(...node.outputs) return false } return true }) thisRow.map(uid => available.add(uid)) result[result.length - 1].sort(sortByProperty(val => -val.outputs.length * 1000 + -val.inputs.length)) if (amount === todo.length) { console.warn("Loop detected! Left over:", todo) result.pop() break } } return result }, [inputs, nodes]) return
{inputs.map((input, idx) => )} {rows.map((row, colIdx) => row.map((node, idx) => (
{ node.linkOut && 🔗 }

{node.name}

{ node.icons?.length ?
{node.icons.map((input) => )}
: null } { node.recipe ? : <>

Inputs

{node.inputs.map((input) => )}
{node.outputs.length ? <>

Outputs

{node.outputs.map((input) => )}
: null} }
)))}
}