Public
Edited
Oct 17, 2023
2 stars
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
data = ({
nodes: [
{x: w/4, y: h/4},
{x: w/2, y: h/2, control: true},
{x: 3*w/4, y: 3*h/4}
],
links: [
{source: 0, target: 1},
{source: 1, target: 2}
]
})
Insert cell
Insert cell
Playground = ({value, connector, sweep, radius} = {}) => {
const vis = d3.create('svg')
const node = vis.node()
// avoid unintended sharing of data structures
value = _.cloneDeep(value)
vis.classed('playground', true)
vis
.attr('width', w)
.attr('height', h)
vis.append('text')
.classed('title', true)
.text(connector)
.attr('x', 10)
.attr('y', h-20)
function update() {
vis.selectAll('.link')
.data(value.links)
.join('path')
.classed('link', true)
.attr('d', d => {
let p1
let p2
if(value.nodes[d.source].control) {
p1 = value.nodes[d.target]
p2 = value.nodes[d.source]
}
else {
p1 = value.nodes[d.source]
p2 = value.nodes[d.target]
}
return corner_connectors[connector](p1, p2, {sweep: sweep, corner_radius: radius})
})

vis.selectAll('.node')
.data(d => value.nodes)
.join(
enter => enter.append('circle')
.classed('node', true)
.classed('control', d => d.control)
.call(d3.drag()
.on('drag', (event, d) => {
// d3.pointer(event, vis) does not work...
d.x = event.x
d.y = event.y
set(node, value) // set this Input value and notify
})
)
)
.attr('r', 8)
.attr('cx', d => d.x)
.attr('cy', d => d.y)
}
Object.defineProperty(node, 'value', {
get() {
return value
},
set(v) {
value = v
update()
}
})
node.value = value
return node
}
Insert cell
ex1 = Playground({value: this ? this.value : data, connector: 'straight', sweep: sweep, radius: corner_radius})
Insert cell
ex2 = Playground({value: this ? this.value : data, connector: 'square', sweep: sweep, radius: corner_radius})
Insert cell
ex4 = Playground({value: this ? this.value : data, connector: 'beveled', sweep: sweep, radius: corner_radius})
Insert cell
ex5 = Playground({value: this ? this.value : data, connector: 'rounded', sweep: sweep, radius: corner_radius})
Insert cell
multibind(ex1, ex2, ex4, ex5)
Insert cell
Insert cell
w = 300
Insert cell
h = w/1.618
Insert cell
html`<style>
.playground {
border: 4px solid white;
background: whitesmoke;
box-sizing: border-box;
}

.node {
fill: white;
stroke: black;
stroke-width: 4;
}
.node:hover {
cursor: move;
}
.control.node {
fill: purple;
stroke: purple;
opacity: 0.2;
}

.link {
fill: none;
stroke: purple;
stroke-width: 4;
stroke-linecap: round;
}

.title {
font-family: sans-serif;
fill: #777;
pointer-events: none;
}
</style>`
Insert cell
Insert cell
_ = require("lodash")
Insert cell
Insert cell
Insert cell
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