-
-
Notifications
You must be signed in to change notification settings - Fork 1.9k
/
Copy pathsieve.js
107 lines (93 loc) · 3.11 KB
/
sieve.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
/**
* Copyright 2012-2017, Plotly, Inc.
* All rights reserved.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
'use strict';
module.exports = Sieve;
var Lib = require('../../lib');
var BADNUM = require('../../constants/numerical').BADNUM;
/**
* Helper class to sieve data from traces into bins
*
* @class
* @param {Array} traces
* Array of calculated traces
* @param {boolean} [separateNegativeValues]
* If true, then split data at the same position into a bar
* for positive values and another for negative values
* @param {boolean} [dontMergeOverlappingData]
* If true, then don't merge overlapping bars into a single bar
*/
function Sieve(traces, separateNegativeValues, dontMergeOverlappingData) {
this.traces = traces;
this.separateNegativeValues = separateNegativeValues;
this.dontMergeOverlappingData = dontMergeOverlappingData;
// for single-bin histograms - see histogram/calc
var width1 = Infinity;
var positions = [];
for(var i = 0; i < traces.length; i++) {
var trace = traces[i];
for(var j = 0; j < trace.length; j++) {
var bar = trace[j];
if(bar.p !== BADNUM) positions.push(bar.p);
}
if(trace[0] && trace[0].width1) {
width1 = Math.min(trace[0].width1, width1);
}
}
this.positions = positions;
var dv = Lib.distinctVals(positions);
this.distinctPositions = dv.vals;
if(dv.vals.length === 1 && width1 !== Infinity) this.minDiff = width1;
else this.minDiff = Math.min(dv.minDiff, width1);
this.binWidth = this.minDiff;
this.bins = {};
}
/**
* Sieve datum
*
* @method
* @param {number} position
* @param {number} value
* @returns {number} Previous bin value
*/
Sieve.prototype.put = function put(position, value) {
var label = this.getLabel(position, value),
oldValue = this.bins[label] || 0;
this.bins[label] = oldValue + value;
return oldValue;
};
/**
* Get current bin value for a given datum
*
* @method
* @param {number} position Position of datum
* @param {number} [value] Value of datum
* (required if this.separateNegativeValues is true)
* @returns {number} Current bin value
*/
Sieve.prototype.get = function put(position, value) {
var label = this.getLabel(position, value);
return this.bins[label] || 0;
};
/**
* Get bin label for a given datum
*
* @method
* @param {number} position Position of datum
* @param {number} [value] Value of datum
* (required if this.separateNegativeValues is true)
* @returns {string} Bin label
* (prefixed with a 'v' if value is negative and this.separateNegativeValues is
* true; otherwise prefixed with '^')
*/
Sieve.prototype.getLabel = function getLabel(position, value) {
var prefix = (value < 0 && this.separateNegativeValues) ? 'v' : '^',
label = (this.dontMergeOverlappingData) ?
position :
Math.round(position / this.binWidth);
return prefix + label;
};