mirror of
https://git.ianrenton.com/ian/spothole.git
synced 2025-10-27 08:49:27 +00:00
Compare commits
8 Commits
229228d209
...
1bad16f478
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1bad16f478 | ||
|
|
ae8be4446c | ||
|
|
3515fbd5c7 | ||
|
|
f5e50dc5b4 | ||
|
|
001ec2c9b9 | ||
|
|
be86160e9c | ||
|
|
0b3b35db35 | ||
|
|
6e9bab5eee |
@@ -14,6 +14,8 @@ Supported data sources include DX Clusters, the Reverse Beacon Network (RBN), th
|
|||||||
|
|
||||||

|

|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
### Accessing the public version
|
### Accessing the public version
|
||||||
|
|
||||||
You can access the public version's web interface at [https://spothole.app](https://spothole.app), and see [https://spothole.app/apidocs](https://spothole.app/apidocs) for the API details.
|
You can access the public version's web interface at [https://spothole.app](https://spothole.app), and see [https://spothole.app/apidocs](https://spothole.app/apidocs) for the API details.
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ SIGS = [
|
|||||||
# Modes. Note "DIGI" and "DIGITAL" are also supported but are normalised into "DATA".
|
# Modes. Note "DIGI" and "DIGITAL" are also supported but are normalised into "DATA".
|
||||||
CW_MODES = ["CW"]
|
CW_MODES = ["CW"]
|
||||||
PHONE_MODES = ["PHONE", "SSB", "USB", "LSB", "AM", "FM", "DV", "DMR", "DSTAR", "C4FM", "M17"]
|
PHONE_MODES = ["PHONE", "SSB", "USB", "LSB", "AM", "FM", "DV", "DMR", "DSTAR", "C4FM", "M17"]
|
||||||
DATA_MODES = ["DATA", "FT8", "FT4", "RTTY", "SSTV", "JS8", "HELL", "BPSK", "PSK", "PSK31", "BPSK31", "OLIVIA"]
|
DATA_MODES = ["DATA", "FT8", "FT4", "RTTY", "SSTV", "JS8", "HELL", "BPSK", "PSK", "PSK31", "BPSK31", "OLIVIA", "MFSK", "MFSK32"]
|
||||||
ALL_MODES = CW_MODES + PHONE_MODES + DATA_MODES
|
ALL_MODES = CW_MODES + PHONE_MODES + DATA_MODES
|
||||||
MODE_TYPES = ["CW", "PHONE", "DATA"]
|
MODE_TYPES = ["CW", "PHONE", "DATA"]
|
||||||
|
|
||||||
|
|||||||
BIN
images/screenshot3.png
Normal file
BIN
images/screenshot3.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 173 KiB |
@@ -1,11 +1,5 @@
|
|||||||
% rebase('webpage_base.tpl')
|
% rebase('webpage_base.tpl')
|
||||||
|
|
||||||
<div class="mt-3">
|
|
||||||
<div class="alert alert-warning" role="alert">
|
|
||||||
<i class="fa-solid fa-triangle-exclamation"></i> This page is a work in progress. It will be refined as Spothole heads towards v1.0.
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="mt-3">
|
<div class="mt-3">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-auto me-auto pt-3">
|
<div class="col-auto me-auto pt-3">
|
||||||
|
|||||||
@@ -153,104 +153,95 @@ div#map {
|
|||||||
/* BANDS PANEL */
|
/* BANDS PANEL */
|
||||||
|
|
||||||
div#bands-container {
|
div#bands-container {
|
||||||
|
min-height: 64em;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
overflow-x: auto;
|
overflow-x: auto;
|
||||||
overflow-y: auto;
|
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
display: flex;
|
|
||||||
overscroll-behavior-x: none;
|
overscroll-behavior-x: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Bands panel inner layout */
|
#bands-table {
|
||||||
div.bandCol {
|
min-width: 100%;
|
||||||
height: 100%;
|
|
||||||
min-width: 8em;
|
|
||||||
display: flex;
|
|
||||||
flex-flow: column;
|
|
||||||
overflow-y: clip;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
div.bandColHeader {
|
#bands-table th {
|
||||||
flex: 0 1 auto;
|
width: 20%;
|
||||||
}
|
max-height: 40px;
|
||||||
|
min-width: 12em;
|
||||||
div.bandColMiddle {
|
padding: 0.5em;
|
||||||
flex: 1 1 auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.bandColMiddle ul {
|
|
||||||
display: table;
|
|
||||||
table-layout: fixed;
|
|
||||||
width: 100%;
|
|
||||||
min-height: 100%;
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
-moz-box-sizing: border-box;
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.bandColMiddle ul li {
|
|
||||||
display: table-row;
|
|
||||||
line-height: 0.5em;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*noinspection CssUnusedSymbol*/
|
|
||||||
div.bandColMiddle ul li.withSpots {
|
|
||||||
line-height: 1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.bandColMiddle ul li span {
|
|
||||||
display: table-cell;
|
|
||||||
vertical-align: middle;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.bandColMiddle ul {
|
|
||||||
display: table;
|
|
||||||
table-layout: fixed;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
-moz-box-sizing: border-box;
|
|
||||||
box-sizing: border-box;
|
|
||||||
border-left: 2px dotted;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.bandColHeader {
|
|
||||||
text-align: center;
|
text-align: center;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
padding: 0.5em;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
div.bandColMiddle {
|
#bands-table td {
|
||||||
margin-left: 3px;
|
width: 20%;
|
||||||
border-left: 2px dotted var(--text);
|
min-width: 12em;
|
||||||
|
height: 62em;
|
||||||
}
|
}
|
||||||
|
|
||||||
div.bandColSpot {
|
div.band-container {
|
||||||
display: block;
|
height: 62em;
|
||||||
|
width: 20%;
|
||||||
|
min-width: 12em;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.band-markers {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
z-index: 13;
|
||||||
|
border-left: 2px dotted black;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.band-spots {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
z-index: 15;
|
||||||
|
}
|
||||||
|
|
||||||
|
canvas.band-lines-canvas {
|
||||||
|
width: 5em;
|
||||||
|
height: 100%;
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
z-index: 11;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.band-spot {
|
||||||
|
position: absolute;
|
||||||
|
left: 5em;
|
||||||
|
padding: 0 0.25em;
|
||||||
|
background-color: white;
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
padding: 3px;
|
cursor: default;
|
||||||
background: lightyellow;
|
|
||||||
margin-right: 2em;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
span.bandColSpot {
|
div.band-spot:hover {
|
||||||
vertical-align: bottom;
|
z-index: 999;
|
||||||
display: inline !important;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Don't wrap frequencies */
|
div.band-spot span.band-spot-call {
|
||||||
span.bandColSpotFreq {
|
display: inline;
|
||||||
white-space: nowrap;
|
|
||||||
display: inline !important;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
span.bandColSpotMode {
|
div.band-spot:hover span.band-spot-call {
|
||||||
padding-left: 0.5em;
|
display: none;
|
||||||
font-size: 0.8em;
|
}
|
||||||
line-height: 0.4em;
|
|
||||||
|
div.band-spot span.band-spot-info {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.band-spot:hover span.band-spot-info {
|
||||||
|
display: inline;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,12 @@
|
|||||||
|
// A couple of constants that must match what's in CSS. We need to know them before the content actually renders, so we
|
||||||
|
// can't just ask the elements themselves for their dimensions.
|
||||||
|
BAND_COLUMN_HEIGHT_EM = 62;
|
||||||
|
BAND_COLUMN_CANVAS_WIDTH_EM = 4;
|
||||||
|
BAND_COLUMN_FONT_SIZE = 16;
|
||||||
|
BAND_COLUMN_HEIGHT_PX = BAND_COLUMN_HEIGHT_EM * BAND_COLUMN_FONT_SIZE;
|
||||||
|
BAND_COLUMN_CANVAS_WIDTH_PX = BAND_COLUMN_CANVAS_WIDTH_EM * BAND_COLUMN_FONT_SIZE;
|
||||||
|
BAND_COLUMN_SPOT_DIV_HEIGHT_PX = BAND_COLUMN_FONT_SIZE * 1.6;
|
||||||
|
|
||||||
// Load spots and populate the bands display.
|
// Load spots and populate the bands display.
|
||||||
function loadSpots() {
|
function loadSpots() {
|
||||||
$.getJSON('/api/v1/spots' + buildQueryString(), function(jsonData) {
|
$.getJSON('/api/v1/spots' + buildQueryString(), function(jsonData) {
|
||||||
@@ -28,9 +37,9 @@ function buildQueryString() {
|
|||||||
// Update the bands display
|
// Update the bands display
|
||||||
function updateBands() {
|
function updateBands() {
|
||||||
// Stop here if nothing to display
|
// Stop here if nothing to display
|
||||||
var bandsPanel = $("#bands-container");
|
var bandsContainer = $("#bands-container");
|
||||||
if (spots.length === 0) {
|
if (spots.length === 0) {
|
||||||
bandsPanel.html("<div class='alert alert-danger' role='alert'>No spots match your filters.</div>");
|
bandsContainer.html("<div class='alert alert-danger' role='alert'>No spots match your filters.</div>");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -51,73 +60,137 @@ function updateBands() {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Build up HTML content for each band
|
// Track if any columns end up taller than expected, so we can resize the container and avoid vertical scroll.
|
||||||
let html = "";
|
var maxHeightBand = 0;
|
||||||
const columnWidthPercent = Math.max(30, 100 / bandToSpots.size);
|
|
||||||
let columnIndex = 0;
|
// Build up table content for each band
|
||||||
|
var table = $('<table id="bands-table">').append('<thead><tr></tr></thead><tbody><tr></tr></tbody>');
|
||||||
bandToSpots.forEach(function (spotList, bandName) {
|
bandToSpots.forEach(function (spotList, bandName) {
|
||||||
// Get the colours for the band from the first spot, and prepare the header
|
// Get the colours for the band from the first spot, and prepare the header
|
||||||
html += "<div class='bandCol' style='width:" + columnWidthPercent + "%'>";
|
table.find('thead tr').append(`<th style='background-color:${spotList[0].band_color}; color:${spotList[0].band_contrast_color}'>${spotList[0].band}</th>`);
|
||||||
html += "<div class='bandColHeader' style='background-color:" + spotList[0].band_color + "; color:" + spotList[0].band_contrast_color + "'>" + spotList[0].band + "</div>";
|
|
||||||
html += "<div class='bandColMiddle'>";
|
|
||||||
|
|
||||||
// Get the band data to fetch start and end frequencies
|
// Get the band data to fetch start and end frequencies
|
||||||
let band = options["bands"].filter(function (b) {
|
let band = options["bands"].filter(function (b) {
|
||||||
return b.name === bandName;
|
return b.name === bandName;
|
||||||
})[0];
|
})[0];
|
||||||
// Start printing the band
|
|
||||||
|
// Print the frequency band markers. This is 41 steps to divide the band evenly into 40 markers. One in every
|
||||||
|
// four will show the actual frequency, the others will just be dashes.
|
||||||
|
bandMarkersDiv = $('<div class="band-markers">');
|
||||||
const freqStep = (band.end_freq - band.start_freq) / 40.0;
|
const freqStep = (band.end_freq - band.start_freq) / 40.0;
|
||||||
html += "<ul>";
|
|
||||||
html += "<li><span>-</span></li>";
|
|
||||||
|
|
||||||
// Do 40 steps down the band
|
|
||||||
for (let i = 0; i <= 40; i++) {
|
for (let i = 0; i <= 40; i++) {
|
||||||
|
|
||||||
// Work out if there are any spots in this step
|
|
||||||
const freqStepStart = band.start_freq + i * freqStep;
|
|
||||||
const freqStepEnd = freqStepStart + freqStep;
|
|
||||||
const spotsInStep = spotList.filter(function (s) {
|
|
||||||
// Normally we do >= start and < end, but in the special case where this is the last step and there is a spot
|
|
||||||
// right at the end of the band, we include this too
|
|
||||||
return s.freq >= freqStepStart && (s.freq < freqStepEnd || (s.freq === freqStepEnd && freqStepEnd === band.end_freq));
|
|
||||||
});
|
|
||||||
|
|
||||||
if (spotsInStep.length > 0) {
|
|
||||||
// If this step has spots in it, print them
|
|
||||||
html += "<li class='withSpots'><span>";
|
|
||||||
spotsInStep.sort((a, b) => (a.freq > b.freq) ? 1 : ((b.freq > a.freq) ? -1 : 0));
|
|
||||||
spotsInStep.forEach(function (s) {
|
|
||||||
html += "<div class='bandColSpot'><span class='bandColSpot'>" + s.dx_call + "<br/><span class='bandColSpotFreq'>" + (s.freq/1000000) + "</span>";
|
|
||||||
if (s.mode != null && s.mode.length > 0 && s.mode !== "Unknown") {
|
|
||||||
html += "<span class='bandColSpotMode'>" + s.mode + "</span>";
|
|
||||||
}
|
|
||||||
html += "</span></div>";
|
|
||||||
});
|
|
||||||
html += "</li></span>";
|
|
||||||
|
|
||||||
} else {
|
|
||||||
// Step had no spots in it, so just print a marker. This is a frequency on multiples of 4, or a dash otherwise.
|
|
||||||
if (i % 4 === 0) {
|
if (i % 4 === 0) {
|
||||||
html += "<li><span>—" + ((band.start_freq + i * freqStep)/1000000).toFixed(3) + "</span></li>";
|
bandMarkersDiv.append("—" + ((band.start_freq + i * freqStep)/1000000).toFixed(3) + "<br/>");
|
||||||
} else if (i % 4 === 2) {
|
} else if (i % 4 === 2) {
|
||||||
html += "<li><span>–</span></li>";
|
bandMarkersDiv.append("–<br/>");
|
||||||
} else {
|
} else {
|
||||||
html += "<li><span>-</span></li>";
|
bandMarkersDiv.append("-<br/>");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
html += "<li><span>-</span></li>";
|
|
||||||
html += "</ul>";
|
|
||||||
|
|
||||||
html += "</div></div>";
|
// Prepare the spots list
|
||||||
columnIndex++;
|
var bandSpotsDiv = $("<div class='band-spots'>");
|
||||||
|
var lastSpotPxDownBand = -999;
|
||||||
|
// Sort by frequency so have a consistent order in which to plan where they will appear on the band div.
|
||||||
|
spotList.sort(function(a, b) { return a.freq - b.freq; });
|
||||||
|
// First calculate how we should be displaying the spots. There are three "modes" to try to place them in a
|
||||||
|
// visually appealing way:
|
||||||
|
// 1) Spaced normally, not going over the end of the band, so we populate them forwards.
|
||||||
|
// 2) Would go over the end, but the spots don't fill the band, so we populate them backwards.
|
||||||
|
// 3) Spots totally fill the band (or more), so we space them evenly starting at the top.
|
||||||
|
// In each case, we don't add anything to the DOM yet, we just calculate "pxDownBandLabel" (how far the *top* of
|
||||||
|
// the label is from the top of the div) and add that as a property to the spot for later use.
|
||||||
|
if (spotList.length >= BAND_COLUMN_HEIGHT_PX / BAND_COLUMN_SPOT_DIV_HEIGHT_PX) {
|
||||||
|
// Mode 3.
|
||||||
|
// Just lay out all spots simply, starting at 0px offset and working down with each one touching.
|
||||||
|
lastSpotPxDownBand = 0 - BAND_COLUMN_SPOT_DIV_HEIGHT_PX;
|
||||||
|
spotList.forEach(s => {
|
||||||
|
lastSpotPxDownBand = lastSpotPxDownBand + BAND_COLUMN_SPOT_DIV_HEIGHT_PX;
|
||||||
|
s["pxDownBandLabel"] = lastSpotPxDownBand;
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
|
// Mode 1 or 2. Run through adding things to the list forwards as a test.
|
||||||
|
spotList.forEach(s => {
|
||||||
|
// Work out how far down the div to draw it
|
||||||
|
var percentDownBand = (s.freq - band.start_freq) / (band.end_freq - band.start_freq) * 0.97; // not 100% due to fudge, the first and last dashes are not exactly at the top and bottom of the div as some space is needed for text
|
||||||
|
var pxDownBand = percentDownBand * BAND_COLUMN_HEIGHT_PX;
|
||||||
|
if (pxDownBand < lastSpotPxDownBand + BAND_COLUMN_SPOT_DIV_HEIGHT_PX) {
|
||||||
|
pxDownBand = lastSpotPxDownBand + BAND_COLUMN_SPOT_DIV_HEIGHT_PX; // Prevent overlap
|
||||||
|
}
|
||||||
|
s["pxDownBandLabel"] = pxDownBand;
|
||||||
|
lastSpotPxDownBand = pxDownBand;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Work out if we overflowed the end.
|
||||||
|
if (lastSpotPxDownBand <= BAND_COLUMN_HEIGHT_PX) {
|
||||||
|
// Mode 1. Current positions are fine and there's nothing to do.
|
||||||
|
} else {
|
||||||
|
// Mode 2. Repeat the process but backwards, starting at the end and working upwards.
|
||||||
|
lastSpotPxDownBand = 999999;
|
||||||
|
spotList.reverse().forEach(s => {
|
||||||
|
// Work out how far down the div to draw it
|
||||||
|
var percentDownBand = (s.freq - band.start_freq) / (band.end_freq - band.start_freq) * 0.97; // not 100% due to fudge, the first and last dashes are not exactly at the top and bottom of the div as some space is needed for text
|
||||||
|
var pxDownBand = percentDownBand * BAND_COLUMN_HEIGHT_PX;
|
||||||
|
if (pxDownBand > lastSpotPxDownBand - BAND_COLUMN_SPOT_DIV_HEIGHT_PX) {
|
||||||
|
pxDownBand = lastSpotPxDownBand - BAND_COLUMN_SPOT_DIV_HEIGHT_PX; // Prevent overlap
|
||||||
|
}
|
||||||
|
s["pxDownBandLabel"] = pxDownBand;
|
||||||
|
lastSpotPxDownBand = pxDownBand;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now each spot is tagged with how far down the div it should go, add them to the DOM.
|
||||||
|
spotList.forEach(s => {
|
||||||
|
bandSpotsDiv.append(`<div class="band-spot" style="top: ${s['pxDownBandLabel']}px; border-top: 1px solid ${s.band_color}; border-left: 5px solid ${s.band_color}; border-bottom: 1px solid ${s.band_color}; border-right: 1px solid ${s.band_color};"><span class="band-spot-call">${s.dx_call}</span><span class="band-spot-info">${s.dx_call} ${(s.freq/1000000).toFixed(3)} ${s.mode}</span></div>`);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Work out how tall the canvas should be. Normally this is matching the normal band column height, but if some
|
||||||
|
// spots have gone off the end of the band markers and stretched their div, we need to resize the canvas to
|
||||||
|
// match, otherwise we have nowhere to draw their connecting lines.
|
||||||
|
var canvasHeight = Math.max(BAND_COLUMN_HEIGHT_PX, lastSpotPxDownBand + BAND_COLUMN_SPOT_DIV_HEIGHT_PX);
|
||||||
|
maxHeightBand = Math.max(maxHeightBand, canvasHeight);
|
||||||
|
|
||||||
|
// Draw horizontal or diagonal lines to join up the "real" frequency with where the spot div ended up
|
||||||
|
var bandLinesCanvas = $(`<canvas class='band-lines-canvas' width='${BAND_COLUMN_CANVAS_WIDTH_PX}px' height='${canvasHeight}px' style='height:${canvasHeight}px !important;'>`);
|
||||||
|
spotList.forEach(s => {
|
||||||
|
// Work out how far down the div to draw it
|
||||||
|
var percentDownBand = (s.freq - band.start_freq) / (band.end_freq - band.start_freq) * 0.97; // not 100% due to fudge, the first and last dashes are not exactly at the top and bottom of the div as some space is needed for text
|
||||||
|
var pxDownBandFreq = (percentDownBand + 0.015) * BAND_COLUMN_HEIGHT_PX; // same fudge but add half to put the left end of the line in the right place
|
||||||
|
var pxDownBandLabel = s["pxDownBandLabel"] + (BAND_COLUMN_SPOT_DIV_HEIGHT_PX / 1.75); // line should be to the vertical text-centre spot, not to the top corner
|
||||||
|
|
||||||
|
// Draw the line on the canvas
|
||||||
|
var ctx = bandLinesCanvas[0].getContext('2d');
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.lineWidth = 2;
|
||||||
|
ctx.lineCap = "round";
|
||||||
|
ctx.strokeStyle = s.band_color;
|
||||||
|
ctx.moveTo(0, pxDownBandFreq);
|
||||||
|
ctx.lineTo(BAND_COLUMN_CANVAS_WIDTH_PX, pxDownBandLabel);
|
||||||
|
ctx.stroke();
|
||||||
|
});
|
||||||
|
|
||||||
|
// Assemble the table cell
|
||||||
|
td = $("<td>");
|
||||||
|
container = $("<div class='band-container'>");
|
||||||
|
container.append(bandLinesCanvas);
|
||||||
|
container.append(bandMarkersDiv);
|
||||||
|
container.append(bandSpotsDiv);
|
||||||
|
td.append(container);
|
||||||
|
table.find('tbody tr').append(td);
|
||||||
|
});
|
||||||
|
|
||||||
// Update the DOM with the band HTML
|
// Update the DOM with the band HTML
|
||||||
bandsPanel.html(html);
|
bandsContainer.html(table);
|
||||||
|
|
||||||
|
// Increase the height of the bands container so we don't have any vertical scroll bars except the browser ones
|
||||||
|
bandsContainer.css("min-height", `${maxHeightBand + 42}px`);
|
||||||
|
|
||||||
// Desktop mouse wheel to scroll bands horizontally if used on the headers
|
// Desktop mouse wheel to scroll bands horizontally if used on the headers
|
||||||
// noinspection JSDeprecatedSymbols
|
table.find('thead tr').on("wheel", () => {
|
||||||
$(".bandColHeader").on("wheel", () => bandsPanel.scrollLeft(bandsPanel.scrollLeft() + event.deltaY / 10.0));
|
bandsContainer.scrollLeft(bandsContainer.scrollLeft() + event.deltaY / 10.0);
|
||||||
|
return false;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Iterate through a temporary list of spots, merging duplicates in a way suitable for the band panel. If two or more
|
// Iterate through a temporary list of spots, merging duplicates in a way suitable for the band panel. If two or more
|
||||||
|
|||||||
Reference in New Issue
Block a user