const type = require('./type'); const {log, pow, floor, abs} = Math; const analyze = (data, key=null) => { const r = { min: Number.MAX_VALUE, max: Number.MAX_VALUE*-1, sum: 0, values: [], count: 0 }; if (type(data) === 'object') { data = Object.values(data); } data.forEach(val => { if (key && type(val) === 'object') val = val[key]; if (val !== undefined && val !== null && !isNaN(val)) { r.values.push(val); r.sum += val; if (val < r.min) r.min = val; if (val > r.max) r.max = val; r.count += 1; } }); r.domain = [r.min, r.max]; r.limits = (mode, num) => limits(r, mode, num) return r; }; const limits = (data, mode='equal', num=7) => { if (type(data) == 'array') { data = analyze(data); } const {min,max} = data; const values = data.values.sort((a,b) => a-b); if (num === 1) { return [min,max]; } const limits = []; if (mode.substr(0,1) === 'c') { // continuous limits.push(min); limits.push(max); } if (mode.substr(0,1) === 'e') { // equal interval limits.push(min); for (let i=1; i 0'); } const min_log = Math.LOG10E * log(min); const max_log = Math.LOG10E * log(max); limits.push(min); for (let i=1; i pb const pr = p - pb; limits.push((values[pb]*(1-pr)) + (values[pb+1]*pr)); } } limits.push(max); } else if (mode.substr(0,1) === 'k') { // k-means clustering /* implementation based on http://code.google.com/p/figue/source/browse/trunk/figue.js#336 simplified for 1-d input values */ let cluster; const n = values.length; const assignments = new Array(n); const clusterSizes = new Array(num); let repeat = true; let nb_iters = 0; let centroids = null; // get seed values centroids = []; centroids.push(min); for (let i=1; i 200) { repeat = false; } } // finished k-means clustering // the next part is borrowed from gabrielflor.it const kClusters = {}; for (let j=0; j a-b); limits.push(tmpKMeansBreaks[0]); for (let i=1; i < tmpKMeansBreaks.length; i+= 2) { const v = tmpKMeansBreaks[i]; if (!isNaN(v) && (limits.indexOf(v) === -1)) { limits.push(v); } } } return limits; } module.exports = {analyze, limits};