2023-09-30 22:45:55 +00:00
|
|
|
<!doctype html>
|
|
|
|
<html lang="en-GB">
|
|
|
|
<head>
|
|
|
|
<meta charset="UTF-8" />
|
|
|
|
<meta http-equiv="content-type" content="text/html" charset="UTF-8" />
|
|
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
|
|
<meta name="description" content="" />
|
|
|
|
<meta name="keyword" content="" />
|
|
|
|
|
|
|
|
<!-- <script src="http://cdn.hiimray.co.uk/8206c600-707c-469e-8d49-a76ae35782af/bootstrap/5.3.0/dist/js/bootstrap.bundle.min.js"></script> -->
|
|
|
|
<!-- <link href="http://cdn.hiimray.co.uk/8206c600-707c-469e-8d49-a76ae35782af/bootstrap/5.3.0/dist/css/bootstrap.min.css" rel="stylesheet" /> -->
|
|
|
|
|
2023-10-22 21:14:12 +00:00
|
|
|
<script src="bbtimeline.js"></script>
|
2023-10-18 13:44:49 +00:00
|
|
|
<script src="bbtimeline-canvas.js"></script>
|
|
|
|
<script src="bbtimeline-background-canvas.js"></script>
|
2023-10-19 23:22:29 +00:00
|
|
|
<script src="bbtimeline-flourish-canvas.js"></script>
|
2023-10-22 21:14:12 +00:00
|
|
|
<script src="bbtimeline-foreground-canvas.js"></script>
|
2023-10-18 13:44:49 +00:00
|
|
|
|
2023-10-22 21:14:12 +00:00
|
|
|
<!-- <script src="bbtimeline.min.js"></script> -->
|
2023-09-30 22:45:55 +00:00
|
|
|
|
|
|
|
<title></title>
|
|
|
|
</head>
|
|
|
|
<body>
|
|
|
|
|
2023-10-06 00:05:54 +00:00
|
|
|
<div class="row">
|
|
|
|
<div class="column1">
|
2023-10-18 13:44:49 +00:00
|
|
|
<div id="myCanvas"></div>
|
2023-10-06 00:05:54 +00:00
|
|
|
|
|
|
|
<p>
|
|
|
|
<textarea id="memoBox1" readonly></textarea>
|
|
|
|
</p>
|
|
|
|
</div>
|
|
|
|
<div class="column2">
|
|
|
|
|
|
|
|
<p>
|
|
|
|
<button onclick="Clear()">Clear</button>
|
2023-10-22 21:14:12 +00:00
|
|
|
<button onclick="Refresh()">Refresh</button>
|
|
|
|
</p>
|
|
|
|
|
|
|
|
<hr />
|
|
|
|
|
|
|
|
<p>
|
2023-10-06 00:05:54 +00:00
|
|
|
<button onclick="ToggleDebug()">Toggle Debug</button>
|
2023-10-22 21:14:12 +00:00
|
|
|
</p>
|
|
|
|
|
|
|
|
<hr />
|
|
|
|
<p>
|
2023-10-19 23:22:29 +00:00
|
|
|
<button onclick="ToggleHotTracking()">Toggle Hot Tracking</button>
|
2023-10-22 21:14:12 +00:00
|
|
|
<button onclick="ToggleShowLabel()">Toggle Marker Label</button>
|
|
|
|
<button onclick="ToggleMarkerTail()">Toggle Marker Tail</button>
|
2023-10-06 00:05:54 +00:00
|
|
|
</p>
|
2023-10-22 21:14:12 +00:00
|
|
|
<p>
|
|
|
|
<button onclick="ToggleXAxisPosition()">Toggle X-Axis Position</button>
|
|
|
|
</p>
|
|
|
|
|
2023-10-06 00:05:54 +00:00
|
|
|
<hr />
|
|
|
|
|
|
|
|
<p>
|
|
|
|
<button onclick="SetToday()">Set Today</button>
|
|
|
|
</p>
|
|
|
|
<hr />
|
|
|
|
|
|
|
|
<p>
|
|
|
|
<button onclick="GenerateRandomMarker()">Add/Generate Random Marker</button>
|
|
|
|
</p>
|
|
|
|
<hr />
|
|
|
|
|
|
|
|
<p>
|
|
|
|
<button onclick="GoToToday()">Show Start Date</button>
|
2023-10-19 23:22:29 +00:00
|
|
|
<button onclick="GoToPrevious()">Show Previous</button>
|
|
|
|
<button onclick="GoToNext()">Show Next</button>
|
2023-10-06 00:05:54 +00:00
|
|
|
</p>
|
|
|
|
<hr />
|
|
|
|
|
|
|
|
<p>
|
|
|
|
<button onclick="UpdateLabel()">Rename Marker</button>
|
|
|
|
<button onclick="UpdateMarker()">Change Marker Style</button>
|
|
|
|
<button onclick="DeleteMarker()">Delete Marker</button>
|
|
|
|
</p>
|
|
|
|
<hr />
|
|
|
|
|
|
|
|
<p>
|
|
|
|
<button onclick="FindVisibleEvents()">Find Visible Events</button>
|
|
|
|
<button onclick="FindAllEvents()">Find All Events</button>
|
|
|
|
</p>
|
|
|
|
<hr />
|
|
|
|
|
|
|
|
|
|
|
|
<p>
|
|
|
|
<input type="date" id="textbox1" />
|
|
|
|
<button onclick="FindEvent()">Find Event (By Date)</button>
|
|
|
|
</p>
|
|
|
|
<p>
|
|
|
|
<input type="date" id="textbox2" />
|
|
|
|
<button onclick="FindDatePosition()">Find Date Position (If Visible)</button>
|
|
|
|
</p>
|
|
|
|
<hr />
|
|
|
|
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2023-09-30 22:45:55 +00:00
|
|
|
<style>
|
|
|
|
|
|
|
|
body {
|
|
|
|
padding: 20px;
|
|
|
|
}
|
|
|
|
|
2023-10-06 00:05:54 +00:00
|
|
|
textarea {
|
|
|
|
border-style: solid;
|
|
|
|
border-width: 1px;
|
|
|
|
border-color: #000000;
|
|
|
|
min-height: calc(100vh - 500px);
|
|
|
|
padding: 10px;
|
|
|
|
width: 100%;
|
|
|
|
}
|
|
|
|
|
2023-10-18 13:44:49 +00:00
|
|
|
|
2023-10-06 00:05:54 +00:00
|
|
|
.column1 {
|
|
|
|
flex: 70%;
|
|
|
|
padding: 20px;
|
|
|
|
}
|
|
|
|
.column2 {
|
|
|
|
flex: 30%;
|
|
|
|
padding: 20px;
|
|
|
|
}
|
|
|
|
.row {
|
|
|
|
display: flex;
|
|
|
|
}
|
|
|
|
|
2023-10-18 13:44:49 +00:00
|
|
|
|
|
|
|
#myCanvas {
|
|
|
|
border-style: solid;
|
|
|
|
border-width: 1px;
|
|
|
|
border-color: #000000;
|
|
|
|
width: 100%;
|
|
|
|
height: 300px;
|
|
|
|
padding: 0;
|
|
|
|
margin: 0;
|
|
|
|
}
|
|
|
|
|
2023-09-30 22:45:55 +00:00
|
|
|
</style>
|
|
|
|
|
|
|
|
<script>
|
|
|
|
|
|
|
|
var timeline1 = new BBTimeline("myCanvas");
|
2023-10-08 14:57:22 +00:00
|
|
|
timeline1.OnMouseDown = function(sender, e, event) {
|
|
|
|
LogInfo("");
|
|
|
|
LogInfo("OnMouseDown");
|
|
|
|
LogInfo(JSON.stringify(sender));
|
|
|
|
LogInfo(JSON.stringify(e));
|
|
|
|
LogInfo(JSON.stringify(event));
|
|
|
|
LogInfo("");
|
|
|
|
}
|
|
|
|
timeline1.OnClick = function(sender, e, event) {
|
|
|
|
LogInfo("");
|
|
|
|
LogInfo("OnClick");
|
|
|
|
LogInfo(JSON.stringify(sender));
|
|
|
|
LogInfo(JSON.stringify(e));
|
|
|
|
LogInfo(JSON.stringify(event));
|
|
|
|
LogInfo("");
|
2023-10-02 22:42:08 +00:00
|
|
|
}
|
2023-10-19 23:22:29 +00:00
|
|
|
timeline1.OnDblClick = function(sender, e, event) {
|
|
|
|
LogInfo("");
|
|
|
|
LogInfo("OnDblClick");
|
|
|
|
LogInfo(JSON.stringify(sender));
|
|
|
|
LogInfo(JSON.stringify(e));
|
|
|
|
LogInfo(JSON.stringify(event));
|
|
|
|
LogInfo("");
|
|
|
|
}
|
2023-10-02 22:42:08 +00:00
|
|
|
|
2023-10-06 00:05:54 +00:00
|
|
|
SetToday();
|
2023-09-30 22:45:55 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2023-10-06 00:05:54 +00:00
|
|
|
function Clear() {
|
2023-10-01 02:37:24 +00:00
|
|
|
timeline1.Clear(true);
|
2023-09-30 22:45:55 +00:00
|
|
|
}
|
|
|
|
|
2023-10-06 00:05:54 +00:00
|
|
|
function ToggleDebug() {
|
|
|
|
timeline1.Debug = !timeline1.Debug;
|
|
|
|
timeline1.Invalidate(true, true);
|
2023-10-02 22:42:08 +00:00
|
|
|
}
|
|
|
|
|
2023-10-19 23:22:29 +00:00
|
|
|
function ToggleHotTracking() {
|
|
|
|
timeline1.EnableHotTracking = !timeline1.EnableHotTracking;
|
|
|
|
timeline1.Invalidate(true, true);
|
|
|
|
}
|
|
|
|
|
2023-10-22 21:14:12 +00:00
|
|
|
function ToggleShowLabel() {
|
|
|
|
timeline1.ShowMarkerLabel = !timeline1.ShowMarkerLabel;
|
|
|
|
timeline1.Invalidate(true, true);
|
|
|
|
}
|
|
|
|
|
|
|
|
function ToggleXAxisPosition() {
|
2023-10-23 00:21:53 +00:00
|
|
|
if (timeline1.XAxis.Position == 'top') {
|
|
|
|
timeline1.XAxis.Position = 'bottom';
|
|
|
|
timeline1.Padding.Top = 20;
|
|
|
|
timeline1.Padding.Bottom = 0;
|
|
|
|
} else {
|
|
|
|
timeline1.XAxis.Position = 'top';
|
|
|
|
timeline1.Padding.Top = 0;
|
|
|
|
timeline1.Padding.Bottom = 20;
|
|
|
|
}
|
|
|
|
|
2023-10-22 21:14:12 +00:00
|
|
|
timeline1.Invalidate(true, true);
|
|
|
|
}
|
|
|
|
|
|
|
|
function ToggleMarkerTail() {
|
|
|
|
timeline1.MarkerLabel.Line.Width = ((timeline1.MarkerLabel.Line.Width <= 0) ? 1 : 0);
|
|
|
|
timeline1.Invalidate(true, true);
|
|
|
|
}
|
|
|
|
|
2023-10-06 00:05:54 +00:00
|
|
|
function Refresh() {
|
2023-10-02 22:42:08 +00:00
|
|
|
timeline1.Invalidate(true, true);
|
|
|
|
}
|
|
|
|
|
2023-10-06 00:05:54 +00:00
|
|
|
function SetToday() {
|
|
|
|
const msPerDay = 1000 * 60 * 60 * 24;
|
2023-10-19 23:22:29 +00:00
|
|
|
const startDate = timeline1.DateToInternalString(new Date());
|
2023-10-02 22:42:08 +00:00
|
|
|
|
2023-10-06 00:05:54 +00:00
|
|
|
timeline1.Load(startDate);
|
|
|
|
|
2023-10-19 23:22:29 +00:00
|
|
|
const endDate = timeline1.VisibleEndDate;
|
2023-10-06 00:05:54 +00:00
|
|
|
const noDays = Math.floor((timeline1.ConvertToDate(endDate) - timeline1.ConvertToDate(startDate)) / msPerDay);
|
|
|
|
|
|
|
|
LogInfo("Set start date to today (" + startDate + ")");
|
|
|
|
LogInfo("Show " + startDate + " to " + endDate + " (" + noDays + " days)");
|
2023-10-02 22:42:08 +00:00
|
|
|
}
|
|
|
|
|
2023-10-06 00:05:54 +00:00
|
|
|
function GenerateRandomMarker() {
|
|
|
|
const msPerDay = 1000 * 60 * 60 * 24;
|
2023-10-19 23:22:29 +00:00
|
|
|
const endDate = timeline1.VisibleEndDate;
|
2023-10-06 00:05:54 +00:00
|
|
|
const noDays = Math.floor((timeline1.ConvertToDate(endDate) - timeline1.ConvertToDate(timeline1.ShowDate)) / msPerDay);
|
|
|
|
|
|
|
|
let randomDay = GetRandy(1, (noDays - 1));
|
|
|
|
|
|
|
|
let date = timeline1.ConvertToDate(timeline1.ShowDate);
|
|
|
|
date.setDate(date.getDate() + randomDay);
|
|
|
|
|
2023-10-19 23:22:29 +00:00
|
|
|
const markerDate = timeline1.DateToInternalString(date);
|
2023-10-06 00:05:54 +00:00
|
|
|
|
|
|
|
const markerName = "Random Marker #" + GetRandy(10000, 99999);
|
|
|
|
|
|
|
|
timeline1.AddEvent(markerDate, markerName, { Title: markerName, Description: "This is a randomly generated marker" });
|
|
|
|
timeline1.Invalidate(false, true);
|
|
|
|
|
|
|
|
LogInfo("Add marker (" + markerDate + ")");
|
|
|
|
}
|
|
|
|
|
|
|
|
function GoToToday() {
|
|
|
|
timeline1.Show(timeline1.StartDate);
|
|
|
|
|
|
|
|
LogInfo("Go to " + timeline1.ShowDate);
|
|
|
|
}
|
|
|
|
|
2023-10-19 23:22:29 +00:00
|
|
|
function GoToPrevious() {
|
2023-10-02 22:42:08 +00:00
|
|
|
timeline1.ShowPrevious();
|
2023-10-06 00:05:54 +00:00
|
|
|
|
|
|
|
LogInfo("Go to " + timeline1.ShowDate);
|
2023-10-01 02:37:24 +00:00
|
|
|
}
|
|
|
|
|
2023-10-19 23:22:29 +00:00
|
|
|
function GoToNext() {
|
2023-10-02 22:42:08 +00:00
|
|
|
timeline1.ShowNext();
|
2023-10-06 00:05:54 +00:00
|
|
|
|
|
|
|
LogInfo("Go to " + timeline1.ShowDate);
|
2023-10-02 22:42:08 +00:00
|
|
|
}
|
2023-10-01 02:37:24 +00:00
|
|
|
|
2023-10-06 00:05:54 +00:00
|
|
|
function UpdateLabel() {
|
2023-10-19 23:22:29 +00:00
|
|
|
const visibleMarkers = timeline1.VisibleEvents;
|
2023-10-06 00:05:54 +00:00
|
|
|
if (visibleMarkers.length <= 0) {
|
|
|
|
LogInfo("No visible markers");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
const randy = GetRandy(0, (visibleMarkers.length - 1));
|
|
|
|
const newMarkerName = "Renamed Random Marker #" + GetRandy(10000, 99999);
|
|
|
|
|
|
|
|
LogInfo("Renamed marker #" + randy + " [" + visibleMarkers[randy].Label + "] to [" + newMarkerName + "]");
|
|
|
|
|
|
|
|
timeline1.UpdateLabel(visibleMarkers[randy].Date, newMarkerName);
|
2023-10-02 22:42:08 +00:00
|
|
|
}
|
|
|
|
|
2023-10-06 00:05:54 +00:00
|
|
|
function UpdateMarker() {
|
2023-10-19 23:22:29 +00:00
|
|
|
const visibleMarkers = timeline1.VisibleEvents;
|
2023-10-06 00:05:54 +00:00
|
|
|
if (visibleMarkers.length <= 0) {
|
|
|
|
LogInfo("No visible markers");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
const randy = GetRandy(0, (visibleMarkers.length - 1));
|
|
|
|
|
|
|
|
LogInfo("Change marker style #" + randy + " [" + visibleMarkers[randy].Label + "]");
|
|
|
|
|
|
|
|
timeline1.UpdateMarker(visibleMarkers[randy].Date, "#E68422", "#FAE7D3");
|
2023-10-02 22:42:08 +00:00
|
|
|
}
|
|
|
|
|
2023-10-06 00:05:54 +00:00
|
|
|
function DeleteMarker() {
|
2023-10-19 23:22:29 +00:00
|
|
|
const visibleMarkers = timeline1.VisibleEvents;
|
2023-10-06 00:05:54 +00:00
|
|
|
if (visibleMarkers.length <= 0) {
|
|
|
|
LogInfo("No visible markers");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
const randy = GetRandy(0, (visibleMarkers.length - 1));
|
|
|
|
|
|
|
|
LogInfo("Delete marker #" + randy + " [" + visibleMarkers[randy].Label + "]");
|
|
|
|
|
|
|
|
timeline1.DeleteMarker(visibleMarkers[randy].Date);
|
2023-10-02 22:42:08 +00:00
|
|
|
timeline1.Invalidate(false, true);
|
2023-10-01 02:37:24 +00:00
|
|
|
}
|
2023-09-30 22:45:55 +00:00
|
|
|
|
2023-10-06 00:05:54 +00:00
|
|
|
function FindVisibleEvents() {
|
2023-10-19 23:22:29 +00:00
|
|
|
const visibleMarkers = timeline1.VisibleEvents;
|
2023-10-02 23:04:03 +00:00
|
|
|
|
2023-10-06 00:05:54 +00:00
|
|
|
LogInfo("");
|
|
|
|
LogInfo(JSON.stringify(visibleMarkers));
|
|
|
|
LogInfo("");
|
|
|
|
}
|
2023-10-02 23:04:03 +00:00
|
|
|
|
2023-10-06 00:05:54 +00:00
|
|
|
function FindAllEvents() {
|
|
|
|
LogInfo("");
|
|
|
|
LogInfo(JSON.stringify(timeline1.Events));
|
|
|
|
LogInfo("");
|
|
|
|
}
|
2023-10-02 23:04:03 +00:00
|
|
|
|
2023-10-06 00:05:54 +00:00
|
|
|
function FindEvent() {
|
|
|
|
const date = document.getElementById("textbox1").value;
|
|
|
|
if (date == null) {
|
|
|
|
LogInfo("No marker found");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
const marker = timeline1.FindEvent(date);
|
|
|
|
if (marker == null) {
|
|
|
|
LogInfo("No marker found");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
LogInfo("");
|
|
|
|
LogInfo(JSON.stringify(marker));
|
|
|
|
LogInfo("");
|
2023-10-02 23:04:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
function FindDatePosition()
|
|
|
|
{
|
2023-10-06 00:05:54 +00:00
|
|
|
const date = document.getElementById("textbox2").value;
|
|
|
|
if (date == null) {
|
|
|
|
LogInfo("No date position found");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
const marker = timeline1.FindDatePosition(date);
|
|
|
|
if (marker == null) {
|
|
|
|
LogInfo("No marker position found");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
LogInfo("");
|
|
|
|
LogInfo(JSON.stringify(marker));
|
|
|
|
LogInfo("");
|
|
|
|
}
|
2023-10-02 23:04:03 +00:00
|
|
|
|
|
|
|
|
2023-10-06 00:05:54 +00:00
|
|
|
function LogInfo(value)
|
|
|
|
{
|
|
|
|
document.getElementById("memoBox1").value += value + "\n";
|
2023-10-02 23:04:03 +00:00
|
|
|
}
|
|
|
|
|
2023-10-06 00:05:54 +00:00
|
|
|
function GetRandy(min, max)
|
2023-10-02 23:04:03 +00:00
|
|
|
{
|
2023-10-06 00:05:54 +00:00
|
|
|
let rand = Math.random();
|
|
|
|
rand = Math.floor(rand * (max - min));
|
|
|
|
rand = rand + min;
|
2023-10-02 23:04:03 +00:00
|
|
|
|
2023-10-06 00:05:54 +00:00
|
|
|
return rand;
|
2023-10-02 23:04:03 +00:00
|
|
|
}
|
|
|
|
|
2023-09-30 22:45:55 +00:00
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
|
|
</body>
|
|
|
|
</html>
|