# Adding custom paths in Plot (replicating Calendar in Plot)

I am using this calendar version for one of my scripts and I took the small challenge of re-writing it in Observable Plot

``````Plot.plot({
height: 150,
width,
x: {
axis: null,
},
y: {
tickFormat: d => Plot.formatWeekday("en", "narrow")(-((d + 6) % 7)),
tickSize: 0,
ticks: 7
},
fy: {
// reverse: true
},
marks: [
Plot.rect(log, {
x1: d => d3.timeMonday.count(d3.utcYear(d[0]), d[0]),
x2: d => d3.timeMonday.count(d3.utcYear(d[0]), d[0]) +1,
// i => (i + 6) % 7
y1: d => -((d[0].getUTCDay() + 6) %7 + d[3]/d[2] - 0.5),
y2: d => -((d[0].getUTCDay() + 6) % 7 + 1/[d[2]] + d[3]/d[2] - 0.5),
fy: d => d[0].getUTCFullYear(),
fill: (d, i) => d[1],
title: (d, i) => `\${i} \${d[0]} \${d[1]} \${d3.timeMonday.count(d3.utcYear(d[0]), d[0])}`,
inset: 0.5
}),
Plot.text(d3.utcMonths(log[0][0], log[log.length -1][0]), {
x: d => d3.timeMonday.count(d3.utcYear(d), d) + 0.5,
y: d => 0,
dy: -15,
text: d3.utcFormat('%b')
}),
]
})
``````

This works (might be improved sure), but I now wanted to add the path that separates the months and I believe I am reaching the limit of what is possible with Observable Plot.

Any idea on how to do that?

You may want to look at this one for inspiration. I think that part is quite tricky.

Hereâ€™s my take:

I did this by implementing a custom mark:

``````class MonthLine extends Plot.Mark {
static defaults = {stroke: "white", strokeWidth: 3};
constructor(data, options = {}) {
const {x, y} = options;
super(data, {x: {value: x, scale: "x"}, y: {value: y, scale: "y"}}, options, MonthFrame.defaults);
}
render(index, {x, y}, {x: X, y: Y}, dimensions) {
const {marginTop, marginBottom, height} = dimensions;
const dx = x.bandwidth(), dy = y.bandwidth();
return htl.svg`<g fill=none stroke=\${this.stroke} stroke-width=\${this.strokeWidth}>
\${Array.from(index, (i) => htl.svg`<path d=\${
Y[i] > marginTop + dy
? `M\${X[i] + dx},\${marginTop + dy}V\${Y[i]}h\${-dx}`
: `M\${X[i]},\${marginTop + dy}`}V\${height - marginBottom}>`)}
</g>`;
}
}
``````

We havenâ€™t documented how to implement custom marks yet, but as the code above hints, itâ€™s possible! In this case weâ€™re using the x and y scales provided by plot to render an SVG path element.

1 Like

brilliant, this is exactly what I wished it was possible!

Thank you!

1 Like

Weird, I am trying @mbostock solution, but apparently `x.bandwidth` not defined. It looks like in your example the type of the x is `band` and in my example is `linear`. I will look into this.

Yes, my code assumes that x and y are band scales; if you use linear scales youâ€™ll need to make some adjustments.