Last active
January 4, 2022 02:36
-
-
Save jared-hughes/c834bef597e205a8b40ac1fa9622b029 to your computer and use it in GitHub Desktop.
Desmos Graph Network. Incomplete
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function download(url, filename) { | |
var a = document.createElement("a"); | |
a.href = url; | |
a.download = filename; | |
document.body.appendChild(a); | |
a.click(); | |
setTimeout(function () { | |
document.body.removeChild(a); | |
window.URL.revokeObjectURL(url); | |
}, 0); | |
} | |
function reprString(s) { | |
return `"${s.replace(/(\\|"|\n)/g, "\\$1")}"`; | |
} | |
function computeContext() { | |
// Emulate what happens in the web worker | |
const Context = require("core/math/context").Context; | |
const context = new Context(); | |
const changeSet = { | |
isCompleteState: true, | |
statements: {}, | |
}; | |
for (let stmt of Calc.controller.getAllItemModels()) { | |
if (stmt.type !== "expression") continue; | |
changeSet.statements[stmt.id] = stmt; | |
} | |
context.processChangeSet(changeSet); | |
context.updateAnalysis(); | |
return context; | |
} | |
function getAllTrees(rawTree) { | |
if (!rawTree) return []; | |
return [ | |
rawTree, | |
rawTree.metaData?.colorLatex, | |
rawTree.metaData?.clickHandler, | |
].filter((e) => e); | |
} | |
function getUpdates(data) { | |
return data._updateSymbols.filter((e) => !ctx.parent_frame[e]); | |
} | |
function getDependencies(data) { | |
return data._dependencies | |
.filter((e) => !data._dummyDependencies.includes(e)) | |
.filter((e) => !ctx.parent_frame[e]); | |
} | |
function getDot() { | |
const ctx = computeContext(); | |
const subgraphs = { _null: [] }; | |
const exprs = Calc.getState().expressions.list; | |
for (const expr of exprs) { | |
if (expr.type === "folder") { | |
subgraphs[expr.id] = [ | |
`label=${reprString(expr.title ?? "")};`, | |
"node [style=filled,color=white];", | |
"style=filled;", | |
"color=lightgrey;", | |
]; | |
} else { | |
const fid = expr.folderId ?? "_null"; | |
if (expr.type === "expression") { | |
expr.latex ??= ""; | |
const rawTree = ctx.analysis[expr.id].rawTree; | |
const symbolOnly = | |
["Slider", "Assignment", "FunctionDefinition"].includes( | |
rawTree.type | |
) && rawTree._symbol; | |
const label = symbolOnly | |
? rawTree._symbol | |
: expr.latex.length > 15 | |
? expr.latex.substring(0, 12) + "..." | |
: expr.latex; | |
subgraphs[fid].push( | |
`${reprString(expr.id)} [label=${reprString(label)}]` | |
); | |
} | |
} | |
} | |
const dot = ["\tnode[shape=rect];"]; | |
dot.push(...subgraphs._null); | |
for (let id in subgraphs) { | |
if (id !== "_null") { | |
dot.push( | |
`\tsubgraph ${reprString("cluster_" + id)} {${subgraphs[id] | |
.map((e) => "\n\t\t" + e) | |
.join("")}\n\t}` | |
); | |
} | |
} | |
function getSymbolID(symbol) { | |
return ctx.frame[symbol]?.userData?.id ?? "@" + symbol; | |
} | |
function getSymbolFolderID(symbol) { | |
return ctx.frame[symbol]?.userData?.folderId ?? "_null"; | |
} | |
const frameEntries = Object.values(ctx.analysis) | |
.map((e) => e.rawTree) | |
.filter((data) => data?.userData?.id); | |
function getUpdates(data) { | |
return data._updateSymbols.filter((e) => !ctx.parent_frame[e]); | |
} | |
function getDependencies(data) { | |
return data._dependencies | |
.filter((e) => !data._dummyDependencies.includes(e)) | |
.filter((e) => !ctx.parent_frame[e]); | |
} | |
for (let data of frameEntries) { | |
const id = data.userData.id; | |
const trees = getAllTrees(data); | |
for (let symb of trees.flatMap(getUpdates)) { | |
dot.push( | |
`\t${reprString(id)}->${reprString(getSymbolID(symb))}[style=dashed]` | |
); | |
} | |
for (let symb of trees.flatMap(getDependencies)) { | |
dot.push(`\t${reprString(getSymbolID(symb))}->${reprString(id)}`); | |
} | |
} | |
return `digraph G{\n${dot.join("\n")}\n}`; | |
} | |
let dotString = getDot(false); | |
function downloadDOT() { | |
const url = URL.createObjectURL( | |
new Blob([dotString], { type: "application/octet-stream" }) | |
); | |
download(url, "desmos_graph_network.dot"); | |
console.log( | |
"Run the following command in terminal (requires GraphViz installed):\ndot -Tsvg desmos_graph_network.dot > desmos_graph_network.svg && xdg-open desmos_graph_network.svg" | |
); | |
} | |
copy(dotString); | |
console.log( | |
"Contents of a DOT file have been placed on your clipboard. Paste the file contents into http://viz-js.com/, or run `downloadDOT()` to run GraphViz locally" | |
); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment