Published
Edited
Sep 4, 2019
1 star
Insert cell
Insert cell
Insert cell
d3 = require('d3');
Insert cell
Insert cell
html`
<style>
rect {
fill: lightgray;
stroke: darkgray;
stroke-width: 2px
}
.red-rect{
width: 200px;
height:200px;
fill:red;
float:left;
}
</style>
`
Insert cell
html`
<svg height="300" width="800" id="example-1">
<rect x="500" y="10" width="50" height="20"></rect>
<rect x="150" y="40" width="100" height="10"></rect>
<rect x="100" y="120" width="500" height="120"></rect>
</svg>
`
Insert cell
Insert cell
viewof Example1A = {
let exampleSvg = d3.select('#example-1');
let aRect = exampleSvg.select('rect');
aRect.classed('red-rect', true);
return aRect;
}
Insert cell
viewof Example1B = {
///Select ALL of the rects
let exampleSvg = d3.select('#example-1');
let aRect = exampleSvg.selectAll('rect');
aRect.classed('red-rect', true);
return aRect;
}
Insert cell
Insert cell
dataArray = [{ color: 'blue', value: 5 }, { color: 'red', value: 8 }, { color: 'yellow', value: 3 }, { color: 'green', value: 9 }]

Insert cell
html`
<svg height="400" width="800" id="example-2">
</svg>
`
Insert cell
viewof Example02 = {
// Select the svg you initialized
let svg = d3.select('#example-2');
//[Update :: Enter :: Exit :: Merge]
// Use Update :: Enter :: Exit :: Merge to create circles bound to dataArray
// n.b., The circles should have a 'fill' associated with the data color,
// a radius associated with the data value, and should be regualrly
// spaced across the svg. For ease of selection assign the circles
// an empty class!
// (You will need to be able to update the data and re-run this code block!)
let circles = svg.selectAll('circle').data(dataArray); // Update
let circleEnter = circles.enter().append('circle'); // Enter
circles.exit().remove() // Exit
circles = circleEnter.merge(circles); // Merge
//Update properties of all circle according to the bound data
circles.attr('cx', (d, i) => i*100+50)
.attr('cy', 200)
.attr('fill', (d) => d.color)
.attr('r', (d) => d.value*5);
return md`**Data Binding - Enter, Exit, Merge ** *(expand)*`}

Insert cell
md`# Data Binding - Try it out!`
Insert cell
html`
<div height="400" width="800" id="your-turn">
</div>
`
Insert cell
yourDataArray = [{ color: 'purple', value: 5 }, { color: 'red', value: 8 }, { color: 'yellow', value: 3 }, { color: 'green', value: 9 }, { color: 'brown', value: 15 }]
Insert cell
{
// Use d3 to select the #your-turn div

// Append an svg element with dimensions (600, 400)
// Give it an id so you can access it in the next code block
return md`**Exercise 1:** *Initialization*`}
Insert cell
{
//Solution 1: Use Data Binding! [Update :: Enter :: Exit :: Merge]
// Select the svg you initialized
// Use Update :: Enter :: Exit :: Merge to create circles bound to dataArray
// n.b., The circles should have a 'fill' associated with the data color,
// a radius associated with the data value, and should be regualrly
// spaced across the svg. For ease of selection assign the circles
// an empty class!
// (You will need to be able to update the data and re-run this code block!)
return md`**Exercise 1.2:** *Update Scheme*`}
Insert cell
Insert cell
Insert cell
html`
<style>
.solar-system-background {
fill: #202060;
}
.orbit {
fill: none
}
</style>
`
Insert cell
Insert cell
solarSystem = [
{name: 'Mercury', diameter: 4879, meanTemperature: 167, distanceFromSun: 57.9, color: '#C0BEC7'},
{name: 'Venus', diameter: 12104, meanTemperature: 464, distanceFromSun: 108.2, color: '#F5B16B'},
{name: 'Earth', diameter: 12756, meanTemperature: 15, distanceFromSun: 149.6, color: '#24BCEA'},
{name: 'Mars', diameter: 6792, meanTemperature: -66, distanceFromSun: 227.9, color: '#FD753E'},
{name: 'Jupiter', diameter: 142984, meanTemperature: -110, distanceFromSun: 778.6, color: '#F49A30'},
{name: 'Saturn', diameter: 120596, meanTemperature: -140, distanceFromSun: 1433.5, color: '#FBDB78'},
{name: 'Uranus', diameter: 51118, meanTemperature: -195, distanceFromSun: 2872.5, color: '#88DBD1'},
{name: 'Neptune', diameter: 49528, meanTemperature: -200, distanceFromSun: 4495.1, color: '#FFAC65'},
{name: 'Pluto', diameter: 2370, meanTemperature: -225, distanceFromSun: 5906.4, color: '#6560C6'},
{name: 'Sun', diameter: 1392530, meanTemperature: 5504, distanceFromSun: 0, color: '#ffff00'}
]

Insert cell
function getRadialX(max) {
const X = Math.random() * max;
if (Math.random() > 0.5)
return X;
return -X;
}
Insert cell
function getRadialY(X, R) {
const Y = Math.sqrt(R*R - X*X);
if (Math.random() > 0.5) return Y;
return -Y;
}
Insert cell
html`
<svg height="900" width="900" id="solar-system">
<rect height=900 width=900 class="solar-system-background"></rect>
</svg>
`
Insert cell
{
let ssSvg = d3.select('#solar-system');
let sortedSolarSystem = solarSystem.sort((a,b)=> a.distanceFromSun - b.distanceFromSun);
const sun = sortedSolarSystem[0];
sortedSolarSystem = sortedSolarSystem.slice(1)
const planetSizeScale = d3.scaleLinear().domain([2370, 142984]).range([5, 20])
const distFromSunScale = d3.scalePow()
.exponent(0.1)
.domain([57.9, 5906.4])
.range([60, 400])
sortedSolarSystem.forEach(planet => {
const X = getRadialX(distFromSunScale(planet.distanceFromSun));
const Y = getRadialY(X, distFromSunScale(planet.distanceFromSun));
planet.X = X;
planet.Y = Y;
});
const solarSystemGroup = ssSvg.append('g').attr('transform', 'translate(450, 450)');

solarSystemGroup.append('circle').attr('r', 30).style('fill', sun.color);
const planets = solarSystemGroup.selectAll('.planet').data(sortedSolarSystem);
planets.join('circle')
.classed('planet', true)
.attr('r', d => planetSizeScale(d.diameter))
.attr('cx', d=> d.X)
.attr('cy', d => d.Y)
.style('fill', d => d.color);
const orbits = solarSystemGroup.selectAll('.orbit').data(sortedSolarSystem);
orbits.join(
enter => enter
.append('circle')
.classed('orbit', true)
.attr('stroke', d=> d.color)
.attr('r', d => distFromSunScale(d.distanceFromSun))
.attr('stroke-width', 1),
update => update.classed('orbit', true)
.attr('stroke', d=> d.color)
.attr('stroke-width', 1),
exit => exit.remove()
)
return sortedSolarSystem;
}
Insert cell
Insert cell
md`A recursive function is a function that call itself. `
Insert cell
Insert cell
function countdown(value, keeper) {
keeper.push(value);
if (value <= 0) { //base case or termination condition
return keeper;
} else {
return countdown(value - 1, keeper);//function calls itself
}
};
Insert cell
md`In recursion, we need a base case that checks if we terminate. In this example, we are checking if we have gotten to zero. If so, we can return the array. Otherwise, we run the function again.`
Insert cell
countdown(10, [])
Insert cell
md`# A slightly more complicated example`
Insert cell
Insert cell
Insert cell
Insert cell
function fibonacciSequence(n, sequence) {
const length = sequence.length;
if (length === n) return sequence;
if (length === 0 || length === 1)
sequence.push(1)
else
sequence.push(sequence[sequence.length-1] + sequence[sequence.length - 2])
fibonacciSequence(n, sequence);
}
Insert cell
{
const arr = []
fibonacciSequence(10, arr)
return arr;
}
Insert cell
Type JavaScript, then Shift-Enter. Ctrl-space for more options. Arrow ↑/↓ to switch modes.

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