Fórmulas🔗

Definição. Expressão Groovy avaliada pelo Freeplane, escrita no texto de um nó ou no valor de um atributo, prefixada por =.

Onde funcionam🔗

LocalSintaxe
Texto do nó=expressão
Valor de atributo=expressão
Detalhe=expressão
NotaEm geral não

Pôr a fórmula no atributo costuma ser melhor: o texto do nó continua legível e o valor calculado fica na tabela.

Objetos disponíveis🔗

ObjetoÉ
nodeO nó em que a fórmula está
cO controlador da interface
configPreferências do Freeplane

Propriedades de node🔗

ExpressãoDevolve
node.textTexto
node.plainTextTexto sem marcação
node.idIdentificador
node.parentNó pai
node.childrenFilhos diretos
node.branchO nó e todos os descendentes
node.leavesSó as folhas do ramo
node.rootA raiz do mapa
node.mapO mapa
node['chave']Valor de atributo
node.attributes.namesChaves presentes
node.note.textTexto da nota
node.detail.textTexto do detalhe
node.icons.iconsLista de nomes de ícone
node.style.nameEstilo aplicado
node.link.textHiperlink
node.createdAt, node.modifiedAtDatas
node.foldedEstado de dobramento

Conversões🔗

Atributos são texto. As conversões seguras:

ConversãoComportamento
.num0Número; vazio e texto viram 0
.numNúmero; falha se não for numérico
.to.num0Idem num0
.textTexto
.dateData, se o formato for reconhecido

Use num0. É a diferença entre uma soma que funciona e um NullPointerException no dia em que alguém deixar um campo em branco.

Padrões úteis🔗

// Soma dos filhos
=node.children.sum { it['custo'].num0 }

// Soma do ramo inteiro
=node.branch.sum { it['custo'].num0 }

// Contagem de descendentes
=node.branch.size() - 1

// Contagem por ícone
=node.branch.count { it.icons.icons.contains('button_ok') }

// Média
=node.children ? node.children.sum { it['nota'].num0 } / node.children.size() : 0

// Máximo
=node.children.collect { it['custo'].num0 }.max()

// Concatenação dos filhos
=node.children.collect { it.text }.join(', ')

// Percentual concluído
=def t = node.leaves.size()
 def d = node.leaves.count { it.icons.icons.contains('button_ok') }
 t ? "${(d*100/t).round()}%" : "—"

// Dias até um prazo
=((Date.parse('yyyy-MM-dd', node['prazo']) - new Date()) as int) + "d"

// Referência a outro nó pelo ID
=node.map.node('ID_1673829104')['valor'].num0

Recálculo🔗

Fórmulas são reavaliadas quando algo de que dependem muda. Ferramentas → Atualizar fórmulas força o recálculo de tudo.

Duas classes de problema:

  • Ciclos — A depende de B que depende de A. Detectado e reportado.
  • Dependências implícitasnew Date() não dispara recálculo ao virar o dia. Atualize à mão.

Erros comuns🔗

MensagemCausa
NullPointerExceptionAtributo ausente; use num0 ou teste antes
A fórmula aparece como textoAvaliação de fórmulas desligada nas preferências
MissingPropertyExceptionNome de propriedade incorreto
groovy.lang.MissingMethodExceptionMétodo que não existe nessa versão da API
Formula cycle detectedDependência circular
Resultado 0 inesperadoAtributo com texto onde se espera número

Segurança🔗

Fórmulas são código, e rodam ao abrir o mapa. Um .mm recebido de terceiros pode conter fórmulas com acesso a arquivos e rede, conforme as permissões que você concedeu.

Trate como trataria uma planilha com macros: as permissões de script devem ser as mínimas necessárias.

Erros comuns

  • Encher o mapa de fórmulas até a abertura ficar lenta — toda fórmula é reavaliada
  • Referenciar nós por texto em vez de ID, e ver a fórmula quebrar quando alguém renomeia
  • Esquecer que valores de atributo são texto e somar strings sem num0
  • Criar dependência circular entre fórmulas e receber um erro difícil de rastrear

Perguntas para reflexão

  1. Por que o atributo costuma ser o lugar certo para a fórmula?
  2. O que num0 faz, e por que ele é necessário?
  3. Qual a diferença entre node.children, node.branch e node.leaves?
  4. Escreva a fórmula que soma o atributo custo de todos os filhos.

Artigos relacionados

Referências🔗

  1. Freeplane — Formulas
  2. Freeplane — Scripting reference