mirror of
https://github.com/Jermolene/TiddlyWiki5
synced 2024-09-18 02:09:43 +00:00
c543036a0f
* Added missing trigonometrics filter operators This PR adds support to trigonometry operators, allowing to create spider graphs and other geometric shapes with filters. * Adds the missing trigonometric filter operators This PR adds support to the missing trigonometric filter operators (cos, sin, tan, acos, asin, atan, atan2), allowing to create spider graphs, [pie charts, donut charts, polar charts](https://ffoodd.github.io/chaarts/pie-charts.html) and other geometric shapes with filters, which was previously not possible without add-ons. Example : `[[2]cos[]] = -0.4161468365471424` See also this radar chart made in wikitext by @saqimtiaz using the new trigonometric operators : https://saqimtiaz.github.io/sq-tw/temp/radar-chart-demo.html * Add documentation for the Trigonometric Operators Accompanies code changes #6127 * Fix formatting of atan2 Operator.tid Removed two empty lines at the end of the tiddler * Add examples for the trigonometric operators Accompanies code changes Jermolene#6127 * Fix version in the doc for trigonometric operators This PR fix the content of the documentation tiddlers regarding trigonometric operators (#6131). <<.from-version "5.1.20">> was changed to <<.from-version "5.1.21">> * Fix formatting of atan2 Operator.tid Removed two empty lines at the end of the tiddler * Add missing parameter to atan2 operator The atan2 operator needs two parameters (Binary Mathematics Operators), this PR adds the second one that was missing. See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/atan2 for more technical info on the atan2 function.
248 lines
6.0 KiB
JavaScript
248 lines
6.0 KiB
JavaScript
/*\
|
|
title: $:/core/modules/filters/math.js
|
|
type: application/javascript
|
|
module-type: filteroperator
|
|
|
|
Filter operators for math. Unary/binary operators work on each item in turn, and return a new item list.
|
|
|
|
Sum/product/maxall/minall operate on the entire list, returning a single item.
|
|
|
|
Note that strings are converted to numbers automatically. Trailing non-digits are ignored.
|
|
|
|
* "" converts to 0
|
|
* "12kk" converts to 12
|
|
|
|
\*/
|
|
(function(){
|
|
|
|
/*jslint node: true, browser: true */
|
|
/*global $tw: false */
|
|
"use strict";
|
|
|
|
exports.negate = makeNumericBinaryOperator(
|
|
function(a) {return -a}
|
|
);
|
|
|
|
exports.abs = makeNumericBinaryOperator(
|
|
function(a) {return Math.abs(a)}
|
|
);
|
|
|
|
exports.ceil = makeNumericBinaryOperator(
|
|
function(a) {return Math.ceil(a)}
|
|
);
|
|
|
|
exports.floor = makeNumericBinaryOperator(
|
|
function(a) {return Math.floor(a)}
|
|
);
|
|
|
|
exports.round = makeNumericBinaryOperator(
|
|
function(a) {return Math.round(a)}
|
|
);
|
|
|
|
exports.trunc = makeNumericBinaryOperator(
|
|
function(a) {return Math.trunc(a)}
|
|
);
|
|
|
|
exports.untrunc = makeNumericBinaryOperator(
|
|
function(a) {return Math.ceil(Math.abs(a)) * Math.sign(a)}
|
|
);
|
|
|
|
exports.sign = makeNumericBinaryOperator(
|
|
function(a) {return Math.sign(a)}
|
|
);
|
|
|
|
exports.add = makeNumericBinaryOperator(
|
|
function(a,b) {return a + b;}
|
|
);
|
|
|
|
exports.subtract = makeNumericBinaryOperator(
|
|
function(a,b) {return a - b;}
|
|
);
|
|
|
|
exports.multiply = makeNumericBinaryOperator(
|
|
function(a,b) {return a * b;}
|
|
);
|
|
|
|
exports.divide = makeNumericBinaryOperator(
|
|
function(a,b) {return a / b;}
|
|
);
|
|
|
|
exports.remainder = makeNumericBinaryOperator(
|
|
function(a,b) {return a % b;}
|
|
);
|
|
|
|
exports.max = makeNumericBinaryOperator(
|
|
function(a,b) {return Math.max(a,b);}
|
|
);
|
|
|
|
exports.min = makeNumericBinaryOperator(
|
|
function(a,b) {return Math.min(a,b);}
|
|
);
|
|
|
|
exports.fixed = makeNumericBinaryOperator(
|
|
function(a,b) {return Number.prototype.toFixed.call(a,Math.min(Math.max(b,0),100));}
|
|
);
|
|
|
|
exports.precision = makeNumericBinaryOperator(
|
|
function(a,b) {return Number.prototype.toPrecision.call(a,Math.min(Math.max(b,1),100));}
|
|
);
|
|
|
|
exports.exponential = makeNumericBinaryOperator(
|
|
function(a,b) {return Number.prototype.toExponential.call(a,Math.min(Math.max(b,0),100));}
|
|
);
|
|
|
|
exports.power = makeNumericBinaryOperator(
|
|
function(a,b) {return Math.pow(a,b);}
|
|
);
|
|
|
|
exports.log = makeNumericBinaryOperator(
|
|
function(a,b) {
|
|
if(b) {
|
|
return Math.log(a)/Math.log(b);
|
|
} else {
|
|
return Math.log(a);
|
|
}
|
|
}
|
|
);
|
|
|
|
exports.sum = makeNumericReducingOperator(
|
|
function(accumulator,value) {return accumulator + value},
|
|
0 // Initial value
|
|
);
|
|
|
|
exports.product = makeNumericReducingOperator(
|
|
function(accumulator,value) {return accumulator * value},
|
|
1 // Initial value
|
|
);
|
|
|
|
exports.maxall = makeNumericReducingOperator(
|
|
function(accumulator,value) {return Math.max(accumulator,value)},
|
|
-Infinity // Initial value
|
|
);
|
|
|
|
exports.minall = makeNumericReducingOperator(
|
|
function(accumulator,value) {return Math.min(accumulator,value)},
|
|
Infinity // Initial value
|
|
);
|
|
|
|
exports.median = makeNumericArrayOperator(
|
|
function(values) {
|
|
var len = values.length, median;
|
|
values.sort();
|
|
if(len % 2) {
|
|
// Odd, return the middle number
|
|
median = values[(len - 1) / 2];
|
|
} else {
|
|
// Even, return average of two middle numbers
|
|
median = (values[len / 2 - 1] + values[len / 2]) / 2;
|
|
}
|
|
return [median];
|
|
}
|
|
);
|
|
|
|
exports.average = makeNumericReducingOperator(
|
|
function(accumulator,value) {return accumulator + value},
|
|
0, // Initial value
|
|
function(finalValue,numberOfValues) {
|
|
return finalValue/numberOfValues;
|
|
}
|
|
);
|
|
|
|
exports.variance = makeNumericReducingOperator(
|
|
function(accumulator,value) {return accumulator + value},
|
|
0,
|
|
function(finalValue,numberOfValues,originalValues) {
|
|
return getVarianceFromArray(originalValues,finalValue/numberOfValues);
|
|
}
|
|
);
|
|
|
|
exports["standard-deviation"] = makeNumericReducingOperator(
|
|
function(accumulator,value) {return accumulator + value},
|
|
0,
|
|
function(finalValue,numberOfValues,originalValues) {
|
|
var variance = getVarianceFromArray(originalValues,finalValue/numberOfValues);
|
|
return Math.sqrt(variance);
|
|
}
|
|
);
|
|
|
|
//trigonometry
|
|
exports.cos = makeNumericBinaryOperator(
|
|
function(a) {return Math.cos(a)}
|
|
);
|
|
|
|
exports.sin = makeNumericBinaryOperator(
|
|
function(a) {return Math.sin(a)}
|
|
);
|
|
|
|
exports.tan = makeNumericBinaryOperator(
|
|
function(a) {return Math.tan(a)}
|
|
);
|
|
|
|
exports.acos = makeNumericBinaryOperator(
|
|
function(a) {return Math.acos(a)}
|
|
);
|
|
|
|
exports.asin = makeNumericBinaryOperator(
|
|
function(a) {return Math.asin(a)}
|
|
);
|
|
|
|
exports.atan = makeNumericBinaryOperator(
|
|
function(a) {return Math.atan(a)}
|
|
);
|
|
|
|
exports.atan2 = makeNumericBinaryOperator(
|
|
function(a,b) {return Math.atan2(a,b)}
|
|
);
|
|
|
|
//Calculate the variance of a population of numbers in an array given its mean
|
|
function getVarianceFromArray(values,mean) {
|
|
var deviationTotal = values.reduce(function(accumulator,value) {
|
|
return accumulator + Math.pow(value - mean, 2);
|
|
},0);
|
|
return deviationTotal/values.length;
|
|
};
|
|
|
|
function makeNumericBinaryOperator(fnCalc) {
|
|
return function(source,operator,options) {
|
|
var result = [],
|
|
numOperand = $tw.utils.parseNumber(operator.operand);
|
|
source(function(tiddler,title) {
|
|
result.push($tw.utils.stringifyNumber(fnCalc($tw.utils.parseNumber(title),numOperand)));
|
|
});
|
|
return result;
|
|
};
|
|
};
|
|
|
|
function makeNumericReducingOperator(fnCalc,initialValue,fnFinal) {
|
|
initialValue = initialValue || 0;
|
|
return function(source,operator,options) {
|
|
var result = [];
|
|
source(function(tiddler,title) {
|
|
result.push($tw.utils.parseNumber(title));
|
|
});
|
|
var value = result.reduce(function(accumulator,currentValue) {
|
|
return fnCalc(accumulator,currentValue);
|
|
},initialValue);
|
|
if(fnFinal) {
|
|
value = fnFinal(value,result.length,result);
|
|
}
|
|
return [$tw.utils.stringifyNumber(value)];
|
|
};
|
|
};
|
|
|
|
function makeNumericArrayOperator(fnCalc) {
|
|
return function(source,operator,options) {
|
|
var results = [];
|
|
source(function(tiddler,title) {
|
|
results.push($tw.utils.parseNumber(title));
|
|
});
|
|
results = fnCalc(results);
|
|
$tw.utils.each(results,function(value,index) {
|
|
results[index] = $tw.utils.stringifyNumber(value);
|
|
});
|
|
return results;
|
|
};
|
|
};
|
|
|
|
})();
|