<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet href="/pool/xslt_ht.xslt" type="application/xml"?>
<xsl:stylesheet
  xmlns = "http://www.w3.org/2000/svg"
  xmlns:xsl = "http://www.w3.org/1999/XSL/Transform"
  xmlns:d = "http://herbaer.de/xmlns/20051201/doc"
  xmlns:pd = "http://herbaer.de/xmlns/20200803/punktediagramm/"
  xmlns:xl = "http://www.w3.org/1999/xlink"
  version = "1.0"
  exclude-result-prefixes = "d pd"
>
<!--
  pd_svg
  Punktediagramm als SVG
  2020-08-03 Herbert Schiemann <h.schiemann@herbaer.de>
  Borkener Straße 167, 46284 Dorsten, Deutschland
  GPL Version 2 oder neuer
-->

<d:info xmlns="http://herbaer.de/xmlns/20051201/doc">
  <title>pd_svg.xslt</title>
  <subtitle>Punktediagramm als SVG</subtitle>
  <date>2020-08-03</date>
  <author>
    <personname>
      <firstname>Herbert</firstname>
      <surname>Schiemann</surname>
    </personname>
    <email>h.schiemann@herbaer.de</email>
  </author>
</d:info>

<xsl:output method="xml" encoding="utf-8" indent="yes"/>

<xsl:key name="pointset_class" match="pd:pointset/pd:class" use="."/>
<xsl:key name="cbezier_class" match="pd:cbezier/pd:class" use="."/>

<xsl:template match="/pd:punktediagramm">
  <svg version="1.1">
    <xsl:apply-templates select="pd:size"/>
    <xsl:apply-templates select="pd:title"/>
    <style>
      <xsl:text>
#frame {
   fill: none;
   stroke: #000000;
   stroke-width: 3px;
}
</xsl:text>
      <xsl:apply-templates
        select =
        "pd:pointset/pd:class [ generate-id(.) = generate-id(key('pointset_class', .)) ]"
        mode = "style"
      />
      <xsl:apply-templates
        select =
        "pd:cbezier/pd:class [ generate-id(.) = generate-id(key('cbezier_class', .)) ]"
        mode = "style"
      />
      <xsl:apply-templates select="pd:sclxticks" mode="style"/>
      <xsl:apply-templates select="pd:sclyticks" mode="style"/>
      <xsl:apply-templates select="pd:xlabels" mode="style"/>
      <xsl:apply-templates select="pd:ylabels" mode="style"/>
      <xsl:apply-templates select="pd:title" mode="style"/>
    </style>
    <defs>
      <xsl:apply-templates
        select =
        "pd:pointset/pd:class [ generate-id(.) = generate-id(key('pointset_class', .)) ]"
        mode = "def"
      />
      <xsl:apply-templates select="pd:sclxticks" mode="def"/>
      <xsl:apply-templates select="pd:sclyticks" mode="def"/>
    </defs>
    <!-- Rahmen -->
    <xsl:apply-templates select="pd:scloutrange" mode="frame"/>
    <!-- Punktreihen -->
    <xsl:apply-templates select="pd:pointset"/>
    <!-- C-Bezier-Kurven -->
    <xsl:apply-templates select="pd:cbezier"/>
    <!-- Ticks und Labels-->
    <xsl:apply-templates select="pd:sclxticks"/>
    <xsl:apply-templates select="pd:sclyticks"/>
    <xsl:apply-templates select="pd:xlabels"/>
    <xsl:apply-templates select="pd:ylabels"/>
    <!-- Titel im Diagramm -->
    <xsl:apply-templates select="pd:title" mode="text"/>
  </svg>
</xsl:template>

<d:para>
Angabe der Größe im Wurzelelement
</d:para>
<xsl:template match="pd:size">
  <xsl:attribute name="width">
    <xsl:value-of select="pd:co[1]"/>
  </xsl:attribute>
  <xsl:attribute name="height">
    <xsl:value-of select="pd:co[2]"/>
  </xsl:attribute>
</xsl:template>

<d:para>
Markierer für Punkte
</d:para>
<xsl:template match="pd:pointset/pd:class" mode="def">
  <path id="ps_{.}" d="M 0 -5 v 10 M -5 0 h 10"/>
</xsl:template>

<d:para>
CSS-Regeln für Markierer für Punkte
</d:para>
<xsl:template match="pd:pointset/pd:class" mode="style">
  <xsl:value-of select="concat ('#ps_', ., ' {')"/>
  <xsl:text>
   stroke: #000000;
   stroke-width: 3px;
}
</xsl:text>
</xsl:template>

<d:para>
CSS-Regeln für Markierer für C-Bezier-Kurven
</d:para>
<xsl:template match="pd:cbezier/pd:class" mode="style">
  <xsl:value-of select="concat ('.cb_', ., ' {')"/>
  <xsl:text>
   fill: none;
   stroke: #000000;
   stroke-width: 3px;
}
</xsl:text>
</xsl:template>

<d:para>
Eine Punktreihe
</d:para>
<xsl:template match="pd:pointset">
  <xsl:variable name="link" select="concat ('#ps_', pd:class)"/>
  <xsl:apply-templates select="pd:scaled/pd:pt">
    <xsl:with-param name="link" select="$link"/>
  </xsl:apply-templates>
</xsl:template>

<d:para>
Ein Punkt einer Punktreihe
</d:para>
<xsl:template match="pd:pointset/pd:scaled/pd:pt">
  <xsl:param name="link"/>
  <use xl:href="{$link}" x="{pd:co[1]}" y="{pd:co[2]}"/>
</xsl:template>

<d:para>
Eine C-Bezier-Kurve
</d:para>
<xsl:template match="pd:cbezier">
  <xsl:variable name="path">
    <xsl:apply-templates select="pd:scaled/pd:pt"/>
  </xsl:variable>
  <path class="cb_{pd:class}" d="{$path}"/>
</xsl:template>

<d:para>
C-Bezier-Pfad
</d:para>
<xsl:template match="pd:cbezier/pd:scaled/pd:pt">
  <xsl:choose>
    <xsl:when test="position() = 1">
      <xsl:text>M</xsl:text>
    </xsl:when>
    <xsl:when test="position() mod 3 = 2">
      <xsl:text>C</xsl:text>
    </xsl:when>
    <xsl:otherwise/>
  </xsl:choose>
  <xsl:value-of select="concat (' ', pd:co[1], ' ', pd:co[2])"/>
</xsl:template>

<d:para>
CSS-Regeln für "x-Tick"
</d:para>
<xsl:template match="pd:sclxticks" mode="style">
  <xsl:text>
#def_xtick {
   stroke: #000000;
   stroke-width: 3;
}
  </xsl:text>
</xsl:template>

<d:para>
Vorlage für "x-Tick"
</d:para>
<xsl:template match="pd:sclxticks" mode="def">
  <path id="def_xtick" d="M0 0 V -7"/>
</xsl:template>

<d:para>
"x-Ticks"
</d:para>
<xsl:template match="pd:sclxticks">
  <xsl:variable name="symin" select="/pd:punktediagramm/pd:scloutrange/pd:co[3]"/>
  <xsl:apply-templates select="pd:tk">
    <xsl:with-param name="y" select="$symin"/>
  </xsl:apply-templates>
</xsl:template>

<d:para>
"x-Tick"
</d:para>
<xsl:template match="pd:sclxticks/pd:tk">
  <xsl:param name="y" select="/pd:punktediagramm/pd:scloutrange/pd:co[3]"/>
  <use xl:href="#def_xtick" x="{.}" y="{$y}"/>
</xsl:template>

<d:para>
CSS-Regeln für "y-Tick"
</d:para>
<xsl:template match="pd:sclyticks" mode="style">
  <xsl:text>
#def_ytick {
   stroke: #000000;
   stroke-width: 3;
}
  </xsl:text>
</xsl:template>

<d:para>
Vorlage für "y-Tick"
</d:para>
<xsl:template match="pd:sclyticks" mode="def">
  <path id="def_ytick" d="M0 0 H 7"/>
</xsl:template>

<d:para>
"y-Ticks"
</d:para>
<xsl:template match="pd:sclyticks">
  <xsl:variable name="sxmin" select="/pd:punktediagramm/pd:scloutrange/pd:co[1]"/>
  <xsl:apply-templates select="pd:tk">
    <xsl:with-param name="x" select="$sxmin"/>
  </xsl:apply-templates>
</xsl:template>

<d:para>
"y-Tick"
</d:para>
<xsl:template match="pd:sclyticks/pd:tk">
  <xsl:param name="x" select="/pd:punktediagramm/pd:scloutrange/pd:co[1]"/>
  <use xl:href="#def_ytick" x="{$x}" y="{.}"/>
</xsl:template>

<d:para>
CSS-Regeln für x-Beschriftung
</d:para>
<xsl:template match="pd:xlabels" mode="style">
  <!-- https://www.w3.org/TR/SVG11/Overview.html -->
  <!-- https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/dominant-baseline -->
  <xsl:text>
.xlabel {
  text-anchor: middle;
  dominant-baseline: text-before-edge;
  font-size: 40px;
}
  </xsl:text>
</xsl:template>

<d:para>
x-Beschriftungen
</d:para>
<xsl:template match="pd:xlabels">
  <xsl:variable name="symin" select="/pd:punktediagramm/pd:scloutrange/pd:co[3]"/>
  <xsl:apply-templates select="pd:lb">
    <xsl:with-param name="y" select="$symin"/>
  </xsl:apply-templates>
</xsl:template>

<d:para>
x-Beschriftung
</d:para>
<xsl:template match="pd:xlabels/pd:lb">
  <xsl:param name="y" select="/pd:punktediagramm/pd:scloutrange/pd:co[3]"/>
  <xsl:variable name="p" select="position()"/>
  <text class="xlabel" y="{$y + 10}" x="{../../pd:sclxticks/pd:tk[$p]}">
    <xsl:value-of select="."/>
  </text>
</xsl:template>

<d:para>
CSS-Regeln für y-Beschriftung
</d:para>
<xsl:template match="pd:ylabels" mode="style">
  <!-- https://www.w3.org/TR/SVG11/Overview.html -->
  <!-- https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/dominant-baseline -->
  <xsl:text>
.ylabel {
  text-anchor: end;
  dominant-baseline: middle;
  font-size: 40px;
}
  </xsl:text>
</xsl:template>

<d:para>
y-Beschriftungen
</d:para>
<xsl:template match="pd:ylabels">
  <xsl:variable name="sxmin" select="/pd:punktediagramm/pd:scloutrange/pd:co[1]"/>
  <xsl:apply-templates select="pd:lb">
    <xsl:with-param name="x" select="$sxmin"/>
  </xsl:apply-templates>
</xsl:template>

<d:para>
y-Beschriftung
</d:para>
<xsl:template match="pd:ylabels/pd:lb">
  <xsl:param name="x" select="/pd:punktediagramm/pd:scloutrange/pd:co[1]"/>
  <xsl:variable name="p" select="position()"/>
  <text class="ylabel" x="{$x - 10}" y="{../../pd:sclyticks/pd:tk[$p]}">
    <xsl:value-of select="."/>
  </text>
</xsl:template>

<d:para>
Rahmen
</d:para>
<xsl:template match="pd:scloutrange" mode="frame">
  <path d="M{pd:co[1]} {pd:co[3]} H{pd:co[2]} V{pd:co[4]} H{pd:co[1]} z" id="frame"/>
</xsl:template>

<d:para>
Titel
</d:para>
<xsl:template match="pd:title">
  <title>
    <xsl:value-of select="."/>
  </title>
</xsl:template>

<d:para>
CSS - Regeln für Titel im Text
</d:para>
<xsl:template match="pd:title" mode="style">
  <xsl:text>
#txt_title {
  text-anchor: start;
  dominant-baseline: text-before-edge;
  font-size: 40px;
}
  </xsl:text>
</xsl:template>

<d:para>
Titel als Text im Diagramm
</d:para>
<xsl:template match="pd:title" mode="text">
  <text
    id = "txt_title"
    x = "{/pd:punktediagramm/pd:scloutrange/pd:co[1] + 10}"
    y = "{/pd:punktediagramm/pd:scloutrange/pd:co[4] + 10}"
  >
    <xsl:value-of select="."/>
  </text>
</xsl:template>

</xsl:stylesheet>
