Change-Id: I223860719b66f8f86afaa7c839ba1320b6a01aadchanges/88/4288/5
parent
e0f80027b1
commit
d8c903281c
@ -1,128 +0,0 @@
|
||||
package NGCP::Panel::Controller::Calls;
|
||||
use NGCP::Panel::Utils::Generic qw(:all);
|
||||
use Sipwise::Base;
|
||||
use DateTime::Format::Strptime;
|
||||
|
||||
BEGIN { use base 'Catalyst::Controller'; }
|
||||
|
||||
use NGCP::Panel::Utils::Navigation;
|
||||
use Number::Phone;
|
||||
|
||||
sub auto :Does(ACL) :ACLDetachTo('/denied_page') :AllowedRole(admin) {
|
||||
my ($self, $c) = @_;
|
||||
$c->log->debug(__PACKAGE__ . '::auto');
|
||||
NGCP::Panel::Utils::Navigation::check_redirect_chain(c => $c);
|
||||
return 1;
|
||||
}
|
||||
|
||||
sub root :PathPart('/') :CaptureArgs(0) {
|
||||
my ( $self, $c ) = @_;
|
||||
}
|
||||
|
||||
sub index :Chained('/') :PathPart('calls') :Args(0) {
|
||||
my ( $self, $c ) = @_;
|
||||
|
||||
$c->stash(template => 'calls/chord.tt');
|
||||
}
|
||||
|
||||
sub calls_matrix_ajax :Chained('/') :PathPart('calls/ajax') :Args(0) {
|
||||
my ( $self, $c ) = @_;
|
||||
|
||||
my $matrix = [];
|
||||
my $countries = [];
|
||||
my $from = $c->req->params->{from};
|
||||
my $to = $c->req->params->{to};
|
||||
my $parse_time = DateTime::Format::Strptime->new(pattern => '%F');
|
||||
|
||||
my $from_epoch;
|
||||
if($from) {
|
||||
$from_epoch = $parse_time->parse_datetime($from)->epoch();
|
||||
} else {
|
||||
$from_epoch = NGCP::Panel::Utils::DateTime::current_local->truncate(to => 'day')->epoch();
|
||||
}
|
||||
my $to_epoch;
|
||||
if($to) {
|
||||
$to_epoch = $parse_time->parse_datetime($to)->add(days => 1)->epoch();
|
||||
} else {
|
||||
$to_epoch = NGCP::Panel::Utils::DateTime::current_local->truncate(to => 'day')->add(days => 1)->epoch();
|
||||
}
|
||||
|
||||
my $rs = $c->model('DB')->resultset('cdr')->search({
|
||||
-and => [
|
||||
start_time => { '>=' => $from_epoch },
|
||||
start_time => { '<=' => $to_epoch },
|
||||
],
|
||||
}, {
|
||||
select => [qw/source_cli destination_user_in/,
|
||||
{ count => '*', -as => 'cnt' },
|
||||
],
|
||||
group_by => [qw/source_cli destination_user_in/],
|
||||
});
|
||||
|
||||
my $id_counter = 0;
|
||||
my $id_table = {};
|
||||
my $i = 0;
|
||||
while(my $ref = $rs->next) {
|
||||
next unless($ref->source_cli && $ref->source_cli =~ /^\d{5,}$/ &&
|
||||
$ref->destination_user_in && $ref->destination_user_in =~ /^\d{5,}$/);
|
||||
my $s = Number::Phone->new($ref->source_cli);
|
||||
my $d = Number::Phone->new($ref->destination_user_in);
|
||||
next unless($s && $d);
|
||||
|
||||
# register new ids for those country codes
|
||||
unless(exists $id_table->{$s->country_code}) {
|
||||
$id_table->{$s->country_code} = $id_counter;
|
||||
$countries->[$id_counter] = $s->country;
|
||||
++$id_counter;
|
||||
}
|
||||
unless(exists $id_table->{$d->country_code}) {
|
||||
$id_table->{$d->country_code} = $id_counter;
|
||||
$countries->[$id_counter] = $d->country;
|
||||
++$id_counter;
|
||||
}
|
||||
|
||||
my $sid = $id_table->{$s->country_code};
|
||||
my $did = $id_table->{$d->country_code};
|
||||
|
||||
unless(defined $matrix->[$sid]) {
|
||||
$matrix->[$sid] = [];
|
||||
}
|
||||
unless(defined $matrix->[$sid]->[$did]) {
|
||||
$matrix->[$sid]->[$did] = 0 + $ref->get_column('cnt');
|
||||
} else {
|
||||
$matrix->[$sid]->[$did] += $ref->get_column('cnt');
|
||||
}
|
||||
}
|
||||
my $count = @{ $countries };
|
||||
for(my $i = 0; $i < $count; ++$i) {
|
||||
unless(defined $matrix->[$i]) {
|
||||
$matrix->[$i] = [];
|
||||
$matrix->[$i]->[$count-1] = undef;
|
||||
} elsif(@{ $matrix->[$i] } != $count) {
|
||||
$matrix->[$i]->[$count-1] = undef;
|
||||
}
|
||||
}
|
||||
my $data = {
|
||||
countries => $countries,
|
||||
calls => $matrix,
|
||||
};
|
||||
my $json = JSON->new->allow_nonref;
|
||||
$c->res->body($json->encode($data));
|
||||
}
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Andreas Granig,,,
|
||||
|
||||
=head1 LICENSE
|
||||
|
||||
This library is free software. You can redistribute it and/or modify
|
||||
it under the same terms as Perl itself.
|
||||
|
||||
=cut
|
||||
|
||||
__PACKAGE__->meta->make_immutable;
|
||||
|
||||
1;
|
||||
|
||||
# vim: set tabstop=4 expandtab:
|
||||
@ -1,82 +0,0 @@
|
||||
[% site_config.title = c.loc('Call Distribution') -%]
|
||||
[%
|
||||
USE date;
|
||||
today = date.format(date.now, '%Y-%m-%d');
|
||||
|
||||
-%]
|
||||
<style>
|
||||
#circle circle {
|
||||
fill: none;
|
||||
pointer-events: all;
|
||||
}
|
||||
|
||||
.group path {
|
||||
fill-opacity: .5;
|
||||
}
|
||||
|
||||
path.chord {
|
||||
stroke: #000;
|
||||
stroke-width: .25px;
|
||||
}
|
||||
|
||||
#circle:hover path.fade {
|
||||
display: none;
|
||||
}
|
||||
|
||||
svg {
|
||||
font: 10px sans-serif;
|
||||
}
|
||||
|
||||
.axis path, .axis line {
|
||||
fill: none;
|
||||
stroke: #000;
|
||||
shape-rendering: crispEdges;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
<script type="text/javascript" src="/js/libs/d3.v2.min-2.8.1.js"></script>
|
||||
<script type="text/javascript" src="/js/libs/ngcp-chord.js"></script>
|
||||
|
||||
<div class="row">
|
||||
<span>
|
||||
<a class="btn btn-primary btn-large" href="[% c.uri_for('/back') %]"><i class="icon-arrow-left"></i> [% c.loc('Back') %]</a>
|
||||
</span>
|
||||
</div>
|
||||
[% back_created = 1 -%]
|
||||
<div class="ngcp-separator"></div>
|
||||
|
||||
<p>[% c.loc('Mouseover on a country name to focus on calls to or from a single country. The thickness of links between countries encodes the relative frequency of calls between two countries: thicker links represent more calls.') %]</p>
|
||||
<p>[% c.loc('Links are colored by the more frequent origin. Mouseover on a link to see the direction details.') %]</p>
|
||||
|
||||
<div class="row-fluid" style="margin-top:50px">
|
||||
<div class="span3">
|
||||
<label>[% c.loc('From Date:') %] <input type="text" id="datepicker_start" class="ngcp-datepicker" rel="tooltip" data-original-title="YYYY-MM-DD" value="[% today %]"/></label>
|
||||
</div>
|
||||
<div class="span3">
|
||||
<label>[% c.loc('To Date:') %] <input type="text" id="datepicker_end" class="ngcp-datepicker" rel="tooltip" data-original-title="YYYY-MM-DD" value="[% today %]"/></label>
|
||||
</div>
|
||||
<div class="span2">
|
||||
<a href="#" id="load-chord" class="btn btn-primary"><i class="icon-repeat" style="padding-top:3px"></i> [% c.loc('Reload') %]</a>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
$('#datepicker_start').datepicker({
|
||||
"dateFormat": "yy-mm-dd",
|
||||
});
|
||||
$('#datepicker_end').datepicker({
|
||||
"dateFormat": "yy-mm-dd"
|
||||
});
|
||||
$('#load-chord').click(function(e) {
|
||||
$('svg').remove();
|
||||
loadChord();
|
||||
});
|
||||
// load diagram after document is ready
|
||||
$(function() {
|
||||
loadChord();
|
||||
});
|
||||
</script>
|
||||
|
||||
<div class="offset2 span6" id="ngcp-cdr-chord" style="margin-top:20px">
|
||||
</div>
|
||||
[% # vim: set tabstop=4 syntax=html expandtab: -%]
|
||||
Loading…
Reference in new issue