69 lines
1.8 KiB
JavaScript
69 lines
1.8 KiB
JavaScript
import {
|
|
formatMedicationLabel,
|
|
formatMedicationTooltip,
|
|
xPixelForMedicationTime,
|
|
} from '@/composables/chartMedications'
|
|
|
|
const HIT_TOLERANCE_PX = 8
|
|
const MARKER_COLOR = '#7c3aed'
|
|
|
|
export const medicationMarkerPlugin = {
|
|
id: 'medicationMarkers',
|
|
|
|
afterDraw(chart, _args, options) {
|
|
const medications = options?.medications ?? []
|
|
const timestamps = options?.timestamps ?? []
|
|
if (!medications.length || !timestamps.length) return
|
|
|
|
const { ctx, chartArea } = chart
|
|
if (!chartArea) return
|
|
|
|
const hits = []
|
|
ctx.save()
|
|
ctx.strokeStyle = MARKER_COLOR
|
|
ctx.fillStyle = MARKER_COLOR
|
|
ctx.lineWidth = 1.5
|
|
ctx.setLineDash([5, 4])
|
|
ctx.font = '10px system-ui, sans-serif'
|
|
|
|
for (const med of medications) {
|
|
const x = xPixelForMedicationTime(med.administeredAt, timestamps, chartArea)
|
|
if (x == null) continue
|
|
|
|
ctx.beginPath()
|
|
ctx.moveTo(x, chartArea.top)
|
|
ctx.lineTo(x, chartArea.bottom)
|
|
ctx.stroke()
|
|
|
|
const label = formatMedicationLabel(med)
|
|
ctx.setLineDash([])
|
|
ctx.fillText(label, Math.min(x + 3, chartArea.right - 40), chartArea.top + 11)
|
|
hits.push({ med, x })
|
|
}
|
|
|
|
ctx.restore()
|
|
chart.$medicationHits = hits
|
|
},
|
|
|
|
afterEvent(chart, args) {
|
|
const event = args.event
|
|
if (!event || (event.type !== 'mousemove' && event.type !== 'mouseout')) return
|
|
|
|
if (event.type === 'mouseout') {
|
|
chart.canvas.title = ''
|
|
chart.canvas.style.cursor = 'default'
|
|
return
|
|
}
|
|
|
|
const hits = chart.$medicationHits ?? []
|
|
const near = hits.find(h => Math.abs(h.x - event.x) <= HIT_TOLERANCE_PX)
|
|
if (near) {
|
|
chart.canvas.title = formatMedicationTooltip(near.med)
|
|
chart.canvas.style.cursor = 'help'
|
|
} else {
|
|
chart.canvas.title = ''
|
|
chart.canvas.style.cursor = 'default'
|
|
}
|
|
},
|
|
}
|