Public
Edited
Aug 8, 2023
1 fork
1 star
Insert cell
Insert cell
Insert cell
Insert cell
width = 800
Insert cell
height = 600
Insert cell
Insert cell
Insert cell
Insert cell
{
addPanel;

function dragged(d) {
// d3.event exposes dx and dy, which tell us how far the target has been
// dragged since the last "drag" event, so we just update the x and y
// properties on that datum and update the SVG.
// console.log('Lets see:', d, data[1])
d.subject.x = d.x;
d.subject.y = d.y;
update();
}

function draggedAdjust(d) {
// d.subject.width = d.x - d.subject.x;
// d.subject.height = d.y - d.subject.y;

d.subject.width += d.dx;
d.subject.height += d.dy;

d.subject.width = d.subject.width < 50 ? 50 : d.subject.width;
d.subject.height = d.subject.height < 50 ? 50 : d.subject.height;

update();
}

function update() {
svg
.selectAll(".rect-main")
.attr("x", (d) => d.x)
.attr("y", (d) => d.y)
.attr("width", (d) => d.width)
.attr("height", (d) => d.height);

svg
.selectAll(".rect-adjuster")
.attr("x", (d) => d.x + d.width - 20)
.attr("y", (d) => d.y + d.height - 20);

svg
.selectAll("text")
.attr("x", (d) => d.x + 20)
.attr("y", (d) => d.y + 20);

svg.selectAll("path").attr("d", link);

const div = document.getElementById("summary-zone");
div.innerHTML = "";
d3.select(div)
.selectAll("div")
.data(data)
.enter()
.append("div")
.text((d) => Object.entries(d).join(";\t").replaceAll(",", ":"));
}

// DOM.svg is just an Observable utility for creating an SVG node
const svg = d3
.select(DOM.svg(width, height))
.attr("style", "background: #aaaaaa");

// Create some data for the nodes

// Define connections between nodes
const links = [
// {
// source: data[0],
// target: data[1]
// },
// {
// source: data[0],
// target: data[2]
// }
];
{
const n = data.length;
for (let i = 0; i < n; ++i) {
for (let j = i; j < n; ++j) {
links.push({ source: data[i], target: data[j] });
}
}
}

// Set up the utility for generating path strings
const link = d3
.linkHorizontal()
.source(function (d) {
// Calculate the (x, y) position for the link attachment
// on the source node.
return [
d.source.x + d.source.width / 2,
d.source.y + d.source.height / 2
];
})
.target(function (d) {
return [
d.target.x + d.target.width / 2,
d.target.y + d.target.height / 2
];
});

// Set up D3's drag behavior
const drag = d3.drag().on("drag", dragged);
const dragAdjust = d3.drag().on("drag", draggedAdjust);

// Initialize the nodes

// Initilize the links between nodes
svg
.selectAll("path")
.data(links)
.enter()
.append("path")
.attr("d", link)
.style("fill", "none")
.style("stroke", "#56445D30")
.style("stroke-width", "4px");

const groups = svg.append("g").selectAll("g").data(data).enter().append("g"); // Apply the drag behaviour to all rects

groups
.append("rect")
.attr("class", "rect-main")
.attr("x", (d) => d.x)
.attr("y", (d) => d.y)
.attr("width", (d) => d.width)
.attr("height", (d) => d.height)
.style("fill", "#ffffffa0")
.style("stroke", "#56445D")
.style("stroke-width", "2px")
.call(drag);

groups
.append("rect")
.attr("class", "rect-adjuster")
.attr("x", (d) => d.x + d.width - 20)
.attr("y", (d) => d.y + d.height - 20)
.attr("width", (d) => 20)
.attr("height", (d) => 20)
.style("fill", "white")
.style("stroke", "#56445D")
.style("stroke-width", "2px")
.style("fill", (d, i) => d3.schemeTableau10[i % 10] + "50")
.call(dragAdjust);

groups
.append("text")
.text((d) => d.name)
.attr("x", (d) => d.x + 20)
.attr("y", (d) => d.y + 20)
.attr("fill", (d, i) => d3.schemeTableau10[i % 10])
.attr("style", "pointer-events: none; font-size: 20");

// This is just to tell the notebook to show the SVG.
update();
return svg.node();
}
Insert cell
{
addPanel;

data.push({
name: "panel" + data.length,
x: d3.randomInt(10, width - 10)(),
y: d3.randomInt(10, height - 10)(),
width: d3.randomInt(100, 200)(),
height: d3.randomInt(100, 200)()
});
}
Insert cell
d3 = require("d3")
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