<?xml version="1.0" encoding="Shift_JIS" ?>

<xsl:stylesheet
   version="1.0"
   xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
   xmlns:java="http://xml.apache.org/xslt/java"
   xmlns:svgcg="http://www.myDomain/svg/cg"
   exclude-result-prefixes="java">

<xsl:variable name="width">200px</xsl:variable>
<xsl:variable name="height">200px</xsl:variable>
<xsl:variable name="viewBox">0 0 200 200</xsl:variable>
<xsl:variable name="cx">100</xsl:variable>
<xsl:variable name="cy">100</xsl:variable>
<xsl:variable name="r">80</xsl:variable>
<!-- 初期開始点 -->
<xsl:variable name="x0">100</xsl:variable>
<xsl:variable name="y0">20</xsl:variable>

<!--支出項目を、費目をキーにして取り出しておく-->
<xsl:key name="outgo" match="//line[@type='outgo']" use="@group"/>

<xsl:template match="/">
  <svg width="{$width}" height="{$height}" viewBox="{$viewBox}">

    <!--全支出合計-->
    <xsl:variable name="sum" select="sum(//@amount[../@type='outgo'])"/>

    <!--費目ごとに-->
    <xsl:apply-templates mode="arc" select="//line[generate-id(.)=generate-id( key('outgo', @group ) )][position()=1]">
       <xsl:with-param name="prevColor"/>
       <xsl:with-param name="angleSum">0</xsl:with-param>
       <xsl:with-param name="x" select="$x0"/>
       <xsl:with-param name="y" select="$y0"/>
       <xsl:with-param name="sum" select="$sum"/>
     </xsl:apply-templates>
   </svg>
</xsl:template>

<!-- 角度と開始点を再帰的に取り扱いながら次の扇形を描いていく -->
<xsl:template mode="arc" match="line">
  <xsl:param name="angleSum"/><!-- 前までの角度合計 -->
  <xsl:param name="prevColor"/><!-- 前の色 -->
  <xsl:param name="x"/><!-- 開始点x座標 -->
  <xsl:param name="y"/><!-- 開始点y座標 -->
  <xsl:param name="sum"/>

  <!-- 角度の算出 -->
  <xsl:variable name="group" select="@group"/>

  <xsl:variable name="group-sum"
    select="sum( ../line/@amount[../@type='outgo'
    and ../@group=$group] )"/>

  <xsl:variable name="angle">
    <xsl:choose>
      <!-- 次があるかで角度計算方法を変える -->
      <xsl:when test="following-sibling::line[generate-id(.)=generate-id( key('outgo', @group ) )]" >
        <xsl:value-of select="round($group-sum * 360 div $sum)"/>
      </xsl:when>
      <xsl:otherwise><xsl:value-of select="360 - $angleSum"/></xsl:otherwise>
    </xsl:choose>
  </xsl:variable>

  <!-- 色の決定 -->
  <xsl:variable name="color">
    <xsl:choose>
      <xsl:when test="not(following-sibling::line[generate-id(.)=generate-id( key('outgo', @group ) )])">purple</xsl:when>
      <xsl:when test="$prevColor='blue'">red</xsl:when>
      <xsl:when test="$prevColor='red'">green</xsl:when>
      <xsl:when test="$prevColor='green'">yellow</xsl:when>
      <xsl:otherwise>blue</xsl:otherwise>
    </xsl:choose>
  </xsl:variable>

  <!-- 開始点の、初期開始点からの相対座標を求める -->
  <xsl:variable name="sx" select="$x - $x0"/>
  <xsl:variable name="sy" select="$y - $y0"/>

  <!-- 終了点の、初期開始点からの相対座標を求める -->
  <xsl:variable name="ex">
    <xsl:choose>
      <xsl:when test="following-sibling::line[generate-id(.)=generate-id( key('outgo', @group ) )]">
        <xsl:value-of select="floor( $r * java:java.lang.Math.sin( java:java.lang.Math.toRadians( number($angle) + number($angleSum) ) ) )"/>
      </xsl:when>
      <xsl:otherwise>0</xsl:otherwise>
    </xsl:choose>
  </xsl:variable>
  <xsl:variable name="ey">
    <xsl:choose>
      <xsl:when test="following-sibling::line[generate-id(.)=generate-id( key('outgo', @group ) )]">
        <xsl:value-of select="floor( $r * ( 1 - java:java.lang.Math.cos( java:java.lang.Math.toRadians( number($angle) + number($angleSum) ) ) ))"/>
      </xsl:when>
      <xsl:otherwise>0</xsl:otherwise>
    </xsl:choose>
  </xsl:variable>

  <!-- 終了点を、開始点からの相対座標に変換する -->
  <xsl:variable name="rex" select="$ex - $sx"/>
  <xsl:variable name="rey" select="$ey - $sy"/>

  <!-- largeArcFlag -->
  <xsl:variable name="largeArcFlag">
    <xsl:choose>
      <xsl:when test="$angle &lt; '180'">0</xsl:when>
      <xsl:otherwise>1</xsl:otherwise>
    </xsl:choose>
  </xsl:variable>

  <!-- 自分自身の描画 -->
  <xsl:choose>
    <!-- 終了点が開始点なら、円を描く -->
    <xsl:when test="$ex = '0' and $ey = '0' and $angle &gt; '180'">
      <circle cx="{$cx}" cy="{$cy}" r="{$r}" style="fill:{$color}"/>
    </xsl:when>
    <!-- それ以外は扇形を描く -->
    <xsl:otherwise>
      <path
        d="M{$cx},{$cy} L{$x},{$y} a{$r},{$r} 0 {$largeArcFlag},1 {$rex},{$rey} z"
        style="fill:{$color}"/>
    </xsl:otherwise>
  </xsl:choose>

  <!-- 足して次を呼ぶ -->
  <xsl:if test="following-sibling::line[generate-id(.)=generate-id( key('outgo', @group ) )]">
    <xsl:apply-templates mode="arc" select="following-sibling::line[generate-id(.)=generate-id( key('outgo', @group ) )][position()=1]">
      <xsl:with-param name="angleSum" select="$angle + $angleSum"/>
      <xsl:with-param name="prevColor" select="$color"/>
      <xsl:with-param name="x" select="$x + $rex"/>
      <xsl:with-param name="y" select="$y + $rey"/>
      <xsl:with-param name="sum" select="$sum"/>
    </xsl:apply-templates>
  </xsl:if>
</xsl:template>

</xsl:stylesheet>

