Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FEAT: persist graph #31

Draft
wants to merge 13 commits into
base: master
Choose a base branch
from
13 changes: 11 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
## CRBN-FTPRNT
## CRBN:FT:PRNT


### CLIENT (D3 visualization)

`yarn`

`yarn start`
`yarn start`

---

### SERVER (serial communications)

`go run commm/main.go`
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,14 @@
"dependencies": {
"@types/animejs": "^2.0.2",
"@types/d3": "^5.7.2",
"@types/d3-drag": "^1.2.3",
"@types/jest": "24.0.16",
"@types/node": "12.6.8",
"@types/react": "16.8.23",
"@types/react-dom": "16.8.5",
"animejs": "^3.1.0",
"d3": "4.9.0",
"libreact": "^2.13.1",
"node-sass": "^4.12.0",
"react": "^16.8.6",
"react-dom": "^16.8.6",
Expand Down
22 changes: 0 additions & 22 deletions serial.py

This file was deleted.

50 changes: 28 additions & 22 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,51 +12,57 @@ const App: FC<IProps> = ({ width, height, ws }) => {
const [currentGif, setCurrentGif] = useState<number>(0)
const [signal, setSignal] = useState<signalType>(null)
const [signalCount, setSignalCount] = useState<number>(0)
let gifs: string[] = []
const gifs: string[] = []
const imagePath = "./../../.."

for (let i = 0; i < 80; i++) {
if (i < 10) {
gifs.push("../../../../gifs/00" + i + ".gif")
gifs.push(`${imagePath}/gifs/00${i}.gif`)
} else {
gifs.push("../../../../gifs/0" + i + ".gif")
gifs.push(`${imagePath}/gifs/0${i}.gif`)
}
}

useEffect(() => {
ws.onmessage = (e) => {
ws.onmessage = (e: MessageEvent) => {
if(e.data !== "") {
setSignal(e.data)
setSignalCount(signalCount+1)
}

const newSignal = signalCount + 1
setSignalCount(newSignal)
}

// clean up
return function cleanup() {
ws.close()
}
}, [])
// 3, 5, 25, 33, 38, 40, 46, 60, 62
})

useEffect(() => {
// if (signalCount % 10 === 0) {
if (currentGif < gifs.length - 1) {
setCurrentGif(currentGif + 1)
} else {
setCurrentGif(0)
}
document.body.style.backgroundImage = 'url("' + gifs[currentGif] + '")'
// }
if (currentGif < gifs.length - 1) {
setCurrentGif(currentGif + 1)
} else {
setCurrentGif(0)
}
document.body.style.backgroundImage = 'url("' + gifs[currentGif] + '")'
}, [signalCount])

const handleClickSignal = (signal: signalType) => {
setSignal(signal)
setSignalCount(signalCount+1)
setSignalCount(signalCount + 1)
}

return (
<div className="App">
<Header />
<TreeNity
width={width}
height={height}
signal={signal}
<Header/>
<TreeNity
width={width}
height={height}
signal={signal}
signalCount={signalCount}
handleClickSignal={handleClickSignal}/>
<Footer />
<Footer/>
</div>
)
}
Expand Down
2 changes: 1 addition & 1 deletion src/components/Footer/Footer.container.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,4 @@ const Footer: FC<object> = () => {
);
};

export default Footer;
export default Footer;
4 changes: 2 additions & 2 deletions src/components/Labels.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ interface ILabelProps {
}

interface ILabelsProps {
nodes: d3Node[]
nodes: d3Node[]
}

const Label: React.FC<ILabelProps> = (props) => {
Expand Down Expand Up @@ -35,4 +35,4 @@ const Labels: React.FC<ILabelsProps> = (props) => {
)
}

export default Labels
export default Labels
84 changes: 74 additions & 10 deletions src/components/Nodes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,84 @@ import React, { useEffect, useRef } from "react"
import * as d3 from 'd3'

interface INodeProps {
node: d3Node
color: string
node: d3Node
color: string
simulation?: any
}

interface INodesProps {
nodes: d3Node[]
nodes: d3Node[]
simulation?: any
}

const drag = (simulation: any) => {
function dragstarted(d: any) {
if (!d3.event.active) simulation.alphaTarget(0.3).restart();
if (!d.fx) {
d.fx = d.x;
d.fy = d.y;
} else {
d.fx = d.fy = null;
}
}

function dragged(d: any) {
d.fx = d3.event.x;
d.fy = d3.event.y;
}

function dragended(d: any) {
if (!d3.event.active) simulation.alphaTarget(0);

// save fixed locations to localStorage
localStorage.setItem(
"positions",
JSON.stringify(
simulation
.nodes()
.map((d: any, i: number) => ({ i, fx: d.fx, fy: d.fy }))
.filter((d: any) => d.fx)
)
)
}

return d3
.drag()
.on("start", dragstarted)
.on("drag", dragged)
.on("end", dragended);
}

const Node: React.FC<INodeProps> = (props) => {
const ref = useRef(null)



useEffect(() => {
d3.select(ref.current).data([props.node])
})
// apply fixed positions found in localStorage
const fx = JSON.parse(localStorage.getItem("positions"))
if (fx && fx.length > 0) {
for (const f of fx) {
const i = f.i
const fx = f.fx
const fy = f.fy
if (i && props.node[i] && fx && fy) {
props.node[i].fx = fx;
props.node[i].fy = fy;
}
}
}

d3.select(ref.current)
.data([props.node])
.call(drag(props.simulation));
}, [props.node])

const handleColor = () => {
let color = props.color
if (props.node.id === "ORIGIN") {
color = "d6d6d6"
} else if (props.node.id.includes("A")){
color = "#000"
} else if (props.node.id.includes("A")) {
color = "#1f77b4"
}
return color
Expand All @@ -40,14 +98,20 @@ const Node: React.FC<INodeProps> = (props) => {
const Nodes: React.FC<INodesProps> = (props) => {
const color = d3.scaleOrdinal(d3.schemeCategory10)
const nodes = props.nodes.map((node: d3Node, index: number) => {
return <Node key={index} node={node} color={color(node.group.toString())}/>
return (
<Node
key={index}
node={node}
color={color(node.group.toString())}
simulation={props.simulation}/>
)
})

return (
<g className="nodes">
{nodes}
</g>
)
}
}

export default Nodes
export default Nodes
Loading