Published
Edited
Mar 28, 2019
4 stars
Insert cell
Insert cell
Insert cell
chart = {
const svg = d3.select(DOM.svg(width, 100))
svg.attr('id', 'svgGeneralUpdatePattern')
svg
.append('g')
.attr('id', 'symbols')
.attr('transform', 'translate(13, 50)')
return svg.node()
}
Insert cell
Insert cell
// Equivalent HTML as above
// chart = html `
// <svg id="svgGeneralUpdatePattern" width=${width} height="100">
// <g id="symbols" transform="translate(13, 50)">
// </g>
// </svg>
// `
Insert cell
aToZ='ABCDEFGHIJKLMNOPQRSTUVWXYZ'.split('');
Insert cell
Insert cell
myData = {
// Run this block after the chart is initialized
chart
// Initialize myData
let myData = 'ACEGIKMOQSUWY'.split('');
while (true) {
if (myData.length <= 13) {
const lettersToChooseFrom = aToZ.filter(letter => !myData.includes(letter))
const letterToBeAdded = lettersToChooseFrom[Math.floor(Math.random() * lettersToChooseFrom.length)]
myData.push(letterToBeAdded)
myData.sort()
} else if (myData.length >= 14) {
const indexOfLetterToBeRemoved = Math.floor(Math.random() * myData.length)
myData.splice(indexOfLetterToBeRemoved, 1)
}

yield Promises.tick(1750, myData);
}
}
Insert cell
Insert cell
updateGraph = {

// First do data join and get the currently existing elements
let existingElements =
d3.select('#svgGeneralUpdatePattern')
.select('#symbols')
.selectAll('#symbol')
.data(myData, (d) => d)
// The new/entering elements
let newElements = existingElements.enter()
// The unused/exiting elements
let unusedElements = existingElements.exit()
// Move the existing elements to the correct location with a transition
if (newElements.size() > 0) {
// New elements will be added. Move existing elements quickly to make space.
existingElements
.transition(quickTransition)
.attr('transform', (d,i) => `translate(${i*30}, 0)`)
} else if (unusedElements.size() > 0) {
// Elements will be removed. Delay moving existing elements.
existingElements
.transition(quickTransition)
.delay(750)
.attr('transform', (d,i) => `translate(${i*30}, 0)`)
}
// If new <g id="symbol"></g> containers are needed to match data length, create them
// Create new containers above visible area then 'drop' to desired location
newElements
.append('g')
.attr('id', 'symbol')
.attr('transform', (d,i) => `translate(${i*30}, -100)`)
.each(addCircleAndText)
.transition() // move containers to visible area with bouncing effect
.delay(250) // wait for existing elements to move aside
.duration(750)
.ease(d3.easeBounce)
.attr('transform', (d,i) => `translate(${i*30}, 0)`)
.selectAll('circle') // change circle fill color from SeaGreen to orange
.transition()
.duration(500)
.ease(d3.easeLinear)
.style('fill', 'orange')
// If there is any unused <g id="symbol"></g> containers, remove them
// Move unused containers off the visible area before removing them
unusedElements
.selectAll('circle') // change circle fill color from orange to Crimson
.transition()
.duration(500)
.ease(d3.easeLinear)
.style('fill', 'Crimson')
unusedElements
.transition() // move containers off the page before removing them
.delay(500) // wait for color change finish
.duration(1000)
.ease(d3.easeBounce)
.attr('transform', (d,i)=> `translate(${i*30}, 100)`)
.remove()
}
Insert cell
// Helper function to add a circle and text to each new container
addCircleAndText = (d, i, nodes) => {
let container = d3.select(nodes[i])
container
.append('circle')
.attr('r', 13)
.attr('cx', (d,i) => i*30)
.style('fill', 'SeaGreen')

container
.append('text')
.attr('transform', "translate(0,6)")
.attr('text-anchor', 'middle')
.style('font-family', 'sans-serif')
.style('fill', 'white')
.text(d)
}
Insert cell
quickTransition =
d3.transition('quickTransition')
.duration(250)
.ease(d3.easeLinear);
Insert cell
import { range } from '@mbostock/generator-cells-functions-and-objects'
Insert cell
d3 = require("d3@5")
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