KLineChart
KLineChart copied to clipboard
Month and day based vertical/time grid
It would be very nice if vertical/time grid is separated by month for daily data and by date for intraday data.
It's not difficult, here's the code I have in my lighter weight candlestick lib to do so by month (Feel free to use it).
chart.drawTimeGrid = () => {
const { ctx, data, geometry, width, barWd, style } = chart
const topPad = geometry.boxPrice.padding
const btmPad = geometry.boxVolume.padding
const barCnts = gen.barCountsByMonth(data, width)
const lineWd = ctx.lineWidth
for (let cnt of barCnts) {
const x = (
cnt===0 ? .5 :
cnt===width ? width - .5 :
topPad.left + (cnt + 0.5) * barWd
)
if (x > width) {
ctx.lineWidth = lineWd
return
}
const isBorder = x===.5 || x===width - .5
ctx.lineWidth = isBorder ? 1 : .5
ctx.strokeStyle = style[isBorder ? 'colorBorder' : 'colorGrid']
ctx.beginPath()
ctx.moveTo(x, topPad.top - 2.5)
ctx.lineTo(x, topPad.ht + btmPad.ht)
ctx.stroke()
}
ctx.lineWidth = lineWd
}
const gen = {}
gen.barCountsByMonth = (data=[], width, borders=true) => {
const res = borders ? [0] : []
if (!data.length)
return res
let mo = getMonth(data[0])
let cnt = 1
let _mo
for (let o of data.slice(2)) {
cnt += 1
_mo = getMonth(o)
if (mo !== _mo) {
mo = _mo
res.push(cnt)
}
}
if (borders)
res.push(width)
return res
}
const getMonth = (o={}) => {
const date = o.date || o.timestamp || o.date || o.time || o.datetime || o.ts
return (
typeof(date)==='string' && o.date[4]==='-' ? o.date.slice(5, 7)
: new Date(date).getMonth()
)
}