Published
Edited
Jul 18, 2022
4 stars
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
function decorate(event, mesh, list) {
invalidation.then(() =>mutable disp = [])

let node = this,
nodes = mesh.filter((_,i,n)=> n[i].classList.contains('node')),
edges = mesh.filter((_,i,n)=> n[i].classList.contains('edge')),
range = d3.selectAll(list);
if (event.type == 'pointerdown' && (node.attr('id') == mesh.attr('id'))) {
mesh.attr('clicked')
? mesh.attr('clicked', null )
: mesh.attr('clicked', true )
} else if (event.type == 'pointerleave') {
mesh.attr('active', node.attr('clicked'))
} else if (event.type == 'pointerenter') {
mesh.attr('active', true )
}

let it = mesh.attr('clicked') ?? mesh.attr('active')
let colorVal = Math.log( // color by focus node
parseInt( node.select("title").text().slice(1)) + 1 ) % 1,
color = d3.interpolateRainbow(1-colorVal),
style = { fill: d3.interpolate(color, 'white')(0.7),
fillOpacity: 1, stroke: color, strokeWidth:4 },
annul = { fill: null, } ;
let shape = nodes.selectAll("path,polygon"),
point = edges.selectAll("polygon"),
paths = edges.selectAll("path"),
group = d3.selectAll([...shape,...point]);
tween(group,{...style})
tween(paths,{...style,...annul})

if( [...mesh].length ) {
var { x, y, width:w, height:h } = node.node().getBBox();
var cx = x + w/2, cy = y + h/2;
node.transition().duration(200)
.ease(d3.easeBackOut.overshoot(4))
.style('transform', it ? `translate(${cx}px, ${cy}px)
scale(${1.1}) translate(${(-cx)}px, ${(-cy)}px)`: null)

mesh.transition().delay(parseInt(Math.random()*100)).duration(200)
.ease(d3.easeBackOut.overshoot(6))
.style('transform', it ? `translate(${cx}px, ${cy}px)
scale(${1.05}) translate(${(-cx)}px, ${(-cy)}px)`: null)
}

function tween(target, map) {
let roll = target.transition().duration(75);
return Object.entries(map).reduce((pool, [key, val]) => {
let stylise = tgt => tgt.style(kebab(key), it ? val+'' : null);
return pool ? stylise(pool) : stylise(roll)
} , roll ) }

function kebab (str) {
return str.split('').map((char, i) => {
return char.toUpperCase() === char
? `${i !== 0 ? '-' : ''}${char.toLowerCase()}`
: char }).join('') }

}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
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