Published
Edited
May 4, 2021
1 star
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
comparisonChart = {
const svg = d3.select(DOM.svg(dimens.width, dimens.height))
.style("width", dimens.width)
.style("height", dimens.height)
.style("font", "10px sans-serif");

let verticalOffset = dimens.marginTop;
const monthNames = ["January", "February", "March", "April", "May", "June",
"July", "August", "September", "October", "November", "December"];
for (let month of ['3', '4']) {
let xOffset = dimens.marginLeft;
addLabel(svg, xOffset-(dimens.marginLeft*0.5), verticalOffset, monthNames[parseInt(month)-1]+" 2020")
addLabel(svg, xOffset-(dimens.marginLeft*0.5)+440, verticalOffset, monthNames[parseInt(month)-1]+" 2021")
verticalOffset += 40
for (let day of [...Array((month=='3') ? 31 : 30).keys()]) {
const dayData = dataByYearMonth.get('20').get(month).get((day+1).toString());
addChart(svg, xOffset+((day%7)*dimens.chartWidth),
verticalOffset+(Math.floor(day/7)*dimens.chartWidth), dayData);
}
for (let day of [...Array((month=='3') ? 31 : 30).keys()]) {
const dayData = dataByYearMonth.get('21').get(month).get((day+1).toString());
addChart(svg, xOffset+440+((day%7)*dimens.chartWidth),
verticalOffset+(Math.floor(day/7)*dimens.chartWidth), dayData);
}
verticalOffset += 330;
}
return svg.node();
}
Insert cell
Insert cell
addLabel = (svg,x,y,text) => {
svg.append("g")
.style("font", "24px sans-serif")
.style("font-weight", "bold")
.attr("transform", `translate(${x}, ${y})`)
.append("text")
.text(text)
}
Insert cell
addChart = (svg,x,y,data) => {
svg.append("g")
.attr("transform", `translate(${x}, ${y})`)
.selectAll("g")
.data(d3.stack().keys(["wind_speed","extra_gust"])(data))
.join("g")
.attr("fill", d => z(d.key))
.selectAll("path")
.data(d => d)
.join("path")
.attr("d", arc);
}
Insert cell
averages = d3.rollup(data, v => d3.mean(v, d => d.wind_speed), d => d.year);
Insert cell
dataByYearMonth = d3.group(data, d => d.year, d => d.month, d => d.day)
Insert cell
data = {
const rawData = await FileAttachment("KBOS-historical-temps@2.csv").csv()
return rawData.map(d => ({
...d,
year: d['date'].split("/")[2],
month: d['date'].split("/")[0],
day: d['date'].split("/")[1],
extra_gust: d3.max([0, d['wind_gust'] - d['wind_speed']]),
}));
}
Insert cell
arc = d3.arc()
.innerRadius(d => y(d[0]))
.outerRadius(d => y(d[1]))
.startAngle(d => x(d.data.hour))
.endAngle(d => x(d.data.hour) + x.bandwidth())
.padRadius(dimens.innerRadius)
Insert cell
x = d3.scaleBand()
.domain(data.map(d => d.hour))
.range([dimens.startAngle, dimens.endAngle])
.align(0)
Insert cell
// This scale maintains area proportionality of radial bars
y = d3.scaleRadial()
.domain([0, 60])//d3.max(data, d => d.wind_gust)])
.range([dimens.innerRadius, dimens.outerRadius])
Insert cell
z = d3.scaleOrdinal()
.domain(["wind_speed","extra_gust"])//.range(["#DB004C", "#8CCBFF", "#FF3700"])
.range(["#69D2E7", "#E0E4CC"])
Insert cell
dimens = {
return {
innerRadius:2, outerRadius:30,
chartHeight:60, chartWidth:60,
marginTop:50, marginLeft: 50,
width:900, height:800,
startAngle:-0.95*Math.PI, endAngle:0.95*Math.PI,
}
}
Insert cell
d3 = require("d3@6")
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