Fórmulas
Nós que calculam: somas, contagens, datas e condições escritas em Groovy dentro do próprio mapa.
O que você vai aprender
- Escrever fórmulas em nós e atributos
- Alcançar pais, filhos, irmãos e atributos a partir de uma fórmula
- Montar somas, contagens, percentuais e cálculos de data
- Entender recálculo, dependências e erros comuns
Antes de começar
Fórmulas🔗
Um nó cujo texto começa com = é tratado como fórmula. O que vem depois é uma expressão Groovy, avaliada pelo Freeplane, e o resultado é o que aparece no mapa.
É a mesma ideia de uma célula de planilha, aplicada a uma árvore.
=2 + 2
Esse nó mostra 4.
A partir daí a coisa fica interessante, porque a expressão tem acesso ao mapa inteiro.
Ligando as fórmulas🔗
Fórmulas dependem de scripting estar habilitado. Em Ferramentas → Preferências → Scripts, ative a execução de fórmulas e defina as permissões. Sem isso, o nó mostra a fórmula em vez do resultado.
O nível de permissão importa: fórmulas que só leem o mapa exigem pouco; fórmulas que leem arquivos ou acessam a rede exigem permissões que você deve conceder com consciência. Um mapa recebido de terceiros pode conter fórmulas — trate como trataria uma macro de planilha.
O objeto node🔗
Dentro da fórmula, node é o nó em que ela está. As propriedades mais usadas:
| Expressão | O que devolve |
|---|---|
node.text | Texto do nó |
node.parent | Nó pai |
node.children | Lista dos filhos |
node.branch | O nó e todos os descendentes |
node.leaves | Só as folhas do ramo |
node['chave'] | Valor do atributo |
node.note.text | Texto da nota |
node.icons.icons | Lista de ícones |
node.detail.text | Texto do detalhe |
node.id | Identificador estável |
node.map | O mapa |
Somando filhos🔗
O caso mais comum. Cada filho tem um atributo custo; o pai mostra a soma:
=node.children.sum { it['custo'].num0 }
num0 converte o atributo em número tratando vazio e texto como zero — sem isso, um atributo em branco quebra a soma. Há também num (mais estrito) e to.num0.
Somando o ramo inteiro, não só os filhos diretos:
=node.branch.sum { it['custo'].num0 }Contando🔗
Quantos descendentes existem:
=node.branch.size() - 1
Quantos estão concluídos, pelo ícone:
=node.branch.count { it.icons.icons.contains('button_ok') }
Os nomes internos dos ícones (button_ok, button_cancel, full-1, help, yes) aparecem no diálogo de filtro por ícone e nos add-ons de desenvolvimento.
Percentual de conclusão🔗
Juntando as duas ideias:
=def t = node.leaves.size()
def d = node.leaves.count { it.icons.icons.contains('button_ok') }
t ? "${(d*100/t).round()}% (${d}/${t})" : "vazio"
Fórmulas podem ter várias linhas — o valor da última expressão é o resultado.
Fórmulas longas ficam melhor num script guardado à parte, chamado da fórmula. Assim você não edita código dentro de um nó estreito e pode reaproveitar em vários mapas.
Datas🔗
Prazo em relação a hoje:
=def p = Date.parse('yyyy-MM-dd', node['prazo'])
def d = (p - new Date()).intdiv(1)
d < 0 ? "atrasado ${-d}d" : "faltam ${d}d"
Isso só funciona se as datas estiverem num formato único — mais um argumento para restringir os valores do atributo prazo em Gerenciar atributos do mapa.
Fórmulas em atributos🔗
O valor de um atributo também pode ser fórmula. Isso é frequentemente melhor que pôr a fórmula no texto: o nó continua legível e o número calculado fica na tabela de atributos.
Crie o atributo total com valor =node.children.sum { it['custo'].num0 } e pronto.
Referências a outros nós🔗
Um nó pode ler outro pelo ID:
=node.map.node('ID_1234567890').text
Ou por busca:
=node.map.root.find { it.text == 'Orçamento total' }.first()['valor']
A primeira forma é robusta (o ID não muda); a segunda é frágil (o texto muda). Prefira IDs para dependências que precisam durar.
Recálculo🔗
Fórmulas são recalculadas quando algo de que dependem muda, e também sob demanda com Ferramentas → Atualizar fórmulas (ou F5, conforme configuração).
Duas armadilhas de dependência:
- Ciclos: A soma B, B soma A. O Freeplane detecta e reporta erro.
- Dependências implícitas: uma fórmula que lê o relógio (
new Date()) não é recalculada sozinha ao virar o dia. Atualize à mão ou aceite a defasagem.
Erros🔗
Quando a fórmula falha, o nó mostra a mensagem de erro. As causas frequentes:
| Sintoma | Causa provável |
|---|---|
NullPointerException | Atributo inexistente; use num0 ou teste antes |
| Fórmula aparece como texto | Scripting desativado nas preferências |
MissingPropertyException | Nome de propriedade errado |
Resultado sempre 0 | Atributo com texto onde se espera número |
Formula cycle detected | Duas fórmulas dependendo uma da outra |
Erros comuns
- Usar
numonde o atributo pode estar vazio;num0é o padrão seguro - Depender do texto de outro nó para localizá-lo — qualquer edição quebra
- Habilitar permissões amplas de script e abrir mapas de origem desconhecida
- Esperar recálculo automático de fórmulas que dependem da data atual
Na prática🔗
Monte um orçamento:
- Um ramo
Orçamentocom três fases, cada uma com quatro itens. - Em cada item, atributo
custocom um número. - Em cada fase, atributo
subtotalcom=node.children.sum { it['custo'].num0 }. - Na raiz do ramo,
totalsomando obranch. - Marque metade dos itens com o ícone de check e some um nó com o percentual de conclusão.
- Mude um custo e confira que tudo recalculou.
Você aprendeu
- Texto começando com
=é fórmula Groovy avaliada no mapa node.children,node.branch,node.leavesenode['chave']cobrem a maioria dos casosnum0evita que atributos vazios quebrem somas- Referencie por ID, não por texto; e desconfie de fórmulas em mapas de terceiros
Perguntas para reflexão
- Que prefixo transforma o texto de um nó em fórmula?
- Qual a diferença entre
node.children,node.branchenode.leaves? - O que
num0evita, e em que situação exata? - Por que referenciar por
IDem vez de por texto?