sysmodellibs/sysmodelgen/extra/dependencies.xsl
changeset 7 3c36c452f013
parent 6 5b32dc297d05
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sysmodellibs/sysmodelgen/extra/dependencies.xsl	Wed Oct 13 16:21:25 2010 +0100
@@ -0,0 +1,350 @@
+<?xml version="1.0"?>
+<xsl:stylesheet  xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" xmlns:s="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+	<xsl:import href="postprocess.xsl"/>	
+	<xsl:output method="xml"/>
+	<xsl:variable name="Size">
+		<xsl:choose>
+			<xsl:when test="/s:svg[substring-after(@class,'-')='fixed' and @class!='component-fixed']">
+				<xsl:value-of select="//s:g[@class=substring-before(/s:svg/@class,'-')]/s:rect/@width"/>
+			</xsl:when>
+			<xsl:otherwise><xsl:value-of select="//s:g[@class='component']/s:use/@width"/></xsl:otherwise>
+		</xsl:choose>
+	 </xsl:variable>
+	<xsl:key name="Using" match="Bin" use="@name"/>
+	<xsl:key name="Used-by" match="dep" use="@name"/>
+	<xsl:key name="Id" match="component|collection|package" use="@id"/>
+	<xsl:variable name="Rank" select="document('')/*/*[@name='RANK']/*"/>
+
+<xsl:template name="RANK">
+<layer rank="0"/>
+<package rank="1"/>
+<collection rank="2"/>
+<component rank="3"/>
+</xsl:template>
+	
+<xsl:template match="/" mode="my-prefix">dep-</xsl:template>
+<xsl:template match="/SystemDefinition" mode="is-present"><xsl:param name="id"/>
+	<xsl:for-each select="key('Id',$id)">
+		<xsl:choose>
+				<!-- no children and higher than the normal placeholder detail -->
+			<xsl:when test="count(meta|unit)=count(*) and /SystemDefinition/@placeholder-detail and ($Rank[name()=current()/ancestor::SystemDefinition/@placeholder-detail]/@rank &gt;= $Rank[name()=name(current())]/@rank)">1</xsl:when>
+			<xsl:when test="not(/SystemDefinition/@detail-type='fixed')"><xsl:if test="self::component">1</xsl:if></xsl:when>  
+			<xsl:when test="name()=/SystemDefinition/@detail">1</xsl:when>
+		</xsl:choose>
+	</xsl:for-each>
+</xsl:template>
+
+ <xsl:template match="/" mode="my-legend">
+ 	<!-- height="9" width="17" -->
+	<s:text text-anchor="end" dy="0.375em" class="label" x="3" y="3" width="5">Uses</s:text>
+	<s:text text-anchor="end" dy="0.375em" class="label" x="3" y="6" width="5">Used by</s:text>
+	<s:path d="M 4 3 L 14 3" class="arrow" style="stroke-width:0.3!important"/>
+	<s:path d="M 4 6 L 14 6" class="arrowF" style="stroke-width:0.3!important"/>
+	
+	<!-- add at some point:
+	<text text-anchor="end" dy="0.375em" class="label" x="24" y="1.5" >Binary</text>
+	<text text-anchor="end" dy="0.375em" class="label" x="24" y="4.5" >API</text>
+	<text text-anchor="end" dy="0.375em" class="label" x="24" y="7.5" >ECom</text>
+	<path d="M 26 1.5 L 36 1.5" class="arrow" style="stroke-width:0.3!important"/>
+	<path d="M 26 4.5 L 36 4.5" class="arrow api" style="stroke-width:0.3!important"/>
+	<path d="M 26 7.5 L 36 7.5" class="arrow ecom" style="stroke-width:0.3!important"/>
+		-->
+ </xsl:template>
+
+<xsl:template match="*" mode="my-defs">
+	<xsl:variable name="width">
+			<xsl:choose>
+			<xsl:when test="/SystemDefinition/@detail='layer'">4.8</xsl:when>
+			<xsl:when test="/SystemDefinition/@detail='package'">2.4</xsl:when>
+			<xsl:when test="/SystemDefinition/@detail='subblock'">1.2</xsl:when>
+			<xsl:when test="/SystemDefinition/@detail='collection'">0.6</xsl:when>
+			<xsl:otherwise>0.3</xsl:otherwise>
+		</xsl:choose>
+	</xsl:variable>
+    <s:defs>
+    <s:marker id="Triangle"
+      viewBox="-1 -1 7 7" refX="5" refY="2" 
+      markerUnits="strokeWidth"
+      markerWidth="6" markerHeight="6"
+      orient="auto">
+      <s:polygon style="fill:black;stroke:black;" points="0,0 5,2 0,4 0,0"/>
+    </s:marker>
+    <s:marker id="TriangleF"
+      viewBox="-1 -1 7 7" refX="0" refY="2" 
+      markerUnits="strokeWidth"
+      markerWidth="6" markerHeight="6"
+      orient="auto">
+      <s:polygon style="fill:blue;stroke:blue;" points="5,0 5,4 0,2 5,0"/>
+    </s:marker>
+  <s:style type="text/css">
+	path.arrow {
+		marker-end: url(#Triangle);
+		fill:none;stroke: black;
+		stroke-width: 0.3px;
+	}
+	path.arrowF {
+		marker-start: url(#TriangleF);
+		fill:none;stroke: blue;
+		stroke-width: 0.3px;		
+	}
+	path.collection  {
+		stroke-width: 0.6px;	
+	}
+	path.package  {
+		stroke-width: 2.4px;	
+	}
+	path.layer  {
+		stroke-width: 4.8px;	
+	}
+	path.api {
+		stroke-dasharray: 2,1;
+	}
+	path.ecom {
+		stroke-dasharray: 0.1,2;
+		stroke-linecap: round;
+	}
+</s:style>
+  </s:defs>
+</xsl:template>
+ 
+<xsl:template name="lower-rank"><xsl:param name="e1"/><xsl:param name="e2"/>
+	<xsl:variable name="rank"> 
+		<xsl:choose>
+			<xsl:when test="$Rank[name()=$e1]/@rank &gt; $Rank[name()=$e2]/@rank">
+				<xsl:value-of select="$e1"/>
+			</xsl:when>
+			<xsl:otherwise>
+				<xsl:value-of select="$e2"/>
+			</xsl:otherwise>
+		</xsl:choose>
+	</xsl:variable>
+	<xsl:if test="$rank!='component'">
+		<xsl:value-of select="concat(' ',$rank)"/>
+	</xsl:if>
+</xsl:template>
+ 
+ <xsl:template match="s:g" mode="my-overlay"><xsl:param name="id"/>
+ 	<!--  this is far more hacky than I'd like. Better to use a mechanism like the $used below-->
+	<xsl:variable name="libs">	<xsl:text> </xsl:text>
+ 		<xsl:for-each select="document($Data,/)/*">
+			<xsl:variable name="detail" select="/SystemDefinition/@detail"/>
+			<xsl:for-each select="key('Id',$id)/meta[@rel='Dependencies' and (@type='generic' or not(@type))]/dep">
+				<xsl:variable name="d" select="."/>
+				<xsl:for-each select="key('Id',@ref)/ancestor-or-self::*[name()=$detail]">
+					<xsl:value-of select="concat(@id,'&#9;',$d/@type,'&#9;',name(),' ')"/>
+				</xsl:for-each>
+				<xsl:for-each select="key('Id',@ref)[not(ancestor-or-self::*[name()=$detail])]">
+					<xsl:value-of select="concat(@id,'&#9;',$d/@type,'&#9;',name(),' ')"/>
+				</xsl:for-each>
+			</xsl:for-each>
+		</xsl:for-each>
+	</xsl:variable>
+	<xsl:variable name="pos">
+		<xsl:apply-templates select="." mode="item-pos"/>
+	</xsl:variable>
+	<xsl:variable name="h">
+		<xsl:apply-templates select="." mode="height"/>
+	</xsl:variable>
+	<xsl:variable name="w">
+		<xsl:apply-templates select="." mode="item-width"/>
+	</xsl:variable>
+	<xsl:variable name="e"><xsl:for-each select="document($Data,/)/*">
+		<xsl:value-of select="name(key('Id',$id))"/></xsl:for-each>
+	</xsl:variable>
+	<xsl:for-each select="//s:g[contains($libs,concat(' ',@id,'&#9;')) and @id!=$id]">
+		<xsl:variable name="type" select="substring-before(substring-after($libs,concat(' ',@id,'&#9;')),'&#9;')"/>
+		<xsl:variable name="this" select="substring-before(substring-after(substring-after($libs,concat(' ',@id,'&#9;')),'&#9;'),' ')"/>
+		<xsl:call-template name="draw-line">
+			<xsl:with-param name="class">
+				<xsl:text>arrow</xsl:text>
+				<xsl:if test="$type!='' and $type!='bin'">
+					<xsl:value-of select="concat(' ',$type)"/>
+				</xsl:if>
+				<xsl:call-template name="lower-rank">
+					<xsl:with-param name="e1" select="$e"/>
+					<xsl:with-param name="e2" select="substring-before(substring-after(substring-after($libs,concat(' ',@id,'&#9;')),'&#9;'),' ')"/>
+				</xsl:call-template>
+			</xsl:with-param>
+			<xsl:with-param name="h0" select="$h"/>
+			<xsl:with-param name="w0" select="$w"/>
+			<xsl:with-param name="origin" select="$pos"/>
+			<xsl:with-param name="end"><xsl:apply-templates select="." mode="item-pos"/></xsl:with-param>
+			<xsl:with-param name="h1"><xsl:apply-templates select="." mode="height"/></xsl:with-param>
+			<xsl:with-param name="w1"><xsl:apply-templates select="." mode="item-width"/></xsl:with-param>
+		</xsl:call-template>
+	</xsl:for-each>	
+
+	<xsl:variable name="used" select="document($Data,/)//*[name()=/SystemDefinition/@detail]/meta[@rel='Dependencies' and (@type='generic' or not(@type))]/dep[@ref=$id]"/>
+	<xsl:for-each select="//s:g[@id=$used/../../@id and @id!=$id]">
+		<xsl:call-template name="draw-line">
+			<xsl:with-param name="class">
+				<xsl:text>arrowF</xsl:text>
+				<xsl:for-each select="$used[@type and @type!='bin' and ../../@id=current()/@id]">
+					<xsl:value-of select="concat(' ',@type)"/>  
+				</xsl:for-each>
+				<xsl:call-template name="lower-rank">
+					<xsl:with-param name="e1" select="$e"/>
+					<xsl:with-param name="e2" select="name($used[../../@id=current()/@id]/../..)"/>
+				</xsl:call-template>
+			</xsl:with-param>
+			<xsl:with-param name="h0" select="$h"/>
+			<xsl:with-param name="w0" select="$w"/>
+			<xsl:with-param name="origin" select="$pos"/>
+			<xsl:with-param name="end"><xsl:apply-templates select="." mode="item-pos"/></xsl:with-param>
+			<xsl:with-param name="h1"><xsl:apply-templates select="." mode="height"/></xsl:with-param>
+			<xsl:with-param name="w1"><xsl:apply-templates select="." mode="item-width"/></xsl:with-param>
+		</xsl:call-template>
+	</xsl:for-each>	
+
+ </xsl:template>
+ 
+<!-- drawing lines follows -->
+ 
+ <xsl:template name="draw-line"><xsl:param name="origin"/><xsl:param name="end"/><xsl:param name="class"/>
+ 	<xsl:param name="h0"/><xsl:param name="h1"/>
+	<xsl:param name="w0"/><xsl:param name="w1"/>
+ 		<xsl:variable name="x0" select="substring-before($origin,',')"/>
+		<xsl:variable name="y0" select="substring-after($origin,',')"/>
+		<xsl:variable name="x1" select="substring-before($end,',')"/>
+		<xsl:variable name="y1" select="substring-after($end,',')"/>
+		<xsl:variable name="dx" select="$x1 - $x0"/>
+		<xsl:variable name="dy" select="$y1 - $y0"/>
+		<xsl:variable name="sgnY" select="($y1 &gt; $y0) * 2 - 1"/>
+		<xsl:variable name="sgnX" select="($x1 &gt; $x0) * 2 - 1"/>
+		<xsl:if test="contains(substring-after($origin,','),',')">/<xsl:value-of select="$origin"/>/</xsl:if>
+
+		<s:path class="{$class}"><xsl:attribute name="d">
+			<xsl:choose>
+				<xsl:when test="$dy=0">
+					<xsl:call-template name="draw-curve">
+						<xsl:with-param name="origin" select="$origin"/>
+						<xsl:with-param name="end" select="$end"/>			
+						<xsl:with-param name="h0" select="$h0"/>
+						<xsl:with-param name="h1" select="$h1"/>
+						<xsl:with-param name="w0" select="$w0"/>
+						<xsl:with-param name="w1" select="$w1"/>
+					</xsl:call-template>
+				</xsl:when>	
+				<xsl:when test="$dx=0">
+					<xsl:call-template name="draw-vcurve">
+						<xsl:with-param name="origin" select="$origin"/>
+						<xsl:with-param name="end" select="$end"/>
+						<xsl:with-param name="h0" select="$h0"/>			
+						<xsl:with-param name="h1" select="$h1"/>															
+						<xsl:with-param name="w0" select="$w0"/>
+						<xsl:with-param name="w1" select="$w1"/>
+					</xsl:call-template>
+				</xsl:when>	
+				<xsl:otherwise>
+					<xsl:text>M</xsl:text>
+				<xsl:choose>
+						<xsl:when test="$dx &gt; 0 and (($dy &gt; 0 and ($dx * $h0 &gt;= $dy* $w0)) or ($dy &lt;= 0 and ($dx * $h0 &gt;= -$dy* $w0)))">
+							<!-- crop against E side of origin  -->
+							<xsl:variable name="y-off" select="$w0 * 0.5 * $dy div $dx "/>
+							<xsl:value-of select="concat($x0 + 0.5 * $w0,',',$y0 + $y-off)"/>
+						</xsl:when>	
+						<xsl:when test="$dy &gt; 0 and (($dx &gt;= 0 and $dx * $h0 &lt; $dy * $w0) or ($dx &lt;= 0 and -$dx * $h0 &lt; $dy* $w0))"> <!-- and dx < dy  -->
+							<!-- crop against S side of origin  -->
+							<xsl:variable name="x-off" select="$h0 * 0.5 * $dx div $dy"/>
+						 	<xsl:value-of select="concat($x0 +  $x-off, ',' ,$y0 + 0.5 * $h0)"/>
+						</xsl:when>	
+						<xsl:when test="$dy &lt; 0 and (($dx &gt;= 0 and $dx * $h0 &lt; -$dy* $w0) or ($dx &lt;= 0 and -$dx * $h0 &lt; -$dy* $w0))">
+							<!-- crop against N side of origin  -->
+							<xsl:variable name="x-off" select="- $h0 * 0.5 * $dx div $dy"/>
+						 	<xsl:value-of select="concat($x0 +  $x-off, ',' ,$y0 - 0.5 * $h0 )"/>
+						</xsl:when>
+						<xsl:otherwise>
+							<!-- crop against W side or origin -->
+							<xsl:variable name="y-off" select=" - $w0 * 0.5 * $dy div $dx "/>
+							 <xsl:value-of select="concat($x0 - 0.5 * $w0,',',$y0 + $y-off)"/>
+						</xsl:otherwise>
+					</xsl:choose>
+					<xsl:text>L </xsl:text>
+					<xsl:choose>
+						<xsl:when test="$dx &gt; 0 and (($dy &gt; 0 and ($dx * $h1 &gt;= $dy* $w1)) or ($dy &lt;= 0 and ($dx * $h1 &gt;= -$dy* $w1)))">
+							<!-- crop against W side of end  -->
+							<xsl:value-of select="concat($x1 - 0.5 * $w1,',',$y0 + ($dx - 0.5 * $w1) * $dy div $dx)"/>
+						</xsl:when>	
+						<xsl:when test="$dy &gt; 0 and (($dx &gt;= 0 and $dx * $h1 &lt; $dy * $w1) or ($dx &lt;= 0 and -$dx * $h1 &lt; $dy* $w1))"> <!-- and dx < dy  -->
+							<!-- crop against N side of end -->
+							<xsl:value-of select="concat($x0 + ($dy - 0.5 * $h1) * $dx div $dy , ',' , $y1 - 0.5 * $h1)"/>
+						</xsl:when>	
+						<xsl:when test="$dy &lt; 0 and (($dx &gt;= 0 and $dx * $h1 &lt; -$dy* $w1) or ($dx &lt;= 0 and -$dx * $h1 &lt; -$dy* $w1))">
+							<!-- crop against S side of end -->
+							<xsl:value-of select="concat($x0 + ($dy + 0.5 * $h1) * $dx div $dy , ',' , $y1 + 0.5 * $h1)"/>
+						</xsl:when>
+						<xsl:otherwise>
+							<!-- crop against E side of end -->
+							<xsl:value-of select="concat($x1 + 0.5 * $w1,',',$y0 + ($dx + 0.5 * $w1) * $dy div $dx)"/>
+						</xsl:otherwise>
+					</xsl:choose>
+				</xsl:otherwise>
+			</xsl:choose>
+		</xsl:attribute>
+	</s:path>
+</xsl:template>
+
+ <xsl:template name="draw-curve"><xsl:param name="origin"/><xsl:param name="end"/><xsl:param name="class"/>
+	  	<xsl:param name="h0"/><xsl:param name="h1"/>
+	  	<xsl:param name="w0"/><xsl:param name="w1"/>
+	<xsl:variable name="x0" select="substring-before($origin,',')"/>
+	<xsl:variable name="y0" select="substring-after($origin,',')"/>
+	<xsl:variable name="x1" select="substring-before($end,',')"/>
+	<xsl:variable name="y1" select="substring-after($end,',')"/>
+	<xsl:variable name="dx" select="$x1 - $x0"/>
+	<xsl:variable name="up" select="floor($dx) mod 2 != 0"/> <!-- line is above or below componetns -->
+	<xsl:variable name="sgn" select="($dx &gt; 0 ) * 2  - 1"/>	
+	<!-- offset the x-coord so that if the components are next to each other the connection is from nearer the edge of the side
+		and if they're very far apart  the connection's closer to the centre of the side. This way the centre of the edge is not too busy 
+		(x-off approches zero as length goes to infiniity)-->
+	<xsl:variable name="x-off" select="0.25 * $sgn * $w0 * $w0 div ($sgn * $dx)"/>	
+	<xsl:value-of select="concat('M',$x0 +  $x-off,',')"/>
+	<xsl:choose>
+		<xsl:when test="($up and ($x1 &gt; $x0)) or (not($up) and ($x1 &lt; $x0)) "><xsl:value-of select="$y0 + (0.5*$h0)"/>c</xsl:when>
+		<xsl:otherwise><xsl:value-of select="$y0 - (0.5*$h0)"/>c</xsl:otherwise>
+	</xsl:choose>
+	<xsl:variable name="peak">
+		<xsl:choose> <!--  don't think i need the 0.5 * h0 -->
+			<xsl:when test="$up"><xsl:value-of select="$sgn * (0.5 * $h0 + ($sgn * $dx div 8))"/></xsl:when>
+			<xsl:otherwise><xsl:value-of select="- $sgn * (0.5 * $h0 + ($sgn * $dx div 8))"/></xsl:otherwise>
+		</xsl:choose>
+	</xsl:variable>
+	<xsl:variable name="x-off2" select="0.25 * $sgn * $w1 * $w1 div ($sgn * $dx)"/>	
+	<xsl:value-of select="concat(($dx   -  $x-off * 2) div 3 , ', ', $peak,' ',$dx  -  $x-off * 2 ,',', 2 * $peak, ' ',$dx -  $x-off2 * 2,',0')"/>
+</xsl:template>
+
+ <xsl:template name="draw-vcurve"><xsl:param name="origin"/><xsl:param name="end"/><xsl:param name="class"/>
+	<xsl:param name="h0"/><xsl:param name="h1"/>
+	<xsl:param name="w0"/><xsl:param name="w1"/>
+	<xsl:variable name="x0" select="substring-before($origin,',')"/>
+	<xsl:variable name="y0" select="substring-after($origin,',')"/>
+	<xsl:variable name="x1" select="substring-before($end,',')"/>
+	<xsl:variable name="y1" select="substring-after($end,',')"/>
+	<xsl:variable name="dy" select="$y1 - $y0"/>
+	<xsl:variable name="left" select="floor($dy) mod 2 != 0"/> <!-- line is above or below componetns -->
+	<xsl:variable name="sgn" select="($dy &gt; 0 ) * 2  - 1"/>	
+	<!-- offset the y-coord so that if the components are next to each other the connection is from nearer the edge of the side
+		and if they're very far apart  the connection's closer to the centre of the side. This way the centre of the edge is not too busy 
+		(y-off approches zero as length goes to infiniity)-->
+	<xsl:variable name="y-off" select="0.25 * $sgn * $h0 * ($h0 +$h1) div ($sgn * $dy)"/>	
+	
+	<xsl:text>M</xsl:text>
+	<xsl:choose>
+		<xsl:when test="($left and ($y1 &gt; $y0)) or (not($left) and ($y1 &lt; $y0)) "><xsl:value-of select="$x0 + (0.5*$w0)"/></xsl:when>
+		<xsl:otherwise><xsl:value-of select="$x0 - (0.5*$w0)"/></xsl:otherwise>
+	</xsl:choose>
+	<xsl:text>,</xsl:text>
+	<xsl:value-of select="$y0 +  $y-off"/>
+	
+	<xsl:text>c</xsl:text>
+	<xsl:variable name="y-off1" select="0.25 * $sgn * $h1 * ($h0 +$h1) div ($sgn * $dy)"/>	
+	<xsl:variable name="peak"><!--  don't think i need the 0.5 * Size -->
+		<xsl:choose>
+			<xsl:when test="$left"><xsl:value-of select="$sgn * (0.5 * $w0 + ($sgn * $dy div 8))"/></xsl:when>
+			<xsl:otherwise><xsl:value-of select="- $sgn * (0.5 * $w0 + ($sgn * $dy div 8))"/></xsl:otherwise>
+		</xsl:choose>
+	</xsl:variable>
+	<xsl:value-of select="concat($peak, ', ', ($dy  -  $y-off1 - $y-off) div 3 , ' ' , 2 * $peak, ' ',$dy  -  $y-off1 - $y-off , ' 0,',$dy -  $y-off1 - $y-off)"/>
+</xsl:template>
+
+</xsl:stylesheet>
\ No newline at end of file