So, I've given up on making a word-cloud, but I have managed to make it rain words!
Lots of things have come together all at once to make this work:
ES6 Modules
I've at last cracked ES6 Modules (which had been baffling me a bit in VizHub)
- IMPORTANT!*
- When importing modules don't forget the ./ in the import module name!
import { select } from 'd3';
import { appendRandomWord } from './random'; // './*' !
import { color } from './color'
import { words } from './data';
Data 'munging'
- Using map to add a (random) 'fill' property to the data
Color Scale
Using…
- scaleSequential
- with an (unnecessarily explicit) domain of [0,1]
- which is great for random colors
- (Math.random delivers numbers in the range [0,1])
- interpolateRainbow
- which is a range of colors across the rainbow
- a custom color function to pass the value to the scale to convert it to a color
- and choosing the necessary property
- .attr('fill', d => color(d.fill) )
Animation
At last!
Using…
- .enter() - to add text objects
- .transition() - to animate the movement
- .duration() - to control the
- setTimeout - (recursive) to dynamically add data to the array
- better:
- setInterval - to repeatedly add data to the array without recursion
- even better:
- setInterval + setTimeout with clearInterval - to play an animation for a fixed duration
- the best yet:
- a custom function to animate at a given rate for a given time:
function playAnimation (animationFunc,rateMS,durationMS)
svg text elements
- animating, appending text elements and defining their content
svg.selectAll('text')
.data(…)
.enter()
.append('text')
:
.text(d => d.text)
- anchoring text centrally using the svg-attributes
.attr('text-anchor','middle')
.attr('dominant-baseline','middle')
Parameterisation
- variables for many aspects of the
- a location function to decide where the words are going to land
- Next steps:
- Rework the whole chart as a function
DON'Ts
It's been a real steep curve learning what you don't need from the (sometimes very old or mediorchre) examples you find (out there ... not the ones from [Curran]).
- You don't need to wrap the .transition()-code in a .call(…)!
- So, NOT this:
- .call(e => e.transition() … );
- You don't need to pass a duration parameter to the .transition() function
- So, NOT this:
- .call(e => e.transition(t)