195 lines
5.8 KiB
PHP
195 lines
5.8 KiB
PHP
<?php
|
|
|
|
namespace view\history\details;
|
|
|
|
use \generic\core\i_view;
|
|
use \api\core\Request;
|
|
use \error\core\Err;
|
|
|
|
|
|
class main extends i_view{
|
|
|
|
public $id_history;
|
|
private $timeline = [];
|
|
private $entry = [];
|
|
|
|
|
|
/* (1) Constructor
|
|
*
|
|
* @id_history<id> UID of the history entry
|
|
*
|
|
---------------------------------------------------------*/
|
|
public function __construct($id_history){
|
|
/* (1) Set attributes
|
|
---------------------------------------------------------*/
|
|
$this->id_history = $id_history;
|
|
|
|
|
|
/* (3) Get entry data
|
|
---------------------------------------------------------*/
|
|
/* (1) Request */
|
|
$entry_req = new Request('historyDefault/getById', [ 'id_entry' => $this->id_history ]);
|
|
|
|
/* (2) Get response */
|
|
$entry_res = $entry_req->dispatch();
|
|
|
|
/* (3) On success, store entry data */
|
|
if( $entry_res->error->get() == Err::Success )
|
|
$this->entry = $entry_res->get('entry');
|
|
|
|
|
|
/* (3) Get machine timeline
|
|
---------------------------------------------------------*/
|
|
/* (1) Request */
|
|
$mac_req = new Request('historyDefault/get_timeline', [ 'id_entry' => $this->id_history ]);
|
|
|
|
/* (2) Get response */
|
|
$mac_res = $mac_req->dispatch();
|
|
|
|
/* (3) On success, store timeline data */
|
|
if( $mac_res->error->get() == Err::Success )
|
|
$this->timeline = $mac_res->get('timeline');
|
|
|
|
}
|
|
|
|
|
|
|
|
/* (2) Format timeline data to svg render
|
|
*
|
|
* @timeline<array> Timeline data
|
|
*
|
|
* @return svg<String> SVG raw render
|
|
*
|
|
---------------------------------------------------------*/
|
|
public function svg(){
|
|
|
|
/* (1) Initialize variables
|
|
---------------------------------------------------------*/
|
|
/* (1) Set date() timezone */
|
|
date_default_timezone_set('Europe/Paris');
|
|
|
|
/* (2) Init. result raw svg */
|
|
$RAW = '';
|
|
|
|
/* (3) Set global range */
|
|
$c = 0;
|
|
$cl = count($this->timeline);
|
|
|
|
/* (4) Create ranges of size 15 */
|
|
$r_size = 10; // set the number of actions by line
|
|
$rl = floor( $cl / $r_size ); // calculate the number of whole lines
|
|
$lrl = $cl % $r_size; // calculate the number of actions in the last line
|
|
$y_range_diff = 100;
|
|
$total_height = ($lrl == 0 ) ? $y_range_diff*$rl : $y_range_diff*($rl+1); // total height (number of entries + last if not empty)
|
|
|
|
|
|
/* (5) Svg tag */
|
|
$RAW .= "<svg width='1000' height='$total_height' viewBox='0 0 1000 $total_height' class='timeline'>";
|
|
|
|
/* (6) Start CIRCLE */
|
|
$RAW .= "<circle cx='50' cy='50' r='6' fill='#edf0f5' class='tstart'/>";
|
|
$RAW .= "<circle cx='50' cy='50' r='4' fill='#555' class='tstart'/>";
|
|
|
|
|
|
for( $r = 0 ; $r <= $rl ; $r++ ){
|
|
|
|
// if last line is empty -> stop here
|
|
if( $r == $rl && $lrl == 0 )
|
|
break;
|
|
|
|
$y = $y_range_diff*$r + 50;
|
|
|
|
/* (2) Build barebone
|
|
---------------------------------------------------------*/
|
|
/* (1) Default TIMELINE */
|
|
if( $r < $rl ){
|
|
|
|
$RAW .= "<path d='m50 $y L900 $y' style='stroke-dasharray: 3px;' stroke='#444' class='timeline line'/>";
|
|
|
|
/* (2) Last TIMELINE (can be shorter) */
|
|
}else{ // if last line -> trace timeline until last element +1
|
|
|
|
$len = 100 + $lrl*800/$r_size;
|
|
$RAW .= "<path d='m50 $y L$len $y' style='stroke-dasharray: 3px;' stroke='#444' class='timeline line'/>";
|
|
|
|
}
|
|
|
|
|
|
|
|
/* (3) Build each action
|
|
---------------------------------------------------------*/
|
|
$el_len = ( $r == $rl ) ? $lrl : $r_size ;// number of elements on the line
|
|
for( $c = 0 ; $c < $el_len ; $c++ ){
|
|
|
|
/* (1) Display nothing if last entry and is empty */
|
|
if( !isset($this->timeline[$r*$r_size+$c]) )
|
|
break;
|
|
|
|
/* (2) Get entry data */
|
|
$entry = $this->timeline[$r*$r_size+$c];
|
|
|
|
/* (3) Get useful data */
|
|
$action_class = strtolower($entry['action_name']);
|
|
$icon_uri = '/src/static/timeline/'.$action_class.'@'.$this->get_action_color($action_class).'.svg';
|
|
$x_offset = 100 + $c*800/$r_size;
|
|
$x_img_offset = $x_offset - 5.5;
|
|
$data_user = "data-user='".$entry['id_user']."'";
|
|
$data_machine = " data-machine='".$entry['id_machine']."'";
|
|
$data_action = " data-action='".$entry['id_action']."'";
|
|
$data_time = " data-time='".date('H:i:s d/m/Y', $entry['timestamp'])."'";
|
|
$data_tags = $data_user.$data_machine.$data_action.$data_time;
|
|
|
|
/* (4) Draw entry circles */
|
|
$RAW .= "<circle cx='$x_offset' cy='$y' r='15' class='timeline around $action_class' $data_tags />";
|
|
$RAW .= "<circle cx='$x_offset' cy='$y' r='12' class='timeline center $action_class' />";
|
|
|
|
/* (5) Draw entry icon (action) */
|
|
$y_decal = $y - 5.5;
|
|
$RAW .= "\t<image x='$x_img_offset' y='$y_decal' width='12' height='12' xlink:href='$icon_uri' class='icon' />";
|
|
|
|
/* (6) Draw circle below if current user */
|
|
if( $this->entry['id_user'] == $entry['id_user'] ){
|
|
$y_decal = $y + 21;
|
|
$RAW .= "<circle cx='$x_offset' cy='$y_decal' r='2' class='timeline below $action_class' />";
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
/* (4) Close SVG
|
|
---------------------------------------------------------*/
|
|
/* (1) Stop CIRCLE */
|
|
$x_offset = 100 + $c*800/$r_size;
|
|
$RAW .= "<circle cx='$x_offset' cy='$y' r='6' fill='#edf0f5' class='tstop' />";
|
|
$RAW .= "<circle cx='$x_offset' cy='$y' r='4' fill='#555' class='tstop' />";
|
|
|
|
/* (2) Close SVG tag */
|
|
$RAW .= "</svg>";
|
|
|
|
|
|
return $RAW;
|
|
}
|
|
|
|
|
|
|
|
private function get_action_color($action_name){
|
|
|
|
return 'ffffff';
|
|
|
|
switch($action_name){
|
|
case 'start': return '2cde8b'; break;
|
|
case 'stop': return '3a3a3a'; break;
|
|
case 'lock': return 'e04343'; break;
|
|
case 'unlock': return 'af1c1c'; break;
|
|
case 'signal': return '3258d8'; break;
|
|
case 'unsignal': return '2041ab'; break;
|
|
}
|
|
|
|
return '000000';
|
|
}
|
|
|
|
} |