Public
Edited
Mar 17, 2023
Insert cell
Insert cell
test1 = {
const svg = d3.create('svg')
.attr('viewBox', [-width/2, -width/4, width, width/2])

const side_length = 200
const square = svg.append('rect')
.attr('x', -side_length/2)
.attr('y', -side_length/2)
.attr('width', side_length)
.attr('height', side_length)
.attr('r', 100)
.style('fill', 'black')

const small_circle = svg.append('circle')
.attr('cx', 0)
.attr('cy', 0)
.attr('r', 30)
.style('fill', 'red')

function update() {
const circle_out = d3.transition()
const square_rotate = circle_out.transition().duration(1000)
const circle_in = square_rotate.transition().duration(250)
small_circle.transition(circle_out)
.attr('cx', 300)
square.transition(square_rotate)
.attr('transform', `rotate(${d3.randomUniform(0,360)()})`)
small_circle.transition(circle_in)
.attr('cx', 0)
}

Object.assign(svg.node(), {update})
return svg.node()
}
Insert cell
Insert cell
PopOutCircle = class {
constructor(options = {}) {
this.element = d3.create('svg:circle')
.attr('r', 30)
.style('fill', 'red')
.attr('cx', 0)
.attr('cy', 0)

this.popOutDuration = options.popOutDuration || 250;
this.restoreDuration = options.restoreDuration || 250;
this.popOutDelay = options.popOutDelay || 0;
this.restoreDelay = options.restoreDelay || 0;
}

popOut() {
// console.log('started')
let popOutTransition = d3.transition()
.duration(this.popOutDuration)
.delay(this.popOutDelay)
this.element.transition(popOutTransition)
.attr('cx', 300)
return popOutTransition
}

restore() {
// console.log('restoring')
let restoreTransition = d3.transition()
.delay(this.restoreDelay)
.duration(this.restoreDuration)
this.element.transition(restoreTransition)
.attr('cx', 0)
return restoreTransition
}

node() {
return this.element.node()
}
}
Insert cell
test2 = {
const svg = d3.create('svg')
.attr('viewBox', [-width/2, -width/4, width, width/2])

const side_length = 200
const square = svg.append('rect')
.attr('x', -side_length/2)
.attr('y', -side_length/2)
.attr('width', side_length)
.attr('height', side_length)
.attr('r', 100)
.style('fill', 'black')

let circle = new PopOutCircle()
// return circle
svg.append(() => circle.element.node())

function rotate_square(transition) {
square.transition(transition)
.attr('transform', `rotate(${d3.randomUniform(0,360)()})`)

return transition
}
function update() {
let popOutTransition = circle.popOut()
popOutTransition.end().then(() => {
const square_rotate = d3.transition()
.duration(1000)
rotate_square(square_rotate)
square_rotate.end().then(() => circle.restore())
})
// popOutTransition.on('end', () => rotate_square(square_rotate))
// square_rotate.on('end', () => circle.restore())
}

Object.assign(svg.node(), { update })
return svg.node()
}
Insert cell
test2.update()
Insert cell
Insert cell
test3 = {
const svg = d3.create('svg')
.attr('viewBox', [-width/2, -width/4, width, width/2])

const side_length = 200
const square = svg.append('rect')
.attr('x', -side_length/2)
.attr('y', -side_length/2)
.attr('width', side_length)
.attr('height', side_length)
.attr('r', 100)
.style('fill', 'black')

const popOutDuration = 1000
const restoreDuration = 250
const squareRotationDuration = 1000
let circle = new PopOutCircle({
popOutDuration: popOutDuration,
restoreDuration: restoreDuration,
restoreDelay: popOutDuration + squareRotationDuration
})
svg.append(() => circle.node())

function update() {
circle.popOut()
square.transition()
.delay(popOutDuration)
.duration(squareRotationDuration)
.attr('transform', `rotate(${d3.randomUniform(0,360)()})`)
circle.restore() // this won't work because it's on the same element?
// or it will work and I understand nothing??
// it works because you can't have multiple *simultaneous* transitions on a single element. You can have multiple temporally-separate ones.
}

Object.assign(svg.node(), {update})

return svg.node()
}
Insert cell
Insert cell
test4 = {
const svg = d3.create('svg')
.attr('viewBox', [-width/2, -width/4, width, width/2])

const small_circle = svg.append('circle')
.attr('cx', 0)
.attr('cy', 0)
.attr('r', 30)
.style('fill', 'red')

function update() {
const transition1 = d3.transition()
.duration(1000)

const transition2 = d3.transition()
.delay(1000)
.duration(500)

const transition3 = d3.transition()
.delay(1500)
.duration(250)

small_circle.transition(transition1)
.attr('cx', 300)

small_circle.transition(transition2)
.attr('cy', -50)

small_circle.transition(transition3)
.attr('cx', 0)
.attr('cy', 0)
}

Object.assign(svg.node(), {update})
return svg.node()
}
Insert cell
test4.update()
Insert cell
test5 = {
}
Insert cell
run = {
while(true) {
yield
await Promises.delay(3000)
}
}
Insert cell
{
run
test1.update()
test2.update()
test3.update()
}
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