geração de svg com xslt

Transcrição

geração de svg com xslt
geração
de
svg
com
xslt
Helder
da
Rocha
([email protected])
Geração
de
SVG
com
XSLT
•  SVG
pode
ser
gerado
a
par-r
de
XSLT
•  É
mais
fácil
gerar
figuras
básicas
que
paths.
•  Mas
paths
podem
ser
geradas
com
texto,
expressões
em
aCrribute
value
templates
{
...
}
ou
funções
XPath
de
texto,
como
concat(...)
<xsl:text
disable‐output‐escaping="yes"><![CDATA[<path
d="M
10
100]]></xsl:text>
<xsl:for‐each
select="Row">
<xsl:text>
L</xsl:text><xsl:value‐of
select="10
+
position()*5"/>
...</xsl:text>
</xsl:for‐each>
<xsl:text
disable‐output‐escaping="yes"><![CDATA["
/>]]></xsl:text>
argonavis.com.br
•  O
namespace
do
SVG
deve
ser
incluído
no
<xsl:stylesheet>
e
não
no
template
onde
<svg>
é
declarado
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
2
Exemplo:
geração
de
SVG
com
XSLT
argonavis.com.br
•  Extrair
dados
do
arquivo‐fonte
abaixo
e
criar
um
gráfico
de
barras
exibindo
diâmetros
de
objetos
que
tenham
900km
ou
mais
<sistemaSolar
versao="2.2"
dataAtualizacao="2010‐12‐29">
<planetas>
<planeta
id="p1"
nome="Mercúrio"
diametrokm="4879"
...
massaGM="22027.573">...
</planeta>
<planeta
id="p2"
nome="Venus"
diametrokm="12104"
...
massaGM="324774.91">...
</planeta>
<planeta
id="p3"
nome="Terra"
diametrokm="12756"
...
massaGM="398511.56">
<satelite
id="p3.1"
nome="Lua"
categoria="redonda"
diametrokm="3475"
...
massaGM="4901.986"/></planeta>
...
<planeta‐anao
id="a1"
nome="Ceres"
diametrokm="952.4"
...
massaGM="62.059"
/>
<planeta‐anao
id="tno1930"
nome="Plutão"
diametrokm="2306"
...
massaGM="874.163">
<satelite
id="s134340.1"
nome="Caronte"
diametrokm="1212"
...
massaGM="101.43
/>
<satelite
id="s134340.2"
nome="Nix"
diametrokm="88"
...
/>
...
</planeta‐anao>
<planeta‐anao
id="tno2003.ub313"
nome="Éris"
diametrokm="2320"
...
massaGM="1114.391">
<satelite
id="s136199.1"
nome="Disnomia"
diametrokm="174"
...
/>
...
</planeta‐anao>
...
</planetas>
<asteroides>...</asteroides>
...
<cometas>...</cometas>
...
<centauros>
...
</centauros>
<trans‐netunianos>
<objeto
id="a2002.lm60"
nome="Quaoar"
...
diametrokm="842">
<satelite
id="s50000.1"
nome="Weywot"
diametrokm="74"
...
/>
</objeto>
<objeto
id="a2003.vb12"
nome="Sedna"
...
diametrokm="1700"/>
...
</trans‐netunianos>
</sistemaSolar>
3
Expressões
XPath
para
extrair
dados
•  Definir
em
variáveis
ou
parâmetros
XSLT
•  Node‐set
com
todos
os
ítens
do
gráfico
de
barras
$itens:
//*[@diametrokm
>=
900]
•  Número
de
itens
do
gráfico
de
barras
$numeroDeItens:
count($itens)
•  Maior
diâmetro
dentre
os
itens
selecionados
(necessário
para
calcular
dimensões
do
gráfico
de
barras)
$maiorDiametro:
argonavis.com.br
//*[not(@diametrokm
<
//*/@diametrokm)]/@diametrokm
•  Divida
o
tamanho
máximo
da
barra
(em
unidades
do
viewbox)
pelo
maior
diâmetro
para
obter
o
fator
de
redução
para
calcular
o
tamanho
das
demais
barras
4
Gráfico
de
barras:
projeto
Diâmetros
de
objetos
do
sistema
solar
$alturaTitulo
com
900km
ou
mais
$maxBarra
(em
unidades
do
viewBox)
1.
@nome
@diametrokm
km
@diametrokm
*
($maxBarra/
$maiorDiametro)
2.
@nome
@diametrokm
km
3.
@nome
@diametrokm
km
$espacoEntreBarras
argonavis.com.br
4.
@nome
@diametrokm
km
$alturaBarra
$alturaGrafico
=
$numeroDeItens
*
($espacoEntreBarras
+
$alturaBarra)
L
E
G
E
N
D
A
Planetas
Planetas‐anão
Satélites
(Luas)
Asteróides
e
outros
objetos
5
ProtóJpo
(1)
<svg
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
viewBox="0
0
1600
1200"
width="1200px"
height="900px">
<defs>
<!‐‐
Titulo
‐‐>
<g
id="titulo">
...
</g>
<!‐‐
Grafico
de
barras
‐‐>
<g
id="grafico"
font‐size="16">
...
</g>
argonavis.com.br
<!‐‐
Legenda
‐‐>
<rect
id="quadrado"
width="25"
height="25"/>
<g
id="legenda"
font‐size="16">
...
</g>
<g
id="tudo"
font‐family="Corbel,
Calibri,
sans‐serif">
<use
xlink:href="#titulo"
transform="translate(20,50)"/>
<use
xlink:href="#grafico"
transform="translate(20,150)"/>
<use
xlink:href="#legenda"
transform="translate(20,550)"/>
</g>
</defs>
<use
xlink:href="#tudo"
/>
</svg>
6
argonavis.com.br
ProtóJpo:
partes
fixas
7
ProtóJpo:
parte
variável
argonavis.com.br
@diametrokm
*
($maxBarra
/
$maiorDiametro)
<g
id="grafico"
font‐size="16">
<g
id="barra_1">
<text
x="0"
y="15">1.
@nome</text>
<rect
x="100"
y="0"
width="1000"
height="25"
fill="rgb(255,180,0)"/>
<text
x="1110"
y="15">@diametrokm
km</text>
Repe-r
este
bloco
inserindo
</g>
valores
extraídos
da
fonte
<g
id="barra_2">
<text
x="0"
y="115">2.
@nome</text>
<rect
x="100"
y="100"
width="750"
height="25"
fill="rgb(255,180,0)"/>
<text
x="860"
y="115">@diametrokm
km</text>
</g>
<g
id="barra_3">
<text
x="0"
y="215">3.
@nome</text>
<rect
x="100"
y="200"
width="500"
height="25"
fill="rgb(150,0,255)"/>
<text
x="610"
y="215">@diametrokm
km</text>
</g>
</g>
8
Folha
de
esJlos
XSLT:
template
fixo
argonavis.com.br
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns="http://www.w3.org/2000/svg"
Namespaces
do
SVG
xmlns:xlink="http://www.w3.org/1999/xlink">
<xsl:output
method="xml"/><xsl:strip‐space
elements="*"/>
<xsl:decimal‐format
decimal‐separator=","
grouping‐separator="."/>
Este
template
gera
dados
fixos
(não
usa
dados
extraídos
da
fonte)
<xsl:template
match="/">
<svg
viewBox="0
0
1200
900"
width="1200px"
height="900px">
<defs>
<g
id="titulo">
...
</g>
Resultado
dos
outros
templates
<g
id="grafico"
font‐size="16">
será
incluído
aqui
<xsl:apply‐templates
/>
</g>
<rect
id="quadrado"
width="15"
height="15"/>
<g
id="legenda"
font‐size="16">
...
</g>
<g
id="tudo"
font‐family="Corbel,
Calibri,
sans‐serif">
<use
xlink:href="#titulo"
transform="translate(20,50)"/>
<use
xlink:href="#grafico"
transform="translate(20,100)"/>
<use
xlink:href="#legenda"
transform="translate(20,870)"/>
</g>
</defs>
Template
que
irá
processar
<use
xlink:href="#tudo"
/>
cada
item
extraído
da
fonte
</svg>
</xsl:template>
<xsl:template
match="sistemaSolar">
...
</xsl:template>
9
</xsl:stylesheet>
Variáveis
e
parâmetros
globais
•  Parâmetros
<xsl:param>
podem
ser
passados
pela
aplicação
que
faz
a
transformação
•  Ex:
aplicações
Java,
processadores
standalone,
etc.
<xsl:param
name="alturaBarra">15</xsl:param>
<xsl:param
name="espacoEntreBarras">5</xsl:param>
<xsl:param
name="maxBarra">800</xsl:param>
<xsl:param
name="corPlaneta">rgb(255,180,0)</xsl:param>
<xsl:param
name="corPlanetaAnao">rgb(255,0,0)</xsl:param>
<xsl:param
name="corLua">rgb(150,0,255)</xsl:param>
<xsl:param
name="corOutros">rgb(0,200,0)</xsl:param>
argonavis.com.br
<xsl:variable
name="maiorDiametro"
select="//*[not(@diametrokm
&lt;
//*/@diametrokm)]/@diametrokm"
/>
<xsl:variable
name="itens"
select="//*[@diametrokm
&gt;=
900]"
/>
10
XSLT:
template
variável
<xsl:template
match="sistemaSolar">
<xsl:for‐each
select="$itens">
<xsl:sort
select="@diametrokm"
data‐type="number"
order="descending"/>
<xsl:variable
name="larguraBarra"
select="@diametrokm
*
$maxBarra
div
$maiorDiametro"
/>
argonavis.com.br
<xsl:variable
name="cor">
<xsl:choose>
<xsl:when
test="name(.)
=
'planeta'">
<xsl:value‐of
select="$corPlaneta"/>
</xsl:when>
...
<xsl:otherwise>
<xsl:value‐of
select="$corOutros"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
Bloco
que
será
repe-do
<g
id="barra_{position()}"
transform="translate(0,
{(position()
‐
1)
*
($alturaBarra
+
$espacoEntreBarras)})">
<text
x="0"
y="10"><xsl:number
format="1.
"
value="position()"/>
<xsl:value‐of
select="@nome"/></text>
<rect
x="120"
y="0"
width="{$larguraBarra}"
height="{$alturaBarra}"
fill="{$cor}"/>
<text
x="{$larguraBarra
+
125}"
y="10">
<xsl:value‐of
select="format‐number(@diametrokm,
'###.##0,##')"/>
km</text>
</g>
</xsl:for‐each>
</xsl:template>
11
Resultado
<svg
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
viewBox="0
0
1200
900"
width="1200px"
height="900px">
<defs>
<g
id="titulo">
...
</g>
<g
id="grafico"
font‐size="16">
<g
id="barra_1"
transform="translate(0,
0)">
<text
x="0"
y="10">1.
Júpiter</text>
<rect
x="120"
y="0"
width="800"
height="15"
fill="rgb(255,180,0)"/>
<text
x="925"
y="10">142.984
km</text>
</g>
<g
id="barra_2"
transform="translate(0,
20)">
<text
x="0"
y="10">2.
Saturno</text>
<rect
x="120"
y="0"
width="674.4027303754266"
height="15"
fill="rgb(255,180,0)"/>
<text
x="799.4027303754266"
y="10">120.536
km</text>
</g>
argonavis.com.br
...
Dados
calculados
Dados
extraídos
da
fonte
e
formatados
<g
id="barra_37"
transform="translate(0,
720)">
<text
x="0"
y="10">37.
Orcus</text>
<rect
x="120"
y="0"
width="5.041123482347675"
height="15"
fill="rgb(0,200,0)"/>
<text
x="130.04112348234767"
y="10">901
km</text>
</g>
</g>
<rect
id="quadrado"
width="15"
height="15"/>
<g
id="legenda"
font‐size="16">
...
</g>
<g
id="tudo"
font‐family="Corbel,
Calibri,
sans‐serif">
...
</g>
</defs>
<use
xlink:href="#tudo"/>
</svg>
12
argonavis.com.br
Resultado
13