webglimpse
Version:
Webglimpse is a data visualization library for the web.
107 lines • 12.6 kB
JavaScript
/*
* Copyright (c) 2014, Metron, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors
* may be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
// XXX: These probably belong in their own namespace
export function indexOf(vs, x) {
let a = 0;
let b = vs.length - 1;
while (a <= b) {
// Bitwise-or-zero truncates to integer
// tslint:disable-next-line:no-bitwise
const pivot = ((a + b) / 2) | 0;
const vPivot = vs[pivot];
if (vPivot < x) {
a = pivot + 1;
}
else if (vPivot > x) {
b = pivot - 1;
}
else {
// This is a little sloppy if either value is NaN, or if one is +0.0 and the other is -0.0
return pivot;
}
}
return -(a + 1);
}
export function indexNearest(vs, x) {
const i = indexOf(vs, x);
// Exact value found
if (i >= 0) {
return i;
}
// Find the closer of the adjacent values
const iAfter = -i - 1;
const iBefore = iAfter - 1;
if (iAfter >= vs.length) {
return iBefore;
}
if (iBefore < 0) {
return iAfter;
}
const diffAfter = vs[iAfter] - x;
const diffBefore = x - vs[iBefore];
return (diffAfter <= diffBefore ? iAfter : iBefore);
}
export function indexAfter(vs, x) {
const i = indexOf(vs, x);
// Exact value not found
if (i < 0) {
return (-i - 1);
}
// If the exact value was found, find the value's last occurrence
const n = vs.length;
for (let j = i + 1; j < n; j++) {
if (vs[j] > x) {
return j;
}
}
return n;
}
export function indexAtOrAfter(vs, x) {
const i = indexOf(vs, x);
// Exact value not found
if (i < 0) {
return (-i - 1);
}
// If the exact value was found, find the value's first occurrence
const n = vs.length;
for (let j = i; j > 0; j--) {
if (vs[j - 1] < x) {
return j;
}
}
return 0;
}
export function indexBefore(vs, x) {
return indexAtOrAfter(vs, x) - 1;
}
export function indexAtOrBefore(vs, x) {
return indexAfter(vs, x) - 1;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic29ydGVkX2FycmF5cy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy93ZWJnbGltcHNlL3V0aWwvc29ydGVkX2FycmF5cy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQTRCRztBQUdILG9EQUFvRDtBQUdwRCxNQUFNLFVBQVUsT0FBTyxDQUFDLEVBQVksRUFBRSxDQUFTO0lBQzNDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUNWLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDO0lBRXRCLE9BQU8sQ0FBQyxJQUFJLENBQUMsRUFBRTtRQUNYLHVDQUF1QztRQUN2QyxzQ0FBc0M7UUFDdEMsTUFBTSxLQUFLLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDaEMsTUFBTSxNQUFNLEdBQUcsRUFBRSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBRXpCLElBQUksTUFBTSxHQUFHLENBQUMsRUFBRTtZQUNaLENBQUMsR0FBRyxLQUFLLEdBQUcsQ0FBQyxDQUFDO1NBQ2pCO2FBQ0ksSUFBSSxNQUFNLEdBQUcsQ0FBQyxFQUFFO1lBQ2pCLENBQUMsR0FBRyxLQUFLLEdBQUcsQ0FBQyxDQUFDO1NBQ2pCO2FBQ0k7WUFDRCwwRkFBMEY7WUFDMUYsT0FBTyxLQUFLLENBQUM7U0FDaEI7S0FDSjtJQUVELE9BQU8sQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztBQUNwQixDQUFDO0FBSUQsTUFBTSxVQUFVLFlBQVksQ0FBQyxFQUFZLEVBQUUsQ0FBUztJQUNoRCxNQUFNLENBQUMsR0FBRyxPQUFPLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBRXpCLG9CQUFvQjtJQUNwQixJQUFJLENBQUMsSUFBSSxDQUFDLEVBQUU7UUFDUixPQUFPLENBQUMsQ0FBQztLQUNaO0lBRUQseUNBQXlDO0lBQ3pDLE1BQU0sTUFBTSxHQUFHLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUN0QixNQUFNLE9BQU8sR0FBRyxNQUFNLEdBQUcsQ0FBQyxDQUFDO0lBRTNCLElBQUksTUFBTSxJQUFJLEVBQUUsQ0FBQyxNQUFNLEVBQUU7UUFDckIsT0FBTyxPQUFPLENBQUM7S0FDbEI7SUFDRCxJQUFJLE9BQU8sR0FBRyxDQUFDLEVBQUU7UUFDYixPQUFPLE1BQU0sQ0FBQztLQUNqQjtJQUVELE1BQU0sU0FBUyxHQUFHLEVBQUUsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUM7SUFDakMsTUFBTSxVQUFVLEdBQUcsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUVuQyxPQUFPLENBQUMsU0FBUyxJQUFJLFVBQVUsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQztBQUN4RCxDQUFDO0FBSUQsTUFBTSxVQUFVLFVBQVUsQ0FBQyxFQUFZLEVBQUUsQ0FBUztJQUM5QyxNQUFNLENBQUMsR0FBRyxPQUFPLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBRXpCLHdCQUF3QjtJQUN4QixJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUU7UUFDUCxPQUFPLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7S0FDbkI7SUFFRCxpRUFBaUU7SUFDakUsTUFBTSxDQUFDLEdBQUcsRUFBRSxDQUFDLE1BQU0sQ0FBQztJQUNwQixLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRTtRQUM1QixJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLEVBQUU7WUFDWCxPQUFPLENBQUMsQ0FBQztTQUNaO0tBQ0o7SUFDRCxPQUFPLENBQUMsQ0FBQztBQUNiLENBQUM7QUFJRCxNQUFNLFVBQVUsY0FBYyxDQUFDLEVBQVksRUFBRSxDQUFTO0lBQ2xELE1BQU0sQ0FBQyxHQUFHLE9BQU8sQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFFekIsd0JBQXdCO0lBQ3hCLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRTtRQUNQLE9BQU8sQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztLQUNuQjtJQUVELGtFQUFrRTtJQUNsRSxNQUFNLENBQUMsR0FBRyxFQUFFLENBQUMsTUFBTSxDQUFDO0lBQ3BCLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUU7UUFDeEIsSUFBSSxFQUFFLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLENBQUMsRUFBRTtZQUNmLE9BQU8sQ0FBQyxDQUFDO1NBQ1o7S0FDSjtJQUNELE9BQU8sQ0FBQyxDQUFDO0FBQ2IsQ0FBQztBQUlELE1BQU0sVUFBVSxXQUFXLENBQUMsRUFBWSxFQUFFLENBQVM7SUFDL0MsT0FBTyxjQUFjLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNyQyxDQUFDO0FBSUQsTUFBTSxVQUFVLGVBQWUsQ0FBQyxFQUFZLEVBQUUsQ0FBUztJQUNuRCxPQUFPLFVBQVUsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2pDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKlxyXG4gKiBDb3B5cmlnaHQgKGMpIDIwMTQsIE1ldHJvbiwgSW5jLlxyXG4gKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxyXG4gKlxyXG4gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQgbW9kaWZpY2F0aW9uLFxyXG4gKiBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XHJcbiAqXHJcbiAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xyXG4gKiAgICBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cclxuICpcclxuICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxyXG4gKiAgICB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uXHJcbiAqICAgIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUgZGlzdHJpYnV0aW9uLlxyXG4gKlxyXG4gKiAzLiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBjb3B5cmlnaHQgaG9sZGVyIG5vciB0aGUgbmFtZXMgb2YgaXRzIGNvbnRyaWJ1dG9yc1xyXG4gKiAgICBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dFxyXG4gKiAgICBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXHJcbiAqXHJcbiAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiIEFORFxyXG4gKiBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRFxyXG4gKiBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFXHJcbiAqIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SXHJcbiAqIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFU1xyXG4gKiAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7XHJcbiAqIExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTlxyXG4gKiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVFxyXG4gKiAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJU1xyXG4gKiBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cclxuICovXHJcblxyXG5cclxuLy8gWFhYOiBUaGVzZSBwcm9iYWJseSBiZWxvbmcgaW4gdGhlaXIgb3duIG5hbWVzcGFjZVxyXG5cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBpbmRleE9mKHZzOiBudW1iZXJbXSwgeDogbnVtYmVyKTogbnVtYmVyIHtcclxuICAgIGxldCBhID0gMDtcclxuICAgIGxldCBiID0gdnMubGVuZ3RoIC0gMTtcclxuXHJcbiAgICB3aGlsZSAoYSA8PSBiKSB7XHJcbiAgICAgICAgLy8gQml0d2lzZS1vci16ZXJvIHRydW5jYXRlcyB0byBpbnRlZ2VyXHJcbiAgICAgICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm5vLWJpdHdpc2VcclxuICAgICAgICBjb25zdCBwaXZvdCA9ICgoYSArIGIpIC8gMikgfCAwO1xyXG4gICAgICAgIGNvbnN0IHZQaXZvdCA9IHZzW3Bpdm90XTtcclxuXHJcbiAgICAgICAgaWYgKHZQaXZvdCA8IHgpIHtcclxuICAgICAgICAgICAgYSA9IHBpdm90ICsgMTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSBpZiAodlBpdm90ID4geCkge1xyXG4gICAgICAgICAgICBiID0gcGl2b3QgLSAxO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgLy8gVGhpcyBpcyBhIGxpdHRsZSBzbG9wcHkgaWYgZWl0aGVyIHZhbHVlIGlzIE5hTiwgb3IgaWYgb25lIGlzICswLjAgYW5kIHRoZSBvdGhlciBpcyAtMC4wXHJcbiAgICAgICAgICAgIHJldHVybiBwaXZvdDtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIC0oYSArIDEpO1xyXG59XHJcblxyXG5cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBpbmRleE5lYXJlc3QodnM6IG51bWJlcltdLCB4OiBudW1iZXIpOiBudW1iZXIge1xyXG4gICAgY29uc3QgaSA9IGluZGV4T2YodnMsIHgpO1xyXG5cclxuICAgIC8vIEV4YWN0IHZhbHVlIGZvdW5kXHJcbiAgICBpZiAoaSA+PSAwKSB7XHJcbiAgICAgICAgcmV0dXJuIGk7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gRmluZCB0aGUgY2xvc2VyIG9mIHRoZSBhZGphY2VudCB2YWx1ZXNcclxuICAgIGNvbnN0IGlBZnRlciA9IC1pIC0gMTtcclxuICAgIGNvbnN0IGlCZWZvcmUgPSBpQWZ0ZXIgLSAxO1xyXG5cclxuICAgIGlmIChpQWZ0ZXIgPj0gdnMubGVuZ3RoKSB7XHJcbiAgICAgICAgcmV0dXJuIGlCZWZvcmU7XHJcbiAgICB9XHJcbiAgICBpZiAoaUJlZm9yZSA8IDApIHtcclxuICAgICAgICByZXR1cm4gaUFmdGVyO1xyXG4gICAgfVxyXG5cclxuICAgIGNvbnN0IGRpZmZBZnRlciA9IHZzW2lBZnRlcl0gLSB4O1xyXG4gICAgY29uc3QgZGlmZkJlZm9yZSA9IHggLSB2c1tpQmVmb3JlXTtcclxuXHJcbiAgICByZXR1cm4gKGRpZmZBZnRlciA8PSBkaWZmQmVmb3JlID8gaUFmdGVyIDogaUJlZm9yZSk7XHJcbn1cclxuXHJcblxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIGluZGV4QWZ0ZXIodnM6IG51bWJlcltdLCB4OiBudW1iZXIpOiBudW1iZXIge1xyXG4gICAgY29uc3QgaSA9IGluZGV4T2YodnMsIHgpO1xyXG5cclxuICAgIC8vIEV4YWN0IHZhbHVlIG5vdCBmb3VuZFxyXG4gICAgaWYgKGkgPCAwKSB7XHJcbiAgICAgICAgcmV0dXJuICgtaSAtIDEpO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIElmIHRoZSBleGFjdCB2YWx1ZSB3YXMgZm91bmQsIGZpbmQgdGhlIHZhbHVlJ3MgbGFzdCBvY2N1cnJlbmNlXHJcbiAgICBjb25zdCBuID0gdnMubGVuZ3RoO1xyXG4gICAgZm9yIChsZXQgaiA9IGkgKyAxOyBqIDwgbjsgaisrKSB7XHJcbiAgICAgICAgaWYgKHZzW2pdID4geCkge1xyXG4gICAgICAgICAgICByZXR1cm4gajtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICByZXR1cm4gbjtcclxufVxyXG5cclxuXHJcblxyXG5leHBvcnQgZnVuY3Rpb24gaW5kZXhBdE9yQWZ0ZXIodnM6IG51bWJlcltdLCB4OiBudW1iZXIpOiBudW1iZXIge1xyXG4gICAgY29uc3QgaSA9IGluZGV4T2YodnMsIHgpO1xyXG5cclxuICAgIC8vIEV4YWN0IHZhbHVlIG5vdCBmb3VuZFxyXG4gICAgaWYgKGkgPCAwKSB7XHJcbiAgICAgICAgcmV0dXJuICgtaSAtIDEpO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIElmIHRoZSBleGFjdCB2YWx1ZSB3YXMgZm91bmQsIGZpbmQgdGhlIHZhbHVlJ3MgZmlyc3Qgb2NjdXJyZW5jZVxyXG4gICAgY29uc3QgbiA9IHZzLmxlbmd0aDtcclxuICAgIGZvciAobGV0IGogPSBpOyBqID4gMDsgai0tKSB7XHJcbiAgICAgICAgaWYgKHZzW2ogLSAxXSA8IHgpIHtcclxuICAgICAgICAgICAgcmV0dXJuIGo7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgcmV0dXJuIDA7XHJcbn1cclxuXHJcblxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIGluZGV4QmVmb3JlKHZzOiBudW1iZXJbXSwgeDogbnVtYmVyKTogbnVtYmVyIHtcclxuICAgIHJldHVybiBpbmRleEF0T3JBZnRlcih2cywgeCkgLSAxO1xyXG59XHJcblxyXG5cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBpbmRleEF0T3JCZWZvcmUodnM6IG51bWJlcltdLCB4OiBudW1iZXIpOiBudW1iZXIge1xyXG4gICAgcmV0dXJuIGluZGV4QWZ0ZXIodnMsIHgpIC0gMTtcclxufVxyXG5cclxuXHJcbiJdfQ==