Commit pirate JS files
This commit is contained in:
181
js/WsprSearchUiFlightStatsController.js
Normal file
181
js/WsprSearchUiFlightStatsController.js
Normal file
@@ -0,0 +1,181 @@
|
||||
/*
|
||||
Copyright (c) 2023-forever Douglas Malnati. All rights reserved.
|
||||
|
||||
See the /faq/tos page for details.
|
||||
|
||||
(If this generated header is stamped on a file which is a 3rd party file or under a different license or copyright, then ignore this copyright statement and use that file's terms.)
|
||||
*/
|
||||
|
||||
import * as utl from '/js/Utl.js';
|
||||
|
||||
import { Base } from './Base.js';
|
||||
import { TabularData } from '../../../../js/TabularData.js';
|
||||
|
||||
|
||||
|
||||
export class WsprSearchUiFlightStatsController
|
||||
extends Base
|
||||
{
|
||||
constructor(cfg)
|
||||
{
|
||||
super();
|
||||
|
||||
this.cfg = cfg;
|
||||
|
||||
this.ok = this.cfg.container;
|
||||
|
||||
if (this.ok)
|
||||
{
|
||||
this.ui = this.#MakeUI();
|
||||
this.cfg.container.appendChild(this.ui);
|
||||
}
|
||||
}
|
||||
|
||||
SetDebug(tf)
|
||||
{
|
||||
super.SetDebug(tf);
|
||||
|
||||
this.t.SetCcGlobal(tf);
|
||||
}
|
||||
|
||||
OnEvent(evt)
|
||||
{
|
||||
if (this.ok)
|
||||
{
|
||||
switch (evt.type) {
|
||||
case "DATA_TABLE_RAW_READY": this.#OnDataTableRawReady(evt); break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#OnDataTableRawReady(evt)
|
||||
{
|
||||
this.t.Reset();
|
||||
this.t.Event(`WsprSearchUiFlightStatsController::OnDataTableRawReady Start`);
|
||||
|
||||
// clear existing child nodes
|
||||
this.cfg.container.innerHTML = "";
|
||||
|
||||
// get handle to data
|
||||
let td = evt.tabularDataReadOnly;
|
||||
|
||||
// calculate distance stats
|
||||
let distKm = 0;
|
||||
let distMi = 0;
|
||||
|
||||
td.ForEach((row) => {
|
||||
distKm += td.Get(row, "DistKm");
|
||||
distMi += td.Get(row, "DistMi");
|
||||
});
|
||||
|
||||
// calculate spot stats
|
||||
let spotCount = td.GetDataTable().length - 1;
|
||||
|
||||
// calculate duration stats
|
||||
let durationStr = "";
|
||||
if (td.Length() > 1)
|
||||
{
|
||||
let dtFirst = td.Get(td.Length() - 1, "DateTimeLocal");
|
||||
let dtLast = td.Get(0, "DateTimeLocal");
|
||||
|
||||
let msFirst = utl.ParseTimeToMs(dtFirst);
|
||||
let msLast = utl.ParseTimeToMs(dtLast);
|
||||
|
||||
let msDiff = msLast - msFirst;
|
||||
durationStr = utl.MsToDurationStrDaysHoursMinutes(msDiff);
|
||||
}
|
||||
|
||||
// calculate eastward laps around world using resolved location
|
||||
let lapCount = this.#CalculateEastwardLapCount(td);
|
||||
|
||||
// create summary
|
||||
let status =
|
||||
`
|
||||
Flight duration: ${durationStr}
|
||||
<br/>
|
||||
<br/>
|
||||
Laps around world: ${utl.Commas(lapCount)}
|
||||
<br/>
|
||||
<br/>
|
||||
Distance Traveled Km: ${utl.Commas(Math.round(distKm))}
|
||||
<br/>
|
||||
Distance Traveled Mi: ${utl.Commas(Math.round(distMi))}
|
||||
<br/>
|
||||
<br/>
|
||||
Spots: ${utl.Commas(spotCount)}
|
||||
`;
|
||||
|
||||
// update UI
|
||||
this.ui.innerHTML = status;
|
||||
|
||||
// replace with new
|
||||
this.cfg.container.appendChild(this.ui);
|
||||
|
||||
this.t.Event(`WsprSearchUiFlightStatsController::OnDataTableRawReady End`);
|
||||
}
|
||||
|
||||
#MakeUI()
|
||||
{
|
||||
this.ui = document.createElement('div');
|
||||
|
||||
return this.ui;
|
||||
}
|
||||
|
||||
#CalculateEastwardLapCount(td)
|
||||
{
|
||||
let lonList = [];
|
||||
|
||||
// Table is newest-first, so iterate oldest -> newest.
|
||||
for (let idx = td.Length() - 1; idx >= 0; --idx)
|
||||
{
|
||||
let lon = td.Get(idx, "Lng");
|
||||
if (lon == undefined || lon == null || lon === "")
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
lon = Number(lon);
|
||||
if (Number.isFinite(lon))
|
||||
{
|
||||
lonList.push(lon);
|
||||
}
|
||||
}
|
||||
|
||||
if (lonList.length < 2)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Unwrap longitude so east/west movement is continuous across +/-180.
|
||||
let unwrappedLonList = [lonList[0]];
|
||||
for (let i = 1; i < lonList.length; ++i)
|
||||
{
|
||||
let prevRaw = lonList[i - 1];
|
||||
let curRaw = lonList[i];
|
||||
|
||||
let delta = curRaw - prevRaw;
|
||||
if (delta > 180) { delta -= 360; }
|
||||
if (delta < -180) { delta += 360; }
|
||||
|
||||
let nextUnwrapped = unwrappedLonList[unwrappedLonList.length - 1] + delta;
|
||||
unwrappedLonList.push(nextUnwrapped);
|
||||
}
|
||||
|
||||
let startLon = unwrappedLonList[0];
|
||||
let lapCount = 0;
|
||||
|
||||
// Count only eastward full wraps past start + 360n.
|
||||
for (let i = 1; i < unwrappedLonList.length; ++i)
|
||||
{
|
||||
let prevRel = unwrappedLonList[i - 1] - startLon;
|
||||
let curRel = unwrappedLonList[i] - startLon;
|
||||
|
||||
while (prevRel < (lapCount + 1) * 360 && curRel >= (lapCount + 1) * 360)
|
||||
{
|
||||
++lapCount;
|
||||
}
|
||||
}
|
||||
|
||||
return lapCount;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user