chart = {
const svg = d3.create('svg')
.attr('width', width, height + margin.top + margin.bottom)
.style("font", "10px sans-serif")
.style("width", width)
.style("height", height + margin.top + margin.bottom)
const year = svg.selectAll("year")
.data(years)
.join("g")
.attr("class", d => yearClass(d))
.attr("transform", (d, i) => `translate(${(yearWidth + yearPadding) * i + margin.left}, ${margin.top})`)
year.append("text")
.attr("x", cellSize/2)
.attr("dx", "-.2em")
.attr("y", 0)
.attr("dy", "-2em")
.attr("font-weight", "bold")
.text(d => d.key);
year.append("g")
.attr("text-anchor", "middle")
.selectAll("text")
.data(d => d.values.filter(d => d.datetime.getHours() == 0))
.join("text")
.attr("x", d => d.datetime.getMonth() * cellSize + cellSize/2)
.attr("y", 0)
.attr("dy", "-.5em")
.text(monthLetter);
year.append("g")
.selectAll("rect")
.data(d => d.values)
.join("rect")
.attr("width", cellSize - 1)
.attr("height", cellSize - 1)
.attr("x", d => d.datetime.getMonth() * cellSize)
.attr("y", d => d.datetime.getHours() * cellSize)
.attr("fill", d => (d.value === undefined) ? color(m(0)) : color(m(d.value)))
.attr("class", d => cellClass(d))
.on("mouseover", handleMouseover)
.on("mouseout", handleMouseout)
.append("title")
.text(d => getTitle(d));
return svg.node();
}