WIP: Added event markers and marker hit-boxes
This commit is contained in:
		
							parent
							
								
									8b0701b2e5
								
							
						
					
					
						commit
						00c38a5e00
					
				
							
								
								
									
										145
									
								
								bbtimeline.js
									
									
									
									
									
								
							
							
						
						
									
										145
									
								
								bbtimeline.js
									
									
									
									
									
								
							| @ -42,12 +42,16 @@ class BBTimeline { | |||||||
|       Colour: "#A6A6A6", |       Colour: "#A6A6A6", | ||||||
|       Width: 1, |       Width: 1, | ||||||
|     }; |     }; | ||||||
|  |     a.Events = []; | ||||||
|     a.StartDate = new Date(); |     a.StartDate = new Date(); | ||||||
|     a.ClientRectangle = a.getClientRectangle(); |     a.ClientRectangle = a.getClientRectangle(); | ||||||
|  |     a.Enabled = false; | ||||||
| 
 | 
 | ||||||
|     a.ctx = a.Container.getContext("2d"); |     a.ctx = a.Container.getContext("2d"); | ||||||
|     a.ctx.canvas.width = a.Size.Width; |     a.ctx.canvas.width = a.Size.Width; | ||||||
|     a.ctx.canvas.height = a.Size.Height; |     a.ctx.canvas.height = a.Size.Height; | ||||||
|  | 
 | ||||||
|  |     a.initialiseComponents(); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   Load(startDate) { |   Load(startDate) { | ||||||
| @ -55,8 +59,9 @@ class BBTimeline { | |||||||
| 
 | 
 | ||||||
|     a.StartDate = ((typeof(startDate) == "undefined") ? new Date() : startDate); |     a.StartDate = ((typeof(startDate) == "undefined") ? new Date() : startDate); | ||||||
| 
 | 
 | ||||||
|     a.invalidate(); |     a.invalidate(true); | ||||||
|     a.initialiseComponents(); | 
 | ||||||
|  |     a.Enabled = true; | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   Clear(all) { |   Clear(all) { | ||||||
| @ -64,46 +69,117 @@ class BBTimeline { | |||||||
| 
 | 
 | ||||||
|     if (all) { |     if (all) { | ||||||
|       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); | ||||||
|  | 
 | ||||||
|  |       a.Events = []; | ||||||
|  |       a.Enabled = false; | ||||||
|     } else { |     } else { | ||||||
|       const rect = a.getChartCoords(); |       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((rect.X1 + a.Axis.LineWidth), rect.Y1, (rect.X2 - rect.X1 - a.Axis.LineWidth), (rect.Y2 - rect.Y1 - a.Axis.LineWidth)); | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|  |   FindDate(date) { | ||||||
|  |     const a = this; | ||||||
|  | 
 | ||||||
|  |     const points = a.getXAxis(); | ||||||
|  |     for (let i=0; i<points.length; i++) { | ||||||
|  |       if (points[i].Date == date){ | ||||||
|  |         return points[i]; | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     return null; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   FindEventByCoords(x, y) { | ||||||
|  |     const a = this; | ||||||
|  | 
 | ||||||
|  |     for (let i=0; i<a.Events.length; i++) { | ||||||
|  |       const e = a.Events[i].Rectangle; | ||||||
|  | 
 | ||||||
|  |       if ((x >= e.X1) && (x <= e.X2) && (y >= e.Y1) && (y <= e.Y2)){ | ||||||
|  |         return a.Events[i]; | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     return null; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   AddEvent(date, title, description, link) { | ||||||
|  |     const a = this; | ||||||
|  | 
 | ||||||
|  |     a.Events.push({ | ||||||
|  |       Date: date, | ||||||
|  |       Title: title, | ||||||
|  |       Description: description, | ||||||
|  |       Link: link | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|  |     a.invalidate(false); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|   initialiseComponents() { |   initialiseComponents() { | ||||||
|     const a = this; |     const a = this; | ||||||
|     const coords = a.getChartCoords(); |     const coords = a.getClientCoords(); | ||||||
| 
 | 
 | ||||||
|     // Vertical highlight line
 |     // Vertical highlight line
 | ||||||
|     a.ctx.canvas.addEventListener('mousemove', function (e) { |     // a.ctx.canvas.addEventListener('mousemove', function (e) {
 | ||||||
|       a.Clear(false); |     //   if (!a.Enabled) {
 | ||||||
|  |     //     return;
 | ||||||
|  |     //   }
 | ||||||
| 
 | 
 | ||||||
|       if ((e.offsetX > (coords.X1 + a.Axis.LineWidth)) && (e.offsetX < coords.X2) && (e.offsetY >= coords.Y1) && (e.offsetY < (coords.Y2 - a.Axis.LineWidth))){ |     //   a.invalidate(false);
 | ||||||
|         a.drawVerticalLine(e.offsetX); | 
 | ||||||
|       } |     //   if ((e.offsetX > (coords.X1 + a.Axis.LineWidth)) && (e.offsetX < coords.X2) && (e.offsetY >= coords.Y1) && (e.offsetY < (coords.Y2 - a.Axis.LineWidth))){
 | ||||||
|     }); |     //     a.drawVerticalLine(e.offsetX);
 | ||||||
|  |     //   }
 | ||||||
|  |     // });
 | ||||||
| 
 | 
 | ||||||
|     a.ctx.canvas.addEventListener('mousedown', function (e) { |     a.ctx.canvas.addEventListener('mousedown', function (e) { | ||||||
|       console.log('mousedown'); |       if (!a.Enabled) { | ||||||
|       console.log(e); |         return; | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       var event = a.FindEventByCoords(e.offsetX, e.offsetY); | ||||||
|  | 
 | ||||||
|  |       console.log(event); | ||||||
|  | 
 | ||||||
|  |       // console.log(e);
 | ||||||
|    }); |    }); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   invalidate() { |   invalidate(all) { | ||||||
|     const a = this; |     const a = this; | ||||||
| 
 | 
 | ||||||
|     a.Clear(true); |     a.Clear(all); | ||||||
| 
 | 
 | ||||||
|  |     if (all) { | ||||||
|       a.drawAxis(); |       a.drawAxis(); | ||||||
|       a.drawXAxis(); |       a.drawXAxis(); | ||||||
|       a.drawXAxisLabels(); |       a.drawXAxisLabels(); | ||||||
|  |     } else { | ||||||
|  |       const coords = a.getClientCoords(); | ||||||
|  |       coords.Y1 += a.Marker.Width; | ||||||
|  | 
 | ||||||
|  |       for (let i=0; i<a.Events.length; i++) { | ||||||
|  |         const event = a.FindDate(a.Events[i].Date); | ||||||
|  | 
 | ||||||
|  |         a.drawVerticalLine(event.X, coords.Y1); | ||||||
|  | 
 | ||||||
|  |         const rect = a.drawMarker(event.X, coords.Y1); | ||||||
|  |         a.Events[i].Rectangle = rect; | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       console.log(a.Events); | ||||||
|  |     } | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|   drawAxis() { |   drawAxis() { | ||||||
|     const a = this; |     const a = this; | ||||||
|     const coords = a.getChartCoords(); |     const coords = a.getClientCoords(); | ||||||
|     if (coords == null) { |     if (coords == null) { | ||||||
|       return; |       return; | ||||||
|     } |     } | ||||||
| @ -119,7 +195,7 @@ class BBTimeline { | |||||||
| 
 | 
 | ||||||
|   drawXAxis() { |   drawXAxis() { | ||||||
|     const a = this; |     const a = this; | ||||||
|     const coords = a.getChartCoords(); |     const coords = a.getClientCoords(); | ||||||
|     if (coords == null) { |     if (coords == null) { | ||||||
|       return; |       return; | ||||||
|     } |     } | ||||||
| @ -156,7 +232,7 @@ class BBTimeline { | |||||||
| 
 | 
 | ||||||
|   drawXAxisLabels() { |   drawXAxisLabels() { | ||||||
|     const a = this; |     const a = this; | ||||||
|     const coords = a.getChartCoords(); |     const coords = a.getClientCoords(); | ||||||
|     if (coords == null) { |     if (coords == null) { | ||||||
|       return; |       return; | ||||||
|     } |     } | ||||||
| @ -194,7 +270,7 @@ class BBTimeline { | |||||||
| 
 | 
 | ||||||
|   drawMarker(x, y) { |   drawMarker(x, y) { | ||||||
|     const a = this; |     const a = this; | ||||||
|     const coords = a.getChartCoords(); |     const coords = a.getClientCoords(); | ||||||
|     if (coords == null) { |     if (coords == null) { | ||||||
|       return; |       return; | ||||||
|     } |     } | ||||||
| @ -208,6 +284,25 @@ class BBTimeline { | |||||||
|     a.ctx.lineWidth = a.Marker.BorderWidth; |     a.ctx.lineWidth = a.Marker.BorderWidth; | ||||||
|     a.ctx.strokeStyle = a.Marker.BorderColour; |     a.ctx.strokeStyle = a.Marker.BorderColour; | ||||||
|     a.ctx.stroke(); |     a.ctx.stroke(); | ||||||
|  | 
 | ||||||
|  |     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) | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     // a.ctx.beginPath();
 | ||||||
|  |     // a.ctx.rect(result.X1, result.Y1, (result.X2 - result.X1), (result.Y2 - result.Y1));
 | ||||||
|  |     // a.ctx.fillStyle = 'yellow';
 | ||||||
|  |     // a.ctx.fill();
 | ||||||
|  |     // a.ctx.lineWidth = 1;
 | ||||||
|  |     // a.ctx.strokeStyle = 'black';
 | ||||||
|  |     // a.ctx.stroke();
 | ||||||
|  | 
 | ||||||
|  |     return result; | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   drawText(x, y, label, align) { |   drawText(x, y, label, align) { | ||||||
| @ -236,22 +331,26 @@ class BBTimeline { | |||||||
|     return size; |     return size; | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   drawVerticalLine(x) { |   drawVerticalLine(x, y) { | ||||||
|     const a = this; |     const a = this; | ||||||
|     const coords = a.getChartCoords(); |     const coords = a.getClientCoords(); | ||||||
|     if (coords == null) { |     if (coords == null) { | ||||||
|       return; |       return; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     if (y <= 0) { | ||||||
|  |       y = (coords.Y1 + a.HighlightLine.Width); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     a.ctx.beginPath(); |     a.ctx.beginPath(); | ||||||
|     a.ctx.moveTo(x, (coords.Y1 + a.HighlightLine.Width)); |     a.ctx.moveTo(x, y); | ||||||
|     a.ctx.lineTo(x, (coords.Y2 - a.HighlightLine.Width)); |     a.ctx.lineTo(x, (coords.Y2 - a.HighlightLine.Width)); | ||||||
|     a.ctx.lineWidth = a.HighlightLine.Width; |     a.ctx.lineWidth = a.HighlightLine.Width; | ||||||
|     a.ctx.strokeStyle = a.HighlightLine.Colour; |     a.ctx.strokeStyle = a.HighlightLine.Colour; | ||||||
|     a.ctx.stroke(); |     a.ctx.stroke(); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   getChartCoords() { |   getClientCoords() { | ||||||
|     const a = this; |     const a = this; | ||||||
| 
 | 
 | ||||||
|     if (a.ClientRectangle == null) { |     if (a.ClientRectangle == null) { | ||||||
| @ -279,7 +378,7 @@ class BBTimeline { | |||||||
| 
 | 
 | ||||||
|   getXAxis() { |   getXAxis() { | ||||||
|     const a = this; |     const a = this; | ||||||
|     const coords = a.getChartCoords(); |     const coords = a.getClientCoords(); | ||||||
|     if (coords == null) { |     if (coords == null) { | ||||||
|       return; |       return; | ||||||
|     } |     } | ||||||
|  | |||||||
| @ -23,6 +23,8 @@ | |||||||
| 
 | 
 | ||||||
| <p> | <p> | ||||||
|   <button onclick="Clear()">Clear</button> |   <button onclick="Clear()">Clear</button> | ||||||
|  |   <button onclick="LoadToday()">Load Today</button> | ||||||
|  |   <button onclick="LoadNext()">Load Next Month</button> | ||||||
| 
 | 
 | ||||||
| </p> | </p> | ||||||
| 
 | 
 | ||||||
| @ -37,7 +39,7 @@ canvas { | |||||||
|   border-width: 1px; |   border-width: 1px; | ||||||
|   border-color: #000000; |   border-color: #000000; | ||||||
|   width: 100%; |   width: 100%; | ||||||
|   height: 400px; |   height: 300px; | ||||||
|   padding: 0; |   padding: 0; | ||||||
|   margin: 0; |   margin: 0; | ||||||
| } | } | ||||||
| @ -49,15 +51,30 @@ canvas { | |||||||
| var timeline1 = new BBTimeline("myCanvas"); | var timeline1 = new BBTimeline("myCanvas"); | ||||||
| 
 | 
 | ||||||
| timeline1.Load(); | timeline1.Load(); | ||||||
|  | timeline1.AddEvent("2023-10-05", "title", "description", "link"); | ||||||
|  | timeline1.AddEvent("2023-10-06", "title", "description", "link"); | ||||||
|  | timeline1.AddEvent("2023-10-16", "title", "description", "link"); | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| function Clear() | function Clear() | ||||||
| { | { | ||||||
|   timeline1.Clear(); |   timeline1.Clear(true); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | function LoadToday() | ||||||
|  | { | ||||||
|  |   timeline1.Load(new Date()); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | function LoadNext() | ||||||
|  | { | ||||||
|  |   let date = timeline1.StartDate; | ||||||
|  |   date.setMonth(date.getMonth() + 1); | ||||||
|  | 
 | ||||||
|  |   timeline1.Load(date); | ||||||
|  | } | ||||||
| 
 | 
 | ||||||
| </script> | </script> | ||||||
| 
 | 
 | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Ray
						Ray