literyzjs-timeline/bbtimeline-background-canvas.js
Ray 0bbed0dfee Changed to multi-layer for hot-tracking and other flourishes
Changed default colours
Added X-Axis top and bottom positions
2023-10-22 22:14:12 +01:00

208 lines
5.3 KiB
JavaScript

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++;
}
}
}