diff options
| -rw-r--r-- | src/index.js | 100 | ||||
| -rw-r--r-- | src/layout.js | 10 |
2 files changed, 61 insertions, 49 deletions
diff --git a/src/index.js b/src/index.js index 2fbbcce..8b3cc16 100644 --- a/src/index.js +++ b/src/index.js @@ -11,6 +11,11 @@ article { } `; +const article = document.createElement('article'); +const canvas = document.createElement('canvas'); +article.appendChild(canvas); +document.body.appendChild(article); + const context = 'https://www.w3.org/ns/activitystreams'; const userCache = {}; @@ -29,69 +34,58 @@ const loadData = async () => { const raw = await require('./graph.json'); const data = await (jsonld.compact(await jsonld.flatten(raw), context)); + const indexedData = {}; + await Promise.all(data['@graph'].map(async (entry) => { - if (entry.type !== 'Note' && entry.formerType !== 'Note') - return; + if (entry.type !== 'Note' && entry.formerType !== 'Note') { + console.info(`entry ${entry.id} is a ${entry.type}`); + return; + } - if (!entry.replies) entry.replies = []; + if (!entry.replies) entry.replies = []; if (!Array.isArray(entry.replies)) entry.replies = [ entry.replies ]; - if (!entry.inReplyTo) entry.inReplyTo = []; + if (!entry.inReplyTo) entry.inReplyTo = []; if (!Array.isArray(entry.inReplyTo)) entry.inReplyTo = [ entry.inReplyTo ]; entry.attributedTo = await loadUser(entry.attributedTo); + + indexedData[entry.id] = entry; })); - return data; + return indexedData; }; -const article = document.createElement('article'); -document.body.appendChild(article); - -loadData().then(async (data) => { - let state = layout.init(); - - article.textContent = ''; - const canvas = document.createElement('canvas'); - article.appendChild(canvas); - - const indexedData = {}; - for (const data of data['@graph']) - indexedData[data.id] = data; - - window.dagData = indexedData; - const graph = {}; - - let rootId; - - for (const data of data['@graph']) { - if (data.inReplyTo.length === 0) - rootId = data.id; +const createNotes = (graph, indexedData) => { + for (const data of Object.values(indexedData)) { + if (data.id in graph) + continue; const onlyParent = data.inReplyTo.length === 1 && indexedData[data.inReplyTo[0]]; const dom = ( <Note - {...data} - smallHeader={ - onlyParent // only one parent post - && onlyParent.attributedTo === data.attributedTo // posted by same user - && onlyParent.published === data.published // in the same second - } + {...data} + smallHeader={ + onlyParent // only one parent post + && onlyParent.attributedTo === data.attributedTo // posted by same user + && onlyParent.published === data.published // in the same second + } /> ); article.appendChild(dom); - const node = { - dom, data, - width: dom.offsetWidth, - height: dom.offsetHeight, - }; - graph[data.id] = node; - state = layout.addNode(state, node); + graph[data.id] = { dom, data }; } +}; + +const layoutNodes = async (graph) => { + let state = layout.init(); + + for (const node of Object.values(graph)) + state = layout.addNode(state, node); await layout.render(state, canvas, (id, x, y) => { @@ -99,11 +93,31 @@ loadData().then(async (data) => { dom.style.left = `${x - dom.offsetWidth/2}px`; dom.style.top = `${y - dom.offsetHeight/2}px`; }, - (width, height) => { + (width, height) => { canvas.width = width; canvas.height = height; }, ); +}; + +const update = async (graph) => { + const indexedData = await loadData(); + window.dagData = indexedData; + + createNotes(graph, indexedData); + await layoutNodes(graph); +}; + +const scrollToRoot = (graph) => { + for (const node of Object.values(graph)) { + if (node.data.inReplyTo.length === 0) { + node.dom.scrollIntoView(); + return; + } + } +} - graph[rootId].dom.scrollIntoView(); -}); +const graph = {}; +update(graph) + .then(() => scrollToRoot(graph)) + .catch(err => console.error(err)); diff --git a/src/layout.js b/src/layout.js index a19bc00..95237c5 100644 --- a/src/layout.js +++ b/src/layout.js @@ -8,7 +8,7 @@ export const init = () => { export const addNode = (dot, node) => { const id = node.data.id; - dot += ` "${id}" [fixedsize=true; width=${node.width / 72}; height=${node.height / 72}];\n`; + dot += ` "${id}" [fixedsize=true; width=${node.dom.offsetWidth / 72}; height=${node.dom.offsetHeight / 72}];\n`; for (const replyId of node.data.replies || []) dot += ` "${id}" -> "${replyId}";\n`; @@ -21,14 +21,12 @@ 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 info = await graphviz.renderJSONObject(dot, { format: 'json0' }); + window.info = info; const [_x, _y, width, height] = info.bb.split(',').map(toNumber); - setSize(width, height); + setSize(width, height); for (const object of info.objects) { const [x, y] = object.pos.split(',').map(toNumber); |
