|
| 1 | +<?xml version="1.0" encoding="UTF-8"?> |
| 2 | +<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.0" exclude-result-prefixes="xsl xsi"> |
| 3 | + <xsl:output method="html" version="5.0" encoding="UTF-8" indent="yes" doctype-system="about:legacy-compat"/> |
| 4 | + <xsl:template match="gas"> |
| 5 | + <html> |
| 6 | + <head> |
| 7 | + <title><xsl:value-of select="usage/@name"/></title> |
| 8 | + <link rel="stylesheet" href="/normalize.css" type="text/css"/> |
| 9 | + <link rel="stylesheet" href="/gas.css" type="text/css"/> |
| 10 | + </head> |
| 11 | + <body> |
| 12 | + <xsl:apply-templates select="usage"/> |
| 13 | + </body> |
| 14 | + </html> |
| 15 | + </xsl:template> |
| 16 | + |
| 17 | + <xsl:template match="usage"> |
| 18 | + <xsl:variable name="max_usage"> |
| 19 | + <xsl:for-each select="periods/period"> |
| 20 | + <xsl:sort select="@usage" data-type="number" order="descending"/> |
| 21 | + <xsl:if test="position() = 1"><xsl:value-of select="@usage"/></xsl:if> |
| 22 | + </xsl:for-each> |
| 23 | + </xsl:variable> |
| 24 | + |
| 25 | + <xsl:choose> |
| 26 | + <xsl:when test="parent"> |
| 27 | + <h1> |
| 28 | + <a> |
| 29 | + <xsl:attribute name="href"><xsl:value-of select="parent/@uri"/></xsl:attribute> |
| 30 | + <xsl:value-of select="substring(@name, 1, string-length(parent/@name))"/> |
| 31 | + </a> |
| 32 | + <xsl:value-of select="substring(@name, string-length(parent/@name) + 1)"/> |
| 33 | + </h1> |
| 34 | + </xsl:when> |
| 35 | + <xsl:otherwise> |
| 36 | + <h1><xsl:value-of select="@name"/></h1> |
| 37 | + </xsl:otherwise> |
| 38 | + </xsl:choose> |
| 39 | + <xsl:apply-templates select="periods" mode="graph"> |
| 40 | + <xsl:with-param name="max_usage"><xsl:value-of select="$max_usage"/></xsl:with-param> |
| 41 | + </xsl:apply-templates> |
| 42 | + <xsl:apply-templates select="periods" mode="table"/> |
| 43 | + </xsl:template> |
| 44 | + |
| 45 | + <xsl:template name="median"> |
| 46 | + <xsl:param name="nodes"/> |
| 47 | + <xsl:param name="attr"/> |
| 48 | + <xsl:variable name="count" select="count($nodes/@*[local-name()=$attr])"/> |
| 49 | + <xsl:variable name="middle" select="ceiling($count div 2)"/> |
| 50 | + <xsl:variable name="even" select="not($count mod 2)"/> |
| 51 | + |
| 52 | + <xsl:variable name="m1"> |
| 53 | + <xsl:for-each select="$nodes/@*[local-name()=$attr]"> |
| 54 | + <xsl:sort data-type="number"/> |
| 55 | + <xsl:if test="position() = $middle"> |
| 56 | + <xsl:value-of select="."/> |
| 57 | + </xsl:if> |
| 58 | + </xsl:for-each> |
| 59 | + </xsl:variable> |
| 60 | + <xsl:variable name="m2"> |
| 61 | + <xsl:for-each select="$nodes/@*[local-name()=$attr]"> |
| 62 | + <xsl:sort data-type="number"/> |
| 63 | + <xsl:if test="position() = $middle + 1"> |
| 64 | + <xsl:value-of select="."/> |
| 65 | + </xsl:if> |
| 66 | + </xsl:for-each> |
| 67 | + </xsl:variable> |
| 68 | + |
| 69 | + <xsl:value-of select="($m1 + $m2) div ($even + 1)"/> |
| 70 | + </xsl:template> |
| 71 | + |
| 72 | + <xsl:template match="periods" mode="table"> |
| 73 | + <xsl:variable name="usage_median"> |
| 74 | + <xsl:call-template name="median"> |
| 75 | + <xsl:with-param name="nodes" select="period"/> |
| 76 | + <xsl:with-param name="attr" select="'usage'"/> |
| 77 | + </xsl:call-template> |
| 78 | + </xsl:variable> |
| 79 | + <table class="usage"> |
| 80 | + <thead> |
| 81 | + <tr> |
| 82 | + <th scope="col" class="name"><xsl:value-of select="@type"/></th> |
| 83 | + <th scope="col" class="usage">Usage (m³)</th> |
| 84 | + </tr> |
| 85 | + </thead> |
| 86 | + <tbody> |
| 87 | + <xsl:apply-templates select="period/@usage/.." mode="table"/> |
| 88 | + </tbody> |
| 89 | + <tfoot> |
| 90 | + <xsl:if test="count(period/@usage) > 1"> |
| 91 | + <tr class="summary average"> |
| 92 | + <th scope="row" class="name">Average</th> |
| 93 | + <td class="usage"><xsl:value-of select="format-number(sum(period/@usage) div count(period/@usage), '#,##0.00')"/></td> |
| 94 | + </tr> |
| 95 | + </xsl:if> |
| 96 | + <xsl:if test="count(period/@usage) > 2"> |
| 97 | + <tr class="summary median"> |
| 98 | + <th scope="row" class="name">Median</th> |
| 99 | + <td class="usage"><xsl:value-of select="format-number($usage_median, '#,##0.00')"/></td> |
| 100 | + </tr> |
| 101 | + </xsl:if> |
| 102 | + <tr class="summary total"> |
| 103 | + <th scope="row" class="name">Total</th> |
| 104 | + <td class="usage"><xsl:value-of select="format-number(sum(period/@usage), '#,##0.00')"/></td> |
| 105 | + </tr> |
| 106 | + </tfoot> |
| 107 | + </table> |
| 108 | + </xsl:template> |
| 109 | + |
| 110 | + <xsl:template match="period" mode="table"> |
| 111 | + <tr> |
| 112 | + <th scope="row" class="name"> |
| 113 | + <xsl:choose> |
| 114 | + <xsl:when test="@uri"> |
| 115 | + <a> |
| 116 | + <xsl:attribute name="href"><xsl:value-of select="@uri"/></xsl:attribute> |
| 117 | + <xsl:value-of select="@name"/> |
| 118 | + </a> |
| 119 | + </xsl:when> |
| 120 | + <xsl:otherwise> |
| 121 | + <xsl:value-of select="@name"/> |
| 122 | + </xsl:otherwise> |
| 123 | + </xsl:choose> |
| 124 | + </th> |
| 125 | + <td class="usage"><xsl:value-of select="format-number(@usage, '#,##0.00')"/></td> |
| 126 | + </tr> |
| 127 | + </xsl:template> |
| 128 | + |
| 129 | + <xsl:template match="periods" mode="graph"> |
| 130 | + <xsl:param name="max_usage"/> |
| 131 | + <xsl:variable name="svg_width" select="1000"/> |
| 132 | + <xsl:variable name="svg_height" select="400"/> |
| 133 | + <xsl:variable name="x_text_height"> |
| 134 | + <xsl:choose> |
| 135 | + <xsl:when test="count(period) <= 25">16</xsl:when> |
| 136 | + <xsl:otherwise>10</xsl:otherwise> |
| 137 | + </xsl:choose> |
| 138 | + </xsl:variable> |
| 139 | + <xsl:variable name="y_text_height" select="12"/> |
| 140 | + <xsl:variable name="x_label_height"> |
| 141 | + <xsl:choose> |
| 142 | + <xsl:when test="count(period) <= 25">30</xsl:when> |
| 143 | + <xsl:otherwise>20</xsl:otherwise> |
| 144 | + </xsl:choose> |
| 145 | + </xsl:variable> |
| 146 | + <xsl:variable name="x_tick_height" select="5"/> |
| 147 | + <xsl:variable name="y_label_width" select="70"/> |
| 148 | + <xsl:variable name="x_period_width" select="($svg_width - $y_label_width) div count(period)"/> |
| 149 | + <xsl:variable name="y_steps" select="10"/> |
| 150 | + <xsl:variable name="y_tick_width" select="5"/> |
| 151 | + <xsl:variable name="y_step_height" select="($svg_height - $x_label_height) div $y_steps"/> |
| 152 | + <xsl:variable name="bar_width" select="0.75"/> |
| 153 | + |
| 154 | + <svg xmlns="http://www.w3.org/2000/svg" version="1.1"> |
| 155 | + <xsl:attribute name="width"><xsl:value-of select="$svg_width"/></xsl:attribute> |
| 156 | + <xsl:attribute name="height"><xsl:value-of select="$svg_height + $y_text_height"/></xsl:attribute> |
| 157 | + <xsl:attribute name="viewBox" xml:space="preserve">0 <xsl:value-of select="-($y_text_height)"/> <xsl:value-of select="$svg_width"/> <xsl:value-of select="$svg_height + $y_text_height"/></xsl:attribute> |
| 158 | + |
| 159 | + <g stroke="grey" stroke-width="1"> |
| 160 | + <xsl:for-each select="period"> |
| 161 | + <!-- bars --> |
| 162 | + <xsl:if test="@usage"> |
| 163 | + <rect fill="steelblue"> |
| 164 | + <xsl:attribute name="x"><xsl:value-of select="$y_label_width + 0.5 + floor(($x_period_width) * (position() - 1) + ($x_period_width - ($x_period_width * $bar_width)) div 2)"/></xsl:attribute> |
| 165 | + <xsl:attribute name="y"><xsl:value-of select="0.5 + ($svg_height - $x_label_height - 1) - floor(($svg_height - $x_label_height - 1) * @usage div $max_usage)"/></xsl:attribute> |
| 166 | + <xsl:attribute name="width"><xsl:value-of select="floor($x_period_width * $bar_width)"/></xsl:attribute> |
| 167 | + <xsl:attribute name="height"><xsl:value-of select="floor(($svg_height - $x_label_height - 1) * @usage div $max_usage)"/></xsl:attribute> |
| 168 | + </rect> |
| 169 | + </xsl:if> |
| 170 | + </xsl:for-each> |
| 171 | + </g> |
| 172 | + |
| 173 | + <g stroke="black" stroke-width="1"> |
| 174 | + <!-- X axis --> |
| 175 | + <line> |
| 176 | + <xsl:attribute name="x1"><xsl:value-of select="$y_label_width"/></xsl:attribute> |
| 177 | + <xsl:attribute name="x2"><xsl:value-of select="$svg_width"/></xsl:attribute> |
| 178 | + <xsl:attribute name="y1"><xsl:value-of select="$svg_height - $x_label_height - 0.5"/></xsl:attribute> |
| 179 | + <xsl:attribute name="y2"><xsl:value-of select="$svg_height - $x_label_height - 0.5"/></xsl:attribute> |
| 180 | + </line> |
| 181 | + |
| 182 | + <!-- Y axis --> |
| 183 | + <line stroke="black" stroke-width="1"> |
| 184 | + <xsl:attribute name="x1"><xsl:value-of select="$y_label_width - 0.5"/></xsl:attribute> |
| 185 | + <xsl:attribute name="x2"><xsl:value-of select="$y_label_width - 0.5"/></xsl:attribute> |
| 186 | + <xsl:attribute name="y1">0</xsl:attribute> |
| 187 | + <xsl:attribute name="y2"><xsl:value-of select="$svg_height - $x_label_height"/></xsl:attribute> |
| 188 | + </line> |
| 189 | + |
| 190 | + <!-- X ticks --> |
| 191 | + <line> |
| 192 | + <xsl:attribute name="x1"><xsl:value-of select="$y_label_width - 0.5"/></xsl:attribute> |
| 193 | + <xsl:attribute name="x2"><xsl:value-of select="$y_label_width - 0.5"/></xsl:attribute> |
| 194 | + <xsl:attribute name="y1"><xsl:value-of select="$svg_height - $x_label_height - $x_tick_height div 2 - 0.5"/></xsl:attribute> |
| 195 | + <xsl:attribute name="y2"><xsl:value-of select="$svg_height - $x_label_height + $x_tick_height div 2 - 0.5"/></xsl:attribute> |
| 196 | + </line> |
| 197 | + <xsl:for-each select="period"> |
| 198 | + <line> |
| 199 | + <xsl:attribute name="x1"><xsl:value-of select="$y_label_width - 0.5 + floor($x_period_width * position())"/></xsl:attribute> |
| 200 | + <xsl:attribute name="x2"><xsl:value-of select="$y_label_width - 0.5 + floor($x_period_width * position())"/></xsl:attribute> |
| 201 | + <xsl:attribute name="y1"><xsl:value-of select="$svg_height - $x_label_height - $x_tick_height div 2 - 0.5"/></xsl:attribute> |
| 202 | + <xsl:attribute name="y2"><xsl:value-of select="$svg_height - $x_label_height + $x_tick_height div 2 - 0.5"/></xsl:attribute> |
| 203 | + </line> |
| 204 | + </xsl:for-each> |
| 205 | + |
| 206 | + <!-- Y ticks --> |
| 207 | + <xsl:for-each select="(//node())[$y_steps >= position() - 1]"> |
| 208 | + <line> |
| 209 | + <xsl:attribute name="x1"><xsl:value-of select="$y_label_width - $y_tick_width div 2 - 0.5"/></xsl:attribute> |
| 210 | + <xsl:attribute name="x2"><xsl:value-of select="$y_label_width"/></xsl:attribute> |
| 211 | + <xsl:attribute name="y1"><xsl:value-of select="floor($y_step_height * (position() - 1)) - 0.5"/></xsl:attribute> |
| 212 | + <xsl:attribute name="y2"><xsl:value-of select="floor($y_step_height * (position() - 1)) - 0.5"/></xsl:attribute> |
| 213 | + </line> |
| 214 | + </xsl:for-each> |
| 215 | + </g> |
| 216 | + |
| 217 | + <!-- X axis labels --> |
| 218 | + <xsl:for-each select="period"> |
| 219 | + <text text-anchor="middle" dy="0.3em"> |
| 220 | + <xsl:attribute name="font-size"><xsl:value-of select="$x_text_height"/></xsl:attribute> |
| 221 | + <xsl:attribute name="x"><xsl:value-of select="$y_label_width - 0.5 + floor($x_period_width * (position() - 0.5))"/></xsl:attribute> |
| 222 | + <xsl:attribute name="y"><xsl:value-of select="$svg_height - $x_label_height div 2"/></xsl:attribute> |
| 223 | + <xsl:choose> |
| 224 | + <xsl:when test="@short_name"> |
| 225 | + <xsl:value-of select="@short_name"/> |
| 226 | + </xsl:when> |
| 227 | + <xsl:otherwise> |
| 228 | + <xsl:value-of select="@name"/> |
| 229 | + </xsl:otherwise> |
| 230 | + </xsl:choose> |
| 231 | + </text> |
| 232 | + </xsl:for-each> |
| 233 | + |
| 234 | + <!-- Y axis labels --> |
| 235 | + <xsl:for-each select="(//node())[$y_steps >= position() - 1]"> |
| 236 | + <text text-anchor="end" dy="0.3em"> |
| 237 | + <xsl:attribute name="font-size"><xsl:value-of select="$y_text_height"/></xsl:attribute> |
| 238 | + <xsl:attribute name="x"><xsl:value-of select="$y_label_width - $y_tick_width"/></xsl:attribute> |
| 239 | + <xsl:attribute name="y"><xsl:value-of select="floor($y_step_height * (position() - 1))"/></xsl:attribute> |
| 240 | + <xsl:value-of select="format-number(($y_steps - (position() - 1)) div $y_steps * $max_usage, '#,##0.0')"/> |
| 241 | + </text> |
| 242 | + </xsl:for-each> |
| 243 | + |
| 244 | + <!-- Y axis type --> |
| 245 | + <text text-anchor="middle" style="writing-mode: tb"> |
| 246 | + <xsl:variable name="x"><xsl:value-of select="$y_text_height"/></xsl:variable> |
| 247 | + <xsl:variable name="y"><xsl:value-of select="($svg_height - $x_label_height) div 2"/></xsl:variable> |
| 248 | + <xsl:attribute name="font-size"><xsl:value-of select="$y_text_height"/></xsl:attribute> |
| 249 | + <xsl:attribute name="x"><xsl:value-of select="$x"/></xsl:attribute> |
| 250 | + <xsl:attribute name="y"><xsl:value-of select="$y"/></xsl:attribute> |
| 251 | + <xsl:attribute name="transform" xml:space="preserve">rotate(180 <xsl:value-of select="$x"/> <xsl:value-of select="$y"/>)</xsl:attribute> |
| 252 | + m³ |
| 253 | + </text> |
| 254 | + </svg> |
| 255 | + </xsl:template> |
| 256 | +</xsl:stylesheet> |
0 commit comments