map info module improvements, new system graph module, map info module refactoring, new CCP API Cronjob (jumps, kills,...)

This commit is contained in:
exodus4d
2015-03-15 20:55:56 +01:00
parent 417961cd1e
commit 5136038bc9
51 changed files with 3158 additions and 1031 deletions

View File

@@ -14,4 +14,10 @@ RewriteCond %{REQUEST_FILENAME} !-l
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule .* index.php [L,QSA]
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization},L]
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization},L]
# PHP global Vars
php_value max_input_vars 5000
php_value suhosin.get.max_vars 5000
php_value suhosin.post.max_vars 5000
php_value suhosin.request.max_vars 5000

102
.idea/dataSources.ids generated
View File

@@ -3573,6 +3573,25 @@
<column name="password_expired" sqlType="ENUM" length="2" precision="0" nullable="false" jdbcType="1" def="J04n"/>
<primary-key name="PRIMARY" columns="Host,User"/>
</table>
<table name="connection" schema="" catalog="pathfinder" type="TABLE">
<column name="id" sqlType="INT" length="10" precision="0" nullable="false" jdbcType="4" autoIncrement="true"/>
<column name="created" sqlType="TIMESTAMP" length="19" precision="0" nullable="false" jdbcType="93" def="Q1VSUkVOVF9USU1FU1RBTVA="/>
<column name="updated" sqlType="TIMESTAMP" length="19" precision="0" nullable="false" jdbcType="93" def="Q1VSUkVOVF9USU1FU1RBTVA=" version="true"/>
<column name="active" sqlType="TINYINT" length="3" precision="0" nullable="false" jdbcType="-6" def="MQ=="/>
<column name="mapId" sqlType="INT" length="10" precision="0" nullable="false" jdbcType="4"/>
<column name="source" sqlType="INT" length="10" precision="0" nullable="false" jdbcType="4"/>
<column name="target" sqlType="INT" length="10" precision="0" nullable="false" jdbcType="4"/>
<column name="scope" sqlType="VARCHAR" length="255" precision="0" nullable="false" jdbcType="12"/>
<column name="type" sqlType="VARCHAR" length="255" precision="0" nullable="false" jdbcType="12"/>
<primary-key name="PRIMARY" columns="id"/>
<foreign-key name="connection_ibfk_1" columns="mapId" ref-table="map" ref-schema="" ref-catalog="pathfinder" ref-columns="id" update-rule="0" delete-rule="0" deferrability="2"/>
<foreign-key name="connection_ibfk_2" columns="source" ref-table="system" ref-schema="" ref-catalog="pathfinder" ref-columns="id" update-rule="0" delete-rule="0" deferrability="2"/>
<foreign-key name="connection_ibfk_3" columns="target" ref-table="system" ref-schema="" ref-catalog="pathfinder" ref-columns="id" update-rule="0" delete-rule="0" deferrability="2"/>
<index name="active" unique="false" columns="active"/>
<index name="created" unique="false" columns="created"/>
<index name="source" unique="false" columns="target,scope"/>
<index name="updated" unique="false" columns="updated"/>
</table>
<table name="connection_scope" schema="" catalog="pathfinder" type="TABLE">
<column name="id" sqlType="INT" length="10" precision="0" nullable="false" jdbcType="4" autoIncrement="true"/>
<column name="created" sqlType="TIMESTAMP" length="19" precision="0" nullable="false" jdbcType="93" def="Q1VSUkVOVF9USU1FU1RBTVA="/>
@@ -3590,11 +3609,16 @@
<column name="created" sqlType="DATETIME" length="19" precision="0" nullable="false" jdbcType="93" def="Q1VSUkVOVF9USU1FU1RBTVA="/>
<column name="updated" sqlType="TIMESTAMP" length="19" precision="0" nullable="false" jdbcType="93" def="Q1VSUkVOVF9USU1FU1RBTVA=" version="true"/>
<column name="active" sqlType="TINYINT" length="3" precision="0" nullable="false" jdbcType="-6" def="MQ=="/>
<column name="scopeId" sqlType="TINYINT" length="3" precision="0" nullable="false" jdbcType="-6"/>
<column name="typeId" sqlType="TINYINT" length="3" precision="0" nullable="false" jdbcType="-6"/>
<column name="scopeId" sqlType="INT" length="10" precision="0" nullable="false" jdbcType="4"/>
<column name="typeId" sqlType="INT" length="10" precision="0" nullable="false" jdbcType="4"/>
<column name="name" sqlType="VARCHAR" length="255" precision="0" nullable="false" jdbcType="12"/>
<column name="icon" sqlType="VARCHAR" length="255" precision="0" nullable="false" jdbcType="12"/>
<primary-key name="PRIMARY" columns="id"/>
<foreign-key name="map_ibfk_1" columns="typeId" ref-table="map_type" ref-schema="" ref-catalog="pathfinder" ref-columns="id" update-rule="0" delete-rule="0" deferrability="2"/>
<foreign-key name="map_ibfk_2" columns="scopeId" ref-table="map_scope" ref-schema="" ref-catalog="pathfinder" ref-columns="id" update-rule="0" delete-rule="0" deferrability="2"/>
<exported-key name="connection_ibfk_1" table="connection" schema="" catalog="pathfinder" columns="mapId"/>
<exported-key name="system_ibfk_1" table="system" schema="" catalog="pathfinder" columns="mapId"/>
<exported-key name="user_map_ibfk_1" table="user_map" schema="" catalog="pathfinder" columns="mapId"/>
<index name="active" unique="false" columns="active"/>
<index name="created" unique="false" columns="created"/>
<index name="updated" unique="false" columns="updated"/>
@@ -3607,6 +3631,7 @@
<column name="name" sqlType="VARCHAR" length="255" precision="0" nullable="false" jdbcType="12"/>
<column name="label" sqlType="VARCHAR" length="255" precision="0" nullable="false" jdbcType="12"/>
<primary-key name="PRIMARY" columns="id"/>
<exported-key name="map_ibfk_2" table="map" schema="" catalog="pathfinder" columns="scopeId"/>
</table>
<table name="map_type" schema="" catalog="pathfinder" type="TABLE">
<column name="id" sqlType="INT" length="10" precision="0" nullable="false" jdbcType="4" autoIncrement="true"/>
@@ -3618,6 +3643,7 @@
<column name="class" sqlType="VARCHAR" length="255" precision="0" nullable="false" jdbcType="12"/>
<column name="classTab" sqlType="VARCHAR" length="255" precision="0" nullable="false" jdbcType="12"/>
<primary-key name="PRIMARY" columns="id"/>
<exported-key name="map_ibfk_1" table="map" schema="" catalog="pathfinder" columns="typeId"/>
<index name="active" unique="false" columns="active"/>
<index name="created" unique="false" columns="created"/>
<index name="updated" unique="false" columns="updated"/>
@@ -3640,24 +3666,69 @@
<column name="systemId" sqlType="INT" length="10" precision="0" nullable="false" jdbcType="4"/>
<column name="name" sqlType="VARCHAR" length="255" precision="0" nullable="false" jdbcType="12"/>
<column name="alias" sqlType="VARCHAR" length="255" precision="0" nullable="false" jdbcType="12"/>
<column name="regionId" sqlType="INT" length="10" precision="0" nullable="false" jdbcType="4"/>
<column name="region" sqlType="VARCHAR" length="255" precision="0" nullable="false" jdbcType="12"/>
<column name="constellationId" sqlType="INT" length="10" precision="0" nullable="false" jdbcType="4"/>
<column name="constellation" sqlType="VARCHAR" length="255" precision="0" nullable="false" jdbcType="12"/>
<column name="effect" sqlType="VARCHAR" length="100" precision="0" nullable="false" jdbcType="12"/>
<column name="typeId" sqlType="INT" length="10" precision="0" nullable="false" jdbcType="4"/>
<column name="security" sqlType="VARCHAR" length="10" precision="0" nullable="false" jdbcType="12"/>
<column name="trueSec" sqlType="DECIMAL" length="2" precision="1" nullable="false" jdbcType="3"/>
<column name="statusId" sqlType="INT" length="10" precision="0" nullable="false" jdbcType="4"/>
<column name="statusId" sqlType="INT" length="10" precision="0" nullable="false" jdbcType="4" def="MQ=="/>
<column name="locked" sqlType="TINYINT" length="3" precision="0" nullable="false" jdbcType="-6" def="MA=="/>
<column name="rally" sqlType="TINYINT" length="3" precision="0" nullable="false" jdbcType="-6" def="MA=="/>
<column name="posX" sqlType="INT" length="10" precision="0" nullable="false" jdbcType="4" def="MA=="/>
<column name="posY" sqlType="INT" length="10" precision="0" nullable="false" jdbcType="4" def="MA=="/>
<primary-key name="PRIMARY" columns="id"/>
<foreign-key name="system_ibfk_1" columns="mapId" ref-table="map" ref-schema="" ref-catalog="pathfinder" ref-columns="id" update-rule="0" delete-rule="0" deferrability="2"/>
<foreign-key name="system_ibfk_2" columns="typeId" ref-table="system_type" ref-schema="" ref-catalog="pathfinder" ref-columns="id" update-rule="0" delete-rule="0" deferrability="2"/>
<foreign-key name="system_ibfk_3" columns="statusId" ref-table="system_status" ref-schema="" ref-catalog="pathfinder" ref-columns="id" update-rule="0" delete-rule="0" deferrability="2"/>
<exported-key name="connection_ibfk_2" table="connection" schema="" catalog="pathfinder" columns="source"/>
<exported-key name="connection_ibfk_3" table="connection" schema="" catalog="pathfinder" columns="target"/>
<index name="mapId_2" unique="true" columns="mapId,systemId"/>
<index name="unique_system" unique="true" columns="mapId,systemId"/>
<index name="active" unique="false" columns="active"/>
<index name="created" unique="false" columns="created"/>
<index name="locked" unique="false" columns="locked"/>
<index name="mapId" unique="false" columns="mapId"/>
<index name="rally" unique="false" columns="rally"/>
<index name="statusId" unique="false" columns="statusId"/>
<index name="regionId" unique="false" columns="regionId"/>
<index name="systemId" unique="false" columns="systemId"/>
<index name="typeId" unique="false" columns="typeId"/>
<index name="updated" unique="false" columns="updated"/>
</table>
<table name="system_jumps" schema="" catalog="pathfinder" type="TABLE">
<column name="id" sqlType="INT" length="10" precision="0" nullable="false" jdbcType="4" autoIncrement="true"/>
<column name="created" sqlType="TIMESTAMP" length="19" precision="0" nullable="false" jdbcType="93" def="Q1VSUkVOVF9USU1FU1RBTVA="/>
<column name="updated" sqlType="TIMESTAMP" length="19" precision="0" nullable="false" jdbcType="93" def="Q1VSUkVOVF9USU1FU1RBTVA=" version="true"/>
<column name="active" sqlType="TINYINT" length="3" precision="0" nullable="false" jdbcType="-6" def="MQ=="/>
<column name="systemId" sqlType="INT" length="10" precision="0" nullable="false" jdbcType="4"/>
<column name="jumps1" sqlType="INT" length="10" precision="0" nullable="false" jdbcType="4" def="MA=="/>
<column name="jumps2" sqlType="INT" length="10" precision="0" nullable="false" jdbcType="4" def="MA=="/>
<column name="jumps3" sqlType="INT" length="10" precision="0" nullable="false" jdbcType="4" def="MA=="/>
<column name="jumps4" sqlType="INT" length="10" precision="0" nullable="false" jdbcType="4" def="MA=="/>
<column name="jumps5" sqlType="INT" length="10" precision="0" nullable="false" jdbcType="4" def="MA=="/>
<column name="jumps6" sqlType="INT" length="10" precision="0" nullable="false" jdbcType="4" def="MA=="/>
<column name="jumps7" sqlType="INT" length="10" precision="0" nullable="false" jdbcType="4" def="MA=="/>
<column name="jumps8" sqlType="INT" length="10" precision="0" nullable="false" jdbcType="4" def="MA=="/>
<column name="jumps9" sqlType="INT" length="10" precision="0" nullable="false" jdbcType="4" def="MA=="/>
<column name="jumps10" sqlType="INT" length="10" precision="0" nullable="false" jdbcType="4" def="MA=="/>
<column name="jumps11" sqlType="INT" length="10" precision="0" nullable="false" jdbcType="4" def="MA=="/>
<column name="jumps12" sqlType="INT" length="10" precision="0" nullable="false" jdbcType="4" def="MA=="/>
<column name="jumps13" sqlType="INT" length="10" precision="0" nullable="false" jdbcType="4" def="MA=="/>
<column name="jumps14" sqlType="INT" length="10" precision="0" nullable="false" jdbcType="4" def="MA=="/>
<column name="jumps15" sqlType="INT" length="10" precision="0" nullable="false" jdbcType="4" def="MA=="/>
<column name="jumps16" sqlType="INT" length="10" precision="0" nullable="false" jdbcType="4" def="MA=="/>
<column name="jumps17" sqlType="INT" length="10" precision="0" nullable="false" jdbcType="4" def="MA=="/>
<column name="jumps18" sqlType="INT" length="10" precision="0" nullable="false" jdbcType="4" def="MA=="/>
<column name="jumps19" sqlType="INT" length="10" precision="0" nullable="false" jdbcType="4" def="MA=="/>
<column name="jumps20" sqlType="INT" length="10" precision="0" nullable="false" jdbcType="4" def="MA=="/>
<column name="jumps21" sqlType="INT" length="10" precision="0" nullable="false" jdbcType="4" def="MA=="/>
<column name="jumps22" sqlType="INT" length="10" precision="0" nullable="false" jdbcType="4" def="MA=="/>
<column name="jumps23" sqlType="INT" length="10" precision="0" nullable="false" jdbcType="4" def="MA=="/>
<column name="jumps24" sqlType="INT" length="10" precision="0" nullable="false" jdbcType="4" def="MA=="/>
<primary-key name="PRIMARY" columns="id"/>
<index name="systemId" unique="true" columns="systemId"/>
<index name="active" unique="false" columns="active"/>
<index name="created" unique="false" columns="created"/>
<index name="updated" unique="false" columns="updated"/>
</table>
<table name="system_status" schema="" catalog="pathfinder" type="TABLE">
@@ -3669,6 +3740,7 @@
<column name="label" sqlType="VARCHAR" length="255" precision="0" nullable="false" jdbcType="12"/>
<column name="class" sqlType="VARCHAR" length="255" precision="0" nullable="false" jdbcType="12"/>
<primary-key name="PRIMARY" columns="id"/>
<exported-key name="system_ibfk_3" table="system" schema="" catalog="pathfinder" columns="statusId"/>
<index name="active" unique="false" columns="active"/>
<index name="created" unique="false" columns="created"/>
<index name="updated" unique="false" columns="updated"/>
@@ -3680,6 +3752,7 @@
<column name="active" sqlType="TINYINT" length="3" precision="0" nullable="false" jdbcType="-6" def="MQ=="/>
<column name="name" sqlType="VARCHAR" length="255" precision="0" nullable="false" jdbcType="12"/>
<primary-key name="PRIMARY" columns="id"/>
<exported-key name="system_ibfk_2" table="system" schema="" catalog="pathfinder" columns="typeId"/>
<index name="active" unique="false" columns="active"/>
<index name="created" unique="false" columns="created"/>
<index name="updated" unique="false" columns="updated"/>
@@ -3693,12 +3766,29 @@
<column name="name" sqlType="VARCHAR" length="255" precision="0" nullable="false" jdbcType="12"/>
<column name="password" sqlType="VARCHAR" length="255" precision="0" nullable="false" jdbcType="12"/>
<primary-key name="PRIMARY" columns="id"/>
<exported-key name="user_map_ibfk_2" table="user_map" schema="" catalog="pathfinder" columns="userId"/>
<index name="id" unique="true" columns="id"/>
<index name="name" unique="true" columns="name"/>
<index name="created" unique="false" columns="created"/>
<index name="lastLogin" unique="false" columns="lastLogin"/>
<index name="updated" unique="false" columns="updated"/>
</table>
<table name="user_map" schema="" catalog="pathfinder" type="TABLE">
<column name="id" sqlType="INT" length="10" precision="0" nullable="false" jdbcType="4" autoIncrement="true"/>
<column name="created" sqlType="TIMESTAMP" length="19" precision="0" nullable="false" jdbcType="93" def="Q1VSUkVOVF9USU1FU1RBTVA="/>
<column name="updated" sqlType="TIMESTAMP" length="19" precision="0" nullable="false" jdbcType="93" def="Q1VSUkVOVF9USU1FU1RBTVA=" version="true"/>
<column name="active" sqlType="TINYINT" length="3" precision="0" nullable="false" jdbcType="-6" def="MQ=="/>
<column name="userId" sqlType="INT" length="10" precision="0" nullable="false" jdbcType="4"/>
<column name="mapId" sqlType="INT" length="10" precision="0" nullable="false" jdbcType="4"/>
<primary-key name="PRIMARY" columns="id"/>
<foreign-key name="user_map_ibfk_1" columns="mapId" ref-table="map" ref-schema="" ref-catalog="pathfinder" ref-columns="id" update-rule="0" delete-rule="0" deferrability="2"/>
<foreign-key name="user_map_ibfk_2" columns="userId" ref-table="user" ref-schema="" ref-catalog="pathfinder" ref-columns="id" update-rule="0" delete-rule="0" deferrability="2"/>
<index name="unique_user" unique="true" columns="userId,mapId"/>
<index name="active" unique="false" columns="active"/>
<index name="created" unique="false" columns="created"/>
<index name="updated" unique="false" columns="updated"/>
<index name="userId" unique="false" columns="mapId"/>
</table>
<table name="wh_statics" schema="" catalog="pathfinder" type="TABLE">
<column name="id" sqlType="INT" length="10" precision="0" nullable="false" jdbcType="4" autoIncrement="true"/>
<column name="constellation_id" sqlType="INT" length="10" precision="0" nullable="false" jdbcType="4"/>

2
.idea/dataSources.xml generated
View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="DataSourceManagerImpl" format="xml" hash="3779592507">
<component name="DataSourceManagerImpl" format="xml" hash="1236303993">
<data-source source="LOCAL" name="Pathfinder" uuid="da3cf616-be39-4091-94bd-76d70f41765d">
<driver-ref>mysql</driver-ref>
<synchronize>true</synchronize>

View File

@@ -4,6 +4,7 @@
<w>addclass</w>
<w>bootbox</w>
<w>contextmenu</w>
<w>cronjob</w>
<w>crosshairs</w>
<w>cytaclysmic</w>
<w>dashstyle</w>
@@ -16,6 +17,7 @@
<w>jumpbridge</w>
<w>killboard</w>
<w>killmail</w>
<w>malihu</w>
<w>mouseover</w>
<w>nonblock</w>
<w>onerror</w>

View File

@@ -1,7 +1,7 @@
[globals]
; Verbosity level of the stack trace. Assign values between 0 to 3 for increasing verbosity levels
DEBUG = 0
DEBUG = 1
; If TRUE, the framework, after having logged stack trace and errors, stops execution (die without any status) when a non-fatal error is detected.
HALT = FALSE

View File

@@ -157,7 +157,7 @@ class AccessController extends Controller {
*/
protected function _getUser(){
$user = Model\BasicModel::getNew('UserModel');
$user = Model\BasicModel::getNew('UserModel', 5);
$user->getById($this->f3->get('SESSION.user.id'));
if($user->dry()){

View File

@@ -74,8 +74,10 @@ class Controller {
$this->f3->get('DB_PASS')
);
}
$this->f3->set('DB', $db);
// set DB timezone to UTC +00:00 (eve server time)
$this->f3->get('DB')->exec('SET @@session.time_zone = "+00:00";');
}

View File

@@ -25,7 +25,6 @@ class MapController extends Controller {
* @param $f3
*/
public function showError($f3){
print_r($f3->get('ERROR'));
// set HTTP status
if(!empty($f3->get('ERROR.code'))){
@@ -44,7 +43,7 @@ class MapController extends Controller {
echo json_encode($errorData);
}else{
echo 'TODO: static errors';
echo $f3->get('ERROR.text');
}
die();

View File

@@ -0,0 +1,68 @@
<?php
/**
* Created by PhpStorm.
* User: exodus4d
* Date: 01.03.15
* Time: 18:37
*/
namespace Controller\Api;
use Model;
class Connection extends \Controller\AccessController{
/**
* event handler
*/
function beforeroute() {
parent::beforeroute();
// set header for all routes
header('Content-type: application/json');
}
/**
* save a new connection or updates an existing (drag/drop) between two systems
* @param $f3
*/
public function save($f3){
$connectionData = (array)$f3->get('POST.connectionData');
$user = $this->_getUser();
$connection = Model\BasicModel::getNew('ConnectionModel');
$connection->getById($connectionData['id']);
$connection->setData($connectionData);
$newConnectionData = [];
if(
$connection->isValid() &&
$connection->hasAccess($user)
){
$connection->save();
$newConnectionData = $connection->getData();
}
echo json_encode($newConnectionData);
}
public function delete($f3){
$connectionIds = $f3->get('POST.connectionIds');
$user = $this->_getUser();
$connection = Model\BasicModel::getNew('ConnectionModel');
foreach($connectionIds as $connectionId){
$connection->getById($connectionId);
$connection->delete($user);
$connection->reset();
}
echo json_encode([]);
}
}

View File

@@ -109,6 +109,45 @@ class Map extends \Controller\AccessController {
echo json_encode($initData);
}
/**
* save a new map or update an existing map
* @param $f3
*/
public function save($f3){
$mapData = (array)$f3->get('POST.mapData');
$map = Model\BasicModel::getNew('MapModel');
$map->getById($mapData['id']);
$map->setData($mapData);
$map->save();
if($map->isPrivate()){
$user = $this->_getUser();
$map->setAccess($user);
}
$mapData = $map->getData();
echo json_encode($mapData);
}
/**
* delete a map and all dependencies
* @param $f3
*/
public function delete($f3){
$mapData = (array)$f3->get('POST.mapData');
$user = $this->_getUser();
$map = Model\BasicModel::getNew('MapModel');
$map->getById($mapData['id']);
$map->delete($user);
echo json_encode([]);
}
/**
* update map data api
* function is called continuously
@@ -116,6 +155,10 @@ class Map extends \Controller\AccessController {
*/
public function updateData($f3){
// cache time for response should be equal or less than this function is called
// security aspect
$responseTTL = 3;
$mapData = (array)$f3->get('POST.mapData');
$user = $this->_getUser();
@@ -125,28 +168,42 @@ class Map extends \Controller\AccessController {
$connection = Model\BasicModel::getNew('ConnectionModel');
foreach($mapData as $data){
$config = $data['config'];
$systems = $data['data']['systems'];
$connections = $data['data']['connections'];
$systems = [];
$connections = [];
// check whether system data and/or connection data is send
// empty arrays are not included in ajax requests
if(array_key_exists('data', $data)){
if(array_key_exists('systems', $data['data'])){
$systems = $data['data']['systems'];
}
if(array_key_exists('connections', $data['data'])){
$connections = $data['data']['connections'];
}
}
// update map data ---------------------------------------------
$map->getById($config['id']);
// update map on change
if( (int)$config['updated'] > strtotime($map->updated)){
$map->setData($config);
$map->save();
if(!$map->dry()){
// update map on change
if( (int)$config['updated'] > strtotime($map->updated)){
$map->setData($config);
$map->save();
}
}
// get system data -----------------------------------------------
foreach($systems as $systemData){
$system->getById($systemData['id']);
if((int)$systemData['updated'] > strtotime($system->updated)){
if(
(int)$systemData['updated'] === 0 &&
!$system->dry()
){
$systemData['mapId'] = $map;
$system->setData($systemData);
$system->save();
@@ -157,15 +214,17 @@ class Map extends \Controller\AccessController {
// get connection data -------------------------------------------
foreach($connections as $connectionData){
$connection->getById($connectionData['id']);
if((int)$connectionData['updated'] > strtotime($connection->updated)){
if(
(int)$connectionData['updated'] === 0 &&
!$connection->dry()
){
$connectionData['mapId'] = $map;
$connection->setData($connectionData);
$connection->save();
$connection->save($user);
}
$connection->reset();
}
@@ -173,25 +232,41 @@ class Map extends \Controller\AccessController {
}
// get map data ======================================================
$cacheKey = 'user_map_data_' . $user->id;
$activeMaps = $user->getMaps();
if($f3->exists($cacheKey) === false){
$activeMaps = $user->getMaps();
$newData = [];
foreach($activeMaps as $activeMap){
// format map Data for return
$newData = self::getFormattedMapData($activeMaps);
$newData[] = [
'config' => $activeMap->getData(),
$f3->set($cacheKey, $newData, $responseTTL);
}else{
// TODO log -> manipulated request
}
echo json_encode( $f3->get($cacheKey) );
}
/**
* @param $mapModels
* @return Model\MapModel[]
*/
public static function getFormattedMapData($mapModels){
$mapData = [];
foreach($mapModels as $mapModel){
$mapData[] = [
'config' => $mapModel->getData(),
'data' => [
'systems' => $activeMap->getSystemData(),
'connections' => $activeMap->getConnectionData(),
'systems' => $mapModel->getSystemData(),
'connections' => $mapModel->getConnectionData(),
]
];
}
echo json_encode($newData);
return $mapData;
}
}

View File

@@ -77,7 +77,7 @@ class System extends \Controller\AccessController {
* build query
* @return string
*/
private function getQuery(){
private function _getQuery(){
$query = $this->mainQuery;
$query .= ' ' . $this->whereQuery;
@@ -88,28 +88,24 @@ class System extends \Controller\AccessController {
return $query;
}
/**
* get system data by systemId
* @param $f3
* @param $params
* get static system Data from CCPs Static DB export
* @param $systemId
* @return null
*/
public function getById($f3, $params){
protected function _getSystemModelById($systemId){
// switch DB
$this->setDB('CCP');
$systemId = '';
// check for search parameter
if( array_key_exists( 'arg1', $params) ){
$systemId = $params['arg1'];
}
$this->whereQuery = "WHERE
map_sys.solarSystemID = " . $systemId . "";
map_sys.solarSystemID = " . (int)$systemId . "";
$this->limitQuery = "Limit 1";
$query = $this->getQuery();
$query = $this->_getQuery();
$rows = $this->f3->get('DB')->exec($query, null, 30);
@@ -120,15 +116,33 @@ class System extends \Controller\AccessController {
// switch DB
$this->setDB('PF');
$system = Model\BasicModel::getNew('SystemModel');
$system->setData(reset($ccpData));
$data = $system->getData();
echo json_encode($data);
return $system;
}
/**
* Get all static system Data from CCP DB (long cache timer)
* @return array
*/
public function getSystems(){
// switch DB
$this->setDB('CCP');
$query = $this->_getQuery();
$rows = $this->f3->get('DB')->exec($query, null, 60 * 60 * 24);
// format result
$mapper = new Mapper\CcpSystemsMapper($rows);
return $mapper->getData();
}
/**
* search systems by name
* @param $f3
@@ -148,9 +162,9 @@ class System extends \Controller\AccessController {
$this->whereQuery = "WHERE
map_sys.solarSystemName LIKE '%" . $searchToken . "%'";
$query = $this->getQuery();
$query = $this->_getQuery();
$rows = $this->f3->get('DB')->exec($query);
$rows = $f3->get('DB')->exec($query);
// format result
$mapper = new Mapper\CcpSystemsMapper($rows);
@@ -160,4 +174,130 @@ class System extends \Controller\AccessController {
echo json_encode($data);
}
}
/**
* save a new system to a a map
* @param $f3
*/
public function save($f3){
$newSystemData = [];
$systemData = (array)$f3->get('POST.systemData');
$mapData = (array)$f3->get('POST.mapData');
$map = Model\BasicModel::getNew('MapModel');
$map->getById($mapData['id']);
// check if map exists
if(!$map->dry()){
$systemData['mapId'] = $map;
// get static system data (CCP DB)
$system = $this->_getSystemModelById($systemData['systemId']);
// set rest of system data
$system->setData($systemData);
$system->save();
$newSystemData = $system->getData();
}
echo json_encode($newSystemData);
}
/**
* delete a system and all its connections
* @param $f3
*/
public function delete($f3){
$systemIds = $f3->get('POST.systemIds');
$user = $this->_getUser();
$system = Model\BasicModel::getNew('SystemModel');
foreach($systemIds as $systemId){
$system->getById($systemId);
$system->delete($user);
$system->reset();
}
echo json_encode([]);
}
/**
* get system log data from CCP API import
* system Kills, Jumps,....
* @param $f3
*/
public function graphData($f3){
$graphData = [];
$systemIds = $f3->get('POST.systemIds');
// number of log entries in each table per system (24 = 24h)
$logEntryCount = 24;
// table names with system data
$logTables = [
'jumps' => 'SystemJumpModel',
'shipKills' => 'SystemShipKillModel',
'podKills' => 'SystemPodKillModel',
'factionKills' => 'SystemFactionKillModel'
];
foreach($systemIds as $systemId){
foreach($logTables as $label => $ModelClass){
$systemLogModel = Model\BasicModel::getNew($ModelClass);
// 10min cache (could be up to 1h cache time)
$systemLogModel->getByForeignKey('systemId', $systemId, array(), 60 * 10);
if(!$systemLogModel->dry()){
$counter = 0;
for( $i = $logEntryCount; $i >= 1; $i--){
$column = 'value' . $i;
// ship and pod kills should be merged into one table
if($label == 'podKills'){
$graphData[$systemId]['shipKills'][$counter]['z'] = $systemLogModel->$column;
}else{
$dataSet = [
'x' => ($i - 1) . 'h',
'y' => $systemLogModel->$column
];
$graphData[$systemId][$label][] = $dataSet;
}
$counter++;
}
}
}
}
echo json_encode($graphData);
}
}

View File

@@ -0,0 +1,232 @@
<?php
/**
* Created by PhpStorm.
* User: exodus4d
* Date: 09.03.15
* Time: 21:31
*/
namespace Controller\Cron;
class Update extends \Controller\Controller {
protected $pathEveApi = 'https://api.eveonline.com';
protected $apiRequestOptions = [
'timeout' => 5
];
/**
* table names for all system log tables
* @var array
*/
protected $logTables = [
'jumps' => 'system_jumps',
'shipKills' => 'system_kills_ships',
'podKills' => 'system_kills_pods',
'factionKills' => 'system_kills_factions'
];
/**
* event handler
*/
function beforeroute() {
// controller access allowed for CLI-mode (command line)
if(php_sapi_name() != 'cli'){
$this->f3->error(401, 'Cronjob: unauthorized access');
}
// set linebreak for status output
define('LNBR', PHP_EOL);
parent::beforeroute();
}
/**
* check all system log tables for the correct number of system entries that will be locked
* @return array
*/
private function _prepareSystemLogTables(){
$systemController = new \Controller\Api\System();
$systemsData = $systemController->getSystems();
// switch DB back to pathfinder
$this->setDB('PF');
// insert systems into each log table if not exist
$this->f3->get('DB')->begin();
foreach($this->logTables as $tableName){
// insert systems into jump log table
$sqlInsertSystem = "INSERT IGNORE INTO " . $tableName . " (systemId)
VALUES(:systemId)";
foreach($systemsData as $systemData){
// skip WH systems -> no jump data available
if($systemData['type']['name'] == 'k-space'){
$this->f3->get('DB')->exec($sqlInsertSystem, array(
':systemId' => $systemData['systemId']
));
}
}
}
$this->f3->get('DB')->commit();
return $systemsData;
}
/**
* imports all relevant map stats from CCPs API
* >> php index.php "/cron/update/importmapdata"
* @param $f3
*/
public function importMapData($f3){
$time_start = microtime(true);
// prepare system jump log table
$systemsData = $this->_prepareSystemLogTables();
$time_end = microtime(true);
$execTimePrepareSystemLogTables = $time_end - $time_start;
// get current jump Data -------------------------------------------------------
$time_start = microtime(true);
$apiPath = $this->pathEveApi . '/map/Jumps.xml.aspx';
$apiResponse = \Web::instance()->request($apiPath, $this->apiRequestOptions );
$jumpData = [];
$updateJumps = false;
if($apiResponse['body']){
$xml = simplexml_load_string($apiResponse['body']);
$rowApiData = $xml->result->rowset;
foreach($rowApiData->children() as $systemApiData){
$attributeApiData = $systemApiData->attributes();
$systemId = $attributeApiData->solarSystemID->__toString();
$shipJumps =$attributeApiData->shipJumps->__toString();
$jumpData[$systemId] = $shipJumps;
}
$updateJumps = true;
}
$time_end = microtime(true);
$execTimeGetJumpData = $time_end - $time_start;
// get current kill Data -------------------------------------------------------
$time_start = microtime(true);
$apiPath = $this->pathEveApi . '/map/Kills.xml.aspx';
$apiResponse = \Web::instance()->request($apiPath, $this->apiRequestOptions );
$killData = [];
$updateKills = false;
if($apiResponse['body']){
$xml = simplexml_load_string($apiResponse['body']);
$rowApiData = $xml->result->rowset;
foreach($rowApiData->children() as $systemApiData){
$attributeApiData = $systemApiData->attributes();
$systemId = $attributeApiData->solarSystemID->__toString();
$shipKills =$attributeApiData->shipKills->__toString();
$podKills =$attributeApiData->podKills->__toString();
$factionKills =$attributeApiData->factionKills->__toString();
$killData[$systemId] = [
'shipKills' => $shipKills,
'podKills' => $podKills,
'factionKills' => $factionKills,
];
}
$updateKills = true;
}
$time_end = microtime(true);
$execTimeGetKillData = $time_end - $time_start;
// update system log tables -----------------------------------------------------
$time_start = microtime(true);
// make sure last update is (at least) 1h ago
$f3->get('DB')->begin();
foreach($this->logTables as $key => $tableName){
$sql = "UPDATE
" . $tableName . "
SET
value24 = value23,
value23 = value22,
value22 = value21,
value21 = value20,
value20 = value19,
value19 = value18,
value18 = value17,
value17 = value16,
value16 = value15,
value15 = value14,
value14 = value13,
value13 = value12,
value12 = value11,
value11 = value10,
value10 = value9,
value9 = value8,
value8 = value7,
value7 = value6,
value6 = value5,
value5 = value4,
value4 = value3,
value3 = value2,
value2 = value1,
value1 = :value
WHERE
systemId = :systemId AND
HOUR(TIMEDIFF(NOW(), updated)) > 0
";
foreach($systemsData as $systemData){
if(
$key == 'jumps' &&
$updateJumps
){
// update jump data (if available)
$currentJumps = 0;
if(array_key_exists($systemData['systemId'], $jumpData)){
$currentJumps = $jumpData[$systemData['systemId']];
}
$f3->get('DB')->exec($sql, array(
':systemId' => $systemData['systemId'],
':value' => $currentJumps
));
}else if($updateKills){
// update kill data (if available)
$currentKills = 0;
if(array_key_exists($systemData['systemId'], $killData)){
$currentKillData = $killData[$systemData['systemId']];
$currentKills = $currentKillData[$key];
}
$f3->get('DB')->exec($sql, array(
':systemId' => $systemData['systemId'],
':value' => $currentKills
));
}
}
}
$f3->get('DB')->commit();
$time_end = microtime(true);
$execTimeUpdateTables = $time_end - $time_start;
// ------------------------
echo 'prepare system log tables: ' . round($execTimePrepareSystemLogTables, 2) . 's' . LNBR;
echo 'get jump data: ' . round($execTimeGetJumpData, 2) . 's' . LNBR;
echo 'get kill data: ' . round($execTimeGetKillData, 2) . 's' . LNBR;
echo 'update log tables: ' . round($execTimeUpdateTables, 2) . 's' . LNBR;
}
}

View File

@@ -14,6 +14,8 @@ use Exception;
class BasicModel extends \DB\Cortex{
protected $db = 'DB';
protected $ttl = 20;
protected $rel_ttl = 20;
/**
* field validation array
@@ -82,7 +84,6 @@ class BasicModel extends \DB\Cortex{
}
break;
}
break;
}
}
@@ -99,31 +100,46 @@ class BasicModel extends \DB\Cortex{
if(!$valid){
break;
}
}
}
return $valid;
}
/**
* get single dataSet by id
* @param $id
* @return array|FALSE
* @param int $ttl
* @return \DB\Cortex
*/
public function getById($id) {
return $this->getByForeignKey('id', (int)$id, array('limit' => 1));
public function getById($id, $ttl = 0) {
return $this->getByForeignKey('id', (int)$id, array('limit' => 1), $ttl);
}
/**
* checks weather this model is active or not
* each model should have an "active" column
* @return bool
*/
public function isActive(){
$isActive = false;
if($this->active === 1){
$isActive = true;
}
return $isActive;
}
/**
* get dataSet by foreign column
* @param $key
* @param $id
* @param $options
* @return array|FALSE
* @param array $options
* @param int $ttl
* @return \DB\Cortex
*/
public function getByForeignKey($key, $id, $options = array()){
public function getByForeignKey($key, $id, $options = array(), $ttl = 0){
$querySet = [];
$query = [];
@@ -140,34 +156,56 @@ class BasicModel extends \DB\Cortex{
array_unshift($querySet, implode(' AND ', $query));
return $this->load( $querySet, $options );
return $this->load( $querySet, $options, $ttl );
}
/**
* get multiple model obj that have an 1->m relation to this model
* @param $model
* @param $foreignKey
* @param null $options
* @param int $ttl
* @return mixed
*/
public function getRelatedModels($model, $foreignKey){
$model = self::getNew($model);
$relatedModels = $model->find(array($foreignKey . ' = ? AND active = 1', $this->id), null, 10);
public function getRelatedModels($model, $foreignKey, $options = null, $ttl = 0){
$model = self::getNew($model, $ttl);
$relatedModels = $model->find(array($foreignKey . ' = ? AND active = 1', $this->id), $options, $ttl);
return $relatedModels;
}
/**
* function should be overwritten in child classes with access restriction
* @param $accessObject
* @return bool
*/
public function hasAccess($accessObject){
return true;
}
/**
* function should be overwritten in parent classes
* @return bool
*/
public function isValid(){
return true;
}
/**
* factory for all Models
* @param $model
* @param int $ttl
* @return null
* @throws \Exception
*/
public static function getNew($model){
public static function getNew($model, $ttl = 20){
$class = null;
$model = '\\' . __NAMESPACE__ . '\\' . $model;
if(class_exists($model)){
$class = new $model();
$f3 = \Base::instance();
$class = new $model($f3->get('DB'), null, null, $ttl );
}else{
throw new \Exception('No model class found');
}

View File

@@ -12,6 +12,8 @@ namespace Model;
class ConnectionModel extends BasicModel{
protected $table = 'connection';
protected $ttl = 5;
protected $rel_ttl = 5;
protected $fieldConf = array(
'mapId' => array(
@@ -33,6 +35,13 @@ class ConnectionModel extends BasicModel{
if(!is_array($value)){
if($this->exists($key)){
$this->$key = $value;
if($key == 'source'){
// set mapId
$sourceSystem = self::getNew('SystemModel');
$sourceSystem->getById( $this->$key );
$this->mapId = $sourceSystem->mapId;
}
}
}elseif($key == 'type'){
// json field
@@ -41,6 +50,10 @@ class ConnectionModel extends BasicModel{
}
}
/**
* get connection data as array
* @return array
*/
public function getData(){
$connectionData = [
@@ -55,4 +68,52 @@ class ConnectionModel extends BasicModel{
return $connectionData;
}
/**
* check object for model access
* @param $accessObject
* @return bool
*/
public function hasAccess($accessObject){
return $this->mapId->hasAccess($accessObject);
}
/**
* check weather this model is valid or not
* @return bool
*/
public function isValid(){
$isValid = true;
// check if source/target belong to same map
$sourceSystem = self::getNew('SystemModel');
$sourceSystem->getById( $this->source );
$targetSystem = self::getNew('SystemModel');
$targetSystem->getById( $this->target);
if(
$sourceSystem->dry() ||
$targetSystem->dry() ||
$sourceSystem->mapId->id !== $targetSystem->mapId->id
){
$isValid = false;
}
return $isValid;
}
/**
* delete a connection
* @param $accessObject
*/
public function delete($accessObject){
if(!$this->dry()){
// check if editor has access
if($this->hasAccess($accessObject)){
$this->erase();
}
}
}
}

View File

@@ -12,6 +12,8 @@ namespace Model;
class MapModel extends BasicModel{
protected $table = 'map';
protected $ttl = 5;
protected $rel_ttl = 5;
protected $fieldConf = array(
'scopeId' => array(
@@ -41,6 +43,10 @@ class MapModel extends BasicModel{
],
];
/**
* set map data by an associative array
* @param $data
*/
public function setData($data){
foreach((array)$data as $key => $value){
@@ -77,7 +83,8 @@ class MapModel extends BasicModel{
],
'type' => [
'id' => $this->typeId->id,
'name' => $this->typeId->name
'name' => $this->typeId->name,
'classTab' => $this->typeId->classTab
],
'icon' => $this->icon,
'updated' => strtotime($this->updated)
@@ -93,11 +100,13 @@ class MapModel extends BasicModel{
* @return array
*/
public function getSystemData(){
$systems = $this->getRelatedModels('SystemModel', 'mapId');
$systems = $this->getRelatedModels('SystemModel', 'mapId', null, 5);
$systemData = [];
foreach($systems as $system){
$systemData[] = $system->getData();
if(is_object($systems)){
foreach($systems as $system){
$systemData[] = $system->getData();
}
}
return $systemData;
@@ -108,16 +117,127 @@ class MapModel extends BasicModel{
* @return array
*/
public function getConnectionData(){
$connections = $this->getRelatedModels('ConnectionModel', 'mapId');
$connections = $this->getRelatedModels('ConnectionModel', 'mapId', null, 5);
$connectionData = [];
foreach($connections as $connection){
$connectionData[] = $connection->getData();
if(is_object($connections)){
foreach($connections as $connection){
$connectionData[] = $connection->getData();
}
}
return $connectionData;
}
/**
* set map access for an object (user or alliance)
* @param $obj
*/
public function setAccess($obj){
if($obj instanceof UserModel){
// private map
// get all userModels who have map access
$userMaps = $this->getRelatedModels('UserMapModel', 'mapId');
$userFound = false;
if($userMaps){
foreach($userMaps as $userMap){
if($userMap->userId->id !== $obj->id){
// remove map access
$userMap->erase();
}else{
$userFound = true;
}
}
}
if(!$userFound){
// set user who has access to this map
$userMap = self::getNew('UserMapModel');
$userMap->userId = $obj;
$userMap->mapId = $this;
$userMap->save();
}
}
}
/**
* checks weather an object (user or alliance) has
* @param $accessObject
* @return bool
*/
public function hasAccess($accessObject){
$hasAccess = false;
if($accessObject instanceof UserModel){
// get all userModels who have map access
$userMaps = $this->getRelatedModels('UserMapModel', 'mapId');
if($userMaps){
foreach($userMaps as $userMap){
if($userMap->userId->id === $accessObject->id){
$hasAccess = true;
break;
}
}
}
}
return $hasAccess;
}
/**
* delete this map and all dependencies
*/
public function delete($accessObject){
if(!$this->dry()){
// check if editor has access
if($this->hasAccess($accessObject)){
// get all userModels who have map access
$userMaps = $this->getRelatedModels('UserMapModel', 'mapId');
if(is_object($userMaps)){
foreach($userMaps as $userMap){
$userMap->erase();
}
}
// get all connections
$connections = $this->getRelatedModels('ConnectionModel', 'mapId');
if(is_object($connections)){
foreach($connections as $connection){
$connection->erase();
}
}
// get all systems
$systems = $this->getRelatedModels('SystemModel', 'mapId');
if(is_object($systems)){
foreach($systems as $system){
$system->erase();
}
}
// delete map
$this->erase();
}
}
}
/**
* checks weather a map is private or not
* @return bool
*/
public function isPrivate(){
$isPrivate = false;
if($this->typeId->id == 2){
$isPrivate = true;
}
return $isPrivate;
}
}

View File

@@ -0,0 +1,15 @@
<?php
/**
* Created by PhpStorm.
* User: exodus4d
* Date: 14.03.15
* Time: 21:04
*/
namespace Model;
class SystemFactionKillModel extends BasicModel {
protected $table = 'system_kills_factions';
}

View File

@@ -0,0 +1,15 @@
<?php
/**
* Created by PhpStorm.
* User: exodus4d
* Date: 14.03.15
* Time: 21:04
*/
namespace Model;
class SystemJumpModel extends BasicModel {
protected $table = 'system_jumps';
}

View File

@@ -12,6 +12,8 @@ namespace Model;
class SystemModel extends BasicModel {
protected $table = 'system';
protected $ttl = 5;
protected $rel_ttl = 5;
protected $fieldConf = array(
'mapId' => array(
@@ -24,7 +26,14 @@ class SystemModel extends BasicModel {
'belongs-to-one' => 'Model\SystemStatusModel'
)
);
/*
protected $validate = [
'statusId' => [
''
'regex' => '/^[1-9]+$/'
]
];
*/
/**
* set an array with all data for a system
* @param $systemData
@@ -60,7 +69,7 @@ class SystemModel extends BasicModel {
}
/**
* get map data for for response
* get map data as array
* @return array
*/
public function getData(){
@@ -100,8 +109,66 @@ class SystemModel extends BasicModel {
];
return $systemData;
}
/**
* check object for model access
* @param $accessObject
* @return bool
*/
public function hasAccess($accessObject){
return $this->mapId->hasAccess($accessObject);
}
/**
* delete a system from a map
* @param $accessObject
*/
public function delete($accessObject){
if(!$this->dry()){
// check if editor has access
if($this->hasAccess($accessObject)){
// delete all system connections
$connections = $this->getConnections();
if(is_object($connections)){
foreach($connections as $connection){
$connection->erase();
}
}
$this->erase();
}
}
}
/**
* get all connections for this system
* @return array
*/
public function getConnections(){
$connections = false;
// connections where system is source
$sourceConnections = $this->getRelatedModels('ConnectionModel', 'source');
$targetConnections = $this->getRelatedModels('ConnectionModel', 'target');
if(is_object($sourceConnections)){
$connections = $sourceConnections;
}
if(is_object($targetConnections)){
if(is_object($connections)){
$connections->append($targetConnections);
}else{
$connections = $targetConnections;
}
}
return $connections;
}
}

View File

@@ -0,0 +1,15 @@
<?php
/**
* Created by PhpStorm.
* User: exodus4d
* Date: 14.03.15
* Time: 21:04
*/
namespace Model;
class SystemPodKillModel extends BasicModel {
protected $table = 'system_kills_pods';
}

View File

@@ -0,0 +1,15 @@
<?php
/**
* Created by PhpStorm.
* User: exodus4d
* Date: 14.03.15
* Time: 21:04
*/
namespace Model;
class SystemShipKillModel extends BasicModel {
protected $table = 'system_kills_ships';
}

View File

@@ -12,8 +12,13 @@ namespace Model;
class UserMapModel extends BasicModel {
protected $table = 'user_map';
protected $ttl = 5;
protected $rel_ttl = 5;
protected $fieldConf = array(
'userId' => array(
'belongs-to-one' => 'Model\UserModel'
),
'mapId' => array(
'belongs-to-one' => 'Model\MapModel'
)

View File

@@ -11,6 +11,8 @@ namespace Model;
class UserModel extends BasicModel {
protected $table = 'user';
protected $ttl = 5;
protected $rel_ttl = 5;
protected $validate = [
'name' => [
@@ -68,11 +70,14 @@ class UserModel extends BasicModel {
* @return array
*/
public function getMaps(){
$userMaps = $this->getRelatedModels('UserMapModel', 'userId');
$userMaps = $this->getRelatedModels('UserMapModel', 'userId', null, 5);
$maps = [];
foreach($userMaps as $userMap){
$maps[] = $userMap->mapId;
if($userMap->mapId->isActive()){
$maps[] = $userMap->mapId;
}
}
return $maps;

View File

@@ -2,8 +2,11 @@
; program routes
GET|POST /= Controller\MapController->showMap
GET|POST /login= Controller\Controller->showLogin
GET|POST /login= Controller\Controller->showLogin, 0, 512
; api routes
GET|POST /api/@controller/@action = Controller\Api\@controller->@action
GET|POST /api/@controller/@action/@arg1 = Controller\Api\@controller->@action
; APIs
GET|POST /api/@controller/@action = Controller\Api\@controller->@action, 0, 512
GET|POST /api/@controller/@action/@arg1 = Controller\Api\@controller->@action, 0, 512
; cronjob APIs
GET /cron/@controller/@action = Controller\Cron\@controller->@action

View File

@@ -19,7 +19,7 @@ requirejs.config({
datatablesBootstrap: 'lib/datatables/dataTables.bootstrap', // DataTables - not used (bootstrap style)
datatablesTableTools: 'lib/datatables/extensions/TableTools/js/dataTables.tableTools', // v2.2.3 TableTools (PlugIn) - https://datatables.net/extensions/tabletools/
xEditable: 'lib/bootstrap-editable.min', // v1.5.1 X-editable - in placed editing
morris: 'lib/morris.min', // v0.5.0 Morris.js - graphs and charts
morris: 'lib/morris.min', // v0.5.1 Morris.js - graphs and charts
raphael: 'lib/raphael-min', // v2.1.2 Raphaël - required for morris (dependency)
bootbox: 'lib/bootbox.min', // v4.3.0 Bootbox.js - custom dialogs
easyPieChart: 'lib/jquery.easypiechart.min', // v2.1.6 Easy Pie Chart - HTML 5 pie charts - http://rendro.github.io/easy-pie-chart/

View File

@@ -8,24 +8,31 @@ define(['jquery'], function($) {
var Config = {
timer: {
programStatusVisible: 5000, // ms: timer for status change visibility in head
mapUpdate: {
delay: 3000, // delay between ping calls
executionLimit: 300 // log timelimit: main map update ping
delay: 3000, // ms: delay between ping calls
executionLimit: 200 // ms: log timelimit: main map update ping
},
userUpdate: {
delay: 2000, // delay between ping calls
executionLimit: 100 // log timelimit: map user update ping
delay: 2000, // ms: delay between ping calls
executionLimit: 200 // ms: log timelimit: map user update ping
},
mapModuleData: {
executionLimit: 100 // log timelimit: get all mapData
executionLimit: 100 // ms: log timelimit: get all mapData
}
},
path: {
img: 'public/img/', // path for images
searchSystems: 'api/system/search', // ajax URL - search system by name
getSystem: 'api/system/getById', // ajax URL - get system by id
initMap: 'api/map/init', // ajax URL - get static data
updateMapData: 'api/map/updateData' // ajax URL - main map update call
updateMapData: 'api/map/updateData', // ajax URL - main map update call
saveMap: 'api/map/save', // ajax URL - save/update map
deleteMap: 'api/map/delete', // ajax URL - delete map
searchSystem: 'api/system/search', // ajax URL - search system by name
saveSystem: 'api/system/save', // ajax URL - saves system to map
deleteSystem: 'api/system/delete', // ajax URL - delete system from map
saveConnection: 'api/connection/save', // ajax URL - save new connection to map
deleteConnection: 'api/connection/delete', // ajax URL - delete connection from map
getSystemGraphData: 'api/system/graphData' // ajax URL - get system graph data
},
url: {
zKillboard: 'https://zkillboard.com/api/', // killboard api
@@ -33,7 +40,9 @@ define(['jquery'], function($) {
},
animationSpeed: {
headerLink: 100, // links in head bar
mapDeleteSystem: 200 // remove system from map
mapMoveSystem: 300, // system position has changed animation
mapDeleteSystem: 200, // remove system from map
mapModule: 100 // show/hide of an map module
},
classes: {
// log types

View File

@@ -216,7 +216,7 @@ define([
lineColors: ['#375959'],
pointFillColors: ['#477372'],
pointStrokeColors: ['#313335'],
lineWidth: 3,
lineWidth: 2,
grid: false,
gridTextSize: 9,
gridTextFamily: 'Oxygen Bold',

View File

@@ -11,6 +11,7 @@ define([
'app/ccp',
'velocity',
'velocityUI',
'app/ui/form_element',
'app/page',
'app/module_map'
], function($, Init, Util, Render, Logging, CCP) {
@@ -32,6 +33,9 @@ define([
$('body').loadPageStructure();
// Map init options
var mapData = [];
/*
var mapData =[{
map: {},
config: {
@@ -520,7 +524,7 @@ define([
connections: []
}
}];
*/
// current user Data for a map
var tempUserData ={
@@ -587,16 +591,16 @@ define([
}
},{
config: { // map config
id: 2 // map id
id: 128 // map id
},
data: {
systems:[ // systems in map
{
id: 50, // system id
id: 8597, // system id
user: [
{
id: 6,
name: 'Schleiferius',
name: 'Exodus 6D Gidrine',
ship: {
id: 69,
name: 'Tengu'
@@ -624,7 +628,6 @@ define([
Init.systemStatus = initData.systemStatus;
Init.systemType = initData.systemType;
console.log(Init.systemType);
// init map module
mapModule.initMapModule();
@@ -636,10 +639,6 @@ define([
});
$.fn.initMapModule = function(){
var mapModule = $(this);
@@ -653,7 +652,7 @@ define([
var mapUserUpdateDelay = Init.timer[mapUserUpdateKey].delay;
// ping for main map update
var triggerMapUpdatePing = function(tempMapData){
var triggerMapUpdatePing = function(){
// check each execution time if map module is still available
var check = $('#' + mapModule.attr('id')).length;
@@ -663,16 +662,6 @@ define([
return;
}
$(document).setProgramStatus('online');
Util.timeStart(mapUpdateKey);
// load map module ==========================================
mapModule.updateMapModule(tempMapData);
var duration = Util.timeStop(mapUpdateKey);
// log execution time
Util.log(mapUpdateKey, {duration: duration, description: 'updateMapModule'});
// get updated map data
Util.timeStart(mapModuleDatakey);
var updatedMapData = mapModule.getMapModuleData();
@@ -684,30 +673,47 @@ define([
// wrap array to object
updatedMapData = {mapData: updatedMapData};
// start log
Util.timeStart(mapUpdateKey);
// store updatedMapData
$.ajax({
type: 'POST',
url: Init.path.updateMapData,
data: updatedMapData,
dataType: 'json'
}).done(function(data){
}).done(function(mapData){
mapData = data;
$(document).setProgramStatus('online');
if(mapData.length === 0){
// no map data available -> show "new map" dialog
$(document).trigger('pf:menuEditMap', {newMap: true});
}else{
// map data found
// load map module
mapModule.updateMapModule(mapData);
// log execution time
var duration = Util.timeStop(mapUpdateKey);
Util.log(mapUpdateKey, {duration: duration, description: 'updateMapModule'});
}
// init new trigger
setTimeout(function(){
triggerMapUpdatePing(mapData);
triggerMapUpdatePing();
}, mapUpdateDelay);
}).fail(function( jqXHR, status, error) {
var reason = status + ': ' + error;
console.log(error);
Util.showNotify({title: jqXHR.status + ': updatedMapData', text: reason, type: 'warning'});
$(document).setProgramStatus('problem');
var reason = status + ' ' + jqXHR.status + ': ' + error;
Util.emergencyShutdown(reason);
});
};
triggerMapUpdatePing(mapData);
triggerMapUpdatePing([]);
// ping for user data update -------------------------------------------------------
var triggerUserUpdatePing = function(userData){
@@ -715,7 +721,7 @@ define([
$(document).setProgramStatus('online');
Util.timeStart(mapUserUpdateKey);
mapModule.updateMapModuleData(userData);
// mapModule.updateMapModuleData(userData);
var duration = Util.timeStop(mapUserUpdateKey);
// log execution time

File diff suppressed because it is too large Load Diff

View File

@@ -4,13 +4,15 @@ define([
'app/util',
'app/render',
'bootbox',
'morris',
//'datatables',
'app/ui/system_info',
'app/ui/system_graph',
'app/ui/system_route',
'app/ui/system_killboard',
'datatablesTableTools',
'xEditable',
'app/map/map',
'app/counter'
], function($, Config, Util, Render, bootbox, Morris) {
], function($, Config, Util, Render, bootbox) {
'use strict';
@@ -29,9 +31,12 @@ define([
mapClass: 'pf-map', // class for each map
// dialogs
newMapDialogId: 'pf-map-new-dialog', // id for system dialog
signatureReaderDialogId: 'pf-signature-reader-dialog', // id for signature reader dialog
// tables
tableToolsClass: 'pf-table-tools', // table toolbar
tableToolsActionClass: 'pf-table-tools-action', // table toolbar action
// TabContentStructure
mapTabContentRow: 'pf-map-content-row', // main row for Tab content (grid)
mapTabContentCell: 'pf-map-content-col', // column
@@ -42,35 +47,20 @@ define([
moduleClass: 'pf-module', // class for each module
// 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
systemInfoGraphKillsClass: 'pf-system-info-graph-kills', // class for system kill graph
systemInfoTableClass: 'pf-system-info-table', // class for system info table
systemInfoTableEffectRowClass: 'pf-system-info-effect-row', // class for system info table effect row
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)
systemInfoProgressScannedClass: 'pf-system-progress-scanned', // progress bar scanned signatures
// sig table module
sigTableModuleClass: 'pf-sig-table-module', // module wrapper
sigTableToolsClass: 'pf-sig-table-tools', // table toolbar
sigTableToolsActionClass: 'pf-sig-table-tools-action', // table toolbar action
sigTableClass: 'pf-sig-table', // Table class for all Signature Tables
sigTableMainClass: 'pf-sig-table-main', // Table class for main sig table
sigTableEditText: 'pf-sig-table-edit-text', // class for editable fields (text)
sigTableEditSigNameInput: 'pf-sig-table-edit-name-input', // class for editable fields (input)
sigTableEditSigTypeSelect: 'pf-sig-table-edit-type-select', // class for editable fields (select)
sigTableEditSigNameSelect: 'pf-sig-table-edit-name-select', // class for editable fields (select)
sigTableCounterClass: 'pf-sig-table-counter', // class for signature table counter
sigTableCounterClass: 'pf-sig-table-counter' // class for signature table counter
};
var cache = {
systemRoutes: {}, // jump information between solar systems
systemKillsGraphData: {} // data for system kills info graph
};
var mapTabChangeBlocked = false; // flag for preventing map tab switch
@@ -122,7 +112,7 @@ define([
// collect all relevant data for SystemInfoElement
var systemInfoData = {
systemId: parseInt( $( mapData.system).data('id') ),
systemData: $( mapData.system).getSystemData(),
mapId: parseInt( $( mapData.system).attr('data-mapid') )
};
@@ -259,7 +249,7 @@ define([
// add toolbar buttons for table -------------------------------------
var tableToolbar = $('<div>', {
class: config.sigTableToolsClass
class: config.tableToolsClass
}).append(
$('<button>', {
class: ['btn', 'btn-primary', 'btn-sm'].join(' '),
@@ -267,7 +257,7 @@ define([
type: 'button'
}).on('click', function(e){
// show "add sig" div
var toolsElement = $(e.target).parents('.' + config.moduleClass).find('.' + config.sigTableToolsActionClass);
var toolsElement = $(e.target).parents('.' + config.moduleClass).find('.' + config.tableToolsActionClass);
toolsElement.slideToggle( 100 );
}).prepend(
$('<i>', {
@@ -318,7 +308,7 @@ define([
// add toolbar action for table -------------------------------------
var tableToolbarAction = $('<div>', {
class: config.sigTableToolsActionClass
class: config.tableToolsActionClass
});
// create "empty table for new signature
@@ -593,6 +583,7 @@ define([
return tableData;
};
/**
* clears and updates the system info element (signature table, system info,...)
* @param tabContentElement
@@ -601,16 +592,23 @@ define([
var drawSystemInfoElement = function(tabContentElement, systemInfoData){
// get Table cell for system Info
var systemCell = $(tabContentElement).find('.' + config.mapTabContentCellFirst);
// clear systemCell
systemCell.empty();
var firstCell = $(tabContentElement).find('.' + config.mapTabContentCellFirst);
var secondCell = $(tabContentElement).find('.' + config.mapTabContentCellSecond);
// update signature table module
systemCell.drawSignatureTableModule(systemInfoData);
firstCell.drawSignatureTableModule(systemInfoData);
// update system info module
systemCell.drawSystemInfo(systemInfoData);
// draw system info module
firstCell.drawSystemInfoModule(systemInfoData.systemData);
// draw system graph module
firstCell.drawSystemGraphModule(systemInfoData.systemData);
// update system routes module
secondCell.drawSystemRouteModule(systemInfoData.systemData);
// draw system killboard module
secondCell.drawSystemKillboardModule(systemInfoData.systemData);
};
$.fn.drawSignatureTableModule = function(systemInfoData){
@@ -704,449 +702,6 @@ define([
};
/**
* update systeminfo
*/
$.fn.drawSystemInfo = function(systemInfoData){
// TODO replace by AJAX
if(systemInfoData.systemId === 30002979){
var system = {
id: 30002979,
//name: 'J150020',
name: 'Tararan',
alias: '',
effect: '',
security: 'L',
trueSec: 0.3,
region: {
id: '10000036',
name: 'Devoid'
},
constellation: {
id: '20000436',
name: 'Jayai'
},
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,
name: 'J150020',
alias: 'Polaris',
effect: 'magnetar',
security: 'C6',
trueSec: -1,
region: {
id: '12345',
name: 'F-R00030'
},
constellation: {
id: '678990',
name: 'F-C00298'
},
static: [{
security: 'C6',
name: ' W237',
lifetime: 24
}],
type: 'wh'
};
}
// create new module container
var moduleElement = $('<div>', {
class: [config.moduleClass, config.systemInfoModuleClass].join(' ')
});
$(this).prepend(moduleElement);
var effectName = Util.getEffectInfoForSystem(system.effect, 'name');
var effectClass = Util.getEffectInfoForSystem(system.effect, 'class');
// confirm dialog
var moduleConfig = {
name: 'modules/system_info',
position: moduleElement,
link: 'append',
functions: {
after: function(){
// init tooltips
var tooltipElements = $('.' + config.systemInfoModuleClass + ' [data-toggle="tooltip"]');
tooltipElements.tooltip();
// load trade routes
if(system.type !== 'wh'){
$(moduleElement).find('.' + config.systemInfoRoutesClass).updateSystemInfoRoutes(system.name, ['Jita', 'Amarr', 'Rens', 'Dodixie']);
}
// init system effect popover
var systemEffectData = Util.getSystemEffectData( system.security, system.effect);
if(systemEffectData !== false){
var systemInfoTable = $(moduleElement).find('.' + config.systemInfoTableClass);
// transform data into table
var systemEffectTable = Util.getSystemEffectTable( systemEffectData );
systemInfoTable.popover({
html: true,
trigger: 'hover',
placement: 'top',
delay: 200,
title: 'System effects',
content: systemEffectTable
});
}
// load kill statistic chart
$(moduleElement).find('.' + config.systemInfoGraphsClass).updateSystemInfoGraphs(system.id);
}
}
};
// add security class for statics
if(system.static){
$.each(system.static, function(i, staticWH){
system['static'][i]['class'] = Util.getSecurityClassForSystem( staticWH.security );
});
}
var moduleData = {
system: system,
tableClass: config.systemInfoTableClass,
securityClass: Util.getSecurityClassForSystem( system.security ),
trueSecClass: Util.getTrueSecClassForSystem( system.trueSec ),
effectName: effectName,
effectClass: effectClass
};
Render.showModule(moduleConfig, moduleData);
};
/**
* get label element with given content
* @param text
* @returns {*|XMLList}
*/
var getLabel = function(text, options){
var label = $('<span>', {
class: ['label', options.type, options.align].join(' ')
}).text( text );
return label;
};
/**
* updates the system info graph
* @param systemId
*/
$.fn.updateSystemInfoGraphs = function(systemId){
var parentElement = $(this);
parentElement.empty();
var graphElement = $('<div>', {
class: config.systemInfoGraphKillsClass
});
parentElement.append(graphElement);
var showHours = 24;
var maxKillmailCount = 200; // limited by API
var labelOptions = {
align: 'center-block'
};
// private function draws a "system kills" graph
var drawGraph = function(data){
var tableData = data.tableData;
var label = '';
if(data.count === 0){
labelOptions.type = 'label-success';
label = getLabel( 'No kills found within 24h', labelOptions );
graphElement.prepend( label );
// reduce height
graphElement.animate({
height: '30px'
}, 200);
return;
}
// draw chart
Morris.Bar({
element: graphElement,
resize: true,
gridTextSize: 10,
gridTextColor: '#3c3f41',
gridTextFamily: 'Oxygen Bold',
hideHover: true,
data: tableData,
xkey: 'label',
ykeys: ['kills'],
labels: ['kills'],
xLabelMargin: 10,
padding: 10,
parseTime: false,
barColors: function (row, series, type) {
if (type === 'bar') {
// highlight last row -> recent kills found
if(this.xmax === row.x){
return '#c2760c';
}
}
return '#63676a';
}
});
// show hint for recent kills
if(tableData[tableData.length - 1].kills > 0){
labelOptions.type = 'label-warning';
label = getLabel( tableData[tableData.length - 1].kills + ' kills within the last hour!', labelOptions );
graphElement.prepend( label );
}
};
// 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);
}
// get current server time
var serverDate= Util.getServerTime();
// 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
if(chartData[timeDiffHour]){
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();
// fill cache
cache.systemKillsGraphData[cacheKey] = {};
cache.systemKillsGraphData[cacheKey].tableData = chartData;
cache.systemKillsGraphData[cacheKey].count = kbData.length;
drawGraph( cache.systemKillsGraphData[cacheKey] );
parentElement.hideLoadingAnimation();
}).error(function(e){
Util.showNotify({title: e.status + ': Get system kills', text: 'Loading failed', type: 'error'});
});
}
};
$.fn.updateSystemInfoRoutes = function(systemFrom, systemsTo){
// TODO get cached routes from backend
var parentElement = $(this);
// crate new route table
var table = $('<table>', {
class: ['compact', 'stripe', 'order-column', 'row-border', config.systemInfoRoutesTableClass].join(' ')
});
parentElement.append( $(table) );
// init empty table
var routesTable = table.DataTable( {
paging: false,
ordering: true,
order: [ 1, 'asc' ],
info: false,
searching: false,
hover: false,
//autoWidth: false,
columnDefs: [
{
targets: 0,
//"orderData": 0,
orderable: true,
title: 'system'
},{
targets: 1,
orderable: true,
title: 'jumps &nbsp;&nbsp;&nbsp',
width: '40px',
class: 'text-right'
},{
targets: 2,
orderable: false,
title: 'route'
}
],
data: [] // will be added dynamic
} );
$.each(systemsTo, function(i, systemTo){
if(systemFrom !== systemTo){
var cacheKey = systemFrom + '_' + systemTo;
// row class
var rowClass = config.systemInfoRoutesTableRowPrefix + i;
if(cache.systemRoutes.hasOwnProperty(cacheKey)){
// add new row from cache
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();
}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();
});
}
}
});
};
/**
* update Progressbar for all scanned signatures in a system
*/
@@ -1726,7 +1281,6 @@ define([
// update map
if(tempMapUserDataClone){
//console.log('User: ' + tempMapUserDataClone.data.systems[0].user.length);
mapElement.updateUserData(tempMapUserDataClone, currentUserData);
}
}
@@ -1749,7 +1303,7 @@ define([
})
).append(
$('<div>', {
class: ['col-xs-6', 'col-md-4', config.mapTabContentCellSecond, config.mapTabContentCell].join(' ')
class: ['col-xs-12', 'col-md-4', config.mapTabContentCellSecond, config.mapTabContentCell].join(' ')
})
);
@@ -1760,7 +1314,7 @@ define([
};
var getTabElementh = function(options){
var getTabElement = function(options){
var tabElement = $('<div>', {
id: config.mapTabElementId
@@ -1781,6 +1335,34 @@ define([
return tabElement;
};
/**
* set data for a map tab, or update an existing map tab with new data
* @param options
*/
$.fn.updateTabData = function(options){
var tabElement = $(this);
// set main data
tabElement.data('map-id', options.id).data('updated', options.updated);
// change tab link
tabElement.attr('href', '#' + config.mapTabIdPrefix + options.id);
// change map icon
tabElement.find('i').removeClass().addClass(['fa', 'fa-fw', options.icon].join(' '));
// change map name label
tabElement.find('.' + config.mapTabLinkTextClass).text(options.name);
// change tabClass
var listElement = tabElement.parent();
tabElement.parent().removeClass().addClass([config.mapTabClass, options.type.classTab ].join(' '));
if(options.right === true){
listElement.addClass('pull-right');
}
};
/**
* add a new tab to tab-map-module end returns the new objects
* @param options
@@ -1792,9 +1374,7 @@ define([
var tabBar = tabElement.find('ul.nav-tabs');
var tabContent = tabElement.find('div.tab-content');
var listElement = $('<li>', {
class: options.tabClasses.join(' ')
}).attr('role', 'presentation');
var listElement = $('<li>').attr('role', 'presentation');
if(options.active === true){
listElement.addClass('active');
@@ -1805,19 +1385,14 @@ define([
}
// link element -------
var linkElement = $('<a>', {
href: '#' + config.mapTabIdPrefix + options.id
}).attr('role', 'tab').data('map-id', options.id);
var linkElement = $('<a>').attr('role', 'tab');
// icon element ------
var iconElement = $('<i>', {
class: ['fa', 'fa-fw', options.icon].join(' ')
});
var iconElement = $('<i>');
// text element -----
var textElement = $('<span>', {
class: config.mapTabLinkTextClass,
text: options.name
class: config.mapTabLinkTextClass
});
var newListElement = listElement.append(
@@ -1826,6 +1401,9 @@ define([
tabBar.append( newListElement );
// update Tab element -> set data
linkElement.updateTabData(options);
// tabs content ====================================
var contentElement = $('<div>', {
id: config.mapTabIdPrefix + options.id,
@@ -1858,21 +1436,27 @@ define([
var tabLinkElement = $(this);
var mapId = tabLinkElement.data('map-id');
var mapElement = $('#' + config.mapTabElementId).getActiveMap();
// ignore "add" tab. no need for map change
if(mapId > 0){
var mapElement = $('#' + config.mapTabElementId).getActiveMap();
if(mapId !== mapElement.data('id')){
// block tabs until switch is done
mapTabChangeBlocked = true;
if(mapId !== mapElement.data('id')){
// block tabs until switch is done
mapTabChangeBlocked = true;
// freeze active map -> no user data update while map switch
mapElement.data('frozen', true);
// freeze active map -> no user data update while map switch
mapElement.data('frozen', true);
// hide current map with animation
mapElement.visualizeMap('hide', function(){
// un-block map tabs
mapTabChangeBlocked = switchTabCallback(mapElement, tabLinkElement);
});
// hide current map with animation
mapElement.visualizeMap('hide', function(){
// un-block map tabs
mapTabChangeBlocked = switchTabCallback(mapElement, tabLinkElement);
});
}
}else{
tabLinkElement.tab('show');
}
}
});
@@ -1945,6 +1529,11 @@ define([
*/
$.fn.updateMapModule = function(mapData){
if(mapData.length === 0){
return true;
}
// update current map data
currentMapData = mapData;
@@ -1968,27 +1557,30 @@ define([
// check whether a tab/map is still active
for(var i = 0; i < tabElements.length; i++){
var mapId = $(tabElements[i]).data('map-id');
var tabElement = $(tabElements[i]);
var mapId = tabElement.data('map-id');
if(mapId > 0){
var tabMapData = getMapDataById(mapId);
if(tabMapData !== false){
// map data available -> update map
// map data available ->
activeMapIds.push(mapId);
// check for map data change and update tab
if(tabMapData.config.updated !== tabElement.data('updated')){
tabElement.updateTabData(tabMapData.config);
}
}else{
tabsChanged = true;
// map data not available -> remove tab
var deletedTabName = tabMapElement.deleteTab(mapId);
tabsChanged = true;
if(deletedTabName.length > 0){
Util.showNotify({title: 'Map removed', text: deletedTabName + ' deleted', type: 'warning'});
}
}
}
}
@@ -2001,12 +1593,13 @@ define([
var tabOptions = {
id: parseInt( data.config.id ),
tabClasses: [config.mapTabClass, Util.getInfoForMap( data.config.type.name, 'classTab') ],
type: data.config.type,
contentClasses: [config.mapTabContentClass],
active: false,
icon: data.config.icon,
name: data.config.name,
right: false
right: false,
updated: data.config.updated
};
var newTabElements = tabMapElement.addTab(tabOptions);
@@ -2017,12 +1610,22 @@ define([
// load all the structure elements for the new tab
newTabElements.contentElement.initContentStructure();
Util.showNotify({title: 'Map added', text: data.config.name + ' added', type: 'success'});
tabsChanged = true;
Util.showNotify({title: 'Map added', text: data.config.name + ' added', type: 'success'});
}
});
// get current active map
var activeMapId = Util.getMapModule().getActiveMap().data('id');
var activeMapData = getMapDataById(activeMapId);
if(activeMapData !== false){
// update active map with new mapData
var currentTabContentElement = $('#' + config.mapTabIdPrefix + activeMapId);
$( currentTabContentElement).loadMap( activeMapData, {} );
}
}else{
// create Tab Element
@@ -2032,7 +1635,7 @@ define([
barId: config.mapTabBarId
};
tabMapElement = getTabElementh(options);
tabMapElement = getTabElement(options);
// add new tab for each map
for(var j = 0; j < tempMapData.length; j++){
@@ -2046,12 +1649,13 @@ define([
var tabOptions = {
id: parseInt( data.config.id ),
tabClasses: [config.mapTabClass, Util.getInfoForMap( data.config.type.name, 'classTab') ],
type: data.config.type,
contentClasses: [config.mapTabContentClass],
active: activeTab,
icon: data.config.icon,
name: data.config.name,
right: false
right: false,
updated: data.config.updated
};
tabMapElement.addTab(tabOptions);
@@ -2061,7 +1665,9 @@ define([
// add "add" button
var tabAddOptions = {
id: 0,
tabClasses: [config.mapTabClass, Util.getInfoForMap( 'standard', 'classTab') ],
type: {
classTab: Util.getInfoForMap( 'standard', 'classTab')
},
contentClasses: [config.mapTabContentClass],
icon: 'fa-plus',
name: 'add',
@@ -2085,7 +1691,7 @@ define([
tabContentElements.initContentStructure();
// load first map i in first tab content container
$( tabContentElements[0] ).loadMap( tempMapData[0] );
$( tabContentElements[0] ).loadMap( tempMapData[0], {showAnimation: true} );
}
if(tabsChanged === true){
@@ -2117,7 +1723,7 @@ define([
// load map
var currentTabContentElement = $('#' + config.mapTabIdPrefix + mapId);
$( currentTabContentElement).loadMap( tabMapData );
$( currentTabContentElement).loadMap( tabMapData, {showAnimation: true} );
// "wake up" scrollbar for map and get previous state back
var scrollableElement = currentTabContentElement.find('.' + config.mapWrapperClass);

View File

@@ -50,6 +50,9 @@ define([
dialogNavigationClass: 'pf-dialog-navigation-list', // class for dialog navigation bar
dialogNavigationListItemClass: 'pf-dialog-navigation-list-item', // class for map manual li main navigation elements
// map dialog
newMapDialogId: 'pf-map-new-dialog', // id for edit/update map dialog
// system effect dialog
systemEffectDialogWrapperClass: 'pf-system-effect-dialog-wrapper', // class for system effect dialog
@@ -267,6 +270,17 @@ define([
).on('click', function(){
$(document).triggerMenuEvent('ShowTaskManager');
})
).append(
$('<a>', {
class: 'list-group-item',
href: '#'
}).html('&nbsp;&nbsp;Delete').prepend(
$('<i>',{
class: 'fa fa-eraser fa-fw'
})
).on('click', function(){
$(document).triggerMenuEvent('DeleteMap');
})
)
);
};
@@ -437,6 +451,20 @@ define([
return false;
});
$(document).on('pf:menuDeleteMap', function(e){
// delete current active map
var mapData = false;
var activeMap = Util.getMapModule().getActiveMap();
if(activeMap){
mapData = activeMap.getMapData(true);
}
showDeleteMapDialog(mapData);
return false;
});
$(document).on('pf:menuShowTaskManager', function(e, data){
// show log dialog
Logging.showDialog();
@@ -554,65 +582,126 @@ define([
};
/**
* shows the add new map dialog
* shows the add/edit map dialog
*/
var showNewMapDialog = function(mapData){
var formData = {};
requirejs(['text!templates/modules/map_dialog.html', 'mustache'], function(template, Mustache) {
// check if dialog is already open
var mapInfoDialogElement = $('#' + config.newMapDialogId);
if(!mapInfoDialogElement.is(':visible')){
var data = {
id: Init.newMapDialogId,
scope: Util.getMapScopes(),
type: Util.getMapTypes(),
icon: Util.getMapIcons(),
formData: formData
};
console.log(data);
var content = Mustache.render(template, data);
requirejs(['text!templates/modules/map_dialog.html', 'mustache'], function(template, Mustache) {
var dialogTitle = 'New map';
var dialogSaveButton = 'add map';
if(mapData !== false){
dialogTitle = 'Edit map';
dialogSaveButton = 'save map';
var data = {
id: config.newMapDialogId,
scope: Util.getMapScopes(),
type: Util.getMapTypes(),
icon: Util.getMapIcons(),
formData: formData
};
content = $(content);
content.find('select[name="icon"]').val( mapData.config.icon );
content.find('input[name="name"]').val( mapData.config.name );
content.find('select[name="scope"]').val( mapData.config.scope );
content.find('select[name="type"]').val( mapData.config.type );
}
var content = Mustache.render(template, data);
var dialogTitle = 'Create new map';
var dialogSaveButton = 'add map';
if(mapData !== false){
dialogTitle = 'Edit map';
dialogSaveButton = 'save map';
content = $(content);
content.find('input[name="id"]').val( mapData.config.id );
content.find('select[name="icon"]').val( mapData.config.icon );
content.find('input[name="name"]').val( mapData.config.name );
content.find('select[name="scopeId"]').val( mapData.config.scope.id );
content.find('select[name="typeId"]').val( mapData.config.type.id );
}
var mapInfoDialog = bootbox.dialog({
title: dialogTitle,
message: content,
buttons: {
close: {
label: 'cancel',
className: 'btn-default'
},
success: {
label: '<i class="fa fa-code-fork fa-fw"></i>' + dialogSaveButton,
className: 'btn-primary',
callback: function() {
var mapInfoDialog = bootbox.dialog({
title: dialogTitle,
message: content,
buttons: {
close: {
label: 'cancel',
className: 'btn-default'
},
success: {
label: '<i class="fa fa-code-fork fa-fw"></i>' + dialogSaveButton,
className: 'btn-primary',
callback: function() {
// get form Values
var form = $('#' + config.newMapDialogId).find('form');
var newMapData = form.getFormValues();
// get form Values
var form = $('#' + config.newMapDialogId).find('form');
// TODO save map data
// validate form
form.validator('validate');
// check weather the form is valid
var formValid = form.isValidForm();
if(formValid === true){
var newMapData = {mapData: form.getFormValues()};
$.ajax({
type: 'POST',
url: Init.path.saveMap,
data: newMapData,
dataType: 'json'
}).done(function(data){
Util.showNotify({title: dialogTitle, text: 'Map: ' + data.name, type: 'success'});
$(mapInfoDialog).modal('hide');
$(document).trigger('pf:closeMenu', [{}]);
}).fail(function( jqXHR, status, error) {
var reason = status + ' ' + error;
Util.showNotify({title: jqXHR.status + ': saveMap', text: reason, type: 'warning'});
$(document).setProgramStatus('problem');
});
}
return false;
}
}
}
}
});
});
});
}
};
/**
* shows the delete map Dialog
* @param mapElement
*/
var showDeleteMapDialog = function(mapData){
var mapName = mapData.config.name;
var mapDeleteDialog = bootbox.confirm('Delete map "' + mapName + '"?', function(result){
if(result){
var data = {mapData: mapData.config};
$.ajax({
type: 'POST',
url: Init.path.deleteMap,
data: data,
dataType: 'json'
}).done(function(data){
Util.showNotify({title: 'Map deleted', text: 'Map: ' + mapName, type: 'success'});
$(mapDeleteDialog).modal('hide');
}).fail(function( jqXHR, status, error) {
var reason = status + ' ' + error;
Util.showNotify({title: jqXHR.status + ': deleteMap', text: reason, type: 'warning'});
$(document).setProgramStatus('problem');
});
return false;
}
});
};
/**
* shows the map manual modal dialog
@@ -925,6 +1014,15 @@ define([
// change status, on status changed
if(iconClass !== false){
// "problem" and "offline" always have priority -> ignore/clear interval
if(
status === 'problem' ||
status === 'offline'
){
clearInterval(programStatusInterval);
programStatusInterval = false;
}
if(! statusElement.hasClass(textClass) ){
if(! programStatusInterval){
@@ -948,7 +1046,8 @@ define([
});
}
programStatusCounter--;
// decrement counter
programStatusCounter -= 1000;
if(programStatusCounter <= 0){
clearInterval(programStatusInterval);

76
js/app/ui/form_element.js Normal file
View File

@@ -0,0 +1,76 @@
/**
* form elements
*/
define([
'jquery',
'app/init',
'app/util'
], function($, Init, Util) {
"use strict";
/**
* init a select element as an ajax based "select2" object
* @param options
*/
$.fn.initSystemSelect = function(options){
var selectElement = $(this);
$.when(
selectElement.select2({
ajax: {
url: function(params){
// add params to URL
return Init.path.searchSystem + '/' + params.term;
},
dataType: 'json',
delay: 250,
timeout: 5000,
cache: true,
data: function(params) {
// no url params here
return;
},
processResults: function(data) {
// parse the results into the format expected by Select2.
return {
results: data.map( function(item){
var secClass = Util.getSecurityClassForSystem(item.security);
var systemSecurity = ' <span style="float: right;" class="' + secClass + '">';
systemSecurity += '(' + item.security + ')</span>';
return {
id: item[options.key],
text: item.name + systemSecurity
};
})
};
},
error: function (jqXHR, status, error) {
if(!Util.isXHRAborted){
// close select
selectElement.select2('destroy');
var reason = status + ' ' + jqXHR.status + ': ' + error;
Util.emergencyShutdown(reason);
}
}
},
minimumInputLength: 2,
placeholder: 'Jita',
allowClear: true
})
).done(function(){
// open select
selectElement.select2('open');
});
};
});

View File

@@ -43,6 +43,16 @@ define([
var countSystems = mapData.data.systems.length;
var countConnections = mapData.data.connections.length;
// map type
var mapTypes = Util.getMapTypes();
var mapTypeName = '';
var mapTypeClass = '';
for(var i = 0; i < mapTypes.length; i++){
if(mapTypes[i].id === mapData.config.type.id){
mapTypeName = mapTypes[i].name;
mapTypeClass = mapTypes[i].class;
}
}
var dlElementLeft = $('<dl>', {
class: 'dl-horizontal',
@@ -63,8 +73,8 @@ define([
$('<dt>').text( 'Type' )
).append(
$('<dd>', {
class: Util.getInfoForMap( mapData.config.type, 'class')
}).text( Util.getInfoForMap( mapData.config.type, 'label') )
class: mapTypeClass
}).text( mapTypeName )
);
mapElement.append(dlElementLeft);
@@ -129,7 +139,7 @@ define([
}
// type
tempData.push(tempSystemData.type);
tempData.push(Util.getSystemTypeInfo(tempSystemData.type.id, 'name'));
// name
tempData.push( tempSystemData.name );
@@ -142,7 +152,7 @@ define([
}
// status
var systemStatusClass = Util.getStatusInfoForSystem(tempSystemData.status, 'class');
var systemStatusClass = Util.getStatusInfoForSystem(tempSystemData.status.id, 'class');
if(systemStatusClass !== ''){
tempData.push( '<i class="fa fa fa-square-o fa-lg fa-fw ' + systemStatusClass + '"></i>' );
}else{
@@ -166,14 +176,14 @@ define([
}
// locked
if(tempSystemData.locked === true){
if(tempSystemData.locked === 1){
tempData.push( '<i class="fa fa-lock fa-lg fa-fw"></i>' );
}else{
tempData.push( '' );
}
// rally point
if(tempSystemData.rally === true){
if(tempSystemData.rally === 1){
tempData.push( '<i class="fa fa-users fa-lg fa-fw"></i>' );
}else{
tempData.push( '' );
@@ -274,7 +284,7 @@ define([
var tempConData = [];
tempConData.push( Util.getScopeInfoForMap( tempConnectionData.scope, 'label') );
tempConData.push( Util.getScopeInfoForConnection( tempConnectionData.scope, 'label') );
// source system name
tempConData.push( tempConnectionData.sourceName );

211
js/app/ui/system_graph.js Normal file
View File

@@ -0,0 +1,211 @@
/**
* System graph module
*/
define([
'jquery',
'app/init',
'app/util',
'morris'
], function($, Init, Util, Morris) {
'use strict';
var config = {
// module info
moduleClass: 'pf-module', // class for each module
// system graph module
systemGraphModuleClass: 'pf-system-graph-module', // class for this module
systemGraphClass: 'pf-system-graph', // class for each graph
// system graph labels
systemGraphLabels: {
jumps: {
headline: 'Jumps',
units: 'jumps',
ykeys: ['y'],
labels: ['jumps'],
lineColors: ['#375959'],
pointFillColors: ['#477372']
},
shipKills: {
headline: 'Ship/POD Kills',
units: 'kills',
ykeys: ['y', 'z'],
labels: ['Ship kills', 'POD kills'],
lineColors: ['#375959', '#477372'],
pointFillColors: ['#477372', '#568a89']
},
factionKills: {
headline: 'NPC Kills',
units: 'kills',
ykeys: ['y'],
labels: ['kills'],
lineColors: ['#375959'],
pointFillColors: ['#477372']
}
}
};
/**
* get info for a given graph key
* @param graphKey
* @param option
* @returns {string}
*/
var getInfoForGraph = function(graphKey, option){
var info = '';
if(config.systemGraphLabels.hasOwnProperty(graphKey)){
info = config.systemGraphLabels[graphKey][option];
}
return info;
};
/**
* init Morris Graph
* @param graphElement
* @param graphKey
* @param graphData
*/
var initGraph = function(graphElement, graphKey, graphData){
if(graphData.length > 0){
var labelYFormat = function(y){
return Math.round(y);
};
Morris.Area({
element: graphElement,
data: graphData,
xkey: 'x',
ykeys: getInfoForGraph(graphKey, 'ykeys'),
labels: getInfoForGraph(graphKey, 'labels'),
parseTime: false,
ymin: 0,
yLabelFormat: labelYFormat,
padding: 10,
hideHover: true,
pointSize: 3,
lineColors: getInfoForGraph(graphKey, 'lineColors'),
pointFillColors: getInfoForGraph(graphKey, 'pointFillColors'),
pointStrokeColors: ['#141413'],
lineWidth: 2,
grid: true,
gridStrokeWidth: 0.3,
gridTextSize: 9,
gridTextFamily: 'Oxygen Bold',
gridTextColor: '#63676a',
behaveLikeLine: false,
goals: [],
goalLineColors: ['#5cb85c'],
smooth: true,
fillOpacity: 0.2,
resize: true,
redraw: true
});
}
};
/**
* draw graph module
* @param parentElement
* @param systemData
*/
var drawModule = function(parentElement, systemData){
// graph data is available for k-space systems
if(systemData.type.id === 2){
var requestData = {
systemIds: [systemData.systemId]
};
$.ajax({
type: 'POST',
url: Init.path.getSystemGraphData,
data: requestData,
dataType: 'json'
}).done(function(systemGraphsData){
// create new (hidden) module container
var moduleElement = $('<div>', {
class: [config.moduleClass, config.systemGraphModuleClass].join(' '),
css: {opacity: 0}
});
parentElement.append(moduleElement);
// row element
var rowElement = $('<div>', {
class: 'row'
});
moduleElement.append(rowElement);
$.each(systemGraphsData, function(systemId, graphsData){
$.each(graphsData, function(graphKey, graphData){
var colElement = $('<div>', {
class: ['col-xs-12', 'col-sm-6', 'col-md-4'].join(' ')
});
var headlineElement = $('<h5>').text( getInfoForGraph(graphKey, 'headline') );
colElement.append(headlineElement);
var graphElement = $('<div>', {
class: config.systemGraphClass
});
colElement.append(graphElement);
rowElement.append(colElement);
initGraph(graphElement, graphKey, graphData);
});
});
moduleElement.append($('<div>', {
css: {'clear': 'both'}
}));
// show module
moduleElement.velocity('stop').velocity('transition.slideUpIn', {
queue: false,
duration: Init.animationSpeed.mapModule
});
}).fail(function( jqXHR, status, error) {
var reason = status + ' ' + error;
Util.showNotify({title: jqXHR.status + ': System graph data', text: reason, type: 'warning'});
$(document).setProgramStatus('problem');
});
}
};
/**
* main module load function
* @param systemData
*/
$.fn.drawSystemGraphModule = function(systemData){
var parentElement = $(this);
// check if module already exists
var moduleElement = parentElement.find('.' + config.systemGraphModuleClass);
if(moduleElement.length > 0){
moduleElement.velocity('stop').velocity('reverse', {
complete: function(tempElement){
$(tempElement).remove();
drawModule(parentElement, systemData);
}
});
}else{
drawModule(parentElement, systemData);
}
};
});

137
js/app/ui/system_info.js Normal file
View File

@@ -0,0 +1,137 @@
/**
* System info module
*/
define([
'jquery',
'app/init',
'app/util',
'app/render'
], function($, Init, Util, Render) {
"use strict";
var config = {
// module info
moduleClass: 'pf-module', // class for each module
// system info module
systemInfoModuleClass: 'pf-system-info-module', // module wrapper
systemInfoTableClass: 'pf-system-info-table' // class for system info table
};
/**
*
* @param parentElement
* @param systemInfoData
*/
var drawModule = function(parentElement, systemData){
// create new module container
var moduleElement = $('<div>', {
class: [config.moduleClass, config.systemInfoModuleClass].join(' '),
css: {opacity: 0}
});
parentElement.prepend(moduleElement);
var effectName = Util.getEffectInfoForSystem(systemData.effect, 'name');
var effectClass = Util.getEffectInfoForSystem(systemData.effect, 'class');
// systemInfo template config
var moduleConfig = {
name: 'modules/system_info',
position: moduleElement,
link: 'append',
functions: {
after: function(){
// init tooltips
var tooltipElements = $('.' + config.systemInfoModuleClass + ' [data-toggle="tooltip"]');
tooltipElements.tooltip();
// init system effect popover
var systemEffectData = Util.getSystemEffectData( systemData.security, systemData.effect);
if(systemEffectData !== false){
var systemInfoTable = $(moduleElement).find('.' + config.systemInfoTableClass);
// transform data into table
var systemEffectTable = Util.getSystemEffectTable( systemEffectData );
systemInfoTable.popover({
html: true,
trigger: 'hover',
placement: 'top',
delay: 200,
title: 'System effects',
content: systemEffectTable
});
}
showModule(moduleElement);
}
}
};
// add security class for statics
if(systemData.static){
$.each(systemData.static, function(i, staticWH){
system['static'][i]['class'] = Util.getSecurityClassForSystem( staticWH.security );
});
}
var moduleData = {
system: systemData,
tableClass: config.systemInfoTableClass,
systemTypeName: Util.getSystemTypeInfo(systemData.type.id, 'name'),
securityClass: Util.getSecurityClassForSystem( systemData.security ),
trueSec: systemData.trueSec.toFixed(1),
trueSecClass: Util.getTrueSecClassForSystem( systemData.trueSec ),
effectName: effectName,
effectClass: effectClass
};
Render.showModule(moduleConfig, moduleData);
};
/**
* show system info module with animation
* @param moduleElement
*/
var showModule = function(moduleElement){
moduleElement.velocity('stop').velocity('transition.slideUpIn', {
queue: false,
duration: Init.animationSpeed.mapModule
});
};
/**
* update system info module
* @param systemInfoData
*/
$.fn.drawSystemInfoModule = function(systemData){
var parentElement = $(this);
// check if module already exists
var moduleElement = parentElement.find('.' + config.systemInfoModuleClass);
if(moduleElement.length > 0){
moduleElement.velocity('stop').velocity('reverse', {
complete: function(tempElement){
$(tempElement).remove();
drawModule(parentElement, systemData);
}
});
}else{
drawModule(parentElement, systemData);
}
};
});

View File

@@ -0,0 +1,291 @@
define([
'jquery',
'app/init',
'app/util',
'morris'
], function($, Init, Util, Morris) {
"use strict";
var config = {
// module info
moduleClass: 'pf-module', // class for each module
// system killboard module
systemKillboardModuleClass: 'pf-system-killboard-module', // module wrapper
systemKillboardGraphsClass: 'pf-system-killboard-graphs', // wrapper for graph
systemKillboardGraphKillsClass: 'pf-system-killboard-graph-kills' // class for system kill graph
};
var cache = {
systemKillsGraphData: {} // data for system kills info graph
};
/**
* get label element with given content
* @param text
* @returns {*|XMLList}
*/
var getLabel = function(text, options){
var label = $('<span>', {
class: ['label', options.type, options.align].join(' ')
}).text( text );
return label;
};
/**
* updates the system info graph
* @param systemId
*/
$.fn.updateSystemInfoGraphs = function(systemId){
var parentElement = $(this);
var graphElement = $('<div>', {
class: config.systemKillboardGraphKillsClass
});
parentElement.append(graphElement);
var showHours = 24;
var maxKillmailCount = 200; // limited by API
var labelOptions = {
align: 'center-block'
};
// private function draws a "system kills" graph
var drawGraph = function(data){
var tableData = data.tableData;
var label = '';
if(data.count === 0){
labelOptions.type = 'label-success';
label = getLabel( 'No kills found within 24h', labelOptions );
graphElement.prepend( label );
// reduce height
graphElement.velocity({
height: '30px'
},{
duration: Init.animationSpeed.mapModule
});
return;
}
var labelYFormat = function(y){
return Math.round(y);
};
// draw chart
Morris.Bar({
element: graphElement,
resize: true,
grid: true,
gridStrokeWidth: 0.3,
gridTextSize: 9,
gridTextColor: '#63676a',
gridTextFamily: 'Oxygen Bold',
hideHover: true,
data: tableData,
xkey: 'label',
ykeys: ['kills'],
labels: ['Kills'],
yLabelFormat: labelYFormat,
xLabelMargin: 10,
padding: 10,
parseTime: false,
barOpacity: 0.8,
barRadius: [2, 2, 0, 0],
barSizeRatio: 0.5,
barGap: 3,
barColors: function (row, series, type) {
if (type === 'bar') {
// highlight last row -> recent kills found
if(this.xmax === row.x){
return '#c2760c';
}
}
return '#375959';
}
});
// show hint for recent kills
if(tableData[tableData.length - 1].kills > 0){
labelOptions.type = 'label-warning';
label = getLabel( tableData[tableData.length - 1].kills + ' kills within the last hour!', labelOptions );
graphElement.prepend( label );
}
};
// 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);
}
// get current server time
var serverDate= Util.getServerTime();
// 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 = Init.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
if(chartData[timeDiffHour]){
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();
// fill cache
cache.systemKillsGraphData[cacheKey] = {};
cache.systemKillsGraphData[cacheKey].tableData = chartData;
cache.systemKillsGraphData[cacheKey].count = kbData.length;
drawGraph( cache.systemKillsGraphData[cacheKey] );
parentElement.hideLoadingAnimation();
}).error(function(e){
Util.showNotify({title: e.status + ': Get system kills', text: 'Loading failed', type: 'error'});
});
}
};
/**
* get module Element
* @param systemData
* @returns {*|HTMLElement}
*/
var getModule = function(parentElement, systemData){
// create new module container
var moduleElement = $('<div>', {
class: [config.moduleClass, config.systemKillboardModuleClass].join(' '),
css: {opacity: 0}
});
// headline
var headline = $('<h5>', {
text: 'Killboard'
});
// graph element
var graphElement = $('<div>', {
class: config.systemKillboardGraphsClass
});
moduleElement.append(headline, graphElement);
parentElement.append(moduleElement);
// update graph
graphElement.updateSystemInfoGraphs(systemData.systemId);
return moduleElement;
};
/**
* main module load function
* @param systemData
*/
$.fn.drawSystemKillboardModule = function(systemData){
var parentElement = $(this);
// show route module
var showModule = function(moduleElement){
if(moduleElement){
moduleElement.velocity('stop').velocity('transition.slideUpIn', {
queue: false,
duration: Init.animationSpeed.mapModule
});
}
};
// check if module already exists
var moduleElement = parentElement.find('.' + config.systemKillboardModuleClass);
if(moduleElement.length > 0){
moduleElement.velocity('stop').velocity('reverse', {
complete: function(tempElement){
$(tempElement).remove();
moduleElement = getModule(parentElement, systemData);
showModule(moduleElement);
}
});
}else{
moduleElement = getModule(parentElement, systemData);
showModule(moduleElement);
}
};
});

383
js/app/ui/system_route.js Normal file
View File

@@ -0,0 +1,383 @@
/**
* system route module
*/
define([
'jquery',
'app/init',
'app/util',
'bootbox'
], function($, Init, Util, bootbox) {
'use strict';
var config = {
// module info
moduleClass: 'pf-module', // class for each module
// system route module
systemRouteModuleClass: 'pf-system-route-module', // class for this module
// tables
tableToolsClass: 'pf-table-tools', // table toolbar
systemSecurityClassPrefix: 'pf-system-security-', // prefix class for system security level (color)
// dialog
routeDialogId: 'pf-route-dialog', // id for route dialog
systemDialogSelectClass: 'pf-system-dialog-select', // class for system select Element
systemInfoRoutesTableRowPrefix: 'pf-system-info-routes-row-', // prefix class for a row in the route table
systemInfoRoutesTableClass: 'pf-system-route-table' // class for route tables
};
var cache = {
systemRoutes: {} // jump information between solar systems
};
/**
* callback function, adds new row to a dataTable with jump information for a route
* @param context
* @param routeData
*/
var callbackAddRouteRow = function(context, routeData){
// format routeData
var rowData = formatRouteData(context, routeData);
cache.systemRoutes[context.cacheKey] = rowData;
// add new row
context.dataTable.row.add( cache.systemRoutes[context.cacheKey] ).draw().nodes().to$().addClass( context.rowClass );
// init tooltips for each jump system
var tooltipElements = context.moduleElement.find('.' + context.rowClass + ' [data-toggle="tooltip"]');
$(tooltipElements).tooltip();
};
/**
* show route dialog. User can search for systems and jump-info for each system is added to a data table
* @param dialogData
*/
var showFindRouteDialog = function(dialogData){
var data = {
id: config.routeDialogId,
selectClass: config.systemDialogSelectClass,
systemFrom: dialogData.systemFrom
};
requirejs(['text!templates/dialog/route.html', 'mustache'], function(template, Mustache) {
var content = Mustache.render(template, data);
// disable modal focus event -> otherwise select2 is not working! -> quick fix
$.fn.modal.Constructor.prototype.enforceFocus = function() {};
var findRouteDialog = bootbox.dialog({
title: 'Search route',
message: content,
buttons: {
close: {
label: 'cancel',
className: 'btn-default',
callback: function(){
$(findRouteDialog).modal('hide');
}
},
success: {
label: '<i class="fa fa-fw fa-search"></i>&nbsp;search route',
className: 'btn-primary',
callback: function () {
// add new route to route table
// get form Values
var form = $('#' + config.routeDialogId).find('form');
var routeDialogData = $(form).getFormValues();
// validate form
form.validator('validate');
// check weather the form is valid
var formValid = form.isValidForm();
if(formValid === false){
// don't close dialog
return false;
}
// get route Data
var requestData = {
systemFrom: dialogData.systemFrom,
systemTo: routeDialogData.systemTo
};
// data passed into callback
var contextData = {
moduleElement: dialogData.moduleElement,
systemTo: routeDialogData.systemTo,
dataTable: dialogData.dataTable,
rowClass: config.systemInfoRoutesTableRowPrefix + dialogData.dataTable.rows().data().length,
cacheKey: dialogData.systemFrom + '_' + routeDialogData.systemTo
};
getRouteData(requestData, contextData, callbackAddRouteRow);
}
}
}
});
// init dialog
findRouteDialog.on('shown.bs.modal', function(e) {
var modalContent = $('#' + config.routeDialogId);
// init system select live search
var selectElement = modalContent.find('.' + config.systemDialogSelectClass);
selectElement.initSystemSelect({key: 'name'});
});
});
};
/**
* requests route data from eveCentral API and execute callback
* @param systemFrom
* @param systemTo
* @param callback
*/
var getRouteData = function(requestData, contextData, callback){
// get route from API
var baseUrl = Init.url.eveCentral + 'route/from/';
var url = baseUrl + requestData.systemFrom + '/to/' + requestData.systemTo;
$.ajax({
url: url,
dataType: 'json',
context: contextData
}).done(function(routeData){
// execute callback
callback(this, routeData);
});
};
/**
* format route data from API request into dataTable row format
* @param context
* @param routeData
* @returns {*[]}
*/
var formatRouteData = function(context, routeData){
// add row Data
var rowData = [context.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();
var tempSystemSec = systemSec;
if(tempSystemSec < 0){
tempSystemSec = '0-0';
}
systemSecClass += tempSystemSec.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(' ') );
return rowData;
};
var getModule = function(systemData){
var moduleElement = null;
// load trade routes for k-space systems
if(systemData.type.id === 2){
// create new module container
moduleElement = $('<div>', {
class: [config.moduleClass, config.systemRouteModuleClass].join(' ')
});
// headline
var headline = $('<h5>', {
class: 'pull-left',
text: 'Routes'
});
moduleElement.append(headline);
var systemFrom = systemData.name;
var systemsTo = ['Jita', 'Amarr', 'Rens', 'Dodixie'];
// crate new route table
var table = $('<table>', {
class: ['compact', 'stripe', 'order-column', 'row-border', config.systemInfoRoutesTableClass].join(' ')
});
moduleElement.append( $(table) );
// init empty table
var routesTable = table.DataTable( {
paging: false,
ordering: true,
order: [ 1, 'asc' ],
info: false,
searching: false,
hover: false,
autoWidth: false,
columnDefs: [
{
targets: 0,
orderable: true,
title: 'system&nbsp;&nbsp;&nbsp;'
},{
targets: 1,
orderable: true,
title: 'jumps&nbsp;&nbsp;&nbsp',
width: '40px',
class: 'text-right'
},{
targets: 2,
orderable: false,
title: 'route'
}
],
data: [] // will be added dynamic
});
// add toolbar buttons for table -------------------------------------
var tableToolbar = $('<div>', {
class: [config.tableToolsClass, 'pull-right'].join(' ')
}).append(
$('<button>', {
class: ['btn', 'btn-primary', 'btn-sm'].join(' '),
text: ' search route',
type: 'button'
}).on('click', function(e){
// show "find route" dialog
var dialogData = {
moduleElement: moduleElement,
systemFrom: systemFrom,
dataTable: routesTable
};
showFindRouteDialog(dialogData);
}).prepend(
$('<i>', {
class: ['fa', 'fa-search', 'fa-fw'].join(' ')
})
)
);
headline.after(tableToolbar);
// fill routesTable with data -------------------------------------------
for(var i = 0; i < systemsTo.length; i++){
var systemTo = systemsTo[i];
if(systemFrom !== systemTo){
var cacheKey = systemFrom + '_' + systemTo;
// row class
var rowClass = config.systemInfoRoutesTableRowPrefix + i;
if(cache.systemRoutes.hasOwnProperty(cacheKey)){
// add new row from cache
routesTable.row.add( cache.systemRoutes[cacheKey] ).draw().nodes().to$().addClass( rowClass );
// init tooltips for each jump system
var tooltipElements = moduleElement.find('.' + rowClass + ' [data-toggle="tooltip"]');
$(tooltipElements).tooltip();
}else{
// get route Data
var requestData = {
systemFrom: systemFrom,
systemTo: systemTo
};
// data passed into callback
var contextData = {
moduleElement: moduleElement,
rowClass: rowClass,
systemTo: systemTo,
dataTable: routesTable,
cacheKey: cacheKey
};
getRouteData(requestData, contextData, callbackAddRouteRow);
}
}
}
}
return moduleElement;
};
/**
* updates an dom element with the system route module
* @param systemData
*/
$.fn.drawSystemRouteModule = function(systemData){
var parentElement = $(this);
// show route module
var showModule = function(moduleElement){
if(moduleElement){
moduleElement.css({ opacity: 0 });
parentElement.append(moduleElement);
moduleElement.velocity('stop').velocity('transition.slideUpIn', {
queue: false,
duration: Init.animationSpeed.mapModule
});
}
};
// check if module already exists
var moduleElement = parentElement.find('.' + config.systemRouteModuleClass);
if(moduleElement.length > 0){
moduleElement.velocity('stop').velocity('reverse', {
complete: function(tempElement){
$(tempElement).remove();
moduleElement = getModule(systemData);
showModule(moduleElement);
}
});
}else{
moduleElement = getModule(systemData);
showModule(moduleElement);
}
};
});

View File

View File

@@ -37,6 +37,10 @@ define([
class: 'fa-plane',
label: 'plane',
unicode: '&#xf072;'
},{
class: 'fa-globe',
label: 'globe',
unicode: '&#xf0ac;'
},{
class: 'fa-rocket',
label: 'rocket',
@@ -296,6 +300,22 @@ define([
return logInfo;
};
/**
* Returns true if the user hit Esc or navigated away from the
* current page before an AJAX call was done. (The response
* headers will be null or empty, depending on the browser.)
*
* NOTE: this function is only meaningful when called from
* inside an AJAX "error" callback!
* @param jqXHR XMLHttpRequest instance
* @returns {boolean}
*/
var isXHRAborted = function(jqXHR){
return !jqXHR.getAllResponseHeaders();
};
// ==================================================================================================
// ==================================================================================================
// ==================================================================================================
/**
@@ -441,6 +461,26 @@ define([
return scopeInfo;
};
/**
* get system type information
* @returns {Array}
*/
var getSystemTypeInfo = function(systemTypeId, option){
var systemTypeInfo = '';
$.each(Init.systemType, function(prop, data){
if(systemTypeId === data.id){
systemTypeInfo = data[option];
return;
}
});
return systemTypeInfo;
};
/**
* get some system info for a given info string (e.g. rally class)
* @param info
@@ -580,7 +620,17 @@ define([
var statusInfo = '';
if( Init.systemStatus.hasOwnProperty(status) ){
// search by status string
statusInfo = Init.systemStatus[status][option];
}else{
// saarch by statusID
$.each(Init.systemStatus, function(prop, data){
if(status === data.id){
statusInfo = data[option];
return;
}
});
}
return statusInfo;
@@ -756,21 +806,6 @@ define([
};
/**
* map backend systemData for frontend
* @param systemData
* @returns {Array}
*/
var mapSystemData = function(systemData){
var data = [];
for(var i = 0; i < systemData.length; i++){
}
return data;
};
return {
getServerTime: getServerTime,
timeStart: timeStart,
@@ -778,6 +813,7 @@ define([
log: log,
showNotify: showNotify,
getLogInfo: getLogInfo,
isXHRAborted: isXHRAborted,
getMapModule: getMapModule,
getMapIcons: getMapIcons,
getMapTypes: getMapTypes,
@@ -785,6 +821,7 @@ define([
getMapScopes: getMapScopes,
getScopeInfoForMap: getScopeInfoForMap,
getScopeInfoForConnection: getScopeInfoForConnection,
getSystemTypeInfo: getSystemTypeInfo,
getInfoForSystem: getInfoForSystem,
getEffectInfoForSystem: getEffectInfoForSystem,
getSystemEffectData: getSystemEffectData,

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

View File

@@ -0,0 +1,36 @@
<div class="row" id="{{id}}">
<div class="col-sm-12">
<form role="form" class="form-horizontal">
<div class="row">
<div class="col-sm-5">
<div class="form-group">
<label class="col-sm-3 control-label" for="form_system">From</label>
<div class="col-sm-9">
<div class=" pull-right">
<p class="form-control-static">
<i class="fa fa-arrow-right"></i>
</p>
</div>
<p class="form-control-static">{{systemFrom}}</p>
</div>
</div>
</div>
<div class="col-sm-7">
<div class="form-group">
<label class="col-sm-1 control-label" for="form_system">To</label>
<div class="col-sm-11">
<div class="input-group">
<label for="form_system"></label>
<select id="form_system" name="systemTo" class="form-control {{selectClass}}" data-error="Choose a valid system" required/>
<span class="help-block with-errors">Search system name</span>
</div>
</div>
</div>
</div>
</div>
</form>
</div>
</div>

View File

@@ -1,36 +1,59 @@
<div id="{{id}}">
<form class="form-horizontal">
<div class="form-group">
<label for="icon" class="col-sm-2 control-label">Icon</label>
<div class="col-sm-2">
<select style="font-family: FontAwesome" name="icon" id="icon" class="form-control">
{{#icon}}
<option value="{{class}}">{{{unicode}}}</option>
{{/icon}}
</select>
<form role="form" class="form-horizontal">
<div class="row">
<div class="col-sm-3">
<div class="form-group">
<label for="icon" class="col-sm-4 control-label">Icon</label>
<div class="col-sm-8">
<select style="font-family: FontAwesome" name="icon" id="icon" class="form-control">
{{#icon}}
<option value="{{class}}">{{{unicode}}}</option>
{{/icon}}
</select>
</div>
</div>
</div>
<label for="name" class="col-sm-1 control-label">Map</label>
<div class="col-sm-7">
<input name="name" type="text" class="form-control" id="name" value="{{formData.name}}" placeholder="Name">
<div class="col-sm-9">
<div class="form-group">
<label for="name" class="col-sm-2 control-label">Name</label>
<div class="col-sm-10">
<input name="name" type="text" class="form-control" id="name" value="{{formData.name}}" placeholder="My map" data-error="Name required" required>
<span class="help-block with-errors">Set unique map name</span>
</div>
</div>
</div>
</div>
<div class="form-group">
<label for="scope" class="col-sm-2 control-label">Scope</label>
<div class="col-sm-4">
<select name="scope" id="scope" class="form-control">
{{#scope}}
<option value="{{id}}">{{label}}</option>
{{/scope}}
</select>
<div class="row">
<div class="col-sm-6">
<div class="form-group">
<label for="scope" class="col-sm-2 control-label">Scope</label>
<div class="col-sm-10">
<select name="scopeId" id="scope" class="form-control">
{{#scope}}
<option value="{{id}}">{{label}}</option>
{{/scope}}
</select>
</div>
</div>
</div>
<label for="type" class="col-sm-1 control-label">Type</label>
<div class="col-sm-5">
<select name="type" id="type" class="form-control">
{{#type}}
<option value="{{id}}">{{label}}</option>
{{/type}}
</select>
<div class="col-sm-6">
<div class="form-group">
<label for="type" class="col-sm-2 control-label">Type</label>
<div class="col-sm-10">
<select name="typeId" id="type" class="form-control">
{{#type}}
<option value="{{id}}">{{label}}</option>
{{/type}}
</select>
</div>
</div>
</div>
</div>
<input type="hidden" name="id" value="0" />
</form>
</div>

View File

@@ -22,7 +22,7 @@
<div class="checkbox">
<label for="form_lock">
<input id="form_lock" name="locked" value="1" type="checkbox">
Lock System
Lock system
</label>
<div class="help-block with-errors"></div>
</div>
@@ -30,7 +30,7 @@
<div class="checkbox">
<label for="form_rally">
<input id="form_rally" name="rally" value="1" type="checkbox">
Rally pooint
Rally point
</label>
<div class="help-block with-errors"></div>
@@ -46,7 +46,7 @@
<div class="form-group">
<label class="col-sm-2 control-label" for="form_status">Status</label>
<div class="col-sm-6" style="min-height: 32px;">
<a class="pf-editable pf-editable-system-status" href="#" id="form_status" data-type="select" data-name="status"></a>
<a class="pf-editable pf-editable-system-status" href="#" id="form_status" data-type="select" data-name="statusId"></a>
</div>
</div>
</div>

View File

@@ -3,7 +3,7 @@
<div class="row">
<div class="col-xs-12 col-sm-7">
<ol class="breadcrumb">
<li><span data-toggle="tooltip" data-placement="bottom" title="type">{{system.type}}</span></li>
<li><span data-toggle="tooltip" data-placement="bottom" title="type">{{systemTypeName}}</span></li>
<li><a href="{{system.region.id}}" data-toggle="tooltip" data-placement="bottom" title="region">{{system.region.name}}</a></li>
<li><a href="{{system.constellation.id}}" data-toggle="tooltip" data-placement="bottom" title="constellation">{{system.constellation.name}}</a></li>
<li>
@@ -11,6 +11,12 @@
<a href="http://evemaps.dotlan.net/system/{{system.name}}" target="_blank">
<div data-toggle="tooltip" data-placement="bottom" title="dotlan" class="pf-icon pf-icon-dotlan"></div>
</a>
<a href="http://wh.pasta.gg/{{system.name}}" target="_blank">
<div data-toggle="tooltip" data-placement="bottom" title="wormhol" class="pf-icon pf-icon-wormhol-es"></div>
</a>
<a href="https://zkillboard.com/system/{{system.systemId}}" target="_blank">
<div data-toggle="tooltip" data-placement="bottom" title="zKillbaord" class="pf-icon pf-icon-zkillboard"></div>
</a>
</li>
</ol>
@@ -35,9 +41,9 @@
</thead>
<tbody>
{{#effectName}}
<tr class="pf-system-info-effect-row">
<tr>
<td>Effect</td>
<td class="text-right">{{effectName}} <i class="fa fa-square pf-system-effect {{effectClass}}"></i></td>
<td class="text-right pf-font-capitalize">{{effectName}} <i class="fa fa-fw fa-square pf-system-effect {{effectClass}}"></i></td>
</tr>
{{/effectName}}
{{#system.static}}
@@ -48,12 +54,10 @@
{{/system.static}}
<tr>
<td>Security</td>
<td class="text-right {{trueSecClass}}">{{system.trueSec}}</td>
<td class="text-right {{trueSecClass}}">{{trueSec}}</td>
</tr>
</tbody>
</table>
<div class="pf-system-info-graphs"></div>
</div>
</div>

View File

@@ -3,9 +3,25 @@
}
.pf-icon-dotlan{
background: url('../img/icons/dotlan_logo.png');
background: inline-image("#{$base-url}/icons/dotlan_logo.png");
width: 17px;
height: 17px;
opacity: 0.8;
margin: -5px 10px 0 10px;
margin: -5px 0px 0 10px;
}
.pf-icon-wormhol-es{
background: inline-image("#{$base-url}/icons/wormhol_es_logo.png");
width: 17px;
height: 17px;
opacity: 0.8;
margin: -5px 0px 0 10px;
}
.pf-icon-zkillboard{
background: inline-image("#{$base-url}/icons/zkillboard_logo.png");
width: 16px;
height: 16px;
opacity: 0.8;
margin: -5px 0px 0 10px;
}

View File

@@ -27,6 +27,28 @@ em{
}
}
.pf-font-capitalize{
text-transform: capitalize;
}
// table styles =====================================================
// table icon toolbar
.pf-table-tools{
height: 45px;
.btn:not(:last-child){
margin-right: 10px;
}
}
.pf-table-tools-action{
height: 75px;
display: none; // triggered by js
}
// full screen view of an element
/*
.pf-fullscreen{
@@ -125,7 +147,7 @@ em{
}
.pf-map-type-tab-global{
border-top: 2px solid $green;
border-top: 2px solid $teal;
}
.pf-map-type-tab-alliance{
@@ -133,7 +155,11 @@ em{
}
.pf-map-type-tab-private{
border-top: 2px solid $teal;
border-top: 2px solid $green;
}
.fa{
margin-right: 5px;
}
}
@@ -553,5 +579,9 @@ Animate the stripes
}
}
.row{
will-change: all, transform;
}

View File

@@ -302,7 +302,7 @@ $mapWidth: 2500px;
stroke-linecap: round; // line endings
path{
@include transition( stroke 0.2s ease-out);
@include transition( stroke 0.2s ease-out) ;
}
path:not(:first-child){

View File

@@ -25,20 +25,6 @@
padding: 0 5px;
}
}
// system info killboard graph ===========================================
.pf-system-info-graph-kills{
width: 100%;
height: 150px;
padding: 10px 0;
position: relative;
}
// routes table ==========================================================
.pf-system-route-table{
font-size: 10px;
}
}
@@ -104,23 +90,39 @@
}
}
}
}
// table icon toolbar
.pf-sig-table-tools{
height: 45px;
// system graph module ===================================================
.pf-system-graph-module{
.btn:not(:last-child){
margin-right: 10px;
}
.pf-system-graph{
width: 100%;
height: 100px;
}
}
// route module ==========================================================
.pf-system-route-module{
.pf-system-route-table{
width: 100%;
font-size: 10px;
}
}
// killboard module ======================================================
.pf-system-killboard-module{
.pf-system-killboard-graphs{
margin-bottom: 10px;
}
.pf-sig-table-tools-action{
height: 75px;
display: none; // triggered by js
.pf-system-killboard-graph-kills{
width: 100%;
height: 100px;
position: relative;
}
}

View File

@@ -13,7 +13,9 @@
&.txt-color-green { color: $green !important; }
&.txt-color-greenLight { color: $greenLight !important; }
&.txt-color-greenDark { color: $greenDark !important; }
&.txt-color-redLight { color: $redLight !important; }
&.txt-color-red { color: $red !important; }
&.txt-color-redDarker { color: $red-darker !important; }
&.txt-color-yellow { color: $yellow !important; }
&.txt-color-orange { color: $orange !important; }
&.txt-color-orangeDark { color: $orangeDark !important; }
@@ -25,7 +27,6 @@
&.txt-color-white { color: $white !important; }
&.txt-color-magenta { color: $magenta !important; }
&.txt-color-teal { color: $teal !important; }
&.txt-color-redLight { color: $redLight !important; }
&.txt-color-primary { color: $brand-primary !important; }
&.txt-color-success { color: $brand-success !important; }

View File

@@ -163,7 +163,7 @@ h4 {
h5 {
font-size: $font-size-h5;
font-weight: 300;
margin: 10px 0;
margin-top: 0;
line-height:normal;
}