New feature: timeplotter
这个提交包含在:
父节点
93730f37e7
当前提交
66365a7e55
共有 5 个文件被更改,包括 353 次插入 和 1 次删除
|
|
@ -0,0 +1,49 @@
|
|||
<?php
|
||||
defined('BASEPATH') OR exit('No direct script access allowed');
|
||||
|
||||
class Timeplotter 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'); }
|
||||
}
|
||||
|
||||
public function index()
|
||||
{
|
||||
// Render Page
|
||||
$data['page_title'] = "Timeplotter";
|
||||
|
||||
$this->load->model('Timeplotter_model');
|
||||
|
||||
$data['worked_bands'] = $this->Timeplotter_model->get_worked_bands();
|
||||
|
||||
$this->load->model('dxcc');
|
||||
$data['dxcc_list'] = $this->dxcc->list();
|
||||
|
||||
$this->load->model('modes');
|
||||
|
||||
$data['modes'] = $this->modes->active();
|
||||
|
||||
$this->load->view('interface_assets/header', $data);
|
||||
$this->load->view('timeplotter/index');
|
||||
$this->load->view('interface_assets/footer');
|
||||
}
|
||||
|
||||
public function getTimes() {
|
||||
// POST data
|
||||
$postData = $this->input->post();
|
||||
|
||||
//load model
|
||||
$this->load->model('Timeplotter_model');
|
||||
|
||||
// get data
|
||||
$data = $this->Timeplotter_model->getTimes($postData);
|
||||
|
||||
return json_encode($data);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,151 @@
|
|||
<?php
|
||||
if (!defined('BASEPATH')) exit('No direct script access allowed');
|
||||
|
||||
class Timeplotter_model extends CI_Model
|
||||
{
|
||||
function __construct()
|
||||
{
|
||||
// Call the Model constructor
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
function get_worked_bands() {
|
||||
$CI =& get_instance();
|
||||
$CI->load->model('Stations');
|
||||
$station_id = $CI->Stations->find_active();
|
||||
|
||||
$data = $this->db->query(
|
||||
"SELECT distinct LOWER(`COL_BAND`) as `COL_BAND` FROM `" . $this->config->item('table_name') . "` WHERE station_id = " . $station_id . " AND COL_PROP_MODE != \"SAT\""
|
||||
);
|
||||
$worked_slots = array();
|
||||
foreach ($data->result() as $row) {
|
||||
array_push($worked_slots, $row->COL_BAND);
|
||||
}
|
||||
|
||||
$SAT_data = $this->db->query(
|
||||
"SELECT distinct LOWER(`COL_PROP_MODE`) as `COL_PROP_MODE` FROM `" . $this->config->item('table_name') . "` WHERE station_id = " . $station_id . " AND COL_PROP_MODE = \"SAT\""
|
||||
);
|
||||
|
||||
foreach ($SAT_data->result() as $row) {
|
||||
array_push($worked_slots, strtoupper($row->COL_PROP_MODE));
|
||||
}
|
||||
|
||||
// bring worked-slots in order of defined $bandslots
|
||||
$results = array();
|
||||
foreach (array_keys($this->bandslots) as $slot) {
|
||||
if (in_array($slot, $worked_slots)) {
|
||||
array_push($results, $slot);
|
||||
}
|
||||
}
|
||||
return $results;
|
||||
}
|
||||
|
||||
public $bandslots = array("160m" => 0,
|
||||
"80m" => 0,
|
||||
"60m" => 0,
|
||||
"40m" => 0,
|
||||
"30m" => 0,
|
||||
"20m" => 0,
|
||||
"17m" => 0,
|
||||
"15m" => 0,
|
||||
"12m" => 0,
|
||||
"10m" => 0,
|
||||
"6m" => 0,
|
||||
"4m" => 0,
|
||||
"2m" => 0,
|
||||
"70cm" => 0,
|
||||
"23cm" => 0,
|
||||
"13cm" => 0,
|
||||
"9cm" => 0,
|
||||
"6cm" => 0,
|
||||
"3cm" => 0,
|
||||
"1.25cm" => 0,
|
||||
"SAT" => 0,
|
||||
);
|
||||
|
||||
function getTimes($postdata) {
|
||||
$CI =& get_instance();
|
||||
$CI->load->model('Stations');
|
||||
$station_id = $CI->Stations->find_active();
|
||||
|
||||
$this->db->select('time(col_time_on) time, col_call as callsign');
|
||||
|
||||
if ($postdata['band'] != 'All') {
|
||||
if ($postdata['band'] == 'sat') {
|
||||
$this->db->where('col_prop_mode', $postdata['band']);
|
||||
}
|
||||
else {
|
||||
$this->db->where('col_band', $postdata['band']);
|
||||
}
|
||||
}
|
||||
|
||||
if ($postdata['dxcc'] != 'All') {
|
||||
$this->db->where('col_dxcc', $postdata['dxcc']);
|
||||
}
|
||||
|
||||
if ($postdata['cqzone'] != 'All') {
|
||||
$this->db->where('col_cqz', $postdata['cqzone']);
|
||||
}
|
||||
|
||||
$this->db->where('station_id', $station_id);
|
||||
$datearray = $this->db->get($this->config->item('table_name'));
|
||||
$this->plot($datearray->result_array());
|
||||
}
|
||||
|
||||
/*
|
||||
* Function generates the array, checks for array entries, and adds them before returning data ready for plot
|
||||
*/
|
||||
function plot($log) {
|
||||
|
||||
$start = "00:00";
|
||||
$end = "23:59";
|
||||
|
||||
$tStart = strtotime($start);
|
||||
$tEnd = strtotime($end);
|
||||
$tNow = $tStart;
|
||||
$i = 0;
|
||||
|
||||
while($tNow <= $tEnd){ // Generates the time array
|
||||
$label = date("H:i",$tNow).'z - ';
|
||||
$tNow = strtotime('+30 minutes',$tNow);
|
||||
$label .= date("H:i",$tNow).'z';
|
||||
$dataarray[$i]['time'] = $label; // Used in x-axis of graph to show label for the timeslot
|
||||
$dataarray[$i]['count'] = '0'; // Used to hold number of contacts found in the timeslot
|
||||
$dataarray[$i]['calls'] = ''; // Used for holding callsigns of contacts in that timeslot
|
||||
$dataarray[$i]['callcount'] = '0'; // Used for counting how many callsigns stored in that timeslot
|
||||
$i++;
|
||||
}
|
||||
|
||||
foreach ($log as $line) { // Looping through all the timestamps found in the log
|
||||
$time = $line['time']; // Resolution is 30, calculates where to put result in array
|
||||
$dt = new DateTime("1970-01-01 $time", new DateTimeZone('UTC'));
|
||||
$arrayplacement = (int)$dt->getTimestamp();
|
||||
$arrayplacement = floor($arrayplacement / 1800);
|
||||
$dataarray[$arrayplacement]['count']++;
|
||||
|
||||
$callCount = $dataarray[$arrayplacement]['callcount'];
|
||||
|
||||
if ($callCount < 5) { // We only save a max of 5 calls to show in the graph
|
||||
if ($callCount > 0) {
|
||||
$dataarray[$arrayplacement]['calls'] .= ', ';
|
||||
}
|
||||
$dataarray[$arrayplacement]['calls'] .= $line['callsign'];
|
||||
$dataarray[$arrayplacement]['callcount']++;
|
||||
}
|
||||
}
|
||||
|
||||
if (count($log) != 0) { // If we have a result from the log
|
||||
header('Content-Type: application/json');
|
||||
$data['qsocount'] = count($log);
|
||||
$data['ok'] = 'OK';
|
||||
$data['qsodata'] = $dataarray;
|
||||
echo json_encode($data);
|
||||
}
|
||||
else {
|
||||
header('Content-Type: application/json');
|
||||
$data['error'] = 'No qsoes to plot found!';
|
||||
echo json_encode($data);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -2042,5 +2042,95 @@ $(document).ready(function(){
|
|||
</script>
|
||||
<?php } ?>
|
||||
|
||||
<?php if ($this->uri->segment(1) == "timeplotter") { ?>
|
||||
<script src="https://code.highcharts.com/stock/highstock.js"></script>
|
||||
<script>
|
||||
|
||||
function timeplot(form) {
|
||||
$(".ld-ext-right").addClass('running');
|
||||
$(".ld-ext-right").prop('disabled', true);
|
||||
$(".alert").remove();
|
||||
var baseURL= "<?php echo base_url();?>";
|
||||
$.ajax({
|
||||
url: baseURL+'index.php/timeplotter/getTimes',
|
||||
type: 'post',
|
||||
data: {'band': form.band.value, 'dxcc': form.dxcc.value, 'cqzone': form.cqzone.value},
|
||||
success: function(tmp) {
|
||||
$(".ld-ext-right").removeClass('running');
|
||||
$(".ld-ext-right").prop('disabled', false);
|
||||
if (tmp.ok == 'OK') {
|
||||
plotTimeplotterChart(tmp);
|
||||
}
|
||||
else {
|
||||
$("#container").remove();
|
||||
$("#info").remove();
|
||||
$("#timeplotter_div").append('<div class="alert alert-danger"><a href="#" class="close" data-dismiss="alert" aria-label="close">×</a>\n' +
|
||||
tmp.error +
|
||||
'</div>');
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function plotTimeplotterChart(tmp) {
|
||||
$("#container").remove();
|
||||
$("#info").remove();
|
||||
$("#timeplotter_div").append('<p id="info">' + tmp.qsocount + ' contacts were plotted.</p><div id="container" style="height: 600px;"></div>');
|
||||
var options = {
|
||||
chart: {
|
||||
type: 'column',
|
||||
zoomType: 'xy',
|
||||
renderTo: 'container'
|
||||
},
|
||||
title: {
|
||||
text: 'Time distribution'
|
||||
},
|
||||
xAxis: {
|
||||
categories: [],
|
||||
crosshair: true,
|
||||
type: "category",
|
||||
min:0,
|
||||
max:47,
|
||||
},
|
||||
yAxis: {
|
||||
title: {
|
||||
text: '# QSOes'
|
||||
}
|
||||
},
|
||||
rangeSelector: {
|
||||
selected: 1
|
||||
},
|
||||
tooltip: {
|
||||
formatter: function () {
|
||||
if(this.point) {
|
||||
return "Time: " + options.xAxis.categories[this.point.x] +
|
||||
"<br />Callsign(s) worked (max 5): " + myComments[this.point.x] +
|
||||
"<br />Number of qsos: <strong>" + series.data[this.point.x] + "</strong>";
|
||||
}
|
||||
}
|
||||
},
|
||||
series: []
|
||||
};
|
||||
var myComments=[];
|
||||
|
||||
var series = {
|
||||
data: []
|
||||
};
|
||||
|
||||
$.each(tmp.qsodata, function(){
|
||||
myComments.push(this.calls);
|
||||
options.xAxis.categories.push(this.time);
|
||||
series.name = 'Number of qsos';
|
||||
series.data.push(this.count);
|
||||
});
|
||||
|
||||
options.series.push(series);
|
||||
|
||||
var chart = new Highcharts.Chart(options);
|
||||
}
|
||||
|
||||
</script>
|
||||
<?php } ?>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@
|
|||
<link rel="stylesheet" type="text/css" href="<?php echo base_url(); ?>assets/plugins/quill/quill.snow.css" />
|
||||
<?php } ?>
|
||||
|
||||
<?php if ($this->uri->segment(1) == "qrz" || $this->uri->segment(1) == "accumulated") { ?>
|
||||
<?php if ($this->uri->segment(1) == "qrz" || $this->uri->segment(1) == "accumulated" || $this->uri->segment(1) == "timeplotter") { ?>
|
||||
<link rel="stylesheet" type="text/css" href="<?php echo base_url(); ?>assets/css/loading.min.css" />
|
||||
<link rel="stylesheet" type="text/css" href="<?php echo base_url(); ?>assets/css/ldbtn.min.css" />
|
||||
<?php } ?>
|
||||
|
|
@ -86,6 +86,8 @@
|
|||
<a class="dropdown-item" href="<?php echo site_url('timeline');?>" title="Dxcctimeline">DXCC Timeline</a>
|
||||
<div class="dropdown-divider"></div>
|
||||
<a class="dropdown-item" href="<?php echo site_url('accumulated');?>" title="Dxcctimeline">Accumulated statistics</a>
|
||||
<div class="dropdown-divider"></div>
|
||||
<a class="dropdown-item" href="<?php echo site_url('timeplotter');?>" title="View time when worked">Timeplotter</a>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,60 @@
|
|||
<div class="container">
|
||||
<h2><?php echo $page_title; ?></h1>
|
||||
<p>This tool is used to analyze your log to find out when you have worked a certain cq zone or dxcc on a chosen band.</p>
|
||||
<form class="form">
|
||||
|
||||
<div class="form-group row">
|
||||
<label class="col-md-1 control-label" for="band">Band</label>
|
||||
<div class="col-md-3">
|
||||
<select id="band" name="band" class="form-control custom-select">
|
||||
<option value="All">All</option>
|
||||
<?php foreach($worked_bands as $band) {
|
||||
echo '<option value="' . $band . '">' . $band . '</option>'."\n";
|
||||
} ?>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<label class="col-md-1 control-label" for="dxcc">DXCC</label>
|
||||
<div class="col-md-3">
|
||||
<select id="dxcc" name="dxcc" class="form-control custom-select">
|
||||
<option value = 'All'>All</option>
|
||||
<?php
|
||||
if ($dxcc_list->num_rows() > 0) {
|
||||
foreach ($dxcc_list->result() as $dxcc) {
|
||||
echo '<option value=' . $dxcc->adif . '> ' . $dxcc->name . ' - ' . $dxcc->prefix;
|
||||
if ($dxcc->end != null) {
|
||||
echo ' (deleted)';
|
||||
}
|
||||
echo '</option>';
|
||||
}
|
||||
}
|
||||
?>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group row">
|
||||
<label class="col-md-1 control-label" for="cqzone">CQ Zone</label>
|
||||
<div class="col-md-3">
|
||||
<select id="cqzone" name="cqzone" class="form-control custom-select">
|
||||
<option value = 'All'>All</option>
|
||||
<?php
|
||||
for ($i = 1; $i<=40; $i++) {
|
||||
echo '<option value='. $i . '>'. $i .'</option>';
|
||||
}
|
||||
?>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group row">
|
||||
<div class="col-md-3">
|
||||
<button id="button1id" type="button" name="button1id" class="btn btn-success btn-primary ld-ext-right" onclick="timeplot(this.form);">Show<div class="ld ld-ring ld-spin"></div></button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</form>
|
||||
|
||||
<div id="timeplotter_div">
|
||||
</div>
|
||||
</div>
|
||||
正在加载…
在新工单中引用