update system-info module

This commit is contained in:
exodus4d
2014-11-30 17:26:08 +01:00
parent 5fb35f85ad
commit 49073e5dd2
20 changed files with 748 additions and 384 deletions

View File

@@ -20,8 +20,6 @@
<div id="pf-dialog-wrapper"/>
<div id="test-container"/>
<script data-main="js/app" src="js/lib/require.js"></script>
</body>

View File

@@ -15,6 +15,8 @@ requirejs.config({
datatables: "lib/jquery.dataTables.min", // tables
datatablesBootstrap: "lib/dataTables.bootstrap", // not used (bootstrap style)
xEditable: "lib/bootstrap-editable.min", // in placed editing
morris: "lib/morris.min", // graphs
raphael: "lib/raphael-min", // required for morris (dependency)
bootbox: "lib/bootbox.min" // custom dialogs
},
shim: {
@@ -40,6 +42,10 @@ requirejs.config({
bootbox: {
deps: ['jquery', 'bootstrap'],
exports: 'bootbox'
},
morris: {
deps: ['jquery', 'raphael'],
exports: 'Morris'
}
}
});

View File

@@ -8,7 +8,10 @@ define(["jquery"], function($) {
var Config = {
// baseUrl: "http://localhost/exodus4d/pathfinder/" // TODO: change baseURL
url:{
zKillboard: 'https://zkillboard.com/api/',
eveCentral: 'http://api.eve-central.com/api/'
},
classes: {
// system effects
systemEffects: {
@@ -42,6 +45,7 @@ define(["jquery"], function($) {
name: 'black hole'
}
},
// system security
systemSecurity: {
security: {
class: 'pf-system-sec'
@@ -74,6 +78,7 @@ define(["jquery"], function($) {
class: 'pf-system-sec-low'
}
},
// true sec
trueSec: {
'0.0': {
class: 'pf-system-security-0-0'
@@ -108,7 +113,34 @@ define(["jquery"], function($) {
'1.0': {
class: 'pf-system-security-1-0'
}
}
},
// system status
systemStatus: {
unknown: {
class: 'pf-system-status-unknown',
label: 'unknown'
},
friendly: {
class: 'pf-system-status-friendly',
label: 'friendly'
},
occupied: {
class: 'pf-system-status-occupied',
label: 'occupied'
},
hostile: {
class: 'pf-system-status-hostile',
label: 'hostile'
},
empty: {
class: 'pf-system-status-empty',
label: 'empty'
},
unscanned: {
class: 'pf-system-status-unscanned',
label: 'unscanned'
}
}
}

View File

@@ -87,6 +87,27 @@ define(["jquery", "app/render", "app/ccp", "app/module_map"], function($, Render
x: 300,
y: 250
}
},{
id: 30000142,
name: 'Jita',
alias: '',
effect: '',
security: 'H',
trueSec: 0.9,
region: {
id: '10000002',
name: 'The Forge'
},
constellation: {
id: '20000020',
name: 'Kimotoro'
},
type: 'k-space',
status: '',
position: {
x: 400,
y: 150
}
}
],
connections: [
@@ -99,6 +120,11 @@ define(["jquery", "app/render", "app/ccp", "app/module_map"], function($, Render
source: 4,
target: 30002979,
type: 'wh'
},
{
source: 4,
target: 30000142,
type: 'wh'
}
]
}

View File

@@ -1,4 +1,12 @@
define(['jquery', 'app/init', 'app/util', 'app/render', 'jsPlumb', 'app/map/contextmenu'], function($, Init, Util, Render) {
define([
'jquery',
'app/init',
'app/util',
'app/render',
'bootbox',
'jsPlumb',
'app/map/contextmenu'
], function($, Init, Util, Render, bootbox) {
"use strict";
@@ -10,14 +18,15 @@ define(['jquery', 'app/init', 'app/util', 'app/render', 'jsPlumb', 'app/map/cont
x: 150,
y: 0
},
formEditableFieldClass: 'pf-editable', // Class for all xEditable fields
mapTabContentClass: 'pf-map-tab-content', // Tab-Content element (parent element)
mapWrapperClass: 'pf-map-wrapper', // wrapper div (scrollable)
mapClass: 'pf-map', // class for all maps
mapIdPrefix: 'pf-map-',
mapIdPrefix: 'pf-map-', // id prefix for all maps
systemIdPrefix: 'pf-system-', // id prefix for a system
systemClass: 'pf-system',
systemActiveClass: 'pf-system-active',
systemClass: 'pf-system', // class for all systems
systemActiveClass: 'pf-system-active', // class for an active system in a map
systemHeadClass: 'pf-system-head',
systemHeadNameClass: 'pf-system-head-name',
systemHeadExpandClass: 'pf-system-head-expand',
@@ -25,7 +34,7 @@ define(['jquery', 'app/init', 'app/util', 'app/render', 'jsPlumb', 'app/map/cont
systemBodyItemClass: 'pf-system-body-item',
systemBodyItemStatusClass: 'pf-user-status',
systemBodyRightClass: 'pf-system-body-right',
dynamicElementWrapperId: 'pf-dialog-wrapper', // wrapper div for dynamic content (dialoges, context-menus,...)
dynamicElementWrapperId: 'pf-dialog-wrapper', // wrapper div for dynamic content (dialogs, context-menus,...)
// endpoint classes
endpointSourceClass: 'pf-map-endpoint-source',
@@ -54,29 +63,7 @@ define(['jquery', 'app/init', 'app/util', 'app/render', 'jsPlumb', 'app/map/cont
systemSecWHMid: 'pf-system-sec-mid',
systemSecWHLow: 'pf-system-sec-low',
// system status
systemStatus: {
friendly: {
class: 'pf-system-status-friendly',
label: 'friendly'
},
occupied: {
class: 'pf-system-status-occupied',
label: 'occupied'
},
hostile: {
class: 'pf-system-status-hostile',
label: 'hostile'
},
empty: {
class: 'pf-system-status-empty',
label: 'empty'
},
unscanned: {
class: 'pf-system-status-unscanned',
label: 'unscanned'
}
},
// user status
userStatus: {
@@ -144,36 +131,7 @@ define(['jquery', 'app/init', 'app/util', 'app/render', 'jsPlumb', 'app/map/cont
// prevent multiple connections between same systems
var connections = checkForConnection(this.instance, info.source, info.target);
if(connections.length > 0){
// confirm dialog
var moduleConfig = {
name: 'modules/dialog',
position: $('#' + config.dynamicElementWrapperId),
link: 'after',
functions: {
after: function(){
$( "#" + config.errorConnectDialogId).dialog({
modal: true,
resizable: false,
buttons: {
'OK': function(){
$(this).dialog('close');
}
}
});
}
}
};
var moduleData = {
id: config.errorConnectDialogId,
titel: 'error: Loopback',
content: 'Connection already exists.'
};
Render.showModule(moduleConfig, moduleData);
bootbox.alert('Connection already exists.');
return false;
}
@@ -199,22 +157,6 @@ define(['jquery', 'app/init', 'app/util', 'app/render', 'jsPlumb', 'app/map/cont
}
};
/**
* get status class for a system
* @param status
* @returns {string}
*/
var getStatusClassForSystem = function(status){
var statusClass = '';
if(config.systemStatus[status]){
statusClass = config.systemStatus[status].class;
}
return statusClass;
};
/**
* get status class for a user
* @param status
@@ -350,7 +292,7 @@ define(['jquery', 'app/init', 'app/util', 'app/render', 'jsPlumb', 'app/map/cont
// get system info classes
var effectClass = Util.getEffectInfoForSystem(data.effect, 'class');
var secClass = Util.getSecurityClassForSystem(data.security);
var statusClass = getStatusClassForSystem(data.status);
var statusClass = Util.getStatusInfoForSystem(data.status, 'class');
system = $('<div>', {
// system
@@ -461,6 +403,25 @@ define(['jquery', 'app/init', 'app/util', 'app/render', 'jsPlumb', 'app/map/cont
};
/**
* checks if json system data is valid
* @param systemData
* @returns {boolean}
*/
var isValidSystem = function(systemData){
var isValid = true;
if(
! systemData.hasOwnProperty('name') ||
systemData.name.length === 0
){
return false;
}
return isValid;
};
/**
* draw a system with its data to a map
* @param map object
@@ -469,52 +430,55 @@ define(['jquery', 'app/init', 'app/util', 'app/render', 'jsPlumb', 'app/map/cont
*/
var drawSystem = function(map, systemData, connectedSystems){
var mapContainer = $(map.getContainer());
// check if systemData is valid
if(isValidSystem(systemData)){
var mapContainer = $(map.getContainer());
// TODO request missing system data
if(!systemData.hasOwnProperty('id')){
systemData.id = config.tempId++;
}
if(!systemData.hasOwnProperty('effect')){
systemData.effect = '';
}
if(!systemData.hasOwnProperty('security')){
systemData.security = 'H';
}
// TODO request missing system data
if(!systemData.hasOwnProperty('id')){
systemData.id = config.tempId++;
}
if(!systemData.hasOwnProperty('effect')){
systemData.effect = '';
}
if(!systemData.hasOwnProperty('security')){
systemData.security = 'H';
}
// get System Element by data
var newSystem = getSystem(map, systemData);
// get System Element by data
var newSystem = getSystem(map, systemData);
// add new system to map
mapContainer.append(newSystem);
// add new system to map
mapContainer.append(newSystem);
// make new system editable
makeEditable(newSystem);
// make new system editable
makeEditable(newSystem);
// make new system draggable
makeDraggable(map, newSystem);
// make new system draggable
makeDraggable(map, newSystem);
// make target
makeTarget(map, newSystem);
// make target
makeTarget(map, newSystem);
// make source
makeSource(map, newSystem);
// make source
makeSource(map, newSystem);
// set system observer
setSystemObserver(map, newSystem);
// set system observer
setSystemObserver(map, newSystem);
// connect new system (if connection data is given)
if(connectedSystems){
// connect new system (if connection data is given)
if(connectedSystems){
$.each(connectedSystems, function(i, connectSystem){
$.each(connectedSystems, function(i, connectSystem){
var connectionData = {
source: $(connectSystem).attr('data-id'),
target: $(newSystem).attr('data-id'),
type: 'wh'
};
drawConnection(map, connectionData);
});
var connectionData = {
source: $(connectSystem).attr('data-id'),
target: $(newSystem).attr('data-id'),
type: 'wh'
};
drawConnection(map, connectionData);
});
}
}
};
@@ -546,11 +510,21 @@ define(['jquery', 'app/init', 'app/util', 'app/render', 'jsPlumb', 'app/map/cont
*/
var makeEditable = function(system){
$(system).find('.' + config.systemHeadNameClass).editable({
var headElement = $(system).find('.' + config.systemHeadNameClass);
$(headElement).editable({
mode: 'popup',
type: 'text',
title: 'system name',
placement: 'top'
placement: 'top',
onblur: 'submit',
showbuttons: false
});
// update z-index for system, editable field should be on top
$(headElement).on('shown', function(e, editable) {
updateZIndex(system);
});
};
@@ -580,7 +554,7 @@ define(['jquery', 'app/init', 'app/util', 'app/render', 'jsPlumb', 'app/map/cont
var mapContainer = $( system.parent() );
// update z-index for dragged system + connections
updateZIndex(map, e.target);
updateZIndex(e.target);
// rerender tooltip
toggleSystemTooltip([e.target], 'show');
@@ -611,21 +585,10 @@ define(['jquery', 'app/init', 'app/util', 'app/render', 'jsPlumb', 'app/map/cont
/**
* update z-index for a system (dragged sytems should be always on top)
* @param map
* @param system
*/
var updateZIndex = function(map, system){
/* do not update connections for now
// get all connections
var connections = getConnections(map, [system]);
var updateZIndex = function(system){
// increase global z-Index counter
var newZIndexConnections = config.zIndexCounter++;
$.each(connections, function(i, connection){
// $(connection.canvas).css('z-index', newZIndexConnections);
})
*/
var newZIndexSystem = config.zIndexCounter++;
$(system).css('z-index', newZIndexSystem);
};
@@ -725,7 +688,6 @@ define(['jquery', 'app/init', 'app/util', 'app/render', 'jsPlumb', 'app/map/cont
{icon: 'fa-eraser', action: 'delete', text: 'delete'},
{icon: 'fa-info-circle', action: 'info', text: 'info'},
{divider: true},
// {icon: 'fa-bomb', action: 'eol', text: 'toggle EOL'},
{text: 'change status', subitems: [
{subIcon: 'fa-clock-o', subAction: 'eol', subText: 'toggle EOL'},
{subDivider: true},
@@ -746,6 +708,17 @@ define(['jquery', 'app/init', 'app/util', 'app/render', 'jsPlumb', 'app/map/cont
*/
var initSystemContextMenu = function(){
var systemStatus = [];
$.each(Init.classes.systemStatus, function(status, statusData){
var tempStatus = {
subIcon: 'fa-circle',
subIconClass: statusData.class,
subAction: 'change_status_' + status,
subText: statusData.label
};
systemStatus.push(tempStatus);
});
var moduleConfig = {
name: 'modules/contextmenu',
position: $('#' + config.dynamicElementWrapperId)
@@ -756,7 +729,9 @@ define(['jquery', 'app/init', 'app/util', 'app/render', 'jsPlumb', 'app/map/cont
items: [
{icon: 'fa-plus', action: 'add_system', text: 'add system'},
{icon: 'fa-eraser', action: 'delete_system', text: 'delete system'},
{icon: 'fa-info-circle', action: 'info', text: 'info'}
{icon: 'fa-info-circle', action: 'info', text: 'info'},
{divider: true},
{text: 'change status', subitems: systemStatus}
]
};
@@ -860,38 +835,30 @@ define(['jquery', 'app/init', 'app/util', 'app/render', 'jsPlumb', 'app/map/cont
case 'delete_system':
// confirm dialog
var moduleConfig = {
name: 'modules/dialog',
position: $('#' + config.dynamicElementWrapperId),
link: 'after',
functions: {
after: function(){
$( "#" + config.confirmDeleteSystemDialogId).dialog({
modal: true,
resizable: false,
buttons: {
'Cancel': function(){
$(this).dialog('close');
},
'Yes': function(){
// map.detach(params.component);
deleteSystem(map, currentSystem);
$(this).dialog('close');
}
}
});
}
bootbox.confirm('Delete system with all its connections?', function(result) {
if(result){
deleteSystem(map, currentSystem);
}
};
});
var moduleData = {
id: config.confirmDeleteSystemDialogId,
titel: 'Delete System',
content: 'Delete system with all its connections?'
};
break;
case 'change_status_unknown':
case 'change_status_friendly':
case 'change_status_occupied':
case 'change_status_hostile':
case 'change_status_empty':
case 'change_status_unscanned':
// remove all status classes from system
$.each(Init.classes.systemStatus, function(status, statusData){
currentSystem.removeClass( statusData.class );
});
Render.showModule(moduleConfig, moduleData);
// add new class
var statusString = action.split('_');
var statusClass = Util.getStatusInfoForSystem(statusString[2], 'class');
currentSystem.addClass( statusClass );
break;
case 'info': console.log('info')
break;
@@ -1019,38 +986,11 @@ define(['jquery', 'app/init', 'app/util', 'app/render', 'jsPlumb', 'app/map/cont
// delete a single connection
// confirm dialog
var moduleConfig = {
name: 'modules/dialog',
position: $('#' + config.dynamicElementWrapperId),
link: 'after',
functions: {
after: function(){
$( "#" + config.confirmDeleteConnectionDialogId).dialog({
modal: true,
resizable: false,
buttons: {
'Cancel': function(){
$(this).dialog('close');
},
'Yes': function(){
map.detach(params.component);
$(this).dialog('close');
}
}
});
}
bootbox.confirm('Is this connection really gone?', function(result) {
if(result){
map.detach(params.component);
}
};
var moduleData = {
id: config.confirmDeleteConnectionDialogId,
titel: 'Delete Connection',
content: 'Is this connection really gone?'
};
Render.showModule(moduleConfig, moduleData);
});
break;
case 'eol':
// toggle eol-status of a connection
@@ -1108,20 +1048,41 @@ define(['jquery', 'app/init', 'app/util', 'app/render', 'jsPlumb', 'app/map/cont
*/
var showNewSystemDialog = function(map, options){
var moduleConfig = {
name: 'modules/system_dialog',
position: $('#' + config.dynamicElementWrapperId),
link: 'after',
functions: {
after: function(){
$( "#" + config.systemDialogId).dialog({
modal: true,
resizable: false,
buttons: {
'Cancel': function(){
$(this).dialog('close');
},
'Add system': function(e){
// format system status for form select
var systemStatus = {};
$.each(Init.classes.systemStatus, function(status, statusData){
//statusData.status = status;
//systemStatus.push(statusData);
systemStatus[status] = statusData.label;
});
var data = {
id: config.systemDialogId,
system: 'lalala',
status: systemStatus
};
requirejs(['text!templates/modules/system_dialog.html', 'lib/mustache'], function(template, Mustache) {
var content = Mustache.render(template, data);
var test = bootbox.dialog({
title: 'Add new system',
message: content,
buttons: {
close: {
label: 'cancel',
className: 'btn-default',
callback: function(){
$(test).modal('hide');
}
},
success: {
label: 'Add system',
className: 'btn-primary',
callback: function () {
// get form Values
var form = $('#' + config.systemDialogId).find('form');
@@ -1132,6 +1093,11 @@ define(['jquery', 'app/init', 'app/util', 'app/render', 'jsPlumb', 'app/map/cont
newSystemData[field.name] = field.value;
});
// add editable fields
var editableValues = $('#' + config.systemDialogId).find('.' + config.formEditableFieldClass).editable('getValue');
newSystemData = $.extend(newSystemData, editableValues);
var currentX = 0;
var currentY = 0;
@@ -1175,28 +1141,28 @@ define(['jquery', 'app/init', 'app/util', 'app/render', 'jsPlumb', 'app/map/cont
// draw new system to map
drawSystem(map, newSystemData, sourceSystem);
$(this).dialog('close');
}
}
});
}
}
};
// format system status for form select
var systemStatus = [];
$.each(config.systemStatus, function(status, statusData){
statusData.status = status;
systemStatus.push(statusData);
}
}
);
// make editable
var modalFields = $('.bootbox .modal-dialog').find('.pf-editable-system-status');
modalFields.editable({
mode: 'inline',
emptytext: 'unknown',
onblur: 'submit',
source: systemStatus
});
});
var moduleData = {
id: config.systemDialogId,
titel: 'Add new system',
status: systemStatus
};
Render.showModule(moduleConfig, moduleData);
};

View File

@@ -1,4 +1,16 @@
define(['jquery', 'app/util', 'app/render', 'bootbox', 'datatables', 'xEditable', 'app/map/map', 'customScrollbar', 'app/counter'], function($, Util, Render, bootbox) {
define([
'jquery',
'app/init',
'app/util',
'app/render',
'bootbox',
'morris',
'datatables',
'xEditable',
'app/map/map',
'customScrollbar',
'app/counter'
], function($, Config, Util, Render, bootbox, Morris) {
"use strict";
@@ -25,6 +37,8 @@ define(['jquery', 'app/util', 'app/render', 'bootbox', 'datatables', 'xEditable'
// system info module
systemInfoModuleClass: 'pf-system-info-module', // module wrapper
systemInfoRoutesClass: 'pf-system-info-routes', // wrapper for trade hub routes
systemInfoGraphsClass: 'pf-system-info-graphs', // wrapper for graphs
systemInfoTableClass: 'pf-system-info-table', // class for system info table
systemInfoRoutesTableClass: 'pf-system-route-table', // class for route tables
systemInfoRoutesTableRowPrefix: 'pf-system-info-routes-row-', // prefix class for a row in the route table
systemSecurityClassPrefix: 'pf-system-security-', // prefix class for system security level (color)
@@ -169,6 +183,11 @@ define(['jquery', 'app/util', 'app/render', 'bootbox', 'datatables', 'xEditable'
};
var cache = {
systemRoutes: {}, // jump information between solar systems
systemKillsGraphData: {} // data for system kills info graph
};
/**
* get map type class for a type
* @param type
@@ -619,6 +638,25 @@ define(['jquery', 'app/util', 'app/render', 'bootbox', 'datatables', 'xEditable'
},
type: 'k-space'
};
}else if(systemInfoData.systemId === 30000142){
var system = {
id: 30000142,
//name: 'J150020',
name: 'Jita',
alias: '',
effect: '',
security: 'H',
trueSec: 0.9,
region: {
id: '10000002',
name: 'The Forge'
},
constellation: {
id: '20000020',
name: 'Kimotoro'
},
type: 'k-space'
};
}else{
var system = {
id: 2,
@@ -671,6 +709,9 @@ define(['jquery', 'app/util', 'app/render', 'bootbox', 'datatables', 'xEditable'
$(moduleElement).find('.' + config.systemInfoRoutesClass).updateSystemInfoRoutes(system.name, ['Jita', 'Amarr', 'Rens', 'Dodixie']);
}
// load kill statistic chart
$(moduleElement).find('.' + config.systemInfoGraphsClass).updateSystemInfoGraphs(system.id);
}
}
@@ -686,7 +727,8 @@ define(['jquery', 'app/util', 'app/render', 'bootbox', 'datatables', 'xEditable'
var moduleData = {
system: system,
system: system,
tableClass: config.systemInfoTableClass,
securityClass: Util.getSecurityClassForSystem( system.security ),
trueSecClass: Util.getTrueSecClassForSystem( system.trueSec ),
effectName: Util.getEffectInfoForSystem(system.effect, 'name'),
@@ -697,25 +739,160 @@ define(['jquery', 'app/util', 'app/render', 'bootbox', 'datatables', 'xEditable'
};
$.fn.updateSystemInfoGraphs = function(systemId){
var parentElement = $(this);
parentElement.empty();
var graphElement = $('<div>');
parentElement.append(graphElement);
var showHours = 24;
var maxKillmailCount = 200; // limited by API
// private function draws a "system kills" graph
var drawGraph = function(data){
// draw chart
Morris.Bar({
element: graphElement,
resize: true,
gridTextSize: 10,
gridTextColor: '#3c3f41',
gridTextFamily: 'Oxygen Bold',
hideHover: true,
data: data,
xkey: 'label',
ykeys: ['kills'],
labels: ['kills'],
xLabelMargin: 10,
padding: 10,
parseTime: false,
barColors: function (row, series, type) {
if (type === 'bar') {
// hightlite last row -> recent kills found
if(this.xmax === row.x){
return '#c2760c';
}
}
return '#63676a';
}
});
};
// get recent KB stats (last 24h))
var localDate = new Date();
// cache result for 5min
var cacheKey = systemId + '_' + localDate.getHours() + '_' + ( Math.ceil( localDate.getMinutes() / 5 ) * 5);
if(cache.systemKillsGraphData.hasOwnProperty(cacheKey) ){
drawGraph( cache.systemKillsGraphData[cacheKey] );
}else{
// chart data
var chartData = [];
for(var i = 0; i < showHours; i++){
var tempData = {
label: i + 'h',
kills: 0
};
chartData.push(tempData);
}
var serverDate= new Date(
localDate.getUTCFullYear(),
localDate.getUTCMonth(),
localDate.getUTCDate(),
localDate.getUTCHours(),
localDate.getUTCMinutes(),
localDate.getUTCSeconds()
);
// get all kills until current server time
var dateStringEnd = String( serverDate.getFullYear() );
dateStringEnd += String( ('0' + (serverDate.getMonth() + 1)).slice(-2) );
dateStringEnd += String( ('0' + serverDate.getDate()).slice(-2) );
dateStringEnd += String( ('0' + serverDate.getHours()).slice(-2) );
dateStringEnd += String( ('0' + serverDate.getMinutes()).slice(-2) );
// get start Date for kills API request (last 24h)
var startDate = new Date( serverDate.getTime() );
startDate.setDate( startDate.getDate() - 1);
var dateStringStart = String( startDate.getFullYear() );
dateStringStart += String( ('0' + (startDate.getMonth() + 1)).slice(-2) );
dateStringStart += String( ('0' + startDate.getDate()).slice(-2) );
dateStringStart += String( ('0' + startDate.getHours()).slice(-2) );
dateStringStart += String( ('0' + startDate.getMinutes()).slice(-2) );
var url = Config.url.zKillboard;
url += '/no-items/no-attackers/solarSystemID/' + systemId + '/startTime/' + dateStringStart + '/endTime/' + dateStringEnd + '/';
graphElement.showLoadingAnimation();
$.getJSON(url, function(kbData){
// the API wont return more than 200KMs ! - remember last bar block with complete KM information
var lastCompleteDiffHourData = 0;
// loop kills and count kills by hour
for(var i = 0; i < kbData.length; i++){
var match = kbData[i].killTime.match(/^(\d+)-(\d+)-(\d+) (\d+)\:(\d+)\:(\d+)$/);
var killDate = new Date(match[1], match[2] - 1, match[3], match[4], match[5], match[6]);
// get time diff
var timeDiffMin = Math.round( ( serverDate - killDate ) / 1000 / 60 );
var timeDiffHour = Math.round( timeDiffMin / 60 );
// update chart data
chartData[timeDiffHour].kills++;
if(timeDiffHour > lastCompleteDiffHourData){
lastCompleteDiffHourData = timeDiffHour;
}
}
// remove empty chart Data
if(kbData.length >= maxKillmailCount){
chartData = chartData.splice(0, lastCompleteDiffHourData + 1);
}
// change order
chartData.reverse();
cache.systemKillsGraphData[cacheKey] = chartData;
drawGraph( cache.systemKillsGraphData[cacheKey] );
parentElement.hideLoadingAnimation();
});
}
};
$.fn.updateSystemInfoRoutes = function(systemFrom, systemsTo){
// TODO get cached routes from backend
var baseUrl = 'http://api.eve-central.com/api/route/from/';
var wrapperElement = $(this);
var parentElement = $(this);
// crate new route table
var table = $('<table>', {
class: ['compact', 'stripe', 'order-column', 'row-border', config.systemInfoRoutesTableClass].join(' ')
});
wrapperElement.append( $(table) );
parentElement.append( $(table) );
// init empty table
var routesTable = table.DataTable( {
paging: false,
ordering: true,
order: [ 1, 'asc' ],
info: false,
searching: false,
hover: false,
@@ -742,53 +919,67 @@ define(['jquery', 'app/util', 'app/render', 'bootbox', 'datatables', 'xEditable'
data: [] // will be added dynamic
} );
$.each(systemsTo, function(i, systemTo){
if(systemFrom !== systemTo){
var url = baseUrl + systemFrom + '/to/' + systemTo;
$.getJSON(url, function(routeData){
// row class
var rowClass = config.systemInfoRoutesTableRowPrefix + i;
var cacheKey = systemFrom + '_' + systemTo;
// add row Data
var rowData = [systemTo, routeData.length];
// row class
var rowClass = config.systemInfoRoutesTableRowPrefix + i;
var jumpData = [];
// loop all systems on a rout
$.each(routeData, function(j, systemData){
if(cache.systemRoutes.hasOwnProperty(cacheKey)){
// add new row from cache
routesTable.row.add( cache.systemRoutes[cacheKey] ).draw().nodes().to$().addClass( rowClass );
var systemSecClass = config.systemSecurityClassPrefix;
var systemSec = systemData.to.security.toFixed(1).toString();
systemSecClass += systemSec.replace('.', '-');
var system = '<i class="fa fa-square ' + systemSecClass + '" ';
system += 'data-toggle="tooltip" data-placement="bottom" ';
system += 'title="' + systemData.to.name + ' - ' + systemSec + ' [' + systemData.to.region.name + ']"></i>';
jumpData.push( system );
// init tooltips for each jump system
var tooltipElements = parentElement.find('.' + rowClass + ' [data-toggle="tooltip"]');
$(tooltipElements).tooltip();
}else{
// get route from API
var baseUrl = Config.url.eveCentral + 'route/from/';
var url = baseUrl + systemFrom + '/to/' + systemTo;
$.getJSON(url, function(routeData){
// add row Data
var rowData = [systemTo, routeData.length];
var jumpData = [];
// loop all systems on a rout
$.each(routeData, function(j, systemData){
var systemSecClass = config.systemSecurityClassPrefix;
var systemSec = systemData.to.security.toFixed(1).toString();
systemSecClass += systemSec.replace('.', '-');
var system = '<i class="fa fa-square ' + systemSecClass + '" ';
system += 'data-toggle="tooltip" data-placement="bottom" ';
system += 'title="' + systemData.to.name + ' - ' + systemSec + ' [' + systemData.to.region.name + ']"></i>';
jumpData.push( system );
});
rowData.push( jumpData.join(' ') );
cache.systemRoutes[cacheKey] = rowData;
// add new row
routesTable.row.add( cache.systemRoutes[cacheKey] ).draw().nodes().to$().addClass( rowClass );
// init tooltips for each jump system
var tooltipElements = parentElement.find('.' + rowClass + ' [data-toggle="tooltip"]');
$(tooltipElements).tooltip();
});
}
rowData.push( jumpData.join(' ') );
// add new row
routesTable.row.add( rowData ).draw().nodes().to$().addClass( rowClass );
// init tooltips for each jump system
var tooltipElements = wrapperElement.find('.' + rowClass + ' [data-toggle="tooltip"]');
$(tooltipElements).tooltip();
});
}
});
};

View File

@@ -2,7 +2,7 @@
* Render controller
*/
define(["jquery", "lib/mustache", "jqueryUI"], function($, Mustache) {
define(['jquery', 'lib/mustache', 'jqueryUI'], function($, Mustache) {
"use strict";

View File

@@ -5,21 +5,64 @@ define(['jquery', 'app/init'], function($, Init) {
"use strict";
var config = {
ajaxOverlayClass: 'pf-loading-overlay',
ajaxOverlayWrapperClass: 'pf-loading-overlay-wrapper',
ajaxOverlayVisibleClass: 'pf-loading-overlay-visible'
};
/**
* get a info for a given effect string
* displays a loading indicator on an element
*/
$.fn.showLoadingAnimation = function(){
var overlay = $('<div>', {
class: config.ajaxOverlayClass
}).append(
$('<div>', {
class: [config.ajaxOverlayWrapperClass].join(' ')
}).append(
$('<i>', {
class: ['fa', 'fa-lg', 'fa-circle-o-notch', 'fa-spin'].join(' ')
})
)
);
$(this).append(overlay);
// fade in
setTimeout(function(){
$(overlay).addClass( config.ajaxOverlayVisibleClass );
}, 10);
};
$.fn.hideLoadingAnimation = function(){
var overlay = $(this).find('.' + config.ajaxOverlayClass );
$(overlay).removeClass( config.ajaxOverlayVisibleClass );
// remove overlay after fade out transition
setTimeout(function(){
$(overlay).remove();
}, 150);
};
/**
* get some info for a given effect string
* @param effect
* @param option
* @returns {string}
*/
var getEffectInfoForSystem = function(effect, option){
var effectClass = '';
var effectInfo = '';
if( Init.classes.systemEffects.hasOwnProperty(effect) ){
effectClass = Init.classes.systemEffects[effect][option];
effectInfo = Init.classes.systemEffects[effect][option];
}
return effectClass;
return effectInfo;
};
/**
@@ -58,9 +101,27 @@ define(['jquery', 'app/init'], function($, Init) {
return trueSecClass;
};
/**
* get status info
* @param status
* @param option
* @returns {string}
*/
var getStatusInfoForSystem = function(status, option){
var statusInfo = '';
if( Init.classes.systemStatus.hasOwnProperty(status) ){
statusInfo = Init.classes.systemStatus[status][option];
}
return statusInfo;
};
return {
getEffectInfoForSystem: getEffectInfoForSystem,
getSecurityClassForSystem: getSecurityClassForSystem,
getTrueSecClassForSystem: getTrueSecClassForSystem
getTrueSecClassForSystem: getTrueSecClassForSystem,
getStatusInfoForSystem: getStatusInfoForSystem
};
});

7
js/lib/morris.min.js vendored Normal file

File diff suppressed because one or more lines are too long

11
js/lib/raphael-min.js vendored Normal file

File diff suppressed because one or more lines are too long

113
node_modules/.bin/build.js generated vendored
View File

@@ -33,39 +33,50 @@
}
],
"paths": {
"layout": "layout",
"jquery": "lib/jquery-1.11.1.min",
//"jquery": "lib/jquery-2.1.1.min",
//"jqueryUI": "lib/jquery-ui.min",
"jqueryUI": "lib/jquery-ui-custom.min", // custom script (without tooltip -> conflict with bootstrap)
"bootstrap": "lib/bootstrap.min",
"text": "lib/requirejs/text",
"templates": "../templates",
"jsPlumb": "lib/jsPlumb-1.6.4-min",
"customScrollbar": "lib/jquery.mCustomScrollbar.concat.min",
"datatables": "lib/jquery.dataTables.min",
"datatablesBootstrap": "lib/dataTables.bootstrap", // not used (bootstrap style)
"xEditable": "lib/bootstrap-editable.min"
layout: "layout",
jquery: "lib/jquery-1.11.1.min",
//jquery: "lib/jquery-2.1.1.min",
//jqueryUI: "lib/jquery-ui.min",
jqueryUI: "lib/jquery-ui-custom.min", // custom script (without tooltip -> conflict with bootstrap)
bootstrap: "lib/bootstrap.min",
text: "lib/requirejs/text",
templates: "../templates",
jsPlumb: "lib/jsPlumb-1.6.4-min", // main map draw plugin
customScrollbar: "lib/jquery.mCustomScrollbar.concat.min", // custom scroll bars
datatables: "lib/jquery.dataTables.min", // tables
datatablesBootstrap: "lib/dataTables.bootstrap", // not used (bootstrap style)
xEditable: "lib/bootstrap-editable.min", // in placed editing
morris: "lib/morris.min", // graphs
raphael: "lib/raphael-min", // required for morris (dependency)
bootbox: "lib/bootbox.min" // custom dialogs
},
shim: {
"jqueryUI": {
export:"$",
deps: ["jquery"]
jqueryUI: {
export: '$',
deps: ['jquery']
},
"bootstrap": {
deps: ["jquery", "jqueryUI"]
bootstrap: {
deps: ['jquery', 'jqueryUI']
},
"customScrollbar": {
deps: ["jquery"]
customScrollbar: {
deps: ['jquery']
},
"datatables": {
deps: ["jquery"]
datatables: {
deps: ['jquery']
},
"datatablesBootstrap": {
deps: ["datatables"]
datatablesBootstrap: {
deps: ['datatables']
},
"xEditable": {
deps: ["bootstrap"]
xEditable: {
deps: ['bootstrap']
},
bootbox: {
deps: ['jquery', 'bootstrap'],
exports: 'bootbox'
},
morris: {
deps: ['jquery', 'raphael'],
exports: 'Morris'
}
},
@@ -80,31 +91,41 @@
//- "closure.keepLines": Same as closure option, but keeps line returns
//in the minified files.
//- "none": no minification will be done.
optimize: "uglify",
optimize: "uglify2",
//If using UglifyJS for script optimization, these config options can be
//used to pass configuration values to UglifyJS.
//See https://github.com/mishoo/UglifyJS for the possible values.
uglify: {
toplevel: true,
ascii_only: true,
beautify: true,
max_line_length: 1000,
//How to pass uglifyjs defined symbols for AST symbol replacement,
//see "defines" options for ast_mangle in the uglifys docs.
defines: {
DEBUG: ['name', 'false']
//If using UglifyJS2 for script optimization, these config options can be
//used to pass configuration values to UglifyJS2.
//For possible `output` values see:
//https://github.com/mishoo/UglifyJS2#beautifier-options
//For possible `compress` values see:
//https://github.com/mishoo/UglifyJS2#compressor-options
uglify2: {
//Example of a specialized config. If you are fine
//with the default options, no need to specify
//any of these properties.
output: {
beautify: false,
comments: false
},
//Custom value supported by r.js but done differently
//in uglifyjs directly:
//Skip the processor.ast_mangle() part of the uglify call (r.js 2.0.5+)
no_mangle: true
compress: {
sequences: false,
drop_console: true,
global_defs: {
DEBUG: false
}
},
warnings: true,
mangle: true
},
//The directory path to save the output. If not specified, then
//the path will default to be a directory called "build" as a sibling
//to the build file. All relative paths are relative to the build file.
dir: "../../build_js"
dir: "../../build_js",
//Inlines the text for any text! dependencies, to avoid the separate
//async XMLHttpRequest calls to load those dependencies.
inlineText: false
})

View File

@@ -170,11 +170,11 @@ $btn-link-disabled-color: $gray-light;
//
//##
$input-bg: #fff;
$input-bg: $gray-dark;
$input-bg-disabled: $gray-lighter;
$input-color: $gray;
$input-border: #ccc;
$input-color: $gray-lighter;
$input-border: $gray-light;
$input-border-radius: 0px;
$input-border-focus: $teal;
@@ -270,7 +270,7 @@ $screen-md-max: ($screen-lg-min - 1);
//** Number of columns in the grid.
$grid-columns: 12;
//** Padding between columns. Gets divided in half for the left and right.
$grid-gutter-width: 26px;
$grid-gutter-width: 20px;
// Navbar collapse
//** Point at which the navbar becomes uncollapsed.
$grid-float-breakpoint: $screen-sm-min;

View File

@@ -13,15 +13,47 @@ a{
}
}
// ajax laoding indicator overlay
.pf-loading-overlay{
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
opacity: 0;
background: $gray-darker;
@include transition(opacity, 0.15s linear);
@include border-radius(5px);
.pf-loading-overlay-wrapper{
width: 20px;
height: 20px;
margin: auto;
text-align: center;
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
}
}
.pf-loading-overlay-visible{
opacity: 0.5;
}
// Maps module ===================================================
#pf-map-module{
margin: 30px 0 0 0;
padding: 10px;
// background: rgba($gray, 0.3); // semi transparent
// Tabs (colored)
#pf-map-tabs {
margin: 0 10px;
.pf-map-type-default{
border-top: 2px solid transparent;
}
@@ -39,6 +71,10 @@ a{
}
}
.tab-content{
width: calc(100% - 20px);
}
}
// Tab Content Body Grid ========================================
@@ -66,6 +102,7 @@ a{
.pf-system-effect{
margin-left: 5px;
cursor: default;
color: $gray-lighter;
}
.pf-system-effect-magnetar{
@@ -168,6 +205,33 @@ a{
color: $blue;
}
// system status ======================================================
.pf-system-status-friendly{
border-color: $blue !important;
color: $blue;
}
.pf-system-status-occupied{
border-color: $orange !important;
color: $orange;
}
.pf-system-status-hostile{
border-color: $red !important;
color: $red;
}
.pf-system-status-empty{
border-color: $green !important;
color: $green;
}
.pf-system-status-unscanned{
border-color: $teal !important;
color: $teal;
}
// Tooltip ======================================================
.tooltip-inner{
opacity: 1;

View File

@@ -35,6 +35,7 @@
height: 530px;
overflow: auto;
padding: 5px;
margin: 0 10px;
background: rgba($gray-darker, 0.95);
box-shadow:inset -1px 1px 6px 0 rgba($black, 0.8);
@@ -75,11 +76,14 @@
.pf-system-head-name{
border: none;
display: inline-block;
min-width: 41px;
color: $gray-lighter;
}
.pf-system-head-expand{
margin-left: 5px;
color: $gray-lighter;
display: none; // triggered by JS
}
}
@@ -138,28 +142,6 @@
@include box-shadow($yellow-lighter 0px 0px 8px 0px);
}
// system status ======================================================
.pf-system-status-friendly{
border-color: $blue;
}
.pf-system-status-occupied{
border-color: $orange;
}
.pf-system-status-hostile{
border-color: $red;
}
.pf-system-status-empty{
border-color: $green;
}
.pf-system-status-unscanned{
border-color: $teal;
}
// Endpoints ====================================================
.pf-map-endpoint-source, .pf-map-endpoint-target{

View File

@@ -5,6 +5,19 @@
}
}
// system info table =====================================================
.pf-system-info-table{
padding-right: 7px;
}
// system info killboard graph ===========================================
.pf-system-info-graphs > div{
width: 100%;
height: 130px;
padding: 10px 0;
position: relative;
}
// routes table ==========================================================
.pf-system-route-table{
font-size: 10px;
@@ -12,7 +25,6 @@
// signature table =======================================================
// signature table
.pf-sig-table{
font-size: 10px;
}

View File

@@ -10,7 +10,7 @@ body {
padding: 0;
min-height: 100%;
background:url("#{$base-url}/#{$body-background-image}") $body-background-color;
background-repeat: no-repeat;
background-repeat: no-repeat;
direction:ltr;
}
@@ -3028,21 +3028,22 @@ img.away {
*/
.morris-hover.morris-default-style {
border-radius: 10px;
padding: 6px;
border-radius: 5px;
padding: 5px;
color: #666;
background: rgba(red($white), green($white), blue($white), 0.8);
border: solid 2px rgba(230, 230, 230, 0.8);
font-family: sans-serif;
font-size: 12px;
text-align: center;
background: rgba(red( $gray-darkest), green($gray-darkest), blue($gray-darkest), 0.9);
border: solid 2px $teal-darker;
font-family: 'Oxygen Bold';
font-size: 10px;
text-align: left;
.morris-hover-row-label {
font-weight: bold;
margin: 0.25em 0;
// margin: 0.25em 0;
}
.morris-hover-point {
white-space: nowrap;
margin: 0.1em 0;
// margin: 0.1em 0;
}
}
.morris-hover {

View File

@@ -1,11 +0,0 @@
<div class="dropdown">
<button class="btn btn-default dropdown-toggle" type="button" id="dropdownMenu1" data-toggle="dropdown">
Dropdown
<span class="caret"></span>
</button>
<ul class="dropdown-menu" role="menu" aria-labelledby="dropdownMenu1">
{{#options}}
<li role="presentation"><a role="menuitem" tabindex="-1" href="#">{{text}}</a></li>
{{/options}}
</ul>
</div>

View File

@@ -7,7 +7,7 @@
{{#subitems}}
{{#subText}}
<li>
<a href="#" tabindex="-1" data-action="{{subAction}}"><i class="fa {{#subIcon}}{{subIcon}}{{/subIcon}}"></i>{{subText}}</a>
<a href="#" tabindex="-1" data-action="{{subAction}}"><i class="fa {{#subIcon}}{{subIcon}}{{/subIcon}} {{#subIconClass}}{{subIconClass}}{{/subIconClass}}"></i>{{subText}}</a>
</li>
{{/subText}}

View File

@@ -1,21 +1,19 @@
<div id="{{id}}" title="{{titel}}">
<form>
<fieldset>
<div>
<label for="system">System</label>
<input type="text" name="name" id="system" value="{{system}}">
<div class="row" id="{{id}}">
<div class="col-sm-12">
<form role="form">
<div class="form-group">
<label class="col-sm-2 control-label" for="form_system">System</label>
<div class="col-sm-10">
<input id="form_system" name="name" type="text" placeholder="System name" class="form-control input-md">
<span class="help-block">Enter system name</span>
</div>
</div>
<div>
<label for="status">Status</label>
<select name="status" id="status" class="text ui-widget-content ui-corner-all">
{{#status}}
<option value="{{status}}">{{label}}</option>
{{/status}}
</select>
<div class="form-group">
<label class="col-sm-2 control-label" for="form_status">Status</label>
<div class="col-sm-10">
<a class="pf-editable pf-editable-system-status" href="#" id="form_status" data-type="select" data-name="status"></a>
</div>
</div>
<!-- Allow form submission with keyboard without duplicating the dialog button -->
<input type="submit" tabindex="-1" style="position:absolute; top:-1000px">
</fieldset>
</form>
</form>
</div>
</div>

View File

@@ -14,14 +14,11 @@
</li>
</ol>
<div class="pf-system-info-routes"></div>
</div>
<div class="col-xs-12 col-sm-5">
<table class="table table-condensed">
<table class="table table-condensed {{tableClass}}">
<tbody>
<tr>
<td>Name</td>
@@ -53,6 +50,8 @@
</tr>
</tbody>
</table>
<div class="pf-system-info-graphs"></div>
</div>
</div>