Campo Calculado (Script)
Introdução
Campos calculados permitem a criação de fórmulas matemáticas que usam valores associados às respostas para calcular valores diversos, tais como médias, valores máximos, mínimos, desvíos padrões, etc.
Para construir uma fórmula você pode usar qualquer tipo de campo/resposta que tenha um valor numérico atribuído.
Veja abaixo a lista de questões que possuem ou, podem possuir, valores numéricos associados e podem ser usadas em uma fórmula:
- Questões numéricas (Inteiros, decimais e quantidade usando Emojis)
- Questões de seleção única (Menu suspenso, Rádio e Botões)
- Questões de seleção múltipla (Caixas de seleção e Botões)
- Questões de data e hora
- Questões de avaliação (Expressões faciais e Emojis)
- Questões de envio de arquivos (número de arquivos enviados)
Criando uma fórmula simples
Imagine que você queira criar uma fórmula que calcule o peso médio de uma série de amostras de determinado produto. Assim, imagine que o formulário tenha as seguintes questões:
- Peso da amostra 1
- Peso da amostra 2
- Peso da amostra 3
Neste caso, cada pergunta deve ser configurada com um nome de campo único, por exemplo,
peso_amostra_1
, peso_amostra_2
e peso_amostra_3
.
// TODO: Adicionar imagens
Para isso, você deve criar um campo calculado e, em seguida, adicionar a fórmula desejada:
function calculateValue() {
return (resp.peso_amostra_1.number
+ resp.peso_amostra_2.number
+ resp.peso_amostra_3.number) / 3;
}
Vamos analisar cada parte da fórmula:
function calculateValue()
é a função que será executada para calcular o valor do campo calculado. Essa função não pode ser renomeada, ela deve sempre ter esse nome, não pode receber parâmetros e deve retornar um valor numérico ounull
(nulo/vazio).resp
é um objeto que contém todas as respostas do formulário.resp.peso_amostra_1
é uma estrutura que contém os dados associados à resposta da perguntapeso_amostra_1
, tais como:number
é o valor numérico da respostaname
é o nome do campo da pergunta, ex.:peso_amostra_1
tags
é uma lista detags
associadas à pergunta- Por fim, a fórmula calcula a média aritmética dos valores das respostas, somando
peso_amostra_1
,peso_amostra_2
,peso_amostra_3
e dividindo por 3.
Você pode usar qualquer nome para as variáveis, mas é recomendado que você use nomes que façam sentido para o seu formulário.
O editor de código possui autocomplete
, ou seja, ele irá sugerir os nomes de variáveis e funções disponíveis para você usar na fórmula.
Você pode usar as teclas Ctrl+Space
ou Ctrl+Shift+Space
para ativar o autocomplete manualmente.
Atributos gerais das respostas
Todas as respostas possuem no mínimo três atributos: name
, tags
e um ou mais atributos específicos
do tipo de resposta, por exemplo, number
para questões numéricas, text
para questões de texto, etc.
name {#name]
name: string
Nome da pergunta. Exemplo: peso_amostra_1
tags [tags]
tags: string[];
Lista de tags da questão, exemplo: ['peso', 'amostra']
As tags
são usadas para agrupar questões e facilitar a criação de fórmulas.
Por exemplo, para calcular a média dos pesos de várias amostras, basta colocar uma tag
em cada questão de peso, por exemplo, #peso
, e usar essa tag na fórmula:
function calculateValue() {
return avgByTag('#peso');
}
Onde avgByTag
significa: "average by tag", ou seja, "média por tag".
Atributos específicos das respostas
Veja abaixo a lista de atributos específicos disponíveis para cada tipo de resposta:
text
text?: string;
Conteúdo textual da resposta, disponível para questões do tipo:
- Texto de uma linha
- Texto de várias linhas
O caractere "?" indica que o atributo é opcional, ou seja, ele pode ou não existir. Se o usuário responder à questão o atributo existirá, caso contrário, ele não existirá.
label
label?: string;
Etiqueta ou Texto vinculado à opção selecionada, disponível para questões do tipo:
- Seleção única
- Seleção múltipla
- Expressões faciais
number
number?: number;
Conteúdo numérico da resposta, seja o conteúdo fornecido pelo usuário, seja o conteúdo numérico vinculado à opção selecionada. Disponível para questões do tipo:
- Números inteiro
- Números decimais
- Quantidade usando Emojis
- Fórmula matemática
- Seleção única/simples
- Expressões faciais
- Tempo/Hora
dateStr
dateStr?: string;
Data em forma de texto (string).
Formato: YYYY-MM-DDTHH:MM:SSZ
, ex: 2030-12-31T23:59:59Z
Disponível para questões do tipo:
- Data
- Data e hora
lat
lat?: number;
Latitude da coordenada geográfica informada na resposta
lon
lon?: number;
Longitude da coordenada geográfica informada na resposta
items
items?: ISelectedItem[];
Lista de itens selecionados, disponível para questões do tipo:
- Seleção múltipla
- Ordenação
Cada item da lista de items
possui os seguintes atributos:
label: string
: Etiqueta ou Texto vinculado à opção selecionada.number?: number
: Conteúdo numérico da opção selecionada.position?: number
: Número que representa a ordem escolhida pelo usuário para o item selecionado. Disponível apenas nas questões do tipoOrdenação
Funções disponíveis
As funções abaixo são ferramentas que auxiliam na criação de fórmulas, permitindo que você realize cálculos complexos em dezenas ou centenas de respostas com apenas uma linha de código.
all
function all(): IResponse[];
Retorna uma lista (array) com todas as respostas existentes até o momento de execução do código, ou seja, as repostas das perguntas que aparecem antes deste elemento.
Note que nem sempre existirá resposta para uma pergunta posicionada antes da fórmula, pois as perguntas podem ser "puladas" por meio de uma lógica de navegação ou simplesmente não serem respondidas.
Este aviso vale para todas as funções que retornam uma lista de respostas.
findByTag
function findByTag(oneOrMoreTagNames: string | string[]): IResponse[];
Retorna uma lista (array) com as respostas que possuem as tags especificadas.
Somente as perguntas que aparecem antes deste elemento serão analisadas.
Exemplo:
A função abaixo retorna a quantidade de respostas que possuem a tag #peso
, ou seja,
a quantidade de amostras preenchidas pelo usuário.
function calculateValue() {
const qntAmostras = findByTag('#peso').filter(r => hasContent(r.number)).length;
return qntAmostras;
}
avgByTag
function avgByTag(...oneOrMoreTagNames: string[]): number;
Calcula a média dos valores numéricos das respostas que possuem as tags especificadas.
Respostas que não possuem valor numérico são ignoradas.
Somente as perguntas que aparecem antes deste elemento serão analisadas.
Evite calcular médias de forma manual, pois se alguma das respostas estiver em branco (não preenchida) o resultado final poderá diferir do esperado.
Ex.: Se o você usar a seguinte fórmula para calcular a média de 3 pesos: (peso1 + peso2 + peso3) / 3
, o resultado
só será correto se todas as 3 amostras forem preenchidas. Caso contrário, o resultado será incorreto.
Image que o usuário preencheu apenas 2 amostras, ou seja, peso1
e peso2
, e deixou a terceira amostra em branco,
neste caso, o resultado da fórmula será: (peso1 + peso2) / 3
, que é diferente do resultado correto: (peso1 + peso2) / 2
.
Para evitar esse tipo de situação, recomenda-se usar a função avgByTag
para calcular a média,
pois ela trata adequadamente as respostas em branco, ou seja, o resultado será sempre correto.
sumByTag
function sumByTag(...oneOrMoreTagNames: string[]): number;
Calcula o somatório dos valores numéricos das respostas que possuem as tags especificadas.
Somente as perguntas que aparecem antes deste elemento serão analisadas.
countByTag
function countByTag(...oneOrMoreTagNames: string[]): number;
Retorna a quantidade de respostas que possuem as tags especificadas.
Somente as perguntas que aparecem antes deste elemento serão analisadas.
maxByTag
function maxByTag(...oneOrMoreTagNames: string[]): number | undefined;
Retorna o maior valor numérico existente nas respostas que possuem as tags especificadas ou 'undefined' caso nenhum valor seja encontrado.
Respostas que não possuem valor numérico são ignoradas.
Somente as perguntas que aparecem antes deste elemento serão analisadas.
minByTag
function minByTag(...oneOrMoreTagNames: string[]): number | undefined;
Retorna o menor valor numérico existente nas respostas que possuem as tags especificadas ou 'undefined' caso nenhum valor seja encontrado.
Respostas que não possuem valor numérico são ignoradas.
Somente as perguntas que aparecem antes deste elemento serão analisadas.
hasContent
declare function hasContent(value: any): boolean;
Retorna true
caso o valor informado seja diferente de undefined
, null
, []
ou uma string vazia (''
).
isEmpty
declare function isEmpty(value: any): boolean;
Retorna true
caso o valor informado seja undefined
, null
, []
ou uma string vazia (''
).
Exemplos
Exemplo 1
Neste exemplo iremos mostrar como calcular os valores da Fórmula de Bhaskara. O objetivo deste exemplo é mostrar como armazenar valores parciais em variáveis e como usar esses valores para realizar cálculos mais complexos.
Neste exemplo veremos, também, como usar funções matemáticas pré-definas, como Math.sqrt
e Math.pow
.
Definição da fórmula de Bhaskara:
function calculateValue() {
let a = resp.a.number;
let b = resp.b.number;
let c = resp.c.number;
let delta = Math.pow(b, 2) - 4 * a * c;
let x1 = (-b + Math.sqrt(delta)) / (2 * a);
let x2 = (-b - Math.sqrt(delta)) / (2 * a);
return x1; // ou x2
}
Onde:
Math.pow(b, 2)
é equivalente a b²
Math.sqrt(delta)
é equivalente a √delta
Exemplo 2
Neste exemplo veremos como calcular a sequência de Fibonacci. O Objetivo deste exemplo é mostrar que é possível definir e usar funções diversas, inclusive funções recursivas, permitindo assim, a criação de cálculos mais complexos.
function calculateValue() {
const n = resp.any_question_answer.number;
return fibonacci(n);
}
function fibonacci(n: number): number {
if (n <= 1) {
return n;
}
return fibonacci(n - 1) + fibonacci(n - 2);
}
Funções matemáticas pré-definidas
Name | Description |
---|---|
abs(x) | Retorna o valor absoluto de x |
acos(x) | Retorna o arco cosseno de x, em radianos |
acosh(x) | Retorna o arco cosseno hiperbólico de x |
asin(x) | Retorna o arco seno de x, em radianos |
asinh(x) | Retorna o arco-seno hiperbólico de x |
atan(x) | Retorna o arco tangente de x como um valor numérico entre -PI/2 e PI/2 radianos |
atan2(y, x) | Retorna o arco tangente do quociente de seus argumentos |
atanh(x) | Retorna o arco tangente hiperbólico de x |
cbrt(x) | Retorna a raiz cúbica de x |
ceil(x) | Retorna x, arredondado para cima para o inteiro mais próximo |
clz32(x) | Retorna o número de zeros à esquerda em uma representação binária de 32 bits de x |
cos(x) | Retorna o cosseno de x (x está em radianos) |
cosh(x) | Retorna o cosseno hiperbólico de x |
exp(x) | Retorna o valor de Ex |
expm1(x) | Retorna o valor de Ex menos 1 |
floor(x) | Retorna x, arredondado para baixo para o inteiro mais próximo |
fround(x) | Retorna a representação flutuante mais próxima (precisão única de 32 bits) de um número |
log(x) | Retorna o logaritmo natural de x |
log10(x) | Retorna o logaritmo de base 10 de x |
log1p(x) | Retorna o logaritmo natural de 1 + x |
log2(x) | Retorna o logaritmo de base 2 de x |
max(x1,x2,..) | Retorna o número com o maior valor |
min(x1,x2,..) | Retorna o número com o menor valor |
pow(x, y) | Retorna o valor de x elevado a y |
random() | Retorna um número aleatório entre 0 e 1 |
round(x) | Arredonda x para o inteiro mais próximo |
sign(x) | Retorna o sinal de um número (verifica se é positivo, negativo ou zero) |
sin(x) | Retorna o seno de x (x está em radianos) |
sinh(x) | Retorna o seno hiperbólico de x |
sqrt(x) | Retorna a raiz quadrada de x |
tan(x) | Retorna a tangente de um ângulo |
tanh(x) | Retorna a tangente hiperbólica de um número |
trunc(x) | Retorna a parte inteira de um número (x) |
Constantes matemáticas pré-definidas
Nome | Descrição |
---|---|
Math.E | Retorna o número de Euler (aprox. 2,718) |
Math.PI | Retorna PI (aprox. 3,14) |
Math.SQRT2 | Retorna a raiz quadrada de 2 (aprox. 1,414) |
Math.SQRT1_2 | Retorna a raiz quadrada de 1/2 (aprox. 0,707) |
Math.LN2 | Retorna o logaritmo natural de 2 (aprox. 0,693) |
Math.LN10 | Retorna o logaritmo natural de 10 (aprox. 2,302) |
Math.LOG2E | Retorna o logaritmo de base 2 de E (aprox. 1,442) |
Math.LOG10E | Retorna o logaritmo de base 10 de E (aprox. 0,434) |