const getDataRanges = (extremes) => { var ranges = []; for (var dimension in extremes) { ranges[dimension] = extremes[dimension].max - extremes[dimension].min; } return ranges; } const getDataExtremes = (data)=> { var extremes = []; for (var i in data) { var point = data[i]; for (var dimension in point) { if (!extremes[dimension]) { extremes[dimension] = { min: 1000, max: 0 }; } if (point[dimension] < extremes[dimension].min) { extremes[dimension].min = point[dimension]; } if (point[dimension] > extremes[dimension].max) { extremes[dimension].max = point[dimension]; } } } return extremes; } const initMeans = (k, dataExtremes, dataRange) => { if (!k) { k = 3; } const means = []; while (k--) { var mean = []; for (var dimension in dataExtremes) { mean[dimension] = dataExtremes[dimension].min + Math.random() * dataRange[dimension]; } means.push(mean); } return means; } const makeAssignments = (means, data) => { const assignments = {}; for (var i in data) { var point = data[i]; var distances = []; for (var j in means) { var mean = means[j]; var sum = 0; for (var dimension in point) { var difference = point[dimension] - mean[dimension]; difference *= difference; sum += difference; } distances[j] = Math.sqrt(sum); } assignments[i] = distances.indexOf(Math.min.apply(null, distances)); } return assignments; } const setup = (data) => { const dataExtremes = getDataExtremes(data); const dataRange = getDataRanges(dataExtremes); const means = initMeans(3, dataExtremes, dataRange); return makeAssignments(means, data); } export default setup;