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.

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 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.

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.


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.

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.

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.

Como funciona por dentro

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:
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
- Abra o relatório publicado. A primeira carga leva alguns segundos, porque sprites e cartas vêm da internet.
- Escolha um Pokémon na lista, troque para Shiny ou Cartas e clique na evolução.
- 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.