Alguns anos atrás, trabalhei para um cliente que gerava uma ampla gama de feeds da dados relacionados a esportes. Precisávamos criar uma maneira de demonstrar a amplitude e profundidade do produto de serviços de dados do cliente e decidimos usar uma analogia de placar que poderia ser colocada no Web site do cliente. A ideia era que mostrar as estatísticas chave dos esportes, como "gols de futebol marcados", "corridas de cavalo realizadas" ou "número de corridas no críquete" —tudo atualizado em tempo real —teria o efeito desejado e transmitiria a qualidade dos serviços de dados do cliente a consumidores em potencial.
Como essa pontuação específica foi desenvolvida não é o foco deste artigo, no entanto, eu conto somente porque uma coisa peculiar ocorreu após o widget ter sido implementado.
Após a pontuação estar em uso, o gerenciamento sênior do cliente começou a fazer perguntas sobre os números gerados. Inicialmente, essas perguntas eram em torno da correção de nossas adições, em seguida, elas se tornaram mais introspectivas, como: "Deveríamos ter mais gols de futebol apresentados" ou "Por que a velocidade de atualização em dias com muitos esportes é mais lenta do que a esperada?" Os diversos números gerados se tornaram avaliações de desempenho efetivas da qualidade e do funcionamento geral dos feeds de dados relacionados a esportes do cliente.
Como o aplicativo de pontuação era atualizado a cada segundo aproximadamente, retransmitia uma pulsação da empresa à gerência sênior, que rapidamente identificava qualquer irregularidade. É claro que o que havíamos feito não era nada de novo—apenas uma reformulação do conceito de desenvolvimento de um painel de KPIs —mas foi necessária uma iniciativa de marketing para criá-lo.
Em círculos de desenvolvimento corporativo, durante um período de tempo, painéis eram o assunto de uma publicidade considerável, portanto, deixe-me tentar fornecer uma definição informal para o uso dos mesmos neste artigo:
Um painel é uma exibição visual de informações importantes necessárias para atingir um ou mais objetivos, consolidadas e organizadas preferivelmente em uma única tela, permitindo que as informações sejam compreendidas com uma visão rápida.
Os objetivos e tipos de dados podem ser divididos em três categorias:
- Estratégico. Os objetivos estratégicos tendem a ser aquelas coisas que interessam executivos e tomadores de decisão chaves de uma empresa, que estão sempre tentando obter um melhor entendimento do que está acontecendo no chão de fábrica para que tenham uma sensação mais intuitiva do funcionamento geral da empresa.
- Analítico. Objetivos que giram em torno de inferir e identificar tendências são de natureza mais analítica.
- Operacional. Dados operacionais surgem quando se monitora diretamente o estado de um processo; exemplos desse tipo de dados são: "O Web site está em execução?" ou "Nosso formulário de e-mail de contato está funcionando?"
Além das categorias acima, os painéis nos quais trabalhei ou vi tendem a ter alguns pontos em comum, como com que frequência são atualizados ou se apresentam dados quantitativos, dados qualitativos ou ambos —alguns se tornam um ponto de partida para navegar e fazer uma pesquisa detalhada.
Painéis têm a tendência de apresentar coisas que são mensuráveis, que são geralmente denotadas nos círculos de negócios como principais indicadores de desempenho Qualquer métrica que possa ser medida e que indique algo sobre o estado ou funcionamento dos processos de negócios da empresa é um KPI. Um bom KPI, portanto, deve ser bom para medir o sucesso ou falha de quaisquer objetivos estratégicos, analíticos ou operacionais em sua organização.
A barra lateral, "Exemplos de KPIs", fornece alguns exemplos de KPIs que podem ser usados em seus negócios. Esses KPIs são genéricos para uma gama inteira de empresas, aconselho abraçar a causa de tentar identificar (como no exemplo de pontuação anterior) um KPI que caracterize de forma sucinta o funcionamento de processos específicos para seus negócios. Quanto mais relacionada a o que sua empresa faz, mais apropriada será a métrica.
Tente perceber que seus KPIs podem apresentar volatilidade em suas definições, à medida que você aprende com o tempo maneiras mais apropriadas para defini-los, assim como quais perguntas deseja responder com eles. No fim, são as questões que deseja perguntar e responder sobre seus negócios para as quais usar KPIs faz mais sentido.
Posto isso, não tenha medo de KPIs. Podem ser tão avançados ou simples quanto você desejar e muitos materiais de referência estão disponíveis na Web para ajudá-lo a montar os seus próprios materiais. Acredito que o mais importante para garantir a criação deles é assegurar que os dados estejam disponíveis.
Um bom painel da Web busca apresentar KPIs da maneira mais clara possível, o que maximiza dados e reduz o máximo possível qualquer ruído gráfico irrelevante à apresentação das informações. Organizar elementos de exibição de forma semelhante a objetivos estratégicos, operacionais e analíticos é um bom ponto de partida para como agrupar itens. Ao agrupar itens que deseja comparar, verifique se a comparação é relevante, válida e fornece algum feedback útil para os negócios em vez de explicar o que ocorreu no passado. Informar como algo específico ocorreu no passado pode ser útil, mas lembre-se de que a tarefa de um painel é explicar o estado presente e atual das coisas. Caso precise de um registro histórico para ajudar a explicar o presente, então, construa seu painel de forma que ele ou seus dados possam ser salvos em intervalos regulares.
Um painel que mostra dados inicialmente na forma mais condensada e, em seguida, divulga progressivamente informações adicionais pode se tornar uma ferramenta para navegação de informações. No entanto, caso forneça elementos como pesquisa detalhada dos dados ou uma UI de navegação, também será necessário estar ciente da necessidade de corresponder o painel a uma função de usuário específica. A melhor prática é tentar corresponder um único painel a uma função específica.
Por fim, um bom painel da Web evita gráficos superelaborados. O exemplo clássico é usar coisas como gráficos de setores circulares tridimensionais (3D), onde a profundidade incluída na verdade torna mais difícil determinar visualmente a contribuição das fatias de um todo. Indo ainda mais longe, muitas discussões de qualidade (consulte Recursos para obter links para informações adicionais) renunciam o uso do gráfico de setores circulares de modo geral.
Um painel ruim exibe a negação de todos os conselhos que acabo de fornecer. Aqui, listo alguns traços estereotipados que percebi estarem invariavelmente presentes em aplicativos de painel pobremente projetados:
- Uso de muitas cores. Organizar dados com base em cores é bom, mas a maioria das pessoas tem uma tendência a exagerar.
- Requer que o usuário role ou use guias. Exceder uma página de dados faz com que o cérebro do usuário trabalhe mais.
- Excesso de detalhes. Não resumir pode tornar praticamente impossível para a pessoa sintetizar dados que resultam em ações concretas.
- Precisão excessiva. Muitas casas decimais em um número ou muitos rótulos de dados em um gráfico são exemplos.
- Exceções críticas passam despercebidas. Não realçar as exceções, como superar alguma meta ou não atingir algum objetivo, torna o painel menos efetivo como uma chamada para ação no espaço de tempo atual.
- Implementação de métricas incompletas ou deficientes. Assegurar que o KPI seja apropriado e esteja formulado corretamente pode parecer óbvio, mas é tão comum quanto as características ruins anteriores. Gere a métrica manualmente ou use uma planilha para auxiliar no teste de alguns cálculos de exemplo antes de integrá-la a seu aplicativo de painel.
A ideia fundamental de data ink inclui outra maneira de descrever o que torna um painel bom ou ruim. Um princípio básico de informações e de design de dados, data ink é literalmente toda a tinta usada para qualquer coisa que represente dados (por exemplo, número ou linhas de dados em um gráfico) em uma página impressa. O mesmo é verdadeiro para uma tela de computador, na qual os pixels de dados são análogos à data ink e tudo o mais não é. Maximizar os pixels de dados no design de informações significa remover o máximo possível de elementos gráficos irrelevantes, usar esquemas de cores suavizados e evitar fontes sofisticadas.
Instalando o Painel de Amostra
Antes de mostrar como construir o painel de exemplo, pode ser que queira obter os arquivos de origem a partir de Download e instalar o painel. Para fazer isso, extraia o arquivo .zip e siga as instruções do arquivo LEIA-ME incluído.
Quando tudo estiver instalado, deve ser possível visualizar o painel de exemplo acessando dashboard.xq a partir do banco de dados eXist usando o navegador da Web e a URL:
http://localhost:8080/exist/rest/db/dashboards_with_xquery/xquery/dashboard.xq |
Caso tenha instalado os arquivos de XQuery em algum outro local no eXist, ajuste a URL conforme necessário.
Também fique atento pois o painel de exemplo usa muitos dados de teste e credenciais para serviços da Web on-line, todos os quais existem na Internet. Esses recursos devem permanecer disponíveis, mas caso encontre problemas, sugiro substituir os dados de exemplo por suas próprias credenciais e dados de teste.
Construindo o Painel de uma Empresa
Agora que você já sabe o que são painéis e que a meta principal dos mesmos é apresentar KPIs de maneira cativante que ajude-o a perguntar e responder questões importantes sobre os negócios, é possível seguir adiante para realmente criar o painel de amostra. Usando tecnologias XML como o banco de dados XML eXist e XQuery, é possível agregar e consumir dados XML e, em seguida, criar uma representação em HTML de um painel.
Figura 1 mostra o painel de amostra em seu formato final.
Figura 1. O Painel de Amostra
Essa página da Web possui poucos elementos de design irrelevantes concorrendo pela atenção dos olhos, o que esperamos que signifique que segui o conselho das seções anteriores de aumentar os pixels de dados sobre todo o resto. O arquivo CSS define um plano de fundo sem cor e fonte que acredito que facilitem a leitura.
Escolhi KPIs que estavam disponíveis já prontos para mostrar como XQuery integra dados bem:
- Faturas por Vencimento. Quando uma empresa cobra por seus serviços, o pagamento geralmente ocorre com base em um conjunto de termos padrão (por exemplo, o número de dias para pagamento pelo cliente).
- Funil de Vendas. Uma empresa categoriza as oportunidades de vendas entre diversos estágios, o que define a probabilidade de realmente ganhar uma tarefa e faturá-la.
- Planilhas de Horas Semanais. As planilhas de horas semanais dos funcionários são exibidas com ênfase em identificar quando os indivíduos trabalharam além das 40 horas de trabalho semanais padrão.
- Operação do Web site. Esse monitor indica se um Web site está em operação.
- Lembretes. São uma série de tarefas datadas para a empresa.
- Web sites de Concorrentes. Esse gráfico indica o desempenho dos Web sites em comparação aos concorrentes.
O painel é um aplicativo mais mashup do que integralmente ampliado, o que tira proveito de funcionalidade localizada especificamente na implementação do banco de dados XML eXist de XQuery. O painel que será criado é implementado usando apenas três arquivos do XQuery, um dos quais é um modelo XQuery usado pelos outros, como na Figura 2.
Figura 2. Componentes XQuery do Painel
O módulo XQuery utility.xqm contém funções que data.xq e dashboard.xq usam. A tarefa do arquivo data.xq de XQuery é gerar um documento XML que contém todos os dados relacionados a KPI. A função do arquivo dashboard.xq é apresentar esses dados, criando um arquivo HTML que pode ser visualizado em um navegador.
Quando desenvolvo software, tento dar substância à camada de dados de um aplicativo antes de fazer qualquer outra coisa. É incomum um aplicativo útil não depender de algum tipo de dado. À medida que um painel que representa dados é criado, é necessário identificar as origens de dados primeiro.
A meta de um painel é apresentar KPIs, portanto segue que origens de dados precisam ser integradas, sejam elas KPIs ou contribuam para seus cálculos. Independentemente de se um KPI é de natureza qualitativa ou quantitativa, todos os KPIs precisam informar algo útil sobre a execução dos negócios. Para este painel de amostra, usei dados publicamente disponíveis para ilustrar como XQuery trata dos cenários de integração. Além disso, escolhi uma gama de serviços da Web populares relevantes para trazerem todos esses dados XML gerados internamente, externamente e à margem dos negócios.
O diagrama na Figura 3 mostra a seleção das origens de dados disponíveis a partir de serviços da Web populares, como o Google™ ou a partir de tecnologias comuns, como bancos de dados relacionais.
Figura 3. Diagrama de Possíveis Origens de Dados
Cada origem de dados requer algum tipo de integração a um serviço da Web, dados XML ou dados gerados por XQuery:
- Operação do Web site. Mostra que XQuery é uma linguagem expansiva por suas próprias habilidades
- Faturas por Vencimento. Ilustra como é possível acessar MySQL a partir de XQuery
- Funil de Vendas. Mostra como é possível acessar planilhas do Google Docs a partir de XQuery
- Planilhas de Horas Semanais. Mostra como acessar uma planilha local do Microsoft® Office Excel®
- Lembretes. Integra-se ao popular serviço da Web Backpack
- Web sites de Concorrentes. Um gráfico que indica desempenho de Web sites em comparação a concorrentes
O resultado de processar data.xq deve ser um único documento XML que contém todos os dados necessários.
A maneira mais fácil de integrar dados a XQuery é usando a função doc() , que recupera XML do site na URL da Web.
Caso forneça a essa função uma URL que aponte para um recurso que retorna dados que não são bem-formados (no sentido XML), então, receberá um erro.
As seções de código na Lista 1 mostram esse processamento em ação no data.xq.
Lista 1. Processando no data.xq
<sales_pipeline desc="example accessing published Google spreadsheet">
{doc("http://spreadsheets.google.com/feeds/list/
pZDPqHJcLzxKntsQv2tuIMQ/1/public/basic")}
</sales_pipeline>
...
<backpack desc="example accessing simple web service">
{doc("http://dashboardwithxquery.backpackit.com/
69babcbce8aa212fc83464088b45f7a97a9f3dce/reminders.xml")}
</backpack>
...
<timesheet desc="example accessing local MS Excel file">
doc("file:///Users/jimfuller/Source/Writing/1_articles/1_ibm/
3_dashboards_with_xquery/working/src/data/MSOFFICE-timesheet.xls")
</timesheet>
|
O elemento sales_pipeline acessa um documento Google que publiquei e disponibilizei através de uma URL.
Documentos Google são expostos dessa forma como um Atom XML feed (consulte
Recursos para obter um link). A URL do Backpack retorna um
XML feed que representa lembretes que configurei na URL
http://www.backpackit.com. O elemento
timesheet faz algo diferente e acessa um arquivo Excel hospedado localmente.
Desde alguns anos é possível usar as planilhas do Excel geradas em um formato XML específico à Microsoft.
A próxima etapa na integração de dados é usar XQuery para criar um conjunto de funções auxiliares, todas as quais estão localizadas no módulo XQuery utility.xqm. Seguem descrições resumidas das funções, com aspectos especiais do código destacado:
- utility:check_site(). Esse pequeno trecho de código
XQuery verifica se uma URL da Web está acessível e quanto tempo levou para o servidor da Web responder.
Lista 2 mostra essa função.
Lista 2. A Função utility:check_site()declare function utility:check_site($uri) { let $start := util:system-time() let $response := httpclient:get(xs:anyURI($uri),false(),()) let $end := util:system-time() let $response-time := (($end - $start) div xs:dayTimeDuration('PT1S')) * 1000 let $status-code := string($response/@statusCode) return <test xmlns="" ts="{current-dateTime()}" status="{$status-code}" response="{$response-time}" /> };
A função retorna um elemento de teste que o dashboard.xq usa para exibir o status de um Web site.
- utility:get-aged-invoices(). Como uma quantidade inimaginável de dados é codificada e armazenada nos bancos de dados relacionais, parece apropriado mostrar um exemplo de integração de um banco de dados XML eXist para interagir com um servidor de comunidade MySQL® .
XQuery não possui nenhuma funcionalidade integrada nativa do relational database management
system (RDBMS), mas muitos dos processadores XQuery populares têm funções de extensão.
O banco de dados XML eXist possui funções de extensão Query
Language (SQL) disponíveis no formato de um módulo opcional, que devem ser ativadas removendo o comentário da seção apropriada no arquivo conf.xml de eXist (leia o arquivo LEIA-ME incluído no código de amostra).
A Lista 3 mostra a função
utility:get-aged-invoices().
Lista 3. A Função utility:get-aged-invoices()declare function utility:get-aged-invoices(){ let $connection := sql:get-connection("com.mysql.jdbc.Driver", "jdbc:mysql://localhost/test", "root", "") let $data := sql:execute($connection, "select * from invoices;", fn:true()) return <invoices> <total>{sum($data/sql:row/sql:invoice_amount)}</total> <age amt="15"> {sum($data/sql:row/sql:invoice_amount[../sql:invoice_terms='15'])}</age> <age amt="30"> {sum($data/sql:row/sql:invoice_amount[../sql:invoice_terms='30'])}</age> <age amt="60"> {sum($data/sql:row/sql:invoice_amount[../sql:invoice_terms='60'])}</age> </invoices> };
A função primeiro estabelece uma conexão com estilo Java™ Database Connectivity (JDBC) usando a função
sql:get-connection()do módulo de extensão SQL de eXist. Em seguida, defina uma instrução SQL para selecionar os dados do banco de dados, que é executado usandosql:execute. Os resultados dessa função são salvas na variável$data, que, em seguida, você usa para selecionar dados relevantes usando XPath.
Segue uma série de funções que se integram aos diversos serviços da Web baseados na Google (consulte Recursos para obter um link para informações adicionais). Muitos serviços da Web da Google usam técnicas semelhantes para expor e conectar a eles, portanto, inclui alguns exemplos adicionais. (Eles mesmos não são usados no painel de amostra, mas pode achá-los instrutivos ou úteis.)
- utility:get-google-token($Email,$Passwd,$accountType,$source,$service). Os serviços da Web da Google têm alguns mecanismos de autenticação diferentes, dependendo de até onde deseja integrar.
Escolhi a versão
ClientToken(na Lista 4) para criar um token de autenticação única apropriado para propósitos deste exemplo.
Lista 4. O Serviço utility:get-google-token($Email,$Passwd,$accountType,$source,$service) da Googledeclare function utility:get-google-token($Email,$Passwd,$accountType,$source,$service){ let $params := concat("Email=",$Email, "&Passwd=",$Passwd, "&source=",$source, "&accountType=",$accountType, "&service=",$service) let $uri := concat("https://www.google.com/accounts/ClientLogin?",$params) let $response := httpclient:get(xs:anyURI($uri),false(),()) let $token := substring-after(xmldb:decode($response),"Auth=") return string($token) };
Esteja ciente de que essa função retorna uma cadeia de caracteres e não XML. Em XQuery, é possível limitar as entradas e saídas de uma função e fornecer a elas um tipo de dados.
- utility:get-google-spreadsheet-feed($Email,$Passwd). Essa função (na
Lista 5) retorna a lista de documentos da Google, como um Atom feed, a partir de seus próprios documentos (ou de outros) da Google.
Como usei uma planilha da Google disponível publicamente, achei que alguns desenvolvedores gostariam de saber como conectar e usar documentos da Google através de XQuery.
Lista 5. A Função utility:get-google-spreadsheet-feed($Email,$Passwd)declare function utility:get-google-spreadsheet-feed($Email,$Passwd){ let $accountType := "HOSTED_OR_GOOGLE" let $source := "Dashboards-XQUERY-Example" let $service := "wise" let $token := utility:get-google-token($Email,$Passwd,$accountType,$source,$service) let $headers := <headers> <header name="Authorization" value="GoogleLogin auth={$token}"/> </headers> let $uri := xs:anyURI('http://spreadsheets.google.com/feeds/spreadsheets/private/full') return httpclient:get($uri, false(), $headers) };
Essa função cria o pedido HTTP apropriado para recuperar uma lista de documentos em documentos da Google, que por sua vez podem ser usados para abrir os documentos em questão.
- utility:get-google-atom-feed(). Outra origem de dados interessante é um endereço de e-mail da Google.
Os dados são expostos no Gmail como uma alimentação de dados Atom, como na
Lista 6. (Esse painel de exemplo não usa realmente essa origem, mas é útil para observar como um exemplo de uma origem de dados para manipular
e-mail.)
Lista 6. A Função utility:get-google-atom-feed()declare function utility:get-google-atom-feed($user,$pass,$label){ let $token := util:string-to-binary(concat($user,':',$pass)) let $headers := <headers> <header name="Authorization" value="Basic {$token}"/> </headers> let $uri := xs:anyURI(concat('https://mail.google.com/mail/feed/atom/',$label)) return httpclient:get($uri, false(), $headers) };
- utility:get-google-cal-feed($Email,$Passwd). Outro serviço popular da Google é o Google Calendar (não usado em data.xq) para mostrar dados de eventos de calendário.
Lista 7 mostra a função correspondente.
Lista 7. A Função utility:get-google-cal-feed($Email,$Passwd)declare function utility:get-google-cal-feed($Email,$Passwd){ let $accountType := "HOSTED_OR_GOOGLE" let $source := "Dashboards-XQUERY-Example" let $service := "cl" let $token := utility:get-google-token($Email,$Passwd,$accountType,$source,$service) let $headers := <headers> <header name="GData-Version" value="2"/> <header name="Authorization" value="GoogleLogin auth={$token}"/> </headers> let $uri := xs:anyURI( concat('http://www.google.com/calendar/feeds/', string($Email), '/private/full') ) return httpclient:get($uri, false(), $headers) };
Essas funções são usadas por data.xq para criar um documento XML massivo que é o documento de origem para o painel digital. Se houver código instalado, sugiro que acesse data.xq através de seu navegador. É possível ver algo semelhante à Figura 4.
Figura 4. Recuperando data.xq
A estrutura dessa marcação é arbitrária e é possível escolher todas as maneiras de alternativas.
O arquivo XQuery dashboard.xq gera saída—um documento HTML—baseada em opções de serialização específicas do banco de dados XML eXist que representam o painel:
declare option exist:serialize
"method=xhtml media-type=text/html indent=yes omit-xml-declaration=no";
|
Para criar o painel de exemplo, pegue o documento XML agregado e use as funções XQuery, definidas em utility.xqm, para construir cada área específica da página da Web, como na Figura 5.
Figura 5. Relacionar Funções ao Painel
Os KPIs são mostrados usando uma mistura de gráficos de barras e HTML para mostrar o status de qualquer métrica específica. Nas áreas em que gráficos de barra são usados, optei por implementar a API do Google Charting. Essa API inteligente cria os gráficos usados nas áreas de funil de vendas, faturas por vencimento e planilhas de horas.
- Faturas por Vencimento. Mostra o status de faturas não pagas, usando três gráficos de barras separados, representando termos padrão (15, 30 e 60 dias).
- Funil de Vendas. Usa gráficos de seis barras para indicar quantas vendas em potencial existem em cada estado do fluxo de trabalho de vendas. O intervalo do gráfico de barras indica destinos desejados para cada fase do funil.
- Folhas de horas. Uma gráfico de barras é gerado para cada indivíduo, com a barra ficando vermelha se um indivíduo trabalhar mais de 40 horas.
Para ajudar a facilitar a criação de gráficos, crie uma função XQuery,
utility:graph(), que está definida em utility.xqm (consulte a Lista 8).
Lista 8. A Função utility:graph()
(: Wrap up Google Charting API :)
declare function utility:graph($type,$colors,$size,$markers,$data,$alt){
let $src
:=concat('http://chart.apis.google.com/chart?chf=bg,s,F7F5E6&chco=',$colors,
'&chs=',$size,
'&cht=',$type,
'&chl=',$markers,
'&chd=t:',$data
)
return <img alt="{$alt}"src="{$src}"/>
};
|
A função utility:graph() constrói a URL e retorna o elemento
img resultante. Para aprender mais sobre as opções da API do
Google Charting, consulte
Recursos.
O painel de exemplo precisa de dados para fazer qualquer coisa, portanto, traz dados agregados gerados por data.xq usando a função doc() , salvando os resultados em uma variável
$data :
let $data :=
doc('http://localhost:8080/exist/rest/db/dashboards_with_xquery/xquery/data.xq')
|
Colocar o documento XML na variável $data significa que as métricas são todas medidas ao mesmo tempo.
Isso não é necessário, mas isso significa que há uma "pulsação" consistente em todas as métricas
—úteis se você tiver a intenção de salvar resultados regularmente e visualizar desempenho histórico.
As listas a seguir descrevem cada área de exibição e explica os princípios mais importantes do que XQuery faz. Realcei o código XQuery em negrito para ajudar você a distingui-lo na marcação HTML.
O código XQuery na Lista 9 exibe três gráficos de barra que devem ser normalizados para que possam ser comparados. Como é usado um intervalo de 10.000, isso significa dividir os valores pela mesma quantia e, em seguida, multiplicar por 100 para obter uma porcentagem da barra usada.
Lista 9. Código do Gráfico de Barra para Faturas por Vencimento
<h3>Aging Invoices<sup>(mysql)</sup></h3>
<table>
<tr>
<td>£{$data/data/strategic/financial/invoices/age[@amt='15']}</td>
<td>
{ let $amt :=(xs:float($data/data/strategic/financial/invoices/age[@amt='15'])
div 10000) * 100
return
utility:graph("bhs","4D89F9",
"150x30", "0|10000",$amt, '15 day')
}
</td>
<td>15 Day</td> </tr>
<tr>
<td>£{$data/data/strategic/financial/invoices/age[@amt='30']}</td>
<td>{ let $amt :=
(xs:float($data/data/strategic/financial/invoices/age[@amt='30'])
div 10000) * 100
return
utility:graph("bhs",
"4D89F9",
"150x30",
"0|10000",
$amt,
'30 day')
} </td>
<td>30 Day</td> </tr>
<tr>
<td>£{$data/data/strategic/financial/invoices/age[@amt='60']}</td>
<td>{ let $amt := (xs:float($data/data/strategic/financial/invoices/age[@amt='60'])
div 10000) * 100
return
utility:graph("bhs","4D89F9", "150x30",
"0|10000", $amt, '60 day') } </td>
<td>60 Day</td> </tr>
</table>
|
Cada linha da tabela precisa selecionar os dados corretos, o que é obtido selecionando o atributo
amt , que representa a quantia total.
Lembre-se de que esses dados foram gerados originalmente a partir do banco de dados MySQL, portanto, é necessário assegurar que o servidor MySQL esteja em execução e carregado com o conjunto de dados de exemplo.
Também será necessário remover comentário do código de data.xq, conforme explicado no arquivo LEIA-ME de instrução da instalação.
Os dados do funil de vendas são obtidos a partir de uma planilha Google Docs que pode ser visualizada publicamente. Isso significa que seleciona os dados de forma efetiva a partir de um Atom feed. A única coisa estranha quando esses dados são apresentados é que o Atom feed (da planilha Google) fornece dados em linhas que contêm dados delimitados, como na Lista 10.
Lista 10. O Código do Funil de Vendas
<h3>Sales Pipeline
<sup>(google spreadsheet)</sup></h3>
<table>
{for $item in $data/data/strategic/sales_pipeline/atom:feed/atom:entry/atom:content
return
let $cols := tokenize($item,',')
return
<tr>
<td>£{substring-after($cols[2],':')}</td>
<td>{
let $amt := (xs:float(substring-after($cols[2],':'))
div 10000) * 100 return
utility:graph("bhs",
"4D89F9,C6D9FD",
"150x30",
"0|10000",
$amt,
substring-after($cols[1],':'))
}</td>
<td>{
substring-after($cols[1],':')
}</td>
</tr> }
</table>
|
A combinação de XML contendo dados delimitados é um tanto quanto estranha, mas XQuery fornece opções suficientes para analisá-la.
Uso a função tokenize()
para separar cada coluna, em seguida, a função substring-after()
chega ao valor dos dados.
Às vezes, a melhor maneira de capturar os dados da planilha de horas é simplesmente abrindo uma planilha local. Agora que o Excel suporta um formato XML, é necessário conhecer apenas sua estrutura para começar brincar com ela, como com o código na Lista 11.
Lista 11. Manipulando Dados da Planilha de Excel
<h3>Weekly Timesheets <sup>(MS Excel)</sup></h3>
<table> {
for $item in $data/data/operational/project/timesheet/
ss:Workbook/ss:Worksheet/ss:Table/ss:Row[not(position()=1)]
return
<tr> <td>{$item/ss:Cell[1]}</td>
<td>{$item/ss:Cell[2]}</td> <td>
{
let $hours := xs:decimal(($item/ss:Cell[3] div 40 ) * 100)
return
if ($hours < 100) then
utility:graph("bhs",
"4D89F9,C6D9FD",
"150x30",
"0|40",
$hours,
$item/ss:Cell[3])
else
utility:graph("bhs",
"FF5858,C6D9FD",
"150x30",
"0|40",
$hours,
$item/ss:Cell[3]) }
</td> </tr>
}
</table>
|
XQuery permite evitar o uso da primeira linha, que contém os rótulos das colunas. A única outra funcionalidade pela qual precisa se responsabilizar é exibir o gráfico de barras em vermelho se o funcionário superar uma semana de trabalho de 40 horas.
A instrução
if|then|else em XQuery permite escolher um gráfico de barras baseado em testar se a variável
$hours é maior que 40.
A incursão da Microsoft em fornecer formatos de origem XML baseados em padrões abertos é um distanciamento dos muitos anos de uso de formatos binários. Esses formatos são, na verdade, mais rápidos, mas ser fechado significa que é difícil obter o tipo de integração mostrado aqui. O formato XML do Excel que representa uma planilha é praticamente racional, mas deixarei qualquer discussão sobre os méritos de sua estrutura específica para outros decidirem.
Os elementos de teste gerados por data.xq indicam se o Web site está on-line e quanto tempo levou para o servidor da Web responder.
Em vez de usar qualquer coisa sofisticada, simplesmente executei um teste no atributo
status , como na
Lista 12.
Lista 12. Testando o Web Site
<h3>Website Operation <sup>(xquery logic)</sup></h3>
<table> {
for $item in $data//website_ok/website
return
<tr>
<td>{$item/@title/string()}</td>
<td>
{
if ( $item/test/@status = '200' ) then
attribute style{'background-color:green'}
else
attribute style{'background-color:red'
}
}  </td>
<td>{
$item/test/@response/string()
} ms</td>
</tr>
}
</table>
|
É possível imaginar usar o mesmo tipo de funções para ir além de apenas testes de existência. Por exemplo, é possível testar se um formulário de contato estava funcionando.
Pegando dados de outro aplicativo da Web (http://www.backpackit.com/), simplesmente itero por um serviço da Web XML usando uma expressão XQuery FLWR (for, let, where e return), como na Lista 13.
Lista 13. Iterando pelo Serviço da Web XML
<h3>Reminders <sup>(simple webservice)</sup></h3> <table> {
for $item in $data/data/operational/project/backpack/reminders/reminder
return
<tr>
<td>{
string($item/creator/@name)
}:</td>
<td> {
$item/content
}</td>
</tr>
}
</table>
|
Para inspirar leitores, pensei que seria divertido incluir widgets internos. Nesse sentido, um painel torna-se mais um mashup. O Web site compete.com faz um bom trabalho exibindo o desempenho de diversos Web sites em comparação.
Construí o painel de exemplo para demonstrar como usar XQuery primeiro, em vez de criar algo rápido ou altamente reutilizável. Seguem algumas sugestões de otimização:
- Gerar dashboard.html planejando execução de dashboard.xq usando
cron(ewgetoucurl). - Como alternativa, use o planejador do banco de dados XML eXist para planejar a criação de dashboard.html.
- Armazene os resultados de cada origem de dados de forma independente dentro do banco de dados XML.
- Modularize cada KPI—possivelmente, usando XSLT para gerenciar a apresentação de dados.
Com três arquivos XQuery diretos, foi implementado um painel da Web que mostra o poder de XQuery e dos bancos de dados XML para agregar e apresentar dados.
| Descrição | Nome | Tamanho | Método de download |
|---|---|---|---|
| Source files for the example dashboard | src.zip | 13KB | HTTP |
Informações sobre métodos de download
Aprender
- Information Dashboard design: Leia a excelente visão geral concisa de Stephen Few sobre o que se deve fazer ao projetar painéis.
- XQuery 1.0: An XML Query Language: Consulte o documento principal que descreve a linguagem XQuery.
- XML Path Language (XPath) 2.0: Leia a especificação XPath 2.0 relacionada.
- eXist XML Database: Explore esse sistema de gerenciamento de banco de dados de software livre que armazena dados XML de acordo com o modelo de dados XML e recursos eficientes, processamento XQuery baseado em índice.
- Atom Feed Specification: Leia a especificação Internet Engineering Task Force (IETF) do formato de marcação XML Atom feed.
- Google API Web services: Consulte a lista principal de APIs da Google.
- Google ClientLogin authentication: Aprenda como a autenticação ClientLogin é solicitada e usada na maioria das APIs da Google.
- Google Calendar Web service: Leia a documentação da API para o serviço Google Calendar.
- Google Docs Web service: Leia a documentação da API para o serviço de lista Google Docs.
- Google Spreadsheet Web service: Leia a documentação da API para o serviço Google Spreadsheet.
- General Google Atom feed: Leia uma visão geral dos serviços da Web da Google que emitem Atom feeds.
- Google Chart API: Leia a documentação da API para o serviço Google Chart.
- 37 Signals' Backpack API Web service: Consulte a API de 37 Signals para obter seu popular serviço Backpack, que é groupware de intranet.
- Data Ink: Explore a Proporção Data-Ink, um conceito concebido primeiramente por Tufte em 1983. Gira em torno do conceito de usar dados sobre todas as outras coisas em design de informações.
- Information Dashboard design: Leia a boa discussão de Stephen Few sobre a razão de reconsiderar o uso de gráficos de setores circulares.
- Certificação em XML da IBM: Descubra como é possível se tornar um Desenvolvedor Certificado pela IBM em XML e tecnologias relacionadas.
- Biblioteca Técnica de XML: Consulte a Zona de XML do developerWorks para obter uma ampla gama de artigos técnicos e dicas, tutoriais, padrões e IBM Redbooks.
-
Eventos Técnicos e Webcasts do developerWorks: Permaneça atualizado com a tecnologia nessas sessões.
- developerWorks podcasts: Ouça entrevistas e discussões interessantes para desenvolvedores de software.
Obter produtos e tecnologias
- MySQL Community Database Server: Faça download e avalie como painel de exemplo integra-se a um banco de dados MySQL.
- MySQL JDBC connector: Faça download do conector JDBC, necessário para o banco de dados eXist.
- versões de avaliação do produto IBM: Faça download ou explore as amostras on-line no IBM SOA Sandbox e obtenha ferramentas de desenvolvimento de aplicativos e produtos de middleware do
DB2®, Lotus®, Rational®, Tivoli®e WebSphere®.
Discutir
- Fóruns de Discussão da Zona XML: Participe de qualquer uma das diversas discussões relacionadas a XML.
- blogs do developerWorks: Verifique esses blogs e envolva-se com a comunidade do developerWorks.

Jim Fuller é um desenvolvedor profissional há 15 anos, trabalha com diversas empresas de software de primeira linha nos EUA, seu país de origem, e no RU. Coescreveu alguns livros relacionados a tecnologia e dá palestras e escreve artigos regularmente focando as tecnologias XML. É membro do comitê fundador de XML Prague e fez parte do pessoal responsável por EXSLT. Passa seu tempo livre brincando com bancos de dados XML e XQuery. Jim é diretor técnico de algumas empresas (FlameDigital, Webcomposite s.r.o.) e pode ser contatado em jim.fuller@webcomposite.com.