Blog

Pokédex em Power BI: quando o relatório vira jogo

Montei uma Pokédex interativa no Power BI com dados da PokeAPI, medidas DAX que geram HTML e quatro páginas em JavaScript, incluindo uma arena de batalhas. Mostro o resultado, as técnicas e o que dá para levar para um relatório de verdade.

7 min de leitura Power BI, DAX, Projetos, HTML Content

Página Pokédex do relatório no Power BI mostrando o Charizard, ao lado do título do post

Todo mundo que trabalha com Power BI já ouviu que "o visual nativo não deixa". Eu quis descobrir até onde dá para ir sem sair do Power BI: nada de site paralelo, nada de embed em outro sistema. Um arquivo PBIP, um modelo semântico e medidas DAX.

O resultado é uma Pokédex interativa e animada com cinco páginas: Pokédex, Arena, Tipos, Quiz e Safari. Ela está publicada e aberta para qualquer pessoa: abra o relatório no Power BI. O código completo está no GitHub.

Página Pokédex com o Charizard selecionado: lista à esquerda, ficha ao centro, atributos, fraquezas e formas à direita
A página Pokédex. Tudo o que não é lista ou filtro é HTML gerado por medidas DAX.

O que tem no relatório

Pokédex. São 1.302 Pokémon, contando as formas. A ficha mostra atributos num radar em SVG, fraquezas e resistências calculadas (de 4× até imunidade) e a cadeia evolutiva. O fundo muda conforme o tipo: bolhas para Água, brasas para Fogo, raios para Elétrico, folhas, neve e assim por diante, tudo em CSS.

Dá para alternar entre os modos Normal, ✨ Shiny e 🃏 Cartas. Na evolução, clicar no próximo estágio dispara uma animação de evolução, e as formas especiais (Mega X, Mega Y, Gigantamax, regionais) também são clicáveis.

O Charizard Mega X na versão shiny, com atributos e fraquezas recalculados
Modo Shiny com a forma Mega X: tipos, atributos e fraquezas mudam junto.

O modo Cartas traz as cartas do Pokémon TCG que correspondem à forma exibida, com uma prévia ampliada ao lado. Para isso, o modelo lê 17,5 mil cartas do repositório oficial de dados do jogo de cartas.

Galeria de cartas do Charizard no modo Cartas
Modo Cartas: 13 cartas casadas com a forma Mega.

Arena. Batalhas 1x1 ou com times de 3, com troca de Pokémon. O dano segue a fórmula oficial dos jogos (nível 50, bônus de mesmo tipo, eficácia de tipos e golpe crítico). O oponente é uma IA que escolhe o melhor golpe e troca de Pokémon quando o confronto está ruim. Tem Mega Evolução e Gigantamax, previsão de vitória, modo automático e uma simulação de mil batalhas para ver quem é favorito.

Seleção de times na Arena: Charizard, Lucario e Gengar contra Blastoise, Garchomp e Gardevoir
Montando os times. A barra de previsão já mostra quem é favorito.

Batalha na Arena com introdução VS, Mega Evolução e golpes animados
Uma batalha no modo automático: introdução, Mega Evolução dos dois lados e efeitos de cada tipo.

Tipos. Uma roda com setas animadas mostra quem vence quem, no ataque e na defesa. Também tem a matriz 18×18, o ranking das 171 combinações defensivas, a cobertura ofensiva e uma calculadora de confronto.

Roda de tipos com setas de dano dobrado, metade e sem efeito
A roda de tipos: escolha um ataque ou uma defesa e as setas se redesenham.

Quiz "Quem é esse Pokémon?". Silhueta, quatro opções ou digitar o nome, cronômetro, dicas, sequência de acertos, recorde e filtro por geração.

Quiz com a silhueta de um Pokémon, quatro opções e a revelação da resposta
O quiz em ação: silhueta, resposta e pontuação.

Safari. Um minijogo em pixel art desenhado em canvas, sem nenhuma imagem de cenário. Você anda pelo mato alto, encontra Pokémon selvagens (às vezes shiny, às vezes lendário) e tenta capturar com Pokébola, Grande Bola, Ultra Bola ou Fruta. A chance de captura usa a fórmula da 3ª geração.

Minijogo Safari: o treinador anda pelo mato, encontra um Numel shiny e captura com uma Ultra Bola
No Safari, um Numel shiny apareceu no mato e foi capturado na primeira Ultra Bola.

Como funciona por dentro

Diagrama: fontes públicas, Power Query, modelo, medidas DAX e o visual HTML Content
Do JSON da API ao HTML na tela, sem sair do Power BI.

Uma consulta, todos os dados. A PokeAPI tem uma API GraphQL. Em vez de centenas de chamadas, o Power Query faz uma única consulta que traz Pokémon, formas, espécies, tipos, gerações e a tabela de eficácia. A partir daí, onze consultas em M derivam o resto: rótulo de cada forma, estágio da evolução, URLs das imagens e a tabela de fraquezas.

Medidas que devolvem HTML. O visual HTML Content renderiza o texto de uma medida. Cada painel tem duas medidas: uma com o HTML e outra só com o CSS. Separar as duas deixa o HTML curto e o estilo reaproveitável, já que as cores por tipo saem de uma única medida gerada a partir da tabela de tipos.

Cliques sem filtrar a página. Quando você clica num estágio da evolução ou numa forma, a lista não pode perder a seleção. A solução foram tabelas desconectadas (Modo, EvoSel e FormaSel) e uma medida que decide qual Pokémon mostrar, por ordem de prioridade:

DAX
Id Selecionado =
VAR _forma = [Id Forma Clicada]     -- clique no visual de Formas
VAR _evo   = [Id Evolução Clicada]  -- clique no visual de Evolução
VAR _lista = [Id Lista]             -- item escolhido na lista
RETURN
    COALESCE(_forma, _evo, _lista)

Os cliques só valem se forem da mesma cadeia evolutiva do item da lista. Assim, quando você escolhe outro Pokémon na lista, um clique antigo de outra cadeia é ignorado sozinho, sem nenhum botão de limpar.

JavaScript dentro de uma medida. As páginas Arena, Tipos, Quiz e Safari são aplicações em JavaScript. A medida [JS Dados] transforma o modelo inteiro (Pokémon, golpes, tipos e eficácia) num objeto JavaScript, e cada página recebe esse objeto junto com o próprio código. Dois cuidados fizeram diferença:

  • Sem aspas duplas no JavaScript. O código vira um texto DAX, e aspas duplas quebrariam a medida. O script de build recusa o arquivo se encontrar alguma.
  • Estado fora do visual. O Power BI redesenha o visual quando quer. Por isso, o estado de cada jogo fica guardado na janela do navegador: se o visual for redesenhado no meio da batalha, ela continua de onde parou.

Tudo como código. O projeto está em formato PBIP, com o modelo em TMDL e o relatório em PBIR. As consultas, as medidas e o JavaScript ficam em arquivos comuns, e dois scripts em Python gravam o modelo e as páginas. Isso deu versionamento de verdade no Git, diffs legíveis e a possibilidade de testar a lógica da Arena em Node, fora do Power BI.

O que eu levo para os relatórios do dia a dia

Ninguém vai pedir uma arena de batalhas num fechamento contábil. Mas as técnicas são as mesmas que uso em painéis financeiros:

  • HTML e CSS em medidas resolvem cards de KPI, tabelas com formatação condicional e tooltips que o visual nativo não faz.
  • Tabelas desconectadas e medidas de seleção dão interações ricas sem bagunçar os filtros da página.
  • PBIP no Git torna o relatório revisável como qualquer outro código, com histórico do que mudou e por quê.
  • Uma fonte bem modelada (uma consulta só, tratada no Power Query) deixa o resto do relatório simples.

Experimente

  1. Abra o relatório publicado. A primeira carga leva alguns segundos, porque sprites e cartas vêm da internet.
  2. Escolha um Pokémon na lista, troque para Shiny ou Cartas e clique na evolução.
  3. Vá para a Arena, sorteie os times e clique em Batalhar.

Quer ver o código ou abrir no Power BI Desktop? Está tudo no repositório do projeto. E se você precisa de um relatório que vá além do visual padrão, me mande uma mensagem.

Dados: PokeAPI e Pokémon TCG Data. Pokémon e marcas relacionadas pertencem à Nintendo, Game Freak e The Pokémon Company. Projeto pessoal, sem fins comerciais.

Leia também

  • Dotinha: minhas partidas de Dota 2 num relatório do Power BI

    Montei um BI das minhas últimas partidas de Dota 2 com a API do OpenDota e os textos oficiais do jogo em português. Mostro as páginas e o detalhe que faz a atualização agendada funcionar sem gateway.

    5 min de leitura Power BI, Power Query, Projetos, HTML Content

  • K-Track: tudo que você assiste e lê, num só lugar

    Criei um app para acompanhar séries, animes, mangás, filmes e livros sem planilha e sem cinco aplicativos diferentes. Mostro o que ele faz, como foi construído e como começar de graça.

    5 min de leitura K-Track, Projetos, Python, FastAPI