ok it kinda renders

This commit is contained in:
Michael Zhang 2024-06-27 19:23:36 -05:00
parent c79fb7de78
commit 354ecd33a6
6 changed files with 80 additions and 48 deletions

15
README.md Normal file
View file

@ -0,0 +1,15 @@
# matter
To install dependencies:
```bash
bun install
```
To run:
```bash
bun run index.ts
```
This project was created using `bun init` in bun v1.1.17. [Bun](https://bun.sh) is a fast all-in-one JavaScript runtime.

BIN
bun.lockb

Binary file not shown.

View file

@ -1,6 +1,7 @@
{ {
"dependencies": { "dependencies": {
"d3": "^7.9.0", "d3": "^7.9.0",
"nanoid": "^5.0.7",
"react": "^18.3.1", "react": "^18.3.1",
"react-dom": "^18.3.1" "react-dom": "^18.3.1"
}, },
@ -11,6 +12,13 @@
"@types/react-dom": "^18.3.0", "@types/react-dom": "^18.3.0",
"@vitejs/plugin-react-swc": "^3.7.0", "@vitejs/plugin-react-swc": "^3.7.0",
"sass": "^1.77.6", "sass": "^1.77.6",
"vite": "^5.3.2" "vite": "^5.3.2",
"@types/bun": "latest"
},
"name": "matter",
"module": "index.ts",
"type": "module",
"peerDependencies": {
"typescript": "^5.0.0"
} }
} }

View file

@ -18,4 +18,12 @@ text {
font-family: "Helvetica Neue", Helvetica, sans-serif; font-family: "Helvetica Neue", Helvetica, sans-serif;
fill: #666; fill: #666;
font-size: 16px; font-size: 16px;
}
.nodeContainer {
box-sizing: border-box;
border: 1px solid gray;
border-radius: 4px;
width: 100%;
height: 100%;
} }

View file

@ -2,8 +2,10 @@ import * as d3 from "d3";
import { useCallback, useEffect, useMemo, useRef, useState } from "react"; import { useCallback, useEffect, useMemo, useRef, useState } from "react";
import styles from "./App.module.scss"; import styles from "./App.module.scss";
import { createPortal } from "react-dom"; import { createPortal } from "react-dom";
import { nanoid } from "nanoid";
interface NodeInfo extends d3.SimulationNodeDatum { interface NodeInfo extends d3.SimulationNodeDatum {
id: string;
name: string; name: string;
} }
@ -16,7 +18,7 @@ const nodes: NodeInfo[] = [
{ name: "F" }, { name: "F" },
{ name: "G" }, { name: "G" },
{ name: "H" }, { name: "H" },
]; ].map((node) => ({ ...node, id: nanoid() }));
const links = [ const links = [
{ source: 0, target: 1 }, { source: 0, target: 1 },
@ -31,7 +33,6 @@ const links = [
export default function App() { export default function App() {
const svgRef = useRef(); const svgRef = useRef();
const simulationRef = useRef();
// Resize listener // Resize listener
const [rect, setRect] = useState<DOMRectReadOnly | null>(null); const [rect, setRect] = useState<DOMRectReadOnly | null>(null);
@ -46,25 +47,7 @@ export default function App() {
const [simulationNodes, setSimulationNodes] = useState(() => nodes); const [simulationNodes, setSimulationNodes] = useState(() => nodes);
const ticked = useCallback((simulation: d3.Simulation<NodeInfo, any>) => { const ticked = useCallback((simulation: d3.Simulation<NodeInfo, any>) => {
const nodes = simulation.nodes(); const nodes = simulation.nodes();
// setSimulationNodes(nodes); setSimulationNodes([...nodes]);
// d3.select("svg .links")
// .selectAll("line")
// .data(links)
// .join("line")
// .attr("x1", (d) => d.source.x)
// .attr("x2", (d) => d.target.x)
// .attr("y1", (d) => d.source.y)
// .attr("y2", (d) => d.target.y);
d3.select("svg .nodes")
.selectAll("rect")
.data(nodes)
.join("rect")
// .append("foreignObject")
.text((d) => d.name)
.attr("x", (d) => d.x)
.attr("y", (d) => d.y)
.attr("dy", (d) => 5);
}, []); }, []);
useEffect(() => { useEffect(() => {
@ -72,13 +55,11 @@ export default function App() {
const simulation = d3 const simulation = d3
.forceSimulation<NodeInfo>(nodes) .forceSimulation<NodeInfo>(nodes)
.force("charge", d3.forceManyBody()) .force("charge", d3.forceManyBody().strength(-500))
.force("link", d3.forceLink(links)) .force("link", d3.forceLink(links))
.force("center", d3.forceCenter(rect.width / 2, rect.height / 2)); .force("center", d3.forceCenter(rect.width / 2, rect.height / 2));
simulation.on("tick", () => ticked(simulation)); simulation.on("tick", () => ticked(simulation));
simulationRef.current = simulation;
}, [ticked, rect]); }, [ticked, rect]);
return ( return (
@ -89,15 +70,19 @@ export default function App() {
<g className="links" /> <g className="links" />
<g className="nodes"> <g className="nodes">
{simulationNodes.map((node, idx) => { {simulationNodes.map((node, idx) => {
console.log("node", node);
return ( return (
<text <g key={idx}>
key={idx} <foreignObject
x={(node.x ?? 0).toString()} width={120}
y={(node.y ?? 0).toString()} height={80}
> x={(node.x ?? 0).toString()}
{node.name} y={(node.y ?? 0).toString()}
</text> >
<div data-xmlns="http://www.w3.org/1999/xhtml" id={node.id}>
<Counter />
</div>
</foreignObject>
</g>
); );
})} })}
</g> </g>
@ -107,13 +92,6 @@ export default function App() {
); );
} }
function ForeignObjectWrapper({ id }) {
const el = useMemo(() => {
return document.getElementById(id);
}, [id]);
return createPortal(<Counter />, el);
}
function Counter() { function Counter() {
const [counter, setCounter] = useState(0); const [counter, setCounter] = useState(0);
@ -133,13 +111,14 @@ function Counter() {
}; };
return ( return (
<div className="btn__container"> <div className={styles.nodeContainer}>
<button className="control__btn" onClick={increase}>
+
</button>
<button className="control__btn" onClick={decrease}> <button className="control__btn" onClick={decrease}>
- -
</button> </button>
{counter}
<button className="control__btn" onClick={increase}>
+
</button>
<button className="reset" onClick={reset}> <button className="reset" onClick={reset}>
Reset Reset
</button> </button>

View file

@ -1,5 +1,27 @@
{ {
"compilerOptions": { "compilerOptions": {
"jsx": "react-jsx" // Enable latest features
} "lib": ["ESNext", "DOM"],
"target": "ESNext",
"module": "ESNext",
"moduleDetection": "force",
"jsx": "react-jsx",
"allowJs": true,
// Bundler mode
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"verbatimModuleSyntax": true,
"noEmit": true,
// Best practices
"strict": true,
"skipLibCheck": true,
"noFallthroughCasesInSwitch": true,
// Some stricter flags (disabled by default)
"noUnusedLocals": false,
"noUnusedParameters": false,
"noPropertyAccessFromIndexSignature": false
}
} }