i’ve managed to make it work. If it is of any use to someone:
dagfuncs.customAvgAggFunc = function(params) {
let sum = 0;
let count = 0;
let squaredDifferences = 0;
params.values.forEach((value) => {
const groupNode =
value !== null && value !== undefined && typeof value === 'object';
if (groupNode) {
// We are aggregating groups, so we take the
// aggregated values to calculate a weighted average.
sum += value.avg * value.count;
count += value.count;
} else {
// Skip values that are not numbers (i.e., skip empty values).
if (typeof value === 'number') {
sum += value;
count++;
}
}
});
let avg = null;
if (count !== 0) {
avg = sum / count;
}
// Calculate the squared differences from the average
params.values.forEach((value) => {
if (typeof value === 'number') {
squaredDifferences += Math.pow(value - avg, 2);
}
});
// Compute the standard deviation (using sample standard deviation formula)
let variance = squaredDifferences / (count - 1);
let standardDeviation = Math.sqrt(variance);
// Compute the RSD
let rsd = (avg === 0) ? 0 : (standardDeviation / avg) * 100;
const result = {
count: count,
avg: avg,
rsd: rsd,
toString: function() {
return (this.avg === 0) ? `${Math.round(this.avg)}` : `${Math.round(this.avg)} (${this.rsd.toFixed(1)}% RSD)`;
}
};
return result;
};
dagfuncs.roundedCustomAvgAggFunc = function(params) {
const result = dagfuncs.customAvgAggFunc(params);
if (result.avg !== null) {
result.avg = Math.round(result.avg);
result.rsd = parseFloat(result.rsd.toFixed(1));
}
return result;
};
However, I am also using valueFormatter on my columns:
"valueFormatter": {"function":"Number(params.value).toFixed(0)"}
} for i in display_columns]
This means that valueFormatter now renders new avg+rsd values to nan, since it can’t handle strings. Any ideas how to apply valueFormatter only to rows that aren’t aggregated or how to valueFormat only number values but not string ones?
Also, my custom agg function renders all headervalues as func(value), I would like to replace func part with smth else but haven’t figured it out how to do this yet.