class BBTimelineBackgroundCanvas extends BBTimelineCanvas { constructor(parentEl, el) { super(parentEl, el); const a = this; a.Margin = 0; a.StepHeight = 0; a.NoStep = 0; a.initialiseComponents(); } initialiseComponents() { super.initialiseComponents(); const a = this; a.Margin = (a.Parent.Marker.BorderWidth * 2); a.StepHeight = a.Parent.Marker.Width + a.Margin; a.NoStep = Math.floor(a.GraphRectangle.H / a.StepHeight); a.Invalidate(); } get GraphRectangle() { const a = this; if (a.Parent.XAxis.Position == 'top') { return { X: a.ClientRectangle.X, Y: (a.ClientRectangle.Y + a.XAxisHeight), W: a.ClientRectangle.W, H: (a.ClientRectangle.H - a.XAxisHeight) }; } else { return { X: a.ClientRectangle.X, Y: a.ClientRectangle.Y, W: a.ClientRectangle.W, H: (a.ClientRectangle.H - a.XAxisHeight) }; } } get XAxisHeight() { const a = this; const labelSize = a.measureText(a.Parent.Axis.Font, "0"); return labelSize.H + a.Parent.Axis.LabelSpacing + (a.Parent.XAxis.DayLineHeight * 2); } get XAxisPositions() { const a = this; const endPosX = (a.GraphRectangle.X + a.GraphRectangle.W); let result = []; let x = a.GraphRectangle.X; let date = a.Parent.ConvertToDate(a.Parent.ShowDate); // Rollback one day date.setDate(date.getDate() - 1); while (true) { if (x >= endPosX) { break; } result.push({ Date: a.Parent.DateToInternalString(date), X: x }); x += (a.Parent.XAxis.HourLineSpace * a.Parent.XAxis.NoPartPerDay); date.setDate(date.getDate() + 1); } return result; } Invalidate() { const a = this; a.Clear(); a.drawAxis(); a.drawXAxisTicks(); a.drawXAxisLabels(); if (a.Parent.Debug) a.drawRectangle(a.ClientRectangle, "red"); if (a.Parent.Debug) a.drawRectangle(a.GraphRectangle, "red"); } drawAxis() { const a = this; a.CTX.beginPath(); if (a.Parent.XAxis.Position == 'top') { a.CTX.moveTo(a.GraphRectangle.X, (a.GraphRectangle.Y + a.GraphRectangle.H)); a.CTX.lineTo(a.GraphRectangle.X, a.GraphRectangle.Y); a.CTX.lineTo((a.GraphRectangle.X + a.GraphRectangle.W), a.GraphRectangle.Y); } else { a.CTX.moveTo(a.GraphRectangle.X, a.GraphRectangle.Y); a.CTX.lineTo(a.GraphRectangle.X, (a.GraphRectangle.Y +a.GraphRectangle.H)); a.CTX.lineTo((a.GraphRectangle.X + a.GraphRectangle.W), (a.GraphRectangle.Y + a.GraphRectangle.H)); } a.CTX.lineWidth = a.Parent.Axis.LineWidth; a.CTX.strokeStyle = a.Parent.Axis.LineColour1; a.CTX.stroke(); } drawXAxisLabels() { const a = this; const labelSize = a.measureText(a.Parent.Axis.Font, "0"); let posY = 0; let posDayY = 0; let posMonthY = 0; if (a.Parent.XAxis.Position == 'top') { posY = (a.GraphRectangle.Y - a.Parent.Axis.LineWidth) - 2; posDayY = (posY - (labelSize.H + a.Parent.XAxis.DayLineHeight)); posMonthY = (posDayY - (labelSize.H + a.Parent.Axis.LabelSpacing)); } else { posY = (a.GraphRectangle.Y + a.GraphRectangle.H) + a.Parent.Axis.LineWidth; posDayY = (posY + a.Parent.XAxis.DayLineHeight); posMonthY = (posDayY + labelSize.H + a.Parent.Axis.LabelSpacing); } a.XAxisPositions.forEach(function(e, i) { const date = a.Parent.ConvertToDate(e.Date); let writeLabel = false; if ((i == 0)) { // Don't label first entry if too close to the next month if (date.getDate() < 25) { writeLabel = true; } } else if (date.getDate() == 1) { writeLabel = true; } // if (i == 0) { // // Don't write first date // } else { // Write date (dd) a.drawText(e.X, posDayY, a.Parent.DateToString(date, "dd"), a.Parent.Axis.Font, a.Parent.Axis.LabelColour, "center"); // } // Write month (MMMM) on first of the month if (writeLabel) { a.drawText(e.X, posMonthY, a.Parent.DateToString(date, "MMMM yyyy"), a.Parent.Axis.Font, a.Parent.Axis.LabelColour, "left"); } }); } drawXAxisTicks() { const a = this; let startPosX = a.GraphRectangle.X; const endPosX = (a.GraphRectangle.X + a.GraphRectangle.W); let posY = 0; let posDayY = 0; let posHourY = 0; if (a.Parent.XAxis.Position == 'top') { posY = (a.GraphRectangle.Y - a.Parent.Axis.LineWidth); posDayY = (posY - a.Parent.XAxis.DayLineHeight); posHourY = (posY - a.Parent.XAxis.HourLineHeight); } else { posY = (a.GraphRectangle.Y + a.GraphRectangle.H) + a.Parent.Axis.LineWidth; posDayY = (posY + a.Parent.XAxis.DayLineHeight); posHourY = (posY + a.Parent.XAxis.HourLineHeight); } let i = 0; while (true) { if (startPosX >= endPosX) { break; } a.CTX.beginPath(); a.CTX.moveTo(startPosX, posY); if ((i % a.Parent.XAxis.NoPartPerDay) == 0) { a.CTX.lineTo(startPosX, posDayY); a.CTX.strokeStyle = a.Parent.XAxis.DayLineColour; } else { a.CTX.lineTo(startPosX, posHourY); a.CTX.strokeStyle = a.Parent.XAxis.HourLineColour; } a.CTX.lineWidth = a.Parent.Axis.LineWidth; a.CTX.stroke(); startPosX += a.Parent.XAxis.HourLineSpace; i++; } } }