Compare commits

...

5 commits

2 changed files with 87 additions and 48 deletions

View file

@ -1,37 +1,55 @@
- header: true - header: true
columns: [power] columns: [power, status]
titles: { titles: {
power_a: Power A, power_a: Power A,
power_e: Power E, power_e: Power E,
power_n: Power N power_n: Power N,
status: Status
} }
comments:
- Status: "P: Primär dem Amateurfunk zugewiesen, P+: Primär (weitgehend exklusiv) dem Amateurfunk zugewiesen, S: Sekundär dem Amateurfunk zugewiesen"
- frequency: 135.7-137.8 - frequency: 135.7-137.8
power: {a: 1 W ERP} power: {a: 1 W ERP}
status: S
- frequency: 472-479 - frequency: 472-479
power: {a: 1 W ERP} power: {a: 1 W ERP}
status: S
- frequency: 1810-1850 - frequency: 1810-1850
power: {a: 750 W PEP, e: 100 W PEP} power: {a: 750 W PEP, e: 100 W PEP}
status: P
- frequency: 1850-1890 - frequency: 1850-1890
power: {a: 75 W PEP, e: 75 W PEP} power: {a: 75 W PEP, e: 75 W PEP}
status: S
- frequency: 1890-2000 - frequency: 1890-2000
power: {a: 10 W PEP, e: 10 W PEP} power: {a: 10 W PEP, e: 10 W PEP}
status: S
- frequency: 3500-3800 - frequency: 3500-3800
power: {a: 750 W PEP, e: 100 W PEP} power: {a: 750 W PEP, e: 100 W PEP}
status: P
- frequency: 5351.5-5366.5 - frequency: 5351.5-5366.5
power: {a: 15 W EIRP} power: {a: 15 W EIRP}
status: S
- frequency: 7000-7100 - frequency: 7000-7100
power: {a: 750 W PEP} power: {a: 750 W PEP}
status: P+
- frequency: 7100-7200 - frequency: 7100-7200
power: {a: 750 W PEP} power: {a: 750 W PEP}
status: P+
- frequency: 10100-10150 - frequency: 10100-10150
power: {a: 150 W PEP} power: {a: 150 W PEP}
status: S
- frequency: 14000-14350 - frequency: 14000-14350
power: {a: 750 W PEP} power: {a: 750 W PEP}
status: P+
- frequency: 18068-18168 - frequency: 18068-18168
power: {a: 750 W PEP} power: {a: 750 W PEP}
status: P
- frequency: 21000-21450 - frequency: 21000-21450
power: {a: 750 W PEP, e: 100 W PEP} power: {a: 750 W PEP, e: 100 W PEP}
status: P+
- frequency: 24890-24990 - frequency: 24890-24990
power: {a: 750 W PEP} power: {a: 750 W PEP}
status: P
- frequency: 28000-29700 - frequency: 28000-29700
power: {a: 750 W PEP, e: 100 W PEP, n: 10 W ERP} power: {a: 750 W PEP, e: 100 W PEP, n: 10 W ERP}
status: P

View file

@ -31,15 +31,15 @@ div>label {
<script> <script>
// require in browser-cjs // require in browser-cjs
// eslint-disable-next-line no-undef // eslint-disable-next-line no-undef
const yaml = require('https://unpkg.com/js-yaml/dist/js-yaml.min.js'); const yaml = require("https://unpkg.com/js-yaml/dist/js-yaml.min.js");
// eslint-disable-next-line no-undef // eslint-disable-next-line no-undef
const Measures = require('https://unpkg.com/measures/dist/measures.cjs.js'); const Measures = require("https://unpkg.com/measures/dist/measures.cjs.js");
// eslint-disable-next-line no-undef // eslint-disable-next-line no-undef
const path = require('https://unpkg.com/path-browserify/index.js'); const path = require("https://unpkg.com/path-browserify/index.js");
function create_element_link(element, href) { function create_element_link(element, href) {
element.addEventListener("click", () => { element.addEventListener("click", () => {
var lnk = document.createElement('a'); let lnk = document.createElement("a");
if (typeof href === "function") { if (typeof href === "function") {
lnk.href = href(); lnk.href = href();
@ -59,7 +59,7 @@ div>label {
}); });
} }
document.addEventListener('DOMContentLoaded', () => { document.addEventListener("DOMContentLoaded", () => {
location.search.substr(1).split("&").forEach((param) => { location.search.substr(1).split("&").forEach((param) => {
let p = param.split("="); let p = param.split("=");
let key = p[0]; let key = p[0];
@ -75,14 +75,14 @@ div>label {
["base", "extension"].forEach((id) => { ["base", "extension"].forEach((id) => {
create_element_link(document.getElementById("download_" + id), document.getElementById(id + "_plan").value); create_element_link(document.getElementById("download_" + id), document.getElementById(id + "_plan").value);
document.getElementById("download_" + id).addEventListener("keydown", (event) => { document.getElementById("download_" + id).addEventListener("keydown", (event) => {
if (event.key === 'Enter') { if (event.key === "Enter") {
update_plan() update_plan()
} }
}); });
}); });
create_element_link(document.getElementById("create_link"), function() { create_element_link(document.getElementById("create_link"), function() {
return window.location.href.split('?')[0] + '?' return window.location.href.split("?")[0] + "?"
+ "base=" + document.getElementById("base_plan").value + "base=" + document.getElementById("base_plan").value
+ "&ext=" + document.getElementById("extension_plan").value; + "&ext=" + document.getElementById("extension_plan").value;
}); });
@ -90,7 +90,7 @@ div>label {
// eslint-disable-next-line no-unused-vars // eslint-disable-next-line no-unused-vars
function filter_with_not(headerValue, rowValue, rowData, filterParams){ function filter_with_not(headerValue, rowValue, rowData, filterParams){
if (headerValue.startsWith('!')) { if (headerValue.startsWith("!")) {
// filter not // filter not
const str = headerValue.slice(1); const str = headerValue.slice(1);
if ((str.length > 0) && (typeof rowValue !== "undefined")) { if ((str.length > 0) && (typeof rowValue !== "undefined")) {
@ -120,21 +120,42 @@ div>label {
return Number(number) >= Number(min) && Number(number) <= Number(max); return Number(number) >= Number(min) && Number(number) <= Number(max);
} }
function add_power(ext, row) { function add_column(row, cols, header) {
for (const [key, value] of Object.entries(ext.power)) { header.columns.forEach((col) => {
row["power_" + key] = value; if (header.columns.includes(col)) {
} if (typeof cols[col] === "object") {
for (const [key, value] of Object.entries(cols[col])) {
row[col + "_" + key] = value;
}
} else {
row[col] = cols[col];
}
}
});
}
function fill_comments(header) {
for (const [key, value] of Object.entries(header)) {
if (typeof value.comments !== "undefined") {
let s = "";
value.comments.forEach((comment) => {
for (const [ckey, cvalue] of Object.entries(comment)) {
s += ckey + ": " + cvalue + "<br>";
}
});
document.getElementById("comments_" + key).innerHTML = s;
}
};
} }
function update_table(bases, extensions) { function update_table(bases, extensions) {
var tdata = []; let tdata = [];
var base_header = {}; let header = {};
var ext_header = {};
// first, fill base_header // first, fill base_header
bases.forEach((base) => { bases.forEach((base) => {
if ((typeof base.header !== "undefined") && base.header) { if ((typeof base.header !== "undefined") && base.header) {
base_header = structuredClone(base); header["base"] = structuredClone(base);
} }
}); });
@ -146,34 +167,32 @@ div>label {
// first, fill ext_header // first, fill ext_header
extensions.forEach((ext) => { extensions.forEach((ext) => {
if ((typeof ext.header !== "undefined") && ext.header) { if ((typeof ext.header !== "undefined") && ext.header) {
ext_header = structuredClone(ext); header["extension"] = structuredClone(ext);
} }
}); });
fill_comments(header);
// then fill tdata // then fill tdata
let already_added = false; let already_added = false;
extensions.forEach((ext) => { extensions.forEach((ext) => {
if ((typeof ext.header === "undefined") || (ext.header == false)) { if ((typeof ext.header === "undefined") || (ext.header == false)) {
base_header.columns.forEach((col) => { add_column(row, base, header["base"]);
if (base_header.columns.includes(col)) {
row[col] = base[col];
}
});
let [ext_start, ext_end] = ext.frequency.split('-'); let [ext_start, ext_end] = ext.frequency.split("-");
if (typeof base.frequency === "number") { if (typeof base.frequency === "number") {
// at single frequency // at single frequency
if (isInRange(base.frequency, ext_start, ext_end)) { if (isInRange(base.frequency, ext_start, ext_end)) {
add_power(ext, row); add_column(row, ext, header["extension"]);
} else { } else {
return; return;
} }
} else { } else {
// frequeny range // frequeny range
let [base_start, base_end] = base.frequency.split('-'); let [base_start, base_end] = base.frequency.split("-");
if (isInRange(base_start, ext_start, ext_end) && isInRange(base_end, ext_start, ext_end)) { if (isInRange(base_start, ext_start, ext_end) && isInRange(base_end, ext_start, ext_end)) {
// base range is inside of ext range or the same // base range is inside of ext range or the same
add_power(ext, row); add_column(row, ext, header["extension"]);
} else { } else {
// base range is split by ext range // base range is split by ext range
if (isInRange(ext_start, base_start, base_end)) { if (isInRange(ext_start, base_start, base_end)) {
@ -181,8 +200,8 @@ div>label {
let r = structuredClone(row); let r = structuredClone(row);
let start = ext_start; let start = ext_start;
let end = base_end < ext_end ? base_end : ext_end; let end = base_end < ext_end ? base_end : ext_end;
r["frequency"] = start + '-' + end; r["frequency"] = start + "-" + end;
add_power(ext, r); add_column(r, ext, header["extension"]);
tdata.push(r); tdata.push(r);
already_added = true; already_added = true;
} else if (isInRange(ext_end, base_start, base_end)) { } else if (isInRange(ext_end, base_start, base_end)) {
@ -190,8 +209,8 @@ div>label {
let r = structuredClone(row); let r = structuredClone(row);
let start = base_start; let start = base_start;
let end = ext_end; let end = ext_end;
r["frequency"] = start + '-' + end; r["frequency"] = start + "-" + end;
add_power(ext, r); add_column(r, ext, header["extension"]);
tdata.push(r); tdata.push(r);
already_added = true; already_added = true;
} }
@ -208,7 +227,7 @@ div>label {
// require in tabular-tables // require in tabular-tables
// eslint-disable-next-line no-undef // eslint-disable-next-line no-undef
var table = new Tabulator("#data-table", { let table = new Tabulator("#data-table", {
layout: "fitDataTable", layout: "fitDataTable",
initialSort: [ initialSort: [
{column: "frequency", dir: "asc"}, {column: "frequency", dir: "asc"},
@ -222,7 +241,7 @@ div>label {
definitions.forEach((column) => { definitions.forEach((column) => {
if (column.field == "band") { if (column.field == "band") {
column.sorter = function(a, b) { column.sorter = function(a, b) {
return parseFloat(new Measures().from(a).to('m')) - parseFloat(new Measures().from(b).to('m')); return parseFloat(new Measures().from(a).to("m")) - parseFloat(new Measures().from(b).to("m"));
} }
} }
@ -232,11 +251,11 @@ div>label {
column.headerFilter = "input"; column.headerFilter = "input";
column.headerFilterFunc = filter_with_not; column.headerFilterFunc = filter_with_not;
if (typeof base_header.titles[column.field] !== "undefined") { if (typeof header["base"].titles[column.field] !== "undefined") {
column.title = base_header.titles[column.field]; column.title = header["base"].titles[column.field];
} }
if (typeof ext_header.titles[column.field] !== "undefined") { if (typeof header["extension"].titles[column.field] !== "undefined") {
column.title = ext_header.titles[column.field]; column.title = header["extension"].titles[column.field];
} }
}); });
@ -251,13 +270,13 @@ div>label {
} }
table.download( table.download(
"pdf", "pdf",
path.basename(document.getElementById('base_plan').value, '.yml') + '.pdf', path.basename(document.getElementById("base_plan").value, ".yml") + ".pdf",
{ orientation:"portrait" }, { orientation:"portrait" },
download_range); download_range);
}); });
table.on("tableBuilt", () => { table.on("tableBuilt", () => {
var div_togglebuttons = document.getElementById("togglebuttons"); let div_togglebuttons = document.getElementById("togglebuttons");
div_togglebuttons.innerHTML = "<span>Toggle column:</span>"; div_togglebuttons.innerHTML = "<span>Toggle column:</span>";
table.getColumns().forEach((col) => { table.getColumns().forEach((col) => {
let col_name = col.getField(); let col_name = col.getField();
@ -274,8 +293,8 @@ div>label {
function update_plan() { function update_plan() {
Promise.all([ Promise.all([
fetch(document.getElementById('base_plan').value, { mode: 'cors' }), fetch(document.getElementById("base_plan").value, { mode: "cors" }),
fetch(document.getElementById('extension_plan').value, { mode: 'cors' }), fetch(document.getElementById("extension_plan").value, { mode: "cors" }),
]).then((res) => { ]).then((res) => {
res.forEach((r) => { res.forEach((r) => {
if (!r.ok) { if (!r.ok) {
@ -300,12 +319,12 @@ div>label {
// eslint-disable-next-line no-unused-vars // eslint-disable-next-line no-unused-vars
function help() { function help() {
alert( alert(
'Base plan and Extension plan: use your own yml file for a band plan, URLs are possible, CORS needs to be allowed for the files, download standard files for examples\n' "Base plan and Extension plan: use your own yml file for a band plan, URLs are possible, CORS needs to be allowed for the files, download standard files for examples\n"
+ 'Filter rows with text in column headings, use filter starting with "!" as exclusion\n' + "Filter rows with text in column headings, use filter starting with \"!\" as exclusion\n"
+ 'Download list: saves .pdf of the current list (selection of rows apply)\n' + "Download list: saves .pdf of the current list (selection of rows apply)\n"
+ 'Selection of rows with mouse possible\n' + "Selection of rows with mouse possible\n"
+ 'Download plans: get the yml plans\n' + "Download plans: get the yml plans\n"
+ 'Create link: get link for currently selected plans for bookmarking\n' + "Create link: get link for currently selected plans for bookmarking\n"
); );
} }
</script> </script>
@ -328,6 +347,8 @@ div>label {
</div> </div>
<div id="data-table"></div> <div id="data-table"></div>
<div id="error"></div> <div id="error"></div>
<div id="comments_base"></div>
<div id="comments_extension"></div>
<div> <div>
<p>This information is supplied without liability.</p> <p>This information is supplied without liability.</p>
<p>Source is at <a href="https://src.dm5wk.de/dm5wk/band-plan-web/">https://src.dm5wk.de/dm5wk/band-plan-web/</a></p> <p>Source is at <a href="https://src.dm5wk.de/dm5wk/band-plan-web/">https://src.dm5wk.de/dm5wk/band-plan-web/</a></p>