Published
Edited
Feb 18, 2022
Insert cell
Insert cell
Insert cell
dataset = d3.csvParse(await FileAttachment("data.csv").text(), rowConverter);
Insert cell
rowConverter = (row) => {
// Modify code here for row conversion
const form = d3.timeParse("%Y-%m-%d");
return {date:form(row['date']),hours_of_sleep: +(row['hours_of_sleep'])};
}
Insert cell
w = 600
Insert cell
h = 500
Insert cell
makeChart()
Insert cell
function makeChart() {
// sort by date ascending
dataset.sort((a,b) => a.date - b.date);

console.log(dataset);

const numDaysSlider = html`
<input id="numDaysSlider" type="range" min="1" max="7" value="7"></input>
`;
const daysText = html`
<span id="daysText">7</span>
`;
const svg = d3.create('svg')
.attr('width', w)
.attr('height', h);

let endDate = new Date(d3.max(dataset, d => d.date));
endDate.setDate(endDate.getDate() + 1);
const xScale = d3.scaleTime()
.domain([d3.min(dataset,d=>d.date), endDate])
.rangeRound([80, w - 80]);
const yScale = d3.scaleLinear()
.domain([12,0])
.rangeRound([20,h-20]);

const colorScale = d3.scaleLinear()
.domain([0,12])
.range(['#f90', '#f00']);
const xAxis = d3.axisBottom(xScale);
xAxis.ticks(7, "%a");
const yAxis = d3.axisLeft(yScale);
const xAxisGroup = svg.append('g')
.attr('class','axis')
.attr('transform', `translate(0, ${h - 20})`)
.call(xAxis);
const yAxisGroup = svg.append('g')
.attr('class', 'axis-left')
.attr('transform', `translate(80,0)`)
.call(yAxis);

svg.selectAll("rect")
.data(dataset, d=>d.date)
.join(enter => enter.append('rect')
.attr('x', d => xScale(d.date))
.attr('y', d=> h-yScale(d.hours_of_sleep)-20)
.attr('width', (w-160)/7)
.attr('height', d => yScale(d.hours_of_sleep))
.attr('fill', d => colorScale(d.hours_of_sleep)))
function updateGraph() {
const numDays = +numDaysSlider.value;
daysText.innerText = numDays;

const subSection = dataset.slice(7-numDays,7);
const axScale = d3.scaleTime()
.domain([d3.min(subSection,d=>d.date), endDate])
.rangeRound([80, w - 80]);
const ayScale = d3.scaleLinear()
.domain([12,0])
.rangeRound([20,h-20]);
svg.selectAll('rect')
.data(subSection, d => d.date)
.join(
enter => enter.append('rect')
.attr('x', d => xScale(d.date) + 800)
.attr('y', d=> h-yScale(d.hours_of_sleep)-20)
.attr('width', (w-160)/(numDays))
.attr('height', d => yScale(d.hours_of_sleep))
.attr('fill', d => colorScale(d.hours_of_sleep)),
update => update.transition()
.attr('x', d => axScale(d.date))
.attr('width', (w-160)/(numDays)),
exit => exit.transition()
.attr('x', d=>xScale(d.date) - 800));

const axAxis = d3.axisBottom(axScale);
axAxis.ticks(numDays, "%a");
const ayAxis = d3.axisLeft(ayScale);

xAxisGroup.call(axAxis);
yAxisGroup.call(ayAxis);
}
numDaysSlider.addEventListener('input', updateGraph);
return html`
<h1>Sleep</h1>
<label>Days to Show</label>
${numDaysSlider}
${daysText}
<div class='chart-div'>
${svg.node()}
</div>
<!-- add any necessary HTML here, either directly or using the pattern
set by numDaysSlider & daysText
-->
`;
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
d3 = require("d3@7")
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