Skip to content

Instantly share code, notes, and snippets.

@dai-shi
Last active April 17, 2021 14:31
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dai-shi/c01449c09e07579f9a2b85df98632225 to your computer and use it in GitHub Desktop.
Save dai-shi/c01449c09e07579f9a2b85df98632225 to your computer and use it in GitHub Desktop.
dot2exalidraw experiment
const path = require('path');
const dot = require(path.resolve(process.argv[2]));
const output = {
"type": "excalidraw",
"version": 2,
"source": "https://excalidraw.com",
"elements": [],
"appState": {
"viewBackgroundColor": "#ffffff"
}
};
const [, bx1, by1, bx2, by2] = /(\d+),(\d+),(\d+),(\d+)/.exec(dot.bb);
const bWidth = Number(bx2) - Number(bx1);
const bHeight = Number(by2) - Number(by1);
dot.objects.forEach(({ pos, width, height, name }) => {
const [, x, y] = /(\d+),(\d+)/.exec(pos);
const w = Number(width) * bWidth / 2;
const h = Number(height) * bHeight / 2;
output.elements.push({
"type": "ellipse",
"x": Number(x) + w / 2,
"y": -Number(y) - h / 2,
"width": w,
"height": h,
"angle": 0,
"strokeColor": "#000000",
"backgroundColor": "transparent",
"fillStyle": "hachure",
"strokeWidth": 1,
"strokeStyle": "solid",
"roughness": 1,
"opacity": 100,
"seed": Math.floor(Math.random() * 1532506170),
});
output.elements.push({
"type": "text",
"x": Number(x) + w / 2,
"y": -Number(y) - h / 2,
"width": w,
"height": h,
"angle": 0,
"strokeColor": "#000000",
"backgroundColor": "transparent",
"fillStyle": "hachure",
"strokeWidth": 1,
"strokeStyle": "solid",
"roughness": 1,
"opacity": 100,
"seed": Math.floor(Math.random() * 1532506170),
"text": name,
"fontSize": 12, // FIXME hard code
"fontFamily": 1,
"textAlign": "center",
"baseline": 18, // FIXME hard code
});
});
dot.edges.forEach(({ pos }) => {
const [, x2, y2, x1, y1] = /e,([0-9.]+),([0-9.]+) ([0-9.]+),([0-9.]+) ([0-9.]+),([0-9.]+) ([0-9.]+),([0-9.]+) ([0-9.]+),([0-9.]+)/.exec(pos);
output.elements.push({
"type": "arrow",
"x": Number(x1) + 48, // FIXME weird offset
"y": -Number(y1),
"width": Math.abs(x2 - x1),
"height": Math.abs(y2 - y1),
"angle": 0,
"strokeColor": "#000000",
"backgroundColor": "transparent",
"fillStyle": "hachure",
"strokeWidth": 1,
"strokeStyle": "solid",
"roughness": 1,
"opacity": 100,
"seed": Math.floor(Math.random() * 1532506170),
"points": [
[
0,
0
],
[
x2 - x1,
-(y2 - y1),
]
],
});
});
console.log(JSON.stringify(output, null, 2));
{
"type": "excalidraw",
"version": 2,
"source": "https://excalidraw.com",
"elements": [
{
"type": "ellipse",
"x": 86.625,
"y": -103.5,
"width": 47.25,
"height": 27,
"angle": 0,
"strokeColor": "#000000",
"backgroundColor": "transparent",
"fillStyle": "hachure",
"strokeWidth": 1,
"strokeStyle": "solid",
"roughness": 1,
"opacity": 100,
"seed": 1487916509
},
{
"type": "text",
"x": 86.625,
"y": -103.5,
"width": 47.25,
"height": 27,
"angle": 0,
"strokeColor": "#000000",
"backgroundColor": "transparent",
"fillStyle": "hachure",
"strokeWidth": 1,
"strokeStyle": "solid",
"roughness": 1,
"opacity": 100,
"seed": 347315451,
"text": "A",
"fontSize": 12,
"fontFamily": 1,
"textAlign": "center",
"baseline": 18
},
{
"type": "ellipse",
"x": 50.625,
"y": -31.5,
"width": 47.25,
"height": 27,
"angle": 0,
"strokeColor": "#000000",
"backgroundColor": "transparent",
"fillStyle": "hachure",
"strokeWidth": 1,
"strokeStyle": "solid",
"roughness": 1,
"opacity": 100,
"seed": 356283316
},
{
"type": "text",
"x": 50.625,
"y": -31.5,
"width": 47.25,
"height": 27,
"angle": 0,
"strokeColor": "#000000",
"backgroundColor": "transparent",
"fillStyle": "hachure",
"strokeWidth": 1,
"strokeStyle": "solid",
"roughness": 1,
"opacity": 100,
"seed": 808290644,
"text": "B",
"fontSize": 12,
"fontFamily": 1,
"textAlign": "center",
"baseline": 18
},
{
"type": "ellipse",
"x": 122.625,
"y": -31.5,
"width": 47.25,
"height": 27,
"angle": 0,
"strokeColor": "#000000",
"backgroundColor": "transparent",
"fillStyle": "hachure",
"strokeWidth": 1,
"strokeStyle": "solid",
"roughness": 1,
"opacity": 100,
"seed": 1057879316
},
{
"type": "text",
"x": 122.625,
"y": -31.5,
"width": 47.25,
"height": 27,
"angle": 0,
"strokeColor": "#000000",
"backgroundColor": "transparent",
"fillStyle": "hachure",
"strokeWidth": 1,
"strokeStyle": "solid",
"roughness": 1,
"opacity": 100,
"seed": 1044764358,
"text": "C",
"fontSize": 12,
"fontFamily": 1,
"textAlign": "center",
"baseline": 18
},
{
"type": "arrow",
"x": 102.65,
"y": -72.765,
"width": 19.345999999999997,
"height": 37.618,
"angle": 0,
"strokeColor": "#000000",
"backgroundColor": "transparent",
"fillStyle": "hachure",
"strokeWidth": 1,
"strokeStyle": "solid",
"roughness": 1,
"opacity": 100,
"seed": 463791638,
"points": [
[
0,
0
],
[
-19.345999999999997,
37.618
]
]
},
{
"type": "arrow",
"x": 119.35,
"y": -72.765,
"width": 19.346000000000004,
"height": 37.618,
"angle": 0,
"strokeColor": "#000000",
"backgroundColor": "transparent",
"fillStyle": "hachure",
"strokeWidth": 1,
"strokeStyle": "solid",
"roughness": 1,
"opacity": 100,
"seed": 836447194,
"points": [
[
0,
0
],
[
19.346000000000004,
37.618
]
]
}
],
"appState": {
"viewBackgroundColor": "#ffffff"
}
}
digraph Foo {
A -> B
A -> C
}
{
"name": "Foo",
"directed": true,
"strict": false,
"_draw_":
[
{
"op": "c",
"grad": "none",
"color": "#fffffe00"
},
{
"op": "C",
"grad": "none",
"color": "#ffffff"
},
{
"op": "P",
"points": [[0.000,0.000],[0.000,108.000],[126.000,108.000],[126.000,0.000]]
}
],
"bb": "0,0,126,108",
"xdotversion": "1.7",
"_subgraph_cnt": 0,
"objects": [
{
"_gvid": 0,
"name": "A",
"_draw_":
[
{
"op": "c",
"grad": "none",
"color": "#000000"
},
{
"op": "e",
"rect": [63.000,90.000,27.000,18.000]
}
],
"_ldraw_":
[
{
"op": "F",
"size": 14.000,
"face": "Times-Roman"
},
{
"op": "c",
"grad": "none",
"color": "#000000"
},
{
"op": "T",
"pt": [63.000,86.300],
"align": "c",
"width": 10.000,
"text": "A"
}
],
"height": "0.5",
"label": "\\N",
"pos": "63,90",
"width": "0.75"
},
{
"_gvid": 1,
"name": "B",
"_draw_":
[
{
"op": "c",
"grad": "none",
"color": "#000000"
},
{
"op": "e",
"rect": [27.000,18.000,27.000,18.000]
}
],
"_ldraw_":
[
{
"op": "F",
"size": 14.000,
"face": "Times-Roman"
},
{
"op": "c",
"grad": "none",
"color": "#000000"
},
{
"op": "T",
"pt": [27.000,14.300],
"align": "c",
"width": 10.000,
"text": "B"
}
],
"height": "0.5",
"label": "\\N",
"pos": "27,18",
"width": "0.75"
},
{
"_gvid": 2,
"name": "C",
"_draw_":
[
{
"op": "c",
"grad": "none",
"color": "#000000"
},
{
"op": "e",
"rect": [99.000,18.000,27.000,18.000]
}
],
"_ldraw_":
[
{
"op": "F",
"size": 14.000,
"face": "Times-Roman"
},
{
"op": "c",
"grad": "none",
"color": "#000000"
},
{
"op": "T",
"pt": [99.000,14.300],
"align": "c",
"width": 10.000,
"text": "C"
}
],
"height": "0.5",
"label": "\\N",
"pos": "99,18",
"width": "0.75"
}
],
"edges": [
{
"_gvid": 0,
"tail": 0,
"head": 1,
"_draw_":
[
{
"op": "c",
"grad": "none",
"color": "#000000"
},
{
"op": "b",
"points": [[54.650,72.760],[50.290,64.280],[44.850,53.710],[39.960,44.200]]
}
],
"_hdraw_":
[
{
"op": "S",
"style": "solid"
},
{
"op": "c",
"grad": "none",
"color": "#000000"
},
{
"op": "C",
"grad": "none",
"color": "#000000"
},
{
"op": "P",
"points": [[42.990,42.440],[35.300,35.150],[36.770,45.640]]
}
],
"pos": "e,35.304,35.147 54.65,72.765 50.288,64.283 44.853,53.714 39.959,44.197"
},
{
"_gvid": 1,
"tail": 0,
"head": 2,
"_draw_":
[
{
"op": "c",
"grad": "none",
"color": "#000000"
},
{
"op": "b",
"points": [[71.350,72.760],[75.710,64.280],[81.150,53.710],[86.040,44.200]]
}
],
"_hdraw_":
[
{
"op": "S",
"style": "solid"
},
{
"op": "c",
"grad": "none",
"color": "#000000"
},
{
"op": "C",
"grad": "none",
"color": "#000000"
},
{
"op": "P",
"points": [[89.230,45.640],[90.700,35.150],[83.010,42.440]]
}
],
"pos": "e,90.696,35.147 71.35,72.765 75.712,64.283 81.147,53.714 86.041,44.197"
}
]
}
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
Display the source blob
Display the rendered blob
Raw
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
@dai-shi
Copy link
Author

dai-shi commented Nov 19, 2020

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment