diff --git a/core/displayablegraph.class.inc.php b/core/displayablegraph.class.inc.php
index ed5849c80..529639e7d 100644
--- a/core/displayablegraph.class.inc.php
+++ b/core/displayablegraph.class.inc.php
@@ -282,22 +282,45 @@ class DisplayableNode extends GraphNode
{
if (count($aGroupProps['nodes']) >= $iThresholdCount)
{
- $oNewNode = new DisplayableGroupNode($oGraph, $this->GetId().'::'.(($sStatus == 'reached') ? '_reached': ''));
- $oNewNode->SetProperty('label', 'x'.$aGroupProps['count']);
- $oNewNode->SetProperty('icon_url', $aGroupProps['icon_url']);
- $oNewNode->SetProperty('class', $sClass);
- $oNewNode->SetProperty('is_reached', ($sStatus == 'reached'));
- $oNewNode->SetProperty('count', $aGroupProps['count']);
+ $sNewId = $this->GetId().'::'.(($sStatus == 'reached') ? '_reached': '');
+ $oNewNode = $oGraph->GetNode($sNewId);
+ if ($oNewNode == null)
+ {
+ $oNewNode = new DisplayableGroupNode($oGraph, $sNewId);
+ $oNewNode->SetProperty('label', 'x'.$aGroupProps['count']);
+ $oNewNode->SetProperty('icon_url', $aGroupProps['icon_url']);
+ $oNewNode->SetProperty('class', $sClass);
+ $oNewNode->SetProperty('is_reached', ($sStatus == 'reached'));
+ $oNewNode->SetProperty('count', $aGroupProps['count']);
+ }
+ else
+ {
+ $oNewNode->SetProperty('count', $oNewNode->GetProperty('count')+$aGroupProps['count']);
+ }
+
+ try
+ {
+ $oIncomingEdge = new DisplayableEdge($oGraph, $this->GetId().'-'.$oNewNode->GetId(), $this, $oNewNode);
+ }
+ catch(Exception $e)
+ {
+ // Ignore this redundant egde
+ }
- $oIncomingEdge = new DisplayableEdge($oGraph, $this->GetId().'-'.$oNewNode->GetId(), $this, $oNewNode);
-
foreach($aGroupProps['nodes'] as $oNode)
{
foreach($oNode->GetIncomingEdges() as $oEdge)
{
if ($oEdge->GetSourceNode()->GetId() !== $this->GetId())
{
- $oNewEdge = new DisplayableEdge($oGraph, $oEdge->GetId().'::'.$sClass, $oEdge->GetSourceNode(), $oNewNode);
+ try
+ {
+ $oNewEdge = new DisplayableEdge($oGraph, $oEdge->GetId().'::'.$sClass, $oEdge->GetSourceNode(), $oNewNode);
+ }
+ catch(Exception $e)
+ {
+ // ignore this edge
+ }
}
}
foreach($oNode->GetOutgoingEdges() as $oEdge)
@@ -825,7 +848,6 @@ class DisplayableGraph extends SimpleGraph
{
throw new Exception($sDot);
}
- $sDot = preg_replace('/.*label=.*,/', '', $sDot); // Get rid of label lines since they may contain weird characters than can break the split and pattern matching below
$aChunks = explode(";", $sDot);
foreach($aChunks as $sChunk)
@@ -975,7 +997,7 @@ class DisplayableGraph extends SimpleGraph
$yMin = $aRemainingArea['ymin'];
$yMax = $aRemainingArea['ymax'];
- //$oPdf->Rect($xMin, $yMin, $xMax - $xMin, $yMax - $yMin, 'D', array(), array(225, 225, 225));
+ //$oPdf->Rect($xMin, $yMin, $xMax - $xMin, $yMax - $yMin, 'D', array(), array(225, 50, 50));
$fPageW = $xMax - $xMin;
$fPageH = $yMax - $yMin;
@@ -1093,7 +1115,7 @@ class DisplayableGraph extends SimpleGraph
$yMax = $yPos - $fPadding;
}
- return array('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);
}
/**
diff --git a/core/metamodel.class.php b/core/metamodel.class.php
index 3b1b1194f..5e0433750 100644
--- a/core/metamodel.class.php
+++ b/core/metamodel.class.php
@@ -1403,10 +1403,11 @@ abstract class MetaModel
$aQueries[$sRemoteClass]['down'][$sLocalClass]['sQueryUp'] = $aNeighbourData['sQueryUp'];
$aQueries[$sRemoteClass]['down'][$sLocalClass]['sDirection'] = 'both';
}
- else
- {
- throw new Exception("Legacy definition of the relation '$sRelCode/$sRevertCode', defined on $sLocalClass (relation: $sRevertCode, inherited to $sClass), missing the counterpart query on class $sRemoteClass ($sRelCode)");
- }
+ // Be silent in order to transparently support legacy data models where the counterpart query does not always exist
+ //else
+ //{
+ // throw new Exception("Legacy definition of the relation '$sRelCode/$sRevertCode', defined on $sLocalClass (relation: $sRevertCode, inherited to $sClass), missing the counterpart query on class $sRemoteClass ($sRelCode)");
+ //}
}
}
}
diff --git a/core/relationgraph.class.inc.php b/core/relationgraph.class.inc.php
index cbcd72727..b7dbddeca 100644
--- a/core/relationgraph.class.inc.php
+++ b/core/relationgraph.class.inc.php
@@ -48,7 +48,7 @@ class RelationObjectNode extends GraphNode
/**
* Formatting for GraphViz
*/
- public function GetDotAttributes()
+ public function GetDotAttributes($bNoLabel = false)
{
$sDot = parent::GetDotAttributes();
if ($this->GetProperty('developped', false))
@@ -114,7 +114,7 @@ class RelationRedundancyNode extends GraphNode
/**
* Formatting for GraphViz
*/
- public function GetDotAttributes()
+ public function GetDotAttributes($bNoLabel = false)
{
$sDisplayThreshold = sprintf('%.1f', $this->GetProperty('threshold'));
$sDot = 'shape=doublecircle,fillcolor=indianred,fontcolor=papayawhip,label="'.$sDisplayThreshold.'"';
diff --git a/core/simplegraph.class.inc.php b/core/simplegraph.class.inc.php
index 49e5ec0b2..1dffe56af 100644
--- a/core/simplegraph.class.inc.php
+++ b/core/simplegraph.class.inc.php
@@ -128,10 +128,14 @@ class GraphNode extends GraphElement
$oGraph->_AddNode($this);
}
- public function GetDotAttributes()
+ public function GetDotAttributes($bNoLabel = false)
{
- $sLabel = addslashes($this->GetProperty('label', $this->GetId()));
- $sDot = 'label="'.$sLabel.'"';
+ $sDot = '';
+ if (!$bNoLabel)
+ {
+ $sLabel = addslashes($this->GetProperty('label', $this->GetId()));
+ $sDot = 'label="'.$sLabel.'"';
+ }
return $sDot;
}
@@ -264,10 +268,14 @@ class GraphEdge extends GraphElement
return $this->oSinkNode;
}
- public function GetDotAttributes()
+ public function GetDotAttributes($bNoLabel = false)
{
- $sLabel = addslashes($this->GetProperty('label', ''));
- $sDot = 'label="'.$sLabel.'"';
+ $sDot = '';
+ if (!$bNoLabel)
+ {
+ $sLabel = addslashes($this->GetProperty('label', ''));
+ $sDot = 'label="'.$sLabel.'"';
+ }
return $sDot;
}
}
@@ -443,9 +451,10 @@ class SimpleGraph
/**
* Get the description of the graph as a text string in the graphviz 'dot' language
+ * @param $bNoLabel bool Whether or not to include the labels in the dot file
* @return string
*/
- public function GetDotDescription()
+ public function GetDotDescription($bNoLabel = false)
{
$sDot =
<< Error: The command: $CommandLine
returned $iRetCode
The output of the command is:
\n".implode("\n", $aOutput)."";
+ IssueLog::Error($sHtml);
}
else
{
$sHtml = ''.file_get_contents($sXdotFilePath).''; - @unlink($sImageFilePath); + @unlink($sXdotFilePath); } - @unlink($sXdotFilePath); + @unlink($sDotFilePath); } else { diff --git a/datamodels/2.x/itop-change-mgmt/de.dict.itop-change-mgmt.php b/datamodels/2.x/itop-change-mgmt/de.dict.itop-change-mgmt.php index 0d7da474a..cafb6ca21 100644 --- a/datamodels/2.x/itop-change-mgmt/de.dict.itop-change-mgmt.php +++ b/datamodels/2.x/itop-change-mgmt/de.dict.itop-change-mgmt.php @@ -103,7 +103,7 @@ Dict::Add('DE DE', 'German', 'Deutsch', array( 'UI-ChangeManagementOverview-ChangeByDomain-last-7-days' => 'Changes der letzten sieben Tage nach Typ', 'UI-ChangeManagementOverview-ChangeByStatus-last-7-days' => 'Changes der letzten sieben Tage nach Status', 'Tickets:Related:OpenChanges' => 'Open changes~~', - 'Tickets:Related:RecentChanges' => 'Recent changes~~', + 'Tickets:Related:RecentChanges' => 'Recent changes (72h)~~', 'Class:Change/Attribute:changemanager_email' => 'Change Manager Email', 'Class:Change/Attribute:changemanager_email+' => '', 'Class:Change/Attribute:parent_name' => 'Parent Change ref', diff --git a/datamodels/2.x/itop-change-mgmt/en.dict.itop-change-mgmt.php b/datamodels/2.x/itop-change-mgmt/en.dict.itop-change-mgmt.php index 76e5bb7b0..356562158 100755 --- a/datamodels/2.x/itop-change-mgmt/en.dict.itop-change-mgmt.php +++ b/datamodels/2.x/itop-change-mgmt/en.dict.itop-change-mgmt.php @@ -47,7 +47,7 @@ Dict::Add('EN US', 'English', 'English', array( 'UI-ChangeManagementOverview-ChangeByDomain-last-7-days' => 'Changes by domain for the last 7 days', 'UI-ChangeManagementOverview-ChangeByStatus-last-7-days' => 'Changes by status for the last 7 days', 'Tickets:Related:OpenChanges' => 'Open changes', - 'Tickets:Related:RecentChanges' => 'Recent changes', + 'Tickets:Related:RecentChanges' => 'Recent changes (72h)', )); // Dictionnay conventions diff --git a/datamodels/2.x/itop-change-mgmt/fr.dict.itop-change-mgmt.php b/datamodels/2.x/itop-change-mgmt/fr.dict.itop-change-mgmt.php index 6d5c13d7d..ac6b60b3b 100755 --- a/datamodels/2.x/itop-change-mgmt/fr.dict.itop-change-mgmt.php +++ b/datamodels/2.x/itop-change-mgmt/fr.dict.itop-change-mgmt.php @@ -126,6 +126,6 @@ Dict::Add('FR FR', 'French', 'Français', array( 'UI-ChangeManagementOverview-ChangeByStatus-last-7-days' => 'Changements par statut', 'UI:ChangeMgmtMenuOverview:Title' => 'Tableau de bord des changements pour les 7 derniers jours', 'Tickets:Related:OpenChanges' => 'Changements en cours', - 'Tickets:Related:RecentChanges' => 'Changements récents', + 'Tickets:Related:RecentChanges' => 'Changements récents (72h)', )); ?> diff --git a/js/simple_graph.js b/js/simple_graph.js index 0b2ae4f3a..c12fa4c5e 100644 --- a/js/simple_graph.js +++ b/js/simple_graph.js @@ -269,10 +269,10 @@ $(function() this.options.ymax = -9999; for(var k in this.aNodes) { - this.options.xmin = Math.min(this.aNodes[k].x + this.aNodes[k].tx, this.options.xmin); - this.options.xmax = Math.max(this.aNodes[k].x + this.aNodes[k].tx, this.options.xmax); - this.options.ymin = Math.min(this.aNodes[k].y + this.aNodes[k].ty, this.options.ymin); - this.options.ymax = Math.max(this.aNodes[k].y + this.aNodes[k].ty, this.options.ymax); + this.options.xmin = Math.min(this.aNodes[k].x + this.aNodes[k].tx - this.aNodes[k].width/2, this.options.xmin); + this.options.xmax = Math.max(this.aNodes[k].x + this.aNodes[k].tx + this.aNodes[k].width/2, this.options.xmax); + this.options.ymin = Math.min(this.aNodes[k].y + this.aNodes[k].ty - this.aNodes[k].width/2, this.options.ymin); + this.options.ymax = Math.max(this.aNodes[k].y + this.aNodes[k].ty + this.aNodes[k].width/2, this.options.ymax); } }, _get_edge_path: function(oEdge) @@ -617,8 +617,10 @@ $(function() this.element.closest('.ui-tabs').tabs({ heightStyle: "fill" }); this._close_all_tooltips(); this.oPaper.rect(0, 0, this.element.width(), this.element.height()).attr({fill: '#000', opacity: 0.4, 'stroke-width': 0}); + $('#'+sId+'_refresh_btn').button('disable'); $.post(sUrl, {excluded_classes: this.options.excluded_classes, g: this.options.grouping_threshold, sources: this.options.sources, excluded: this.options.excluded, contexts: aContexts, context_key: this.options.context_key }, function(data) { me.load(data); + $('#'+sId+'_refresh_btn').button('enable'); }, 'json'); }, export_as_attachment: function() @@ -665,13 +667,22 @@ $(function() $.post(sUrl, oParams, function(data) { var sDownloadLink = GetAbsoluteUrlAppRoot()+'pages/ajax.render.php?operation=download_document&class=Attachment&id='+data.att_id+'&field=contents'; var sIcon = GetAbsoluteUrlModulesRoot()+'itop-attachments/icons/pdf.png'; - $('#attachments').append(''); if (jTab != null) { var re = /^([^(]+)\(([0-9]+)\)(.*)$/; var aParts = re.exec(sTabText); - var iPrevCount = parseInt(aParts[2], 10); - jTab.find('span').html(aParts[1]+'('+(1 + iPrevCount)+')'+aParts[3]); + if (aParts == null) + { + // First attachment + $('#attachments').html(''); + jTab.find('span').html(sTabText +' (1)'); + } + else + { + $('#attachments').append(''); + var iPrevCount = parseInt(aParts[2], 10); + jTab.find('span').html(aParts[1]+'('+(1 + iPrevCount)+')'+aParts[3]); + } } }, 'json'); return false; @@ -691,15 +702,15 @@ $(function() return sTooltipContent; }, items: '.popupMenuTarget', + tooltipClass: 'tooltip-simple-graph', position: { my: "center bottom-10", - at: "center top", + at: "center top", using: function( position, feedback ) { $(this).css( position ); $( "