Public
Edited
May 12, 2023
1 star
Insert cell
Insert cell
import {formWithSumbit} from "@forresto/form-input-with-submit"
Insert cell
Insert cell
chart = {
// "this" saves the output value of the block, and can be used
// to persist the DOM from one execution to the next.
const svg = d3.select(DOM.svg(width, height));
// Select the already existing nodes ("g") and edges ("line") if they exist
// Set their data to the new, updated dynamicData
let nodes = svg.selectAll("g").data(dynamicData.nodes)
let edges = svg.selectAll("line").data(dynamicData.links)

console.log(dynamicData.links)
// For any new edges being added, append a line
var enterEdges = edges.enter().append("line").lower()
.attr("stroke", "#222")
.attr("stroke-opacity", 0.2)
.attr("stroke-width", 1)
.attr("x1", d => d.source.x)
.attr("y1", d => d.source.y)
.attr("x2", d => d.target.x)
.attr("y2", d => d.target.y)
// For any new nodes being added, append a g
var enterNodes = nodes.enter().append("g")
// .attr('transform', d => `translate(${d.x},${d.y})`)
// .attr('skewX', 70)
// .attr('skewY', 70)
.append('circle')
.attr("stroke", "#FFF")
.attr("stroke-width", 0.2)
.attr("class","node")
.attr("cx", d => d.x)
.attr("cy", d => d.y)
.attr("r", d => d.r || 5)//make this one of three sizes
.attr("fill", d => d.color)
.call(drag());
// merge the new nodes with the existing nodes
nodes = nodes.merge(enterNodes);
// merge the new edges with the existing edges
edges = edges.merge(enterEdges);
function ticked() {
edges
.attr("x1", d => d.source.x)
.attr("y1", d => d.source.y)
.attr("x2", d => d.target.x)
.attr("y2", d => d.target.y);

nodes
// .attr("transform", d => `translate(${d.x},${d.y}) skewX(30)`)
//.attr("transform", d => `translate(${d.x},${d.y})`)
.attr("cx", d => d.x)
.attr("cy", d => d.y);
};
simulation
.on("tick", ticked)

return svg.node();
}
Insert cell
dynamicData = {
let numeric_node_size2 = function(size) {
switch(size) {
case "small":
return 5;
case "medium":
return 10;
case "large":
return 15;
}
}
// If the data does not yet exist, initialize
if (!this) {
return {
nodes: [],
links: []
}
}
let color = new_node.color || "black";
let size = numeric_node_size2(new_node.size);
let len = this.nodes.length

// create new nodes when nodeColor activated
if (this.nodes.length > 0) {
//randomly select another node to connect with
//let randomNode = this.nodes[Math.floor(Math.random() * len)];
let randomNode = this.nodes[0];
console.log(this.nodes.length);
console.log("=> " + randomNode.id);
this.nodes.push({id: len,
color: color,
r: size, // Math.floor(Math.random() * 10) + 5,
x: Math.random() * width,
y: Math.random()* height}) // x: randomNode.x, y: randomNode.y})
this.links.push({source: randomNode.id,
target: len,
value: 1})
} else {
console.log("first node");
this.nodes.push({id: len,
r: size,
color: color})
}
return this
}
Insert cell
simulation = {
// If the simulation already exists, just alter the nodes, links, and restart
if (this) {
return this.nodes(dynamicData.nodes)
.force("link", d3.forceLink(dynamicData.links).id(d => d.id))
.restart()
}
// If the simulation doesn't yet exist, create it.
return d3.forceSimulation(dynamicData.nodes)
.force("link", d3.forceLink(dynamicData.links).id(d => d.id))
.force("center", d3.forceCenter(width / 2, height / 2))
.force("charge", d3.forceManyBody().strength(-60))
.restart()
.alphaDecay(0.0002);
}
Insert cell
Insert cell
drag = () => {
function dragstarted(d) {
console.log("started drag");
if (!d3.event.active) simulation.alphaTarget(0.0002).restart();
d.fx = d.x;
d.fy = d.y;
}
function dragged(d) {
d.fx = d3.event.x;
d.fy = d3.event.y;
}
function dragended(d) {
if (!d3.event.active) simulation.alphaTarget(0);
d.fx = null;
d.fy = null;
}
return d3.drag()
.on("start", dragstarted)
.on("drag", dragged)
.on("end", dragended);
}
Insert cell
d3 = require("d3@5")
Insert cell
import { text } from "@jashkenas/inputs"
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