xAxis = g => g
.call(g => g.selectAll("g")
.data(months.slice(0, -1).map((date, i) => ({
date,
month: techFormat(date),
isMajor: date.getMonth() % 6 === 0,
isFirst: i === 0,
offset: date.getMonth() === 0 ? 30 : 10,
})))
.join("g")
.attr("font-size", 12)
.call(g => g.append("path")
.attr("class", (d, i) => `x-tick--line x-tick--line-${d.isMajor || i === 0 ? 'major' : 'minor'} x-tick--line-${techFormat(d.date)}`)
.attr("stroke", "#000")
.attr("stroke-opacity", 0.2)
.attr("stroke-dasharray", "2 4")
.attr("opacity", (d, i) => i === 0 || +d.isMajor)
.attr("d", (d, i) => `
M${d3.pointRadial(x(d.month), outerRadius + d.offset + (i === 0 ? 30 : 0))}
L${d3.pointRadial(x(d.month), innerRadius - 20)}
`))
.call(g => g.append("path")
.attr("id", (_, i) => `x-tick--text-path-${i}`)
.attr("stroke", "none")
.attr("fill", "none")
.attr('d', (d) => `
M${d3.pointRadial(x(d.month), outerRadius + d.offset - 8)}
A${outerRadius + d.offset - 8},${outerRadius + d.offset - 8} 0,0,1 ${d3.pointRadial(x(techFormat(d3.timeMonth.offset(d.date, 2))), outerRadius + d.offset - 8)}
`))
.call(g => g.append("text")
.attr("class", d => `x-tick--label x-tick--label-${d.isMajor ? 'major' : 'minor'} x-tick--label-${techFormat(d.date)}`)
.attr("opacity", d => +d.isMajor)
.append("textPath")
.attr("startOffset", 5)
.attr("xlink:href", (_, i) => `#x-tick--text-path-${i}`)
.text(d => d.date.getMonth() === 0 ? formatTime(d.date) : formatMonth(d.date)))
.call(g => g.append("path")
.attr("class", d => `x-tick--arc-inner x-tick--arc-inner-${d.month}`)
.attr("fill", "transparent")
.attr("stroke", "#000")
.attr("stroke-opacity", 0.2)
.attr("stroke-dasharray", "2 4")
.attr("opacity", 0)
.attr('d', (d) => {
let leftDate = d3.timeMonth.offset(d.date, -8);
if (!months.map(techFormat).includes(techFormat(leftDate))) {
const offset = d3.timeMonth.count(leftDate, months[0]);
leftDate = months[months.length - offset];
}
let rightDate = d3.timeMonth.offset(d.date, 8);
if (!months.map(techFormat).includes(techFormat(rightDate))) {
const offset = d3.timeMonth.count(months[months.length -1], rightDate);
rightDate = months[offset-1];
}
return `
M${d3.pointRadial(x(techFormat(leftDate)), innerRadius - 40)}
A${innerRadius - 40},${innerRadius - 40} 0,0,1 ${d3.pointRadial(x(techFormat(rightDate)), innerRadius - 40)}`;
}
))
)