/** * BBTimeline * @version v0.1.1.121 beta (2023/10/18 2058) */ class BBTimelineCanvas{constructor(t,e){const n=this;n.Parent=t,n.Container=e,n.CTX=n.Container.getContext("2d"),n.ClientRectangle={X:0,Y:0,W:0,H:0},n.initialiseComponents()}initialiseComponents(){const t=this;t.Container.style.width=t.Parent.Size.W+"px",t.Container.style.height=t.Parent.Size.H+"px",t.Container.style.position="absolute",t.Container.style.border="none",t.CTX.canvas.width=t.Parent.Size.W,t.CTX.canvas.height=t.Parent.Size.H,t.Clear()}Clear(){const t=this;t.CTX.clearRect(0,0,t.CTX.canvas.width,t.CTX.canvas.height)}Invalidate(){}drawText(t,e,n,i,s,a){const o=this;o.CTX.font=i,o.CTX.fillStyle=s;const r=o.measureText(i,n);switch(a){case"center":t-=r.OffsetLeft;break;case"right":t-=r.Width}return o.CTX.fillText(n,t,e+r.Height),r}drawRectangle(t,e){const n=this;n.CTX.beginPath(),n.CTX.rect(t.X,t.Y,t.W,t.H),n.CTX.lineWidth=1,n.CTX.strokeStyle=e,n.CTX.stroke()}half(t){return t/2}measureText(t,e){const n=this;n.CTX.font=t;const i=n.CTX.measureText(e);return{Width:i.width,Height:i.fontBoundingBoxAscent,OffsetLeft:n.half(i.width),OffsetTop:n.half(i.fontBoundingBoxAscent)}}} class BBTimelineBackgroundCanvas extends BBTimelineCanvas{constructor(e,t){super(e,t);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 e=this;e.ClientRectangle={X:e.Parent.Padding.Left,Y:e.Parent.Padding.Top,W:e.Parent.Size.W-(e.Parent.Padding.Left+e.Parent.Padding.Right),H:e.Parent.Size.H-(e.Parent.Padding.Top+e.Parent.Padding.Bottom)},e.GraphRectangle={X:e.ClientRectangle.X,Y:e.ClientRectangle.Y,W:e.ClientRectangle.W,H:e.ClientRectangle.H-e.XAxisHeight},e.Margin=2*e.Parent.Marker.BorderWidth,e.StepHeight=e.Parent.Marker.Width+e.Margin,e.NoStep=Math.floor(e.GraphRectangle.H/e.StepHeight),e.Invalidate()}get XAxisHeight(){const e=this;return e.measureText(e.Parent.Axis.Font,"0").Height+e.Parent.Axis.LabelSpacing+2*e.Parent.Axis.X.DayLineHeight}get XAxisPositions(){const e=this,t=e.GraphRectangle.X+e.GraphRectangle.W;let a=[],n=e.GraphRectangle.X,i=e.Parent.ConvertToDate(e.Parent.ShowDate);for(i.setDate(i.getDate()-1);!(n>=t);)a.push({Date:e.Parent.DateToInternalString(i),X:n}),n+=e.Parent.Axis.X.HourLineSpace*e.Parent.Axis.X.NoPartPerDay,i.setDate(i.getDate()+1);return a}Invalidate(){const e=this;e.Clear(),e.drawAxis(),e.drawXAxisTicks(),e.drawXAxisLabels(),e.Parent.Debug&&e.drawRectangle(e.ClientRectangle,"red"),e.Parent.Debug&&e.drawRectangle(e.GraphRectangle,"red")}drawAxis(){const e=this;e.CTX.beginPath(),e.CTX.moveTo(e.GraphRectangle.X,e.GraphRectangle.Y),e.CTX.lineTo(e.GraphRectangle.X,e.GraphRectangle.H+e.GraphRectangle.Y),e.CTX.lineTo(e.GraphRectangle.W+e.GraphRectangle.X,e.GraphRectangle.H+e.GraphRectangle.Y),e.CTX.lineWidth=e.Parent.Axis.LineWidth,e.CTX.strokeStyle=e.Parent.Axis.LineColour1,e.CTX.stroke()}drawXAxisLabels(){const e=this,t=e.GraphRectangle.Y+e.GraphRectangle.H+e.Parent.Axis.LineWidth;e.XAxisPositions.forEach((function(a,n){const i=e.Parent.ConvertToDate(a.Date);let r=!1;0==n?i.getDate()<25&&(r=!0):1==i.getDate()&&(r=!0);const s=e.drawText(a.X,t+e.Parent.Axis.X.DayLineHeight,e.Parent.DateToString(i,"dd"),e.Parent.Axis.Font,e.Parent.Axis.LabelColour,"center");r&&e.drawText(a.X,t+e.Parent.Axis.X.DayLineHeight+s.Height+e.Parent.Axis.LabelSpacing,e.Parent.DateToString(i,"MMMM yyyy"),e.Parent.Axis.Font,e.Parent.Axis.LabelColour,"left")}))}drawXAxisTicks(){const e=this;let t=e.GraphRectangle.X;const a=e.GraphRectangle.X+e.GraphRectangle.W,n=e.GraphRectangle.Y+e.GraphRectangle.H+e.Parent.Axis.LineWidth;let i=0;for(;!(t>=a);)e.CTX.beginPath(),e.CTX.moveTo(t,n),i%e.Parent.Axis.X.NoPartPerDay==0?(e.CTX.lineTo(t,n+e.Parent.Axis.X.DayLineHeight),e.CTX.strokeStyle=e.Parent.Axis.X.DayLineColour):(e.CTX.lineTo(t,n+e.Parent.Axis.X.HourLineHeight),e.CTX.strokeStyle=e.Parent.Axis.X.HourLineColour),e.CTX.lineWidth=e.Parent.Axis.LineWidth,e.CTX.stroke(),t+=e.Parent.Axis.X.HourLineSpace,i++}} class BBTimelineFlourishCanvas extends BBTimelineCanvas{constructor(e,r){super(e,r)}DrawVerticalLine(e){const r=this,a=r.Parent.Layer.Background.GraphRectangle,n=a.Y+a.H;r.Clear(),r.CTX.beginPath(),r.CTX.moveTo(e,a.Y),r.CTX.lineTo(e,n-r.Parent.Marker.Line.Width),r.CTX.lineWidth=1,r.CTX.strokeStyle=r.Parent.HotTrack.Colour,r.CTX.stroke()}} class BBTimelineForegroundCanvas extends BBTimelineCanvas{constructor(e,r){super(e,r)}initialiseComponents(){super.initialiseComponents();const e=this;e.CTX.canvas.addEventListener("mousedown",(function(r){if(e.Parent.Enabled){var n=e.Parent.FindEventsByCoords(r.offsetX,r.offsetY);null!=n&&(e.Parent.Debug&&console.log(n),e.Parent.OnMouseDown(this,r,n))}})),e.CTX.canvas.addEventListener("click",(function(r){if(e.Parent.Enabled){var n=e.Parent.FindEventsByCoords(r.offsetX,r.offsetY);null!=n&&(e.Parent.Debug&&console.log(n),e.Parent.OnClick(this,r,n))}})),e.CTX.canvas.addEventListener("dblclick",(function(r){if(e.Parent.Enabled){var n=e.Parent.FindEventsByCoords(r.offsetX,r.offsetY);null!=n&&(e.Parent.Debug&&console.log(n),e.Parent.OnDblClick(this,r,n))}})),e.Parent.EnableHotTracking&&e.CTX.canvas.addEventListener("mousemove",(function(r){if(!e.Parent.Enabled)return;if(!e.Parent.EnableHotTracking)return;const n={X:r.offsetX,Y:r.offsetY};e.Parent.HasInterception(e.Parent.Layer.Background.GraphRectangle,n)?(e.Parent.Debug&&console.log(n),e.Parent.DrawHotTracking(n.X),e.Parent.OnMouseMove(this,r,n)):e.Parent.DrawHotTracking(-1)})),e.Invalidate()}Invalidate(){const e=this,r=e.Parent.Layer.Background.GraphRectangle,n=e.Parent.Layer.Background.Margin;e.Clear();const t=r.Y+e.Parent.Marker.Width;e.Parent.VisibleEvents.forEach((function(r,a){let o=e.calcMarkerPosition(r.Position.X,t);e.drawVerticalLine(r.Position.X,o);const i=e.drawMarker(r.Position.X,o,r.BorderColour,r.BackColour),s=e.drawText(i.X+i.W+n,i.Y,r.Label,e.Parent.Marker.Font,e.Parent.Marker.ForeColour,"left");r.Position={X:r.Position.X,Y:o},r.HitBox={X:i.X,Y:i.Y,W:i.W+n+s.Width+e.Parent.Marker.CollisionMargin,H:i.H},e.Parent.Debug&&e.drawRectangle(r.HitBox,"red"),e.Parent.Debug&&console.log(r)}))}OnMouseDown(e){if(a.Parent.Enabled){var r=a.Parent.FindEventsByCoords(e.offsetX,e.offsetY);null!=r&&(a.Parent.Debug&&console.log(r),console.log("!"),a.Parent.OnMouseDown(this,e,r))}}calcMarkerPosition(e,r){const n=this;n.Parent.Layer.Background.GraphRectangle;let t=!1,a=r;for(let o=0;o=n.X&&e<=o&&t>=n.Y&&t<=i)return a.Events[r]}return null}Load(e){this.StartDate=e,this.Show(e)}Show(e){const t=this;t.ConvertToDate(e)12?e.getHours()-12:e.getHours()).toString().padStart(2,"0")),a=a.replace("mm",e.getMinutes().toString().padStart(2,"0")),a=a.replace("ss",e.getSeconds().toString().padStart(2,"0")),a=a.replace("ff",e.getMilliseconds().toString().padStart(2,"0")),a=a.replace("tt","{5}"),a=a.replace("zz",""),a=a.replace("y",e.getFullYear().toString()),a=a.replace("M",(e.getMonth()+1).toString()),a=a.replace("d",e.getDate().toString()),a=a.replace("H",e.getHours().toString()),a=a.replace("h",(e.getHours()>12?e.getHours()-12:e.getHours()).toString()),a=a.replace("m",e.getMinutes().toString()),a=a.replace("s",e.getSeconds().toString()),a=a.replace("z",""),a=a.replace("t","{6}"),a=a.replace("Z",""),a=a.replace("{1}",e.toLocaleString("default",{month:"long"})),a=a.replace("{2}",e.toLocaleString("default",{weekday:"long"})),a=a.replace("{3}",e.toLocaleString("default",{month:"short"})),a=a.replace("{4}",e.toLocaleString("default",{weekday:"short"})),a=a.replace("{5}",e.getHours()>=12?"PM":"AM"),a=a.replace("{6}",e.getHours()>=12?"P":"A"),a}DateToInternalString(e){return this.DateToString(e,this.DateParsePattern)}DrawHotTracking(e){const t=this;e<0?t.Layer.Flourish.Clear():t.Layer.Flourish.DrawVerticalLine(e)}ConvertToDate(e){return new Date(Date.parse(e))}HasInterception(e,t){const a=e.X+e.W,r=e.Y+e.H;return t.X>=e.X&&t.X<=a&&t.Y>=e.Y&&t.Y<=r}OnMouseDown(e,t,a){}OnMouseMove(e,t,a){}OnClick(e,t,a){}OnDblClick(e,t,a){}initialiseComponents(){const e=this;e.Container.innerHTML="";const t=e.Container.getElementsByTagName("canvas");e.Layer.Background=new BBTimelineBackgroundCanvas(e,t[0]),e.Layer.Flourish=new BBTimelineFlourishCanvas(e,t[1]),e.Layer.Markers=new BBTimelineForegroundCanvas(e,t[2])}}