WIP: Added multi-layers
This commit is contained in:
parent
f064d12e4c
commit
e48dca5da1
175
bbtimeline-background-canvas.js
Normal file
175
bbtimeline-background-canvas.js
Normal file
@ -0,0 +1,175 @@
|
|||||||
|
class BBTimelineBackgroundCanvas extends BBTimelineCanvas {
|
||||||
|
constructor(parentEl, el) {
|
||||||
|
super(parentEl, el);
|
||||||
|
|
||||||
|
const a = this;
|
||||||
|
|
||||||
|
a.GraphRectangle = { X: 0, Y: 0, W: 0, H: 0 };
|
||||||
|
a.Margin = 0;
|
||||||
|
a.StepHeight = 0;
|
||||||
|
a.NoStep = 0;
|
||||||
|
|
||||||
|
a.initialiseComponents();
|
||||||
|
}
|
||||||
|
|
||||||
|
initialiseComponents() {
|
||||||
|
super.initialiseComponents();
|
||||||
|
|
||||||
|
const a = this;
|
||||||
|
|
||||||
|
a.ClientRectangle = {
|
||||||
|
X: a.Parent.Padding.Left,
|
||||||
|
Y: a.Parent.Padding.Top,
|
||||||
|
W: (a.Parent.Size.W - (a.Parent.Padding.Left + a.Parent.Padding.Right)),
|
||||||
|
H: (a.Parent.Size.H - (a.Parent.Padding.Top + a.Parent.Padding.Bottom))
|
||||||
|
};
|
||||||
|
|
||||||
|
a.GraphRectangle = {
|
||||||
|
X: a.ClientRectangle.X,
|
||||||
|
Y: a.ClientRectangle.Y,
|
||||||
|
W: a.ClientRectangle.W,
|
||||||
|
H: (a.ClientRectangle.H - a.calcXAxisHeight())
|
||||||
|
};
|
||||||
|
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
|
||||||
|
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();
|
||||||
|
a.CTX.moveTo(a.GraphRectangle.X, a.GraphRectangle.Y);
|
||||||
|
a.CTX.lineTo(a.GraphRectangle.X, (a.GraphRectangle.H + a.GraphRectangle.Y));
|
||||||
|
a.CTX.lineTo((a.GraphRectangle.W + a.GraphRectangle.X), (a.GraphRectangle.H + a.GraphRectangle.Y));
|
||||||
|
a.CTX.lineWidth = a.Parent.Axis.LineWidth;
|
||||||
|
a.CTX.strokeStyle = a.Parent.Axis.LineColour1;
|
||||||
|
a.CTX.stroke();
|
||||||
|
}
|
||||||
|
|
||||||
|
drawXAxisTicks() {
|
||||||
|
const a = this;
|
||||||
|
|
||||||
|
let startPosX = a.GraphRectangle.X;
|
||||||
|
const endPosX = (a.GraphRectangle.X + a.GraphRectangle.W);
|
||||||
|
const posY = (a.GraphRectangle.Y + a.GraphRectangle.H) + a.Parent.Axis.LineWidth;
|
||||||
|
|
||||||
|
let i = 0;
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
if (startPosX >= endPosX) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
a.CTX.beginPath();
|
||||||
|
a.CTX.moveTo(startPosX, posY);
|
||||||
|
|
||||||
|
if ((i % a.Parent.Axis.X.NoPartPerDay) == 0) {
|
||||||
|
a.CTX.lineTo(startPosX, (posY + a.Parent.Axis.X.DayLineHeight));
|
||||||
|
a.CTX.strokeStyle = a.Parent.Axis.X.DayLineColour;
|
||||||
|
} else {
|
||||||
|
a.CTX.lineTo(startPosX, (posY + a.Parent.Axis.X.HourLineHeight));
|
||||||
|
a.CTX.strokeStyle = a.Parent.Axis.X.HourLineColour;
|
||||||
|
}
|
||||||
|
|
||||||
|
a.CTX.lineWidth = a.Parent.Axis.LineWidth;
|
||||||
|
a.CTX.stroke();
|
||||||
|
|
||||||
|
startPosX += a.Parent.Axis.X.HourLineSpace;
|
||||||
|
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
drawXAxisLabels() {
|
||||||
|
const a = this;
|
||||||
|
|
||||||
|
const result = a.calcXAxisPositions();
|
||||||
|
const posY = (a.GraphRectangle.Y + a.GraphRectangle.H) + a.Parent.Axis.LineWidth;
|
||||||
|
|
||||||
|
result.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) {
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
|
||||||
|
const labelSize = a.drawText(e.X, (posY + a.Parent.Axis.X.DayLineHeight), a.Parent.DateToString(date, "dd"), a.Parent.Axis.Font, a.Parent.Axis.LabelColour, "center");
|
||||||
|
|
||||||
|
// Write month on first of the month
|
||||||
|
if (writeLabel) {
|
||||||
|
a.drawText(e.X, (posY + a.Parent.Axis.X.DayLineHeight + labelSize.Height + a.Parent.Axis.LabelSpacing), a.Parent.DateToString(date, "MMMM yyyy"), a.Parent.Axis.Font, a.Parent.Axis.LabelColour, "left");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
calcXAxisPositions() {
|
||||||
|
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.DateToString(date, a.Parent.DateParsePattern),
|
||||||
|
X: x
|
||||||
|
});
|
||||||
|
|
||||||
|
x += (a.Parent.Axis.X.HourLineSpace * a.Parent.Axis.X.NoPartPerDay);
|
||||||
|
date.setDate(date.getDate() + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
calcXAxisHeight() {
|
||||||
|
const a = this;
|
||||||
|
const labelSize = a.measureText(a.Parent.Axis.Font, "0");
|
||||||
|
|
||||||
|
return labelSize.Height + a.Parent.Axis.LabelSpacing + (a.Parent.Axis.X.DayLineHeight * 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
// OnMouseDown(sender, e, event) {
|
||||||
|
// }
|
||||||
|
|
||||||
|
// OnClick(sender, e, event) {
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
}
|
95
bbtimeline-canvas.js
Normal file
95
bbtimeline-canvas.js
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
class BBTimelineCanvas {
|
||||||
|
constructor(parentEl, el) {
|
||||||
|
const a = this;
|
||||||
|
|
||||||
|
a.Parent = parentEl;
|
||||||
|
a.Container = el;
|
||||||
|
a.CTX = a.Container.getContext("2d");
|
||||||
|
|
||||||
|
a.ClientRectangle = { X: 0, Y: 0, W: 0, H: 0 };
|
||||||
|
|
||||||
|
a.initialiseComponents();
|
||||||
|
}
|
||||||
|
|
||||||
|
Clear() {
|
||||||
|
const a = this;
|
||||||
|
|
||||||
|
a.CTX.clearRect(0, 0, a.CTX.canvas.width, a.CTX.canvas.height);
|
||||||
|
}
|
||||||
|
|
||||||
|
Invalidate() {
|
||||||
|
// placeholder
|
||||||
|
}
|
||||||
|
|
||||||
|
initialiseComponents() {
|
||||||
|
const a = this;
|
||||||
|
|
||||||
|
a.Container.style.width = a.Parent.Size.W + "px";
|
||||||
|
a.Container.style.height = a.Parent.Size.H + "px";
|
||||||
|
a.Container.style.position = 'absolute';
|
||||||
|
a.Container.style.border = 'none';
|
||||||
|
|
||||||
|
a.CTX.canvas.width = a.Parent.Size.W;
|
||||||
|
a.CTX.canvas.height = a.Parent.Size.H;
|
||||||
|
|
||||||
|
a.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
drawText(x, y, label, font, foreColour, align) {
|
||||||
|
const a = this;
|
||||||
|
|
||||||
|
a.CTX.font = font;
|
||||||
|
a.CTX.fillStyle = foreColour;
|
||||||
|
|
||||||
|
const size = a.measureText(font, label);
|
||||||
|
|
||||||
|
switch (align) {
|
||||||
|
case "center":
|
||||||
|
x = (x - size.OffsetLeft);
|
||||||
|
break;
|
||||||
|
case "right":
|
||||||
|
x = (x - size.Width);
|
||||||
|
break;
|
||||||
|
case "left":
|
||||||
|
default:
|
||||||
|
// do nothing
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
a.CTX.fillText(label, x, (y + size.Height));
|
||||||
|
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
drawRectangle(rectangle, colour) {
|
||||||
|
const a = this;
|
||||||
|
|
||||||
|
a.CTX.beginPath();
|
||||||
|
a.CTX.rect(rectangle.X, rectangle.Y, rectangle.W, rectangle.H);
|
||||||
|
//a.ctx.fillStyle = 'yellow';
|
||||||
|
//a.ctx.fill();
|
||||||
|
a.CTX.lineWidth = 1;
|
||||||
|
a.CTX.strokeStyle = colour;
|
||||||
|
a.CTX.stroke();
|
||||||
|
}
|
||||||
|
|
||||||
|
half(value) {
|
||||||
|
return (value / 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
measureText(font, value) {
|
||||||
|
const a = this;
|
||||||
|
|
||||||
|
a.CTX.font = font;
|
||||||
|
const size = a.CTX.measureText(value);
|
||||||
|
|
||||||
|
return {
|
||||||
|
Width: size.width,
|
||||||
|
Height: size.fontBoundingBoxAscent,
|
||||||
|
OffsetLeft: a.half(size.width),
|
||||||
|
OffsetTop: a.half(size.fontBoundingBoxAscent)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
125
bbtimeline-foreground-canvas.js
Normal file
125
bbtimeline-foreground-canvas.js
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
class BBTimelineForegroundCanvas extends BBTimelineCanvas {
|
||||||
|
constructor(parentEl, el) {
|
||||||
|
super(parentEl, el);
|
||||||
|
|
||||||
|
const a = this;
|
||||||
|
|
||||||
|
a.initialiseComponents();
|
||||||
|
}
|
||||||
|
|
||||||
|
initialiseComponents() {
|
||||||
|
super.initialiseComponents();
|
||||||
|
|
||||||
|
const a = this;
|
||||||
|
|
||||||
|
a.Invalidate();
|
||||||
|
}
|
||||||
|
|
||||||
|
Invalidate() {
|
||||||
|
const a = this;
|
||||||
|
const rect = a.Parent.Layer.Background.GraphRectangle;
|
||||||
|
const margin = a.Parent.Layer.Background.Margin;
|
||||||
|
|
||||||
|
a.Clear();
|
||||||
|
|
||||||
|
const startPosY = (rect.Y + a.Parent.Marker.Width);
|
||||||
|
|
||||||
|
const visibleEvents = a.Parent.FindVisibleEvents();
|
||||||
|
visibleEvents.forEach(function (e, i) {
|
||||||
|
// Calculate Y position
|
||||||
|
let posY = a.calcMarkerPosition(e.Position.X, startPosY);
|
||||||
|
|
||||||
|
a.drawVerticalLine(e.Position.X, posY);
|
||||||
|
|
||||||
|
const markerRectangle = a.drawMarker(e.Position.X, posY, e.BorderColour, e.BackColour);
|
||||||
|
const labelSize = a.drawText((markerRectangle.X + markerRectangle.W + margin), markerRectangle.Y, e.Label, a.Parent.Marker.Font, a.Parent.Marker.ForeColour, "left");
|
||||||
|
|
||||||
|
e.Position = { X: e.Position.X, Y: posY };
|
||||||
|
|
||||||
|
e.HitBox = {
|
||||||
|
X: markerRectangle.X,
|
||||||
|
Y: markerRectangle.Y,
|
||||||
|
W: (markerRectangle.W + margin + labelSize.Width + a.Parent.Marker.CollisionMargin),
|
||||||
|
H: markerRectangle.H
|
||||||
|
};
|
||||||
|
|
||||||
|
if (a.Parent.Debug) a.drawRectangle(e.HitBox, "red");
|
||||||
|
if (a.Parent.Debug) console.log(e);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
calcMarkerPosition(x, y) {
|
||||||
|
const a = this;
|
||||||
|
const rect = a.Parent.Layer.Background.GraphRectangle;
|
||||||
|
|
||||||
|
// Calculate Y position
|
||||||
|
let hasMoved = false;
|
||||||
|
let posY = y;
|
||||||
|
for (let i=0; i<a.Parent.Layer.Background.NoStep; i++)
|
||||||
|
{
|
||||||
|
posY = y + (a.Parent.Layer.Background.StepHeight * i);
|
||||||
|
|
||||||
|
var clippedEvent = a.Parent.FindEventsByCoords(x, posY);
|
||||||
|
if (clippedEvent == null) {
|
||||||
|
hasMoved = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!hasMoved) {
|
||||||
|
posY = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
return posY;
|
||||||
|
}
|
||||||
|
|
||||||
|
drawMarker(x, y, borderColour, backColour) {
|
||||||
|
const a = this;
|
||||||
|
const width = a.Parent.Marker.Width - (a.Parent.Marker.BorderWidth * 2);
|
||||||
|
|
||||||
|
a.CTX.beginPath();
|
||||||
|
a.CTX.arc(x, y, width, 0, 2 * Math.PI, false);
|
||||||
|
a.CTX.fillStyle = backColour;
|
||||||
|
a.CTX.fill();
|
||||||
|
a.CTX.lineWidth = a.Parent.Marker.BorderWidth;
|
||||||
|
a.CTX.strokeStyle = borderColour;
|
||||||
|
a.CTX.stroke();
|
||||||
|
|
||||||
|
return a.measureMarker(x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
drawVerticalLine(x, y) {
|
||||||
|
const a = this;
|
||||||
|
const rect = a.Parent.Layer.Background.GraphRectangle;
|
||||||
|
const highlightLine = a.Parent.HighlightLine;
|
||||||
|
const linePosY = (rect.Y + rect.H);
|
||||||
|
|
||||||
|
if (y <= 0) {
|
||||||
|
y = (rect.Y + highlightLine.Width);
|
||||||
|
}
|
||||||
|
|
||||||
|
a.CTX.beginPath();
|
||||||
|
a.CTX.moveTo(x, y);
|
||||||
|
a.CTX.lineTo(x, (linePosY - highlightLine.Width));
|
||||||
|
a.CTX.lineWidth = highlightLine.Width;
|
||||||
|
a.CTX.strokeStyle = highlightLine.Colour;
|
||||||
|
a.CTX.stroke();
|
||||||
|
}
|
||||||
|
|
||||||
|
measureMarker(x, y) {
|
||||||
|
const a = this;
|
||||||
|
const offset = a.half(a.Parent.Marker.Width);
|
||||||
|
|
||||||
|
const result = {
|
||||||
|
X: x - (offset + a.Parent.Marker.BorderWidth),
|
||||||
|
Y: y - (offset + a.Parent.Marker.BorderWidth),
|
||||||
|
W: (a.Parent.Marker.Width + (a.Parent.Marker.BorderWidth * 2)),
|
||||||
|
H: (a.Parent.Marker.Width + (a.Parent.Marker.BorderWidth * 2))
|
||||||
|
};
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
648
bbtimeline.js
648
bbtimeline.js
@ -1,14 +1,12 @@
|
|||||||
/**
|
/**
|
||||||
* BBTimeline
|
* BBTimeline
|
||||||
* @version v0.1.0.089 beta (2023/10/14 1658)
|
* @version v0.1.1.121 beta (2023/10/18 2058)
|
||||||
*/
|
*/
|
||||||
class BBTimeline {
|
class BBTimeline {
|
||||||
constructor(el) {
|
constructor(el) {
|
||||||
const a = this;
|
const a = this;
|
||||||
|
|
||||||
a.Container = document.getElementById(el);
|
a.Container = document.getElementById(el);
|
||||||
a.DateParsePattern = "yyyy-MM-dd";
|
|
||||||
a.Debug = false;
|
|
||||||
a.Padding = {
|
a.Padding = {
|
||||||
Left: 20,
|
Left: 20,
|
||||||
Top: 20,
|
Top: 20,
|
||||||
@ -19,10 +17,13 @@ class BBTimeline {
|
|||||||
W: a.Container.innerWidth || a.Container.clientWidth,
|
W: a.Container.innerWidth || a.Container.clientWidth,
|
||||||
H: a.Container.innerHeight || a.Container.clientHeight
|
H: a.Container.innerHeight || a.Container.clientHeight
|
||||||
};
|
};
|
||||||
|
a.Layer = {
|
||||||
|
Background: null,
|
||||||
|
Flourish: null,
|
||||||
|
Markers: null
|
||||||
|
};
|
||||||
|
|
||||||
a.ctx = a.Container.getContext("2d");
|
a.DateParsePattern = "yyyy-MM-dd";
|
||||||
a.ctx.canvas.width = a.Size.W;
|
|
||||||
a.ctx.canvas.height = a.Size.H;
|
|
||||||
|
|
||||||
a.Axis = {
|
a.Axis = {
|
||||||
LineColour1: "#CFCFCF",
|
LineColour1: "#CFCFCF",
|
||||||
@ -39,6 +40,7 @@ class BBTimeline {
|
|||||||
DayLineColour: "#282828"
|
DayLineColour: "#282828"
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
a.Marker = {
|
a.Marker = {
|
||||||
BorderColour: "#3A5D9C",
|
BorderColour: "#3A5D9C",
|
||||||
BorderWidth: 2,
|
BorderWidth: 2,
|
||||||
@ -48,15 +50,19 @@ class BBTimeline {
|
|||||||
Font: "9pt Arial",
|
Font: "9pt Arial",
|
||||||
CollisionMargin: 8
|
CollisionMargin: 8
|
||||||
};
|
};
|
||||||
|
|
||||||
a.HighlightLine = {
|
a.HighlightLine = {
|
||||||
Colour: "#A6A6A6",
|
Colour: "#A6A6A6",
|
||||||
Width: 1,
|
Width: 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
a.Events = [];
|
a.Events = [];
|
||||||
a.StartDate = a.DateToString(new Date(), a.DateParsePattern);
|
a.StartDate = a.DateToString(new Date(), a.DateParsePattern);
|
||||||
a.ShowDate = a.StartDate;
|
a.ShowDate = a.StartDate;
|
||||||
a.GraphRectangle = a.calcGraphRectangle();
|
// a.GraphRectangle = a.calcGraphRectangle();
|
||||||
|
|
||||||
a.Enabled = false;
|
a.Enabled = false;
|
||||||
|
a.Debug = false;
|
||||||
|
|
||||||
a.initialiseComponents();
|
a.initialiseComponents();
|
||||||
}
|
}
|
||||||
@ -82,8 +88,8 @@ class BBTimeline {
|
|||||||
|
|
||||||
CalcEndDate() {
|
CalcEndDate() {
|
||||||
const a = this;
|
const a = this;
|
||||||
|
const clientWidth = (a.Size.W - (a.Padding.Left + a.Padding.Right));
|
||||||
const calcdays = Math.floor(a.GraphRectangle.W / (a.Axis.X.NoPartPerDay * a.Axis.X.HourLineSpace));
|
const calcdays = Math.floor(clientWidth / (a.Axis.X.NoPartPerDay * a.Axis.X.HourLineSpace));
|
||||||
|
|
||||||
let date = a.ConvertToDate(a.ShowDate);
|
let date = a.ConvertToDate(a.ShowDate);
|
||||||
date.setDate(date.getDate() + calcdays);
|
date.setDate(date.getDate() + calcdays);
|
||||||
@ -97,7 +103,9 @@ class BBTimeline {
|
|||||||
Clear() {
|
Clear() {
|
||||||
const a = this;
|
const a = this;
|
||||||
|
|
||||||
a.ctx.clearRect(0, 0, a.ctx.canvas.width, a.ctx.canvas.height);
|
a.Layer.Background.Clear();
|
||||||
|
a.Layer.Flourish.Clear();
|
||||||
|
a.Layer.Markers.Clear();
|
||||||
|
|
||||||
a.StartDate = a.DateToString(new Date(), a.DateParsePattern);
|
a.StartDate = a.DateToString(new Date(), a.DateParsePattern);
|
||||||
a.ShowDate = a.StartDate;
|
a.ShowDate = a.StartDate;
|
||||||
@ -121,7 +129,7 @@ class BBTimeline {
|
|||||||
FindDatePosition(date) {
|
FindDatePosition(date) {
|
||||||
const a = this;
|
const a = this;
|
||||||
|
|
||||||
const points = a.getXAxis();
|
const points = a.Layer.Background.calcXAxisPositions();
|
||||||
for (let i=0; i<points.length; i++) {
|
for (let i=0; i<points.length; i++) {
|
||||||
if (points[i].Date == date){
|
if (points[i].Date == date){
|
||||||
return points[i];
|
return points[i];
|
||||||
@ -135,7 +143,8 @@ class BBTimeline {
|
|||||||
const a = this;
|
const a = this;
|
||||||
let result = [];
|
let result = [];
|
||||||
|
|
||||||
const availableX = a.getXAxis();
|
const availableX = a.Layer.Background.calcXAxisPositions();
|
||||||
|
|
||||||
availableX.forEach(function (e) {
|
availableX.forEach(function (e) {
|
||||||
const event = a.FindEvent(e.Date);
|
const event = a.FindEvent(e.Date);
|
||||||
if (event == null) {
|
if (event == null) {
|
||||||
@ -204,23 +213,23 @@ class BBTimeline {
|
|||||||
a.Invalidate(true, true);
|
a.Invalidate(true, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
ShowNext() {
|
// ShowNext() {
|
||||||
const a = this;
|
// const a = this;
|
||||||
|
|
||||||
let date = a.ConvertToDate(a.ShowDate);
|
// let date = a.ConvertToDate(a.ShowDate);
|
||||||
date.setMonth(date.getMonth() + 1);
|
// date.setMonth(date.getMonth() + 1);
|
||||||
|
|
||||||
a.Show(a.DateToString(date, a.DateParsePattern));
|
// a.Show(a.DateToString(date, a.DateParsePattern));
|
||||||
}
|
// }
|
||||||
|
|
||||||
ShowPrevious() {
|
// ShowPrevious() {
|
||||||
const a = this;
|
// const a = this;
|
||||||
|
|
||||||
let date = a.ConvertToDate(a.ShowDate);
|
// let date = a.ConvertToDate(a.ShowDate);
|
||||||
date.setMonth(date.getMonth() - 1);
|
// date.setMonth(date.getMonth() - 1);
|
||||||
|
|
||||||
a.Show(a.DateToString(date, a.DateParsePattern));
|
// a.Show(a.DateToString(date, a.DateParsePattern));
|
||||||
}
|
// }
|
||||||
|
|
||||||
UpdateLabel(date, label) {
|
UpdateLabel(date, label) {
|
||||||
const a = this;
|
const a = this;
|
||||||
@ -249,43 +258,54 @@ class BBTimeline {
|
|||||||
a.Invalidate(false, true);
|
a.Invalidate(false, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
initialiseComponents() {
|
// initialiseComponents2() {
|
||||||
const a = this;
|
// const a = this;
|
||||||
|
|
||||||
a.ctx.canvas.addEventListener('mousedown', function (e) {
|
// a.ctx.canvas.addEventListener('mousedown', function (e) {
|
||||||
if (!a.Enabled) {
|
// if (!a.Enabled) {
|
||||||
return;
|
// return;
|
||||||
}
|
// }
|
||||||
|
|
||||||
var event = a.FindEventsByCoords(e.offsetX, e.offsetY);
|
// var event = a.FindEventsByCoords(e.offsetX, e.offsetY);
|
||||||
if (event == null) {
|
// if (event == null) {
|
||||||
return;
|
// return;
|
||||||
}
|
// }
|
||||||
|
|
||||||
if (a.Debug) console.log(event);
|
// if (a.Debug) console.log(event);
|
||||||
|
|
||||||
a.OnMouseDown(this, e, event);
|
// a.OnMouseDown(this, e, event);
|
||||||
});
|
// });
|
||||||
|
|
||||||
a.ctx.canvas.addEventListener('click', function (e) {
|
// a.ctx.canvas.addEventListener('click', function (e) {
|
||||||
if (!a.Enabled) {
|
// if (!a.Enabled) {
|
||||||
return;
|
// return;
|
||||||
}
|
// }
|
||||||
|
|
||||||
var event = a.FindEventsByCoords(e.offsetX, e.offsetY);
|
// var event = a.FindEventsByCoords(e.offsetX, e.offsetY);
|
||||||
if (event == null) {
|
// if (event == null) {
|
||||||
return;
|
// return;
|
||||||
}
|
// }
|
||||||
|
|
||||||
if (a.Debug) console.log(event);
|
// if (a.Debug) console.log(event);
|
||||||
|
|
||||||
a.OnClick(this, e, event);
|
// a.OnClick(this, e, event);
|
||||||
});
|
// });
|
||||||
}
|
// }
|
||||||
|
|
||||||
Invalidate(redrawAxis, redrawMarkers) {
|
Invalidate(redrawAxis, redrawMarkers) {
|
||||||
const a = this;
|
const a = this;
|
||||||
|
|
||||||
|
if (redrawAxis) {
|
||||||
|
a.Layer.Background.Invalidate();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (redrawMarkers) {
|
||||||
|
a.Layer.Markers.Invalidate();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return;
|
||||||
|
|
||||||
if (redrawAxis) {
|
if (redrawAxis) {
|
||||||
a.ctx.clearRect(0, 0, a.ctx.canvas.width, a.ctx.canvas.height);
|
a.ctx.clearRect(0, 0, a.ctx.canvas.width, a.ctx.canvas.height);
|
||||||
|
|
||||||
@ -295,12 +315,12 @@ class BBTimeline {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (redrawMarkers) {
|
if (redrawMarkers) {
|
||||||
a.clearChart();
|
// a.clearChart();
|
||||||
|
|
||||||
const startPosY = (a.GraphRectangle.Y + a.Marker.Width);
|
// const startPosY = (a.GraphRectangle.Y + a.Marker.Width);
|
||||||
const visibleEvents = a.FindVisibleEvents();
|
// const visibleEvents = a.FindVisibleEvents();
|
||||||
|
|
||||||
if (a.Debug) console.log(visibleEvents);
|
// if (a.Debug) console.log(visibleEvents);
|
||||||
|
|
||||||
visibleEvents.forEach(function (e, i) {
|
visibleEvents.forEach(function (e, i) {
|
||||||
// Calculate Y position
|
// Calculate Y position
|
||||||
@ -405,295 +425,319 @@ class BBTimeline {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
calcGraphRectangle() {
|
// calcGraphRectangle() {
|
||||||
const a = this;
|
// const a = this;
|
||||||
|
|
||||||
const xAxisHeight = a.calcXAxisHeight();
|
// // const xAxisHeight = a.calcXAxisHeight();
|
||||||
|
|
||||||
let result = {
|
// // let result = {
|
||||||
X: a.Padding.Left,
|
// // X: a.Padding.Left,
|
||||||
Y: a.Padding.Top,
|
// // Y: a.Padding.Top,
|
||||||
W: (a.Size.W - (a.Padding.Left + a.Padding.Right)),
|
// // W: (a.Size.W - (a.Padding.Left + a.Padding.Right)),
|
||||||
H: (a.Size.H - (a.Padding.Top + a.Padding.Bottom) - xAxisHeight),
|
// // H: (a.Size.H - (a.Padding.Top + a.Padding.Bottom) - xAxisHeight),
|
||||||
Margin: (a.Marker.BorderWidth * 2)
|
// // Margin: (a.Marker.BorderWidth * 2)
|
||||||
};
|
// // };
|
||||||
|
|
||||||
result.StepHeight = a.Marker.Width + result.Margin;
|
// let result = {
|
||||||
result.NoStep = Math.floor(result.H / result.StepHeight);
|
// X: a.Padding.Left,
|
||||||
|
// Y: a.Padding.Top,
|
||||||
|
// W: (a.Size.W - (a.Padding.Left + a.Padding.Right)),
|
||||||
|
// H: (a.Size.H - (a.Padding.Top + a.Padding.Bottom)),
|
||||||
|
// Margin: (a.Marker.BorderWidth * 2)
|
||||||
|
// };
|
||||||
|
|
||||||
return result;
|
// result.StepHeight = a.Marker.Width + result.Margin;
|
||||||
}
|
// result.NoStep = Math.floor(result.H / result.StepHeight);
|
||||||
|
|
||||||
calcXAxisHeight() {
|
// return result;
|
||||||
const a = this;
|
|
||||||
const labelSize = a.measureText(a.Axis.Font, "0");
|
|
||||||
const result = labelSize.Height + a.Axis.LabelSpacing + (a.Axis.X.DayLineHeight * 2);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
calcMarkerPosition(x, y) {
|
|
||||||
const a = this;
|
|
||||||
|
|
||||||
// Calculate Y position
|
|
||||||
let hasMoved = false;
|
|
||||||
let posY = y;
|
|
||||||
for (let i=0; i<a.GraphRectangle.NoStep; i++)
|
|
||||||
{
|
|
||||||
posY = y + (a.GraphRectangle.StepHeight * i);
|
|
||||||
|
|
||||||
var clippedEvent = a.FindEventsByCoords(x, posY);
|
|
||||||
if (clippedEvent == null) {
|
|
||||||
hasMoved = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!hasMoved) {
|
|
||||||
posY = y;
|
|
||||||
}
|
|
||||||
|
|
||||||
return posY;
|
|
||||||
}
|
|
||||||
|
|
||||||
clearChart() {
|
|
||||||
const a = this;
|
|
||||||
const rect = {
|
|
||||||
X: a.GraphRectangle.X,
|
|
||||||
Y: a.GraphRectangle.Y,
|
|
||||||
W: a.GraphRectangle.W,
|
|
||||||
H: a.GraphRectangle.H
|
|
||||||
};
|
|
||||||
|
|
||||||
rect.X += a.Axis.LineWidth;
|
|
||||||
rect.Y -= a.Padding.Top;
|
|
||||||
rect.W -= a.Axis.LineWidth;
|
|
||||||
rect.W += a.Padding.Right;
|
|
||||||
rect.H -= a.Axis.LineWidth;
|
|
||||||
rect.H += a.Padding.Top;
|
|
||||||
|
|
||||||
a.ctx.clearRect(rect.X, rect.Y, rect.W, rect.H);
|
|
||||||
|
|
||||||
if (a.Debug) a.drawRectangle(rect);
|
|
||||||
|
|
||||||
// Clear marker positions
|
|
||||||
const visibleEvents = a.FindVisibleEvents();
|
|
||||||
visibleEvents.forEach(function (e, i) {
|
|
||||||
e.Position = { X: 0, Y: 0 };
|
|
||||||
e.HitBox = null;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
drawAxis() {
|
|
||||||
const a = this;
|
|
||||||
|
|
||||||
a.ctx.beginPath();
|
|
||||||
a.ctx.moveTo(a.GraphRectangle.X, a.GraphRectangle.Y);
|
|
||||||
a.ctx.lineTo(a.GraphRectangle.X, (a.GraphRectangle.H + a.GraphRectangle.Y));
|
|
||||||
a.ctx.lineTo((a.GraphRectangle.W + a.GraphRectangle.X), (a.GraphRectangle.H + a.GraphRectangle.Y));
|
|
||||||
a.ctx.lineWidth = a.Axis.LineWidth;
|
|
||||||
a.ctx.strokeStyle = a.Axis.LineColour1;
|
|
||||||
a.ctx.stroke();
|
|
||||||
}
|
|
||||||
|
|
||||||
drawXAxis() {
|
|
||||||
const a = this;
|
|
||||||
|
|
||||||
let startPosX = a.GraphRectangle.X;
|
|
||||||
const endPosX = (a.GraphRectangle.X + a.GraphRectangle.W);
|
|
||||||
const posY = (a.GraphRectangle.Y + a.GraphRectangle.H) + a.Axis.LineWidth;
|
|
||||||
|
|
||||||
let i = 0;
|
|
||||||
|
|
||||||
while (true) {
|
|
||||||
if (startPosX >= endPosX) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
a.ctx.beginPath();
|
|
||||||
a.ctx.moveTo(startPosX, posY);
|
|
||||||
|
|
||||||
if ((i % a.Axis.X.NoPartPerDay) == 0) {
|
|
||||||
a.ctx.lineTo(startPosX, (posY + a.Axis.X.DayLineHeight));
|
|
||||||
a.ctx.strokeStyle = a.Axis.X.DayLineColour;
|
|
||||||
} else {
|
|
||||||
a.ctx.lineTo(startPosX, (posY + a.Axis.X.HourLineHeight));
|
|
||||||
a.ctx.strokeStyle = a.Axis.X.HourLineColour;
|
|
||||||
}
|
|
||||||
|
|
||||||
a.ctx.lineWidth = a.Axis.LineWidth;
|
|
||||||
a.ctx.stroke();
|
|
||||||
|
|
||||||
startPosX += a.Axis.X.HourLineSpace;
|
|
||||||
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
drawXAxisLabels() {
|
|
||||||
const a = this;
|
|
||||||
|
|
||||||
const result = a.getXAxis();
|
|
||||||
const posY = (a.GraphRectangle.Y + a.GraphRectangle.H) + a.Axis.LineWidth;
|
|
||||||
|
|
||||||
result.forEach(function(e, i) {
|
|
||||||
const date = a.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) {
|
|
||||||
// return;
|
|
||||||
// }
|
// }
|
||||||
|
|
||||||
const labelSize = a.drawText(e.X, (posY + a.Axis.X.DayLineHeight), a.DateToString(date, "dd"), a.Axis.Font, a.Axis.LabelColour, "center");
|
// calcXAxisHeight() {
|
||||||
|
// const a = this;
|
||||||
|
// const labelSize = a.measureText(a.Axis.Font, "0");
|
||||||
|
// const result = labelSize.Height + a.Axis.LabelSpacing + (a.Axis.X.DayLineHeight * 2);
|
||||||
|
|
||||||
// Write month on first of the month
|
// return result;
|
||||||
if (writeLabel) {
|
// }
|
||||||
a.drawText(e.X, (posY + a.Axis.X.DayLineHeight + labelSize.Height + a.Axis.LabelSpacing), a.DateToString(date, "MMMM yyyy"), a.Axis.Font, a.Axis.LabelColour, "left");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
drawMarker(x, y, borderColour, backColour) {
|
|
||||||
const a = this;
|
|
||||||
const width = a.Marker.Width - (a.Marker.BorderWidth * 2);
|
|
||||||
|
|
||||||
a.ctx.beginPath();
|
// calcMarkerPosition(x, y) {
|
||||||
a.ctx.arc(x, y, width, 0, 2 * Math.PI, false);
|
// const a = this;
|
||||||
a.ctx.fillStyle = backColour;
|
|
||||||
a.ctx.fill();
|
|
||||||
a.ctx.lineWidth = a.Marker.BorderWidth;
|
|
||||||
a.ctx.strokeStyle = borderColour;
|
|
||||||
a.ctx.stroke();
|
|
||||||
|
|
||||||
return a.measureMarker(x, y);
|
// // Calculate Y position
|
||||||
}
|
// let hasMoved = false;
|
||||||
|
// let posY = y;
|
||||||
|
// for (let i=0; i<a.GraphRectangle.NoStep; i++)
|
||||||
|
// {
|
||||||
|
// posY = y + (a.GraphRectangle.StepHeight * i);
|
||||||
|
|
||||||
drawText(x, y, label, font, foreColour, align) {
|
// var clippedEvent = a.FindEventsByCoords(x, posY);
|
||||||
const a = this;
|
// if (clippedEvent == null) {
|
||||||
|
// hasMoved = true;
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
a.ctx.font = font;
|
// if (!hasMoved) {
|
||||||
a.ctx.fillStyle = foreColour;
|
// posY = y;
|
||||||
|
// }
|
||||||
|
|
||||||
const size = a.measureText(font, label);
|
// return posY;
|
||||||
|
// }
|
||||||
|
|
||||||
switch (align) {
|
// clearChart() {
|
||||||
case "center":
|
// const a = this;
|
||||||
x = (x - size.OffsetLeft);
|
// const rect = {
|
||||||
break;
|
// X: a.GraphRectangle.X,
|
||||||
case "right":
|
// Y: a.GraphRectangle.Y,
|
||||||
x = (x - size.Width);
|
// W: a.GraphRectangle.W,
|
||||||
break;
|
// H: a.GraphRectangle.H
|
||||||
case "left":
|
// };
|
||||||
default:
|
|
||||||
// do nothing
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
a.ctx.fillText(label, x, (y + size.Height));
|
// rect.X += a.Axis.LineWidth;
|
||||||
|
// rect.Y -= a.Padding.Top;
|
||||||
|
// rect.W -= a.Axis.LineWidth;
|
||||||
|
// rect.W += a.Padding.Right;
|
||||||
|
// rect.H -= a.Axis.LineWidth;
|
||||||
|
// rect.H += a.Padding.Top;
|
||||||
|
|
||||||
return size;
|
// a.ctx.clearRect(rect.X, rect.Y, rect.W, rect.H);
|
||||||
}
|
|
||||||
|
|
||||||
drawRectangle(rectangle) {
|
// if (a.Debug) a.drawRectangle(rect);
|
||||||
const a = this;
|
|
||||||
|
|
||||||
a.ctx.beginPath();
|
// // Clear marker positions
|
||||||
a.ctx.rect(rectangle.X, rectangle.Y, rectangle.W, rectangle.H);
|
// const visibleEvents = a.FindVisibleEvents();
|
||||||
//a.ctx.fillStyle = 'yellow';
|
// visibleEvents.forEach(function (e, i) {
|
||||||
|
// e.Position = { X: 0, Y: 0 };
|
||||||
|
// e.HitBox = null;
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
|
||||||
|
// drawAxis() {
|
||||||
|
// const a = this;
|
||||||
|
|
||||||
|
// a.ctx.beginPath();
|
||||||
|
// a.ctx.moveTo(a.GraphRectangle.X, a.GraphRectangle.Y);
|
||||||
|
// a.ctx.lineTo(a.GraphRectangle.X, (a.GraphRectangle.H + a.GraphRectangle.Y));
|
||||||
|
// a.ctx.lineTo((a.GraphRectangle.W + a.GraphRectangle.X), (a.GraphRectangle.H + a.GraphRectangle.Y));
|
||||||
|
// a.ctx.lineWidth = a.Axis.LineWidth;
|
||||||
|
// a.ctx.strokeStyle = a.Axis.LineColour1;
|
||||||
|
// a.ctx.stroke();
|
||||||
|
// }
|
||||||
|
|
||||||
|
// drawXAxis() {
|
||||||
|
// const a = this;
|
||||||
|
|
||||||
|
// let startPosX = a.GraphRectangle.X;
|
||||||
|
// const endPosX = (a.GraphRectangle.X + a.GraphRectangle.W);
|
||||||
|
// const posY = (a.GraphRectangle.Y + a.GraphRectangle.H) + a.Axis.LineWidth;
|
||||||
|
|
||||||
|
// let i = 0;
|
||||||
|
|
||||||
|
// while (true) {
|
||||||
|
// if (startPosX >= endPosX) {
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// a.ctx.beginPath();
|
||||||
|
// a.ctx.moveTo(startPosX, posY);
|
||||||
|
|
||||||
|
// if ((i % a.Axis.X.NoPartPerDay) == 0) {
|
||||||
|
// a.ctx.lineTo(startPosX, (posY + a.Axis.X.DayLineHeight));
|
||||||
|
// a.ctx.strokeStyle = a.Axis.X.DayLineColour;
|
||||||
|
// } else {
|
||||||
|
// a.ctx.lineTo(startPosX, (posY + a.Axis.X.HourLineHeight));
|
||||||
|
// a.ctx.strokeStyle = a.Axis.X.HourLineColour;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// a.ctx.lineWidth = a.Axis.LineWidth;
|
||||||
|
// a.ctx.stroke();
|
||||||
|
|
||||||
|
// startPosX += a.Axis.X.HourLineSpace;
|
||||||
|
|
||||||
|
// i++;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// drawXAxisLabels() {
|
||||||
|
// const a = this;
|
||||||
|
|
||||||
|
// const result = a.getXAxis();
|
||||||
|
// const posY = (a.GraphRectangle.Y + a.GraphRectangle.H) + a.Axis.LineWidth;
|
||||||
|
|
||||||
|
// result.forEach(function(e, i) {
|
||||||
|
// const date = a.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) {
|
||||||
|
// // return;
|
||||||
|
// // }
|
||||||
|
|
||||||
|
// const labelSize = a.drawText(e.X, (posY + a.Axis.X.DayLineHeight), a.DateToString(date, "dd"), a.Axis.Font, a.Axis.LabelColour, "center");
|
||||||
|
|
||||||
|
// // Write month on first of the month
|
||||||
|
// if (writeLabel) {
|
||||||
|
// a.drawText(e.X, (posY + a.Axis.X.DayLineHeight + labelSize.Height + a.Axis.LabelSpacing), a.DateToString(date, "MMMM yyyy"), a.Axis.Font, a.Axis.LabelColour, "left");
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
|
||||||
|
// drawMarker(x, y, borderColour, backColour) {
|
||||||
|
// const a = this;
|
||||||
|
// const width = a.Marker.Width - (a.Marker.BorderWidth * 2);
|
||||||
|
|
||||||
|
// a.ctx.beginPath();
|
||||||
|
// a.ctx.arc(x, y, width, 0, 2 * Math.PI, false);
|
||||||
|
// a.ctx.fillStyle = backColour;
|
||||||
// a.ctx.fill();
|
// a.ctx.fill();
|
||||||
a.ctx.lineWidth = 1;
|
// a.ctx.lineWidth = a.Marker.BorderWidth;
|
||||||
a.ctx.strokeStyle = 'red';
|
// a.ctx.strokeStyle = borderColour;
|
||||||
a.ctx.stroke();
|
// a.ctx.stroke();
|
||||||
}
|
|
||||||
|
|
||||||
drawVerticalLine(x, y) {
|
// return a.measureMarker(x, y);
|
||||||
const a = this;
|
// }
|
||||||
const linePosY = (a.GraphRectangle.Y + a.GraphRectangle.H);
|
|
||||||
|
|
||||||
if (y <= 0) {
|
// drawText(x, y, label, font, foreColour, align) {
|
||||||
y = (a.GraphRectangle.Y + a.HighlightLine.Width);
|
// const a = this;
|
||||||
}
|
|
||||||
|
|
||||||
a.ctx.beginPath();
|
// a.ctx.font = font;
|
||||||
a.ctx.moveTo(x, y);
|
// a.ctx.fillStyle = foreColour;
|
||||||
a.ctx.lineTo(x, (linePosY - a.HighlightLine.Width));
|
|
||||||
a.ctx.lineWidth = a.HighlightLine.Width;
|
|
||||||
a.ctx.strokeStyle = a.HighlightLine.Colour;
|
|
||||||
a.ctx.stroke();
|
|
||||||
}
|
|
||||||
|
|
||||||
getXAxis() {
|
// const size = a.measureText(font, label);
|
||||||
const a = this;
|
|
||||||
const endPosX = (a.GraphRectangle.X + a.GraphRectangle.W);
|
|
||||||
|
|
||||||
let result = [];
|
// switch (align) {
|
||||||
let x = a.GraphRectangle.X;
|
// case "center":
|
||||||
let date = a.ConvertToDate(a.ShowDate);
|
// x = (x - size.OffsetLeft);
|
||||||
|
// break;
|
||||||
|
// case "right":
|
||||||
|
// x = (x - size.Width);
|
||||||
|
// break;
|
||||||
|
// case "left":
|
||||||
|
// default:
|
||||||
|
// // do nothing
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
|
||||||
// Rollback one day
|
// a.ctx.fillText(label, x, (y + size.Height));
|
||||||
date.setDate(date.getDate() - 1);
|
|
||||||
|
|
||||||
while (true) {
|
// return size;
|
||||||
if (x >= endPosX) {
|
// }
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
result.push({
|
// drawRectangle(rectangle) {
|
||||||
Date: a.DateToString(date, a.DateParsePattern),
|
// const a = this;
|
||||||
X: x
|
|
||||||
});
|
|
||||||
|
|
||||||
x += (a.Axis.X.HourLineSpace * a.Axis.X.NoPartPerDay);
|
// a.ctx.beginPath();
|
||||||
date.setDate(date.getDate() + 1);
|
// a.ctx.rect(rectangle.X, rectangle.Y, rectangle.W, rectangle.H);
|
||||||
}
|
// //a.ctx.fillStyle = 'yellow';
|
||||||
|
// //a.ctx.fill();
|
||||||
|
// a.ctx.lineWidth = 1;
|
||||||
|
// a.ctx.strokeStyle = 'red';
|
||||||
|
// a.ctx.stroke();
|
||||||
|
// }
|
||||||
|
|
||||||
return result;
|
// drawVerticalLine(x, y) {
|
||||||
}
|
// const a = this;
|
||||||
|
// const linePosY = (a.GraphRectangle.Y + a.GraphRectangle.H);
|
||||||
|
|
||||||
half(value) {
|
// if (y <= 0) {
|
||||||
return (value / 2);
|
// y = (a.GraphRectangle.Y + a.HighlightLine.Width);
|
||||||
}
|
// }
|
||||||
|
|
||||||
measureMarker(x, y) {
|
// a.ctx.beginPath();
|
||||||
const a = this;
|
// a.ctx.moveTo(x, y);
|
||||||
const offset = a.half(a.Marker.Width);
|
// a.ctx.lineTo(x, (linePosY - a.HighlightLine.Width));
|
||||||
|
// a.ctx.lineWidth = a.HighlightLine.Width;
|
||||||
|
// a.ctx.strokeStyle = a.HighlightLine.Colour;
|
||||||
|
// a.ctx.stroke();
|
||||||
|
// }
|
||||||
|
|
||||||
const result = {
|
// getXAxis() {
|
||||||
X: x - (offset + a.Marker.BorderWidth),
|
// const a = this;
|
||||||
Y: y - (offset + a.Marker.BorderWidth),
|
// const endPosX = (a.GraphRectangle.X + a.GraphRectangle.W);
|
||||||
W: (a.Marker.Width + (a.Marker.BorderWidth * 2)),
|
|
||||||
H: (a.Marker.Width + (a.Marker.BorderWidth * 2))
|
|
||||||
};
|
|
||||||
|
|
||||||
return result;
|
// let result = [];
|
||||||
}
|
// let x = a.GraphRectangle.X;
|
||||||
|
// let date = a.ConvertToDate(a.ShowDate);
|
||||||
|
|
||||||
measureText(font, value) {
|
// // Rollback one day
|
||||||
const a = this;
|
// date.setDate(date.getDate() - 1);
|
||||||
|
|
||||||
a.ctx.font = font;
|
// while (true) {
|
||||||
const size = a.ctx.measureText(value);
|
// if (x >= endPosX) {
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
|
||||||
return {
|
// result.push({
|
||||||
Width: size.width,
|
// Date: a.DateToString(date, a.DateParsePattern),
|
||||||
Height: size.fontBoundingBoxAscent,
|
// X: x
|
||||||
OffsetLeft: a.half(size.width),
|
// });
|
||||||
OffsetTop: a.half(size.fontBoundingBoxAscent)
|
|
||||||
};
|
// x += (a.Axis.X.HourLineSpace * a.Axis.X.NoPartPerDay);
|
||||||
}
|
// date.setDate(date.getDate() + 1);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// return result;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// half(value) {
|
||||||
|
// return (value / 2);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// measureMarker(x, y) {
|
||||||
|
// const a = this;
|
||||||
|
// const offset = a.half(a.Marker.Width);
|
||||||
|
|
||||||
|
// const result = {
|
||||||
|
// X: x - (offset + a.Marker.BorderWidth),
|
||||||
|
// Y: y - (offset + a.Marker.BorderWidth),
|
||||||
|
// W: (a.Marker.Width + (a.Marker.BorderWidth * 2)),
|
||||||
|
// H: (a.Marker.Width + (a.Marker.BorderWidth * 2))
|
||||||
|
// };
|
||||||
|
|
||||||
|
// return result;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// measureText(font, value) {
|
||||||
|
// const a = this;
|
||||||
|
|
||||||
|
// a.ctx.font = font;
|
||||||
|
// const size = a.ctx.measureText(value);
|
||||||
|
|
||||||
|
// return {
|
||||||
|
// Width: size.width,
|
||||||
|
// Height: size.fontBoundingBoxAscent,
|
||||||
|
// OffsetLeft: a.half(size.width),
|
||||||
|
// OffsetTop: a.half(size.fontBoundingBoxAscent)
|
||||||
|
// };
|
||||||
|
// }
|
||||||
|
|
||||||
ConvertToDate(value) {
|
ConvertToDate(value) {
|
||||||
return new Date(Date.parse(value));
|
return new Date(Date.parse(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
initialiseComponents() {
|
||||||
|
const a = this;
|
||||||
|
|
||||||
|
a.Container.innerHTML = "<canvas></canvas><canvas></canvas><canvas></canvas>";
|
||||||
|
|
||||||
|
const canvasList = a.Container.getElementsByTagName("canvas");
|
||||||
|
|
||||||
|
a.Layer.Background = new BBTimelineBackgroundCanvas(a, canvasList[0]);
|
||||||
|
a.Layer.Flourish = new BBTimelineCanvas(a, canvasList[1]);
|
||||||
|
a.Layer.Markers = new BBTimelineForegroundCanvas(a, canvasList[2]);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
2
bbtimeline.min.js
vendored
2
bbtimeline.min.js
vendored
File diff suppressed because one or more lines are too long
@ -11,6 +11,10 @@
|
|||||||
<!-- <link href="http://cdn.hiimray.co.uk/8206c600-707c-469e-8d49-a76ae35782af/bootstrap/5.3.0/dist/css/bootstrap.min.css" rel="stylesheet" /> -->
|
<!-- <link href="http://cdn.hiimray.co.uk/8206c600-707c-469e-8d49-a76ae35782af/bootstrap/5.3.0/dist/css/bootstrap.min.css" rel="stylesheet" /> -->
|
||||||
|
|
||||||
<script src="bbtimeline.js"></script>
|
<script src="bbtimeline.js"></script>
|
||||||
|
<script src="bbtimeline-canvas.js"></script>
|
||||||
|
<script src="bbtimeline-background-canvas.js"></script>
|
||||||
|
<script src="bbtimeline-foreground-canvas.js"></script>
|
||||||
|
|
||||||
<!-- <script src="bbtimeline.min.js"></script> -->
|
<!-- <script src="bbtimeline.min.js"></script> -->
|
||||||
|
|
||||||
<title></title>
|
<title></title>
|
||||||
@ -19,11 +23,10 @@
|
|||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="column1">
|
<div class="column1">
|
||||||
<canvas id="myCanvas"></canvas>
|
<div id="myCanvas"></div>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
<textarea id="memoBox1" readonly></textarea>
|
<textarea id="memoBox1" readonly></textarea>
|
||||||
|
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="column2">
|
<div class="column2">
|
||||||
@ -88,16 +91,6 @@ body {
|
|||||||
padding: 20px;
|
padding: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
canvas {
|
|
||||||
border-style: solid;
|
|
||||||
border-width: 1px;
|
|
||||||
border-color: #000000;
|
|
||||||
width: 100%;
|
|
||||||
height: 300px;
|
|
||||||
padding: 0;
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
textarea {
|
textarea {
|
||||||
border-style: solid;
|
border-style: solid;
|
||||||
border-width: 1px;
|
border-width: 1px;
|
||||||
@ -107,6 +100,7 @@ textarea {
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
.column1 {
|
.column1 {
|
||||||
flex: 70%;
|
flex: 70%;
|
||||||
padding: 20px;
|
padding: 20px;
|
||||||
@ -119,6 +113,17 @@ textarea {
|
|||||||
display: flex;
|
display: flex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#myCanvas {
|
||||||
|
border-style: solid;
|
||||||
|
border-width: 1px;
|
||||||
|
border-color: #000000;
|
||||||
|
width: 100%;
|
||||||
|
height: 300px;
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
Loading…
Reference in New Issue
Block a user