UNPKG

webglimpse

Version:

Webglimpse is a data visualization library for the web.

78 lines 15 kB
/* * 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. */ import { black } from '../color'; import { Program, UniformColor, Attribute } from '../shader'; import { xyFrac_VERTSHADER, solid_FRAGSHADER } from '../misc'; import { newDynamicBuffer } from '../buffer'; import { ensureCapacityFloat32, GL, hasval, parseTime_PMILLIS } from '../util/util'; import { getTickTimes_PMILLIS } from './time_axis_painter'; export function newTimeGridPainter(timeAxis, isVerticalAxis, timeZone, options) { const tickSpacing = (hasval(options) && hasval(options.tickSpacing) ? options.tickSpacing : 60); const gridColor = (hasval(options) && hasval(options.gridColor) ? options.gridColor : black); const referenceDate_PMILLIS = (hasval(options) && hasval(options.referenceDate) ? parseTime_PMILLIS(options.referenceDate) : undefined); const program = new Program(xyFrac_VERTSHADER, solid_FRAGSHADER); const u_Color = new UniformColor(program, 'u_Color'); const a_XyFrac = new Attribute(program, 'a_XyFrac'); let xyFrac = new Float32Array(0); const xyFracBuffer = newDynamicBuffer(); return function (gl, viewport) { const tickTimes_PMILLIS = getTickTimes_PMILLIS(timeAxis, (isVerticalAxis ? viewport.h : viewport.w), tickSpacing, timeZone, referenceDate_PMILLIS); const tickCount = tickTimes_PMILLIS.length; program.use(gl); u_Color.setData(gl, gridColor); xyFrac = ensureCapacityFloat32(xyFrac, 4 * tickCount); for (let n = 0; n < tickCount; n++) { let tFrac = timeAxis.tFrac(tickTimes_PMILLIS[n]); if (isVerticalAxis) { tFrac = (Math.floor(tFrac * viewport.h) + 0.5) / viewport.h; xyFrac[(4 * n + 0)] = 0; xyFrac[(4 * n + 1)] = tFrac; xyFrac[(4 * n + 2)] = 1; xyFrac[(4 * n + 3)] = tFrac; } else { // Adding epsilon is a crude way to compensate for floating-point error (which is probably introduced up where we compute tFrac) tFrac = (Math.floor(tFrac * viewport.w + 1e-4) + 0.5) / viewport.w; xyFrac[(4 * n + 0)] = tFrac; xyFrac[(4 * n + 1)] = 0; xyFrac[(4 * n + 2)] = tFrac; xyFrac[(4 * n + 3)] = 1; } } xyFracBuffer.setData(xyFrac.subarray(0, 4 * tickCount)); a_XyFrac.setDataAndEnable(gl, xyFracBuffer, 2, GL.FLOAT); // IE does not support lineWidths other than 1, so make sure all browsers use lineWidth of 1 gl.lineWidth(1); gl.drawArrays(GL.LINES, 0, 2 * tickCount); a_XyFrac.disable(gl); program.endUse(gl); }; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGltZV9ncmlkX3BhaW50ZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvd2ViZ2xpbXBzZS90aW1lbGluZS90aW1lX2dyaWRfcGFpbnRlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQTRCRztBQUNILE9BQU8sRUFBUyxLQUFLLEVBQUUsTUFBTSxVQUFVLENBQUM7QUFHeEMsT0FBTyxFQUFFLE9BQU8sRUFBRSxZQUFZLEVBQUUsU0FBUyxFQUFFLE1BQU0sV0FBVyxDQUFDO0FBQzdELE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLFNBQVMsQ0FBQztBQUM5RCxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxXQUFXLENBQUM7QUFFN0MsT0FBTyxFQUFFLHFCQUFxQixFQUFFLEVBQUUsRUFBRSxNQUFNLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxjQUFjLENBQUM7QUFDcEYsT0FBTyxFQUFFLG9CQUFvQixFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFVM0QsTUFBTSxVQUFVLGtCQUFrQixDQUFDLFFBQW9CLEVBQUUsY0FBdUIsRUFBRSxRQUFnQixFQUFFLE9BQWdDO0lBQ2hJLE1BQU0sV0FBVyxHQUFHLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxJQUFJLE1BQU0sQ0FBQyxPQUFPLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDO0lBQ2hHLE1BQU0sU0FBUyxHQUFHLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxJQUFJLE1BQU0sQ0FBQyxPQUFPLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQzdGLE1BQU0scUJBQXFCLEdBQUcsQ0FBQyxNQUFNLENBQUMsT0FB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QUNELFlBQVksQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxHQUFHLFNBQVMsQ0FBQyxDQUFDLENBQUM7UUFDeEQsUUFBUSxDQUFDLGdCQUFnQixDQUFDLEVBQUUsRUFBRSxZQUFZLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUV6RCw0RkFBNEY7UUFDNUYsRUFBRSxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNoQixFQUFFLENBQUMsVUFBVSxDQUFDLEVBQUUsQ0FBQyxLQUFLLEVBQUUsQ0FBQyxFQUFFLENBQUMsR0FBRyxTQUFTLENBQUMsQ0FBQztRQUUxQyxRQUFRLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBQ3JCLE9BQU8sQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLENBQUM7SUFDdkIsQ0FBQyxDQUFDO0FBQ04sQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qXHJcbiAqIENvcHlyaWdodCAoYykgMjAxNCwgTWV0cm9uLCBJbmMuXHJcbiAqIEFsbCByaWdodHMgcmVzZXJ2ZWQuXHJcbiAqXHJcbiAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dCBtb2RpZmljYXRpb24sXHJcbiAqIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcclxuICpcclxuICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXHJcbiAqICAgIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxyXG4gKlxyXG4gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXHJcbiAqICAgIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb25cclxuICogICAgYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZSBkaXN0cmlidXRpb24uXHJcbiAqXHJcbiAqIDMuIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIGNvcHlyaWdodCBob2xkZXIgbm9yIHRoZSBuYW1lcyBvZiBpdHMgY29udHJpYnV0b3JzXHJcbiAqICAgIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0XHJcbiAqICAgIHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cclxuICpcclxuICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCIgQU5EXHJcbiAqIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEXHJcbiAqIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkVcclxuICogRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1JcclxuICogQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTXHJcbiAqIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUztcclxuICogTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OXHJcbiAqIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUXHJcbiAqIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTXHJcbiAqIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxyXG4gKi9cclxuaW1wb3J0IHsgQ29sb3IsIGJsYWNrIH0gZnJvbSAnLi4vY29sb3InO1xyXG5pbXBvcnQgeyBUaW1lQXhpczFEIH0gZnJvbSAnLi90aW1lX2F4aXMnO1xyXG5pbXBvcnQgeyBQYWludGVyIH0gZnJvbSAnLi4vY29yZSc7XHJcbmltcG9ydCB7IFByb2dyYW0sIFVuaWZvcm1Db2xvciwgQXR0cmlidXRlIH0gZnJvbSAnLi4vc2hhZGVyJztcclxuaW1wb3J0IHsgeHlGcmFjX1ZFUlRTSEFERVIsIHNvbGlkX0ZSQUdTSEFERVIgfSBmcm9tICcuLi9taXNjJztcclxuaW1wb3J0IHsgbmV3RHluYW1pY0J1ZmZlciB9IGZyb20gJy4uL2J1ZmZlcic7XHJcbmltcG9ydCB7IEJvdW5kc1VubW9kaWZpYWJsZSB9IGZyb20gJy4uL2JvdW5kcyc7XHJcbmltcG9ydCB7IGVuc3VyZUNhcGFjaXR5RmxvYXQzMiwgR0wsIGhhc3ZhbCwgcGFyc2VUaW1lX1BNSUxMSVMgfSBmcm9tICcuLi91dGlsL3V0aWwnO1xyXG5pbXBvcnQgeyBnZXRUaWNrVGltZXNfUE1JTExJUyB9IGZyb20gJy4vdGltZV9heGlzX3BhaW50ZXInO1xyXG5cclxuXHJcbmV4cG9ydCBpbnRlcmZhY2UgVGltZUdyaWRQYWludGVyT3B0aW9ucyB7XHJcbiAgICB0aWNrU3BhY2luZz86IG51bWJlcjtcclxuICAgIGdyaWRDb2xvcj86IENvbG9yO1xyXG4gICAgcmVmZXJlbmNlRGF0ZT86IHN0cmluZztcclxufVxyXG5cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBuZXdUaW1lR3JpZFBhaW50ZXIodGltZUF4aXM6IFRpbWVBeGlzMUQsIGlzVmVydGljYWxBeGlzOiBib29sZWFuLCB0aW1lWm9uZTogc3RyaW5nLCBvcHRpb25zPzogVGltZUdyaWRQYWludGVyT3B0aW9ucyk6IFBhaW50ZXIge1xyXG4gICAgY29uc3QgdGlja1NwYWNpbmcgPSAoaGFzdmFsKG9wdGlvbnMpICYmIGhhc3ZhbChvcHRpb25zLnRpY2tTcGFjaW5nKSA/IG9wdGlvbnMudGlja1NwYWNpbmcgOiA2MCk7XHJcbiAgICBjb25zdCBncmlkQ29sb3IgPSAoaGFzdmFsKG9wdGlvbnMpICYmIGhhc3ZhbChvcHRpb25zLmdyaWRDb2xvcikgPyBvcHRpb25zLmdyaWRDb2xvciA6IGJsYWNrKTtcclxuICAgIGNvbnN0IHJlZmVyZW5jZURhdGVfUE1JTExJUyA9IChoYXN2YWwob3B0aW9ucykgJiYgaGFzdmFsKG9wdGlvbnMucmVmZXJlbmNlRGF0ZSkgPyBwYXJzZVRpbWVfUE1JTExJUyhvcHRpb25zLnJlZmVyZW5jZURhdGUpIDogdW5kZWZpbmVkKTtcclxuXHJcbiAgICBjb25zdCBwcm9ncmFtID0gbmV3IFByb2dyYW0oeHlGcmFjX1ZFUlRTSEFERVIsIHNvbGlkX0ZSQUdTSEFERVIpO1xyXG4gICAgY29uc3QgdV9Db2xvciA9IG5ldyBVbmlmb3JtQ29sb3IocHJvZ3JhbSwgJ3VfQ29sb3InKTtcclxuICAgIGNvbnN0IGFfWHlGcmFjID0gbmV3IEF0dHJpYnV0ZShwcm9ncmFtLCAnYV9YeUZyYWMnKTtcclxuXHJcbiAgICBsZXQgeHlGcmFjID0gbmV3IEZsb2F0MzJBcnJheSgwKTtcclxuICAgIGNvbnN0IHh5RnJhY0J1ZmZlciA9IG5ld0R5bmFtaWNCdWZmZXIoKTtcclxuXHJcbiAgICByZXR1cm4gZnVuY3Rpb24gKGdsOiBXZWJHTFJlbmRlcmluZ0NvbnRleHQsIHZpZXdwb3J0OiBCb3VuZHNVbm1vZGlmaWFibGUpIHtcclxuICAgICAgICBjb25zdCB0aWNrVGltZXNfUE1JTExJUyA9IGdldFRpY2tUaW1lc19QTUlMTElTKHRpbWVBeGlzLCAoaXNWZXJ0aWNhbEF4aXMgPyB2aWV3cG9ydC5oIDogdmlld3BvcnQudyksIHRpY2tTcGFjaW5nLCB0aW1lWm9uZSwgcmVmZXJlbmNlRGF0ZV9QTUlMTElTKTtcclxuICAgICAgICBjb25zdCB0aWNrQ291bnQgPSB0aWNrVGltZXNfUE1JTExJUy5sZW5ndGg7XHJcblxyXG4gICAgICAgIHByb2dyYW0udXNlKGdsKTtcclxuICAgICAgICB1X0NvbG9yLnNldERhdGEoZ2wsIGdyaWRDb2xvcik7XHJcblxyXG4gICAgICAgIHh5RnJhYyA9IGVuc3VyZUNhcGFjaXR5RmxvYXQzMih4eUZyYWMsIDQgKiB0aWNrQ291bnQpO1xyXG4gICAgICAgIGZvciAobGV0IG4gPSAwOyBuIDwgdGlja0NvdW50OyBuKyspIHtcclxuICAgICAgICAgICAgbGV0IHRGcmFjID0gdGltZUF4aXMudEZyYWModGlja1RpbWVzX1BNSUxMSVNbbl0pO1xyXG4gICAgICAgICAgICBpZiAoaXNWZXJ0aWNhbEF4aXMpIHtcclxuICAgICAgICAgICAgICAgIHRGcmFjID0gKE1hdGguZmxvb3IodEZyYWMgKiB2aWV3cG9ydC5oKSArIDAuNSkgLyB2aWV3cG9ydC5oO1xyXG4gICAgICAgICAgICAgICAgeHlGcmFjWyg0ICogbiArIDApXSA9IDA7XHJcbiAgICAgICAgICAgICAgICB4eUZyYWNbKDQgKiBuICsgMSldID0gdEZyYWM7XHJcbiAgICAgICAgICAgICAgICB4eUZyYWNbKDQgKiBuICsgMildID0gMTtcclxuICAgICAgICAgICAgICAgIHh5RnJhY1soNCAqIG4gKyAzKV0gPSB0RnJhYztcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgIC8vIEFkZGluZyBlcHNpbG9uIGlzIGEgY3J1ZGUgd2F5IHRvIGNvbXBlbnNhdGUgZm9yIGZsb2F0aW5nLXBvaW50IGVycm9yICh3aGljaCBpcyBwcm9iYWJseSBpbnRyb2R1Y2VkIHVwIHdoZXJlIHdlIGNvbXB1dGUgdEZyYWMpXHJcbiAgICAgICAgICAgICAgICB0RnJhYyA9IChNYXRoLmZsb29yKHRGcmFjICogdmlld3BvcnQudyArIDFlLTQpICsgMC41KSAvIHZpZXdwb3J0Lnc7XHJcbiAgICAgICAgICAgICAgICB4eUZyYWNbKDQgKiBuICsgMCldID0gdEZyYWM7XHJcbiAgICAgICAgICAgICAgICB4eUZyYWNbKDQgKiBuICsgMSldID0gMDtcclxuICAgICAgICAgICAgICAgIHh5RnJhY1soNCAqIG4gKyAyKV0gPSB0RnJhYztcclxuICAgICAgICAgICAgICAgIHh5RnJhY1soNCAqIG4gKyAzKV0gPSAxO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHh5RnJhY0J1ZmZlci5zZXREYXRhKHh5RnJhYy5zdWJhcnJheSgwLCA0ICogdGlja0NvdW50KSk7XHJcbiAgICAgICAgYV9YeUZyYWMuc2V0RGF0YUFuZEVuYWJsZShnbCwgeHlGcmFjQnVmZmVyLCAyLCBHTC5GTE9BVCk7XHJcblxyXG4gICAgICAgIC8vIElFIGRvZXMgbm90IHN1cHBvcnQgbGluZVdpZHRocyBvdGhlciB0aGFuIDEsIHNvIG1ha2Ugc3VyZSBhbGwgYnJvd3NlcnMgdXNlIGxpbmVXaWR0aCBvZiAxXHJcbiAgICAgICAgZ2wubGluZVdpZHRoKDEpO1xyXG4gICAgICAgIGdsLmRyYXdBcnJheXMoR0wuTElORVMsIDAsIDIgKiB0aWNrQ291bnQpO1xyXG5cclxuICAgICAgICBhX1h5RnJhYy5kaXNhYmxlKGdsKTtcclxuICAgICAgICBwcm9ncmFtLmVuZFVzZShnbCk7XHJcbiAgICB9O1xyXG59XHJcblxyXG5cclxuIl19