Published
Edited
Apr 29, 2019
1 fork
9 stars
Insert cell
Insert cell
Insert cell
Insert cell
import { census } from "@uwdata/introduction-to-d3"
Insert cell
d3 = require("d3@5")
Insert cell
Insert cell
width = 600
Insert cell
height = 400
Insert cell
margin = {
return {
top: 50,
right: 50,
bottom: 50,
left: 100
}

}
Insert cell
container = d3.create('svg')
.attr('width', width + margin.left + margin.right)
.attr('height', height + margin.top + margin.bottom)
Insert cell
chart = container.append('g')
.attr('id', 'chart')
.attr('transform', `translate(${margin.left}, ${margin.top})`)
Insert cell
Insert cell
function unique(array) {
return array.filter((v, i) => array.indexOf(v) == i)
}
Insert cell
ageDomain = unique(census.map(row => row.age_group))
Insert cell
peopleDomain = [0, d3.max(census, row => row.people)]
Insert cell
sexDomain = [1, 2]
Insert cell
Insert cell
x = d3.scaleBand().rangeRound([0, width])
.padding(0.1)
.domain(ageDomain)
Insert cell
y = d3.scaleLinear()
.rangeRound([height, 0])
.domain(peopleDomain)
Insert cell
color = {
const maleColor = "#42adf4";
const femaleColor = "#ff96ca";
return d3.scaleOrdinal().range([maleColor, femaleColor]).domain(sexDomain);
}
Insert cell
Insert cell
xaxis = chart.append('g')
.attr('class', 'axis axis_x')
.attr('transform', `translate(0, ${height})`)
.call(d3.axisBottom(x))
Insert cell
d3.selectAll('.axis_x').remove()
Insert cell
yaxis = chart.append('g')
.attr('class', 'axis axis--y')
.call(d3.axisLeft(y));
Insert cell
Insert cell
container.selectAll('text').style("font-family", "sans-serif");
Insert cell
title = container.append('text')
.attr("transform", `translate(${(width+margin.left+margin.right) / 2}, 20)`)
.style("text-anchor", "middle")
.style("font-weight", 700)
.text("Census Age Group and Population by Sex")
Insert cell
// text label for the y axis
ytitle = chart.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 0 - margin.left)
.attr("x", 0 - (height / 2))
.attr("dy", "1em")
.style("text-anchor", "middle")
.text("Population");
Insert cell
// text label for the x axis
xtitle = chart.append("text")
.attr("transform", `translate(${(width/2)}, ${(height + margin.top - 10)})`)
.style("text-anchor", "middle")
.text("Age Group");
Insert cell
Insert cell
d3Legend = require('d3-svg-legend')
Insert cell
legend_auto = d3Legend
.legendColor()
.scale(color)
.labels(["Male", "Female"])
Insert cell
container.append("g")
.attr("class", "legend_auto")
.attr("transform", `translate(${width - 20}, 65)`)
.style('font-size', '12px')
.call(legend_auto)
Insert cell
Insert cell
state = {
return {
year: 1900,
sex: 2
}
};
Insert cell
function isYearAndSex(row, year, sex) {
return row.year === year && row.sex === sex;
}
Insert cell
filteredData = census.filter(row => isYearAndSex(row, state.year, state.sex))
Insert cell
Insert cell
barElements = chart.selectAll('.bar')
Insert cell
bars = barElements.data(filteredData)
Insert cell
bars.enter()
.append('rect')
.attr('class', 'bar')
.attr('x', d => x(d.age_group))
.attr('y', d => y(d.people))
.attr('width', x.bandwidth())
.attr('height', d => height - y(d.people))
.attr('fill', d => color(d.sex));
Insert cell
Insert cell
function updateChart(sex, step) {
state.sex = sex;
state.year = state.year + step;
const newYear = state.year;
const newData = census.filter(row => isYearAndSex(row, state.year, state.sex));
console.log(newData);
const bars = chart.selectAll('.bar').data(newData, d => {
if (d.year === state.year) {
return d.age_group - step;
} else {
return d.age_group;
}
});
bars.enter().append('rect')
.attr('class', 'bar')
.attr('x', d => x(d.age_group))
.attr('y', d => y(0))
.attr('width', x.bandwidth())
.attr('height', 0)
.attr('fill', d => color(d.sex))
.transition('enter-transition')
.duration(500)
.attr('y', d => y(d.people))
.attr('height', d => height - y(d.people));
bars.transition('update').duration(500).attr('x', d => x(d.age_group))
.attr('y', d => y(d.people))
.attr('width', x.bandwidth())
.attr('height', d => height - y(d.people))
.attr('fill', d => color(d.sex));
// Step 5. Exit.
bars.exit()
.transition('exit-transition')
.duration(500)
.attr('height', 0)
.attr('y', y(0))
.remove();
document.getElementById('curr-year-naive').textContent = state.year;

}
Insert cell
container.node()
Insert cell
viewof buttons = {
const decrement = html`<button id="decrement">&lt;&lt;</button>`;
decrement.onclick = () => updateChart(state.sex, -10);
const increment = html`<button id="increment">&gt;&gt;</button>`;
increment.onclick = () => updateChart(state.sex, 10);
const switchSexButton = html`<button>switch sex</button>`;
switchSexButton.onclick = () => updateChart(state.sex === 2 ? 1 : 2, 0);
const view = html`
<div style="width: 800px; text-align: center; font-family: sans-serif">
${decrement}
<span id="curr-year-naive">
${state.year}
</span>
${increment}
<br/>
${switchSexButton}
</div>
`
return view;
}
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