mirror of
https://github.com/Combodo/iTop.git
synced 2026-02-13 07:24:13 +01:00
N°4479 - Impact analysis : Display and apply filter before display impact analysis graphical
This commit is contained in:
@@ -31,7 +31,7 @@ class DisplayableNode extends GraphNode
|
|||||||
{
|
{
|
||||||
public $x;
|
public $x;
|
||||||
public $y;
|
public $y;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new node inside a graph
|
* Create a new node inside a graph
|
||||||
* @param SimpleGraph $oGraph
|
* @param SimpleGraph $oGraph
|
||||||
@@ -51,27 +51,27 @@ class DisplayableNode extends GraphNode
|
|||||||
{
|
{
|
||||||
return $this->GetProperty('icon_url', '');
|
return $this->GetProperty('icon_url', '');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function GetLabel()
|
public function GetLabel()
|
||||||
{
|
{
|
||||||
return $this->GetProperty('label', $this->sId);
|
return $this->GetProperty('label', $this->sId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function GetWidth()
|
public function GetWidth()
|
||||||
{
|
{
|
||||||
return max(32, 5*strlen($this->GetProperty('label'))); // approximation of the text's bounding box
|
return max(32, 5*strlen($this->GetProperty('label'))); // approximation of the text's bounding box
|
||||||
}
|
}
|
||||||
|
|
||||||
public function GetHeight()
|
public function GetHeight()
|
||||||
{
|
{
|
||||||
return 32;
|
return 32;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function Distance2(DisplayableNode $oNode)
|
public function Distance2(DisplayableNode $oNode)
|
||||||
{
|
{
|
||||||
$dx = $this->x - $oNode->x;
|
$dx = $this->x - $oNode->x;
|
||||||
$dy = $this->y - $oNode->y;
|
$dy = $this->y - $oNode->y;
|
||||||
|
|
||||||
$d2 = $dx*$dx + $dy*$dy - $this->GetHeight()*$this->GetHeight();
|
$d2 = $dx*$dx + $dy*$dy - $this->GetHeight()*$this->GetHeight();
|
||||||
if ($d2 < 40)
|
if ($d2 < 40)
|
||||||
{
|
{
|
||||||
@@ -79,12 +79,12 @@ class DisplayableNode extends GraphNode
|
|||||||
}
|
}
|
||||||
return $d2;
|
return $d2;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function Distance(DisplayableNode $oNode)
|
public function Distance(DisplayableNode $oNode)
|
||||||
{
|
{
|
||||||
return sqrt($this->Distance2($oNode));
|
return sqrt($this->Distance2($oNode));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function GetForRaphael($aContextDefs)
|
public function GetForRaphael($aContextDefs)
|
||||||
{
|
{
|
||||||
$aNode = array();
|
$aNode = array();
|
||||||
@@ -100,7 +100,7 @@ class DisplayableNode extends GraphNode
|
|||||||
$aNode['label'] = $this->GetLabel();
|
$aNode['label'] = $this->GetLabel();
|
||||||
$aNode['id'] = $this->GetId();
|
$aNode['id'] = $this->GetId();
|
||||||
$fOpacity = ($this->GetProperty('is_reached') ? 1 : 0.4);
|
$fOpacity = ($this->GetProperty('is_reached') ? 1 : 0.4);
|
||||||
$aNode['icon_attr'] = array('opacity' => $fOpacity);
|
$aNode['icon_attr'] = array('opacity' => $fOpacity);
|
||||||
$aNode['text_attr'] = array('opacity' => $fOpacity);
|
$aNode['text_attr'] = array('opacity' => $fOpacity);
|
||||||
$aNode['tooltip'] = $this->GetTooltip($aContextDefs);
|
$aNode['tooltip'] = $this->GetTooltip($aContextDefs);
|
||||||
$aNode['context_icons'] = array();
|
$aNode['context_icons'] = array();
|
||||||
@@ -114,7 +114,7 @@ class DisplayableNode extends GraphNode
|
|||||||
}
|
}
|
||||||
return $aNode;
|
return $aNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function RenderAsPDF(iTopPDF $oPdf, DisplayableGraph $oGraph, $fScale, $aContextDefs)
|
public function RenderAsPDF(iTopPDF $oPdf, DisplayableGraph $oGraph, $fScale, $aContextDefs)
|
||||||
{
|
{
|
||||||
$Alpha = 1.0;
|
$Alpha = 1.0;
|
||||||
@@ -170,7 +170,7 @@ class DisplayableNode extends GraphNode
|
|||||||
$oPdf->SetTextColor(0, 0, 0);
|
$oPdf->SetTextColor(0, 0, 0);
|
||||||
$oPdf->Text($this->x*$fScale - $width/2, ($this->y + 18)*$fScale, $this->GetProperty('label'));
|
$oPdf->Text($this->x*$fScale - $width/2, ($this->y + 18)*$fScale, $this->GetProperty('label'));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a "whitened" version of the icon (retaining the transparency) to be used a background for masking the underlying lines
|
* Create a "whitened" version of the icon (retaining the transparency) to be used a background for masking the underlying lines
|
||||||
* @param string $sIconFile The path to the file containing the icon
|
* @param string $sIconFile The path to the file containing the icon
|
||||||
@@ -179,35 +179,35 @@ class DisplayableNode extends GraphNode
|
|||||||
protected function CreateWhiteIcon(DisplayableGraph $oGraph, $sIconFile)
|
protected function CreateWhiteIcon(DisplayableGraph $oGraph, $sIconFile)
|
||||||
{
|
{
|
||||||
$aInfo = getimagesize($sIconFile);
|
$aInfo = getimagesize($sIconFile);
|
||||||
|
|
||||||
$im = null;
|
$im = null;
|
||||||
switch($aInfo['mime'])
|
switch($aInfo['mime'])
|
||||||
{
|
{
|
||||||
case 'image/png':
|
case 'image/png':
|
||||||
if (function_exists('imagecreatefrompng'))
|
if (function_exists('imagecreatefrompng'))
|
||||||
{
|
{
|
||||||
$im = imagecreatefrompng($sIconFile);
|
$im = imagecreatefrompng($sIconFile);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'image/gif':
|
case 'image/gif':
|
||||||
if (function_exists('imagecreatefromgif'))
|
if (function_exists('imagecreatefromgif'))
|
||||||
{
|
{
|
||||||
$im = imagecreatefromgif($sIconFile);
|
$im = imagecreatefromgif($sIconFile);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'image/jpeg':
|
case 'image/jpeg':
|
||||||
case 'image/jpg':
|
case 'image/jpg':
|
||||||
if (function_exists('imagecreatefromjpeg'))
|
if (function_exists('imagecreatefromjpeg'))
|
||||||
{
|
{
|
||||||
$im = imagecreatefromjpeg($sIconFile);
|
$im = imagecreatefromjpeg($sIconFile);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
}
|
}
|
||||||
if($im && imagefilter($im, IMG_FILTER_COLORIZE, 255, 255, 255))
|
if($im && imagefilter($im, IMG_FILTER_COLORIZE, 255, 255, 255))
|
||||||
{
|
{
|
||||||
@@ -222,17 +222,17 @@ class DisplayableNode extends GraphNode
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function GetObjectCount()
|
public function GetObjectCount()
|
||||||
{
|
{
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function GetObjectClass()
|
public function GetObjectClass()
|
||||||
{
|
{
|
||||||
return is_object($this->GetProperty('object', null)) ? get_class($this->GetProperty('object', null)) : null;
|
return is_object($this->GetProperty('object', null)) ? get_class($this->GetProperty('object', null)) : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function AddToStats($oNode, &$aNodesPerClass)
|
protected function AddToStats($oNode, &$aNodesPerClass)
|
||||||
{
|
{
|
||||||
$sClass = $oNode->GetObjectClass();
|
$sClass = $oNode->GetObjectClass();
|
||||||
@@ -256,9 +256,9 @@ class DisplayableNode extends GraphNode
|
|||||||
{
|
{
|
||||||
$aNodesPerClass[$sClass][$sKey]['nodes'][$oNode->GetId()] = $oNode;
|
$aNodesPerClass[$sClass][$sKey]['nodes'][$oNode->GetId()] = $oNode;
|
||||||
$aNodesPerClass[$sClass][$sKey]['count'] += $oNode->GetObjectCount();
|
$aNodesPerClass[$sClass][$sKey]['count'] += $oNode->GetObjectCount();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves the list of neighbour nodes, in the given direction: 'up' or 'down'
|
* Retrieves the list of neighbour nodes, in the given direction: 'up' or 'down'
|
||||||
* @param bool $bDirectionDown
|
* @param bool $bDirectionDown
|
||||||
@@ -279,11 +279,11 @@ class DisplayableNode extends GraphNode
|
|||||||
foreach($this->GetIncomingEdges() as $oEdge)
|
foreach($this->GetIncomingEdges() as $oEdge)
|
||||||
{
|
{
|
||||||
$aNextNodes[] = $oEdge->GetSourceNode();
|
$aNextNodes[] = $oEdge->GetSourceNode();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return $aNextNodes;
|
return $aNextNodes;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Replaces the next neighbour node (in the given direction: 'up' or 'down') by the supplied group node
|
* Replaces the next neighbour node (in the given direction: 'up' or 'down') by the supplied group node
|
||||||
* preserving the connectivity of the graph
|
* preserving the connectivity of the graph
|
||||||
@@ -351,7 +351,7 @@ class DisplayableNode extends GraphNode
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($oGraph->GetNode($oNextNode->GetId()))
|
if ($oGraph->GetNode($oNextNode->GetId()))
|
||||||
{
|
{
|
||||||
$oGraph->_RemoveNode($oNextNode);
|
$oGraph->_RemoveNode($oNextNode);
|
||||||
@@ -367,9 +367,9 @@ class DisplayableNode extends GraphNode
|
|||||||
{
|
{
|
||||||
$oNewNode->AddObject($oNextNode->GetProperty('object'));
|
$oNewNode->AddObject($oNextNode->GetProperty('object'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Group together (as a special kind of nodes) all the similar neighbours of the current node
|
* Group together (as a special kind of nodes) all the similar neighbours of the current node
|
||||||
* @param DisplayableGraph $oGraph
|
* @param DisplayableGraph $oGraph
|
||||||
@@ -381,7 +381,7 @@ class DisplayableNode extends GraphNode
|
|||||||
{
|
{
|
||||||
if ($this->GetProperty('grouped') === true) return;
|
if ($this->GetProperty('grouped') === true) return;
|
||||||
$this->SetProperty('grouped', true);
|
$this->SetProperty('grouped', true);
|
||||||
|
|
||||||
$aNodesPerClass = array();
|
$aNodesPerClass = array();
|
||||||
foreach($this->GetNextNodes($bDirectionDown) as $oNode)
|
foreach($this->GetNextNodes($bDirectionDown) as $oNode)
|
||||||
{
|
{
|
||||||
@@ -412,7 +412,7 @@ class DisplayableNode extends GraphNode
|
|||||||
$oNewNode->SetProperty('is_reached', ($sStatus == 'reached'));
|
$oNewNode->SetProperty('is_reached', ($sStatus == 'reached'));
|
||||||
$oNewNode->SetProperty('count', $aGroupProps['count']);
|
$oNewNode->SetProperty('count', $aGroupProps['count']);
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if ($bDirectionDown)
|
if ($bDirectionDown)
|
||||||
@@ -427,8 +427,8 @@ class DisplayableNode extends GraphNode
|
|||||||
catch(Exception $e)
|
catch(Exception $e)
|
||||||
{
|
{
|
||||||
// Ignore this redundant egde
|
// Ignore this redundant egde
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach($aGroupProps['nodes'] as $oNextNode)
|
foreach($aGroupProps['nodes'] as $oNextNode)
|
||||||
{
|
{
|
||||||
$this->ReplaceNextNodeBy($oGraph, $oNextNode, $oNewNode, $bDirectionDown);
|
$this->ReplaceNextNodeBy($oGraph, $oNextNode, $oNewNode, $bDirectionDown);
|
||||||
@@ -445,7 +445,7 @@ class DisplayableNode extends GraphNode
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function GetTooltip($aContextDefs)
|
public function GetTooltip($aContextDefs)
|
||||||
{
|
{
|
||||||
$sHtml = '';
|
$sHtml = '';
|
||||||
@@ -474,9 +474,9 @@ class DisplayableNode extends GraphNode
|
|||||||
$sHtml .= '<tr><td>'.$oAttDef->GetLabel().': </td><td>'.$oCurrObj->GetAsHtml($sAttCode).'</td></tr>';
|
$sHtml .= '<tr><td>'.$oAttDef->GetLabel().': </td><td>'.$oCurrObj->GetAsHtml($sAttCode).'</td></tr>';
|
||||||
}
|
}
|
||||||
$sHtml .= '</tbody></table>';
|
$sHtml .= '</tbody></table>';
|
||||||
return $sHtml;
|
return $sHtml;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the description of the node in "dot" language
|
* Get the description of the node in "dot" language
|
||||||
* Used to generate the positions in the graph, but we'd better use fake label
|
* Used to generate the positions in the graph, but we'd better use fake label
|
||||||
@@ -508,7 +508,7 @@ class DisplayableRedundancyNode extends DisplayableNode
|
|||||||
{
|
{
|
||||||
return 24;
|
return 24;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function GetForRaphael($aContextDefs)
|
public function GetForRaphael($aContextDefs)
|
||||||
{
|
{
|
||||||
$aNode = array();
|
$aNode = array();
|
||||||
@@ -519,7 +519,7 @@ class DisplayableRedundancyNode extends DisplayableNode
|
|||||||
$aNode['x'] = $this->x;
|
$aNode['x'] = $this->x;
|
||||||
$aNode['y']= $this->y;
|
$aNode['y']= $this->y;
|
||||||
$aNode['label'] = $this->GetLabel();
|
$aNode['label'] = $this->GetLabel();
|
||||||
$aNode['id'] = $this->GetId();
|
$aNode['id'] = $this->GetId();
|
||||||
$fDiscOpacity = ($this->GetProperty('is_reached') ? 1 : 0.2);
|
$fDiscOpacity = ($this->GetProperty('is_reached') ? 1 : 0.2);
|
||||||
$sColor = ($this->GetProperty('is_reached_count') > $this->GetProperty('threshold')) ? '#c33' : '#999';
|
$sColor = ($this->GetProperty('is_reached_count') > $this->GetProperty('threshold')) ? '#c33' : '#999';
|
||||||
$aNode['disc_attr'] = array('stroke-width' => 2, 'stroke' => '#000', 'fill' => $sColor, 'opacity' => $fDiscOpacity);
|
$aNode['disc_attr'] = array('stroke-width' => 2, 'stroke' => '#000', 'fill' => $sColor, 'opacity' => $fDiscOpacity);
|
||||||
@@ -550,35 +550,35 @@ class DisplayableRedundancyNode extends DisplayableNode
|
|||||||
$height = $oPdf->GetStringHeight(1000, $sLabel);
|
$height = $oPdf->GetStringHeight(1000, $sLabel);
|
||||||
$xPos = (float)$this->x*$fScale - $width/2;
|
$xPos = (float)$this->x*$fScale - $width/2;
|
||||||
$yPos = (float)$this->y*$fScale - $height/2;
|
$yPos = (float)$this->y*$fScale - $height/2;
|
||||||
|
|
||||||
$oPdf->SetXY(($this->x - 16)*$fScale, ($this->y - 16)*$fScale);
|
$oPdf->SetXY(($this->x - 16)*$fScale, ($this->y - 16)*$fScale);
|
||||||
|
|
||||||
$oPdf->Cell(32*$fScale, 32*$fScale, $sLabel, 0, 0, 'C', 0, '', 0, false, 'T', 'C');
|
$oPdf->Cell(32*$fScale, 32*$fScale, $sLabel, 0, 0, 'C', 0, '', 0, false, 'T', 'C');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see DisplayableNode::GroupSimilarNeighbours()
|
* @see DisplayableNode::GroupSimilarNeighbours()
|
||||||
*/
|
*/
|
||||||
public function GroupSimilarNeighbours(DisplayableGraph $oGraph, $iThresholdCount, $bDirectionUp = false, $bDirectionDown = true)
|
public function GroupSimilarNeighbours(DisplayableGraph $oGraph, $iThresholdCount, $bDirectionUp = false, $bDirectionDown = true)
|
||||||
{
|
{
|
||||||
parent::GroupSimilarNeighbours($oGraph, $iThresholdCount, $bDirectionUp, $bDirectionDown);
|
parent::GroupSimilarNeighbours($oGraph, $iThresholdCount, $bDirectionUp, $bDirectionDown);
|
||||||
|
|
||||||
if ($bDirectionUp)
|
if ($bDirectionUp)
|
||||||
{
|
{
|
||||||
$aNodesPerClass = array();
|
$aNodesPerClass = array();
|
||||||
foreach($this->GetIncomingEdges() as $oEdge)
|
foreach($this->GetIncomingEdges() as $oEdge)
|
||||||
{
|
{
|
||||||
$oNode = $oEdge->GetSourceNode();
|
$oNode = $oEdge->GetSourceNode();
|
||||||
|
|
||||||
if (($oNode->GetObjectClass() !== null) && (!$oNode->GetProperty('is_reached')))
|
if (($oNode->GetObjectClass() !== null) && (!$oNode->GetProperty('is_reached')))
|
||||||
{
|
{
|
||||||
$this->AddToStats($oNode, $aNodesPerClass);
|
$this->AddToStats($oNode, $aNodesPerClass);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//$oNode->GroupSimilarNeighbours($oGraph, $iThresholdCount, $bDirectionUp, $bDirectionDown);
|
//$oNode->GroupSimilarNeighbours($oGraph, $iThresholdCount, $bDirectionUp, $bDirectionDown);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
foreach($aNodesPerClass as $sClass => $aDefs)
|
foreach($aNodesPerClass as $sClass => $aDefs)
|
||||||
{
|
{
|
||||||
foreach($aDefs as $sStatus => $aGroupProps)
|
foreach($aDefs as $sStatus => $aGroupProps)
|
||||||
@@ -591,8 +591,8 @@ class DisplayableRedundancyNode extends DisplayableNode
|
|||||||
$oNewNode->SetProperty('is_reached', ($sStatus == 'is_reached'));
|
$oNewNode->SetProperty('is_reached', ($sStatus == 'is_reached'));
|
||||||
$oNewNode->SetProperty('class', $sClass);
|
$oNewNode->SetProperty('class', $sClass);
|
||||||
$oNewNode->SetProperty('count', count($aGroupProps['nodes']));
|
$oNewNode->SetProperty('count', count($aGroupProps['nodes']));
|
||||||
|
|
||||||
|
|
||||||
$sNewId = $this->GetId().'::'.$sClass.'/'.(($sStatus == 'reached') ? '_reached': '');
|
$sNewId = $this->GetId().'::'.$sClass.'/'.(($sStatus == 'reached') ? '_reached': '');
|
||||||
$oNewNode = $oGraph->GetNode($sNewId);
|
$oNewNode = $oGraph->GetNode($sNewId);
|
||||||
if ($oNewNode == null)
|
if ($oNewNode == null)
|
||||||
@@ -604,7 +604,7 @@ class DisplayableRedundancyNode extends DisplayableNode
|
|||||||
$oNewNode->SetProperty('is_reached', ($sStatus == 'reached'));
|
$oNewNode->SetProperty('is_reached', ($sStatus == 'reached'));
|
||||||
$oNewNode->SetProperty('count', $aGroupProps['count']);
|
$oNewNode->SetProperty('count', $aGroupProps['count']);
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
$oOutgoingEdge = new DisplayableEdge($oGraph, '-'.$this->GetId().'-'.$oNewNode->GetId().'/'.$sStatus, $oNewNode, $this);
|
$oOutgoingEdge = new DisplayableEdge($oGraph, '-'.$this->GetId().'-'.$oNewNode->GetId().'/'.$sStatus, $oNewNode, $this);
|
||||||
@@ -613,7 +613,7 @@ class DisplayableRedundancyNode extends DisplayableNode
|
|||||||
{
|
{
|
||||||
// Ignore this redundant egde
|
// Ignore this redundant egde
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach($aGroupProps['nodes'] as $oNextNode)
|
foreach($aGroupProps['nodes'] as $oNextNode)
|
||||||
{
|
{
|
||||||
$this->ReplaceNextNodeBy($oGraph, $oNextNode, $oNewNode, !$bDirectionUp);
|
$this->ReplaceNextNodeBy($oGraph, $oNextNode, $oNewNode, !$bDirectionUp);
|
||||||
@@ -631,7 +631,7 @@ class DisplayableRedundancyNode extends DisplayableNode
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function GetTooltip($aContextDefs)
|
public function GetTooltip($aContextDefs)
|
||||||
{
|
{
|
||||||
$sHtml = '';
|
$sHtml = '';
|
||||||
@@ -640,9 +640,9 @@ class DisplayableRedundancyNode extends DisplayableNode
|
|||||||
$sHtml .= "<tr><td>".Dict::Format('UI:RelationTooltip:ImpactedItems_N_of_M' , $this->GetProperty('is_reached_count'), $this->GetProperty('min_up') + $this->GetProperty('threshold'))."</td></tr>";
|
$sHtml .= "<tr><td>".Dict::Format('UI:RelationTooltip:ImpactedItems_N_of_M' , $this->GetProperty('is_reached_count'), $this->GetProperty('min_up') + $this->GetProperty('threshold'))."</td></tr>";
|
||||||
$sHtml .= "<tr><td>".Dict::Format('UI:RelationTooltip:CriticalThreshold_N_of_M' , $this->GetProperty('threshold'), $this->GetProperty('min_up') + $this->GetProperty('threshold'))."</td></tr>";
|
$sHtml .= "<tr><td>".Dict::Format('UI:RelationTooltip:CriticalThreshold_N_of_M' , $this->GetProperty('threshold'), $this->GetProperty('min_up') + $this->GetProperty('threshold'))."</td></tr>";
|
||||||
$sHtml .= '</tbody></table>';
|
$sHtml .= '</tbody></table>';
|
||||||
return $sHtml;
|
return $sHtml;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public function GetObjectCount()
|
public function GetObjectCount()
|
||||||
{
|
{
|
||||||
@@ -666,7 +666,7 @@ class DisplayableEdge extends GraphEdge
|
|||||||
}
|
}
|
||||||
$xStart = $oSourceNode->x * $fScale;
|
$xStart = $oSourceNode->x * $fScale;
|
||||||
$yStart = $oSourceNode->y * $fScale;
|
$yStart = $oSourceNode->y * $fScale;
|
||||||
|
|
||||||
$oSinkNode = $this->GetSinkNode();
|
$oSinkNode = $this->GetSinkNode();
|
||||||
if (($oSinkNode->x == null) || ($oSinkNode->y == null))
|
if (($oSinkNode->x == null) || ($oSinkNode->y == null))
|
||||||
{
|
{
|
||||||
@@ -674,9 +674,9 @@ class DisplayableEdge extends GraphEdge
|
|||||||
}
|
}
|
||||||
$xEnd = $oSinkNode->x * $fScale;
|
$xEnd = $oSinkNode->x * $fScale;
|
||||||
$yEnd = $oSinkNode->y * $fScale;
|
$yEnd = $oSinkNode->y * $fScale;
|
||||||
|
|
||||||
$bReached = ($this->GetSourceNode()->GetProperty('is_reached') && $this->GetSinkNode()->GetProperty('is_reached'));
|
$bReached = ($this->GetSourceNode()->GetProperty('is_reached') && $this->GetSinkNode()->GetProperty('is_reached'));
|
||||||
|
|
||||||
$oPdf->setAlpha(1);
|
$oPdf->setAlpha(1);
|
||||||
if ($bReached)
|
if ($bReached)
|
||||||
{
|
{
|
||||||
@@ -688,8 +688,8 @@ class DisplayableEdge extends GraphEdge
|
|||||||
}
|
}
|
||||||
$oPdf->SetLineStyle(array('width' => 2*$fScale, 'cap' => 'round', 'join' => 'miter', 'dash' => 0, 'color' => $aColor));
|
$oPdf->SetLineStyle(array('width' => 2*$fScale, 'cap' => 'round', 'join' => 'miter', 'dash' => 0, 'color' => $aColor));
|
||||||
$oPdf->Line($xStart, $yStart, $xEnd, $yEnd);
|
$oPdf->Line($xStart, $yStart, $xEnd, $yEnd);
|
||||||
|
|
||||||
|
|
||||||
$vx = $xEnd - $xStart;
|
$vx = $xEnd - $xStart;
|
||||||
$vy = $yEnd - $yStart;
|
$vy = $yEnd - $yStart;
|
||||||
$l = sqrt($vx*$vx + $vy*$vy);
|
$l = sqrt($vx*$vx + $vy*$vy);
|
||||||
@@ -699,24 +699,24 @@ class DisplayableEdge extends GraphEdge
|
|||||||
$uy = $vx;
|
$uy = $vx;
|
||||||
$lPos = max($l/2, $l - 40*$fScale);
|
$lPos = max($l/2, $l - 40*$fScale);
|
||||||
$iArrowSize = 5*$fScale;
|
$iArrowSize = 5*$fScale;
|
||||||
|
|
||||||
$x = $xStart + $lPos * $vx;
|
$x = $xStart + $lPos * $vx;
|
||||||
$y = $yStart + $lPos * $vy;
|
$y = $yStart + $lPos * $vy;
|
||||||
$oPdf->Line($x, $y, $x + $iArrowSize * ($ux-$vx), $y + $iArrowSize * ($uy-$vy));
|
$oPdf->Line($x, $y, $x + $iArrowSize * ($ux-$vx), $y + $iArrowSize * ($uy-$vy));
|
||||||
$oPdf->Line($x, $y, $x - $iArrowSize * ($ux+$vx), $y - $iArrowSize * ($uy+$vy));
|
$oPdf->Line($x, $y, $x - $iArrowSize * ($ux+$vx), $y - $iArrowSize * ($uy+$vy));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class DisplayableGroupNode extends DisplayableNode
|
class DisplayableGroupNode extends DisplayableNode
|
||||||
{
|
{
|
||||||
protected $aObjects;
|
protected $aObjects;
|
||||||
|
|
||||||
public function __construct(SimpleGraph $oGraph, $sId, $x = 0, $y = 0)
|
public function __construct(SimpleGraph $oGraph, $sId, $x = 0, $y = 0)
|
||||||
{
|
{
|
||||||
parent::__construct($oGraph, $sId, $x, $y);
|
parent::__construct($oGraph, $sId, $x, $y);
|
||||||
$this->aObjects = array();
|
$this->aObjects = array();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function AddObject(DBObject $oObj = null)
|
public function AddObject(DBObject $oObj = null)
|
||||||
{
|
{
|
||||||
if (is_object($oObj))
|
if (is_object($oObj))
|
||||||
@@ -729,12 +729,12 @@ class DisplayableGroupNode extends DisplayableNode
|
|||||||
$this->aObjects[$oObj->GetKey()] = $oObj;
|
$this->aObjects[$oObj->GetKey()] = $oObj;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function GetObjects()
|
public function GetObjects()
|
||||||
{
|
{
|
||||||
return $this->aObjects;
|
return $this->aObjects;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function GetWidth()
|
public function GetWidth()
|
||||||
{
|
{
|
||||||
return 50;
|
return 50;
|
||||||
@@ -760,7 +760,7 @@ class DisplayableGroupNode extends DisplayableNode
|
|||||||
$aNode['tooltip'] = $this->GetTooltip($aContextDefs);
|
$aNode['tooltip'] = $this->GetTooltip($aContextDefs);
|
||||||
return $aNode;
|
return $aNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function RenderAsPDF(iTopPDF $oPdf, DisplayableGraph $oGraph, $fScale, $aContextDefs)
|
public function RenderAsPDF(iTopPDF $oPdf, DisplayableGraph $oGraph, $fScale, $aContextDefs)
|
||||||
{
|
{
|
||||||
$bReached = $this->GetProperty('is_reached');
|
$bReached = $this->GetProperty('is_reached');
|
||||||
@@ -790,7 +790,7 @@ class DisplayableGroupNode extends DisplayableNode
|
|||||||
$oPdf->SetTextColor(0, 0, 0);
|
$oPdf->SetTextColor(0, 0, 0);
|
||||||
$oPdf->Text($this->x * $fScale - $width / 2, ($this->y + 25) * $fScale, $this->GetProperty('label'));
|
$oPdf->Text($this->x * $fScale - $width / 2, ($this->y + 25) * $fScale, $this->GetProperty('label'));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function GetTooltip($aContextDefs)
|
public function GetTooltip($aContextDefs)
|
||||||
{
|
{
|
||||||
$iGroupIdx = $this->GetProperty('group_index');
|
$iGroupIdx = $this->GetProperty('group_index');
|
||||||
@@ -823,7 +823,7 @@ class DisplayableGraph extends SimpleGraph
|
|||||||
protected $aTempImages;
|
protected $aTempImages;
|
||||||
protected $aSourceObjects;
|
protected $aSourceObjects;
|
||||||
protected $aSinkObjects;
|
protected $aSinkObjects;
|
||||||
|
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
parent::__construct();
|
parent::__construct();
|
||||||
@@ -831,14 +831,14 @@ class DisplayableGraph extends SimpleGraph
|
|||||||
$this->aSourceObjects = array();
|
$this->aSourceObjects = array();
|
||||||
$this->aSinkObjects = array();
|
$this->aSinkObjects = array();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function GetTempImageName()
|
public function GetTempImageName()
|
||||||
{
|
{
|
||||||
$sNewTempName = tempnam(APPROOT.'data', 'img-');
|
$sNewTempName = tempnam(APPROOT.'data', 'img-');
|
||||||
$this->aTempImages[] = $sNewTempName;
|
$this->aTempImages[] = $sNewTempName;
|
||||||
return $sNewTempName;
|
return $sNewTempName;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function __destruct()
|
public function __destruct()
|
||||||
{
|
{
|
||||||
foreach($this->aTempImages as $sTempFile)
|
foreach($this->aTempImages as $sTempFile)
|
||||||
@@ -918,7 +918,7 @@ class DisplayableGraph extends SimpleGraph
|
|||||||
$oSinkNode = $oNewGraph->GetNode($oEdge->GetSinkNode()->GetId());
|
$oSinkNode = $oNewGraph->GetNode($oEdge->GetSinkNode()->GetId());
|
||||||
$oNewEdge = new DisplayableEdge($oNewGraph, $oEdge->GetId(), $oSourceNode, $oSinkNode);
|
$oNewEdge = new DisplayableEdge($oNewGraph, $oEdge->GetId(), $oSourceNode, $oSinkNode);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove duplicate edges between two nodes
|
// Remove duplicate edges between two nodes
|
||||||
$oEdgesIter = new RelationTypeIterator($oNewGraph, 'Edge');
|
$oEdgesIter = new RelationTypeIterator($oNewGraph, 'Edge');
|
||||||
$aEdgeKeys = array();
|
$aEdgeKeys = array();
|
||||||
@@ -946,7 +946,7 @@ class DisplayableGraph extends SimpleGraph
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$oNodesIter = new RelationTypeIterator($oNewGraph, 'Node');
|
$oNodesIter = new RelationTypeIterator($oNewGraph, 'Node');
|
||||||
foreach($oNodesIter as $oNode)
|
foreach($oNodesIter as $oNode)
|
||||||
{
|
{
|
||||||
@@ -981,7 +981,7 @@ class DisplayableGraph extends SimpleGraph
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove duplicate edges between two nodes
|
// Remove duplicate edges between two nodes
|
||||||
$oEdgesIter = new RelationTypeIterator($oNewGraph, 'Edge');
|
$oEdgesIter = new RelationTypeIterator($oNewGraph, 'Edge');
|
||||||
$aEdgeKeys = array();
|
$aEdgeKeys = array();
|
||||||
@@ -1010,10 +1010,10 @@ class DisplayableGraph extends SimpleGraph
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
set_time_limit(intval($iPreviousTimeLimit));
|
set_time_limit(intval($iPreviousTimeLimit));
|
||||||
|
|
||||||
return $oNewGraph;
|
return $oNewGraph;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initializes the positions by rendering using Graphviz in xdot format
|
* Initializes the positions by rendering using Graphviz in xdot format
|
||||||
* and parsing the output.
|
* and parsing the output.
|
||||||
@@ -1026,7 +1026,7 @@ class DisplayableGraph extends SimpleGraph
|
|||||||
{
|
{
|
||||||
throw new Exception($sDot);
|
throw new Exception($sDot);
|
||||||
}
|
}
|
||||||
|
|
||||||
$aChunks = explode(";", $sDot);
|
$aChunks = explode(";", $sDot);
|
||||||
foreach($aChunks as $sChunk)
|
foreach($aChunks as $sChunk)
|
||||||
{
|
{
|
||||||
@@ -1035,7 +1035,7 @@ class DisplayableGraph extends SimpleGraph
|
|||||||
$sId = $aMatches[1];
|
$sId = $aMatches[1];
|
||||||
$xPos = $aMatches[2];
|
$xPos = $aMatches[2];
|
||||||
$yPos = $aMatches[3];
|
$yPos = $aMatches[3];
|
||||||
|
|
||||||
$oNode = $this->GetNode($sId);
|
$oNode = $this->GetNode($sId);
|
||||||
if ($oNode !== null)
|
if ($oNode !== null)
|
||||||
{
|
{
|
||||||
@@ -1049,7 +1049,7 @@ class DisplayableGraph extends SimpleGraph
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function GetBoundingBox()
|
public function GetBoundingBox()
|
||||||
{
|
{
|
||||||
$xMin = null;
|
$xMin = null;
|
||||||
@@ -1074,10 +1074,10 @@ class DisplayableGraph extends SimpleGraph
|
|||||||
$yMax = max($yMax, $oNode->y + $oNode->GetHeight() / 2);
|
$yMax = max($yMax, $oNode->y + $oNode->GetHeight() / 2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return array('xmin' => $xMin, 'xmax' => $xMax, 'ymin' => $yMin, 'ymax' => $yMax);
|
return array('xmin' => $xMin, 'xmax' => $xMax, 'ymin' => $yMin, 'ymax' => $yMax);
|
||||||
}
|
}
|
||||||
|
|
||||||
function Translate($dx, $dy)
|
function Translate($dx, $dy)
|
||||||
{
|
{
|
||||||
$oIterator = new RelationTypeIterator($this, 'Node');
|
$oIterator = new RelationTypeIterator($this, 'Node');
|
||||||
@@ -1085,9 +1085,9 @@ class DisplayableGraph extends SimpleGraph
|
|||||||
{
|
{
|
||||||
$oNode->x += $dx;
|
$oNode->x += $dx;
|
||||||
$oNode->y += $dy;
|
$oNode->y += $dy;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function UpdatePositions($aPositions)
|
public function UpdatePositions($aPositions)
|
||||||
{
|
{
|
||||||
foreach($aPositions as $sNodeId => $aPos)
|
foreach($aPositions as $sNodeId => $aPos)
|
||||||
@@ -1107,7 +1107,7 @@ class DisplayableGraph extends SimpleGraph
|
|||||||
function GetAsJSON($sContextKey)
|
function GetAsJSON($sContextKey)
|
||||||
{
|
{
|
||||||
$aContextDefs = static::GetContextDefinitions($sContextKey, false);
|
$aContextDefs = static::GetContextDefinitions($sContextKey, false);
|
||||||
|
|
||||||
$aData = array('nodes' => array(), 'edges' => array(), 'groups' => array(), 'lists' => array());
|
$aData = array('nodes' => array(), 'edges' => array(), 'groups' => array(), 'lists' => array());
|
||||||
$iGroupIdx = 0;
|
$iGroupIdx = 0;
|
||||||
$oIterator = new RelationTypeIterator($this, 'Node');
|
$oIterator = new RelationTypeIterator($this, 'Node');
|
||||||
@@ -1131,7 +1131,7 @@ class DisplayableGraph extends SimpleGraph
|
|||||||
$aData['groups'][$iGroupIdx] = array('class' => $sClass, 'keys' => $aKeys);
|
$aData['groups'][$iGroupIdx] = array('class' => $sClass, 'keys' => $aKeys);
|
||||||
$oNode->SetProperty('group_index', $iGroupIdx);
|
$oNode->SetProperty('group_index', $iGroupIdx);
|
||||||
$iGroupIdx++;
|
$iGroupIdx++;
|
||||||
|
|
||||||
if ($oNode->GetProperty('is_reached'))
|
if ($oNode->GetProperty('is_reached'))
|
||||||
{
|
{
|
||||||
// Also add the objects from this group into the 'list' tab
|
// Also add the objects from this group into the 'list' tab
|
||||||
@@ -1139,11 +1139,11 @@ class DisplayableGraph extends SimpleGraph
|
|||||||
{
|
{
|
||||||
$aData['lists'][$sClass] = $aKeys;
|
$aData['lists'][$sClass] = $aKeys;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
$aData['lists'][$sClass] = array_merge($aData['lists'][$sClass], $aKeys);
|
$aData['lists'][$sClass] = array_merge($aData['lists'][$sClass], $aKeys);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (($oNode instanceof DisplayableNode) && $oNode->GetProperty('is_reached') && is_object($oNode->GetProperty('object')))
|
if (($oNode instanceof DisplayableNode) && $oNode->GetProperty('is_reached') && is_object($oNode->GetProperty('object')))
|
||||||
@@ -1157,9 +1157,9 @@ class DisplayableGraph extends SimpleGraph
|
|||||||
}
|
}
|
||||||
$aData['nodes'][] = $oNode->GetForRaphael($aContextDefs);
|
$aData['nodes'][] = $oNode->GetForRaphael($aContextDefs);
|
||||||
}
|
}
|
||||||
|
|
||||||
uksort($aData['lists'], array(get_class($this), 'SortOnClassLabel')); // sort on the localized names of the classes to provide a consistent and stable order
|
uksort($aData['lists'], array(get_class($this), 'SortOnClassLabel')); // sort on the localized names of the classes to provide a consistent and stable order
|
||||||
|
|
||||||
$oIterator = new RelationTypeIterator($this, 'Edge');
|
$oIterator = new RelationTypeIterator($this, 'Edge');
|
||||||
foreach($oIterator as $sId => $oEdge)
|
foreach($oIterator as $sId => $oEdge)
|
||||||
{
|
{
|
||||||
@@ -1171,7 +1171,7 @@ class DisplayableGraph extends SimpleGraph
|
|||||||
$aEdge['attr'] = array('opacity' => $fOpacity, 'stroke' => '#000');
|
$aEdge['attr'] = array('opacity' => $fOpacity, 'stroke' => '#000');
|
||||||
$aData['edges'][] = $aEdge;
|
$aData['edges'][] = $aEdge;
|
||||||
}
|
}
|
||||||
|
|
||||||
return json_encode($aData);
|
return json_encode($aData);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1200,12 +1200,12 @@ class DisplayableGraph extends SimpleGraph
|
|||||||
{
|
{
|
||||||
$aContextDefs = static::GetContextDefinitions($sContextKey, false); // No need to develop the parameters
|
$aContextDefs = static::GetContextDefinitions($sContextKey, false); // No need to develop the parameters
|
||||||
$oPdf = $oPage->get_tcpdf();
|
$oPdf = $oPage->get_tcpdf();
|
||||||
|
|
||||||
$aBB = $this->GetBoundingBox();
|
$aBB = $this->GetBoundingBox();
|
||||||
$this->Translate(-$aBB['xmin'], -$aBB['ymin']);
|
$this->Translate(-$aBB['xmin'], -$aBB['ymin']);
|
||||||
|
|
||||||
$aMargins = $oPdf->getMargins();
|
$aMargins = $oPdf->getMargins();
|
||||||
|
|
||||||
if ($xMin == -1)
|
if ($xMin == -1)
|
||||||
{
|
{
|
||||||
$xMin = $aMargins['left'];
|
$xMin = $aMargins['left'];
|
||||||
@@ -1222,7 +1222,7 @@ class DisplayableGraph extends SimpleGraph
|
|||||||
{
|
{
|
||||||
$yMax = $oPdf->getPageHeight() - $aMargins['bottom'];
|
$yMax = $oPdf->getPageHeight() - $aMargins['bottom'];
|
||||||
}
|
}
|
||||||
|
|
||||||
$fBreakMargin = $oPdf->getBreakMargin();
|
$fBreakMargin = $oPdf->getBreakMargin();
|
||||||
$oPdf->SetAutoPageBreak(false);
|
$oPdf->SetAutoPageBreak(false);
|
||||||
$aRemainingArea = $this->RenderKey($oPdf, $sComments, $xMin, $yMin, $xMax, $yMax, $aContextDefs);
|
$aRemainingArea = $this->RenderKey($oPdf, $sComments, $xMin, $yMin, $xMax, $yMax, $aContextDefs);
|
||||||
@@ -1230,19 +1230,19 @@ class DisplayableGraph extends SimpleGraph
|
|||||||
$xMax = $aRemainingArea['xmax'];
|
$xMax = $aRemainingArea['xmax'];
|
||||||
$yMin = $aRemainingArea['ymin'];
|
$yMin = $aRemainingArea['ymin'];
|
||||||
$yMax = $aRemainingArea['ymax'];
|
$yMax = $aRemainingArea['ymax'];
|
||||||
|
|
||||||
//$oPdf->Rect($xMin, $yMin, $xMax - $xMin, $yMax - $yMin, 'D', array(), array(225, 50, 50));
|
//$oPdf->Rect($xMin, $yMin, $xMax - $xMin, $yMax - $yMin, 'D', array(), array(225, 50, 50));
|
||||||
|
|
||||||
$fPageW = $xMax - $xMin;
|
$fPageW = $xMax - $xMin;
|
||||||
$fPageH = $yMax - $yMin;
|
$fPageH = $yMax - $yMin;
|
||||||
|
|
||||||
$w = $aBB['xmax'] - $aBB['xmin'];
|
$w = $aBB['xmax'] - $aBB['xmin'];
|
||||||
$h = $aBB['ymax'] - $aBB['ymin'] + 10; // Extra space for the labels which may appear "below" the icons
|
$h = $aBB['ymax'] - $aBB['ymin'] + 10; // Extra space for the labels which may appear "below" the icons
|
||||||
|
|
||||||
$fScale = min($fPageW / $w, $fPageH / $h);
|
$fScale = min($fPageW / $w, $fPageH / $h);
|
||||||
$dx = ($fPageW - $fScale * $w) / 2;
|
$dx = ($fPageW - $fScale * $w) / 2;
|
||||||
$dy = ($fPageH - $fScale * $h) / 2;
|
$dy = ($fPageH - $fScale * $h) / 2;
|
||||||
|
|
||||||
$this->Translate(($xMin + $dx)/$fScale, ($yMin + $dy)/$fScale);
|
$this->Translate(($xMin + $dx)/$fScale, ($yMin + $dy)/$fScale);
|
||||||
|
|
||||||
$oIterator = new RelationTypeIterator($this, 'Edge');
|
$oIterator = new RelationTypeIterator($this, 'Edge');
|
||||||
@@ -1264,7 +1264,7 @@ class DisplayableGraph extends SimpleGraph
|
|||||||
$oPdf->SetAlpha(1);
|
$oPdf->SetAlpha(1);
|
||||||
$oPdf->SetTextColor(0, 0, 0);
|
$oPdf->SetTextColor(0, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Renders (in PDF) the key (legend) of the graphics vertically to the left of the specified zone (xmin,ymin, xmax,ymax),
|
* Renders (in PDF) the key (legend) of the graphics vertically to the left of the specified zone (xmin,ymin, xmax,ymax),
|
||||||
* and the comment (if any) at the bottom of the page. Returns the position of remaining area.
|
* and the comment (if any) at the bottom of the page. Returns the position of remaining area.
|
||||||
@@ -1332,7 +1332,7 @@ class DisplayableGraph extends SimpleGraph
|
|||||||
$yPos += $fIconSize + 2 * $fPadding;
|
$yPos += $fIconSize + 2 * $fPadding;
|
||||||
}
|
}
|
||||||
$oPdf->Rect($xMin, $yMin, $fMaxWidth + $fIconSize + 3*$fPadding, $yMax - $yMin, 'D');
|
$oPdf->Rect($xMin, $yMin, $fMaxWidth + $fIconSize + 3*$fPadding, $yMax - $yMin, 'D');
|
||||||
|
|
||||||
if ($sComments != '')
|
if ($sComments != '')
|
||||||
{
|
{
|
||||||
// Draw the comment text (surrounded by a rectangle)
|
// Draw the comment text (surrounded by a rectangle)
|
||||||
@@ -1347,10 +1347,10 @@ class DisplayableGraph extends SimpleGraph
|
|||||||
$oPdf->Rect($xPos, $yPos, $w + 2*$fPadding, $h + 2*$fPadding, 'D');
|
$oPdf->Rect($xPos, $yPos, $w + 2*$fPadding, $h + 2*$fPadding, 'D');
|
||||||
$yMax = $yPos - $fPadding;
|
$yMax = $yPos - $fPadding;
|
||||||
}
|
}
|
||||||
|
|
||||||
return array('xmin' => $xMin + $fMaxWidth + $fIconSize + 4*$fPadding, 'xmax' => $xMax, 'ymin' => $yMin, 'ymax' => $yMax);
|
return array('xmin' => $xMin + $fMaxWidth + $fIconSize + 4*$fPadding, 'xmax' => $xMax, 'ymin' => $yMin, 'ymax' => $yMax);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the context definitions from the parameters / configuration. The format of the "key" string is:
|
* Get the context definitions from the parameters / configuration. The format of the "key" string is:
|
||||||
* <module>/relation_context/<class>/<relation>/<direction>
|
* <module>/relation_context/<class>/<relation>/<direction>
|
||||||
@@ -1372,7 +1372,7 @@ class DisplayableGraph extends SimpleGraph
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
$sLeafClass = $aLevels[2];
|
$sLeafClass = $aLevels[2];
|
||||||
|
|
||||||
if (!MetaModel::IsValidClass($sLeafClass))
|
if (!MetaModel::IsValidClass($sLeafClass))
|
||||||
{
|
{
|
||||||
IssueLog::Warning("GetContextDefinitions: invalid 'sLeafClass' = '$sLeafClass'. A valid class name is expected in 3rd position inside '$sContextKey' !");
|
IssueLog::Warning("GetContextDefinitions: invalid 'sLeafClass' = '$sLeafClass'. A valid class name is expected in 3rd position inside '$sContextKey' !");
|
||||||
@@ -1387,7 +1387,7 @@ class DisplayableGraph extends SimpleGraph
|
|||||||
$aContextDefs = array_merge($aContextDefs, $aRelationContext[$sClass][$aLevels[3]][$aLevels[4]]['items']);
|
$aContextDefs = array_merge($aContextDefs, $aRelationContext[$sClass][$aLevels[3]][$aLevels[4]]['items']);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if the queries are valid
|
// Check if the queries are valid
|
||||||
foreach($aContextDefs as $sKey => $sDefs)
|
foreach($aContextDefs as $sKey => $sDefs)
|
||||||
{
|
{
|
||||||
@@ -1425,168 +1425,101 @@ class DisplayableGraph extends SimpleGraph
|
|||||||
* @throws \CoreException
|
* @throws \CoreException
|
||||||
* @throws \DictExceptionMissingString
|
* @throws \DictExceptionMissingString
|
||||||
*/
|
*/
|
||||||
function Display(WebPage $oP, $aResults, $sRelation, ApplicationContext $oAppContext, $aExcludedObjects, $sObjClass, $iObjKey, $sContextKey, $aContextParams = array())
|
function Display(WebPage $oP, $aResults, $sRelation, ApplicationContext $oAppContext, $aExcludedObjects, $sObjClass, $iObjKey, $sContextKey, $aContextParams = array(), bool $sLazyLoading = false)
|
||||||
{
|
{
|
||||||
$aContextDefs = static::GetContextDefinitions($sContextKey, true, $aContextParams);
|
list($aExcludedByClass, $aAdditionalContexts) = $this->DisplayFiltering($sContextKey, $aContextParams, $aExcludedObjects, $oP, $aResults, $sLazyLoading);
|
||||||
$aExcludedByClass = array();
|
|
||||||
foreach($aExcludedObjects as $oObj)
|
|
||||||
{
|
|
||||||
if (!array_key_exists(get_class($oObj), $aExcludedByClass))
|
|
||||||
{
|
|
||||||
$aExcludedByClass[get_class($oObj)] = array();
|
|
||||||
}
|
|
||||||
$aExcludedByClass[get_class($oObj)][] = $oObj->GetKey();
|
|
||||||
}
|
|
||||||
$sSftShort = Dict::S('UI:ElementsDisplayed');
|
|
||||||
$sSearchToggle = Dict::S('UI:Search:Toggle');
|
|
||||||
$oP->add("<div class=\"not-printable\">\n");
|
|
||||||
$oUiSearchBlock = new Panel($sSftShort, [],Panel::ENUM_COLOR_SCHEME_CYAN, 'ds_flash');
|
|
||||||
$oUiSearchBlock->SetCSSClasses(["ibo-search-form-panel", "display_block"]);
|
|
||||||
$oUiSearchBlock->SetIsCollapsible(true);
|
|
||||||
$oUiHtmlBlock = new Combodo\iTop\Application\UI\Base\Component\Html\Html(
|
|
||||||
<<<EOF
|
|
||||||
<div id="ds_flash" class="search_box ibo-display-graph--search-box">
|
|
||||||
<div id="dh_flash_criterion_outer" class="sf_criterion_area"><div class="sf_criterion_row">
|
|
||||||
EOF
|
|
||||||
);
|
|
||||||
$oP->add_ready_script(
|
|
||||||
<<<EOF
|
|
||||||
$("#dh_flash > .sf_title").on('click', function() {
|
|
||||||
$("#dh_flash").toggleClass('closed');
|
|
||||||
});
|
|
||||||
$('#ReloadMovieBtn').button().button('disable');
|
|
||||||
EOF
|
|
||||||
);
|
|
||||||
$aSortedElements = array();
|
|
||||||
foreach($aResults as $sClassIdx => $aObjects)
|
|
||||||
{
|
|
||||||
foreach($aObjects as $oCurrObj)
|
|
||||||
{
|
|
||||||
$sSubClass = get_class($oCurrObj);
|
|
||||||
$aSortedElements[$sSubClass] = MetaModel::GetName($sSubClass);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
asort($aSortedElements);
|
|
||||||
$idx = 0;
|
|
||||||
foreach($aSortedElements as $sSubClass => $sClassName)
|
|
||||||
{
|
|
||||||
$oUiHtmlBlock->AddHtml("<div><input type=\"checkbox\" id=\"exclude_$idx\" name=\"excluded[]\" value=\"$sSubClass\" checked onChange=\"$('#ReloadMovieBtn').button('enable')\"><label for=\"exclude_$idx\">");
|
|
||||||
$oUiMedallionBlock= new MedallionIcon(MetaModel::GetClassIcon($sSubClass, false));
|
|
||||||
$oUiMedallionBlock->SetDescription($sClassName);
|
|
||||||
$oUiHtmlBlock->AddHtml(BlockRenderer::RenderBlockTemplates($oUiMedallionBlock));
|
|
||||||
$oUiHtmlBlock->AddHtml("</label></div>");
|
|
||||||
$idx++;
|
|
||||||
}
|
|
||||||
$oUiHtmlBlock->AddHtml("</div>");
|
|
||||||
$oUiHtmlBlock->AddHtml("<button type=\"button\" id=\"ReloadMovieBtn\" class=\"ibo-button ibo-is-neutral ibo-is-regular\" onClick=\"DoReload()\">".Dict::S('UI:Button:Refresh')."</button></div></form>");
|
|
||||||
$oUiHtmlBlock->AddHtml("</div>\n");
|
|
||||||
$oUiHtmlBlock->AddHtml("</div>\n"); // class="not-printable"
|
|
||||||
|
|
||||||
$oUiSearchBlock->AddSubBlock($oUiHtmlBlock);
|
|
||||||
$oP->AddUiBlock($oUiSearchBlock);
|
|
||||||
$aAdditionalContexts = array();
|
|
||||||
foreach($aContextDefs as $sKey => $aDefinition)
|
|
||||||
{
|
|
||||||
$aAdditionalContexts[] = array('key' => $sKey, 'label' => Dict::S($aDefinition['dict']), 'oql' => $aDefinition['oql'], 'default' => (array_key_exists('default', $aDefinition) && ($aDefinition['default'] == 'yes')));
|
|
||||||
}
|
|
||||||
|
|
||||||
$sDirection = utils::ReadParam('d', 'horizontal');
|
|
||||||
$iGroupingThreshold = utils::ReadParam('g', 5);
|
$iGroupingThreshold = utils::ReadParam('g', 5);
|
||||||
|
|
||||||
WebResourcesHelper::EnableSimpleGraphInWebPage($oP);
|
WebResourcesHelper::EnableSimpleGraphInWebPage($oP);
|
||||||
try
|
try {
|
||||||
{
|
|
||||||
$this->InitFromGraphviz();
|
$this->InitFromGraphviz();
|
||||||
$sExportAsPdfURL = '';
|
|
||||||
$sExportAsPdfURL = utils::GetAbsoluteUrlAppRoot().'pages/ajax.render.php?operation=relation_pdf&relation='.$sRelation.'&direction='.($this->bDirectionDown ? 'down' : 'up');
|
$sExportAsPdfURL = utils::GetAbsoluteUrlAppRoot().'pages/ajax.render.php?operation=relation_pdf&relation='.$sRelation.'&direction='.($this->bDirectionDown ? 'down' : 'up');
|
||||||
$oAppcontext = new ApplicationContext();
|
|
||||||
$sContext = $oAppContext->GetForLink();
|
$sContext = $oAppContext->GetForLink();
|
||||||
$sDrillDownURL = utils::GetAbsoluteUrlAppRoot().'pages/UI.php?operation=details&class=%1$s&id=%2$s&'.$sContext;
|
$sDrillDownURL = utils::GetAbsoluteUrlAppRoot().'pages/UI.php?operation=details&class=%1$s&id=%2$s&'.$sContext;
|
||||||
$sExportAsDocumentURL = utils::GetAbsoluteUrlAppRoot().'pages/ajax.render.php?operation=relation_attachment&relation='.$sRelation.'&direction='.($this->bDirectionDown ? 'down' : 'up');
|
$sExportAsDocumentURL = utils::GetAbsoluteUrlAppRoot().'pages/ajax.render.php?operation=relation_attachment&relation='.$sRelation.'&direction='.($this->bDirectionDown ? 'down' : 'up');
|
||||||
$sLoadFromURL = utils::GetAbsoluteUrlAppRoot().'pages/ajax.render.php?operation=relation_json&relation='.$sRelation.'&direction='.($this->bDirectionDown ? 'down' : 'up');
|
$sLoadFromURL = utils::GetAbsoluteUrlAppRoot().'pages/ajax.render.php?operation=relation_json&relation='.$sRelation.'&direction='.($this->bDirectionDown ? 'down' : 'up');
|
||||||
$sAttachmentExportTitle = '';
|
$sAttachmentExportTitle = '';
|
||||||
if (($sObjClass != null) && ($iObjKey != null))
|
if (($sObjClass != null) && ($iObjKey != null)) {
|
||||||
{
|
|
||||||
$oTargetObj = MetaModel::GetObject($sObjClass, $iObjKey, false);
|
$oTargetObj = MetaModel::GetObject($sObjClass, $iObjKey, false);
|
||||||
if ($oTargetObj)
|
if ($oTargetObj) {
|
||||||
{
|
|
||||||
$sAttachmentExportTitle = Dict::Format('UI:Relation:AttachmentExportOptions_Name', $oTargetObj->GetName());
|
$sAttachmentExportTitle = Dict::Format('UI:Relation:AttachmentExportOptions_Name', $oTargetObj->GetName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$sId = 'graph';
|
$sId = 'graph';
|
||||||
$sStyle = '';
|
$sStyle = '';
|
||||||
if ($oP->IsPrintableVersion())
|
if ($oP->IsPrintableVersion()) {
|
||||||
{
|
|
||||||
// Optimize for printing on A4/Letter vertically
|
// Optimize for printing on A4/Letter vertically
|
||||||
$sStyle = 'margin-left:auto; margin-right:auto;';
|
$sStyle = 'margin-left:auto; margin-right:auto;';
|
||||||
$oP->add_ready_script("$('.simple-graph').width(18/2.54*96).resizable({ stop: function() { $(window).trigger('resized'); }});"); // Default width about 18 cm, since most browsers assume 96 dpi
|
$oP->add_ready_script("$('.simple-graph').width(18/2.54*96).resizable({ stop: function() { $(window).trigger('resized'); }});"); // Default width about 18 cm, since most browsers assume 96 dpi
|
||||||
}
|
}
|
||||||
$oP->add('<div id="'.$sId.'" class="simple-graph" style="'.$sStyle.'"></div>');
|
$oP->add('<div id="'.$sId.'" class="simple-graph" style="'.$sStyle.'"></div>');
|
||||||
$aParams = array(
|
$aParams = array(
|
||||||
'source_url' => $sLoadFromURL,
|
'source_url' => $sLoadFromURL,
|
||||||
'sources' => ($this->bDirectionDown ? $this->aSourceObjects : $this->aSinkObjects),
|
'sources' => ($this->bDirectionDown ? $this->aSourceObjects : $this->aSinkObjects),
|
||||||
'excluded' => $aExcludedByClass,
|
'excluded' => $aExcludedByClass,
|
||||||
'grouping_threshold' => $iGroupingThreshold,
|
'grouping_threshold' => $iGroupingThreshold,
|
||||||
'export_as_pdf' => array('url' => $sExportAsPdfURL, 'label' => Dict::S('UI:Relation:ExportAsPDF')),
|
'export_as_pdf' => array('url' => $sExportAsPdfURL, 'label' => Dict::S('UI:Relation:ExportAsPDF')),
|
||||||
'export_as_attachment' => array('url' => $sExportAsDocumentURL, 'label' => Dict::S('UI:Relation:ExportAsAttachment'), 'obj_class' => $sObjClass, 'obj_key' => $iObjKey),
|
'export_as_attachment' => array('url' => $sExportAsDocumentURL, 'label' => Dict::S('UI:Relation:ExportAsAttachment'), 'obj_class' => $sObjClass, 'obj_key' => $iObjKey),
|
||||||
'drill_down' => array('url' => $sDrillDownURL, 'label' => Dict::S('UI:Relation:DrillDown')),
|
'drill_down' => array('url' => $sDrillDownURL, 'label' => Dict::S('UI:Relation:DrillDown')),
|
||||||
'labels' => array(
|
'labels' => array(
|
||||||
'export_pdf_title' => Dict::S('UI:Relation:PDFExportOptions'),
|
'export_pdf_title' => Dict::S('UI:Relation:PDFExportOptions'),
|
||||||
'export_as_attachment_title' => $sAttachmentExportTitle,
|
'export_as_attachment_title' => $sAttachmentExportTitle,
|
||||||
'export' => Dict::S('UI:Button:Export'),
|
'export' => Dict::S('UI:Button:Export'),
|
||||||
'cancel' => Dict::S('UI:Button:Cancel'),
|
'cancel' => Dict::S('UI:Button:Cancel'),
|
||||||
'title' => Dict::S('UI:RelationOption:Title'),
|
'title' => Dict::S('UI:RelationOption:Title'),
|
||||||
'untitled' => Dict::S('UI:RelationOption:Untitled'),
|
'untitled' => Dict::S('UI:RelationOption:Untitled'),
|
||||||
'include_list' => Dict::S('UI:RelationOption:IncludeList'),
|
'include_list' => Dict::S('UI:RelationOption:IncludeList'),
|
||||||
'comments' => Dict::S('UI:RelationOption:Comments'),
|
'comments' => Dict::S('UI:RelationOption:Comments'),
|
||||||
'grouping_threshold' => Dict::S('UI:RelationOption:GroupingThreshold'),
|
'grouping_threshold' => Dict::S('UI:RelationOption:GroupingThreshold'),
|
||||||
'refresh' => Dict::S('UI:Button:Refresh'),
|
'refresh' => Dict::S('UI:Button:Refresh'),
|
||||||
'check_all' => Dict::S('UI:SearchValue:CheckAll'),
|
'check_all' => Dict::S('UI:SearchValue:CheckAll'),
|
||||||
'uncheck_all' => Dict::S('UI:SearchValue:UncheckAll'),
|
'uncheck_all' => Dict::S('UI:SearchValue:UncheckAll'),
|
||||||
'none_selected' => Dict::S('UI:Relation:NoneSelected'),
|
'none_selected' => Dict::S('UI:Relation:NoneSelected'),
|
||||||
'nb_selected' => Dict::S('UI:SearchValue:NbSelected'),
|
'nb_selected' => Dict::S('UI:SearchValue:NbSelected'),
|
||||||
'additional_context_info' => Dict::S('UI:Relation:AdditionalContextInfo'),
|
'additional_context_info' => Dict::S('UI:Relation:AdditionalContextInfo'),
|
||||||
'zoom' => Dict::S('UI:Relation:Zoom'),
|
'zoom' => Dict::S('UI:Relation:Zoom'),
|
||||||
'loading' => Dict::S('UI:Loading'),
|
'loading' => Dict::S('UI:Loading'),
|
||||||
),
|
),
|
||||||
'page_format' => array(
|
'page_format' => array(
|
||||||
'label' => Dict::S('UI:Relation:PDFExportPageFormat'),
|
'label' => Dict::S('UI:Relation:PDFExportPageFormat'),
|
||||||
'values' => array(
|
'values' => array(
|
||||||
'A3' => Dict::S('UI:PageFormat_A3'),
|
'A3' => Dict::S('UI:PageFormat_A3'),
|
||||||
'A4' => Dict::S('UI:PageFormat_A4'),
|
'A4' => Dict::S('UI:PageFormat_A4'),
|
||||||
'Letter' => Dict::S('UI:PageFormat_Letter'),
|
'Letter' => Dict::S('UI:PageFormat_Letter'),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
'page_orientation' => array(
|
'page_orientation' => array(
|
||||||
'label' => Dict::S('UI:Relation:PDFExportPageOrientation'),
|
'label' => Dict::S('UI:Relation:PDFExportPageOrientation'),
|
||||||
'values' => array(
|
'values' => array(
|
||||||
'P' => Dict::S('UI:PageOrientation_Portrait'),
|
'P' => Dict::S('UI:PageOrientation_Portrait'),
|
||||||
'L' => Dict::S('UI:PageOrientation_Landscape'),
|
'L' => Dict::S('UI:PageOrientation_Landscape'),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
'additional_contexts' => $aAdditionalContexts,
|
'additional_contexts' => $aAdditionalContexts,
|
||||||
'context_key' => $sContextKey,
|
'context_key' => $sContextKey,
|
||||||
);
|
);
|
||||||
if (!extension_loaded('gd'))
|
if (!extension_loaded('gd')) {
|
||||||
{
|
|
||||||
// PDF export requires GD
|
// PDF export requires GD
|
||||||
unset($aParams['export_as_pdf']);
|
unset($aParams['export_as_pdf']);
|
||||||
}
|
}
|
||||||
if (!extension_loaded('gd') || is_null($sObjClass) || is_null($iObjKey))
|
if (!extension_loaded('gd') || is_null($sObjClass) || is_null($iObjKey)) {
|
||||||
{
|
|
||||||
// Export as Attachment requires GD (for building the PDF) AND a valid objclass/objkey couple
|
// Export as Attachment requires GD (for building the PDF) AND a valid objclass/objkey couple
|
||||||
unset($aParams['export_as_attachment']);
|
unset($aParams['export_as_attachment']);
|
||||||
}
|
}
|
||||||
$oP->add_ready_script("$('#$sId').simple_graph(".json_encode($aParams).");");
|
if ($oP->IsPrintableVersion() || !$sLazyLoading) {
|
||||||
|
$oP->add_ready_script(" $('#$sId').simple_graph(".json_encode($aParams).");");
|
||||||
|
} else {
|
||||||
|
$oP->add_script("function Load(){var aExcluded = []; $('input[name^=excluded]').each( function() {if (!$(this).prop('checked')) { aExcluded.push($(this).val()); }} ); var params= $.extend(".json_encode($aParams).", {excluded_classes: aExcluded}); $('#$sId').simple_graph(params);}");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch(Exception $e)
|
catch(Exception $e)
|
||||||
{
|
{
|
||||||
$oP->add('<div>'.$e->getMessage().'</div>');
|
$oP->add('<div>'.$e->getMessage().'</div>');
|
||||||
}
|
}
|
||||||
$oP->add_script(
|
$oP->add_script(
|
||||||
<<<EOF
|
<<<EOF
|
||||||
|
|
||||||
function DoReload()
|
function DoReload()
|
||||||
{
|
{
|
||||||
@@ -1611,5 +1544,95 @@ EOF
|
|||||||
EOF
|
EOF
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $sContextKey
|
||||||
|
* @param array $aContextParams
|
||||||
|
* @param array $aExcludedObjects
|
||||||
|
* @param \WebPage $oP
|
||||||
|
* @param array $aResults
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
* @throws \CoreException
|
||||||
|
* @throws \DictExceptionMissingString
|
||||||
|
* @throws \ReflectionException
|
||||||
|
* @throws \Twig\Error\LoaderError
|
||||||
|
* @throws \Twig\Error\RuntimeError
|
||||||
|
* @throws \Twig\Error\SyntaxError
|
||||||
|
*/
|
||||||
|
public function DisplayFiltering(string $sContextKey, array $aContextParams, array $aExcludedObjects, WebPage $oP, array $aResults, bool $sLazyLoading = false): array
|
||||||
|
{
|
||||||
|
$aContextDefs = static::GetContextDefinitions($sContextKey, true, $aContextParams);
|
||||||
|
$aExcludedByClass = array();
|
||||||
|
foreach ($aExcludedObjects as $oObj) {
|
||||||
|
if (!array_key_exists(get_class($oObj), $aExcludedByClass)) {
|
||||||
|
$aExcludedByClass[get_class($oObj)] = array();
|
||||||
|
}
|
||||||
|
$aExcludedByClass[get_class($oObj)][] = $oObj->GetKey();
|
||||||
|
}
|
||||||
|
$sSftShort = Dict::S('UI:ElementsDisplayed');
|
||||||
|
$oP->add("<div class=\"not-printable\">\n");
|
||||||
|
$oUiSearchBlock = new Panel($sSftShort, [], Panel::ENUM_COLOR_SCHEME_CYAN, 'dh_flash');
|
||||||
|
$oUiSearchBlock->SetCSSClasses(["ibo-search-form-panel", "display_block"]);
|
||||||
|
$oUiSearchBlock->SetIsCollapsible(true);
|
||||||
|
$oUiHtmlBlock = new Combodo\iTop\Application\UI\Base\Component\Html\Html(
|
||||||
|
<<<EOF
|
||||||
|
|
||||||
|
<div id="ds_flash" class="search_box ibo-display-graph--search-box">
|
||||||
|
<div id="dh_flash_criterion_outer" class="sf_criterion_area"><div class="sf_criterion_row">
|
||||||
|
EOF
|
||||||
|
);
|
||||||
|
$oP->add_ready_script(
|
||||||
|
<<<EOF
|
||||||
|
$("#dh_flash > .sf_title").on("click", function() {
|
||||||
|
$("#dh_flash").toggleClass("closed");
|
||||||
|
});
|
||||||
|
$("#ReloadMovieBtn").button().button("disable");
|
||||||
|
EOF
|
||||||
|
);
|
||||||
|
if ($sLazyLoading) {
|
||||||
|
$oP->add_ready_script("$('#ReloadMovieBtn').button('enable');");
|
||||||
|
} else {
|
||||||
|
$oP->add_ready_script("$('#dh_flash').addClass('closed');");
|
||||||
|
}
|
||||||
|
$aSortedElements = array();
|
||||||
|
foreach ($aResults as $sClassIdx => $aObjects) {
|
||||||
|
foreach ($aObjects as $oCurrObj) {
|
||||||
|
$sSubClass = get_class($oCurrObj);
|
||||||
|
$aSortedElements[$sSubClass] = MetaModel::GetName($sSubClass);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
asort($aSortedElements);
|
||||||
|
$idx = 0;
|
||||||
|
foreach ($aSortedElements as $sSubClass => $sClassName) {
|
||||||
|
$oUiHtmlBlock->AddHtml("<div><input type=\"checkbox\" id=\"exclude_$idx\" name=\"excluded[]\" value=\"$sSubClass\" checked onChange=\"$('#ReloadMovieBtn').button('enable')\"><label for=\"exclude_$idx\">");
|
||||||
|
$oUiMedallionBlock = new MedallionIcon(MetaModel::GetClassIcon($sSubClass, false));
|
||||||
|
$oUiMedallionBlock->SetDescription($sClassName);
|
||||||
|
$oUiHtmlBlock->AddHtml(BlockRenderer::RenderBlockTemplates($oUiMedallionBlock));
|
||||||
|
$oUiHtmlBlock->AddHtml("</label></div>");
|
||||||
|
$idx++;
|
||||||
|
}
|
||||||
|
$oUiHtmlBlock->AddHtml("</div>");
|
||||||
|
if ($sLazyLoading) {
|
||||||
|
$sOnCLick = "Load(); $('#ReloadMovieBtn').attr('onclick','DoReload()');$('#ReloadMovieBtn').html('".Dict::S('UI:Button:Refresh')."');";
|
||||||
|
$oUiHtmlBlock->AddHtml("<button type=\"button\" id=\"ReloadMovieBtn\" class=\"ibo-button ibo-is-neutral ibo-is-regular\" onClick=\"$sOnCLick\">".Dict::S('Relation:impacts/LoadData')."</button></div></form>");
|
||||||
|
} else {
|
||||||
|
$sOnCLick = "DoReload()";
|
||||||
|
$oUiHtmlBlock->AddHtml("<button type=\"button\" id=\"ReloadMovieBtn\" class=\"ibo-button ibo-is-neutral ibo-is-regular\" onClick=\"$sOnCLick\">".Dict::S('UI:Button:Refresh')."</button></div></form>");
|
||||||
|
}
|
||||||
|
$oUiHtmlBlock->AddHtml("</div>\n");
|
||||||
|
$oUiHtmlBlock->AddHtml("</div>\n"); // class="not-printable"
|
||||||
|
|
||||||
|
$oUiSearchBlock->AddSubBlock($oUiHtmlBlock);
|
||||||
|
$oP->AddUiBlock($oUiSearchBlock);
|
||||||
|
|
||||||
|
$aAdditionalContexts = array();
|
||||||
|
foreach ($aContextDefs as $sKey => $aDefinition) {
|
||||||
|
$aAdditionalContexts[] = array('key' => $sKey, 'label' => Dict::S($aDefinition['dict']), 'oql' => $aDefinition['oql'], 'default' => (array_key_exists('default', $aDefinition) && ($aDefinition['default'] == 'yes')));
|
||||||
|
}
|
||||||
|
|
||||||
|
return array($aExcludedByClass, $aAdditionalContexts);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
1844
js/simple_graph.js
1844
js/simple_graph.js
File diff suppressed because it is too large
Load Diff
23
pages/UI.php
23
pages/UI.php
@@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
use Combodo\iTop\Application\Helper\Session;
|
use Combodo\iTop\Application\Helper\Session;
|
||||||
use Combodo\iTop\Application\TwigBase\Twig\TwigHelper;
|
use Combodo\iTop\Application\TwigBase\Twig\TwigHelper;
|
||||||
|
use Combodo\iTop\Application\UI\Base\Component\Alert\AlertUIBlockFactory;
|
||||||
use Combodo\iTop\Application\UI\Base\Component\Button\ButtonUIBlockFactory;
|
use Combodo\iTop\Application\UI\Base\Component\Button\ButtonUIBlockFactory;
|
||||||
use Combodo\iTop\Application\UI\Base\Component\DataTable\DataTableUIBlockFactory;
|
use Combodo\iTop\Application\UI\Base\Component\DataTable\DataTableUIBlockFactory;
|
||||||
use Combodo\iTop\Application\UI\Base\Component\Form\Form;
|
use Combodo\iTop\Application\UI\Base\Component\Form\Form;
|
||||||
@@ -18,6 +19,7 @@ use Combodo\iTop\Application\UI\Base\Component\Title\TitleUIBlockFactory;
|
|||||||
use Combodo\iTop\Application\UI\Base\Component\Toolbar\ToolbarUIBlockFactory;
|
use Combodo\iTop\Application\UI\Base\Component\Toolbar\ToolbarUIBlockFactory;
|
||||||
use Combodo\iTop\Application\UI\Base\Layout\PageContent\PageContentFactory;
|
use Combodo\iTop\Application\UI\Base\Layout\PageContent\PageContentFactory;
|
||||||
use Combodo\iTop\Application\UI\Base\Layout\UIContentBlock;
|
use Combodo\iTop\Application\UI\Base\Layout\UIContentBlock;
|
||||||
|
use Combodo\iTop\Application\UI\Base\Layout\UIContentBlockUIBlockFactory;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Displays a popup welcome message, once per session at maximum
|
* Displays a popup welcome message, once per session at maximum
|
||||||
@@ -266,21 +268,12 @@ function DisplayMultipleSelectionForm(WebPage $oP, DBSearch $oFilter, string $sN
|
|||||||
function DisplayNavigatorListTab($oP, $aResults, $sRelation, $sDirection, $oObj)
|
function DisplayNavigatorListTab($oP, $aResults, $sRelation, $sDirection, $oObj)
|
||||||
{
|
{
|
||||||
$oP->SetCurrentTab('UI:RelationshipList');
|
$oP->SetCurrentTab('UI:RelationshipList');
|
||||||
$oP->add("<div id=\"impacted_objects\">");
|
$oImpactedObject = UIContentBlockUIBlockFactory::MakeStandard("impacted_objects", ['ibo-is-visible']);
|
||||||
$sOldRelation = $sRelation;
|
$oP->AddSubBlock($oImpactedObject);
|
||||||
if (($sRelation == 'impacts') && ($sDirection == 'up'))
|
$oImpactedObject->AddSubBlock(AlertUIBlockFactory::MakeForWarning(Dict::S("Relation:impacts/FilteredData"), '', "alert_filtered_list")->SetIsHidden(true));
|
||||||
{
|
$oImpactedObjectList = UIContentBlockUIBlockFactory::MakeStandard("impacted_objects_lists", ['ibo-is-visible']);
|
||||||
$sOldRelation = 'depends on';
|
$oImpactedObject->AddSubBlock($oImpactedObjectList);
|
||||||
}
|
$oImpactedObjectList->AddSubBlock(UIContentBlockUIBlockFactory::MakeStandard("impacted_objects_lists_placeholder", ['ibo-is-visible']));
|
||||||
$oP->add("<div id=\"impacted_objects_lists\">");
|
|
||||||
$oP->add("<div id=\"impacted_objects_lists_placeholder\"></div>");
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Content is rendered asynchronously via pages/ajax.render.php?operation=relation_lists
|
|
||||||
*/
|
|
||||||
|
|
||||||
$oP->add("</div>");
|
|
||||||
$oP->add("</div>");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function DisplayNavigatorGroupTab($oP)
|
function DisplayNavigatorGroupTab($oP)
|
||||||
|
|||||||
Reference in New Issue
Block a user