--- ./include/hosts.inc.php.orig	2014-06-23 16:12:58.000000000 +0200
+++ ./include/hosts.inc.php	2014-08-11 16:28:12.000000000 +0200
@@ -812,3 +812,53 @@
 
 	return 0;
 }
+
+function gvConfigHandle($gv, $config) {
+	foreach ($config as $attribute => $value) {
+		gv::setv($gv, $attribute, $value);
+	}
+}
+
+function gvDrawParentTemplates($gv, $templateId, $nodeDef = array(), $edgeDef = array(), $deep = false) {
+	$linkedTemplates = API::Template()->get(array(
+		'templateids' => $templateId,
+		'selectParentTemplates' => array('templateid', 'name'),
+		'output' => array('templateid', 'name')
+	));
+
+	foreach ($linkedTemplates as $template) {
+		$headNode = gv::node($gv, $template['name']);
+		gvConfigHandle(&$headNode, $nodeDef);
+		foreach ($template['parentTemplates'] as $parentTemplate) {
+			$gvEdge = gv::edge($headNode, $parentTemplate['name']);
+			gvConfigHandle(&$gvEdge, $edgeDef);
+
+			gvDrawParentTemplates(&$gv, $parentTemplate['templateid'], $nodeDef, $edgeDef, $deep);
+			if ($deep) {
+				gvDrawChildTemplates(&$gv, $parentTemplate['templateid'], $nodeDef, $edgeDef);
+			}
+		}
+	}
+}
+
+function gvDrawChildTemplates($gv, $hostId, $nodeDef = array(), $edgeDef = array(), $deep = false) {
+	$linkedToTemplates = API::Template()->get(array(
+		'templateids' => $hostId,
+		'selectTemplates' => array('templateid', 'name'),
+		'output' => array('templateid', 'name')
+	));
+
+	foreach ($linkedToTemplates as $template) {
+		$tailNode = gv::node($gv, $template['name']);
+		gvConfigHandle(&$tailNode, $nodeDef);
+		foreach ($template['templates'] as $childTemplate) {
+			$gvEdge = gv::edge($childTemplate['name'], $tailNode);
+			gvConfigHandle(&$gvEdge, $edgeDef);
+
+			gvDrawChildTemplates(&$gv, $childTemplate['templateid'], $nodeDef, $edgeDef, $deep);
+			if ($deep) {
+				gvDrawParentTemplates(&$gv, $childTemplate['templateid'], $nodeDef, $edgeDef);
+			}
+		}
+	}
+}
--- ./include/views/configuration.template.edit.php.orig	2014-07-17 15:49:46.000000000 +0200
+++ ./include/views/configuration.template.edit.php	2014-08-11 00:12:12.000000000 +0200
@@ -447,6 +447,10 @@
 ));
 $divTabs->addTab('macroTab', _('Macros'), $macrosView->render());
 
+// Linkage overview
+$tmplTreeView = new Cimg('data:image/png;base64,'.$data['tmplTreeImage'], _('Template tree'));
+$divTabs->addTab('tmplTreeTab', _('Linkage overview'), $tmplTreeView);
+
 $frmHost->addItem($divTabs);
 
 // Footer
--- ./templates.php.orig	2014-07-17 15:49:50.000000000 +0200
+++ ./templates.php	2014-08-11 16:34:49.000000000 +0200
@@ -24,6 +24,7 @@
 require_once dirname(__FILE__).'/include/screens.inc.php';
 require_once dirname(__FILE__).'/include/forms.inc.php';
 require_once dirname(__FILE__).'/include/ident.inc.php';
+require_once 'gv.php';
 
 if (isset($_REQUEST['go']) && $_REQUEST['go'] == 'export' && isset($_REQUEST['templates'])) {
 	$exportData = true;
@@ -453,6 +454,48 @@
 		'output' => array('templateid', 'name')
 	));
 
+	$gvGraphCfg = array(
+		'nodesep' => '0.1',
+		'rankdir' => 'RL',
+		'bgcolor' => 'transparent');
+
+	$gvNodeCfg = array(
+		'fontname' => 'verdana arial helvetica sans-serif',
+		'fontsize' => '7',
+		'height'   => '0',
+		'shape'    => 'none');
+
+	$gvEdgeCfg = array(
+		'arrowhed'  => 'normal',
+		'arrowsize' => '0.5',
+		'dir'       => 'back');
+
+	$gvRootNodeCfg = array('fontname' => 'verdana arial helvetica sans-serif bold');
+
+	$gvGraph = gv::strictdigraph(_('Linkage overview'));
+	gvConfigHandle(&$gvGraph, $gvGraphCfg);
+
+	gvDrawParentTemplates(&$gvGraph, $templateId, $gvNodeCfg, $gvEdgeCfg, false);
+	gvDrawChildTemplates(&$gvGraph, $templateId, $gvNodeCfg, $gvEdgeCfg, false);
+
+	if (isset($data['dbTemplate']['name'])) {
+	  $gvRootNode = gv::findnode($gvGraph, $data['dbTemplate']['name']);
+	  gvConfigHandle(&$gvRootNode, $gvRootNodeCfg);
+	}
+
+	gv::layout($gvGraph, 'dot');
+
+	/*
+	 * fixme: poor work-around because:
+	 *        string gv::renderresult (graph_handle ing ,string format);
+	 *        didn't work for any reason
+	 */
+	ob_start();
+	gv::renderresult($gvGraph, 'png', null);
+	$data['tmplTreeImage'] = base64_encode(ob_get_contents());
+	ob_end_clean();
+	gv::rm($gvGraph);
+
 	CArrayHelper::sort($data['linkedTemplates'], array('name'));
 
 	$templateForm = new CView('configuration.template.edit', $data);
@@ -492,8 +535,9 @@
 		_('Screens'),
 		_('Discovery'),
 		_('Web'),
-		_('Linked templates'),
-		_('Linked to')
+		//_('Linked templates'),
+		//_('Linked to'),
+		_('Linkage overview')
 	));
 
 	// get templates
@@ -560,15 +604,55 @@
 		$httpTests = array(new CLink(_('Web'), 'httpconf.php?groupid='.$_REQUEST['groupid'].'&hostid='.$template['templateid']),
 			' ('.$template['httpTests'].')');
 
+		$gvGraphCfg = array(
+			'nodesep' => '0.1',
+			'rankdir' => 'RL',
+			'ranksep' => '0.2',
+			'bgcolor' => 'transparent');
+
+		$gvRootNodeCfg = array(
+			'fillcolor' => 'transparent',
+			'fontname'  => 'verdana arial helvetica sans-serif',
+			'fontsize'  => '7',
+			'height'    => '0',
+			'shape'     => 'none');
+
+		$gvNodeCfg = array(
+			'fillcolor' => 'transparent',
+			'fontname'  => 'verdana arial helvetica sans-serif',
+			'fontsize'  => '7',
+			'height'    => '0',
+			'shape'     => 'none',
+			'style'     => 'filled');
+
+		$gvEdgeCfg = array(
+			'arrowhead' => 'normal',
+			'arrowsize' => '0.5',
+			'dir'       => 'back');
+
+		$gvGraph = gv::strictdigraph($template['name']);
+		gvConfigHandle(&$gvGraph, $gvGraphCfg);
+
+		$gvRootNode = gv::node($gvGraph, $template['name']);
+		gvConfigHandle(&$gvRootNode, $gvRootNodeCfg);
+
 		order_result($template['parentTemplates'], 'name');
 
 		$i = 0;
 		$linkedTemplatesOutput = array();
 
 		foreach ($template['parentTemplates'] as $linkedTemplate) {
+			$gvNode = gv::node($gvGraph, $linkedTemplate['name']);
+			gvConfigHandle(&$gvNode, $gvNodeCfg);
+
+			$gvEdge = gv::edge($gvGraph, $template['name'], $linkedTemplate['name']);
+			gvConfigHandle(&$gvEdge, $gvEdgeCfg);
+
 			$i++;
 
 			if ($i > $config['max_in_table']) {
+				gv::setv($gvNode, 'label', '...');
+
 				$linkedTemplatesOutput[] = '...';
 				$linkedTemplatesOutput[] = '//empty element for array_pop';
 				break;
@@ -598,7 +682,15 @@
 		order_result($linkedToObjects, 'name');
 
 		foreach ($linkedToObjects as $linkedToHost) {
+			$gvNode = gv::node($gvGraph, $linkedToHost['name']);
+			gvConfigHandle(&$gvNode, $gvNodeCfg);
+
+			$gvEdge = gv::edge($gvGraph, $linkedToHost['name'], $template['name']);
+			gvConfigHandle(&$gvEdge, $gvEdgeCfg);
+
 			if (++$i > $config['max_in_table']) {
+				gv::setv($gvNode, 'label', '...');
+
 				$linkedToOutput[] = '...';
 				$linkedToOutput[] = '//empty element for array_pop';
 				break;
@@ -625,6 +717,20 @@
 		}
 		array_pop($linkedToOutput);
 
+		gv::layout($gvGraph, 'dot');
+
+		/*
+	 	* fixme: poor work-around because:
+	 	*        string gv::renderresult (graph_handle ing ,string format);
+	 	*        didn't work for any reason
+	 	*/
+		ob_start();
+		gv::renderresult($gvGraph, 'png', null);
+		$imgSrc = base64_encode(ob_get_contents());
+		ob_end_clean();
+
+		gv::rm($gvGraph);
+
 		$table->addRow(array(
 			new CCheckBox('templates['.$template['templateid'].']', null, null, $template['templateid']),
 			$displayNodes ? get_node_name_by_elid($template['templateid'], true) : null,
@@ -636,8 +742,9 @@
 			$screens,
 			$discoveries,
 			$httpTests,
-			$linkedTemplatesOutput ? new CCol($linkedTemplatesOutput, 'wraptext') : '-',
-			$linkedToOutput ? new CCol($linkedToOutput, 'wraptext') : '-'
+			//$linkedTemplatesOutput ? new CCol($linkedTemplatesOutput, 'wraptext') : '-',
+			//$linkedToOutput ? new CCol($linkedToOutput, 'wraptext') : '-',
+			new Cimg('data:image/png;base64,'.$imgSrc, _('Linkage overview'))
 		));
 	}
 
--- ./include/views/configuration.host.edit.php.orig	2014-06-23 16:12:58.000000000 +0200
+++ ./include/views/configuration.host.edit.php	2014-08-11 13:25:41.000000000 +0200
@@ -838,6 +838,11 @@
 $inventoryFormList->addRow('', $clearFixDiv);
 
 $divTabs->addTab('inventoryTab', _('Host inventory'), $inventoryFormList);
+
+// Linkage overview
+$hostTreeView = new Cimg('data:image/png;base64,'.$data['hostTreeImage'], _('Host tree'));
+$divTabs->addTab('hostTreeTab', _('Linkage overview'), $hostTreeView);
+
 $frmHost->addItem($divTabs);
 
 /*
--- ./hosts.php.orig	2014-08-11 16:38:49.000000000 +0200
+++ ./hosts.php	2014-08-11 16:34:00.000000000 +0200
@@ -21,6 +21,7 @@
 
 require_once dirname(__FILE__).'/include/config.inc.php';
 require_once dirname(__FILE__).'/include/forms.inc.php';
+require_once 'gv.php';
 
 if (isset($_REQUEST['go']) && $_REQUEST['go'] == 'export' && isset($_REQUEST['hosts'])) {
 	$page['file'] = 'zbx_export_hosts.xml';
@@ -738,6 +739,54 @@
 		$data['dbHost'] = $dbHost;
 	}
 
+	$gvGraphCfg = array(
+		'nodesep' => '0.1',
+		'rankdir' => 'RL',
+		'bgcolor' => 'transparent');
+
+	$gvNodeCfg = array(
+		'fontname' => 'verdana arial helvetica sans-serif',
+		'fontsize' => '7',
+		'height'   => '0',
+		'shape'    => 'none');
+
+	$gvEdgeCfg = array(
+		'arrowhed'  => 'normal',
+		'arrowsize' => '0.5',
+		'dir'       => 'back');
+
+	$gvRootNodeCfg = array(
+		'shape'    => 'none',
+		'fontsize' => '7',
+		'height'   => '0',
+		'fontname' => 'verdana arial helvetica sans-serif');
+
+	$gvGraph = gv::strictdigraph(_('Linkage overview'));
+	gvConfigHandle(&$gvGraph, $gvGraphCfg);
+
+	$gvRootNode = gv::node($gvGraph, $data['dbHost']['name']);
+	gvConfigHandle(&$gvRootNode, $gvRootNodeCfg);
+
+	foreach ($data['dbHost']['parentTemplates'] as $parentTemplate) {
+		$gvEdge = gv::edge($gvRootNode, $parentTemplate['name']);
+		gvConfigHandle(&$gvEdge, $gvEdgeCfg);
+		gvDrawParentTemplates(&$gvGraph, $parentTemplate['templateid'], $gvNodeCfg, $gvEdgeCfg);
+	}
+
+	gv::layout($gvGraph, 'dot');
+
+	/*
+	* fixme: poor work-around because:
+	*        string gv::renderresult (graph_handle ing ,string format);
+	*        didn't work for any reason
+	*/
+	ob_start();
+	gv::renderresult($gvGraph, 'png', null);
+	$data['hostTreeImage'] = base64_encode(ob_get_contents());
+	ob_end_clean();
+
+	gv::rm($gvGraph);
+
 	$hostForm = new CView('configuration.host.edit', $data);
 	$hostsWidget->addItem($hostForm->render());
 
