This commit is contained in:
Sebastian Seedorf
2022-08-18 17:27:32 +02:00
parent b88ae9ceaa
commit fdf0902d93
10 changed files with 62 additions and 33 deletions

View File

@@ -1,26 +0,0 @@
.plane {
box-shadow: 0 0 0 1px red; /* Border left */
padding: 2em;
width: fit-content;
display: flex;
flex-direction: column;
gap: 10em;
position: relative;
}
.row {
display: flex;
gap: 2em;
justify-content: space-evenly;
}
.node {
padding: 0.5em;
border-radius: 4px;
border: 1px solid #dddddd;
background-color: #eee;
}
.hidden {
width: 0;
}

View File

@@ -1,126 +0,0 @@
import { FC, HTMLProps, PropsWithChildren, useEffect, useRef, useState } from 'react'
import styles from './ProducingGraph.module.css'
import { EntityIcon } from '../../home/EntityIcon/EntityIcon'
import { createPath, drawLine } from '../../../src/svg'
import {
AdditionalNode,
GraphNode,
GraphNodeWithIds,
isAdditionalNode
} from '../../../src/graph-untangle/types'
import { graphUntangled } from '../../../src/graph-untangle'
import { Dict } from '../../../src/types'
interface Props<T extends Dict<unknown>> {
nodes: GraphNode<T>[]
inputs: string[]
outputs?: string[]
childType: FC<HTMLProps<HTMLDivElement> & { node: GraphNode<T> }>
}
export const ProducingGraph = <T extends Dict<unknown>>({
nodes,
inputs,
outputs,
childType: ChildType
}: PropsWithChildren<Props<T>>) => {
const planeRef = useRef<HTMLDivElement>(null)
const [[rows, nodeMap]] = useState<[string[][], Dict<GraphNodeWithIds<T | AdditionalNode>>]>(
graphUntangled(nodes, inputs, outputs ?? [], 3000)
)
useEffect(() => {
if (!planeRef.current) return
const plane = planeRef.current
function createSvgElement() {
const elem = document.createElementNS('http://www.w3.org/2000/svg', 'svg')
elem.id = 'arrows'
elem.setAttribute(
'style',
'position: absolute; inset: 0 0 0 0; pointer-events: none; z-index: -10;'
)
elem.setAttributeNS(null, 'stroke', 'black')
elem.setAttributeNS(null, 'fill', 'none')
plane.appendChild(elem)
return elem
}
const svg = document.getElementById('arrows') ?? createSvgElement()
const width = Math.round(plane.getBoundingClientRect().width)
const height = Math.round(plane.getBoundingClientRect().height)
svg.setAttribute('width', `${width}`)
svg.setAttribute('height', `${height}`)
svg.setAttributeNS(null, 'viewBox', `0 0 ${width} ${height}`)
svg.replaceChildren()
const paths: string[] = []
plane.querySelectorAll('[data-outputs]').forEach(startNode => {
if (!(startNode instanceof HTMLElement)) return
;(startNode.dataset.outputs?.split(' ') ?? []).forEach(output => {
const endNode = plane.querySelector(`[data-name="${output}"]`)
if (!(endNode instanceof HTMLElement)) return
paths.push(
createPath(
plane.getBoundingClientRect(),
startNode.getBoundingClientRect(),
endNode.getBoundingClientRect()
)
)
})
})
plane.querySelectorAll('[data-hidden="true"][data-outputs]').forEach(elem => {
if (!(elem instanceof HTMLElement)) return
paths.push(drawLine(plane.getBoundingClientRect(), elem.getBoundingClientRect()))
})
const path = document.createElementNS('http://www.w3.org/2000/svg', 'path')
path.setAttributeNS(null, 'd', paths.join(' '))
svg.appendChild(path)
})
return (
<div className={styles.plane} ref={planeRef}>
{rows.map((row, colIdx) => (
<div className={styles.row} key={colIdx} data-row={true}>
{row.map(uid => {
const node = nodeMap[uid]
return !isAdditionalNode(node) ? (
<span
data-name={node.___uid}
data-inputs={node.___uidInputs.join(' ')}
data-outputs={node.___uidOutputs.join(' ')}
key={node.___uid}
data-hidden={node.___uidOutputs.length > 0}
>
<ChildType className={styles.node} node={node} />
</span>
) : node.___type === 'h' ? (
<span
className={styles.hidden}
key={node.___uid}
data-name={node.___uid}
data-inputs={node.___uidInputs.join(' ')}
data-outputs={node.___uidOutputs.join(' ')}
data-hidden={true}
></span>
) : node.___type === 'i' ? (
<span
key={node.___uid}
data-name={node.___uid}
data-outputs={node.___uidOutputs.join(' ')}
data-hidden={true}
>
<EntityIcon value={node.name} />
</span>
) : (
<EntityIcon
key={node.___uid}
value={node.name}
data-name={node.___uid}
data-inputs={node.___uidInputs.join(' ')}
/>
)
})}
</div>
))}
</div>
)
}

View File

@@ -1,10 +0,0 @@
.container {
width: 100vw;
height: 100vh;
}
.inner {
padding: 2em;
width: fit-content;
height: fit-content;
}

View File

@@ -1,25 +0,0 @@
import { FC, PropsWithChildren, useEffect, useRef } from 'react'
import IndianaDragScoll from 'react-indiana-drag-scroll'
import styles from './ScrollContainer.module.css'
export const ScrollContainer: FC<PropsWithChildren> = ({ children }) => {
const container = useRef<HTMLDivElement>(null)
useEffect(() => {
if (container.current) {
container.current.oncontextmenu = e => e.preventDefault()
}
}, [])
return (
<IndianaDragScoll
className={styles.container}
buttons={[2]}
innerRef={container}
hideScrollbars={false}
activationDistance={5}
>
<div className={styles.inner}>{children}</div>
</IndianaDragScoll>
)
}