diff --git a/bbtimeline.js b/bbtimeline.js index 928b083..81bb04a 100644 --- a/bbtimeline.js +++ b/bbtimeline.js @@ -7,22 +7,29 @@ class BBTimeline { const a = this; a.Container = document.getElementById(el); - + a.DateParsePattern = "yyyy-MM-dd"; + a.Debug = false; a.Padding = { Left: 20, Top: 20, Right: 20, - Bottom: 40 + Bottom: 0 }; a.Size = { - Width: a.Container.innerWidth || a.Container.clientWidth, - Height: a.Container.innerHeight || a.Container.clientHeight + W: a.Container.innerWidth || a.Container.clientWidth, + H: a.Container.innerHeight || a.Container.clientHeight }; + + a.ctx = a.Container.getContext("2d"); + a.ctx.canvas.width = a.Size.W; + a.ctx.canvas.height = a.Size.H; + a.Axis = { LineColour1: "#CFCFCF", LineWidth: 1, Font: "8pt Arial", LabelColour: "#000000", + LabelSpacing: 6, X: { NoPartPerDay: 4, HourLineSpace: 6, @@ -46,16 +53,10 @@ class BBTimeline { Width: 1, }; a.Events = []; - a.StartDate = a.DateToString(new Date(), "yyyy-MM-dd"); + a.StartDate = a.DateToString(new Date(), a.DateParsePattern); a.ShowDate = a.StartDate; - a.LastDate = null; - a.GraphRectangle = a.calcGraphArea(); + a.GraphRectangle = a.calcGraphRectangle(); a.Enabled = false; - a.Debug = false; - - a.ctx = a.Container.getContext("2d"); - a.ctx.canvas.width = a.Size.Width; - a.ctx.canvas.height = a.Size.Height; a.initialiseComponents(); } @@ -79,16 +80,29 @@ class BBTimeline { event.Events.push(_options); } + CalcEndDate() { + const a = this; + + const calcdays = Math.floor(a.GraphRectangle.W / (a.Axis.X.NoPartPerDay * a.Axis.X.HourLineSpace)); + + let date = a.ConvertToDate(a.ShowDate); + date.setDate(date.getDate() + calcdays); + + // Minus one for lead up + date.setDate(date.getDate() - 1); + + return a.DateToString(date, a.DateParsePattern); + } + Clear() { const a = this; a.ctx.clearRect(0, 0, a.ctx.canvas.width, a.ctx.canvas.height); - a.StartDate = a.DateToString(new Date(), "yyyy-MM-dd"); + a.StartDate = a.DateToString(new Date(), a.DateParsePattern); a.ShowDate = a.StartDate; a.Enabled = false; a.Events = []; - a.LastDate = null; } DeleteMarker(date) @@ -158,7 +172,7 @@ class BBTimeline { continue; } - if ((x >= e.X1) && (x <= e.X2) && (y >= e.Y1) && (y <= e.Y2)){ + if ((x >= e.X) && (x <= e.X2) && (y >= e.Y) && (y <= e.Y2)){ return a.Events[i]; } } @@ -177,7 +191,7 @@ class BBTimeline { Show(date) { const a = this; - if (a.stringToDate(date) < a.stringToDate(a.StartDate)) { + if (a.ConvertToDate(date) < a.ConvertToDate(a.StartDate)) { date = a.StartDate; } @@ -190,19 +204,19 @@ class BBTimeline { ShowNext() { const a = this; - let date = a.stringToDate(a.ShowDate); + let date = a.ConvertToDate(a.ShowDate); date.setMonth(date.getMonth() + 1); - a.Show(a.DateToString(date, "yyyy-MM-dd")); + a.Show(a.DateToString(date, a.DateParsePattern)); } ShowPrevious() { const a = this; - let date = a.stringToDate(a.ShowDate); + let date = a.ConvertToDate(a.ShowDate); date.setMonth(date.getMonth() - 1); - a.Show(a.DateToString(date, "yyyy-MM-dd")); + a.Show(a.DateToString(date, a.DateParsePattern)); } UpdateLabel(date, label) { @@ -234,7 +248,6 @@ class BBTimeline { initialiseComponents() { const a = this; - const coords = a.getClientCoords(); a.ctx.canvas.addEventListener('mousedown', function (e) { if (!a.Enabled) { @@ -248,7 +261,7 @@ class BBTimeline { if (a.Debug) console.log(event); - a.OnEventClick(event); + a.OnEventClick(this, e, event); }); } @@ -266,27 +279,26 @@ class BBTimeline { if (redrawMarkers) { a.clearChart(); + const startPosY = (a.GraphRectangle.Y + a.Marker.Width); const visibleEvents = a.FindVisibleEvents(); - const coords = a.getClientCoords(); - coords.Y1 += a.Marker.Width; if (a.Debug) console.log(visibleEvents); visibleEvents.forEach(function (e, i) { // Calculate Y position - let posY = a.calcMarkerPosition(e.Position.X, coords.Y1); + let posY = a.calcMarkerPosition(e.Position.X, startPosY); a.drawVerticalLine(e.Position.X, posY); - const markerCoords = a.drawMarker(e.Position.X, posY, e.BorderColour, e.BackColour); - const labelSize = a.drawText((markerCoords.X2 + a.GraphRectangle.Margin), markerCoords.Y1, e.Label, a.Marker.Font, a.Marker.ForeColour, "left"); + const markerRectangle = a.drawMarker(e.Position.X, posY, e.BorderColour, e.BackColour); + const labelSize = a.drawText((markerRectangle.X + markerRectangle.W + a.GraphRectangle.Margin), markerRectangle.Y, e.Label, a.Marker.Font, a.Marker.ForeColour, "left"); e.Position = { X: e.Position.X, Y: posY }; e.HitBox = { - X1: markerCoords.X1, - Y1: markerCoords.Y1, - X2: (markerCoords.X2 + a.GraphRectangle.Margin + labelSize.Width), - Y2: markerCoords.Y2 + X: markerRectangle.X, + Y: markerRectangle.Y, + X2: (markerRectangle.X + a.GraphRectangle.Margin + labelSize.Width), + Y2: (markerRectangle.Y + markerRectangle.H) }; if (a.Debug) a.drawRectangle(e.HitBox); @@ -366,27 +378,41 @@ class BBTimeline { return result; } - OnEventClick(event) { + OnEventClick(sender, e, event) { } - calcGraphArea() { + calcGraphRectangle() { const a = this; + const xAxisHeight = a.calcXAxisHeight(); + let result = { X: a.Padding.Left, Y: a.Padding.Top, - Width: (a.Size.Width - a.Padding.Right), - Height: (a.Size.Height - a.Padding.Bottom), + W: (a.Size.W - (a.Padding.Left + a.Padding.Right)), + H: (a.Size.H - (a.Padding.Top + a.Padding.Bottom) - xAxisHeight), Margin: (a.Marker.BorderWidth * 2) }; result.StepHeight = a.Marker.Width + result.Margin; - result.NoStep = Math.floor(result.Height / result.StepHeight); + result.NoStep = Math.floor(result.H / result.StepHeight); return result; } + calcXAxisHeight() { + const a = this; + + console.log(a.Axis.Font); + 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; @@ -413,9 +439,8 @@ class BBTimeline { clearChart() { const a = this; - const rect = a.getClientCoords(); - a.ctx.clearRect((rect.X1 + a.Axis.LineWidth), rect.Y1, (rect.X2 - rect.X1 - a.Axis.LineWidth), (rect.Y2 - rect.Y1 - a.Axis.LineWidth)); + a.ctx.clearRect((a.GraphRectangle.X + a.Axis.LineWidth), a.GraphRectangle.Y, (a.GraphRectangle.W -a.Axis.LineWidth), (a.GraphRectangle.H - a.Axis.LineWidth)); // Clear marker positions const visibleEvents = a.FindVisibleEvents(); @@ -427,15 +452,11 @@ class BBTimeline { drawAxis() { const a = this; - const coords = a.getClientCoords(); - if (coords == null) { - return; - } a.ctx.beginPath(); - a.ctx.moveTo(coords.X1, coords.Y1); - a.ctx.lineTo(coords.X1, coords.Y2); - a.ctx.lineTo(coords.X2, coords.Y2); + 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(); @@ -445,36 +466,33 @@ class BBTimeline { drawXAxis() { const a = this; - const coords = a.getClientCoords(); - if (coords == null) { - return; - } - let x = coords.X1; - let y = coords.Y2 + a.Axis.LineWidth; + 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 (x >= coords.X2) { + if (startPosX >= endPosX) { break; } a.ctx.beginPath(); - a.ctx.moveTo(x, y); + a.ctx.moveTo(startPosX, posY); if ((i % a.Axis.X.NoPartPerDay) == 0) { - a.ctx.lineTo(x, (y + a.Axis.X.DayLineHeight)); + a.ctx.lineTo(startPosX, (posY + a.Axis.X.DayLineHeight)); a.ctx.strokeStyle = a.Axis.X.DayLineColour; } else { - a.ctx.lineTo(x, (y + a.Axis.X.HourLineHeight)); + 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(); - x += a.Axis.X.HourLineSpace; + startPosX += a.Axis.X.HourLineSpace; i++; } @@ -482,17 +500,12 @@ class BBTimeline { drawXAxisLabels() { const a = this; - const coords = a.getClientCoords(); - if (coords == null) { - return; - } const result = a.getXAxis(); - - const y = coords.Y2 + a.Axis.LineWidth; + const posY = (a.GraphRectangle.Y + a.GraphRectangle.H) + a.Axis.LineWidth; result.forEach(function(e, i) { - const date = a.stringToDate(e.Date); + const date = a.ConvertToDate(e.Date); let writeLabel = false; if ((i == 0)) { @@ -508,25 +521,17 @@ class BBTimeline { // return; // } - const labelSize = a.drawText(e.X, (y + a.Axis.X.DayLineHeight), a.DateToString(date, "dd"), a.Axis.Font, a.Axis.LabelColour, "center"); - const label2Spacing = 6; - - a.LastDate = a.DateToString(date, "yyyy-MM-dd"); + 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, (y + a.Axis.X.DayLineHeight + labelSize.Height + label2Spacing), a.DateToString(date, "MMMM yyyy"), a.Axis.Font, a.Axis.LabelColour, "left"); + 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 coords = a.getClientCoords(); - if (coords == null) { - return; - } - const width = a.Marker.Width - (a.Marker.BorderWidth * 2); a.ctx.beginPath(); @@ -570,7 +575,7 @@ class BBTimeline { const a = this; a.ctx.beginPath(); - a.ctx.rect(coords.X1, coords.Y1, (coords.X2 - coords.X1), (coords.Y2 - coords.Y1)); + a.ctx.rect(coords.X, coords.Y, (coords.X2 - coords.X), (coords.Y2 - coords.Y)); //a.ctx.fillStyle = 'yellow'; //a.ctx.fill(); a.ctx.lineWidth = 1; @@ -580,59 +585,38 @@ class BBTimeline { drawVerticalLine(x, y) { const a = this; - const coords = a.getClientCoords(); - if (coords == null) { - return; - } + const linePosY = (a.GraphRectangle.Y + a.GraphRectangle.H); if (y <= 0) { - y = (coords.Y1 + a.HighlightLine.Width); + y = (a.GraphRectangle.Y + a.HighlightLine.Width); } a.ctx.beginPath(); a.ctx.moveTo(x, y); - a.ctx.lineTo(x, (coords.Y2 - a.HighlightLine.Width)); + a.ctx.lineTo(x, (linePosY - a.HighlightLine.Width)); a.ctx.lineWidth = a.HighlightLine.Width; a.ctx.strokeStyle = a.HighlightLine.Colour; a.ctx.stroke(); } - getClientCoords() { - const a = this; - - if (a.GraphRectangle == null) { - return null; - } - - return { - X1: a.GraphRectangle.X, - Y1: a.GraphRectangle.Y, - X2: (a.GraphRectangle.Width - a.GraphRectangle.X), - Y2: (a.GraphRectangle.Height - a.GraphRectangle.Y) - }; - } - getXAxis() { const a = this; - const coords = a.getClientCoords(); - if (coords == null) { - return; - } + const endPosX = (a.GraphRectangle.X + a.GraphRectangle.W); let result = []; - let x = coords.X1; - let date = a.stringToDate(a.ShowDate); + let x = a.GraphRectangle.X; + let date = a.ConvertToDate(a.ShowDate); // Rollback one day date.setDate(date.getDate() - 1); while (true) { - if (x >= coords.X2) { + if (x >= endPosX) { break; } result.push({ - Date: a.DateToString(date, "yyyy-MM-dd"), + Date: a.DateToString(date, a.DateParsePattern), X: x }); @@ -652,10 +636,10 @@ class BBTimeline { const offset = a.half(a.Marker.Width); const result = { - X1: x - (offset + a.Marker.BorderWidth), - Y1: y - (offset + a.Marker.BorderWidth), - X2: x + (offset + a.Marker.BorderWidth), - Y2: y + (offset + a.Marker.BorderWidth) + 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; @@ -675,7 +659,7 @@ class BBTimeline { }; } - stringToDate(value) { + ConvertToDate(value) { return new Date(Date.parse(value)); } diff --git a/demo-test.html b/demo-test.html index 6c4582e..3028456 100644 --- a/demo-test.html +++ b/demo-test.html @@ -61,7 +61,7 @@ canvas {