Skip to content

Instantly share code, notes, and snippets.

@jared-hughes
Last active January 4, 2022 02:36
Show Gist options
  • Save jared-hughes/c834bef597e205a8b40ac1fa9622b029 to your computer and use it in GitHub Desktop.
Save jared-hughes/c834bef597e205a8b40ac1fa9622b029 to your computer and use it in GitHub Desktop.
Desmos Graph Network. Incomplete
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