Xp history
This commit is contained in:
+58
-1
@@ -1,6 +1,63 @@
|
|||||||
|
|
||||||
<div ng-controller="PlayerXpController" flex layout="column" id="PlayerXpController">
|
<div ng-controller="PlayerXpController" flex layout="column" id="PlayerXpController">
|
||||||
|
|
||||||
Show info about this player xp here
|
<md-content flex layout-padding>
|
||||||
|
|
||||||
|
<h2>Statistics for player <a href="#/player/{{userid}}/">{{userid}}</a></h2>
|
||||||
|
|
||||||
|
<div layout="row" layout-sm="column">
|
||||||
|
|
||||||
|
<div flex>
|
||||||
|
<md-card>
|
||||||
|
<md-card-title>
|
||||||
|
<md-card-title-text>
|
||||||
|
<span class="md-headline">Xp Income Sources</span>
|
||||||
|
<span class="md-subhead">Where has this user got their Xp from</span>
|
||||||
|
</md-card-title-text>
|
||||||
|
</md-card-title>
|
||||||
|
<md-card-content layout="row" layout-align="space-between">
|
||||||
|
<md-card-title-media flex>
|
||||||
|
<nvd3 flex options="Sources.Options" data="Sources.Data"></nvd3>
|
||||||
|
</md-card-title-media>
|
||||||
|
</md-card-content>
|
||||||
|
</md-card>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div flex>
|
||||||
|
<md-card>
|
||||||
|
<md-card-title>
|
||||||
|
<md-card-title-text>
|
||||||
|
<span class="md-headline">Xp Outgoing Sources</span>
|
||||||
|
<span class="md-subhead">Where has this user spent their Xp</span>
|
||||||
|
</md-card-title-text>
|
||||||
|
</md-card-title>
|
||||||
|
<md-card-content layout="row" layout-align="space-between">
|
||||||
|
<md-card-title-media flex>
|
||||||
|
<nvd3 flex options="Outgoings.Options" data="Outgoings.Data"></nvd3>
|
||||||
|
</md-card-title-media>
|
||||||
|
</md-card-content>
|
||||||
|
</md-card>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div flex>
|
||||||
|
<md-card>
|
||||||
|
<md-card-title>
|
||||||
|
<md-card-title-text>
|
||||||
|
<span class="md-headline">Xp Over Time</span>
|
||||||
|
<span class="md-subhead">How much XP has this user got over time</span>
|
||||||
|
</md-card-title-text>
|
||||||
|
</md-card-title>
|
||||||
|
<md-card-content layout="row" layout-align="space-between">
|
||||||
|
<md-card-title-media flex>
|
||||||
|
<nvd3 flex options="OverTime.Options" data="OverTime.Data"></nvd3>
|
||||||
|
</md-card-title-media>
|
||||||
|
</md-card-content>
|
||||||
|
</md-card>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</md-content>
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
@@ -1,9 +1,7 @@
|
|||||||
<div ng-controller="PlayerListController" flex layout="column" id="PlayerListController">
|
<div ng-controller="PlayerListController" flex layout="column" id="PlayerListController">
|
||||||
|
|
||||||
<md-content flex id="vertical-container">
|
<md-content flex id="vertical-container">
|
||||||
<md-list>
|
<md-list>
|
||||||
<div ng-repeat="line in Players | filter : FilterText">
|
<md-list-item class="" ng-repeat="line in Players | filter : FilterText" href="#/player/{{line.SteamID}}/">
|
||||||
<md-list-item class="md-3-line" layout="row" style="min-height: auto;">
|
|
||||||
<div flex layout="row">
|
<div flex layout="row">
|
||||||
<div flex class="md-list-item-text">
|
<div flex class="md-list-item-text">
|
||||||
<h3><a href="#/player/{{line.SteamID}}/">{{line.DisplayName}}</a></h3>
|
<h3><a href="#/player/{{line.SteamID}}/">{{line.DisplayName}}</a></h3>
|
||||||
@@ -23,7 +21,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div flex="10"style="text-align: right">
|
<div flex="10"style="text-align: right">
|
||||||
XP: {{line.UnspentXp}}
|
XP: <a href="#/player/{{line.SteamID}}/xp">{{line.UnspentXp}}</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div flex="20"style="text-align: right">
|
<div flex="20"style="text-align: right">
|
||||||
@@ -36,12 +34,8 @@
|
|||||||
{{line.ConnectedSeconds | SecondsToDuration}}
|
{{line.ConnectedSeconds | SecondsToDuration}}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
</md-list-item>
|
|
||||||
<md-divider></md-divider>
|
<md-divider></md-divider>
|
||||||
</div>
|
</md-list-item>
|
||||||
|
|
||||||
|
|
||||||
</md-list>
|
</md-list>
|
||||||
</md-content>
|
</md-content>
|
||||||
|
|
||||||
|
|||||||
+7
-3
@@ -13,10 +13,10 @@
|
|||||||
</head>
|
</head>
|
||||||
<body ng-cloak layout="row" ng-controller="RconController">
|
<body ng-cloak layout="row" ng-controller="RconController">
|
||||||
|
|
||||||
<div ng-include="'html/connect.html'" ng-show="!Connected" flex layout="row">
|
<div ng-include="'html/connect.html'" ng-show="!Connected" flex layout="row" ng-cloak>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<md-sidenav md-component-id="left" md-is-locked-open="$mdMedia('gt-sm')" class="md-whiteframe-6dp menu" ng-show="Connected">
|
<md-sidenav md-component-id="left" md-is-locked-open="$mdMedia('gt-sm')" class="md-whiteframe-6dp menu" ng-show="Connected" ng-cloak>
|
||||||
|
|
||||||
<md-list>
|
<md-list>
|
||||||
<md-list-item ng-repeat="p in pages | filter: { Nav: '' } ">
|
<md-list-item ng-repeat="p in pages | filter: { Nav: '' } ">
|
||||||
@@ -28,7 +28,7 @@
|
|||||||
|
|
||||||
</md-sidenav>
|
</md-sidenav>
|
||||||
|
|
||||||
<div layout="column" flex ng-show="Connected">
|
<div layout="column" flex ng-show="Connected" ng-cloak>
|
||||||
|
|
||||||
<md-toolbar layout="row">
|
<md-toolbar layout="row">
|
||||||
<div class="md-toolbar-tools">
|
<div class="md-toolbar-tools">
|
||||||
@@ -62,6 +62,10 @@
|
|||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/nvd3/1.8.2/nv.d3.min.js"></script>
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/nvd3/1.8.2/nv.d3.min.js"></script>
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-nvd3/1.0.5/angular-nvd3.min.js"></script>
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-nvd3/1.0.5/angular-nvd3.min.js"></script>
|
||||||
|
|
||||||
|
<!-- Data manipulation -->
|
||||||
|
<script src="js/linq.min.js"></script>
|
||||||
|
|
||||||
|
<!-- Our stuff -->
|
||||||
<script src="js/rconService.js"></script>
|
<script src="js/rconService.js"></script>
|
||||||
<script src="js/app.js"></script>
|
<script src="js/app.js"></script>
|
||||||
<script src="js/console.js"></script>
|
<script src="js/console.js"></script>
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
|
|
||||||
|
|
||||||
var app = angular.module( 'RconApp', ['ngMaterial', 'ngRoute'] );
|
var app = angular.module( 'RconApp', ['ngMaterial', 'ngRoute', 'nvd3'] );
|
||||||
|
|
||||||
app.service( 'rconService', [RconService] );
|
app.service( 'rconService', [RconService] );
|
||||||
|
|
||||||
@@ -30,8 +30,6 @@ function RconController( $scope, $rootScope, rconService, $mdSidenav, $timeout,
|
|||||||
return [value];
|
return [value];
|
||||||
} );
|
} );
|
||||||
|
|
||||||
console.log( $scope.pages );
|
|
||||||
|
|
||||||
$scope.OpenLeftMenu = function ()
|
$scope.OpenLeftMenu = function ()
|
||||||
{
|
{
|
||||||
$mdSidenav( 'left' ).toggle();
|
$mdSidenav( 'left' ).toggle();
|
||||||
@@ -89,8 +87,6 @@ function ConnectionController( $scope, rconService )
|
|||||||
if ( $scope.PreviousConnects == null )
|
if ( $scope.PreviousConnects == null )
|
||||||
$scope.PreviousConnects = new Array();
|
$scope.PreviousConnects = new Array();
|
||||||
|
|
||||||
console.log( $scope.PreviousConnects );
|
|
||||||
|
|
||||||
$scope.Connect = function ()
|
$scope.Connect = function ()
|
||||||
{
|
{
|
||||||
$scope.LastErrorMessage = null;
|
$scope.LastErrorMessage = null;
|
||||||
|
|||||||
Vendored
+10
File diff suppressed because one or more lines are too long
+142
@@ -1,7 +1,149 @@
|
|||||||
|
|
||||||
app.controller( 'PlayerXpController', PlayerXpController );
|
app.controller( 'PlayerXpController', PlayerXpController );
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function PlayerXpController( $scope, rconService, $routeParams )
|
function PlayerXpController( $scope, rconService, $routeParams )
|
||||||
{
|
{
|
||||||
$scope.userid = $routeParams.userid;
|
$scope.userid = $routeParams.userid;
|
||||||
|
|
||||||
|
$scope.Sources =
|
||||||
|
{
|
||||||
|
Options: {
|
||||||
|
chart: {
|
||||||
|
type: "pieChart",
|
||||||
|
height: 400,
|
||||||
|
x: function ( d ) { return d.key; },
|
||||||
|
y: function ( d ) { return d.value; },
|
||||||
|
showLabels : false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.Outgoings =
|
||||||
|
{
|
||||||
|
Options: {
|
||||||
|
chart: {
|
||||||
|
type: "pieChart",
|
||||||
|
height: 400,
|
||||||
|
x: function ( d ) { return d.key; },
|
||||||
|
y: function ( d ) { return d.value; },
|
||||||
|
showLabels: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.OverTime =
|
||||||
|
{
|
||||||
|
Options: {
|
||||||
|
chart: {
|
||||||
|
type: "multiBarChart",
|
||||||
|
height: 700,
|
||||||
|
stacked: true,
|
||||||
|
x: function ( d ) { return d[0]; },
|
||||||
|
y: function ( d ) { return Math.round( d[1] * 10 ) / 10; },
|
||||||
|
showLabels: false,
|
||||||
|
xAxis: { showMaxMin: false, tickFormat: function ( d ) { return d3.time.format( '%d %b %H%p' )( new Date( d ) ) } },
|
||||||
|
yAxis: { tickFormat: function ( d ) { return d3.format( ',.2f' )( d ); } },
|
||||||
|
clipEdge: true,
|
||||||
|
useInteractiveGuideline: true,
|
||||||
|
defined: function(d) { return d[0] != null }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$scope.Refresh = function ()
|
||||||
|
{
|
||||||
|
rconService.Request( "xp.history " + $scope.userid, $scope, function ( msg )
|
||||||
|
{
|
||||||
|
$scope.History = JSON.parse( msg.Message );
|
||||||
|
|
||||||
|
$scope.Sources.Data = Enumerable.From( $scope.History )
|
||||||
|
.Where( function ( x ) { return x.Amount > 0; } )
|
||||||
|
.GroupBy( "$.Type", null,
|
||||||
|
function ( key, g )
|
||||||
|
{
|
||||||
|
return {
|
||||||
|
key: key,
|
||||||
|
value: g.Sum( "$.Amount" )
|
||||||
|
}
|
||||||
|
} )
|
||||||
|
.ToArray();
|
||||||
|
|
||||||
|
$scope.Outgoings.Data = Enumerable.From( $scope.History )
|
||||||
|
.Where( function ( x ) { return x.Amount < 0; } )
|
||||||
|
.GroupBy( "$.Type", null,
|
||||||
|
function ( key, g )
|
||||||
|
{
|
||||||
|
return {
|
||||||
|
key: key,
|
||||||
|
value: -1 * g.Sum( "$.Amount" )
|
||||||
|
}
|
||||||
|
} )
|
||||||
|
.ToArray();
|
||||||
|
|
||||||
|
var Hour = 60 * 60;
|
||||||
|
|
||||||
|
$scope.OverTime.Data = FixMissingData( Enumerable.From( $scope.History )
|
||||||
|
.Where( function ( x ) { return x.Amount > 0; } )
|
||||||
|
.GroupBy( "$.Type", null,
|
||||||
|
function ( key, g )
|
||||||
|
{
|
||||||
|
return {
|
||||||
|
key: key,
|
||||||
|
values: g.GroupBy( function ( x ) { return Math.round( x.Date / Hour ) * Hour; }, null, function ( key, g )
|
||||||
|
{
|
||||||
|
return [key * 1000, g.Sum( "$.Amount" )];
|
||||||
|
} )
|
||||||
|
.ToArray()
|
||||||
|
}
|
||||||
|
} )
|
||||||
|
.ToArray(), Hour * 1000 );
|
||||||
|
|
||||||
|
console.log( $scope.OverTime.Data );
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
|
||||||
|
rconService.InstallService( $scope, $scope.Refresh )
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Fix missing gaps in a range
|
||||||
|
function FixMissingData( data, series )
|
||||||
|
{
|
||||||
|
// Get the range
|
||||||
|
var min = Enumerable.From( data ).Min( function ( x ) { return Enumerable.From( x.values ).Min( "$[0]" ); } )
|
||||||
|
var max = Enumerable.From( data ).Max( function ( x ) { return Enumerable.From( x.values ).Max( "$[0]" ); } )
|
||||||
|
|
||||||
|
// Fucking Javascript You Cunt
|
||||||
|
data.forEach( function ( d )
|
||||||
|
{
|
||||||
|
var expected = min;
|
||||||
|
var newData = [];
|
||||||
|
|
||||||
|
d.values.forEach( function ( d )
|
||||||
|
{
|
||||||
|
while ( d[0] != expected && expected <= max )
|
||||||
|
{
|
||||||
|
newData.push( [expected, 0.0] );
|
||||||
|
expected += series;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( d[0] == expected )
|
||||||
|
{
|
||||||
|
newData.push( d );
|
||||||
|
expected += series;
|
||||||
|
}
|
||||||
|
} );
|
||||||
|
|
||||||
|
while ( expected <= max )
|
||||||
|
{
|
||||||
|
newData.push( [expected, 0.0] );
|
||||||
|
expected += series;
|
||||||
|
}
|
||||||
|
|
||||||
|
d.values = newData;
|
||||||
|
} );
|
||||||
|
|
||||||
|
return data;
|
||||||
}
|
}
|
||||||
+8
-1
@@ -1,7 +1,7 @@
|
|||||||
|
|
||||||
app.controller( 'PlayerListController', PlayerListController );
|
app.controller( 'PlayerListController', PlayerListController );
|
||||||
|
|
||||||
function PlayerListController( $scope, rconService )
|
function PlayerListController( $scope, rconService, $interval )
|
||||||
{
|
{
|
||||||
$scope.Output = new Array();
|
$scope.Output = new Array();
|
||||||
|
|
||||||
@@ -14,4 +14,11 @@ function PlayerListController( $scope, rconService )
|
|||||||
}
|
}
|
||||||
|
|
||||||
rconService.InstallService( $scope, $scope.Refresh )
|
rconService.InstallService( $scope, $scope.Refresh )
|
||||||
|
|
||||||
|
var timer = $interval( function ()
|
||||||
|
{
|
||||||
|
//$scope.Refresh();
|
||||||
|
}.bind( this ), 1000 );
|
||||||
|
|
||||||
|
$scope.$on( '$destroy', function () { $interval.cancel( timer ) } )
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user