Public
Edited
Sep 12, 2023
Insert cell
Insert cell
Insert cell
<svg width=${width} height="800" viewBox="0 0 ${width} 800" id='mySVG'></svg>
Insert cell
// Tree
main = {

const svg = d3.select('#mySVG');
const height = 800 // document.body.clientHeight;
//const width = document.body.clientWidth;

const treeLayout = d3.tree().nodeSize([160, 260]);

const zoomG = svg
.attr('width', width)
.attr('height', height)
.append('g');

svg.call(d3.zoom().on('zoom', () => { zoomG.attr('transform', d3.event.transform); }));

const root = d3.hierarchy(jsonData);
const links = treeLayout(root).links();

const treeHeight = d3.max(root.descendants(), d => d.y)
const treeWidth = d3.max(root.descendants(), d => d.x)
const translations = getTranslations(height, width, treeHeight, treeWidth)

const g = zoomG.append('g').attr('transform', `translate(${translations[0]},${translations[1]}) scale(${getScale(height, treeHeight)})`);

makeLines(g, links);
makeCircle(g, root.descendants());
makeText(g, root.descendants());
makeIcons(g, root.descendants());

}
Insert cell
Insert cell
function getTranslations(boxHeight, boxWidth, treeHeight, treeWidth) {
if (treeHeight == 0) {
return [boxWidth / 2, (boxHeight / 2)]
}
else if (boxHeight + 100 >= treeHeight) {
return [boxWidth / 2, (boxHeight - (treeHeight * 0.8)) / 2];
}
return [boxWidth / 2, 50];
}

Insert cell
function getScale(boxHeight, treeHeight) {
if (boxHeight + 100 >= treeHeight) {
return 0.8;
}
return (boxHeight - 100) / treeHeight;
}
Insert cell
function makeLines(g, l) {
g.selectAll('path').data(l)
.enter().append('path')
.attr("fill", "orange")
.attr("stroke-width", 3)
.attr('d', customCurve);
}
Insert cell
function customCurve(d) {
return "M" + d.source.x + "," + d.source.y // move to
+ "C" + d.source.x + "," + (d.source.y + d.target.y) / 2 // curve start C instructs CVG to draw a cubic Bézier curve
+ " " + d.target.x + "," + (d.source.y + d.target.y) / 2 // curve mid point
+ " " + d.target.x + "," + d.target.y; // curve end
}
Insert cell
Insert cell
function makeCircle(g, r) {
g.selectAll('circle').data(r)
.enter().append('circle')
.attr('cx', d => d.x)
.attr('cy', d => d.y)
.attr('r', 60)
.attr('stroke', d => d.data.data.isFocused ? blue : surface2)
.attr('stroke-width', 4)
.attr('fill', crust);
}

Insert cell
function makeText(g, r) {
g.selectAll('text').data(r)
.enter().append('text')
.attr('x', d => d.x)
.attr('y', d => d.y - 15)
.attr('dy', '0.32em')
.attr('fill', d => d.data.data.isFocused ? blue : textt)
.attr('text-anchor', 'middle')
.attr('font-size', 30)
.text(d => d.data.data.wff);
}
Insert cell
function makeIcons(g, r) {
r.forEach(node => {
const icons = getIcons(node.data);

switch (icons.length) {
case 4:
makeIcon(g, icons[0][0], icons[0][1], node.x - 50, node.y + 7);
makeIcon(g, icons[1][0], icons[1][1], node.x - 23, node.y + 7);
makeIcon(g, icons[2][0], icons[2][1], node.x, node.y + 7);
makeIcon(g, icons[3][0], icons[3][1], node.x + 24, node.y + 7);
break;
case 3:
makeIcon(g, icons[0][0], icons[0][1], node.x - 35, node.y + 7);
makeIcon(g, icons[1][0], icons[1][1], node.x - 13, node.y + 7);
makeIcon(g, icons[2][0], icons[2][1], node.x + 12, node.y + 7);
break;
case 2:
makeIcon(g, icons[0][0], icons[0][1], node.x - 23, node.y + 7);
makeIcon(g, icons[1][0], icons[1][1], node.x, node.y + 7);
break;
case 1:
makeIcon(g, icons[0][0], icons[0][1], node.x - 10, node.y + 7);
break;
default:
break;
}
});
}
Insert cell
function makeIcon(g, icon, color, x, y) {
g.append('g')
.append('path')
.attr('d', icon)
.attr('transform', `translate(${x},${y}) scale(.04)`)
.style('fill', color)
.style('stroke', color);
}
Insert cell
function getIcons(n) {
const icons = [];

if (n.data.isFocused) {
icons.push([eye, blue]);
}

if (n.data.isYours) {
icons.push([user, green]);
} else {
icons.push([user, red]);
}

switch (n.data.doxasticState) {
case "agnosticism":
icons.push([brain, peach]);
break;
case "belief":
icons.push([brain, green]);
break;
case "disbelief":
icons.push([brain, red]);
break;
default:
break;
}

switch (n.data.doxasticStateSupport) {
case "agnosticism":
icons.push([nodes, peach]);
break;
case "belief":
icons.push([nodes, green]);
break;
case "disbelief":
icons.push([nodes, red]);
break;
default:
break;
}

return icons;
}
Insert cell
rosewater = '#f5e0dc';
Insert cell
flamingo = '#f2cdcd';
Insert cell
pink = '#f5c2e7';
Insert cell
mauve = '#cba6f7';
Insert cell
red = '#f38ba8';
Insert cell
maroon = '#eba0ac';
Insert cell
peach = '#fab387';
Insert cell
yellow = '#f9e2af';
Insert cell
green = '#a6e3a1';
Insert cell
teal = '#94e2d5';
Insert cell
sky = '#89dceb';
Insert cell
sapphire = '#74c7ec';
Insert cell
blue = '#89b4fa';
Insert cell
lavender = '#b4befe';
Insert cell
textt = '#cdd6f4';
Insert cell
subtext1 = '#bac2de';
Insert cell
subtext0 = '#a6adc8';
Insert cell
overlay2 = '#9399b2';
Insert cell
overlay1 = '#7f849c';
Insert cell
overlay0 = '#6c7086';
Insert cell
surface2 = '#585b70';
Insert cell
surface1 = '#45475a';
Insert cell
surface0 = '#313244';
Insert cell
base = '#1e1e2e';
Insert cell
mantle = '#181825';
Insert cell
crust = '#11111b';
Insert cell
brain = 'M184 0c30.9 0 56 25.1 56 56V456c0 30.9-25.1 56-56 56c-28.9 0-52.7-21.9-55.7-50.1c-5.2 1.4-10.7 2.1-16.3 2.1c-35.3 0-64-28.7-64-64c0-7.4 1.3-14.6 3.6-21.2C21.4 367.4 0 338.2 0 304c0-31.9 18.7-59.5 45.8-72.3C37.1 220.8 32 207 32 192c0-30.7 21.6-56.3 50.4-62.6C80.8 123.9 80 118 80 112c0-29.9 20.6-55.1 48.3-62.1C131.3 21.9 155.1 0 184 0zM328 0c28.9 0 52.6 21.9 55.7 49.9c27.8 7 48.3 32.1 48.3 62.1c0 6-.8 11.9-2.4 17.4c28.8 6.2 50.4 31.9 50.4 62.6c0 15-5.1 28.8-13.8 39.7C493.3 244.5 512 272.1 512 304c0 34.2-21.4 63.4-51.6 74.8c2.3 6.6 3.6 13.8 3.6 21.2c0 35.3-28.7 64-64 64c-5.6 0-11.1-.7-16.3-2.1c-3 28.2-26.8 50.1-55.7 50.1c-30.9 0-56-25.1-56-56V56c0-30.9 25.1-56 56-56z';
Insert cell
eye = 'M288 32c-80.8 0-145.5 36.8-192.6 80.6C48.6 156 17.3 208 2.5 243.7c-3.3 7.9-3.3 16.7 0 24.6C17.3 304 48.6 356 95.4 399.4C142.5 443.2 207.2 480 288 480s145.5-36.8 192.6-80.6c46.8-43.5 78.1-95.4 93-131.1c3.3-7.9 3.3-16.7 0-24.6c-14.9-35.7-46.2-87.7-93-131.1C433.5 68.8 368.8 32 288 32zM144 256a144 144 0 1 1 288 0 144 144 0 1 1 -288 0zm144-64c0 35.3-28.7 64-64 64c-7.1 0-13.9-1.2-20.3-3.3c-5.5-1.8-11.9 1.6-11.7 7.4c.3 6.9 1.3 13.8 3.2 20.7c13.7 51.2 66.4 81.6 117.6 67.9s81.6-66.4 67.9-117.6c-11.1-41.5-47.8-69.4-88.6-71.1c-5.8-.2-9.2 6.1-7.4 11.7c2.1 6.4 3.3 13.2 3.3 20.3z';

Insert cell
nodes = 'M208 80c0-26.5 21.5-48 48-48h64c26.5 0 48 21.5 48 48v64c0 26.5-21.5 48-48 48h-8v40H464c30.9 0 56 25.1 56 56v32h8c26.5 0 48 21.5 48 48v64c0 26.5-21.5 48-48 48H464c-26.5 0-48-21.5-48-48V368c0-26.5 21.5-48 48-48h8V288c0-4.4-3.6-8-8-8H312v40h8c26.5 0 48 21.5 48 48v64c0 26.5-21.5 48-48 48H256c-26.5 0-48-21.5-48-48V368c0-26.5 21.5-48 48-48h8V280H112c-4.4 0-8 3.6-8 8v32h8c26.5 0 48 21.5 48 48v64c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V368c0-26.5 21.5-48 48-48h8V288c0-30.9 25.1-56 56-56H264V192h-8c-26.5 0-48-21.5-48-48V80z';

Insert cell
user = 'M224 256A128 128 0 1 0 224 0a128 128 0 1 0 0 256zm-45.7 48C79.8 304 0 383.8 0 482.3C0 498.7 13.3 512 29.7 512H418.3c16.4 0 29.7-13.3 29.7-29.7C448 383.8 368.2 304 269.7 304H178.3z';

Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more