[Bandmap] First integration of bandmap from @int2001
这个提交包含在:
父节点
49dcc9c3d0
当前提交
198389a764
共有 8 个文件被更改,包括 269 次插入 和 5 次删除
|
|
@ -0,0 +1,23 @@
|
||||||
|
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
|
||||||
|
|
||||||
|
class Bandmap extends CI_Controller {
|
||||||
|
|
||||||
|
function __construct() {
|
||||||
|
parent::__construct();
|
||||||
|
|
||||||
|
$this->load->model('user_model');
|
||||||
|
if(!$this->user_model->authorize(2)) { $this->session->set_flashdata('notice', 'You\'re not allowed to do that!'); redirect('dashboard'); }
|
||||||
|
}
|
||||||
|
|
||||||
|
function index() {
|
||||||
|
$footerData = [];
|
||||||
|
$footerData['scripts'] = [
|
||||||
|
'assets/js/sections/bandmap.js',
|
||||||
|
];
|
||||||
|
|
||||||
|
$data['page_title'] = "Bandmap";
|
||||||
|
$this->load->view('interface_assets/header', $data);
|
||||||
|
$this->load->view('bandmap/index');
|
||||||
|
$this->load->view('interface_assets/footer', $footerData);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -13,6 +13,7 @@ $lang['menu_live_qso'] = 'Live QSO';
|
||||||
$lang['menu_post_qso'] = 'Post QSO';
|
$lang['menu_post_qso'] = 'Post QSO';
|
||||||
$lang['menu_live_contest_logging'] = 'Live Contest Logging';
|
$lang['menu_live_contest_logging'] = 'Live Contest Logging';
|
||||||
$lang['menu_post_contest_logging'] = 'Post Contest Logging';
|
$lang['menu_post_contest_logging'] = 'Post Contest Logging';
|
||||||
|
$lang['menu_bandmap'] = 'Bandmap';
|
||||||
$lang['menu_view_qsl'] = 'View QSL';
|
$lang['menu_view_qsl'] = 'View QSL';
|
||||||
$lang['menu_view_eqsl'] = 'View eQSL';
|
$lang['menu_view_eqsl'] = 'View eQSL';
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ $lang['menu_live_qso'] = 'Live QSO';
|
||||||
$lang['menu_post_qso'] = 'Zeitversetztes QSO';
|
$lang['menu_post_qso'] = 'Zeitversetztes QSO';
|
||||||
$lang['menu_live_contest_logging'] = 'Live Contest Logging';
|
$lang['menu_live_contest_logging'] = 'Live Contest Logging';
|
||||||
$lang['menu_post_contest_logging'] = 'Zeitversetztes Contest Logging';
|
$lang['menu_post_contest_logging'] = 'Zeitversetztes Contest Logging';
|
||||||
|
$lang['menu_bandmap'] = 'Bandmap';
|
||||||
$lang['menu_view_qsl'] = 'QSL Ansicht';
|
$lang['menu_view_qsl'] = 'QSL Ansicht';
|
||||||
$lang['menu_view_eqsl'] = 'eQSL Ansicht';
|
$lang['menu_view_eqsl'] = 'eQSL Ansicht';
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,12 @@
|
||||||
|
<div class="container">
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
||||||
|
<h2><?php echo $page_title; ?></h2>
|
||||||
|
|
||||||
|
<figure class="highcharts-figure">
|
||||||
|
<div id="bandmap"></div>
|
||||||
|
<p class="highcharts-description">
|
||||||
|
</p>
|
||||||
|
</figure>
|
||||||
|
</div>
|
||||||
|
|
@ -2911,6 +2911,15 @@ function viewEqsl(picture, callsign) {
|
||||||
</script>
|
</script>
|
||||||
<?php } ?>
|
<?php } ?>
|
||||||
|
|
||||||
|
<?php if ($this->uri->segment(1) == "bandmap") { ?>
|
||||||
|
|
||||||
|
<script src="https://code.highcharts.com/highcharts.js"></script>
|
||||||
|
<script src="https://code.highcharts.com/modules/timeline.js"></script>
|
||||||
|
<script src="https://code.highcharts.com/modules/exporting.js"></script>
|
||||||
|
<script src="https://code.highcharts.com/modules/accessibility.js"></script>
|
||||||
|
|
||||||
|
<?php } ?>
|
||||||
|
|
||||||
<?php if ($this->uri->segment(1) == "awards") {
|
<?php if ($this->uri->segment(1) == "awards") {
|
||||||
// Get Date format
|
// Get Date format
|
||||||
if($this->session->userdata('user_date_format')) {
|
if($this->session->userdata('user_date_format')) {
|
||||||
|
|
|
||||||
|
|
@ -81,6 +81,8 @@
|
||||||
<div class="dropdown-divider"></div>
|
<div class="dropdown-divider"></div>
|
||||||
<a class="dropdown-item" href="<?php echo site_url('contesting?manual=1');?>" title="Post contest QSOs"><i class="fas fa-list"></i> <?php echo lang('menu_post_contest_logging'); ?></a>
|
<a class="dropdown-item" href="<?php echo site_url('contesting?manual=1');?>" title="Post contest QSOs"><i class="fas fa-list"></i> <?php echo lang('menu_post_contest_logging'); ?></a>
|
||||||
<div class="dropdown-divider"></div>
|
<div class="dropdown-divider"></div>
|
||||||
|
<a class="dropdown-item" href="<?php echo site_url('bandmap');?>" title="Bandmap"><i class="fa fa-id-card"></i> <?php echo lang('menu_bandmap'); ?></a>
|
||||||
|
<div class="dropdown-divider"></div>
|
||||||
<a class="dropdown-item" href="<?php echo site_url('qsl');?>" title="QSL"><i class="fa fa-id-card"></i> <?php echo lang('menu_view_qsl'); ?></a>
|
<a class="dropdown-item" href="<?php echo site_url('qsl');?>" title="QSL"><i class="fa fa-id-card"></i> <?php echo lang('menu_view_qsl'); ?></a>
|
||||||
<div class="dropdown-divider"></div>
|
<div class="dropdown-divider"></div>
|
||||||
<a class="dropdown-item" href="<?php echo site_url('eqsl');?>" title="eQSL"><i class="fa fa-id-card"></i> <?php echo lang('menu_view_eqsl'); ?></a>
|
<a class="dropdown-item" href="<?php echo site_url('eqsl');?>" title="eQSL"><i class="fa fa-id-card"></i> <?php echo lang('menu_view_eqsl'); ?></a>
|
||||||
|
|
@ -179,7 +181,7 @@
|
||||||
<div class="dropdown-divider"></div>
|
<div class="dropdown-divider"></div>
|
||||||
|
|
||||||
<a class="dropdown-item" href="<?php echo site_url('debug');?>" title="Debug Information"><i class="fas fa-tools"></i> <?php echo lang('menu_debug_information'); ?></a>
|
<a class="dropdown-item" href="<?php echo site_url('debug');?>" title="Debug Information"><i class="fas fa-tools"></i> <?php echo lang('menu_debug_information'); ?></a>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
<?php } ?>
|
<?php } ?>
|
||||||
|
|
@ -282,8 +284,8 @@ $oqrs_requests = $CI->oqrs_model->oqrs_requests($location_list);
|
||||||
<a class="dropdown-item" href="<?php echo site_url('user/logout');?>" title="Logout"><i class="fas fa-sign-out-alt"></i> <?php echo lang('menu_logout'); ?></a>
|
<a class="dropdown-item" href="<?php echo site_url('user/logout');?>" title="Logout"><i class="fas fa-sign-out-alt"></i> <?php echo lang('menu_logout'); ?></a>
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
<?php
|
<?php
|
||||||
// Can add extra menu items by defining them in options. The format is json.
|
// Can add extra menu items by defining them in options. The format is json.
|
||||||
// Useful to add extra things in Cloudlog without the need for modifying files. If you add extras, these files will not be overwritten when updating.
|
// Useful to add extra things in Cloudlog without the need for modifying files. If you add extras, these files will not be overwritten when updating.
|
||||||
//
|
//
|
||||||
|
|
@ -308,7 +310,7 @@ $oqrs_requests = $CI->oqrs_model->oqrs_requests($location_list);
|
||||||
<li class="nav-item dropdown">
|
<li class="nav-item dropdown">
|
||||||
<a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Extras</a>
|
<a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Extras</a>
|
||||||
<div class="dropdown-menu" aria-labelledby="navbarDropdown">
|
<div class="dropdown-menu" aria-labelledby="navbarDropdown">
|
||||||
<?php
|
<?php
|
||||||
foreach(json_decode($this->optionslib->get_option('menuitems')) as $item) {
|
foreach(json_decode($this->optionslib->get_option('menuitems')) as $item) {
|
||||||
echo '<a class="dropdown-item" href="' . site_url($item->url) . '" title="Gridsquares"><i class="fas '. $item->icon .'"></i> ' . $item->text . '</a>';
|
echo '<a class="dropdown-item" href="' . site_url($item->url) . '" title="Gridsquares"><i class="fas '. $item->icon .'"></i> ' . $item->text . '</a>';
|
||||||
}
|
}
|
||||||
|
|
@ -316,7 +318,7 @@ $oqrs_requests = $CI->oqrs_model->oqrs_requests($location_list);
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
<?php } ?>
|
<?php } ?>
|
||||||
|
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<?php } ?>
|
<?php } ?>
|
||||||
|
|
|
||||||
|
|
@ -458,3 +458,53 @@ div#station_logbooks_linked_table_paginate {
|
||||||
.lotw_info_red {
|
.lotw_info_red {
|
||||||
background-image: linear-gradient(to bottom, #3fb618, red);
|
background-image: linear-gradient(to bottom, #3fb618, red);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.highcharts-strong {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.highcharts-figure,
|
||||||
|
.highcharts-data-table table {
|
||||||
|
min-width: 320px;
|
||||||
|
max-width: 100%;
|
||||||
|
margin: 1em auto;
|
||||||
|
max-height: calc(100vh - 200px) !important;
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.highcharts-data-table table {
|
||||||
|
font-family: Verdana, sans-serif;
|
||||||
|
border-collapse: collapse;
|
||||||
|
border: 1px solid #ebebeb;
|
||||||
|
margin: 10px auto;
|
||||||
|
text-align: center;
|
||||||
|
width: 100%;
|
||||||
|
max-width: 500px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.highcharts-data-table caption {
|
||||||
|
padding: 1em 0;
|
||||||
|
font-size: 1.2em;
|
||||||
|
color: #555;
|
||||||
|
}
|
||||||
|
|
||||||
|
.highcharts-data-table th {
|
||||||
|
font-weight: 600;
|
||||||
|
padding: 0.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.highcharts-data-table td,
|
||||||
|
.highcharts-data-table th,
|
||||||
|
.highcharts-data-table caption {
|
||||||
|
padding: 0.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.highcharts-data-table thead tr,
|
||||||
|
.highcharts-data-table tr:nth-child(even) {
|
||||||
|
background: #f8f8f8;
|
||||||
|
}
|
||||||
|
|
||||||
|
.highcharts-data-table tr:hover {
|
||||||
|
background: #f1f7ff;
|
||||||
|
}
|
||||||
166
assets/js/sections/bandmap.js
普通文件
166
assets/js/sections/bandmap.js
普通文件
|
|
@ -0,0 +1,166 @@
|
||||||
|
$(function() {
|
||||||
|
(function(H) {
|
||||||
|
H.seriesTypes.timeline.prototype.distributeDL = function() {
|
||||||
|
var series = this,
|
||||||
|
dataLabelsOptions = series.options.dataLabels,
|
||||||
|
options,
|
||||||
|
pointDLOptions,
|
||||||
|
newOptions = {},
|
||||||
|
visibilityIndex = 1,
|
||||||
|
j = 2,
|
||||||
|
distance;
|
||||||
|
|
||||||
|
series.points.forEach(function(point, i) {
|
||||||
|
distance = dataLabelsOptions.distance;
|
||||||
|
|
||||||
|
if (point.visible && !point.isNull) {
|
||||||
|
options = point.options;
|
||||||
|
pointDLOptions = point.options.dataLabels;
|
||||||
|
|
||||||
|
if (!series.hasRendered) {
|
||||||
|
point.userDLOptions = H.merge({}, pointDLOptions);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
if (i === j || i === j + 1) {
|
||||||
|
distance = distance * 2.5
|
||||||
|
|
||||||
|
if (i === j + 1) {
|
||||||
|
j += 4
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
if (i % 6 == 0) { distance = distance * 1; }
|
||||||
|
if (i % 6 == 1) { distance = distance * -1; }
|
||||||
|
if (i % 6 == 2) { distance = distance * 2; }
|
||||||
|
if (i % 6 == 3) { distance = distance * -2; }
|
||||||
|
if (i % 6 == 4) { distance = distance * 3; }
|
||||||
|
if (i % 6 == 5) { distance = distance * -3; }
|
||||||
|
|
||||||
|
newOptions[series.chart.inverted ? 'x' : 'y'] = distance;
|
||||||
|
// newOptions[series.chart.inverted ? 'x' : 'y'] = dataLabelsOptions.alternate && (visibilityIndex % 3 != 0) ? -distance : distance;
|
||||||
|
|
||||||
|
options.dataLabels = H.merge(newOptions, point.userDLOptions);
|
||||||
|
visibilityIndex++;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}(Highcharts));
|
||||||
|
|
||||||
|
var dxcluster_provider = 'https://dxc.jo30.de/dxcache';
|
||||||
|
var bandMapChart;
|
||||||
|
var color = ifDarkModeThemeReturn('white', 'grey');
|
||||||
|
|
||||||
|
function render_chart (band,spot_data) {
|
||||||
|
let chartObject=Highcharts.chart('bandmap', {
|
||||||
|
chart: {
|
||||||
|
type: 'timeline',
|
||||||
|
zoomType: 'x',
|
||||||
|
inverted: true,
|
||||||
|
backgroundColor: getBodyBackground(),
|
||||||
|
height: '800px'
|
||||||
|
},
|
||||||
|
accessibility: {
|
||||||
|
screenReaderSection: {
|
||||||
|
beforeChartFormat: '<h5>{chartTitle}</h5>' +
|
||||||
|
'<div>{typeDescription}</div>' +
|
||||||
|
'<div>{chartSubtitle}</div>' +
|
||||||
|
'<div>{chartLongdesc}</div>' +
|
||||||
|
'<div>{viewTableButton}</div>'
|
||||||
|
},
|
||||||
|
point: {
|
||||||
|
valueDescriptionFormat: '{index}. {point.label}. {point.description}.'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
xAxis: {
|
||||||
|
visible: true,
|
||||||
|
type: 'linear',
|
||||||
|
labels: {
|
||||||
|
style: {
|
||||||
|
color: color,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
yAxis: {
|
||||||
|
visible: false,
|
||||||
|
},
|
||||||
|
title: {
|
||||||
|
text: band,
|
||||||
|
style: {
|
||||||
|
color: color
|
||||||
|
}
|
||||||
|
},
|
||||||
|
series: [ { data: spot_data } ]
|
||||||
|
});
|
||||||
|
return chartObject;
|
||||||
|
}
|
||||||
|
|
||||||
|
function SortByQrg(a, b){
|
||||||
|
var a = a.frequency;
|
||||||
|
var b = b.frequency;
|
||||||
|
return ((a< b) ? -1 : ((a> b) ? 1 : 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
function reduce_spots(spotobject) {
|
||||||
|
let unique=[];
|
||||||
|
spotobject.forEach((single) => {
|
||||||
|
if (!spotobject.find((item) => ((item.spotted == single.spotted) && (item.frequency == single.frequency) && (Date.parse(item.when)>Date.parse(single.when))))) {
|
||||||
|
unique.push(single);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return unique;
|
||||||
|
}
|
||||||
|
|
||||||
|
function convert2high(spotobject) {
|
||||||
|
let ret={};
|
||||||
|
ret.name=spotobject.spotted;
|
||||||
|
ret.x=spotobject.frequency;
|
||||||
|
ret.description=spotobject.frequency + " / "+Math.round( (Date.now() - Date.parse(spotobject.when)) / 1000 / 60)+"min. ago";
|
||||||
|
ret.dataLabels={};
|
||||||
|
ret.dataLabels.alternate=true;
|
||||||
|
ret.dataLabels.distance=200;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
function update_chart(lowerQrg,upperQrg,maxAgeMinutes) {
|
||||||
|
$.ajax({
|
||||||
|
url: dxcluster_provider + "/spots",
|
||||||
|
cache: false,
|
||||||
|
dataType: "json"
|
||||||
|
}).done(function(dxspots) {
|
||||||
|
spots4chart=[];
|
||||||
|
dxspots.sort(SortByQrg);
|
||||||
|
dxspots=reduce_spots(dxspots);
|
||||||
|
dxspots.forEach((single) => {
|
||||||
|
if ( (single.frequency >= lowerQrg) && (single.frequency <= upperQrg) && (Date.parse(single.when)>(Date.now() - 1000 * 60 * maxAgeMinutes)) ) {
|
||||||
|
spots4chart.push(convert2high(single));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// console.log(spots4chart);
|
||||||
|
bandMapChart.series[0].setData(spots4chart);
|
||||||
|
bandMapChart.redraw();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function set_chart(lowerQrg,upperQrg,maxAgeMinutes) {
|
||||||
|
$.ajax({
|
||||||
|
url: dxcluster_provider + "/spots",
|
||||||
|
cache: false,
|
||||||
|
dataType: "json"
|
||||||
|
}).done(function(dxspots) {
|
||||||
|
spots4chart=[];
|
||||||
|
dxspots.sort(SortByQrg);
|
||||||
|
dxspots=reduce_spots(dxspots);
|
||||||
|
dxspots.forEach((single) => {
|
||||||
|
if ( (single.frequency >= lowerQrg) && (single.frequency <= upperQrg) && (Date.parse(single.when)>(Date.now() - 1000 * 60 * maxAgeMinutes)) ) {
|
||||||
|
spots4chart.push(convert2high(single));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
bandMapChart=render_chart('20m',spots4chart);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
set_chart(14000,14350,30);
|
||||||
|
setInterval(function () { update_chart(14000,14350,30); },60000);
|
||||||
|
});
|
||||||
正在加载…
在新工单中引用