UNIVERSIDADE FEDERAL DE SANTA CATARINA
DEPARTAMENTO DE INFORMÁTICA E ESTATÍSTICA
CURSO DE CIÊNCIAS DA COMPUTAÇÃO
Geração de Gráficos Estatísticos como Gráficos Vetoriais
Escaláveis a Partir de Dados em XML
Autor:
Henrique Andrade Viecili
Orientador:
Prof. Fernando Ostuni Gauthier, Dr.Eng
Membros da Banca:
Profª Silvia Modesto Nassar, Dra. Eng
Prof. José Eduardo De Lucca
Florianópolis, fevereiro de 2004
HENRIQUE ANDRADE VIECILI
“GERAÇÃO DE GRÁFICOS ESTATÍSTICOS COMO GRÁFICOS VETORIAIS
ESCALÁVEIS A PARTIR DE DADOS EM XML”
Este trabalho de Conclusão de Curso foi julgado adequado para a obtenção de
Graduação em Bacharelado em Ciências da Computação.
Apresentado à Banca Examinadora, integrada por:
___________________________________________________
Prof. Fernando Ostuni Gauthier, Dr.Eng - Orientador
___________________________________________________
Profª Silvia Modesto Nassar, Dra. Eng – Coorientadora
____________________________________________________
Prof. José Eduardo De Lucca
Este trabalho é dedicado à memória de Lory Werner Viecili,
minha estimada avó, e a todos aqueles que ajudaram
a construir meu caráter e não estão mais entre nós.
Agradeço a Deus por tudo que pude construir até agora,
Aos meus pais por serem os responsáveis pela minha existência e educação,
A minha namorada por ser compreensiva e me dar apoio nos momentos difíceis,
Aos meus colegas e amigos por me incentivarem a concluir este trabalho,
Ao meu orientador e coorientadora por apoiarem minhas idéias,
Aos meus mestres professores por me agraciarem com a luz do conhecimento.
Lista de Tabelas Tabela 1 – Tabela de Formas Básicas
Lista de Figuras Figura 1 – Exemplo básico de documento XML
Figura 3 – Estrutura básica de um documento SVG
Figura 3 – Estrutura básica de um documento SVG
Figura 4 – utilização de estilo inline.
Figura 5 – utilização de estilo interno
Figura 6 – referência a folha de estilos externa
Figura 7 – Exemplo de Gráfico de Colunas Agrupadas
Figura 8 – Exemplo de Gráfico de Barras Agrupadas
Figura 9 – Exemplo de Gráfico de Linhas
Figura 10 – Exemplo de Gráfico de Pizza
Figura 11 – Exemplo de Gráfico de Dispersão
Figura 12 – Exemplo de Gráfico de Área
Figura 13 – Arquivo svgchart_data.dtd
Figura 14 – Diagrama de Classes de Conjunto de Dados
Figura 15 – Formulário HTML da aplicação exemplo
Figura 16 – Fluxo do Processo de Geração dos Gráficos
Figura 17 – Exemplo de arquivo de entrada XML para Gráfico de Pizza
Figura 18 – Exemplo de arquivo de entrada XML para Gráfico de Dispersão
Figura 19 – Exemplo de arquivo de entrada XML para Gráfico de Colunas Agrupadas
Figura 20 – Gráfico de Pizza gerado pela aplicação
Figura 21 – Gráfico de Dispersão gerado pela aplicação
Figura 22– Gráfico de Colunas Agrupadas gerado pela aplicação
Figura 23 – Gráfico de Barras Agrupadas gerado pela aplicação
Figura 24 – Gráfico de Linhas gerado pela aplicação
Figura 25 – Gráfico de Área gerado pela aplicação
SUMÁRIO
1 INTRODUÇÃO ........................................................................................................................ 1
2 OBJETIVOS ............................................................................................................................. 2
2.1 OBJETIVOS GERAIS................................................................................................................. 2 2.2 OBJETIVOS ESPECÍFICOS......................................................................................................... 2
3 REVISÃO DE LITERATURA................................................................................................ 3
3.1 XML ...................................................................................................................................... 3 3.1.1 Visão Geral .................................................................................................................. 3 3.1.2 Regras Básicas de XML ............................................................................................... 4 3.1.3 DTD.............................................................................................................................. 5
3.2 CSS ........................................................................................................................................ 6 3.2.1 Visão Geral .................................................................................................................. 6 3.2.2 Como Funciona ............................................................................................................ 6
4 SVG............................................................................................................................................ 8
4.1 SISTEMAS GRÁFICOS .............................................................................................................. 8 4.2 UM POUCO SOBRE SVG .......................................................................................................... 8 4.3 CONCEITOS E DEFINIÇÕES ...................................................................................................... 9
4.3.1 Estrutura de um documento SVG ................................................................................. 9 4.3.2 Formas Básicas .......................................................................................................... 11 4.3.3 Texto........................................................................................................................... 12 4.3.4 Conceitos e Definições Avançadas............................................................................. 13
5 DESENVOLVIMENTO E IMPLEMENTAÇÃO ............................................................... 15
5.1 DEFINIÇÃO DOS TIPOS DE GRÁFICOS ..................................................................................... 15 5.1.1 Gráfico de Colunas Agrupadas .................................................................................. 16 5.1.2 Gráfico de Barras Agrupadas .................................................................................... 17 5.1.3 Gráfico de Linhas....................................................................................................... 18 5.1.4 Gráfico de Pizza ......................................................................................................... 19 5.1.5 Gráfico de Dispersão ................................................................................................. 20 5.1.6 Gráfico de Área.......................................................................................................... 21
5.2 ELABORAÇÃO DO DTD......................................................................................................... 22 5.3 SEMÂNTICA DO XML DE ENTRADA...................................................................................... 23 5.4 DEFINIÇÃO DA LINGUAGEM DE PROGRAMAÇÃO E API XML ............................................... 25
5.4.1 JAVA........................................................................................................................... 26
i
5.4.2 SAX – Simple API for XML ........................................................................................ 26 5.5 DEFINIÇÃO DA INTERFACE DO USUÁRIO E TECNOLOGIAS RELACIONADAS .......................... 27 5.6 UTILIZAÇÃO DE FERRAMENTAS DE AUXÍLIO AO DESENVOLVIMENTO .................................. 29
5.6.1 Oracle JDeveloper 10g IDE....................................................................................... 29 5.6.2 JFreeChart ................................................................................................................. 29 5.6.3 Batik SVG Toolkit....................................................................................................... 29
5.7 FERRAMENTA DE TESTES, EXECUÇÃO E VISUALIZAÇÃO ...................................................... 30 5.7.1 Apache Tomcat........................................................................................................... 30 5.7.2 Adobe SVGViewer ...................................................................................................... 31 5.7.3 Squiggle SVG Browser ............................................................................................... 31
5.8 A CLASSE SVGCHART.......................................................................................................... 31 5.9 IMPLEMENTAÇÃO DA CLASSE DE MANIPULAÇÃO DOS DADOS ............................................. 31
5.9.1 Bibliotecas Utilizadas................................................................................................. 32 5.9.2 Implementação ........................................................................................................... 32
5.10 IMPLEMENTAÇÃO DAS CLASSES DE CONJUNTOS DE DADOS ............................................ 33 5.11 CRIAÇÃO DA APLICAÇÃO EXEMPLO ................................................................................ 35
6 MODELO DO PROCESSO DE GERAÇÃO DOS GRÁFICOS........................................ 37
6.1 CRIAÇÃO E ENVIO DO ARQUIVO DE ENTRADA XML ............................................................ 37 6.2 ANÁLISE E CONVERSÃO DOS DADOS EM OBJETOS DE CONJUNTOS DE DADOS ..................... 38 6.3 TRANSFORMAÇÃO EM OBJETOS GRÁFICOS JAVA 2D............................................................ 38 6.4 TRANSFORMAÇÃO DOS OBJETOS GRÁFICOS JAVA 2D EM SVG............................................ 39 6.5 ENVIO DO GRÁFICO SVG ..................................................................................................... 39
7 APLICAÇÃO PRÁTICA DO PROCESSO DE GERAÇÃO DOS GRÁFICOS............... 40
7.1 ELABORAÇÃO DO DOCUMENTO DE ENTRADA XML............................................................. 40 7.1.1 Gráficos de Pizza ....................................................................................................... 40 7.1.2 Gráficos de Dispersão................................................................................................ 41 7.1.3 Gráficos de Categorias .............................................................................................. 43
7.2 ANÁLISE E MANIPULAÇÃO DO DOCUMENTO DE ENTRADA XML ......................................... 44 7.3 GRÁFICOS EM SVG............................................................................................................... 45
7.3.1 Gráfico de Pizza ......................................................................................................... 46 7.3.2 Gráfico de Dispersão ................................................................................................. 46 7.3.3 Gráfico de Categorias ................................................................................................ 47
8 CONCLUSÃO......................................................................................................................... 49
9 TRABALHOS FUTUROS ..................................................................................................... 50
10 REFERÊNCIAS BIBLIOGRÁFICAS.................................................................................. 51
ii
11 ANEXOS ................................................................................................................................. 55
11.1 CÓDIGO FONTE DOS GRÁFICOS GERADOS........................................................................ 55 11.2 CÓDIGO FONTE DA APLICAÇÃO EXEMPLO....................................................................... 85 11.3 CÓDIGO FONTE ................................................................................................................ 91
11.3.1 Pacote br.ufsc.inf.viecili.svgchart ..................................................... 91 11.3.2 Pacote br.ufsc.inf.viecili.svgchart.data ......................................... 92 11.3.3 Pacote br.ufsc.inf.viecili.svgchart.parser .................................. 100
11.4 ARTIGO.......................................................................................................................... 105
iii
Resumo
Este trabalho apresenta todo o processo de aprendizado e desenvolvimento de uma
ferramenta que visa unir as tecnologias XML e SVG na geração de gráficos estatísticos de
uma forma genérica e funcional. São descritas todas as tecnologias associadas ao
planejamento, desenvolvimento e implementação da ferramenta. Também é apresentado o
modelo do projeto e sua aplicação prática, com exemplos simples e objetivos.
Palavras Chave: SVG, XML, JAVA, CSS, DTD, Servlet, Gráficos Estatísticos,
Gráficos Vetoriais Escaláveis.
iv
Abstract
This work presents the entire process of learning and development of a tool that
wishes to join technologies XML and SVG in the statistical charts’ generation in a generic
and functional form. All the technologies related to the planning, development and
implementation of this project are described. Also it is presented the model of the project
and its practical application, with simple and objective examples.
Key-words: SVG, XML, JAVA, CSS, DTD, Servlet, Statistical Charts, Scalable
Vector Graphics.
v
1 Introdução
Este trabalho visa aplicar os conhecimentos teóricos adquirido durante todo curso
em um trabalho prático que possa não apenas desenvolver habilidades técnicas, mas
também acrescentar uma nova aplicação que será de grande valia para empresas e comércio
em geral na área de geração de imagens vetoriais escaláveis.
O projeto propõe-se a criar uma ferramenta que possibilite transformar dados
especificados em um arquivo de marcação XML, para um arquivo de imagem gráfica
vetorial escalável SVG, através de definições de tipos de dados e de um conjunto de classes
implementadas na linguagem JAVA.
Ao longo deste relatório serão descritas as tecnologias utilizadas para execução do
projeto, apresentando características específicas e peculiaridades de cada uma delas. Serão
observados também os vários tipos de gráficos que este projeto dispõe-se a gerar em forma
de gráficos vetoriais escaláveis.
Será possível acompanhar as soluções encontradas e decisões tomadas durante todo
o desenvolvimento do projeto, mostrando como foi possível chegar a um resultado final que
possa sanar os objetivos traçados.
1
2 Objetivos
2.1 Objetivos Gerais
Produzir um conjunto de classes Java em código aberto, que possibilitem a geração
de gráficos estatísticos como gráficos vetoriais escaláveis a partir de dados contidos em um
documento XML.
2.2 Objetivos Específicos
Como objetivos específicos envolvidos no projeto temos :
• Estudo aprofundado das tecnologias recomendadas pelo W3C (World Wide
Web Consortium): XML (eXtensible Markup Language), SVG (Scalable
Vector Graphics) e sua interoperabilidade com a linguagem JAVA;
• Estudo dos padrões para representação de estatísticos em XML;
• Estudo das ferramentas relacionadas com a geração de gráficos estatísticos e
SVG;
• Estudo das bibliotecas JAVA para parsing de dados em XML;
• Analisar tecnologias relacionadas com a proposta deste projeto;
• Criação de um modelo de representação de dados estatísticos em XML;
• Criação de um mecanismo capaz de receber dados de entrada em XML e
transformá-los em gráficos vetoriais no padrão SVG, em vários modos de
apresentação.
2
3 Revisão de Literatura
3.1 XML
3.1.1 Visão Geral
XML (eXtensible Markup Language) é uma linguagem de marcação que usa um
formato de representação de dados em documento de uma forma mais amigável para sua
utilização na internet, recomendada pelo World Wide Web Consortium (W3C) em 1998.
XML tem suas raízes numa outra linguagem de marcação chamada SGML (Standard
Generalized Markup Language), e é usada para simplificar e dar maior flexibilidade às
aplicações (mais sobre SGML disponível em [SGML, 2003] )
Exemplo de um arquivo XML
A melhor forma de entender XML é apresentar um exemplo simples de um
documento nesta linguagem. O exemplo a seguir mostra um documento XML que descreve
dois professores:
1 <?xml version=”1.0” encoding=”UTF-8”?>
2 <professores>
3 <pessoa id=”silva”>
4 <nome>Eduardo da Silva</nome>
5 <especialidade>Cálculo Numérico</especialidade>
6 </pessoa>
7 <pessoa id=”souza”>
8 <nome>Luiza Souto e Souza</nome>
9 <especialidade>Álgebra linear</especialidade>
10 </pessoa>
11 <pessoa id=”desconhecido” />
12 </professores>
Figura 1 – Exemplo básico de documento XML
A linha 1 é conhecida como declaração XML e informa qual versão do XML está
sendo usada e qual a codificação de caracteres do documento. Esta linha faz parte do bloco
3
conhecido como Prólogo. No Prólogo podemos ter também: uma “declaração de tipo de
documento” (DTD – Data Type Declaration) que define o tipo e a estrutura do documento,
e uma ou mais instruções de processamento, como a ligação com uma “folha de estilos”
(style sheet) ao documento XML.
Na linha 2 temos a tag <professores> que começa um elemento único que inclui
tudo o que está à direita do caractere ‘>’ e a esquerda de </professores>. Este é o
elemento que engloba todos os outros, portanto, denominado “elemento raiz” (root).
Elementos podem conter outros elementos e/ou texto, e um arquivo XML deve conter ao
menos um elemento raíz que irá conter todos os outros elementos e definirá o tipo do
documento.
O elemento pessoa que descreve cada professor possui um atributo chamado id, que
diferentemente de elementos podem conter somente texto e os valores devem estar entre
aspas (simples ou duplas). Atributos são normalmente usados para metadados (dados sobre
dados), descrevendo propriedades do conteúdo dos elementos.
3.1.2 Regras Básicas de XML
Para criar um documento XML “bem-formado” é necessário observar algumas
regras simples para que o documento possa ser processado por um browser ou outro
programa. São elas:
• O documento deve ter exatamente um único elemento raiz. E todos os
outros elementos devem estar aninhados dentro dele.
• Elementos devem estar corretamente aninhados. Isto é, se um elemento
inicia dentro de um outro elemento, ele deve ser fechado dentro deste
mesmo elemento.
• Cada elemento deve ter uma tag inicial e uma final. XML é diferente de
HTML, todas as tags devem ser fechadas. Existe uma notação para
fechamento abreviado de elementos vazios.
4
• O nome que é utilizado na tag inicial deve corresponder exatamente ao
nome usado na sua tag final de fechamento.
• Os nomes utilizados nos documentos XML são Case-sensitives. Todos os
textos usados em um documento XML são, na realidade, case-sensitives.
Isto significa que existe diferenciação entre caracteres maiúsculos e
minúsculos. Portanto, o seguinte exemplo não é válido: <PESSOA>Fulano de Tal</Pessoa>
Mais informações sobre XML estão disponíveis em [XML, 2003]
3.1.3 DTD
Document Type Definition (DTD) é um documento que define um conjunto de
regras para um documento XML, especificando quantas e quais tags são permitidas neste
documento, os atributos e os relacionamentos das tags. São estas regras que definem qual é
o tipo do documento XML e servem principalmente como parâmetro de validação do
documento XML.
É um modelo de definição bastante robusto porém com DTD não é possível modelar
conteúdos desordenados e exceções de inclusão e exclusão.
Um DTD é formado por sete componentes básicos: Declaração do Tipo de
Documento; tipo Elemento; tipo Atributo; tipo Notação; tipo Entidade; seções
Condicionais; e Instruções de Processamento.
Nesta seção não será exemplificada a estrutura de um DTD, pois posteriormente
será apresentado o modelo de DTD usado para a validação dos dados de entrada XML.
5
3.2 CSS
3.2.1 Visão Geral
CSS (Cascading StyleSheet) é um mecanismo simples para adicionar estilo (fontes,
cores, espaçamento) aos documentos da web sem comprometer sua estrutura. CSS dá a
flexibilidade de definir estilos em um documento sem comprometer seus dados, além de
manter sua usabilidade em vários ambientes.
O suporte das propriedades CSS dependem do browser ou da aplicação que estiver
interpretando o documento, portanto nem todas as propriedades definidas na especificação
CSS estão implementadas.
3.2.2 Como Funciona
Folhas de estilos possuem regras compostas de seletores e declarações que definem
como os estilos serão aplicados. O seletor, que pode ser uma redefinição de tag, nome de
classe ou nome de ID, é a ligação entre o estilo e o documento. Existem dois tipos de
seletores: os de tipo, que definem globalmente tags do documento, e os de atributo, que
definem uma classe ou ID. Seguem alguns exemplos:
circle { stroke: black; stroke-width: 1.5; } //tag
aplica-se a toda tag <circle>
.filtro { filter: Alpha(Add=2,Direction=135,Strength=50} //atributo
aplica-se quando definida a classe <circle class=”filtro”>
#gramado {background-color: green; } //de ID
aplica-se quando definido o id <rect id=”gramado”>
Figura 2 – Declarações de estilos
Dependendo do tipo de documento no qual aplica-se uma folha de estilos, existem
propriedades específicas para determinados elementos, como elementos de texto que
possuem propriedades específicas para definir, por exemplo, a distância entre letras e/ou
palavras dentro de um bloco de texto.
6
A última especificação é a CSS2 revisão 1 que define muitas propriedades e
comportamento, e ainda está em desenvolvimento a versão 3, a especificação CSS3, que
deverá abranger a parte de módulos em CSS.
7
4 SVG Scalable Vector Graphics (SVG), em português “Gráficos Vetoriais Escaláveis”, é
uma aplicação de XML que torna possível representar informação gráfica de uma forma
compacta e portável. Os tópicos a seguir apresentarão maiores detalhes sobre
representações gráficas e alguns conceitos de SVG.
4.1 Sistemas Gráficos
Existem dois principais sistemas gráficos para representação de informação gráfica
usados na computação:
• Gráficos Raster: neste padrão, a imagem é representada como uma matriz
retangular de pixels chamada de bitmap, que é freqüentemente armazeda em
um formato compactado (GIF, JPEG e PNG). A utilização de gráficos raster
é mais apropriada para o uso em imagens que não se procupam em definir
formas geometricas individualmente, e sim em apresentar a imagem como
um todo.
• Gráficos Vetoriais: neste sistema, uma imagem é descrita como uma
coleção de formas geométricas que contêm o conjunto de instruções
necessárias para o desenho. Os usos mais comuns de gráficos vetoriais são
em programas CAD (Computer Assisted Drafting), impressoras de alta
resolução, animações e apresentações, principalmente pela facilidade de
transformar e visualizar em alta definição esses gráficos.
4.2 Um pouco sobre SVG
Em 1998, o W3C formou um grupo para desenvolver uma representação de gráficos
vetoriais como uma aplicação XML. Uma vez que SVG é uma aplicação XML, a
8
informação sobre a imagem é armazenada em texto puro, e traz as vantagens de liberdade,
transportabilidade e interoperabilidade do XML.
Com isso, SVG pode cooperar com outras aplicações XML, como por exemplo um
sistema matemático de equações onde o SVG gere os gráficos para as equações. E é neste
ponto que este trabalho é focado, “o uso do SVG como forma de apresentação dos dados”.
4.3 Conceitos e Definições
4.3.1 Estrutura de um documento SVG
O documento abaixo possui as declarações padrões de XML e a declaração de
DOCTYPE iniciais. O elemento raíz <svg> define a largura e a altura do gráfico. Os
elementos subseqüentes (<title> e <desc>) apresentam o título e uma descrição da
imagem.
1 <?xml version=”1.0” encoding=”UTF-8”?>
2 <!DOCTYPE svg PUBLIC “-/W3C//DTD SVG 1.0//EN
“http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd”>
3 <svg width=”140” height=”170”>
4 <title>Título</title>
5 <desc>Descrição</desc>
6 <!-- desenho será inserido aqui -->
7 </svg>
Figura 3 – Estrutura básica de um documento SVG
Utilizando Estilos com SVG
SVG permite definir estilos de apresentação dos gráficos de quatro maneiras:
• Estilos Inline: a definição e feita colocando uma série de propriedades
visuais e seus valores no atributo <style> de qualquer elemento SVG.
<circle cx=”20” cy=”20” r=”10”
style=”stroke: black; stroke-width: 1.5;” />
Figura 4 – utilização de estilo inline.
9
• Estilos Internos: a definição do estilo é feita como conteúdo de uma tag
<style> pertencente a uma tag <defs>.
...
<defs>
<style type=”text/css”><![CDATA[
estilo {
fill: #66cc99
stroke: green;
stroke-width: 2;
}]]>
</style>
</defs>
...
Figura 5 – utilização de estilo interno
• Estilos Externos: a definição dos estilos é feita em um arquivo separado do
documento SVG, e é inserida no documento usando a sintaxe XML para
declaração de instruções de processamento.
<?xml version=”1.0”?>
<?xml-stylesheet href=”est_externo.css”
type=”text/css”?>
... (doctype declaration) ...
Figura 6 – referência a folha de estilos externa
10
4.3.2 Formas Básicas
A tabela a seguir apresenta as formas básicas disponíveis em SVG.
Forma Descrição <line x1=”x-inicial” y1=”y-
inicial” x2=”x-final” y2=”y-final”
/>
Desenha uma linha a partir da
coordenada (x-inicial, y-inicial) até
ao ponto final de coordenada (x-final, y-
final) <rect x=”x-esquerda” y=”y-
superior” width=”largura”
height=”comprimento” />
Desenha um retângulo o qual seu
canto superior esquerdo tem coordenada (x-
esquerda, y-superior) com sua
respectiva largura e comprimento <circle cx=”x-centro” cy=”y-
centro” r=”raio” /> Desenha um círculo com o raio
informado com o centro na coordenada (x-
centro, y-centro) <ellipse cx=”x-centro” cy=”y-
centro” rx=”raio-x” ry=”raio-y” /> Desenha uma elípse com os raios x e
y informados e com o centro na coordenada
(x-centro, y-centro) <polygon
points=”especificação dos pontos”
/>
Desenha um polígono fechado cujas
arestas são definidas dentro da
especificação dos pontos como retas
entre os pontos <polyline
points=”especificação dos pontos”
/>
Desenha uma série de linhas
conectadas descritas através da especificação dos pontos
Tabela 1 – Tabela de Formas Básicas
11
4.3.3 Texto
Como SVG é definido todo em forma de caracteres legíveis, a representação de
texto é uma funcionalidade bastante desenvolvida nesta tecnologia.
Para definir um elemento de texto <text> é necessário somente dois atributos, x e y,
que definem o ponto onde a linha base do primeiro caractere será posicionada.
Como as fontes de texto usadas para o SVG são todas definidas de forma vetorial, a
grafia e as propriedades do caractere/texto podem ser modificadas assim como qualquer
outro objeto através de definições de estilos, porém textos possuem propriedades de
visualização específicas, como: tipo, tamanho, peso e estilo de fonte, decoração do texto,
espaçamento entre palavras e letras, alinhamento etc.
Para construir um bloco de texto com diferentes propriedades internas como, por
exemplo, misturando textos em itálico, normal e negrito, utiliza-se o elemento denominado
text span ou, simplesmente, <tspan>. Este elemento assemelha-se ao <span> do XHTML,
e possibilita aplicar qualquer modificação no texto dentro de seu escopo, substituindo os
valores das propriedades e mantendo somente a posição do texto.
Como o texto comporta-se como objeto, é possível aplicar várias transformações,
inclusive colocá-lo na vertical e em ordem inversa, ou até mesmo ajustá-lo a um caminho
adjacente.
Contudo existe um problema quando usa-se quebra de linha em um bloco de texto,
pois durante o parsing do documento a quebra de linha não é interpretada e a nova linha
não é exibida em outra linha. Porém este problema está sendo trabalhado e deve ser
corrigido nas próximas versões do SVG.
12
4.3.4 Conceitos e Definições Avançadas
SVG ainda possui uma série de conceitos e definições mais complexas que as
apresentadas até aqui, que não são tão significantes neste trabalho porém não podem ser
deixadas de lado. A seguir são apresentadas algumas dessas definições e conceitos:
Agrupamento de Objetos
O elemento <g> junta seus elementos filhos como um grupo que possui um
identificador único. Este grupo comporta-se como sendo um objeto.
Referência a Objetos
Para fazer referências posteriores a objetos existe o elemento <use>, que faz isto
através do identificador de objeto.
O Elemento defs
Colocando objetos agrupados ou simples dentro do escopo do elemento <defs> é
possível definir tais objetos sem desenhá-los.
O Elemento image
Em um documento SVG é possível colocar outro SVG inteiro ou uma imagem
raster (JPG ou PNG) utilizando o elemento <image>.
Transformações
SVG ainda possibilita vários tipos de transformações no sistema de coordenadas. É
possível fazer translação (mover), escala (aumentar - diminuir), rotação (girar), skew
(enviesamento, inclinar) dos objetos no plano cartesiano. Na realidade essas transformações
são aplicadas ao sistema de coordenadas, mantendo todas as propriedades dos objetos.
13
Caminhos
É possível desenhar linhas e caminhos de muitas formas diferentes, através de
seqüência de comandos e coordenadas. Com estes comandos pode-se criar desde linhas
retas e arcos elípticos, até curvas de bézier cúbicas, quadráticas e simples.
Scripts
Através de scripts ECMA (JavaScript, Perl) é possível atribuir comportamentos a
determinados eventos em um objeto. Tais scripts podem estar definidos dentro do
documento SVG no elemento <script> ou por referência em outro arquivo.
14
5 Desenvolvimento e Implementação A partir de todos esses conhecimentos básicos adquiridos durante o primeiro
aprendizado dentro deste projeto foi possível iniciar o seu desenvolvimento de uma forma
objetiva e consciente, visando o alcançar os objetivos determinados.
A seguir são apresentados todos os processos que foram passados durante a etapa de
desenvolvimento e implementação:
5.1 Definição dos tipos de gráficos
O primeiro passo do desenvolvimento deste trabalho foi definir quais seriam os
tipos de gráficos estatísticos a serem gerados. Portanto, foram escolhidos seis tipos de
gráficos simples.
Esses tipos de gráficos são explicados e exemplificados1 nos tópicos seguintes:
11 Os exemplos de gráficos usados neste tópico 5.1 são meramente ilustrativos e não
representam o aspecto final dos gráficos que serão gerados.
15
5.1.1 Gráfico de Colunas Agrupadas
As informações dos dados das variáveis neste tipo de gráfico são mostradas como
colunas organizadas em grupos que representam os intervalos de suas medições, sendo que
a altura das colunas indica a quantidade de dados de uma variável.
Este tipo de gráfico é bastante útil em sistemas com dados em multi-variáveis,
possibilitando uma maior compreensão visual na comparação destes dados entre si,
facilitando sua análise.
Gráfico de Colunas Agrupadas
0,00
20,00
40,00
60,00
80,00
100,00
jan fev mar abr mai jun jul ago set
Eixo X
Eix
o Y
abcd
Figura 7 – Exemplo de Gráfico de Colunas Agrupadas
16
5.1.2 Gráfico de Barras Agrupadas
Apresenta as informações de uma forma bastante semelhante ao gráfico descrito
anteriormente, com a diferença de que, ao invés de colunas, são utilizadas barras
horizontais, onde a largura destas barras define a quantidade de dados de uma variável.
É uma forma alternativa de apresentação à forma em colunas, contudo possui as
mesmas vantagens.
Gráfico de Barras Agrupadas
0,00 20,00 40,00 60,00 80,00 100,00
jan
mar
mai
jul
set
Eix
o X
Eixo Y
dcba
Figura 8 – Exemplo de Gráfico de Barras Agrupadas
17
5.1.3 Gráfico de Linhas
É um gráfico onde os pontos referentes à evolução dos dados de uma variável são
conectados através de uma linha.
Este tipo de gráfico é bastante útil para a comparação da evolução dos valores de
uma ou mais variáveis, pois as linhas que conectam os valores fornecem uma relação visual
desta evolução.
Gráfico de Linhas
0,00
20,00
40,00
60,00
80,00
100,00
jan fev mar abr mai jun jul ago set
Eixo X
Eixo
Y
abcd
Figura 9 – Exemplo de Gráfico de Linhas
18
5.1.4 Gráfico de Pizza
Este é um modelo de gráfico que somente admite uma seqüência de valores,
apresentados como um círculo divido em fatias que representam a contribuição percentual
de um valor ao universo (soma de todos os valores).
Este gráfico é bastante utilizado para representar gráficos de pesquisa de opinião e
análise setorial.
Gráfico de Pizza
50,86; 14%
50,71; 14%
41,72; 12%
34,38; 10%43,28; 12%
73,86; 22%
22,22; 6%
34,57; 10%
0,86; 0%janfevmarabrmaijunjulagoset
Figura 10 – Exemplo de Gráfico de Pizza
19
5.1.5 Gráfico de Dispersão
Este gráfico apresenta múltiplos pontos distribuídos no plano de acordo com suas
coordenadas x e y.
É bastante utilizado para definir um comportamento médio dentro de um universo
muito grande de dados observados.
Gráfico de Dispersão
-1
-0,5
0
0,5
1
0 20 40 60 80 100 120
Eixo X
Eix
o Y
a
Figura 11 – Exemplo de Gráfico de Dispersão
20
5.1.6 Gráfico de Área
O gráfico de área é bastante semelhante ao gráfico de linhas, porém com a diferença
de que o espaço abaixo da linha é preenchido com uma determinada cor.
É útil para analisar e evolução de variáveis sobrepostas através da sobreposição de
cores dentro do gráfico.
Gráfico de Área
0,00
20,00
40,00
60,00
80,00
100,00
120,00
jan fev mar abr mai jun jul ago set
Eixo X
Eix
o Y
abcd
Figura 12 – Exemplo de Gráfico de Área
21
5.2 Elaboração do DTD
Para organizar e definir o documento XML com os dados de entrada para geração
dos gráficos fez-se necessária a utilização de um DTD bastante simples e eficaz, que
pudesse representar os dados de uma forma trivial e real.
Qual seria a forma mais trivial para organizar dados textuais? Tabelas, a forma mais
comum para a representação textual de informações de dados.
A partir deste momento então iniciou-se o processo de modelagem de uma estrutura
de arquivo DTD que representasse a estrutura de uma tabela de dados. E, como o objetivo
deste projeto não é reinventar a roda, a mesma estrutura simples de elementos de tabela
usada em HTML foi usada para compor os tipos Elemento do DTD e seus relacionamentos.
O mesmo nome que os elementos têm em HTML foi utilizado nesta Definição de
Tipo de Documento, a fim de possibilitar a reusabilidade das ferramentas disponíveis no
mercado para criação de tabelas HTML; entretanto os atributos dos elementos foram
definidos de modo mais simplificado com o objetivo de compatibilizar o documento com
os seus propósitos.
Então o DTD foi definido do seguinte modo:
<?xml version="1.0" encoding="UTF-8"?>
<!ELEMENT TABLE (DESC?, TR+)>
<!ELEMENT DESC (#PCDATA)>
<!ELEMENT TR (TD+)>
<!ELEMENT TD (#PCDATA)>
<!ATTLIST TABLE
type CDATA #IMPLIED
name CDATA #IMPLIED
xAxisLabel CDATA #IMPLIED
yAxisLabel CDATA #IMPLIED
svgWidth CDATA #IMPLIED
22
svgHeight CDATA #IMPLIED
>
<!ATTLIST TR
type CDATA #IMPLIED
name CDATA #IMPLIED
>
<!ATTLIST TD
type CDATA #IMPLIED
name CDATA #IMPLIED
>
Figura 13 – Arquivo svgchart_data.dtd
Este DTD deve ser usado em todo documento XML de entrada em seu prólogo na
declaração do tipo de documento.
5.3 Semântica do XML de Entrada
Embora a sintaxe da para definição dos dados de entrada seja bastante parecida com
a sintaxe de tabela HTML, o significado dessas tags está diretamente relacionado com o
objetivo deste projeto que é a geração de gráficos estatísticos em SVG.
Eis então algumas definições sobre cada elemento e seu relacionamento com os
demais:
• TABLE: é o elemento raiz do documento, irá conter todos os dados do
gráfico e seus atributos referem-se a propriedades gerais do gráfico. O
elemento TABLE tem os seguintes atributos:
o type (opcional): é usado para identificar qual o tipo de gráfico que
deve ser gerado. Pode assumir os seguintes valores:
groupedColumnChart (default): Gráfico de Colunas Agrupadas
groupedBarChart: Gráfico de Barras Agrupadas
lineChart: Gráfico de Linhas
pizzaChart: Gráfico de Pizza
scatterChart: Gráfico de Dispersão
23
areaChart: Gráfico de Área
o name (opcional): é usado para dar um título ao gráfico gerado. Pode
assumir qualquer valor.
o xAxisLabel (opcional): é usado para dar título ao Eixo X do plano
gráfico. Pode assumir qualquer valor.
o yAxisLabel (opcional): é usado para dar título ao Eixo Y do plano
gráfico. Pode assumir qualquer valor.
o svgWidth (opcional): é usado para definir a dimensão de largura do
gráfico gerado. Deve assumir valor numérico representando pixels.
o svgHeight (opcional): é usado para definir a dimensão de altura do
gráfico gerado. Deve assumir valor numérico representando pixels.
• DESC: dentro deste elemento pode-se colocar uma breve descrição do
gráfico, que dependendo do tipo do gráfico será usada como subtítulo. O
caractere de nova-linha é ignorado durante o parsing do conteúdo deste
elemento, portanto para definir uma nova linha devem-se usar dois pontos-e-
virgula (;;). Este elemento não possui atributos. Dentro da tag <TABLE> pode
existir no máximo um elemento <DESC>.
• TR: (Table Row) define uma linha (tupla) para entrada de dados. Dentro de
uma tag <TABLE> deve existir no mínimo 1 (um) elemento <TR>. Esse
elemento possui os seguintes atributos:
o type (opcional): este atributo é usado para definir se as informações
da linha em questão são nomes das variáveis (colunas da tabela) ou
são os dados propriamente ditos. Pode assumir os seguintes valores:
data (default): define que as informações da linha são dados
propriamente ditos.
dataField: define que as informações da linha se referem ao
nome das variáveis (colunas) correspondentes aos dados.
o name (opcional): serve para dar um nome para a linha de dados que,
dependendo do gráfico, pode ser usado como um identificador). Este
atributo pode assumir qualquer valor.
24
• TD: (Table Data) representa uma célula (dado) de uma tabela. A tag <TR>
deve conter uma ou mais tags <TD>. Este elemento possui os seguintes
atributos:
o type (opcional): define se o dado é um número inteiro, de ponto
flutuante ou uma string. Pode assumir os seguintes valores:
string (default): define que o dado é uma seqüência de
caracteres e não pode ser operado.
int: define que o dado é um número inteiro.
float: define que o dado é um número de ponto flutuante.
Para separar a parte inteira das casas decimais deve-se
usar “.” (ponto). Pode-se usar ainda a notação
exponencial, por exemplo, 1.2e-9 para representar o
número 0.0000000012.
o name (opcional): é utilizado para identificar o dado que, dependendo
do tipo do gráfico e do dado, pode ser mostrado como texto
alternativo.
A semântica básica do arquivo XML de entrada é esta apresentada, porém alguns
gráficos possuem características bastante específicas e, dependendo do gráfico solicitado, a
interpretação dos dados (não da estrutura, nem dos elementos) pode mudar. Estas diferentes
interpretações serão abordadas mais tarde.
5.4 Definição da Linguagem de Programação e API XML
A linguagem de programação a ser usada neste projeto estava definida desde o
início, porém neste ponto do desenvolvimento foi que ela se tornou efetiva. JAVA foi
escolhida, pois é a linguagem que possui a filosofia que mais se encaixa na proposta de um
produto livre e com tecnologias voltadas para web, um dos pontos fortes dessa linguagem.
Entretanto, neste momento foi necessário pensar em algo que ainda não havia
pensado: Qual API (Application Programming Interface) para XML disponível usar?
25
Existem duas opções a serem analisadas: DOM (Document Object Model) e SAX(Simple
API for XML). A API escolhida foi a SAX.
A linguagem de programação e a API são apresentadas a seguir, juntamente com a
explicação das suas escolhas:
5.4.1 JAVA
A linguagem de programação Java foi desenvolvida pela Sun Microsystems, mais
especificamente por um de seus engenheiros, o Sr. James Gosling entre os anos de 1991 a
1995, quando foi apresentada ao mercado.
É uma linguagem Orientada a Objetos, e independente de plataforma que está se
estabilizando rapidamente como um meio para a programação baseada em rede (ou
programação para web). Pois é uma linguagem pré-compilada e interpretada, baseada em
uma máquina virtual bem especificada, a Java Virtual Machine, que roda em todas as
plataformas atuais, possuindo um sistema de tipos forte o suficiente para manter sua
estabilidade e segurança.
Além disso, Java possui um extenso suporte de bibliotecas, como bibliotecas de
interface gráfica, segurança e XML, que possibilitam um estilo de programação mais
abstrato e transparente.
Estas são as principais razões pelas quais a linguagem Java foi escolhida, não
somente para este projeto, mas também como a linguagem na qual eu tenho me dedicado
como estudante e futuro profissional.
5.4.2 SAX – Simple API for XML
A escolha de SAX para criar o parser XML foi baseada em aspectos bem definidos,
porém antes de citá-los é necessário que se faça uma pequena descrição dessas duas APIs
disponíveis:
26
• DOM - Document Object Model: é uma interface de plataforma e
linguagem que permite que programas e scripts acessem e atualizem o
conteúdo, a estrutura e o estilo de documentos XML de forma dinâmica,
permitindo criar documentos, navegar dentro da estrutura do documento e
adicionar, apagar e alterar elementos. Isto é feito através da conversão de
todo o documento XML em uma estrutura de árvore, e todas as funções são
baseadas em algoritmos de busca, percorrimento e modificação em árvores.
• SAX – Simple API for XML: assim como DOM, SAX é uma forma de
acesso às informações armazenadas nos documentos XML usando uma
linguagem qualquer de programação (e um parser para a linguagem).
Contudo, enquanto DOM cria uma árvore de nós para armazenar a
informação, o SAX tem um parser que informa à aplicação o que está no
documento através de um fluxo de eventos de parsing (abertura e
fechamento de tag, reconhecimento de caracteres, etc). A aplicação então
processa esses eventos para agir em cima dos dados. SAX é bastante útil
quando o documento em questão for bastante extenso.
Portanto, os principais aspectos que foram considerados para a escolha do SAX são
a capacidade de lidar com grandes quantidades de informações, o pouco uso de memória
durante o parsing do documento XML e, principalmente, a sua estrutura baseada em
eventos que facilitam o tratamento dos dados de entrada, uma vez que estes não precisam
ser modificados ao longo do processo.
5.5 Definição da Interface do Usuário e Tecnologias
Relacionadas
Como as tecnologias já citadas anteriormente estão todas relacionadas com o meio
web ficou definido também que a interface do usuário seria uma interface web simples,
composta de uma página simples e um elemento (Servlet Java) que recebe a requisição
através do método post contendo o arquivo XML como parâmetro de entrada e fornece
como saída o gráfico vetorial escalável em SVG.
27
Na verdade, esta interface do usuário realmente a casca da aplicação, que será
desenvolvida de modo que permita sua total reusabilidade, tanto em sistemas web como em
sistema standalone, devendo apresentar uma estrutura de implementação com
características de JavaBeans.
Nestes dois parágrafos anteriores foram citadas duas tecnologias importantes na
execução deste projeto, os Servlets Java e o padrão de construção JavaBean, em poucas
palavras:
• Servlet: são classes Java que rodam em um servidor web recebendo
requisições a partir de formulários HTML através dos métodos post e get. Os
servlets executam operações com base nos dados recebidos e fornecem uma
resposta que pode variar desde um arquivo de texto plano, um documento
XML, uma página HTML ou qualquer outro dado binário.
• Padrão JavaBean: é um padrão de componente reutilizável que define que
uma classe deve ser pública, possuir um construtor público default, ser
serializável e ter métodos de acesso às propriedades. Deste modo estas
classes podem ser combinadas com qualquer outro tipo de aplicação.
28
5.6 Utilização de Ferramentas de Auxílio ao Desenvolvimento
Para auxiliar o desenvolvimento das classes e do projeto como um todo, foram
escolhidas algumas ferramentas livres e de código aberto para executar algumas tarefas.
Depois de algum tempo pesquisando pela web, encontrei as seguintes ferramentas:
5.6.1 Oracle JDeveloper 10g IDE
É um Ambiente de Desenvolvimento Integrado (Integrated Development
Environment) desenvolvido pela Oracle, projetado para prover suporte total no
desenvolvimento de aplicações Java e Web Services.
Esta ferramenta foi usada como ambiente de desenvolvimento do projeto, foi usada
para codificar, compilar e fazer o debug da aplicação.
5.6.2 JFreeChart
É uma biblioteca de classes, escritas em Java, de código aberto e de uso livre para
propostas acadêmicas (sobre os termos da GNU Lesser General Public Licence), que
facilita a criação de vários tipos de gráficos estatísticos.
5.6.3 Batik SVG Toolkit
É um subprojeto do Projeto APACHE XML com o objetivo de dar aos
desenvolvedores um conjunto módulos base que possam ser usados na construção de
soluções diretamente relacionadas a SVG.
O Projeto Batik é uma biblioteca de classes e ferramentas livres baseada em Java
para auxiliar aplicações a gerar, manipular e visualizar imagens SVG, seguindo os termos
da Apache Software License. A versão atual do Batik é a 1.5.
29
Esta ferramenta foi usada otimizar o processo de criação dos arquivos SVG a partir
dos dados obtidos com o parsing e tradução do documento XML de entrada, e a passagem
pelo JFreeChart.
5.7 Ferramenta de Testes, Execução e Visualização
Para que o projeto seja bem sucedido é necessário que se definam quais serão as
ferramentas utilizadas para executar os testes durante o desenvolvimento, a execução do
produto final e a visualização dos gráficos gerados.
Como a interface do usuário escolhida foi uma interface web fez-se necessária a
adoção de um servidor de aplicações, que juntamente com o ambiente integrado de
desenvolvimento citado anteriormente, serviu para fornecer o suporte necessário para fazer
os testes e executar a aplicação como um todo. O servidor escolhido foi o:
5.7.1 Apache Tomcat
É um subprojeto do Projeto Jakarta da Apache desenvolvido em um ambiente aberto
e participativo sobre os termos da Apache Software License.
O Tomcat é um servlet container que é usado como implementação de referência
para as tecnologias Java Servlet e JavaServer Pages (JSP).
E foi por ser a maior referência de implementação para estas tecnologias,
reconhecido pela própria Sun Microsystem, foi escolhido para rodar e testar a aplicação
desenvolvida neste projeto que irá gerar os documentos SVG que podem ser visualizados
nos seguintes aplicativos:
30
5.7.2 Adobe SVGViewer
É um plug-in desenvolvido pela Adobe para fazer a visualização que suporta a
maioria dos elementos SVG definidos na especificação, vários estilos CSS e possibilita
salvar os documentos SVG em um padrão compactado chamado de SVGZ.
5.7.3 Squiggle SVG Browser
É um browser de arquivos SVG incluído na distribuição do Batik, e foi construído
totalmente com as bibliotecas Batik. Ele permite visualizar, fazer zoom e aplicar
transformações nos arquivos SVG. É uma ferramenta livre e de código aberto.
5.8 A classe SVGChart
A classe SVGChart é a classe que segue, de um modo geral, o padrão JavaBean. É
esta a classe responsável por receber os dados de entrada e retorná-los quando lhe for
solicitado. Ou seja, é o ponto de ligação entre as aplicações externas e a máquina interna de
processamento.
Esta classe possui poucos métodos, dentre eles estão os métodos setData() que são
utilizados para passar o documento de entrada ou o seu conteúdo, e os métodos
getSVGChart() que retornam o documento ou o conteúdo do arquivo gerado em SVG.
5.9 Implementação da Classe de Manipulação dos Dados
Para fazer a divisão e a análise do documento de entrada de dados foi necessário
criar uma classe handler. A criação desta classe foi auxiliada pelo tutorial de Web Services
Java (ARMSTRONG, 2003). Alguns aspectos da criação desta classe são definidos a
seguir:
31
5.9.1 Bibliotecas Utilizadas
Para a parte de processamento do arquivo de entrada foram usadas as seguintes
bibliotecas:
• org.xml.sax: pacote que provê classes e interfaces para SAX.
• org.xml.sax.helpers: pacote que provê classes de ajuda para SAX.
• javax.xml.parsers: pacote que provê classes que permitem o processamento
de documentos XML.
Para os métodos de retorno dos dados, já como gráficos vetoriais escaláveis, foram
usadas as seguintes bibliotecas:
• org.jfree.chart: pacote que provê classes bases para a criação dos gráficos
estatísticos.
• org.jfree.data: pacote que provê classes e interface referentes aos dados dos
gráficos estatísticos.
• org.apache.batik.svggen: pacote que provê a API para tradução das
primitivas gráficas de Java para SVG.
• org.apache.batik.dom: pacote que provê as classes de implementação do
módulo base do DOM level 2.
• org.w3c.dom: pacote que provê as interfaces para DOM.
5.9.2 Implementação
A classe para a manipulação desses dados foi nomeada como XMLHandler e
colocada no pacote br.ufsc.inf.viecili.svgchart.parser, sendo também definida
como uma classe de especialização da classe org.xml.sax.helpers.DefaultHandler.
A classe DefaultHandler é uma classe básica para a criação de outras classes
manipuladoras de dados XML, pois possui o método que gerencia o processo de parsing e
também possui implementações vazias de métodos/eventos que devem ser sobrescritos por
suas classes de especialização.
32
Portanto, coube a classe XMLHandler implementar os métodos startElement(),
characters() e endElement(). Além destes métodos básicos para a análise do
documento foram criados mais dois métodos para receber o arquivo ou o conteúdo do
documento de entrada XML e produzir a saída do documento SVG.
Dentro do método startElement() é feito o reconhecimento das tags, a leitura dos
seus atributos e o ajuste de alguns objetos e atributos referentes ao conjunto de dados.
Dentro do método characters() são recolhidos os dados propriamente ditos, que
são armazenados em variáveis globais que serão utilizadas dentro do método
endElement(), que coordena a inserção dos dados destas variáveis nos objetos de conjunto
de dados.
Os outros dois métodos implementados são métodos de acesso aos dados de entrada,
que solicitam à superclasse que inicie a execução do processo de parsing e fazem a ligação
dos conjuntos de dados com o JFreeChart e posteriormente com o Batik para retornar o
conteúdo ou o arquivo com os dados do gráfico em SVG.
5.10 Implementação das Classes de Conjuntos de Dados
Para organizar os dados lidos do documento de entrada foi necessário especificar e
implementar um conjunto de classes que armazenasse os dados em estruturas de dados que
pudessem ser acessadas de uma forma mais rápida e objetiva pela aplicação, principalmente
para quando fosse feita a tradução destas estruturas de dados em objetos gráficos Java 2D
através do JFreeChart.
O diagrama de classes deste módulo da aplicação é apresentado, de forma
compacta, a seguir:
33
Figura 14 – Diagrama de Classes de Conjunto de Dados
Este modelo é composto de uma interface que define os métodos para inclusão e
ajustes de propriedades para um conjunto de dados (dataset) que podem ser consultados
nos anexos de código fonte.
O modelo também possui uma classe factory que ‘produz’ instâncias das
implementações da interface de acordo com a solicitação que é feita através do método
createDataset() que recebe o tipo do gráfico a ser gerado como parâmetro e do método
createDefaultDataset() que retorna uma instância de SVGCategoryChartDataset para
um gráfico de colunas agrupadas.
O construtor de cada uma das classes que implementam SVGChartDataset recebem
como parâmetro o tipo do gráfico de deve ser gerado como saída do método getChart(), e
a partir deste parâmetro os atributos são inicializados e ações são definidas. A seguir é
apresentada uma breve descrição de cada componente do diagrama:
Interface SVGChartDataset: é a interface que define os métodos a serem
implementados de acordo com o tipo de organização de dados desejado.
34
Classe SVGPizzaChartDataset: esta classe implementa os métodos definidos na
interface, organiza e mantém os dados quando o gráfico solicitado é do tipo Gráfico de
Pizza.
Classe SVGCategoryChartDataset: esta classe implementa os métodos definidos na
interface, organiza e mantém os dados quando os gráficos solicitados são: Gráfico de
Colunas Agrupadas, de Barras Agrupadas, de Linha e de Área.
Classe SVGScatterChartDataset: esta classe implementa os métodos definidos na
interface, organiza e mantém os dados quando o gráfico solicitado é do tipo Gráfico de
Dispersão.
Classe SVGChartDatasetFactory: é a classe responsável por fornecer uma instância
de implementação da interface SVGChartDataset de acordo com o tipo de gráfico
informado como parâmetro em um de seus métodos.
Optou-se por esse modelo de implementação devido a maior transparência e
generalização no momento de implementar as classes de dataset específicas. Entretanto,
ainda é possível especificar mais algumas classes para tornar esse modelo mais genérico e
robusto através da inclusão de classes abstratas que implementem genericamente, para cada
tipo de gráfico, os métodos definidos na interface. Porém isto não foi feito nesta versão do
projeto por demandar uma análise bem mais profunda das várias possibilidades dentro da
modelagem do diagrama, prejudicando o objetivo de ao final do projeto poder ser
apresentada uma ferramenta funcional.
5.11 Criação da Aplicação Exemplo
Depois de modelar e codificar boa parte das classes foi necessário criar uma
pequena aplicação para servir como interface de usuário e testar a aplicação. Portanto, criei
uma aplicação web baseada em uma página HTML e um Servlet.
35
A página inicial é composta de um formulário com um campo (de nome xmlfile)
onde o usuário informa o arquivo XML com os dados de entrada, e um botão submit que
envia o formulário através do método POST — é necessário que o formulário seja enviado
por POST, pois contém um arquivo anexado (XML) e possui características não suportadas
pelo método GET.
(...)
<form action="svgchartservlet" method="POST"
enctype="multipart/form-data">
<H3>
Informe o arquivo XML com a definição dos dados:
<BR/>
<input type="file" name="xmlfile" style="width:60%"/>
</H3>
<P align="right">
<input type="SUBMIT" value="Gerar Gráfico"/>
</P>
</form>
(...)
Figura 15 – Formulário HTML da aplicação exemplo
Essa requisição parte do usuário local para o Servlet que roda no servidor de
aplicação web. Este servlet recebe a requisição e processa o conteúdo verificando a
ocorrência de um campo de arquivo, posteriormente envia o documento para que a classe
SVGChart o processe e retorne o gráfico em formato SVG que será escrito diretamente no
conteúdo in-line da resposta à solicitação.
Desta maneira criou-se um meio intuitivo e conveniente para que um usuário possa
testar e usufruir a aplicação desenvolvida.
36
6 Modelo do Processo de Geração dos Gráficos Todo o processo de geração do gráfico no formato SVG envolve basicamente sete
passos que estão indicados na figura abaixo e explicados posteriormente.
Figura 16 – Fluxo do Processo de Geração dos Gráficos
6.1 Criação e Envio do Arquivo de Entrada XML
Para gerar um gráfico estatístico no formato SVG é necessário primeiro elaborar um
documento de entrada em XML contendo algumas diretivas para a execução desta tarefa. É
neste arquivo que são especificados o nome do gráfico, dos eixos e das séries de dados,
qual o tipo do gráfico a ser gerado, e mais algumas outras propriedades.
37
Depois deste documento ser produzido, é necessário que seu conteúdo, ou a
referência para sua localização física, seja enviada ao XMLHandler que irá manipular os
dados.
6.2 Análise e Conversão dos Dados em Objetos de Conjuntos de
Dados
Uma vez que o XMLHandler tenha recebido o documento de entrada XML é
iniciado um processamento sobre este arquivo, quando o seu conteúdo é analisado e
convertido em um objeto que mantém os dados em uma estrutura mais organizada que
possibilite um acesso mais eficiente a estes métodos.
Após os dados serem organizados nestes objetos de conjuntos de dados —
chamados de SVGChartDataset’s — eles são repassados ao JFreeChart que, após ser
ajustado, transforma tais objetos em um objeto gráfico Java 2D.
6.3 Transformação em Objetos Gráficos Java 2D
Para que seja possível transformar os datasets em objetos gráficos Java 2D é
necessário que se ajuste algumas propriedades internas do JFreeChart.
Após ajustar tais propriedades faz-se a transformação quando vários cálculos são
efetuados para ajustar intervalos, definir alturas e larguras, estabelecer proporções, e por
fim transformar todos os dados em uma forma visual dentro de um objeto Java 2D.
Este objeto com a representação visual do gráfico é retornado ao XMLHandler que é
responsável por fazer a ligação entre o objeto gráfico Java 2D e a biblioteca do Batik SVG
Toolkit.
38
6.4 Transformação dos Objetos Gráficos Java 2D em SVG
Após o objeto Java 2D ser passado ao XMLHandler, é criada uma instância da
classe org.apache.batik.svggen.SVGGraphics2D que é responsável por traduzir os
objetos Java 2D em gráficos SVG.
Isto é possível pois a classe SVGGraphics2D é uma implementação da classe
abstrata java.awt.Graphics2D que, diferente das implementações da plataforma Java,
escreve sua saída em um documento SVG e não em um monitor ou impressora.
Entretanto, para que o gráfico seja gerado corretamente é preciso ajustar algumas
propriedades e definir parâmetros de estilo a serem usados. Depois disto o gráfico é escrito
em um arquivo que será lido e retornado a quem solicitou sua criação através do
XMLHandler.
6.5 Envio do Gráfico SVG
Estando o gráfico disponível, é necessário verificar se a solicitação foi para retorna
o próprio arquivo ou seu conteúdo. Caso tenha sido solicitado seu conteúdo, o arquivo é
totalmente lido em uma string e retornado, senão é retornada uma referência a localização
física do arquivo.
E, por fim, o gráfico SVG é passado através do SVGChart para quem enviou o
arquivo de entrada XML.
39
7 Aplicação Prática do Processo de Geração dos Gráficos
O passo mais importante do processo de geração do gráfico SVG é a elaboração e a
análise do documento de entrada em XML, portanto estes serão os aspectos discutidos nesta
seção:
7.1 Elaboração do Documento de Entrada XML
O gráfico a ser gerado depende quase exclusivamente das informações contidas no
documento de entrada em XML. De fato, o gráfico a ser gerado será a apresentação visual
dos dados descritos no documento.
São três as classes de gráficos estatísticos implementadas neste projeto — Pizza,
Dispersão e Categorias —, elas variam conforme a organização dos conjuntos de dados, o
que implica em alguns detalhes que devem ser observados na construção do documento de
entrada XML:
7.1.1 Gráficos de Pizza
O gráfico de Pizza é um gráfico que possui somente uma série de dados, portanto é
necessário informar somente uma linha com os dataFields (que representa o nome
correspondente a cada fatia da pizza) e uma outra linha com o dados desta série, além de
especificar o tipo de gráfico no atributo type da tabela.
<?xml version="1.0" encoding="iso-8859-1"?>
<TABLE name="Eleições 2004" type="pizzaChart" svgWidth="480"
svgHeight="360" >
<DESC>
Intenções de Voto - Prefeitura Florianópolis;; Fonte:
Instituto DATAFOLHA
</DESC>
40
<TR type="dataField" name="Candidatos">
<TD>Berger (PSDB)</TD>
<TD>Blasi (PMDB)</TD>
<TD>Passos (PT)</TD>
<TD>Capela (PFL)</TD>
<TD>Não Sabe</TD>
<TD>Não Opinou</TD>
</TR>
<TR type="data" name="Intenção">
<TD>24</TD>
<TD>23</TD>
<TD>10</TD>
<TD>6</TD>
<TD>14</TD>
<TD>23</TD>
</TR>
</TABLE>
Figura 17 – Exemplo de arquivo de entrada XML para Gráfico de Pizza
Caso seja informada mais de uma linha do tipo data, somente a última será
considerada; e caso não seja informada a linha dos dataFields será gerada uma seqüência
de valores para preencher a legenda.
7.1.2 Gráficos de Dispersão
No gráfico de dispersão de pontos o principal aspecto a ser observado na criação do
documento XML é o modo de informar os pares de coordenadas XY nas séries, que devem
ser colocados dentro de uma mesma tag <TD> separados por ‘,’. Neste tipo de gráfico é
irrelevante informar a linha de dataFields pois não apresenta significado neste contexto.
Neste tipo de gráfico podem ser informadas várias séries de dados que serão
identificadas na legenda através do atributo name de cada tag <TR>.
<?xml version='1.0' encoding='iso-8859-1'?>
41
<TABLE name="Vazão de Fluidos" type="scatterChart"
xAxisLabel="Tempo(min)" yAxisLabel="V" svgWidth="480" svgHeight="360">
<DESC>Resultados do Experimento de Vazão.;;UFSC - LMPT</DESC>
<TR type="data" name="1a Serie">
<TD>1,34</TD>
<TD>3,56</TD>
<TD>5,32</TD>
<TD>7,90</TD>
<TD>9,67</TD>
<TD>11,63</TD>
<TD>13,69</TD>
<TD>15,26</TD>
</TR>
<TR type="data" name="2a Serie">
<TD>2,56</TD>
<TD>4,43</TD>
<TD>6,48</TD>
<TD>8,40</TD>
<TD>10,37</TD>
<TD>12,59</TD>
<TD>14,31</TD>
<TD>16,49</TD>
</TR>
<TR type="data" name="3a Serie">
<TD>1,10</TD>
<TD>2,20</TD>
<TD>3,30</TD>
<TD>4,40</TD>
<TD>5,45</TD>
<TD>6,50</TD>
<TD>7,20</TD>
<TD>8,75</TD>
</TR>
</TABLE>
Figura 18 – Exemplo de arquivo de entrada XML para Gráfico de Dispersão
42
Caso não seja informado o atributo name em alguma tag <TR>, ele será assumido
como sendo o número seqüencial referente a posição da linha no documento.
7.1.3 Gráficos de Categorias
Gráficos de Categorias são os gráficos de linhas, barras, colunas e área. Estes
gráficos são os mais completos em termos de estrutura do documento de entrada XML.
Todos os atributos são importantes na geração e interpretação dos dados, onde a linha de
dataField representa as categorias e cada linha data representa uma série de valores para
cada categoria.
<?xml version="1.0" encoding="iso-8859-1"?>
<table name="Exemplo de Gráfico de Categoria"
type="groupedColumnChart" svgWidth="480" svgHeight="360" xAxisLabel="Eixo
X" yAxisLabel="Y">
<desc>Gráfico de Categorias;;SVGChart 2004</desc>
<tr type="dataField" name="Categorias">
<td>Cat 1</td>
<td>Cat 2</td>
<td>Cat 3</td>
<td>Cat 4</td>
<td>Cat 5</td>
<td>Cat 6</td>
</tr>
<tr type="data" name="Série 1">
<td>153</td>
<td>58</td>
<td>95</td>
<td>102</td>
<td>71</td>
<td>53</td>
</tr>
<tr type="data" name="Série 2">
<td>102</td>
<td>142</td>
43
<td>130</td>
<td>168</td>
<td>59</td>
<td>79</td>
</tr>
<tr type="data" name="Série 3">
<td>125</td>
<td>71</td>
<td>168</td>
<td>153</td>
<td>95</td>
<td>130</td>
</tr>
</table>
Figura 19 – Exemplo de arquivo de entrada XML para Gráfico de Colunas Agrupadas
O exemplo acima representa um gráfico de colunas, entretanto, basta alterar
somente o atributo type da tag <TABLE> para transformar este gráfico em qualquer outro
gráfico de categorias sem perda de informação.
Caso algum dos atributos não seja informado, será tomado o seu valor default
definido anteriormente.
7.2 Análise e Manipulação do Documento de Entrada XML
Como dito anteriormente, toda a análise e manipulação é executada pela classe
XMLHandler dentro dos métodos startElement(), characters() e endElement(). Esta
análise é feita com base no nome dos elementos e seus atributos do seguinte modo:
1. O XMLHandler inicia o processo de parsing e executa as inicializações;
2. Reconhece o elemento <TABLE> e efetua as seguintes operações:
a. Verifica o conteúdo do atributo type e solicita a classe
SVGChartDatasetFactory uma implementação da interface de
conjunto de dados
44
b. Armazena os valores dos demais atributos em variáveis ou como
atributos da classe de implementação do conjunto de dados
3. Reconhece o elemento <DESC> e coloca seu valor como um atributo da
classe de implementação que será utilizado na geração do subtítulo do
gráfico;
4. Inicia o reconhecimento dos elementos <TR> e <TD> organizando-os em
estruturas de dados e adicionando-os aos dados dentro das estruturas na
classe de implementação de conjunto de dados. Nesta etapa são feitos
também alguns controles do processo;
5. Após o reconhecimento de todos os elementos do documento, quando é
reconhecido que o elemento <TABLE> foi fechado, é feita a solicitação do
gráfico pela classe de conjunto de dados e é executada a transformação dos
objetos recebidos no documento SVG com o gráfico gerado.
Assim podemos realmente perceber que a classe XMLHandler é quem centraliza e
gerencia todo o processo de geração do gráfico.
7.3 Gráficos em SVG
Já foi visto anteriormente como especificar os documentos de entrada em XML nas
três classes de gráficos estatísticos implementadas. Entretanto, até agora ainda foi mostrado
o resultado de todo este processo, que são os gráficos estatísticos na sua forma visual,
portanto os gráficos referentes aos modelos de documento de entrada apresentados
anteriormente são os seguintes: (o código fonte de cada gráfico pode ser consultado nos
anexos)
45
7.3.1 Gráfico de Pizza
Figura 20 – Gráfico de Pizza gerado pela aplicação
7.3.2 Gráfico de Dispersão
Figura 21 – Gráfico de Dispersão gerado pela aplicação
46
7.3.3 Gráfico de Categorias
Gráfico de Colunas Agrupadas
Figura 22– Gráfico de Colunas Agrupadas gerado pela aplicação
Gráfico de Barras Agrupadas
Figura 23 – Gráfico de Barras Agrupadas gerado pela aplicação
47
Gráfico de Linhas
Figura 24 – Gráfico de Linhas gerado pela aplicação
Gráfico de Área
Figura 25 – Gráfico de Área gerado pela aplicação
48
8 Conclusão Ao concluir este projeto verificou-se que todos os objetivos definidos foram
alcançados, pois durante seu planejamento e execução foram bastante aprofundados os
conhecimentos específicos das tecnologias relacionadas com XML e exercitadas as
capacidades de planejamento e organização de estruturas de dados e de aplicação.
Um dos principais alvos deste projeto foi o estudo do SVG que foi altamente
praticado durante os primeiros meses, enquanto ainda estava decidindo-se como fazer e o
que utilizar no desenvolvimento do projeto. E este estudo rendeu, principalmente, a
compreensão do comportamento e do código dos gráficos vetoriais escaláveis.
Os conhecimentos na linguagem Java também puderam ser exercitados, quando
usou-se a API JAXP juntamente com o SAX e o DOM, rendendo um bom tempo de leitura
de tutoriais e especificações.
Neste projeto analisou-se algumas ferramentas de propósito semelhante, dentre elas
a The Graphics Connection, ferramentas da Adobe como o Adobe Illustrator, e da Corel
como o CorelDraw. Porém, todas essas ferramentas são proprietárias e usam o SVG como
um aspecto secundário, como uma alternativa na geração dos gráficos estatísticos ou outros
gráficos. Com relação a ferramentas de código aberto, não foi possível verificar a existência
de alguma com o propósito específico de geração de gráficos estatísticos em SVG, o que
torna este projeto, de certa forma, único.
Concluindo o projeto verificou-se que ele se tornou bastante funcional e
possivelmente de interesse dos outros membros da comunidade de software, a partir daí foi
solicitada sua aprovação em um dos mais famosos repositórios de projetos de software
livre, o SourceForge.net, acabando por ser aprovado pelos administradores e agora ele está
disponível para toda a comunidade como o Projeto SVGChart podendo ser acessado em
http://sourceforge.net/projects/svgchart .
49
9 Trabalhos Futuros Como sugestão para trabalhos futuros fica a implementação de mais tipos de
gráficos estatísticos, maior personalização dos gráficos, remodelagem da estrutura do
diagrama de classes dos conjuntos de dados, e também a criação de aplicações do tipo web
services fazendo uso da principal vantagem do projeto, que é a especificação dos dados
através de XML.
50
10 Referências Bibliográficas
[BM] MCLAUGHLIN, Brett. Java & XML – Solutions to Real-World Problems. 2. ed. EEUU: O’Reilly, Sept. 2001. 528 p.
[EMB] BURKE, Erik M. Java and XSLT. 1. ed. EEUU: O’Reilly, Sept. 2001. 528
p.
[JDE] EISENBERG, J. David. SVG Essentials. 1. ed. EEUU: Feb. O’Reilly,
2002. 364 p.
[DEI] DEITEL, H. M.; DEITEL, P. J. Java, como programar. Tradução Edson
Furnankiewicz. 3. ed. Porto Alegre: Bookman, 2001. 1201 p.
[SVG] WORLD WIDE WEB CONSORTIUM (W3C). Scalable Vector Graphics (SVG). Disponível em: <http://www.w3.org/Graphics/SVG/> Acessado em:
17 jan. 2004.
[XML] WORLD WIDE WEB CONSORTIUM (W3C). Extensible Markup Language (XML). Disponível em: <http://www.w3.org/XML/> Acessado
em: 17 jan. 2004.
[CSS] WORLD WIDE WEB CONSORTIUM (W3C). Cascading Style Sheets (CSS). Disponível em: <http://www.w3.org/Style/CSS/> Acessado em: 17
jan. 2004.
51
[SGML] WORLD WIDE WEB CONSORTIUM (W3C). Standard Generalized Markup Language (SGML). Disponível em:
<http://www.w3.org/MarkUp/SGML/> Acessado em: 17 jan. 2004.
[DTD] WORLD WIDE WEB CONSORTIUM (W3C). Extensible Markup Language (XML) 1.0 (Second Edition). Disponível em:
<http://www.w3.org/TR/REC-xml#sec-prolog-dtd>. Acessado em: 12 jan.
2004. cap. 2.8.
[DOM] WORLD WIDE WEB CONSORTIUM (W3C). W3C Document Object Model (DOM). Disponível em: <http://www.w3.org/DOM/>. Acessado em:
18 jan. 2004.
[JFC] WWW.JFREE.ORG. JFreeChart. Disponível em:
<http://www.jfree.org/jfreechart/>. Acessado em: 8 jan 2004.
[BTK] THE APACHE XML PROJECT. Batik SVG Toolkit. Disponível em:
<http://xml.apache.org/batik/>. Acessado em: 9 jan 2004.
[TOM] THE APACHE JAKARTA PROJECT. The Jakarta Site – Apache Tomcat. Disponível em: <http://jakarta.apache.org/tomcat/>. Acessado
em: 9 jan. 2004.
[ASZ] ADOBE. Adobe SVG Zone. Disponível em:
<http://www.adobe.com/svg/>. Acessado em: 15 jan. 2004.
52
[JAXP] SUN MICROSYSTEMS. Java API for XML Processing (JAXP). Disponível em: <http://java.sun.com/xml/jaxp/index.jsp>. Acessado em: 9
jan. 2004.
[JSE] SUN MICROSYSTEMS. JavaTM 2 Platform, Standard Edition, v 1.4.1 API Specification. Disponível em:
<http://java.sun.com/j2se/1.4.1/docs/api/>. Acessado em: 17 jan. 2004.
[JEE] SUN MICROSYSTEMS. JavaTM 2 Platform Enterprise Edition, v 1.4 API Specification. Disponível em:
<http://java.sun.com/j2ee/1.4/docs/api/index.html>. Acessado em: 17 jan.
2004.
[JST] SUN MICROSYSTEMS. Java Servlet Technology. Disponível em:
<http://java.sun.com/products/servlet/index.jsp>. Acessado em: 17 jan.
2004.
[JML] SUN MICROSYSTEMS. Java Technology and XML-Part One.
Disponível em:
<http://java.sun.com/developer/technicalArticles/xml/JavaTechandXML/>.
Acessado em: 21 jan. 2004.
[EA] ARMSTRONG, Erick. et al. The Java Web Services Tutorial. 23 jul 2003.
Disponível em:
<http://java.sun.com/webservices/docs/1.2/tutorial/doc/index.html>.
Acessado em: 23 jan. 2004.
53
[OJD] ORACLE. Oracle JDeveloper. Disponível em:
<http://otn.oracle.com/products/jdev/index.html>. Acessado em: 18 jan.
2004.
[TGC] SQUARE ONE. The Graphics Connection. Disponível em:
<http://www.square1.nl/TGC-SITE/index.htm>. Acessado em 24 jan. 2004.
54
11 Anexos
11.1 Código Fonte dos Gráficos Gerados
Código fonte do gráfico de pizza <?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 1.0//EN' 'http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd'> <svg xmlns:xlink="http://www.w3.org/1999/xlink" style="fill-opacity:1; color-rendering:auto; color-interpolation:auto; stroke:black; text-rendering:auto; stroke-linecap:square; stroke-miterlimit:10; shape-rendering:auto; stroke-opacity:1; fill:black; stroke-dasharray:none; font-weight:normal; stroke-width:1; font-family:'sansserif'; font-style:normal; stroke-linejoin:miter; font-size:12; stroke-dashoffset:0; image-rendering:auto;" xmlns="http://www.w3.org/2000/svg"> <!--Documento gerado por SVGChart - Henrique A. Viecili--> <defs id="genericDefs"/> <g> <defs id="defs1"> <clipPath clipPathUnits="userSpaceOnUse" id="clipPath1"> <path d="M0 0 L480 0 L480 360 L0 360 L0 0 Z"/> </clipPath> <clipPath clipPathUnits="userSpaceOnUse" id="clipPath2"> <path d="M5 76.6008 L5 355 L475 355 L475 76.6008 Z"/> </clipPath> </defs> <g style="fill:rgb(50,150,250); text-rendering:optimizeLegibility; stroke:rgb(50,150,250);"> <rect x="0" y="0" width="480" style="clip-path:url(#clipPath1); stroke:none;" height="360"/> </g> <g style="text-rendering:optimizeLegibility; font-size:18; font-weight:bold; font-family:sans-serif;"> <text x="180.9551" y="24.8889" style="clip-path:url(#clipPath1); stroke:none;" xml:space="preserve">Eleições 2004</text> <text x="115.6494" y="49.4215" style="font-size:12; clip-path:url(#clipPath1); stroke:none;" xml:space="preserve">Intenções de Voto - Prefeitura Florianópolis</text> <text x="155.6836" y="71.3074" style="font-size:12; clip-path:url(#clipPath1); stroke:none;" xml:space="preserve"> Fonte: Instituto DATAFOLHA</text> <rect x="5" y="76.6008" width="470" style="clip-path:url(#clipPath1); fill:white; stroke:none;" height="278.3992"/> <rect x="5" y="76.6008" width="470" style="clip-path:url(#clipPath1); fill:none; stroke:gray;" height="278.3992"/> <path d="M240 111.4007 C295.113 111.4007 340.7331 154.2408 344.1937 209.2451 L240 215.8004 Z" style="fill:red; clip-path:url(#clipPath2); stroke:none;"/> <path d="M240 111.4007 C295.113 111.4007 340.7331 154.2408 344.1937 209.2451 L240 215.8004 Z" style="fill:none; clip-path:url(#clipPath2); stroke:silver;"/> <text x="318.6132" y="132.0859" style="font-size:10; clip-path:url(#clipPath2); stroke:none; font-weight:normal;" xml:space="preserve"> Berger (PSDB) (24%)</text>
55
</g> <g style="fill:blue; text-rendering:optimizeLegibility; font-size:10; font-family:sans-serif; stroke:blue;"> <path d="M344.1937 209.2451 C347.4964 261.7404 311.23 308.4948 259. 626 318.3509 L240 215.8004 Z" style="clip-path:url(#clipPath2)5 ; stroke:none;"/> <path d="M344.1937 209.2451 C347.4964 261.7404 311.23 308.4948 259.5626 318.3509 L240 215.8004 Z" style="fill:none; clip-path:url(#clipPath2); stroke:silver;"/> <text x="330.7411" y="296.2401" style="clip-path:url(#clipPath2); fill:black; stroke:none;" xml:space="preserve"> Blasi (PMDB) (23%)</text> <path d="M259.5626 318.3509 C237.906 322.4821 215.4975 319.6512 195.5488 310.2641 L240 215.8004 Z" style="fill:lime; clip-path:url(#clipPath2); stroke:none;"/> <path d="M259.5626 318.3509 C237.906 322.4821 215.4975 319.6512 195.5488 310.2641 L240 215.8004 Z" style="fill:none; clip-path:url(#clipPath2); stroke:silver;"/> <text x="118.9173" y="339.7882" style="clip-path:url(#clipPath2); fill:black; stroke:none;" xml:space="preserve"> Passos (PT) (10%)</text> <path d="M195.5488 310.2641 C183.6428 304.6616 172.9033 296.8589 163.8959 287.2669 L240 215.8004 Z" style="fill:yellow; clip-path:url(#clipPath2); stroke:none;"/> <path d="M195.5488 310.2641 C183.6428 304.6616 172.9033 296.8589 163.8959 287.2669 L240 215.8004 Z" style="fill:none; clip-path:url(#clipPath2); stroke:silver;"/> <text x="66.913" y="318.7614" style="clip-path:url(#clipPath2); fill:black; stroke:none;" xml:space="preserve"> Capela (PFL) (6%)</text> <path d="M163.8959 287.2669 C142.5963 264.5852 132.5238 233.5851 136.4235 202.7156 L240 215.8004 Z" style="fill:rgb(255,200,0); clip-path:url(#clipPath2); stroke:none;"/> <path d="M163.8959 287.2669 C142.5963 264.5852 132.5238 233.5851 136.4235 202.7156 L240 215.8004 Z" style="fill:none; clip-path:url(#clipPath2); stroke:silver;"/> <text x="34.6237" y="261.3415" style="clip-path:url(#clipPath2); fill:black; stroke:none;" xml:space="preserve"> Não Sabe (14%)</text> <path d="M136.4235 202.7156 C143.0159 150.5312 187.4008 111.4007 240 111.4007 L240 215.8004 Z" style="fill:fuchsia; clip-path:url(#clipPath2); stroke:none;"/> <path d="M136.4235 202.7156 C143.0159 150.5312 187.4008 111.4007 240 111.4007 L240 215.8004 Z" style="fill:none; clip-path:url(#clipPath2); stroke:silver;"/> <text x="59.0063" y="129.6579" style="clip-path:url(#clipPath2); fill:black; stroke:none;" xml:space="preserve"> Não Opinou (23%)</text> <rect x="5" y="76.6008" width="470" style="clip-path:url(#clipPath2); fill:none; stroke:gray;" height="278.3992"/> </g> </g> </svg>
56
Código fonte do gráfico de dispersão <?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 1.0//EN' 'http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd'> <svg xmlns:xlink="http://www.w3.org/1999/xlink" style="fill-opacity:1; color-rendering:auto; color-interpolation:auto; stroke:black; text-rendering:auto; stroke-linecap:square; stroke-miterlimit:10; shape-rendering:auto; stroke-opacity:1; fill:black; stroke-dasharray:none; font-weight:normal; stroke-width:1; font-family:'sansserif'; font-style:normal; stroke-linejoin:miter; font-size:12; stroke-dashoffset:0; image-rendering:auto;" xmlns="http://www.w3.org/2000/svg"> <!--Documento gerado por SVGChart - Henrique A. Viecili--> <defs id="genericDefs"/> <g> <defs id="defs1"> <clipPath clipPathUnits="userSpaceOnUse" id="clipPath1"> <path d="M0 0 L480 0 L480 360 L0 360 L0 0 Z"/> </clipPath> <clipPath clipPathUnits="userSpaceOnUse" id="clipPath2"> <path d="M-418.2622 -193.4332 L61.7378 -193.4332 L61.7378 166.5668 L-418.2622 166.5668 L-418.2622 -193.4332 Z"/> </clipPath> <clipPath clipPathUnits="userSpaceOnUse" id="clipPath3"> <path d="M218.0113 180.9176 L218.0113 660.9176 L-141.9887 660.9176 L-141.9887 180.9176 L218.0113 180.9176 Z"/> </clipPath> <clipPath clipPathUnits="userSpaceOnUse" id="clipPath4"> <path d="M48.2168 80.6008 L48.2168 318.3281 L407.2622 318.3281 L407.2622 80.6008 Z"/> </clipPath> </defs> <g style="fill:rgb(50,150,250); text-rendering:optimizeLegibility; stroke:rgb(50,150,250);"> <rect x="0" y="0" width="480" style="clip-path:url(#clipPath1); stroke:none;" height="360"/> </g> <g style="text-rendering:optimizeLegibility; font-size:18; font-weight:bold; font-family:sans-serif;"> <text x="166.4883" y="24.8889" style="clip-path:url(#clipPath1); stroke:none;" xml:space="preserve">Vazão de Fluidos</text> <text x="131.3086" y="49.4215" style="font-size:12; clip-path:url(#clipPath1); stroke:none;" xml:space="preserve">Resultados do Experimento de Vazão.</text> <text x="202.0049" y="71.3074" style="font-size:12; clip-path:url(#clipPath1); stroke:none;" xml:space="preserve">UFSC - LMPT</text> </g> <g transform="translate(418.2622,193.4332)" style="font-size:10; fill:white; text-rendering:optimizeLegibility; font-family:sans-serif; stroke:white;"> <rect x="0" y="0" width="58.7378" style="clip-path:url(#clipPath2); stroke:none;" height="49.7344"/> <rect x="0" y="0" width="58.7378" style="clip-path:url(#clipPath2); fill:none; stroke:gray;" height="49.7344"/>
57
<path d="M5.2891 5.2891 L11.2891 5.2891 L11.2891 11.2891 L5.2891 11.2891 L5.2891 5.2891 Z" style="fill:red; clip-path:url(#clipPath2); stroke:none;"/> <text x="16" y="12" style="clip-path:url(#clipPath2); fill:black; stroke:none;" xml:space="preserve">1a Serie</text> <path d="M11.2891 24.8672 C11.2891 26.524 9.9459 27.8672 8.2891 27.8672 C6.6322 27.8672 5.2891 26.524 5.2891 24.8672 C5.2891 23.2103 6.6322 21.8672 8.2891 21.8672 C9.9459 21.8672 11.2891 23.2103 11.2891 24.8672 Z" style="fill:blue; clip-path:url(#clipPath2); stroke:none;"/> <text x="16" y="28" style="clip-path:url(#clipPath2); fill:black; stroke:none;" xml:space="preserve">2a Serie</text> <path style="fill:lime; clip-path:url(#clipPath2); fill-rule:evenodd; stroke:none;" d="M8.2891 38.4453 L11.2891 44.4453 L5.2891 44.4453 Z"/> <text x="16" y="45" style="clip-path:url(#clipPath2); fill:black; stroke:none;" xml:space="preserve">3a Serie</text> <rect x="48.2168" y="80.6008" transform="translate(-418.2622,-193.4332)" width="359.0454" style="clip-path:url(#clipPath1); stroke:none;" height="237.7273"/> <line transform="translate(-418.2622,-193.4332)" x1="48.2168" x2="407.2622" y1="318.3281" style="clip-path:url(#clipPath1); fill:none; stroke:gray;" y2="318.3281"/> <text x="61.7563" y="332.3818" transform="translate(-418.2622,-193.4332)" style="clip-path:url(#clipPath1); fill:black; stroke:none;" xml:space="preserve">1</text> </g> <g style="fill:gray; text-rendering:optimizeLegibility; font-size:10; font-family:sans-serif; stroke:gray;"> <line x1="64.537" x2="64.537" y1="320.3281" style="clip-path:url(#clipPath1); fill:none;" y2="318.3281"/> <text x="83.5166" y="332.3818" style="clip-path:url(#clipPath1); fill:black; stroke:none;" xml:space="preserve">2</text> </g> <g style="fill:gray; text-rendering:optimizeLegibility; font-size:10; font-family:sans-serif; stroke:gray;"> <line x1="86.2974" x2="86.2974" y1="320.3281" style="clip-path:url(#clipPath1); fill:none;" y2="318.3281"/> <text x="105.2769" y="332.3818" style="clip-path:url(#clipPath1); fill:black; stroke:none;" xml:space="preserve">3</text> </g> <g style="fill:gray; text-rendering:optimizeLegibility; font-size:10; font-family:sans-serif; stroke:gray;"> <line x1="108.0577" x2="108.0577" y1="320.3281" style="clip-path:url(#clipPath1); fill:none;" y2="318.3281"/> <text x="127.0373" y="332.3818" style="clip-path:url(#clipPath1); fill:black; stroke:none;" xml:space="preserve">4</text> </g> <g style="fill:gray; text-rendering:optimizeLegibility; font-size:10; font-family:sans-serif; stroke:gray;"> <line x1="129.818" x2="129.818" y1="320.3281" style="clip-path:url(#clipPath1); fill:none;" y2="318.3281"/> <text x="148.7976" y="332.3818" style="clip-path:url(#clipPath1); fill:black; stroke:none;" xml:space="preserve">5</text> </g> <g style="fill:gray; text-rendering:optimizeLegibility; font-size:10; font-family:sans-serif; stroke:gray;">
58
<line x1="151.5784" x2="151.5784" y1="320.3281" style="clip-path:url(#clipPath1); fill:none;" y2="318.3281"/> <text x="170.5579" y="332.3818" style="clip-path:url(#clipPath1); fill:black; stroke:none;" xml:space="preserve">6</text> </g> <g style="fill:gray; text-rendering:optimizeLegibility; font-size:10; font-family:sans-serif; stroke:gray;"> <line x1="173.3387" x2="173.3387" y1="320.3281" style="clip-path:url(#clipPath1); fill:none;" y2="318.3281"/> <text x="192.3183" y="332.3818" style="clip-path:url(#clipPath1); fill:black; stroke:none;" xml:space="preserve">7</text> </g> <g style="fill:gray; text-rendering:optimizeLegibility; font-size:10; font-family:sans-serif; stroke:gray;"> <line x1="195.099" x2="195.099" y1="320.3281" style="clip-path:url(#clipPath1); fill:none;" y2="318.3281"/> <text x="214.0786" y="332.3818" style="clip-path:url(#clipPath1); fill:black; stroke:none;" xml:space="preserve">8</text> </g> <g style="fill:gray; text-rendering:optimizeLegibility; font-size:10; font-family:sans-serif; stroke:gray;"> <line x1="216.8593" x2="216.8593" y1="320.3281" style="clip-path:url(#clipPath1); fill:none;" y2="318.3281"/> <text x="235.8389" y="332.3818" style="clip-path:url(#clipPath1); fill:black; stroke:none;" xml:space="preserve">9</text> </g> <g style="fill:gray; text-rendering:optimizeLegibility; font-size:10; font-family:sans-serif; stroke:gray;"> <line x1="238.6197" x2="238.6197" y1="320.3281" style="clip-path:url(#clipPath1); fill:none;" y2="318.3281"/> <text x="254.8185" y="332.3818" style="clip-path:url(#clipPath1); fill:black; stroke:none;" xml:space="preserve">10</text> </g> <g style="fill:gray; text-rendering:optimizeLegibility; font-size:10; font-family:sans-serif; stroke:gray;"> <line x1="260.38" x2="260.38" y1="320.3281" style="clip-path:url(#clipPath1); fill:none;" y2="318.3281"/> <text x="276.5788" y="332.3818" style="clip-path:url(#clipPath1); fill:black; stroke:none;" xml:space="preserve">11</text> </g> <g style="fill:gray; text-rendering:optimizeLegibility; font-size:10; font-family:sans-serif; stroke:gray;"> <line x1="282.1403" x2="282.1403" y1="320.3281" style="clip-path:url(#clipPath1); fill:none;" y2="318.3281"/> <text x="298.3391" y="332.3818" style="clip-path:url(#clipPath1); fill:black; stroke:none;" xml:space="preserve">12</text> </g> <g style="fill:gray; text-rendering:optimizeLegibility; font-size:10; font-family:sans-serif; stroke:gray;"> <line x1="303.9006" x2="303.9006" y1="320.3281" style="clip-path:url(#clipPath1); fill:none;" y2="318.3281"/> <text x="320.0995" y="332.3818" style="clip-path:url(#clipPath1); fill:black; stroke:none;" xml:space="preserve">13</text> </g> <g style="fill:gray; text-rendering:optimizeLegibility; font-size:10; font-family:sans-serif; stroke:gray;">
59
<line x1="325.661" x2="325.661" y1="320.3281" style="clip-path:url(#clipPath1); fill:none;" y2="318.3281"/> <text x="341.8598" y="332.3818" style="clip-path:url(#clipPath1); fill:black; stroke:none;" xml:space="preserve">14</text> </g> <g style="fill:gray; text-rendering:optimizeLegibility; font-size:10; font-family:sans-serif; stroke:gray;"> <line x1="347.4213" x2="347.4213" y1="320.3281" style="clip-path:url(#clipPath1); fill:none;" y2="318.3281"/> <text x="363.6201" y="332.3818" style="clip-path:url(#clipPath1); fill:black; stroke:none;" xml:space="preserve">15</text> </g> <g style="fill:gray; text-rendering:optimizeLegibility; font-size:10; font-family:sans-serif; stroke:gray;"> <line x1="369.1816" x2="369.1816" y1="320.3281" style="clip-path:url(#clipPath1); fill:none;" y2="318.3281"/> <text x="385.3804" y="332.3818" style="clip-path:url(#clipPath1); fill:black; stroke:none;" xml:space="preserve">16</text> </g> <g style="fill:gray; text-rendering:optimizeLegibility; font-size:10; font-family:sans-serif; stroke:gray;"> <line x1="390.942" x2="390.942" y1="320.3281" style="clip-path:url(#clipPath1); fill:none;" y2="318.3281"/> <text x="195.4016" y="349.9707" style="font-size:12; clip-path:url(#clipPath1); fill:black; stroke:none;" xml:space="preserve">Tempo(min)</text> </g> <g style="fill:gray; text-rendering:optimizeLegibility; font-family:sans-serif; stroke:gray;"> <line x1="48.2168" x2="48.2168" y1="80.6008" style="clip-path:url(#clipPath1); fill:none;" y2="318.3281"/> <text x="31.0938" y="311.287" style="font-size:10; clip-path:url(#clipPath1); fill:black; stroke:none;" xml:space="preserve">10</text> </g> <g style="fill:gray; text-rendering:optimizeLegibility; font-size:10; font-family:sans-serif; stroke:gray;"> <line x1="46.2168" x2="48.2168" y1="307.5223" style="clip-path:url(#clipPath1); fill:none;" y2="307.5223"/> <text x="31.0938" y="284.2725" style="clip-path:url(#clipPath1); fill:black; stroke:none;" xml:space="preserve">20</text> </g> <g style="fill:gray; text-rendering:optimizeLegibility; font-size:10; font-family:sans-serif; stroke:gray;"> <line x1="46.2168" x2="48.2168" y1="280.5079" style="clip-path:url(#clipPath1); fill:none;" y2="280.5079"/> <text x="31.0938" y="257.2581" style="clip-path:url(#clipPath1); fill:black; stroke:none;" xml:space="preserve">30</text> </g> <g style="fill:gray; text-rendering:optimizeLegibility; font-size:10; font-family:sans-serif; stroke:gray;"> <line x1="46.2168" x2="48.2168" y1="253.4934" style="clip-path:url(#clipPath1); fill:none;" y2="253.4934"/> <text x="31.0938" y="230.2436" style="clip-path:url(#clipPath1); fill:black; stroke:none;" xml:space="preserve">40</text> </g>
60
<g style="fill:gray; text-rendering:optimizeLegibility; font-size:10; font-family:sans-serif; stroke:gray;"> <line x1="46.2168" x2="48.2168" y1="226.4789" style="clip-path:url(#clipPath1); fill:none;" y2="226.4789"/> <text x="31.0938" y="203.2291" style="clip-path:url(#clipPath1); fill:black; stroke:none;" xml:space="preserve">50</text> </g> <g style="fill:gray; text-rendering:optimizeLegibility; font-size:10; font-family:sans-serif; stroke:gray;"> <line x1="46.2168" x2="48.2168" y1="199.4644" style="clip-path:url(#clipPath1); fill:none;" y2="199.4644"/> <text x="31.0938" y="176.2146" style="clip-path:url(#clipPath1); fill:black; stroke:none;" xml:space="preserve">60</text> </g> <g style="fill:gray; text-rendering:optimizeLegibility; font-size:10; font-family:sans-serif; stroke:gray;"> <line x1="46.2168" x2="48.2168" y1="172.45" style="clip-path:url(#clipPath1); fill:none;" y2="172.45"/> <text x="31.0938" y="149.2002" style="clip-path:url(#clipPath1); fill:black; stroke:none;" xml:space="preserve">70</text> </g> <g style="fill:gray; text-rendering:optimizeLegibility; font-size:10; font-family:sans-serif; stroke:gray;"> <line x1="46.2168" x2="48.2168" y1="145.4355" style="clip-path:url(#clipPath1); fill:none;" y2="145.4355"/> <text x="31.0938" y="122.1857" style="clip-path:url(#clipPath1); fill:black; stroke:none;" xml:space="preserve">80</text> </g> <g style="fill:gray; text-rendering:optimizeLegibility; font-size:10; font-family:sans-serif; stroke:gray;"> <line x1="46.2168" x2="48.2168" y1="118.421" style="clip-path:url(#clipPath1); fill:none;" y2="118.421"/> <text x="31.0938" y="95.1712" style="clip-path:url(#clipPath1); fill:black; stroke:none;" xml:space="preserve">90</text> </g> <g style="fill:gray; text-rendering:optimizeLegibility; font-size:10; font-family:sans-serif; stroke:gray;"> <line x1="46.2168" x2="48.2168" y1="91.4066" style="clip-path:url(#clipPath1); fill:none;" y2="91.4066"/> <text x="14.5449" y="203.982" transform="matrix(0,-1,1,0,-180.9176,218.0113)" style="font-size:12; clip-path:url(#clipPath3); fill:black; stroke:none;" xml:space="preserve">V</text> </g> <g style="stroke-linecap:butt; fill:silver; text-rendering:optimizeLegibility; stroke-linejoin:bevel; font-family:sans-serif; stroke-dasharray:2,2; stroke:silver; stroke-width:0.5; stroke-miterlimit:0;"> <line x1="64.537" x2="64.537" y1="80.6008" style="clip-path:url(#clipPath4); fill:none;" y2="318.3281"/> <line x1="86.2974" x2="86.2974" y1="80.6008" style="clip-path:url(#clipPath4); fill:none;" y2="318.3281"/> <line x1="108.0577" x2="108.0577" y1="80.6008" style="clip-path:url(#clipPath4); fill:none;" y2="318.3281"/> <line x1="129.818" x2="129.818" y1="80.6008" style="clip-path:url(#clipPath4); fill:none;" y2="318.3281"/> <line x1="151.5784" x2="151.5784" y1="80.6008" style="clip-path:url(#clipPath4); fill:none;" y2="318.3281"/>
61
<line x1="173.3387" x2="173.3387" y1="80.6008" style="clip-path:url(#clipPath4); fill:none;" y2="318.3281"/> <line x1="195.099" x2="195.099" y1="80.6008" style="clip-path:url(#clipPath4); fill:none;" y2="318.3281"/> <line x1="216.8593" x2="216.8593" y1="80.6008" style="clip-path:url(#clipPath4); fill:none;" y2="318.3281"/> <line x1="238.6197" x2="238.6197" y1="80.6008" style="clip-path:url(#clipPath4); fill:none;" y2="318.3281"/> <line x1="260.38" x2="260.38" y1="80.6008" style="clip-path:url(#clipPath4); fill:none;" y2="318.3281"/> <line x1="282.1403" x2="282.1403" y1="80.6008" style="clip-path:url(#clipPath4); fill:none;" y2="318.3281"/> <line x1="303.9006" x2="303.9006" y1="80.6008" style="clip-path:url(#clipPath4); fill:none;" y2="318.3281"/> <line x1="325.661" x2="325.661" y1="80.6008" style="clip-path:url(#clipPath4); fill:none;" y2="318.3281"/> <line x1="347.4213" x2="347.4213" y1="80.6008" style="clip-path:url(#clipPath4); fill:none;" y2="318.3281"/> <line x1="369.1816" x2="369.1816" y1="80.6008" style="clip-path:url(#clipPath4); fill:none;" y2="318.3281"/> <line x1="390.942" x2="390.942" y1="80.6008" style="clip-path:url(#clipPath4); fill:none;" y2="318.3281"/> <line x1="48.2168" x2="407.2622" y1="307.5223" style="clip-path:url(#clipPath4); fill:none;" y2="307.5223"/> <line x1="48.2168" x2="407.2622" y1="280.5079" style="clip-path:url(#clipPath4); fill:none;" y2="280.5079"/> <line x1="48.2168" x2="407.2622" y1="253.4934" style="clip-path:url(#clipPath4); fill:none;" y2="253.4934"/> <line x1="48.2168" x2="407.2622" y1="226.4789" style="clip-path:url(#clipPath4); fill:none;" y2="226.4789"/> <line x1="48.2168" x2="407.2622" y1="199.4645" style="clip-path:url(#clipPath4); fill:none;" y2="199.4645"/> <line x1="48.2168" x2="407.2622" y1="172.45" style="clip-path:url(#clipPath4); fill:none;" y2="172.45"/> <line x1="48.2168" x2="407.2622" y1="145.4355" style="clip-path:url(#clipPath4); fill:none;" y2="145.4355"/> <line x1="48.2168" x2="407.2622" y1="118.421" style="clip-path:url(#clipPath4); fill:none;" y2="118.421"/> <line x1="48.2168" x2="407.2622" y1="91.4066" style="clip-path:url(#clipPath4); fill:none;" y2="91.4066"/> </g> <g style="fill:red; text-rendering:optimizeLegibility; font-family:sans-serif; stroke-linejoin:bevel; stroke:red;"> <path d="M61.537 239.6876 L67.537 239.6876 L67.537 245.6876 L61.537 245.6876 L61.537 239.6876 Z" style="clip-path:url(#clipPath4); stroke:none;"/> <path d="M105.0577 180.2558 L111.0577 180.2558 L111.0577 186.2558 L105.0577 186.2558 L105.0577 180.2558 Z" style="clip-path:url(#clipPath4); stroke:none;"/> <path d="M148.5784 245.0905 L154.5784 245.0905 L154.5784 251.0905 L148.5784 251.0905 L148.5784 245.0905 Z" style="clip-path:url(#clipPath4); stroke:none;"/> <path d="M192.099 88.4066 L198.099 88.4066 L198.099 94.4066 L192.099 94.4066 L192.099 88.4066 Z" style="clip-path:url(#clipPath4); stroke:none;"/>
62
<path d="M235.6197 150.5399 L241.6197 150.5399 L241.6197 156.5399 L235.6197 156.5399 L235.6197 150.5399 Z" style="clip-path:url(#clipPath4); stroke:none;"/> <path d="M279.1403 161.3456 L285.1403 161.3456 L285.1403 167.3456 L279.1403 167.3456 L279.1403 161.3456 Z" style="clip-path:url(#clipPath4); stroke:none;"/> <path d="M322.661 145.137 L328.661 145.137 L328.661 151.137 L322.661 151.137 L322.661 145.137 Z" style="clip-path:url(#clipPath4); stroke:none;"/> <path d="M366.1816 261.2992 L372.1816 261.2992 L372.1816 267.2992 L366.1816 267.2992 L366.1816 261.2992 Z" style="clip-path:url(#clipPath4); stroke:none;"/> <path d="M89.2974 183.2558 C89.2974 184.9126 87.9542 186.2558 86.2974 186.2558 C84.6405 186.2558 83.2974 184.9126 83.2974 183.2558 C83.2974 181.5989 84.6405 180.2558 86.2974 180.2558 C87.9542 180.2558 89.2974 181.5989 89.2974 183.2558 Z" style="fill:blue; clip-path:url(#clipPath4); stroke:none;"/> <path d="M132.818 218.3746 C132.818 220.0314 131.4749 221.3746 129.818 221.3746 C128.1612 221.3746 126.818 220.0314 126.818 218.3746 C126.818 216.7177 128.1612 215.3746 129.818 215.3746 C131.4749 215.3746 132.818 216.7177 132.818 218.3746 Z" style="fill:blue; clip-path:url(#clipPath4); stroke:none;"/> <path d="M176.3387 204.8673 C176.3387 206.5242 174.9955 207.8673 173.3387 207.8673 C171.6818 207.8673 170.3387 206.5242 170.3387 204.8673 C170.3387 203.2105 171.6818 201.8673 173.3387 201.8673 C174.9955 201.8673 176.3387 203.2105 176.3387 204.8673 Z" style="fill:blue; clip-path:url(#clipPath4); stroke:none;"/> <path d="M219.8593 226.4789 C219.8593 228.1358 218.5162 229.4789 216.8593 229.4789 C215.2025 229.4789 213.8593 228.1358 213.8593 226.4789 C213.8593 224.8221 215.2025 223.4789 216.8593 223.4789 C218.5162 223.4789 219.8593 224.8221 219.8593 226.4789 Z" style="fill:blue; clip-path:url(#clipPath4); stroke:none;"/> <path d="M263.38 234.5833 C263.38 236.2401 262.0368 237.5833 260.38 237.5833 C258.7231 237.5833 257.38 236.2401 257.38 234.5833 C257.38 232.9264 258.7231 231.5833 260.38 231.5833 C262.0368 231.5833 263.38 232.9264 263.38 234.5833 Z" style="fill:blue; clip-path:url(#clipPath4); stroke:none;"/> <path d="M306.9006 175.1514 C306.9006 176.8083 305.5575 178.1514 303.9006 178.1514 C302.2438 178.1514 300.9006 176.8083 300.9006 175.1514 C300.9006 173.4946 302.2438 172.1514 303.9006 172.1514 C305.5575 172.1514 306.9006 173.4946 306.9006 175.1514 Z" style="fill:blue; clip-path:url(#clipPath4); stroke:none;"/> <path d="M350.4213 250.7919 C350.4213 252.4488 349.0782 253.7919 347.4213 253.7919 C345.7645 253.7919 344.4213 252.4488 344.4213 250.7919 C344.4213 249.1351 345.7645 247.7919 347.4213 247.7919 C349.0782 247.7919 350.4213 249.1351 350.4213 250.7919 Z" style="fill:blue; clip-path:url(#clipPath4); stroke:none;"/> <path d="M393.942 202.1659 C393.942 203.8228 392.5988 205.1659 390.942 205.1659 C389.2851 205.1659 387.942 203.8228 387.942 202.1659 C387.942 200.509 389.2851 199.1659 390.942 199.1659 C392.5988 199.1659 393.942 200.509 393.942 202.1659 Z" style="fill:blue; clip-path:url(#clipPath4); stroke:none;"/> <path style="fill:lime; clip-path:url(#clipPath4); fill-rule:evenodd; stroke:none;" d="M64.537 304.5223 L67.537 310.5223 L61.537 310.5223 Z"/>
63
<path style="fill:lime; clip-path:url(#clipPath4); fill-rule:evenodd; stroke:none;" d="M86.2974 277.5079 L89.2974 283.5079 L83.2974 283.5079 Z"/> <path style="fill:lime; clip-path:url(#clipPath4); fill-rule:evenodd; stroke:none;" d="M108.0577 250.4934 L111.0577 256.4934 L105.0577 256.4934 Z"/> <path style="fill:lime; clip-path:url(#clipPath4); fill-rule:evenodd; stroke:none;" d="M129.818 223.4789 L132.818 229.4789 L126.818 229.4789 Z"/> <path style="fill:lime; clip-path:url(#clipPath4); fill-rule:evenodd; stroke:none;" d="M151.5784 209.9717 L154.5784 215.9717 L148.5784 215.9717 Z"/> <path style="fill:lime; clip-path:url(#clipPath4); fill-rule:evenodd; stroke:none;" d="M173.3387 196.4644 L176.3387 202.4644 L170.3387 202.4644 Z"/> <path style="fill:lime; clip-path:url(#clipPath4); fill-rule:evenodd; stroke:none;" d="M195.099 277.5079 L198.099 283.5079 L192.099 283.5079 Z"/> <path style="fill:lime; clip-path:url(#clipPath4); fill-rule:evenodd; stroke:none;" d="M216.8593 128.9283 L219.8593 134.9283 L213.8593 134.9283 Z"/> <rect x="48.2168" y="80.6008" width="359.0454" style="clip-path:url(#clipPath1); fill:none; stroke-linejoin:miter; stroke:gray;" height="237.7273"/> </g> </g> </svg>
Código fonte do gráfico de colunas agrupadas <?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 1.0//EN' 'http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd'> <svg xmlns:xlink="http://www.w3.org/1999/xlink" style="fill-opacity:1; color-rendering:auto; color-interpolation:auto; stroke:black; text-rendering:auto; stroke-linecap:square; stroke-miterlimit:10; shape-rendering:auto; stroke-opacity:1; fill:black; stroke-dasharray:none; font-weight:normal; stroke-width:1; font-family:'sansserif'; font-style:normal; stroke-linejoin:miter; font-size:12; stroke-dashoffset:0; image-rendering:auto;" xmlns="http://www.w3.org/2000/svg"> <!--Documento gerado por SVGChart - Henrique A. Viecili--> <defs id="genericDefs"/> <g> <defs id="defs1"> <clipPath clipPathUnits="userSpaceOnUse" id="clipPath1"> <path d="M0 0 L480 0 L480 360 L0 360 L0 0 Z"/> </clipPath> <clipPath clipPathUnits="userSpaceOnUse" id="clipPath2"> <path d="M-423.8237 -193.4332 L56.1763 -193.4332 L56.1763 166.5668 L-423.8237 166.5668 L-423.8237 -193.4332 Z"/> </clipPath> <clipPath clipPathUnits="userSpaceOnUse" id="clipPath3"> <path d="M215.8004 178.7066 L215.8004 658.7067 L-144.1996 658.7067 L-144.1996 178.7066 L215.8004 178.7066 Z"/> </clipPath> <clipPath clipPathUnits="userSpaceOnUse" id="clipPath4">
64
<path d="M53.7783 80.6008 L53.7783 313.9062 L412.8237 313.9062 L412.8237 80.6008 Z"/> </clipPath> </defs> <g style="fill:rgb(50,150,250); text-rendering:optimizeLegibility; stroke:rgb(50,150,250);"> <rect x="0" y="0" width="480" style="clip-path:url(#clipPath1); stroke:none;" height="360"/> </g> <g style="text-rendering:optimizeLegibility; font-size:18; font-weight:bold; font-family:sans-serif;"> <text x="104.4683" y="24.8889" style="clip-path:url(#clipPath1); stroke:none;" xml:space="preserve">Exemplo de Gráfico de Colunas</text> <text x="177.6475" y="49.4215" style="font-size:12; clip-path:url(#clipPath1); stroke:none;" xml:space="preserve">Gráfico de Categorias</text> <text x="196.6465" y="71.3074" style="font-size:12; clip-path:url(#clipPath1); stroke:none;" xml:space="preserve">SVGChart 2004</text> </g> <g transform="translate(423.8237,193.4332)" style="font-size:10; fill:white; text-rendering:optimizeLegibility; font-family:sans-serif; stroke:white;"> <rect x="0" y="0" width="53.1763" style="clip-path:url(#clipPath2); stroke:none;" height="49.7344"/> <rect x="0" y="0" width="53.1763" style="clip-path:url(#clipPath2); fill:none; stroke:gray;" height="49.7344"/> <rect x="3.8867" y="3.8867" width="8.8047" style="clip-path:url(#clipPath2); fill:red; stroke:none;" height="8.8047"/> <text x="16" y="12" style="clip-path:url(#clipPath2); fill:black; stroke:none;" xml:space="preserve">Série 1</text> <rect x="3.8867" y="20.4648" width="8.8047" style="clip-path:url(#clipPath2); fill:blue; stroke:none;" height="8.8047"/> <text x="16" y="28" style="clip-path:url(#clipPath2); fill:black; stroke:none;" xml:space="preserve">Série 2</text> <rect x="3.8867" y="37.043" width="8.8047" style="clip-path:url(#clipPath2); fill:lime; stroke:none;" height="8.8047"/> <text x="16" y="45" style="clip-path:url(#clipPath2); fill:black; stroke:none;" xml:space="preserve">Série 3</text> <rect x="53.7783" y="80.6008" transform="translate(-423.8237,-193.4332)" width="359.0454" style="clip-path:url(#clipPath1); stroke:none;" height="233.3055"/> <line transform="translate(-423.8237,-193.4332)" x1="53.7783" x2="412.8237" y1="313.9062" style="clip-path:url(#clipPath1); fill:none; stroke:gray;" y2="313.9062"/> <text x="77.6749" y="327.96" transform="translate(-423.8237,-193.4332)" style="clip-path:url(#clipPath1); fill:black; stroke:none;" xml:space="preserve"> Cat 1</text> </g> <g style="text-rendering:optimizeLegibility; font-size:10; font-family:sans-serif;"> <text x="130.9254" y="327.96" style="clip-path:url(#clipPath1); stroke:none;" xml:space="preserve"> Cat 2</text> </g> <g style="text-rendering:optimizeLegibility; font-size:10; font-family:sans-serif;">
65
<text x="187.1758" y="327.96" style="clip-path:url(#clipPath1); stroke:none;" xml:space="preserve"> Cat 3</text> </g> <g style="text-rendering:optimizeLegibility; font-size:10; font-family:sans-serif;"> <text x="243.4262" y="327.96" style="clip-path:url(#clipPath1); stroke:none;" xml:space="preserve"> Cat 4</text> </g> <g style="text-rendering:optimizeLegibility; font-size:10; font-family:sans-serif;"> <text x="299.6767" y="327.96" style="clip-path:url(#clipPath1); stroke:none;" xml:space="preserve"> Cat 5</text> </g> <g style="text-rendering:optimizeLegibility; font-size:10; font-family:sans-serif;"> <text x="355.9272" y="327.96" style="clip-path:url(#clipPath1); stroke:none;" xml:space="preserve"> Cat 6</text> </g> <g style="font-family:sans-serif; text-rendering:optimizeLegibility;"> <text x="215.9602" y="349.9707" style="clip-path:url(#clipPath1); stroke:none;" xml:space="preserve">Eixo X</text> </g> <g style="fill:gray; text-rendering:optimizeLegibility; font-family:sans-serif; stroke:gray;"> <line x1="53.7783" x2="53.7783" y1="80.6008" style="clip-path:url(#clipPath1); fill:none;" y2="313.9062"/> <text x="42.2168" y="317.6709" style="font-size:10; clip-path:url(#clipPath1); fill:black; stroke:none;" xml:space="preserve">0</text> </g> <g style="fill:gray; text-rendering:optimizeLegibility; font-size:10; font-family:sans-serif; stroke:gray;"> <line x1="51.7783" x2="53.7783" y1="313.9062" style="clip-path:url(#clipPath1); fill:none;" y2="313.9062"/> <text x="36.6553" y="284.6061" style="clip-path:url(#clipPath1); fill:black; stroke:none;" xml:space="preserve">25</text> </g> <g style="fill:gray; text-rendering:optimizeLegibility; font-size:10; font-family:sans-serif; stroke:gray;"> <line x1="51.7783" x2="53.7783" y1="280.8414" style="clip-path:url(#clipPath1); fill:none;" y2="280.8414"/> <text x="36.6553" y="251.5412" style="clip-path:url(#clipPath1); fill:black; stroke:none;" xml:space="preserve">50</text> </g> <g style="fill:gray; text-rendering:optimizeLegibility; font-size:10; font-family:sans-serif; stroke:gray;"> <line x1="51.7783" x2="53.7783" y1="247.7766" style="clip-path:url(#clipPath1); fill:none;" y2="247.7766"/> <text x="36.6553" y="218.4764" style="clip-path:url(#clipPath1); fill:black; stroke:none;" xml:space="preserve">75</text> </g> <g style="fill:gray; text-rendering:optimizeLegibility; font-size:10; font-family:sans-serif; stroke:gray;"> <line x1="51.7783" x2="53.7783" y1="214.7117" style="clip-path:url(#clipPath1); fill:none;" y2="214.7117"/>
66
<text x="31.0938" y="185.4116" style="clip-path:url(#clipPath1); fill:black; stroke:none;" xml:space="preserve">100</text> </g> <g style="fill:gray; text-rendering:optimizeLegibility; font-size:10; font-family:sans-serif; stroke:gray;"> <line x1="51.7783" x2="53.7783" y1="181.6469" style="clip-path:url(#clipPath1); fill:none;" y2="181.6469"/> <text x="31.0938" y="152.3467" style="clip-path:url(#clipPath1); fill:black; stroke:none;" xml:space="preserve">125</text> </g> <g style="fill:gray; text-rendering:optimizeLegibility; font-size:10; font-family:sans-serif; stroke:gray;"> <line x1="51.7783" x2="53.7783" y1="148.5821" style="clip-path:url(#clipPath1); fill:none;" y2="148.5821"/> <text x="31.0938" y="119.2819" style="clip-path:url(#clipPath1); fill:black; stroke:none;" xml:space="preserve">150</text> </g> <g style="fill:gray; text-rendering:optimizeLegibility; font-size:10; font-family:sans-serif; stroke:gray;"> <line x1="51.7783" x2="53.7783" y1="115.5172" style="clip-path:url(#clipPath1); fill:none;" y2="115.5172"/> <text x="31.0938" y="86.2171" style="clip-path:url(#clipPath1); fill:black; stroke:none;" xml:space="preserve">175</text> </g> <g style="fill:gray; text-rendering:optimizeLegibility; font-size:10; font-family:sans-serif; stroke:gray;"> <line x1="51.7783" x2="53.7783" y1="82.4524" style="clip-path:url(#clipPath1); fill:none;" y2="82.4524"/> <text x="14.5449" y="201.7711" transform="matrix(0,-1,1,0,-178.7066,215.8004)" style="font-size:12; clip-path:url(#clipPath3); fill:black; stroke:none;" xml:space="preserve">Y</text> </g> <g style="stroke-linecap:butt; fill:silver; text-rendering:optimizeLegibility; stroke-linejoin:bevel; font-family:sans-serif; stroke-dasharray:2,2; stroke:silver; stroke-width:0.5; stroke-miterlimit:0;"> <line x1="53.7783" x2="412.8237" y1="313.9062" style="clip-path:url(#clipPath1); fill:none;" y2="313.9062"/> <line x1="53.7783" x2="412.8237" y1="280.8414" style="clip-path:url(#clipPath1); fill:none;" y2="280.8414"/> <line x1="53.7783" x2="412.8237" y1="247.7766" style="clip-path:url(#clipPath1); fill:none;" y2="247.7766"/> <line x1="53.7783" x2="412.8237" y1="214.7117" style="clip-path:url(#clipPath1); fill:none;" y2="214.7117"/> <line x1="53.7783" x2="412.8237" y1="181.6469" style="clip-path:url(#clipPath1); fill:none;" y2="181.6469"/> <line x1="53.7783" x2="412.8237" y1="148.5821" style="clip-path:url(#clipPath1); fill:none;" y2="148.5821"/> <line x1="53.7783" x2="412.8237" y1="115.5172" style="clip-path:url(#clipPath1); fill:none;" y2="115.5172"/> <line x1="53.7783" x2="412.8237" y1="82.4524" style="clip-path:url(#clipPath1); fill:none;" y2="82.4524"/> </g> <g style="fill-opacity:0.502; fill:rgb(204,204,204); text-rendering:optimizeLegibility; font-family:sans-serif; stroke:rgb(204,204,204); stroke-opacity:0.502;">
67
<line x1="53.7783" x2="412.8237" y1="313.9062" style="clip-path:url(#clipPath1); fill:none;" y2="313.9062"/> </g> <g style="fill:red; text-rendering:optimizeLegibility; font-family:sans-serif; stroke:red;"> <rect x="71.7306" y="111.5495" width="9.9735" style="clip-path:url(#clipPath4); opacity:0.5; stroke:none;" height="202.3568"/> <rect x="71.7306" y="111.5495" width="9.9735" style="clip-path:url(#clipPath4); fill:none; stroke-linejoin:bevel; opacity:0.5; stroke:silver;" height="202.3568"/> <rect x="87.6882" y="179.0017" width="9.9735" style="clip-path:url(#clipPath4); fill:blue; stroke-linejoin:bevel; opacity:0.5; stroke:none;" height="134.9045"/> <rect x="87.6882" y="179.0017" width="9.9735" style="clip-path:url(#clipPath4); fill:none; stroke-linejoin:bevel; opacity:0.5; stroke:silver;" height="134.9045"/> <rect x="103.6457" y="148.5821" width="9.9735" style="clip-path:url(#clipPath4); fill:lime; stroke-linejoin:bevel; opacity:0.5; stroke:none;" height="165.3242"/> <rect x="103.6457" y="148.5821" width="9.9735" style="clip-path:url(#clipPath4); fill:none; stroke-linejoin:bevel; opacity:0.5; stroke:silver;" height="165.3242"/> <rect x="127.981" y="237.1958" width="9.9735" style="clip-path:url(#clipPath4); stroke-linejoin:bevel; opacity:0.5; stroke:none;" height="76.7104"/> <rect x="127.981" y="237.1958" width="9.9735" style="clip-path:url(#clipPath4); fill:none; stroke-linejoin:bevel; opacity:0.5; stroke:silver;" height="76.7104"/> <rect x="143.9386" y="126.098" width="9.9735" style="clip-path:url(#clipPath4); fill:blue; stroke-linejoin:bevel; opacity:0.5; stroke:none;" height="187.8083"/> <rect x="143.9386" y="126.098" width="9.9735" style="clip-path:url(#clipPath4); fill:none; stroke-linejoin:bevel; opacity:0.5; stroke:silver;" height="187.8083"/> <rect x="159.8962" y="220.0021" width="9.9735" style="clip-path:url(#clipPath4); fill:lime; stroke-linejoin:bevel; opacity:0.5; stroke:none;" height="93.9041"/> <rect x="159.8962" y="220.0021" width="9.9735" style="clip-path:url(#clipPath4); fill:none; stroke-linejoin:bevel; opacity:0.5; stroke:silver;" height="93.9041"/> <rect x="184.2315" y="188.2599" width="9.9735" style="clip-path:url(#clipPath4); stroke-linejoin:bevel; opacity:0.5; stroke:none;" height="125.6464"/> <rect x="184.2315" y="188.2599" width="9.9735" style="clip-path:url(#clipPath4); fill:none; stroke-linejoin:bevel; opacity:0.5; stroke:silver;" height="125.6464"/> <rect x="200.1891" y="141.9691" width="9.9735" style="clip-path:url(#clipPath4); fill:blue; stroke-linejoin:bevel; opacity:0.5; stroke:none;" height="171.9371"/> <rect x="200.1891" y="141.9691" width="9.9735" style="clip-path:url(#clipPath4); fill:none; stroke-linejoin:bevel; opacity:0.5; stroke:silver;" height="171.9371"/> <rect x="216.1466" y="91.7106" width="9.9735" style="clip-path:url(#clipPath4); fill:lime; stroke-linejoin:bevel; opacity:0.5; stroke:none;" height="222.1957"/>
68
<rect x="216.1466" y="91.7106" width="9.9735" style="clip-path:url(#clipPath4); fill:none; stroke-linejoin:bevel; opacity:0.5; stroke:silver;" height="222.1957"/> <rect x="240.4819" y="179.0017" width="9.9735" style="clip-path:url(#clipPath4); stroke-linejoin:bevel; opacity:0.5; stroke:none;" height="134.9045"/> <rect x="240.4819" y="179.0017" width="9.9735" style="clip-path:url(#clipPath4); fill:none; stroke-linejoin:bevel; opacity:0.5; stroke:silver;" height="134.9045"/> <rect x="256.4395" y="91.7106" width="9.9735" style="clip-path:url(#clipPath4); fill:blue; stroke-linejoin:bevel; opacity:0.5; stroke:none;" height="222.1957"/> <rect x="256.4395" y="91.7106" width="9.9735" style="clip-path:url(#clipPath4); fill:none; stroke-linejoin:bevel; opacity:0.5; stroke:silver;" height="222.1957"/> <rect x="272.3971" y="111.5495" width="9.9735" style="clip-path:url(#clipPath4); fill:lime; stroke-linejoin:bevel; opacity:0.5; stroke:none;" height="202.3568"/> <rect x="272.3971" y="111.5495" width="9.9735" style="clip-path:url(#clipPath4); fill:none; stroke-linejoin:bevel; opacity:0.5; stroke:silver;" height="202.3568"/> <rect x="296.7324" y="220.0021" width="9.9735" style="clip-path:url(#clipPath4); stroke-linejoin:bevel; opacity:0.5; stroke:none;" height="93.9041"/> <rect x="296.7324" y="220.0021" width="9.9735" style="clip-path:url(#clipPath4); fill:none; stroke-linejoin:bevel; opacity:0.5; stroke:silver;" height="93.9041"/> <rect x="312.69" y="235.8732" width="9.9735" style="clip-path:url(#clipPath4); fill:blue; stroke-linejoin:bevel; opacity:0.5; stroke:none;" height="78.033"/> <rect x="312.69" y="235.8732" width="9.9735" style="clip-path:url(#clipPath4); fill:none; stroke-linejoin:bevel; opacity:0.5; stroke:silver;" height="78.033"/> <rect x="328.6475" y="188.2599" width="9.9735" style="clip-path:url(#clipPath4); fill:lime; stroke-linejoin:bevel; opacity:0.5; stroke:none;" height="125.6464"/> <rect x="328.6475" y="188.2599" width="9.9735" style="clip-path:url(#clipPath4); fill:none; stroke-linejoin:bevel; opacity:0.5; stroke:silver;" height="125.6464"/> <rect x="352.9828" y="243.8088" width="9.9735" style="clip-path:url(#clipPath4); stroke-linejoin:bevel; opacity:0.5; stroke:none;" height="70.0974"/> <rect x="352.9828" y="243.8088" width="9.9735" style="clip-path:url(#clipPath4); fill:none; stroke-linejoin:bevel; opacity:0.5; stroke:silver;" height="70.0974"/> <rect x="368.9404" y="209.4214" width="9.9735" style="clip-path:url(#clipPath4); fill:blue; stroke-linejoin:bevel; opacity:0.5; stroke:none;" height="104.4849"/> <rect x="368.9404" y="209.4214" width="9.9735" style="clip-path:url(#clipPath4); fill:none; stroke-linejoin:bevel; opacity:0.5; stroke:silver;" height="104.4849"/> <rect x="384.898" y="141.9691" width="9.9735" style="clip-path:url(#clipPath4); fill:lime; stroke-linejoin:bevel; opacity:0.5; stroke:none;" height="171.9371"/> <rect x="384.898" y="141.9691" width="9.9735" style="clip-path:url(#clipPath4); fill:none; stroke-linejoin:bevel; opacity:0.5; stroke:silver;" height="171.9371"/>
69
<rect x="53.7783" y="80.6008" width="359.0454" style="clip-path:url(#clipPath1); fill:none; stroke:gray;" height="233.3055"/> </g> </g> </svg>
Código fonte do gráfico de barras agrupadas <?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 1.0//EN' 'http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd'> <svg xmlns:xlink="http://www.w3.org/1999/xlink" style="fill-opacity:1; color-rendering:auto; color-interpolation:auto; stroke:black; text-rendering:auto; stroke-linecap:square; stroke-miterlimit:10; shape-rendering:auto; stroke-opacity:1; fill:black; stroke-dasharray:none; font-weight:normal; stroke-width:1; font-family:'sansserif'; font-style:normal; stroke-linejoin:miter; font-size:12; stroke-dashoffset:0; image-rendering:auto;" xmlns="http://www.w3.org/2000/svg"> <!--Documento gerado por SVGChart - Henrique A. Viecili--> <defs id="genericDefs"/> <g> <defs id="defs1"> <clipPath clipPathUnits="userSpaceOnUse" id="clipPath1"> <path d="M0 0 L480 0 L480 360 L0 360 L0 0 Z"/> </clipPath> <clipPath clipPathUnits="userSpaceOnUse" id="clipPath2"> <path d="M-423.8237 -193.4332 L56.1763 -193.4332 L56.1763 166.5668 L-423.8237 166.5668 L-423.8237 -193.4332 Z"/> </clipPath> <clipPath clipPathUnits="userSpaceOnUse" id="clipPath3"> <path d="M255.6832 218.5894 L255.6832 698.5895 L-104.3168 698.5895 L-104.3168 218.5894 L255.6832 218.5894 Z"/> </clipPath> <clipPath clipPathUnits="userSpaceOnUse" id="clipPath4"> <path d="M73.0938 118.2727 L73.0938 356 L412.8237 356 L412.8237 118.2727 Z"/> </clipPath> </defs> <g style="fill:rgb(50,150,250); text-rendering:optimizeLegibility; stroke:rgb(50,150,250);"> <rect x="0" y="0" width="480" style="clip-path:url(#clipPath1); stroke:none;" height="360"/> </g> <g style="text-rendering:optimizeLegibility; font-size:18; font-weight:bold; font-family:sans-serif;"> <text x="59.9473" y="24.8889" style="clip-path:url(#clipPath1); stroke:none;" xml:space="preserve">Exemplo de Gráfico de Barras Horizontais</text> <text x="177.6475" y="49.4215" style="font-size:12; clip-path:url(#clipPath1); stroke:none;" xml:space="preserve">Gráfico de Categorias</text> <text x="196.6465" y="71.3074" style="font-size:12; clip-path:url(#clipPath1); stroke:none;" xml:space="preserve">SVGChart 2004</text> </g>
70
<g transform="translate(423.8237,193.4332)" style="font-size:10; fill:white; text-rendering:optimizeLegibility; font-family:sans-serif; stroke:white;"> <rect x="0" y="0" width="53.1763" style="clip-path:url(#clipPath2); stroke:none;" height="49.7344"/> <rect x="0" y="0" width="53.1763" style="clip-path:url(#clipPath2); fill:none; stroke:gray;" height="49.7344"/> <rect x="3.8867" y="3.8867" width="8.8047" style="clip-path:url(#clipPath2); fill:red; stroke:none;" height="8.8047"/> <text x="16" y="12" style="clip-path:url(#clipPath2); fill:black; stroke:none;" xml:space="preserve">Série 1</text> <rect x="3.8867" y="20.4648" width="8.8047" style="clip-path:url(#clipPath2); fill:blue; stroke:none;" height="8.8047"/> <text x="16" y="28" style="clip-path:url(#clipPath2); fill:black; stroke:none;" xml:space="preserve">Série 2</text> <rect x="3.8867" y="37.043" width="8.8047" style="clip-path:url(#clipPath2); fill:lime; stroke:none;" height="8.8047"/> <text x="16" y="45" style="clip-path:url(#clipPath2); fill:black; stroke:none;" xml:space="preserve">Série 3</text> <rect x="73.0938" y="118.2727" transform="translate(-423.8237,-193.4332)" width="339.73" style="clip-path:url(#clipPath1); stroke:none;" height="237.7273"/> <line transform="translate(-423.8237,-193.4332)" x1="73.0938" x2="412.8237" y1="118.2727" style="clip-path:url(#clipPath1); fill:none; stroke:gray;" y2="118.2727"/> <text x="70.313" y="111.7482" transform="translate(-423.8237,-193.4332)" style="clip-path:url(#clipPath1); fill:black; stroke:none;" xml:space="preserve">0</text> </g> <g style="fill:gray; text-rendering:optimizeLegibility; font-size:10; font-family:sans-serif; stroke:gray;"> <line x1="73.0938" x2="73.0938" y1="116.2727" style="clip-path:url(#clipPath1); fill:none;" y2="118.2727"/> <text x="115.6799" y="111.7482" style="clip-path:url(#clipPath1); fill:black; stroke:none;" xml:space="preserve">25</text> </g> <g style="fill:gray; text-rendering:optimizeLegibility; font-size:10; font-family:sans-serif; stroke:gray;"> <line x1="121.2414" x2="121.2414" y1="116.2727" style="clip-path:url(#clipPath1); fill:none;" y2="118.2727"/> <text x="163.8276" y="111.7482" style="clip-path:url(#clipPath1); fill:black; stroke:none;" xml:space="preserve">50</text> </g> <g style="fill:gray; text-rendering:optimizeLegibility; font-size:10; font-family:sans-serif; stroke:gray;"> <line x1="169.3891" x2="169.3891" y1="116.2727" style="clip-path:url(#clipPath1); fill:none;" y2="118.2727"/> <text x="211.9753" y="111.7482" style="clip-path:url(#clipPath1); fill:black; stroke:none;" xml:space="preserve">75</text> </g> <g style="fill:gray; text-rendering:optimizeLegibility; font-size:10; font-family:sans-serif; stroke:gray;"> <line x1="217.5368" x2="217.5368" y1="116.2727" style="clip-path:url(#clipPath1); fill:none;" y2="118.2727"/> <text x="257.3422" y="111.7482" style="clip-path:url(#clipPath1); fill:black; stroke:none;" xml:space="preserve">100</text> </g>
71
<g style="fill:gray; text-rendering:optimizeLegibility; font-size:10; font-family:sans-serif; stroke:gray;"> <line x1="265.6844" x2="265.6844" y1="116.2727" style="clip-path:url(#clipPath1); fill:none;" y2="118.2727"/> <text x="305.4898" y="111.7482" style="clip-path:url(#clipPath1); fill:black; stroke:none;" xml:space="preserve">125</text> </g> <g style="fill:gray; text-rendering:optimizeLegibility; font-size:10; font-family:sans-serif; stroke:gray;"> <line x1="313.8321" x2="313.8321" y1="116.2727" style="clip-path:url(#clipPath1); fill:none;" y2="118.2727"/> <text x="353.6375" y="111.7482" style="clip-path:url(#clipPath1); fill:black; stroke:none;" xml:space="preserve">150</text> </g> <g style="fill:gray; text-rendering:optimizeLegibility; font-size:10; font-family:sans-serif; stroke:gray;"> <line x1="361.9798" x2="361.9798" y1="116.2727" style="clip-path:url(#clipPath1); fill:none;" y2="118.2727"/> <text x="401.7852" y="111.7482" style="clip-path:url(#clipPath1); fill:black; stroke:none;" xml:space="preserve">175</text> </g> <g style="fill:gray; text-rendering:optimizeLegibility; font-size:10; font-family:sans-serif; stroke:gray;"> <line x1="410.1275" x2="410.1275" y1="116.2727" style="clip-path:url(#clipPath1); fill:none;" y2="118.2727"/> <text x="225.6179" y="95.6652" style="font-size:12; clip-path:url(#clipPath1); fill:black; stroke:none;" xml:space="preserve">Eixo Y</text> </g> <g style="fill:gray; text-rendering:optimizeLegibility; font-family:sans-serif; stroke:gray;"> <line x1="73.0938" x2="73.0938" y1="118.2727" style="clip-path:url(#clipPath1); fill:none;" y2="356"/> <text x="39.0938" y="147.5802" style="font-size:10; clip-path:url(#clipPath1); fill:black; stroke:none;" xml:space="preserve"> Cat 1</text> </g> <g style="text-rendering:optimizeLegibility; font-size:10; font-family:sans-serif;"> <text x="33.0938" y="184.8241" style="clip-path:url(#clipPath1); stroke:none;" xml:space="preserve"> Cat 2</text> </g> <g style="text-rendering:optimizeLegibility; font-size:10; font-family:sans-serif;"> <text x="33.0938" y="222.0681" style="clip-path:url(#clipPath1); stroke:none;" xml:space="preserve"> Cat 3</text> </g> <g style="text-rendering:optimizeLegibility; font-size:10; font-family:sans-serif;"> <text x="33.0938" y="259.312" style="clip-path:url(#clipPath1); stroke:none;" xml:space="preserve"> Cat 4</text> </g> <g style="text-rendering:optimizeLegibility; font-size:10; font-family:sans-serif;"> <text x="33.0938" y="296.556" style="clip-path:url(#clipPath1); stroke:none;" xml:space="preserve"> Cat 5</text> </g>
72
<g style="text-rendering:optimizeLegibility; font-size:10; font-family:sans-serif;"> <text x="33.0938" y="333.7999" style="clip-path:url(#clipPath1); stroke:none;" xml:space="preserve"> Cat 6</text> </g> <g style="text-rendering:optimizeLegibility; font-family:sans-serif;" transform="matrix(0,-1,1,0,-218.5894,255.6832)"> <text x="14.5449" y="241.6539" style="clip-path:url(#clipPath3); stroke:none;" xml:space="preserve">X</text> </g> <g style="stroke-linecap:butt; fill:silver; text-rendering:optimizeLegibility; stroke-linejoin:bevel; font-family:sans-serif; stroke-dasharray:2,2; stroke:silver; stroke-width:0.5; stroke-miterlimit:0;"> <line x1="73.0938" x2="73.0938" y1="118.2727" style="clip-path:url(#clipPath1); fill:none;" y2="356"/> <line x1="121.2414" x2="121.2414" y1="118.2727" style="clip-path:url(#clipPath1); fill:none;" y2="356"/> <line x1="169.3891" x2="169.3891" y1="118.2727" style="clip-path:url(#clipPath1); fill:none;" y2="356"/> <line x1="217.5368" x2="217.5368" y1="118.2727" style="clip-path:url(#clipPath1); fill:none;" y2="356"/> <line x1="265.6844" x2="265.6844" y1="118.2727" style="clip-path:url(#clipPath1); fill:none;" y2="356"/> <line x1="313.8321" x2="313.8321" y1="118.2727" style="clip-path:url(#clipPath1); fill:none;" y2="356"/> <line x1="361.9798" x2="361.9798" y1="118.2727" style="clip-path:url(#clipPath1); fill:none;" y2="356"/> <line x1="410.1275" x2="410.1275" y1="118.2727" style="clip-path:url(#clipPath1); fill:none;" y2="356"/> </g> <g style="fill-opacity:0.502; fill:rgb(204,204,204); text-rendering:optimizeLegibility; font-family:sans-serif; stroke:rgb(204,204,204); stroke-opacity:0.502;"> <line x1="73.0938" x2="73.0938" y1="118.2727" style="clip-path:url(#clipPath1); fill:none;" y2="356"/> </g> <g style="fill:red; text-rendering:optimizeLegibility; font-family:sans-serif; stroke:red;"> <rect x="73.0938" y="130.159" width="294.6638" style="clip-path:url(#clipPath4); opacity:0.5; stroke:none;" height="6.6035"/> <rect x="73.0938" y="130.159" width="294.6638" style="clip-path:url(#clipPath4); fill:none; stroke-linejoin:bevel; opacity:0.5; stroke:silver;" height="6.6035"/> <rect x="73.0938" y="140.7247" width="196.4425" style="clip-path:url(#clipPath4); fill:blue; stroke-linejoin:bevel; opacity:0.5; stroke:none;" height="6.6035"/> <rect x="73.0938" y="140.7247" width="196.4425" style="clip-path:url(#clipPath4); fill:none; stroke-linejoin:bevel; opacity:0.5; stroke:silver;" height="6.6035"/> <rect x="73.0938" y="151.2903" width="240.7384" style="clip-path:url(#clipPath4); fill:lime; stroke-linejoin:bevel; opacity:0.5; stroke:none;" height="6.6035"/> <rect x="73.0938" y="151.2903" width="240.7384" style="clip-path:url(#clipPath4); fill:none; stroke-linejoin:bevel; opacity:0.5; stroke:silver;" height="6.6035"/>
73
<rect x="73.0938" y="167.403" width="111.7026" style="clip-path:url(#clipPath4); stroke-linejoin:bevel; opacity:0.5; stroke:none;" height="6.6035"/> <rect x="73.0938" y="167.403" width="111.7026" style="clip-path:url(#clipPath4); fill:none; stroke-linejoin:bevel; opacity:0.5; stroke:silver;" height="6.6035"/> <rect x="73.0938" y="177.9686" width="273.4788" style="clip-path:url(#clipPath4); fill:blue; stroke-linejoin:bevel; opacity:0.5; stroke:none;" height="6.6035"/> <rect x="73.0938" y="177.9686" width="273.4788" style="clip-path:url(#clipPath4); fill:none; stroke-linejoin:bevel; opacity:0.5; stroke:silver;" height="6.6035"/> <rect x="73.0938" y="188.5343" width="136.7394" style="clip-path:url(#clipPath4); fill:lime; stroke-linejoin:bevel; opacity:0.5; stroke:none;" height="6.6035"/> <rect x="73.0938" y="188.5343" width="136.7394" style="clip-path:url(#clipPath4); fill:none; stroke-linejoin:bevel; opacity:0.5; stroke:silver;" height="6.6035"/> <rect x="73.0938" y="204.6469" width="182.9612" style="clip-path:url(#clipPath4); stroke-linejoin:bevel; opacity:0.5; stroke:none;" height="6.6035"/> <rect x="73.0938" y="204.6469" width="182.9612" style="clip-path:url(#clipPath4); fill:none; stroke-linejoin:bevel; opacity:0.5; stroke:silver;" height="6.6035"/> <rect x="73.0938" y="215.2126" width="250.3679" style="clip-path:url(#clipPath4); fill:blue; stroke-linejoin:bevel; opacity:0.5; stroke:none;" height="6.6035"/> <rect x="73.0938" y="215.2126" width="250.3679" style="clip-path:url(#clipPath4); fill:none; stroke-linejoin:bevel; opacity:0.5; stroke:silver;" height="6.6035"/> <rect x="73.0938" y="225.7782" width="323.5524" style="clip-path:url(#clipPath4); fill:lime; stroke-linejoin:bevel; opacity:0.5; stroke:none;" height="6.6035"/> <rect x="73.0938" y="225.7782" width="323.5524" style="clip-path:url(#clipPath4); fill:none; stroke-linejoin:bevel; opacity:0.5; stroke:silver;" height="6.6035"/> <rect x="73.0938" y="241.8909" width="196.4425" style="clip-path:url(#clipPath4); stroke-linejoin:bevel; opacity:0.5; stroke:none;" height="6.6035"/> <rect x="73.0938" y="241.8909" width="196.4425" style="clip-path:url(#clipPath4); fill:none; stroke-linejoin:bevel; opacity:0.5; stroke:silver;" height="6.6035"/> <rect x="73.0938" y="252.4565" width="323.5524" style="clip-path:url(#clipPath4); fill:blue; stroke-linejoin:bevel; opacity:0.5; stroke:none;" height="6.6035"/> <rect x="73.0938" y="252.4565" width="323.5524" style="clip-path:url(#clipPath4); fill:none; stroke-linejoin:bevel; opacity:0.5; stroke:silver;" height="6.6035"/> <rect x="73.0938" y="263.0222" width="294.6638" style="clip-path:url(#clipPath4); fill:lime; stroke-linejoin:bevel; opacity:0.5; stroke:none;" height="6.6035"/> <rect x="73.0938" y="263.0222" width="294.6638" style="clip-path:url(#clipPath4); fill:none; stroke-linejoin:bevel; opacity:0.5; stroke:silver;" height="6.6035"/> <rect x="73.0938" y="279.1348" width="136.7394" style="clip-path:url(#clipPath4); stroke-linejoin:bevel; opacity:0.5; stroke:none;" height="6.6035"/>
74
<rect x="73.0938" y="279.1348" width="136.7394" style="clip-path:url(#clipPath4); fill:none; stroke-linejoin:bevel; opacity:0.5; stroke:silver;" height="6.6035"/> <rect x="73.0938" y="289.7005" width="113.6285" style="clip-path:url(#clipPath4); fill:blue; stroke-linejoin:bevel; opacity:0.5; stroke:none;" height="6.6035"/> <rect x="73.0938" y="289.7005" width="113.6285" style="clip-path:url(#clipPath4); fill:none; stroke-linejoin:bevel; opacity:0.5; stroke:silver;" height="6.6035"/> <rect x="73.0938" y="300.2661" width="182.9612" style="clip-path:url(#clipPath4); fill:lime; stroke-linejoin:bevel; opacity:0.5; stroke:none;" height="6.6035"/> <rect x="73.0938" y="300.2661" width="182.9612" style="clip-path:url(#clipPath4); fill:none; stroke-linejoin:bevel; opacity:0.5; stroke:silver;" height="6.6035"/> <rect x="73.0938" y="316.3788" width="102.0731" style="clip-path:url(#clipPath4); stroke-linejoin:bevel; opacity:0.5; stroke:none;" height="6.6035"/> <rect x="73.0938" y="316.3788" width="102.0731" style="clip-path:url(#clipPath4); fill:none; stroke-linejoin:bevel; opacity:0.5; stroke:silver;" height="6.6035"/> <rect x="73.0938" y="326.9444" width="152.1466" style="clip-path:url(#clipPath4); fill:blue; stroke-linejoin:bevel; opacity:0.5; stroke:none;" height="6.6035"/> <rect x="73.0938" y="326.9444" width="152.1466" style="clip-path:url(#clipPath4); fill:none; stroke-linejoin:bevel; opacity:0.5; stroke:silver;" height="6.6035"/> <rect x="73.0938" y="337.5101" width="250.3679" style="clip-path:url(#clipPath4); fill:lime; stroke-linejoin:bevel; opacity:0.5; stroke:none;" height="6.6035"/> <rect x="73.0938" y="337.5101" width="250.3679" style="clip-path:url(#clipPath4); fill:none; stroke-linejoin:bevel; opacity:0.5; stroke:silver;" height="6.6035"/> <rect x="73.0938" y="118.2727" width="339.73" style="clip-path:url(#clipPath1); fill:none; stroke:gray;" height="237.7273"/> </g> </g> </svg>
Código fonte do gráfico de linhas <?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 1.0//EN' 'http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd'> <svg xmlns:xlink="http://www.w3.org/1999/xlink" style="fill-opacity:1; color-rendering:auto; color-interpolation:auto; stroke:black; text-rendering:auto; stroke-linecap:square; stroke-miterlimit:10; shape-rendering:auto; stroke-opacity:1; fill:black; stroke-dasharray:none; font-weight:normal; stroke-width:1; font-family:'sansserif'; font-style:normal; stroke-linejoin:miter; font-size:12; stroke-dashoffset:0; image-rendering:auto;" xmlns="http://www.w3.org/2000/svg"> <!--Documento gerado por SVGChart - Henrique A. Viecili--> <defs id="genericDefs"/> <g> <defs id="defs1"> <clipPath clipPathUnits="userSpaceOnUse" id="clipPath1">
75
<path d="M0 0 L480 0 L480 360 L0 360 L0 0 Z"/> </clipPath> <clipPath clipPathUnits="userSpaceOnUse" id="clipPath2"> <path d="M-423.8237 -193.4332 L56.1763 -193.4332 L56.1763 166.5668 L-423.8237 166.5668 L-423.8237 -193.4332 Z"/> </clipPath> <clipPath clipPathUnits="userSpaceOnUse" id="clipPath3"> <path d="M215.8004 178.7066 L215.8004 658.7067 L-144.1996 658.7067 L-144.1996 178.7066 L215.8004 178.7066 Z"/> </clipPath> <clipPath clipPathUnits="userSpaceOnUse" id="clipPath4"> <path d="M53.7783 80.6008 L53.7783 313.9062 L412.8237 313.9062 L412.8237 80.6008 Z"/> </clipPath> </defs> <g style="fill:rgb(50,150,250); text-rendering:optimizeLegibility; stroke:rgb(50,150,250);"> <rect x="0" y="0" width="480" style="clip-path:url(#clipPath1); stroke:none;" height="360"/> </g> <g style="text-rendering:optimizeLegibility; font-size:18; font-weight:bold; font-family:sans-serif;"> <text x="110.9678" y="24.8889" style="clip-path:url(#clipPath1); stroke:none;" xml:space="preserve">Exemplo de Gráfico de Linhas</text> <text x="177.6475" y="49.4215" style="font-size:12; clip-path:url(#clipPath1); stroke:none;" xml:space="preserve">Gráfico de Categorias</text> <text x="196.6465" y="71.3074" style="font-size:12; clip-path:url(#clipPath1); stroke:none;" xml:space="preserve">SVGChart 2004</text> </g> <g transform="translate(423.8237,193.4332)" style="font-size:10; fill:white; text-rendering:optimizeLegibility; font-family:sans-serif; stroke:white;"> <rect x="0" y="0" width="53.1763" style="clip-path:url(#clipPath2); stroke:none;" height="49.7344"/> <rect x="0" y="0" width="53.1763" style="clip-path:url(#clipPath2); fill:none; stroke:gray;" height="49.7344"/> <rect x="3.8867" y="3.8867" width="8.8047" style="clip-path:url(#clipPath2); fill:red; stroke:none;" height="8.8047"/> <text x="16" y="12" style="clip-path:url(#clipPath2); fill:black; stroke:none;" xml:space="preserve">Série 1</text> <rect x="3.8867" y="20.4648" width="8.8047" style="clip-path:url(#clipPath2); fill:blue; stroke:none;" height="8.8047"/> <text x="16" y="28" style="clip-path:url(#clipPath2); fill:black; stroke:none;" xml:space="preserve">Série 2</text> <rect x="3.8867" y="37.043" width="8.8047" style="clip-path:url(#clipPath2); fill:lime; stroke:none;" height="8.8047"/> <text x="16" y="45" style="clip-path:url(#clipPath2); fill:black; stroke:none;" xml:space="preserve">Série 3</text> <rect x="53.7783" y="80.6008" transform="translate(-423.8237,-193.4332)" width="359.0454" style="clip-path:url(#clipPath1); stroke:none;" height="233.3055"/> <line transform="translate(-423.8237,-193.4332)" x1="53.7783" x2="412.8237" y1="313.9062" style="clip-path:url(#clipPath1); fill:none; stroke:gray;" y2="313.9062"/>
76
<text x="77.6749" y="327.96" transform="translate(-423.8237,-193.4332)" style="clip-path:url(#clipPath1); fill:black; stroke:none;" xml:space="preserve"> Cat 1</text> </g> <g style="text-rendering:optimizeLegibility; font-size:10; font-family:sans-serif;"> <text x="130.9254" y="327.96" style="clip-path:url(#clipPath1); stroke:none;" xml:space="preserve"> Cat 2</text> </g> <g style="text-rendering:optimizeLegibility; font-size:10; font-family:sans-serif;"> <text x="187.1758" y="327.96" style="clip-path:url(#clipPath1); stroke:none;" xml:space="preserve"> Cat 3</text> </g> <g style="text-rendering:optimizeLegibility; font-size:10; font-family:sans-serif;"> <text x="243.4262" y="327.96" style="clip-path:url(#clipPath1); stroke:none;" xml:space="preserve"> Cat 4</text> </g> <g style="text-rendering:optimizeLegibility; font-size:10; font-family:sans-serif;"> <text x="299.6767" y="327.96" style="clip-path:url(#clipPath1); stroke:none;" xml:space="preserve"> Cat 5</text> </g> <g style="text-rendering:optimizeLegibility; font-size:10; font-family:sans-serif;"> <text x="355.9272" y="327.96" style="clip-path:url(#clipPath1); stroke:none;" xml:space="preserve"> Cat 6</text> </g> <g style="font-family:sans-serif; text-rendering:optimizeLegibility;"> <text x="215.9602" y="349.9707" style="clip-path:url(#clipPath1); stroke:none;" xml:space="preserve">Eixo X</text> </g> <g style="fill:gray; text-rendering:optimizeLegibility; font-family:sans-serif; stroke:gray;"> <line x1="53.7783" x2="53.7783" y1="80.6008" style="clip-path:url(#clipPath1); fill:none;" y2="313.9062"/> <text x="42.2168" y="317.6709" style="font-size:10; clip-path:url(#clipPath1); fill:black; stroke:none;" xml:space="preserve">0</text> </g> <g style="fill:gray; text-rendering:optimizeLegibility; font-size:10; font-family:sans-serif; stroke:gray;"> <line x1="51.7783" x2="53.7783" y1="313.9062" style="clip-path:url(#clipPath1); fill:none;" y2="313.9062"/> <text x="36.6553" y="284.6061" style="clip-path:url(#clipPath1); fill:black; stroke:none;" xml:space="preserve">25</text> </g> <g style="fill:gray; text-rendering:optimizeLegibility; font-size:10; font-family:sans-serif; stroke:gray;"> <line x1="51.7783" x2="53.7783" y1="280.8414" style="clip-path:url(#clipPath1); fill:none;" y2="280.8414"/> <text x="36.6553" y="251.5412" style="clip-path:url(#clipPath1); fill:black; stroke:none;" xml:space="preserve">50</text> </g>
77
<g style="fill:gray; text-rendering:optimizeLegibility; font-size:10; font-family:sans-serif; stroke:gray;"> <line x1="51.7783" x2="53.7783" y1="247.7766" style="clip-path:url(#clipPath1); fill:none;" y2="247.7766"/> <text x="36.6553" y="218.4764" style="clip-path:url(#clipPath1); fill:black; stroke:none;" xml:space="preserve">75</text> </g> <g style="fill:gray; text-rendering:optimizeLegibility; font-size:10; font-family:sans-serif; stroke:gray;"> <line x1="51.7783" x2="53.7783" y1="214.7117" style="clip-path:url(#clipPath1); fill:none;" y2="214.7117"/> <text x="31.0938" y="185.4116" style="clip-path:url(#clipPath1); fill:black; stroke:none;" xml:space="preserve">100</text> </g> <g style="fill:gray; text-rendering:optimizeLegibility; font-size:10; font-family:sans-serif; stroke:gray;"> <line x1="51.7783" x2="53.7783" y1="181.6469" style="clip-path:url(#clipPath1); fill:none;" y2="181.6469"/> <text x="31.0938" y="152.3467" style="clip-path:url(#clipPath1); fill:black; stroke:none;" xml:space="preserve">125</text> </g> <g style="fill:gray; text-rendering:optimizeLegibility; font-size:10; font-family:sans-serif; stroke:gray;"> <line x1="51.7783" x2="53.7783" y1="148.5821" style="clip-path:url(#clipPath1); fill:none;" y2="148.5821"/> <text x="31.0938" y="119.2819" style="clip-path:url(#clipPath1); fill:black; stroke:none;" xml:space="preserve">150</text> </g> <g style="fill:gray; text-rendering:optimizeLegibility; font-size:10; font-family:sans-serif; stroke:gray;"> <line x1="51.7783" x2="53.7783" y1="115.5172" style="clip-path:url(#clipPath1); fill:none;" y2="115.5172"/> <text x="31.0938" y="86.2171" style="clip-path:url(#clipPath1); fill:black; stroke:none;" xml:space="preserve">175</text> </g> <g style="fill:gray; text-rendering:optimizeLegibility; font-size:10; font-family:sans-serif; stroke:gray;"> <line x1="51.7783" x2="53.7783" y1="82.4524" style="clip-path:url(#clipPath1); fill:none;" y2="82.4524"/> <text x="14.5449" y="201.7711" transform="matrix(0,-1,1,0,-178.7066,215.8004)" style="font-size:12; clip-path:url(#clipPath3); fill:black; stroke:none;" xml:space="preserve">Y</text> </g> <g style="stroke-linecap:butt; fill:silver; text-rendering:optimizeLegibility; stroke-linejoin:bevel; font-family:sans-serif; stroke-dasharray:2,2; stroke:silver; stroke-width:0.5; stroke-miterlimit:0;"> <line x1="53.7783" x2="412.8237" y1="313.9062" style="clip-path:url(#clipPath1); fill:none;" y2="313.9062"/> <line x1="53.7783" x2="412.8237" y1="280.8414" style="clip-path:url(#clipPath1); fill:none;" y2="280.8414"/> <line x1="53.7783" x2="412.8237" y1="247.7766" style="clip-path:url(#clipPath1); fill:none;" y2="247.7766"/> <line x1="53.7783" x2="412.8237" y1="214.7117" style="clip-path:url(#clipPath1); fill:none;" y2="214.7117"/> <line x1="53.7783" x2="412.8237" y1="181.6469" style="clip-path:url(#clipPath1); fill:none;" y2="181.6469"/>
78
<line x1="53.7783" x2="412.8237" y1="148.5821" style="clip-path:url(#clipPath1); fill:none;" y2="148.5821"/> <line x1="53.7783" x2="412.8237" y1="115.5172" style="clip-path:url(#clipPath1); fill:none;" y2="115.5172"/> <line x1="53.7783" x2="412.8237" y1="82.4524" style="clip-path:url(#clipPath1); fill:none;" y2="82.4524"/> </g> <g style="fill-opacity:0.502; fill:rgb(204,204,204); text-rendering:optimizeLegibility; font-family:sans-serif; stroke:rgb(204,204,204); stroke-opacity:0.502;"> <line x1="53.7783" x2="412.8237" y1="313.9062" style="clip-path:url(#clipPath1); fill:none;" y2="313.9062"/> </g> <g style="fill:red; text-rendering:optimizeLegibility; font-family:sans-serif; stroke-linejoin:bevel; stroke:red;"> <line x1="92.6749" x2="148.9254" y1="111.5495" style="clip-path:url(#clipPath4); fill:none; opacity:0.5;" y2="237.1958"/> <line x1="92.6749" x2="148.9254" y1="179.0017" style="clip-path:url(#clipPath4); fill:none; opacity:0.5; stroke:blue;" y2="126.098"/> <line x1="92.6749" x2="148.9254" y1="148.5821" style="clip-path:url(#clipPath4); fill:none; opacity:0.5; stroke:lime;" y2="220.0021"/> <line x1="148.9254" x2="205.1758" y1="237.1958" style="clip-path:url(#clipPath4); fill:none; opacity:0.5;" y2="188.2599"/> <line x1="148.9254" x2="205.1758" y1="126.098" style="clip-path:url(#clipPath4); fill:none; opacity:0.5; stroke:blue;" y2="141.9691"/> <line x1="148.9254" x2="205.1758" y1="220.0021" style="clip-path:url(#clipPath4); fill:none; opacity:0.5; stroke:lime;" y2="91.7106"/> <line x1="205.1758" x2="261.4262" y1="188.2599" style="clip-path:url(#clipPath4); fill:none; opacity:0.5;" y2="179.0017"/> <line x1="205.1758" x2="261.4262" y1="141.9691" style="clip-path:url(#clipPath4); fill:none; opacity:0.5; stroke:blue;" y2="91.7106"/> <line x1="205.1758" x2="261.4262" y1="91.7106" style="clip-path:url(#clipPath4); fill:none; opacity:0.5; stroke:lime;" y2="111.5495"/> <line x1="261.4262" x2="317.6767" y1="179.0017" style="clip-path:url(#clipPath4); fill:none; opacity:0.5;" y2="220.0021"/> <line x1="261.4262" x2="317.6767" y1="91.7106" style="clip-path:url(#clipPath4); fill:none; opacity:0.5; stroke:blue;" y2="235.8732"/> <line x1="261.4262" x2="317.6767" y1="111.5495" style="clip-path:url(#clipPath4); fill:none; opacity:0.5; stroke:lime;" y2="188.2599"/> <line x1="317.6767" x2="373.9271" y1="220.0021" style="clip-path:url(#clipPath4); fill:none; opacity:0.5;" y2="243.8088"/> <line x1="317.6767" x2="373.9271" y1="235.8732" style="clip-path:url(#clipPath4); fill:none; opacity:0.5; stroke:blue;" y2="209.4214"/> <line x1="317.6767" x2="373.9271" y1="188.2599" style="clip-path:url(#clipPath4); fill:none; opacity:0.5; stroke:lime;" y2="141.9691"/>
79
<rect x="53.7783" y="80.6008" width="359.0454" style="clip-path:url(#clipPath1); fill:none; stroke-linejoin:miter; stroke:gray;" height="233.3055"/> </g> </g> </svg>
Código fonte do gráfico de área <?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 1.0//EN' 'http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd'> <svg xmlns:xlink="http://www.w3.org/1999/xlink" style="fill-opacity:1; color-rendering:auto; color-interpolation:auto; stroke:black; text-rendering:auto; stroke-linecap:square; stroke-miterlimit:10; shape-rendering:auto; stroke-opacity:1; fill:black; stroke-dasharray:none; font-weight:normal; stroke-width:1; font-family:'sansserif'; font-style:normal; stroke-linejoin:miter; font-size:12; stroke-dashoffset:0; image-rendering:auto;" xmlns="http://www.w3.org/2000/svg"> <!--Documento gerado por SVGChart - Henrique A. Viecili--> <defs id="genericDefs"/> <g> <defs id="defs1"> <clipPath clipPathUnits="userSpaceOnUse" id="clipPath1"> <path d="M0 0 L480 0 L480 360 L0 360 L0 0 Z"/> </clipPath> <clipPath clipPathUnits="userSpaceOnUse" id="clipPath2"> <path d="M-423.8237 -193.4332 L56.1763 -193.4332 L56.1763 166.5668 L-423.8237 166.5668 L-423.8237 -193.4332 Z"/> </clipPath> <clipPath clipPathUnits="userSpaceOnUse" id="clipPath3"> <path d="M215.8004 178.7066 L215.8004 658.7067 L-144.1996 658.7067 L-144.1996 178.7066 L215.8004 178.7066 Z"/> </clipPath> <clipPath clipPathUnits="userSpaceOnUse" id="clipPath4"> <path d="M53.7783 80.6008 L53.7783 313.9062 L412.8237 313.9062 L412.8237 80.6008 Z"/> </clipPath> </defs> <g style="fill:rgb(50,150,250); text-rendering:optimizeLegibility; stroke:rgb(50,150,250);"> <rect x="0" y="0" width="480" style="clip-path:url(#clipPath1); stroke:none;" height="360"/> </g> <g style="text-rendering:optimizeLegibility; font-size:18; font-weight:bold; font-family:sans-serif;"> <text x="119.959" y="24.8889" style="clip-path:url(#clipPath1); stroke:none;" xml:space="preserve">Exemplo de Gráfico de Área</text> <text x="177.6475" y="49.4215" style="font-size:12; clip-path:url(#clipPath1); stroke:none;" xml:space="preserve">Gráfico de Categorias</text> <text x="196.6465" y="71.3074" style="font-size:12; clip-path:url(#clipPath1); stroke:none;" xml:space="preserve">SVGChart 2004</text> </g>
80
<g transform="translate(423.8237,193.4332)" style="font-size:10; fill:white; text-rendering:optimizeLegibility; font-family:sans-serif; stroke:white;"> <rect x="0" y="0" width="53.1763" style="clip-path:url(#clipPath2); stroke:none;" height="49.7344"/> <rect x="0" y="0" width="53.1763" style="clip-path:url(#clipPath2); fill:none; stroke:gray;" height="49.7344"/> <rect x="3.8867" y="3.8867" width="8.8047" style="clip-path:url(#clipPath2); fill:red; stroke:none;" height="8.8047"/> <text x="16" y="12" style="clip-path:url(#clipPath2); fill:black; stroke:none;" xml:space="preserve">Série 1</text> <rect x="3.8867" y="20.4648" width="8.8047" style="clip-path:url(#clipPath2); fill:blue; stroke:none;" height="8.8047"/> <text x="16" y="28" style="clip-path:url(#clipPath2); fill:black; stroke:none;" xml:space="preserve">Série 2</text> <rect x="3.8867" y="37.043" width="8.8047" style="clip-path:url(#clipPath2); fill:lime; stroke:none;" height="8.8047"/> <text x="16" y="45" style="clip-path:url(#clipPath2); fill:black; stroke:none;" xml:space="preserve">Série 3</text> <rect x="53.7783" y="80.6008" transform="translate(-423.8237,-193.4332)" width="359.0454" style="clip-path:url(#clipPath1); stroke:none;" height="233.3055"/> <line transform="translate(-423.8237,-193.4332)" x1="53.7783" x2="412.8237" y1="313.9062" style="clip-path:url(#clipPath1); fill:none; stroke:gray;" y2="313.9062"/> <text x="83.659" y="327.96" transform="translate(-423.8237,-193.4332)" style="clip-path:url(#clipPath1); fill:black; stroke:none;" xml:space="preserve"> Cat 1</text> </g> <g style="text-rendering:optimizeLegibility; font-size:10; font-family:sans-serif;"> <text x="134.5158" y="327.96" style="clip-path:url(#clipPath1); stroke:none;" xml:space="preserve"> Cat 2</text> </g> <g style="text-rendering:optimizeLegibility; font-size:10; font-family:sans-serif;"> <text x="188.3726" y="327.96" style="clip-path:url(#clipPath1); stroke:none;" xml:space="preserve"> Cat 3</text> </g> <g style="text-rendering:optimizeLegibility; font-size:10; font-family:sans-serif;"> <text x="242.2294" y="327.96" style="clip-path:url(#clipPath1); stroke:none;" xml:space="preserve"> Cat 4</text> </g> <g style="text-rendering:optimizeLegibility; font-size:10; font-family:sans-serif;"> <text x="296.0862" y="327.96" style="clip-path:url(#clipPath1); stroke:none;" xml:space="preserve"> Cat 5</text> </g> <g style="text-rendering:optimizeLegibility; font-size:10; font-family:sans-serif;"> <text x="349.9431" y="327.96" style="clip-path:url(#clipPath1); stroke:none;" xml:space="preserve"> Cat 6</text> </g> <g style="font-family:sans-serif; text-rendering:optimizeLegibility;">
81
<text x="215.9602" y="349.9707" style="clip-path:url(#clipPath1); stroke:none;" xml:space="preserve">Eixo X</text> </g> <g style="fill:gray; text-rendering:optimizeLegibility; font-family:sans-serif; stroke:gray;"> <line x1="53.7783" x2="53.7783" y1="80.6008" style="clip-path:url(#clipPath1); fill:none;" y2="313.9062"/> <text x="42.2168" y="317.6709" style="font-size:10; clip-path:url(#clipPath1); fill:black; stroke:none;" xml:space="preserve">0</text> </g> <g style="fill:gray; text-rendering:optimizeLegibility; font-size:10; font-family:sans-serif; stroke:gray;"> <line x1="51.7783" x2="53.7783" y1="313.9062" style="clip-path:url(#clipPath1); fill:none;" y2="313.9062"/> <text x="36.6553" y="284.6061" style="clip-path:url(#clipPath1); fill:black; stroke:none;" xml:space="preserve">25</text> </g> <g style="fill:gray; text-rendering:optimizeLegibility; font-size:10; font-family:sans-serif; stroke:gray;"> <line x1="51.7783" x2="53.7783" y1="280.8414" style="clip-path:url(#clipPath1); fill:none;" y2="280.8414"/> <text x="36.6553" y="251.5412" style="clip-path:url(#clipPath1); fill:black; stroke:none;" xml:space="preserve">50</text> </g> <g style="fill:gray; text-rendering:optimizeLegibility; font-size:10; font-family:sans-serif; stroke:gray;"> <line x1="51.7783" x2="53.7783" y1="247.7766" style="clip-path:url(#clipPath1); fill:none;" y2="247.7766"/> <text x="36.6553" y="218.4764" style="clip-path:url(#clipPath1); fill:black; stroke:none;" xml:space="preserve">75</text> </g> <g style="fill:gray; text-rendering:optimizeLegibility; font-size:10; font-family:sans-serif; stroke:gray;"> <line x1="51.7783" x2="53.7783" y1="214.7117" style="clip-path:url(#clipPath1); fill:none;" y2="214.7117"/> <text x="31.0938" y="185.4116" style="clip-path:url(#clipPath1); fill:black; stroke:none;" xml:space="preserve">100</text> </g> <g style="fill:gray; text-rendering:optimizeLegibility; font-size:10; font-family:sans-serif; stroke:gray;"> <line x1="51.7783" x2="53.7783" y1="181.6469" style="clip-path:url(#clipPath1); fill:none;" y2="181.6469"/> <text x="31.0938" y="152.3467" style="clip-path:url(#clipPath1); fill:black; stroke:none;" xml:space="preserve">125</text> </g> <g style="fill:gray; text-rendering:optimizeLegibility; font-size:10; font-family:sans-serif; stroke:gray;"> <line x1="51.7783" x2="53.7783" y1="148.5821" style="clip-path:url(#clipPath1); fill:none;" y2="148.5821"/> <text x="31.0938" y="119.2819" style="clip-path:url(#clipPath1); fill:black; stroke:none;" xml:space="preserve">150</text> </g> <g style="fill:gray; text-rendering:optimizeLegibility; font-size:10; font-family:sans-serif; stroke:gray;"> <line x1="51.7783" x2="53.7783" y1="115.5172" style="clip-path:url(#clipPath1); fill:none;" y2="115.5172"/>
82
<text x="31.0938" y="86.2171" style="clip-path:url(#clipPath1); fill:black; stroke:none;" xml:space="preserve">175</text> </g> <g style="fill:gray; text-rendering:optimizeLegibility; font-size:10; font-family:sans-serif; stroke:gray;"> <line x1="51.7783" x2="53.7783" y1="82.4524" style="clip-path:url(#clipPath1); fill:none;" y2="82.4524"/> <text x="14.5449" y="201.7711" transform="matrix(0,-1,1,0,-178.7066,215.8004)" style="font-size:12; clip-path:url(#clipPath3); fill:black; stroke:none;" xml:space="preserve">Y</text> </g> <g style="stroke-linecap:butt; fill:silver; text-rendering:optimizeLegibility; stroke-linejoin:bevel; font-family:sans-serif; stroke-dasharray:2,2; stroke:silver; stroke-width:0.5; stroke-miterlimit:0;"> <line x1="53.7783" x2="412.8237" y1="313.9062" style="clip-path:url(#clipPath1); fill:none;" y2="313.9062"/> <line x1="53.7783" x2="412.8237" y1="280.8414" style="clip-path:url(#clipPath1); fill:none;" y2="280.8414"/> <line x1="53.7783" x2="412.8237" y1="247.7766" style="clip-path:url(#clipPath1); fill:none;" y2="247.7766"/> <line x1="53.7783" x2="412.8237" y1="214.7117" style="clip-path:url(#clipPath1); fill:none;" y2="214.7117"/> <line x1="53.7783" x2="412.8237" y1="181.6469" style="clip-path:url(#clipPath1); fill:none;" y2="181.6469"/> <line x1="53.7783" x2="412.8237" y1="148.5821" style="clip-path:url(#clipPath1); fill:none;" y2="148.5821"/> <line x1="53.7783" x2="412.8237" y1="115.5172" style="clip-path:url(#clipPath1); fill:none;" y2="115.5172"/> <line x1="53.7783" x2="412.8237" y1="82.4524" style="clip-path:url(#clipPath1); fill:none;" y2="82.4524"/> </g> <g style="fill-opacity:0.502; fill:rgb(204,204,204); text-rendering:optimizeLegibility; font-family:sans-serif; stroke:rgb(204,204,204); stroke-opacity:0.502;"> <line x1="53.7783" x2="412.8237" y1="313.9062" style="clip-path:url(#clipPath1); fill:none;" y2="313.9062"/> </g> <g style="fill:red; text-rendering:optimizeLegibility; font-family:sans-serif; stroke-linejoin:bevel; stroke:red;"> <path d="M72 313.9062 L72 313.9062 L99 111.5495 L126 174.3727 L126 313.9062 Z" style="clip-path:url(#clipPath4); opacity:0.5; stroke:none;"/> <path style="fill:blue; clip-path:url(#clipPath4); opacity:0.5; stroke:none;" d="M72 313.9062 L72 313.9062 L99 179.0017 L126 152.5499 L126 313.9062 Z"/> <path style="fill:lime; clip-path:url(#clipPath4); opacity:0.5; stroke:none;" d="M72 313.9062 L72 313.9062 L99 148.5821 L126 184.2921 L126 313.9062 Z"/> <path d="M126 313.9062 L126 174.3727 L153 237.1958 L179 212.7279 L179 313.9062 Z" style="clip-path:url(#clipPath4); opacity:0.5; stroke:none;"/> <path style="fill:blue; clip-path:url(#clipPath4); opacity:0.5; stroke:none;" d="M126 313.9062 L126 152.5499 L153 126.098 L179 134.0336 L179 313.9062 Z"/>
83
<path style="fill:lime; clip-path:url(#clipPath4); opacity:0.5; stroke:none;" d="M126 313.9062 L126 184.2921 L153 220.0021 L179 155.8563 L179 313.9062 Z"/> <path d="M179 313.9062 L179 212.7279 L206 188.2599 L233 183.6308 L233 313.9062 Z" style="clip-path:url(#clipPath4); opacity:0.5; stroke:none;"/> <path style="fill:blue; clip-path:url(#clipPath4); opacity:0.5; stroke:none;" d="M179 313.9062 L179 134.0336 L206 141.9691 L233 116.8398 L233 313.9062 Z"/> <path style="fill:lime; clip-path:url(#clipPath4); opacity:0.5; stroke:none;" d="M179 313.9062 L179 155.8563 L206 91.7106 L233 101.63 L233 313.9062 Z"/> <path d="M233 313.9062 L233 183.6308 L260 179.0017 L287 199.5019 L287 313.9062 Z" style="clip-path:url(#clipPath4); opacity:0.5; stroke:none;"/> <path style="fill:blue; clip-path:url(#clipPath4); opacity:0.5; stroke:none;" d="M233 313.9062 L233 116.8398 L260 91.7106 L287 163.7919 L287 313.9062 Z"/> <path style="fill:lime; clip-path:url(#clipPath4); opacity:0.5; stroke:none;" d="M233 313.9062 L233 101.63 L260 111.5495 L287 149.9047 L287 313.9062 Z"/> <path d="M287 313.9062 L287 199.5019 L314 220.0021 L341 231.9055 L341 313.9062 Z" style="clip-path:url(#clipPath4); opacity:0.5; stroke:none;"/> <path style="fill:blue; clip-path:url(#clipPath4); opacity:0.5; stroke:none;" d="M287 313.9062 L287 163.7919 L314 235.8732 L341 222.6473 L341 313.9062 Z"/> <path style="fill:lime; clip-path:url(#clipPath4); opacity:0.5; stroke:none;" d="M287 313.9062 L287 149.9047 L314 188.2599 L341 165.1145 L341 313.9062 Z"/> <path d="M341 313.9062 L341 231.9055 L368 243.8088 L395 313.9062 L395 313.9062 Z" style="clip-path:url(#clipPath4); opacity:0.5; stroke:none;"/> <path style="fill:blue; clip-path:url(#clipPath4); opacity:0.5; stroke:none;" d="M341 313.9062 L341 222.6473 L368 209.4214 L395 313.9062 L395 313.9062 Z"/> <path style="fill:lime; clip-path:url(#clipPath4); opacity:0.5; stroke:none;" d="M341 313.9062 L341 165.1145 L368 141.9691 L395 313.9062 L395 313.9062 Z"/> <rect x="53.7783" y="80.6008" width="359.0454" style="clip-path:url(#clipPath1); fill:none; stroke-linejoin:miter; stroke:gray;" height="233.3055"/> </g> </g> </svg>
84
11.2 Código Fonte da Aplicação Exemplo
Página index.jsp <%@ page contentType="text/html;charset=windows-1252"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=windows-
1252">
<title>SVG Chart</title>
<link href="css/jdeveloper.css" rel="stylesheet" media="screen"/>
</head>
<body>
<table cellspacing="0" cellpadding="0" border="0" width="90%"
align="center">
<tr>
<td> </td>
<td>
<H1 align="center"><FONT face="Verdana">SVG Chart</FONT></H1>
</td>
<td> </td>
</tr>
<tr>
<td> </td>
<td>
<form action="svgchartservlet" method="POST"
enctype="multipart/form-data">
<H3>Informe o arquivo XML com a definição dos
dados:
<BR/>
<input type="file" name="xmlfile" style="width:60%"/>
</H3>
<P align="right">
<input type="SUBMIT" value="Gerar Gráfico"/>
</P>
</form>
</td>
<td> </td>
85
</tr>
<tr>
<td> </td>
<td> </td>
<td> </td>
</tr>
</table>
</body>
</html>
Código fonte da folha de estilos BODY, P, LI, UL, OL { font-family: Arial, Helvetica, sans-serif; font-size: 97%; color:#000000; list-style-position: outside; } A:link { font-family: Arial, Helvetica, sans-serif; color:#663300; } A:active { font-family: Arial, Helvetica, sans-serif; color:#ff6600; } A:visited { font-family: Arial, Helvetica, sans-serif; color:#996633; } A.navigation:link { font-family: Arial, Helvetica, sans-serif; font-size:65%; color:#996633; } A.navigation:active { font-family: Arial, Helvetica, sans-serif; font-size:65%; color:#996633; }
86
A.navigation:visited { font-family: Arial, Helvetica, sans-serif; font-size:65%; color:#996633; } p.listpara {text-indent: 15%} H1 { font-family: Arial, Helvetica, sans-serif; font-size:170%; color:#336699; border : solid #CCCC99; width : 100%; border-width : 0px 0px 2px 0px; } H2 { font-family: Arial, Helvetica, sans-serif; font-size:130%; color:#336699; border : solid #cccc99; border-width : 0px 0px 2px 0px; width : 100%; } H3 { font-family: Arial, Helvetica, sans-serif; font-size:110%; color:#336699; width : 100%; } H4 { font-family: Arial, Helvetica, sans-serif; font-size:92%; color:#000000; font-weight: bold; width : 100%; } .code_no_color { color : #000000; font-family : "Courier New", "Courier", "monospace"; } code { color : #336699; font-family : "Courier New", "Courier", "monospace"; } P.indent { text-indent: 9%; }
87
table.borders { border : 1% solid #BDB76B; } TR { text-align : left; vertical-align : top; } TH { font-family: Arial, Helvetica, sans-serif; font-size: 11pt; color:#000000; font-weight: bold; } TD { font-family: Arial, Helvetica, sans-serif; font-size: 11pt%; color:#000000; } .smalltext { font-size:80%; } p.note { display: block; font-family: Arial, Helvetica, Geneva, sans-serif; font-size: 95%; } p.warning { display: block; font-family: Arial, Helvetica, Geneva, sans-serif; font-size: 95%; } pre { font-family: "Courier New", Courier, mono; font-size: 92%; text-indent : 15%; } .GUITag { font-family: Arial, Helvetica, Geneva, sans-serif; font-size: 95%; font-weight: bold; font-style: normal; } .PropertyName { font-family: "Courier New", Courier, mono; font-style: normal; } .GlossaryItem {
88
color : #008080; font-family: Arial, Helvetica, sans-serif; font-size : 95%; }
Código fonte do arquivo de configuração web (web.xml) <?xml version = '1.0' encoding = 'windows-1252'?> <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd"> <web-app> <description>Empty web.xml file for Web Application</description> <servlet> <servlet-name>SVGChartServlet</servlet-name> <servlet-class>br.ufsc.inf.viecili.svgchart.servlet.SVGChartServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>SVGChartServlet</servlet-name> <url-pattern>/svgchartservlet</url-pattern> </servlet-mapping> <session-config> <session-timeout>35</session-timeout> </session-config> <mime-mapping> <extension>html</extension> <mime-type>text/html</mime-type> </mime-mapping> <mime-mapping> <extension>txt</extension> <mime-type>text/plain</mime-type> </mime-mapping> <welcome-file-list> <welcome-file>index.jsp</welcome-file> <welcome-file>index.html</welcome-file> </welcome-file-list> </web-app>
Código fonte do servlet package br.ufsc.inf.viecili.svgchart.servlet; import br.ufsc.inf.viecili.svgchart.SVGChart; import java.util.Iterator; import javax.servlet.*; import javax.servlet.http.*; import java.io.PrintWriter; import java.io.IOException; import org.apache.commons.fileupload.*; public class SVGChartServlet extends HttpServlet { private static final String CONTENT_TYPE = "image/svg+xml"; public static final int MAX_MEMORY_SIZE = 10240000;//10MBytes public static final int MAX_REQUEST_SIZE = 3072000;//3MBytes public static final String TEMP_DIR = System.getProperty("user.home");
89
public void init(ServletConfig config) throws ServletException { super.init(config); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType(CONTENT_TYPE); PrintWriter out = response.getWriter(); try { if(FileUpload.isMultipartContent(request)) { DiskFileUpload xmlfile = new DiskFileUpload(); Iterator itensfile = xmlfile.parseRequest(request, MAX_MEMORY_SIZE, MAX_REQUEST_SIZE, TEMP_DIR).iterator(); while(itensfile.hasNext()) { FileItem item = (FileItem) itensfile.next(); boolean hasFile = false; if(!item.isFormField()) { hasFile = true; if(item.getContentType().equals("text/xml")) { //executar o parsing e receber o arquivo svg SVGChart svgchart = new SVGChart(); svgchart.setDataContent(item.getString()); String grafico = svgchart.getSVGChartContent(); out.print(grafico); } else { response.sendError(response.SC_BAD_REQUEST); } } } } else { response.sendError(response.SC_BAD_REQUEST); } } catch(Exception e) { e.printStackTrace(); response.sendError(response.SC_BAD_REQUEST); } out.close(); } }
90
11.3 Código Fonte
11.3.1 Pacote br.ufsc.inf.viecili.svgchart
Classe SVGChart package br.ufsc.inf.viecili.svgchart; import br.ufsc.inf.viecili.svgchart.parser.*; import java.io.File; import java.io.Serializable; public class SVGChart extends java.lang.Object implements Serializable { private String xmlContent; private File xmlFile; public SVGChart() { xmlContent = ""; xmlFile = null; } public void setDataFile(File xmlFile) { this.xmlFile = xmlFile; } public void setDataContent(String xmlContent) { this.xmlContent = xmlContent; } public File getDataFile() { return xmlFile; } public String getDataContent() { return xmlContent; } public File getSVGChartFile() throws SVGChartException { try { return new XMLHandler().parse(this.xmlFile); } catch (Exception e) { e.printStackTrace(); throw new SVGChartException(e); } } public String getSVGChartContent() throws SVGChartException { try { return new XMLHandler().parse(this.xmlContent); } catch (Exception e) { e.printStackTrace(); throw new SVGChartException(e); } } }
91
Classe SVGChartException package br.ufsc.inf.viecili.svgchart; public class SVGChartException extends Exception { public SVGChartException() { super(); } public SVGChartException(String msg) { super(msg); } public SVGChartException(Throwable cause) { super(cause); } public SVGChartException(String msg, Throwable cause) { super(msg, cause); } }
11.3.2 Pacote br.ufsc.inf.viecili.svgchart.data
Classe SVGChartDataset package br.ufsc.inf.viecili.svgchart.data; import org.jfree.chart.JFreeChart; import java.util.ArrayList; public interface SVGChartDataset { public static final String GROUPED_COLUMN_CHART = "groupedColumnChart"; public static final String GROUPED_BAR_CHART = "groupedBarChart"; public static final String LINE_CHART = "lineChart"; public static final String PIZZA_CHART = "pizzaChart"; public static final String SCATTER_CHART = "scatterChart"; public static final String AREA_CHART = "areaChart"; public static final String BOX_PLOT_CHART = "boxPlotChart"; public static final String SUBTITLE_DELIM = ";;"; public void setDataFields(ArrayList dataFields); public void addDataRow(ArrayList dataRow, String rowName); public JFreeChart getChart(int columnCount); public void setTitle(String title); public void setXAxisTitle(String xAxisTitle); public void setYAxisTitle(String yAxisTitle); public void setDesc(String desc); public void setColumnCount(int columnCount); }
92
Classe SVGChartDatasetFactory package br.ufsc.inf.viecili.svgchart.data; public class SVGChartDatasetFactory { SVGChartDataset dataset; public static SVGChartDataset createDefaultDataset() { return new SVGCategoryChartDataset(SVGChartDataset.GROUPED_COLUMN_CHART); } public static SVGChartDataset createDataset(String chartType) { if(chartType.equals(SVGChartDataset.PIZZA_CHART)) return new SVGPizzaChartDataset(chartType); else if(chartType.equals(SVGChartDataset.SCATTER_CHART)) return new SVGScatterChartDataset(chartType); else return new SVGCategoryChartDataset(chartType); } }
Classe SVGPizzaChartDataset package br.ufsc.inf.viecili.svgchart.data; import java.awt.Color; import java.util.StringTokenizer; import org.jfree.chart.*; import org.jfree.chart.labels.StandardPieItemLabelGenerator; import org.jfree.chart.plot.*; import org.jfree.data.*; import java.util.ArrayList; import java.util.HashMap; import org.jfree.chart.JFreeChart; import org.jfree.data.PieDataset; public class SVGPizzaChartDataset implements SVGChartDataset { private String chartType; private PieDataset dataset; private HashMap chartData; private ArrayList orderedKeys; private ArrayList dataFields; private String title; private int columnCount; private String desc; public SVGPizzaChartDataset(String chartType) { this.chartType = chartType; chartData = new HashMap(); orderedKeys = new ArrayList(); dataFields = new ArrayList(); title = ""; desc = ""; columnCount = Integer.MAX_VALUE; }
93
public JFreeChart getChart(int columnCount) { setColumnCount(columnCount); ajustaDataFields(); montaDataset(); JFreeChart chart = ChartFactory.createPieChart(title,dataset,true,true,false); chart.setSubtitles(getSubtitles()); PiePlot pplot = (PiePlot) chart.getPlot(); pplot.setSectionLabelType(PiePlot.NAME_AND_PERCENT_LABELS); pplot.setItemLabelGenerator(new StandardPieItemLabelGenerator()); chart.setBackgroundPaint(new Color(50,150,250)); chart.setLegend(null); return chart; } public void addDataRow(ArrayList dataRow, String rowName) { orderedKeys.add(rowName); chartData.put(rowName,dataRow); } public void setDataFields(ArrayList dataFields) { this.dataFields = dataFields; } public void setTitle(String title) { this.title = title; } public void setXAxisTitle(String xAxisTitle) { } public void setYAxisTitle(String yAxisTitle) { } public void setDesc(String desc) { this.desc = desc; } public void setColumnCount(int columnCount) { this.columnCount = columnCount; } private void ajustaDataFields() { int dfCount = dataFields.size(); if(columnCount > dfCount) { int dif = columnCount - dfCount; for(int i = 1; i <= dif; i++) { dataFields.add(new String("c"+String.valueOf(i))); } } } private void montaDataset() { DefaultPieDataset dset = new DefaultPieDataset(); int nrows = orderedKeys.size(); for (int i = 0; i < nrows; i++) { ArrayList linha = (ArrayList) chartData.get(orderedKeys.get(i));
94
for (int j = 0; j < dataFields.size(); j++) { Double valor; String nmCampo; try { valor = Double.valueOf((String)linha.get(j)); nmCampo = (String) dataFields.get(j); } catch (Exception e) { valor = null; nmCampo = "c"+String.valueOf(j); } dset.setValue(nmCampo,valor); } } dataset = dset; } private ArrayList getSubtitles() { StringTokenizer stk = new StringTokenizer(this.desc,SVGChartDataset.SUBTITLE_DELIM); ArrayList subs = new ArrayList(); while(stk.hasMoreTokens()) { subs.add(new TextTitle(stk.nextToken())); } return subs; } }
Classe SVGScatterChartDataset package br.ufsc.inf.viecili.svgchart.data; import java.awt.Color; import java.util.StringTokenizer; import org.jfree.chart.*; import java.util.ArrayList; import java.util.HashMap; import org.jfree.chart.axis.*; import org.jfree.chart.plot.*; import org.jfree.chart.renderer.*; import org.jfree.data.*; import org.jfree.ui.ApplicationFrame; import org.jfree.chart.JFreeChart; public class SVGScatterChartDataset extends AbstractSeriesDataset implements SVGChartDataset, XYDataset { public static final String XY_DELIM = ","; private String chartType; private HashMap chartData; private ArrayList orderedKeys; private ArrayList dataFields; private String title; private String xAxisTitle; private String yAxisTitle; private int columnCount; private String desc;
95
public SVGScatterChartDataset(String chartType) { this.chartType = chartType; chartData = new HashMap(); orderedKeys = new ArrayList(); dataFields = new ArrayList(); title = ""; desc = ""; columnCount = 200; xAxisTitle = "X"; yAxisTitle = "Y"; } public void addDataRow(ArrayList dataRow, String rowName) { orderedKeys.add(rowName); chartData.put(rowName,dataRow); } public JFreeChart getChart(int columnCount) { setColumnCount(columnCount); JFreeChart chart = ChartFactory.createScatterPlot(this.title,this.xAxisTitle,this.yAxisTitle,this,PlotOrientation.VERTICAL,true,true,false); chart.setSubtitles(getSubtitles()); chart.setBackgroundPaint(new Color(50,150,250)); XYPlot plot = (XYPlot) chart.getPlot(); Legend legend = chart.getLegend(); legend.setAnchor(legend.EAST); if (legend instanceof StandardLegend) { StandardLegend sl = (StandardLegend) legend; sl.setDisplaySeriesShapes(true); } NumberAxis domainAxis = (NumberAxis) plot.getDomainAxis(); domainAxis.setAutoRangeIncludesZero(false); return chart; } public void setDataFields(ArrayList dataFields) { this.dataFields = dataFields; } public void setTitle(String title) { this.title = title; } public void setXAxisTitle(String xAxisTitle) { this.xAxisTitle = xAxisTitle; } public void setYAxisTitle(String yAxisTitle) { this.yAxisTitle = yAxisTitle; } public void setDesc(String desc) { this.desc = desc; }
96
public void setColumnCount(int columnCount) { this.columnCount = columnCount; } public Number getXValue(int series, int item) { Double valor; try { ArrayList xValues = (ArrayList) chartData.get(orderedKeys.get(series)); StringTokenizer stk = new StringTokenizer(((String)xValues.get(item)),this.XY_DELIM); valor = Double.valueOf(stk.nextToken()); } catch (Exception e) { valor = null; } return valor; } public Number getYValue(int series, int item) { Double valor; try { ArrayList yValues = (ArrayList) chartData.get(orderedKeys.get(series)); StringTokenizer stk = new StringTokenizer(((String)yValues.get(item)),this.XY_DELIM); String yValue = null; while(stk.hasMoreTokens()) yValue = stk.nextToken(); valor = Double.valueOf(yValue); } catch (Exception e) { valor = null; } return valor; } public int getItemCount(int series) { return ((ArrayList)chartData.get(orderedKeys.get(series))).size(); } public String getSeriesName(int series) { return (String) orderedKeys.get(series); } public int getSeriesCount() { return this.orderedKeys.size(); } private ArrayList getSubtitles() { StringTokenizer stk = new StringTokenizer(this.desc,SVGChartDataset.SUBTITLE_DELIM); ArrayList subs = new ArrayList(); while(stk.hasMoreTokens()) { subs.add(new TextTitle(stk.nextToken())); } return subs; } }
97
Classe SVGCategoryChartDataset package br.ufsc.inf.viecili.svgchart.data; import java.awt.Color; import java.util.StringTokenizer; import java.util.ArrayList; import java.util.HashMap; import org.jfree.chart.*; import org.jfree.chart.axis.*; import org.jfree.chart.plot.*; import org.jfree.data.*; import org.jfree.text.*; import org.jfree.ui.*; public class SVGCategoryChartDataset implements SVGChartDataset { private String chartType; private HashMap chartData; private CategoryDataset dataset; private ArrayList orderedKeys; private ArrayList dataFields; private String title; private String xAxisTitle; private String yAxisTitle; private int columnCount; private String desc; public SVGCategoryChartDataset(String chartType) { this.chartType = chartType; chartData = new HashMap(); orderedKeys = new ArrayList(); dataFields = new ArrayList(); title = ""; xAxisTitle = ""; yAxisTitle = ""; columnCount = 200; desc = ""; } public void addDataRow(ArrayList dataRow, String rowName) { orderedKeys.add(rowName); chartData.put(rowName,dataRow); } public JFreeChart getChart(int columnCount) { setColumnCount(columnCount); ajustaDataFields(); montaDataset(); JFreeChart chart; if(this.chartType.equals(SVGChartDataset.AREA_CHART)) { chart = ChartFactory.createAreaChart(this.title,this.xAxisTitle,this.yAxisTitle,this.dataset,PlotOrientation.VERTICAL,true,true,false); } else if(this.chartType.equals(SVGChartDataset.GROUPED_BAR_CHART)) {
98
chart = ChartFactory.createBarChart(this.title,this.xAxisTitle,this.yAxisTitle,this.dataset,PlotOrientation.HORIZONTAL,true,true,false); } else if(this.chartType.equals(SVGChartDataset.LINE_CHART)) { chart = ChartFactory.createLineChart(this.title,this.xAxisTitle,this.yAxisTitle,this.dataset,PlotOrientation.VERTICAL,true,true,false); } else {//Column_Chart (default) chart = ChartFactory.createBarChart(this.title,this.xAxisTitle,this.yAxisTitle,this.dataset,PlotOrientation.VERTICAL,true,true,false); } chart.setSubtitles(getSubtitles()); chart.setBackgroundPaint(new Color(50,150,250)); StandardLegend legend = (StandardLegend) chart.getLegend(); legend.setAnchor(Legend.EAST); CategoryPlot cplot = (CategoryPlot) chart.getPlot(); cplot.setForegroundAlpha(0.5f); return chart; } public void setDataFields(ArrayList dataFields) { this.dataFields = dataFields; } public void setTitle(String title) { this.title = title; } public void setXAxisTitle(String xAxisTitle) { this.xAxisTitle = xAxisTitle; } public void setYAxisTitle(String yAxisTitle) { this.yAxisTitle = yAxisTitle; } public void setDesc(String desc) { this.desc = desc; } public void setColumnCount(int columnCount) { this.columnCount = columnCount; } private void ajustaDataFields() { int dfCount = dataFields.size(); if(columnCount > dfCount) { int dif = columnCount - dfCount; for(int i = 1; i <= dif; i++) { dataFields.add(new String("c"+String.valueOf(i))); } } } private ArrayList getSubtitles() {
99
StringTokenizer stk = new StringTokenizer(this.desc,SVGChartDataset.SUBTITLE_DELIM); ArrayList subs = new ArrayList(); while(stk.hasMoreTokens()) { subs.add(new TextTitle(stk.nextToken())); } return subs; } public void montaDataset() { DefaultCategoryDataset dset = new DefaultCategoryDataset(); for (int i = 0; i < orderedKeys.size(); i++) { ArrayList serie = (ArrayList) chartData.get(orderedKeys.get(i)); for (int j = 0; j < dataFields.size(); j++) { Double valor; String nmCampo; try { valor = Double.valueOf((String)serie.get(j)); nmCampo = (String) dataFields.get(j); } catch (Exception e) { valor = null; nmCampo = "c"+String.valueOf(j); } dset.addValue(valor,(String)orderedKeys.get(i),nmCampo); } } dataset = dset; } }
11.3.3 Pacote br.ufsc.inf.viecili.svgchart.parser
Classe XMLHandler package br.ufsc.inf.viecili.svgchart.parser; import br.ufsc.inf.viecili.svgchart.*; import br.ufsc.inf.viecili.svgchart.data.*; import java.awt.Rectangle; import java.io.*; import java.util.ArrayList; import javax.xml.parsers.SAXParserFactory; import org.jfree.chart.ChartFactory; import org.jfree.chart.JFreeChart; import org.jfree.data.Dataset; import org.xml.sax.helpers.DefaultHandler; import org.xml.sax.SAXException; import org.xml.sax.Attributes; import org.w3c.dom.Document; import org.apache.batik.svggen.*; import org.apache.batik.dom.GenericDOMImplementation; import java.io.File; public class XMLHandler extends DefaultHandler {
100
private SAXParserFactory factory; private SVGChartDataset dataset; private JFreeChart chart; private int svgWidth; private int svgHeight; private static final String TABLE_TAG = "TABLE"; private static final String DESC_TAG = "DESC"; private static final String TR_TAG = "TR"; private static final String TD_TAG = "TD"; private static final String DATA_FIELD_ROW_TYPE = "dataField"; public static final int DEFAULT_SVG_HEIGHT = 640; public static final int DEFAULT_SVG_WIDTH = 480; private String tagAtual; private String chartType; private boolean isDataFieldRow; private boolean podeLer; private ArrayList row; private int rowCount; private int columnCount; private String rowName; private String readBuffer; private int nMaxColunas; public XMLHandler() { super(); factory = SAXParserFactory.newInstance(); factory.setValidating(true); dataset = null; chart = null; svgWidth = this.DEFAULT_SVG_WIDTH; svgHeight = this.DEFAULT_SVG_HEIGHT; isDataFieldRow = false; podeLer = false; rowCount = 0; rowName = ""; readBuffer = ""; columnCount = 0; nMaxColunas = 0; } public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { String eName = localName; if("".equals(eName)) eName = qName; eName = eName.toUpperCase(); if(eName.equals(this.TABLE_TAG)) { podeLer = false; tagAtual = this.TABLE_TAG; dataset = SVGChartDatasetFactory.createDataset(attributes.getValue("type")); dataset.setTitle(attributes.getValue("name")); dataset.setXAxisTitle(attributes.getValue("xAxisLabel")); dataset.setYAxisTitle(attributes.getValue("yAxisLabel")); try {
101
this.svgWidth = Integer.parseInt(attributes.getValue("svgWidth")); } catch (Exception e) { this.svgWidth = this.DEFAULT_SVG_WIDTH; } try { this.svgHeight = Integer.parseInt(attributes.getValue("svgHeight")); } catch (Exception e) { this.svgHeight = this.DEFAULT_SVG_HEIGHT; } } else if(eName.equals(this.TR_TAG)) { podeLer = false; tagAtual = this.TR_TAG; columnCount = 0; isDataFieldRow = attributes.getValue("type").equals(this.DATA_FIELD_ROW_TYPE); if(!isDataFieldRow) rowCount++; row = new ArrayList(); rowName = (attributes.getValue("name") != null && !("".equals(attributes.getValue("name")))) ? attributes.getValue("name") : String.valueOf(rowCount) ; } else if(eName.equals(this.TD_TAG)) { podeLer = true; tagAtual = this.TD_TAG; columnCount++; nMaxColunas = (nMaxColunas < columnCount) ? columnCount : nMaxColunas; } else if(eName.equals(this.DESC_TAG)) { podeLer = true; tagAtual = this.DESC_TAG; } } public void characters(char[] ch, int start, int length) throws SAXException { String cont = new String(ch,start,length); if(podeLer) { readBuffer += cont; } } public void endElement(String uri, String localName, String qName) throws SAXException { String eName = localName; if("".equals(eName)) eName = qName; eName = eName.toUpperCase(); if(eName.equals(this.DESC_TAG)) { dataset.setDesc(readBuffer); readBuffer = new String(""); } else if(eName.equals(this.TD_TAG)) { row.add(readBuffer); readBuffer = new String(""); } else if(eName.equals(this.TR_TAG)) { if(isDataFieldRow) { dataset.setDataFields(row);
102
} else { dataset.addDataRow(row,rowName); } } else if(eName.equals(this.TABLE_TAG)) { chart = dataset.getChart(columnCount); } } public String parse(String xmlContent) throws XMLHandlerException { String result = ""; try { File xmlFile = File.createTempFile(("~SVGChart-"+String.valueOf(System.currentTimeMillis())),(".xml")); FileOutputStream fos = new FileOutputStream(xmlFile); fos.write(xmlContent.getBytes()); fos.flush(); fos.close(); fos = null; File svgFile = parse(xmlFile); BufferedReader fr = new BufferedReader(new FileReader(svgFile)); String line = fr.readLine(); while(line != null) { result += line; line = fr.readLine(); } fr.close(); fr = null; xmlFile.delete(); svgFile.delete(); return result; } catch (Exception e) { e.printStackTrace(); throw new XMLHandlerException(e); } } public File parse(File xmlFile) throws XMLHandlerException { try{ factory.newSAXParser().parse(xmlFile ,this); Document document = GenericDOMImplementation.getDOMImplementation().createDocument(null,"svg",null); SVGGeneratorContext ctx = SVGGeneratorContext.createDefault(document); SVGGraphics2D svg = new SVGGraphics2D(document); svg.getGeneratorContext().setComment("Documento gerado por SVGChart - Henrique A. Viecili"); chart.draw(svg, new Rectangle(0,0,svgWidth,svgHeight)); File svgFile = File.createTempFile(("~SVGChart-"+String.valueOf(System.currentTimeMillis())),(".svg")); OutputStreamWriter fw = new OutputStreamWriter(new FileOutputStream(svgFile), "iso-8859-1"); svg.stream(fw,true); fw.flush(); fw.close(); fw = null;
103
return svgFile; } catch (Exception e) { e.printStackTrace(); throw new XMLHandlerException(e); } } }
Classe XMLHandlerException package br.ufsc.inf.viecili.svgchart.parser; public class XMLHandlerException extends Exception { public XMLHandlerException() { } public XMLHandlerException(String msg) { super(msg); } public XMLHandlerException(Throwable cause) { super(cause); } public XMLHandlerException(String msg, Throwable cause) { super(msg, cause); } }
104
SVGChart Geração de Gráficos Estatísticos como
Gráficos Vetoriais Escaláveis a partir de Dados em XML
Henrique Andrade Viecili1
1Ciências da Computação, 8ª. Fase, 2003, Depto de Informática e Estatística
Universidade Federal de Santa Catarina (UFSC), Brasil, 88040-900 Fone (0XX48)331-9000
Resumo Este artigo apresenta uma visão geral sobre o trabalho de conclusão de curso de Ciências da Computação da Universidade Federal de Santa Catarina, feito por Henrique Andrade Viecili, entitulado “Geração de Gráficos Estatísticos como Gráficos Vetoriais Escaláveis a partir de Dados em XML” [5]. Será descrita a ferramenta SVGChart desenvolvida no projeto e as tecnologias relacionadas com sua criação. Palavras Chave: SVG, XML, JAVA, JFreeChart, Batik SVG Toolkit, Gráficos Estatísticos, Gráficos Vetoriais Escaláveis.
Abstract This article presents an overview on the Federal University of Santa Catarina’s Computer Sciences’ end-course work, done by Henrique Andrade Viecili, titled “Geração de Gráficos Estatísticos como Gráficos Vetoriais Escaláveis a partir de Dados em XML” [5]. The SVGChart tool and its creation-related technologies will be described along the article. Key-words: SVG, XML, JAVA, JFreeChart, Batik SVG Toolkit, Statistical Charts, Scalable Vector Graphics.
Introdução
Muito se produz atualmente com base nos novos padrões que vêm surgindo com os contínuos avanços no campo das tecnologias ligadas ao conteúdo apresentado na Web. Entretanto, o aparecimento destes novos padrões é maior do que o surgimento de aplicações que os englobe, isto cria lacunas que
possibilitam a criação de novas aplicações que executem e unam as novas tecnologias, preenchendo este espaço.
A ferramenta SVGChart foi criada com o objetivo de unir, de uma forma genérica e funcional, a descrição de dados estatísticos em XML e sua apresentação gráfica em um documento SVG. Sendo que a sua principal funcionalidade é tomar os dados estatísticos em XML e
1
transformá-los em gráficos vetoriais escaláveis em SVG através de um conjunto de classes desenvolvidas em Java e as bibliotecas do JFreeChart [1] e do Batik SVG Toolkit [2].
XML
XML — eXtensible Markup Language — é uma linguagem de marcação que usa um formato de representação de dados em documento de uma forma mais amigável para sua utilização na internet, recomendada pelo World Wide Web Consortium (W3C) [4] em 1998. XML tem suas raízes numa outra linguagem de marcação chamada SGML (Standard Generalized Markup Language), e é usada para simplificar e dar maior flexibilidade às aplicações.
SVG Scalable Vector Graphics (SVG),
em português, “Gráficos Vetoriais Escaláveis”, é uma aplicação de XML que torna possível representar informação gráfica de uma forma compacta e portável.[3]
Em 1998, o W3C formou um grupo para desenvolver uma representação de gráficos vetoriais como uma aplicação XML. Uma vez que SVG é uma aplicação XML, a informação sobre a imagem é armazenada em texto puro, e traz as vantagens de liberdade, transportabilidade e interoperabilidade do XML.
Com isso, SVG pode cooperar com outras aplicações XML, como por exemplo, um sistema matemático de equações onde o SVG gere os gráficos para as equações. E é neste ponto que este
trabalho é focado, “o uso do SVG como forma de apresentação dos dados”.
Gráficos Vetoriais: a imagem é descrita como uma coleção de formas geométricas que contêm o conjunto de instruções necessárias para o desenho. Os usos mais comuns de gráficos vetoriais são em programas CAD (Computer Assisted Drafting), impressoras de alta resolução, animações e apresentações, principalmente pela facilidade de transformar e visualizar em alta definição esses gráficos.
Estrutura da Aplicação
O processo de geração dos gráficos pelo SVGChart [5] é ilustrado na figura abaixo:
Existe uma unidade centralizadora
que gerencia todo o processo de geração dos gráficos, a classe XMLHandler.
O processo consiste no envio dados estatísticos na forma de um documento XML que é processado e manipulado, a fim de converter estes dados em objetos Java que representem o conjunto das estruturas destes dados.
Após este processo de análise, manipulação e conversão, os objetos criados são passados pelo JFreeChart — biblioteca Java para criação de gráficos
2
3
estatísticos como objetos Java2D — para que sejam criados os gráficos estatísticos.
Posteriormente, utilizando-se das ferramentas do Batik SVG Toolkit, faz-se a conversão destes objetos Java2D para um documento SVG, que será devolvido ao usuário como a representação gráfica dos dados fornecidos como entrada no documento XML.
Com a ferramenta desenvolvida é possível gerar seis tipos de gráficos estatísticos: Gráfico de Pizza, de Dispersão, de Colunas, de Barras, de Linhas, e de Área.
Discussão e Conclusão
Como foi visto, a ferramenta
desenvolvida une as mais novas tecnologias de armazenamento (XML) e representação gráfica (SVG) de dados de uma forma genérica e funcional, onde o usuário tem como único trabalho organizar os dados estatísticos dentro de um arquivo e solicitar a geração do gráfico.
Na conclusão do projeto foi possível observar a importância dos novos padrões para o desenvolvimento de novas tecnologias, sendo indispensável que exista um constante aprendizado por parte de quem deseja dominar este meio.
Bibliografia
[1] WWW.JFREE.ORG. JFreeChart. Disponível em: <http://www.jfree.org/jfreechart/>. Acessado em: 8 jan 2004.
[2] THE APACHE XML PROJECT.
Batik SVG Toolkit. Disponível em: <http://xml.apache.org/batik/>. Acessado em: 9 jan 2004.
[3] WORLD WIDE WEB
CONSORTIUM (W3C). Scalable Vector Graphics (SVG). Disponível em: <http://www.w3.org/Graphics/SVG/> Acessado em: 17 jan. 2004.
[4] WORLD WIDE WEB
CONSORTIUM (W3C). Extensible Markup Language (XML). Disponível em: <http://www.w3.org/XML/> Acessado em: 17 jan. 2004.
[5] VIECILI, Henrique. Geração de
Gráficos Estatísticos como Gráficos Vetoriais Escaláveis a partir de Dados em XML. 2004. 105f. Trabalho de Conclusão de Curso (Graduação) - Ciências da Computação, Universidade Federal de Santa Catarina. Florianópolis. 2004.