Published
Edited
Jun 17, 2020
Insert cell
Insert cell
chart = draw()
Insert cell
dataAll = d3.csv(
"https://raw.githubusercontent.com/statistikZH/economy_SHAB/master/Economy_SHAB.csv?token=ALJEHNRXJP32QSN53TQQDKC66LTXK"
)
Insert cell
cantons = getDistinct(dataAll, "location")
Insert cell
function getDistinct(data, value) {
let retData = [];
let flags = [];
for(let i=0; i<data.length; i++) {
if( flags[data[i][value]]) continue;
flags[data[i][value]] = true;
retData.push(data[i][value]);
}
return retData;
}
Insert cell
filteredData = Object.assign(
d3
.csvParse(await FileAttachment("Economy_SHAB.csv").text(), d3.autoType)
.map(({ date, location, value }) => ({
date,
location,
value
})),
{ y: "Anzahl" }
)
Insert cell
height = 500
Insert cell
margin = ({top: 20, right: 30, bottom: 30, left: 40})
Insert cell
lineColor = "#fdc032"
Insert cell
areaColor = "#fff3d6"
Insert cell
lineWidth = 1.5
Insert cell
lineCurve = "curveStepAfter"
Insert cell
circleRadius = 5
Insert cell
d3 = require("d3@5", "d3-array@^2.2")
Insert cell
x = d3
.scaleTime()
.domain(d3.extent(cumulativeByDate, d => d.date))
.range([margin, width - margin])
Insert cell
y = d3
.scaleLinear()
.domain([0, filteredData.length])
.range([height - margin, margin])
Insert cell
line = d3
.line()
.x(d => x(d.date))
.y(d => y(d.value))
.curve(d3[lineCurve])
Insert cell
area = d3.area()
.x(d => x(d.date))
.y1(d => y(d.value))
.y0(d => y(0))
.curve(d3[lineCurve])
Insert cell
xAxis = g => g
.attr("transform", `translate(0,${height - margin})`)
.call(d3.axisBottom(x))
Insert cell
yAxis = g => g
.attr("transform", `translate(${margin},0)`)
.call(d3.axisLeft(y))
Insert cell
function draw() {
// Create a blank SVG object
const svg = d3.select(DOM.svg(width, height));
// Draw an area plot
svg.append("path")
.datum(cumulativeByDate)
.attr("fill", areaColor)
.attr("d", area);

// Draw a line on top of the area p lot
svg.append("path")
.datum(cumulativeByDate)
.attr("fill", "none")
.attr("stroke", lineColor)
.attr("stroke-width", lineWidth)
.attr("d", line);

// Plot a circle marking the final tweet
svg.append("circle")
.attr("cx", x(filteredData.endDate))
.attr("cy", y(filteredData.length))
.attr("fill", lineColor)
.attr("r", circleRadius);
// Draw the x axis
svg.append("g")
.call(xAxis);

// Draw the y axis
svg.append("g")
.call(yAxis);
// Return the chart for rendering
return svg.node();
}
Insert cell
groupByDate = d3
.nest()
.key(d => dateFormatter(d.date)) // Groups on day
.rollup(d => d.length) // Counts how many records are in each date group
.entries(filteredData) // Passes in the current tweet list for grouping and counting
Insert cell
groupByLocation = d3.group(filteredData, d => d.location)
Insert cell
dateLookup = groupByDate.reduce(
(lookup, date) => ((lookup[date.key] = date.value), lookup),
{}
)
Insert cell
dateFormatter = d3.timeFormat("%Y-%m-%d")
Insert cell
cumulativeByDate = {
// Start the running count at zero.
let runningCount = 0;
// Loop through all the dates in the current filtered Tweet list
return filteredData.dateRange.map(d => {
// Use the lookup and the date formatter to pull the count for each day.
let dateCount = dateLookup[dateFormatter(d)] || 0; // <-- If it isn't in the lookup, set it to zero.
// Add each day's tally to the running count
runningCount += dateCount;
// Return a new datum for this date with the cumulative tally instead of that day's count.
return { date: d, value: runningCount };
});
}
Insert cell

One platform to build and deploy the best data apps

Experiment and prototype by building visualizations in live JavaScript notebooks. Collaborate with your team and decide which concepts to build out.
Use Observable Framework to build data apps locally. Use data loaders to build in any language or library, including Python, SQL, and R.
Seamlessly deploy to Observable. Test before you ship, use automatic deploy-on-commit, and ensure your projects are always up-to-date.
Learn more