diff options
Diffstat (limited to 'src/layout.js')
| -rw-r--r-- | src/layout.js | 116 |
1 files changed, 116 insertions, 0 deletions
diff --git a/src/layout.js b/src/layout.js new file mode 100644 index 0000000..4762f4a --- /dev/null +++ b/src/layout.js @@ -0,0 +1,116 @@ +import Viz from './viz.es'; + +const graphviz = new Viz({ workerURL: 'lib/lite.render.js' }); + +export const init = () => { + return 'digraph { node [shape="rectangle"];\n'; +} + +export const addNode = (dot, node) => { + const id = node.data.id; + dot += ` "${id}" [fixedsize=true; width=${node.width / 72}; height=${node.height / 72}];\n`; + + for (const replyId of node.data.replies || []) + dot += ` "${id}" -> "${replyId}";\n`; + + return dot; +}; + +const toNumber = (i) => Number(i); + +export const render = async (dot, canvas, setPosition, setSize) => { + dot += '}'; + + console.log(dot); + + const info = await graphviz.renderJSONObject(dot, { format: 'json0' }); + window.info = info; + + const [_x, _y, width, height] = info.bb.split(',').map(toNumber); + + setSize(width, height); + + for (const object of info.objects) { + const [x, y] = object.pos.split(',').map(toNumber); + setPosition(object.name, x, height - y); + } + + const ctx = canvas.getContext('2d'); + ctx.lineWidth = 4; + ctx.lineCap = 'round'; + ctx.lineJoin = 'round'; + ctx.strokeStyle = '#696969'; + + for (const edge of info.edges) { + const pos = edge.pos.slice(2); + const points = pos.split(' ').map(p => { + const [x, y] = p.split(','); + return [toNumber(x), height - toNumber(y)]; + }); + + ctx.beginPath(); + ctx.moveTo(...points[1]); + for (let i = 4; i < points.length; i += 3) { + const [ax, ay] = points[i - 2]; + const [bx, by] = points[i - 1]; + const [x, y] = points[i]; + ctx.bezierCurveTo(ax, ay, bx, by, x, y); + } + ctx.lineTo(...points[0]); + ctx.stroke(); + } +} + +/* +import * as dagre from 'dagre'; + +export const init = () => { + const graph = new dagre.graphlib.Graph(); + + graph.setGraph({ + rankSep: 20, + nodeSep: 40, + }); + graph.setDefaultEdgeLabel(() => ({})); + + return graph; +}; + +export const addNode = (graph, node) => { + graph.setNode(node.data.id, node); + + for (const reply of node.data.replies || []) { + graph.setEdge(node.data.id, reply); + } + + return graph; +}; + +export const render = (graph, canvas, setPosition, setSize) => { + dagre.layout(graph); + const info = graph.graph(); + + setSize(info.width, info.height); + + for (const id of graph.nodes()) { + const node = graph.node(id); + setPosition(node, node.x, node.y); + } + + const ctx = canvas.getContext('2d'); + ctx.lineWidth = 4; + ctx.lineCap = 'round'; + ctx.lineJoin = 'round'; + ctx.strokeStyle = '#696969'; + + for (const eo of graph.edges()) { + const edge = graph.edge(eo); + + ctx.beginPath(); + ctx.moveTo(edge.points[0].x, edge.points[0].y); + for (const p of edge.points.slice(1)) + ctx.lineTo(p.x, p.y); + ctx.stroke(); + } +}; +*/ |
