UNPKG

ui-widget-toolkit

Version:

UI widgets built on top of D3, Pixi.js and ag-grid-community

171 lines • 90.6 kB
(function webpackUniversalModuleDefinition(root, factory) {
	if(typeof exports === 'object' && typeof module === 'object')
		module.exports = factory(require("d3"));
	else if(typeof define === 'function' && define.amd)
		define("UWT", ["d3"], factory);
	else if(typeof exports === 'object')
		exports["UWT"] = factory(require("d3"));
	else
		root["UWT"] = factory(root["d3"]);
})(window, function(__WEBPACK_EXTERNAL_MODULE_d3__) {
return /******/ (function(modules) { // webpackBootstrap
/******/ 	// The module cache
/******/ 	var installedModules = {};
/******/
/******/ 	// The require function
/******/ 	function __webpack_require__(moduleId) {
/******/
/******/ 		// Check if module is in cache
/******/ 		if(installedModules[moduleId]) {
/******/ 			return installedModules[moduleId].exports;
/******/ 		}
/******/ 		// Create a new module (and put it into the cache)
/******/ 		var module = installedModules[moduleId] = {
/******/ 			i: moduleId,
/******/ 			l: false,
/******/ 			exports: {}
/******/ 		};
/******/
/******/ 		// Execute the module function
/******/ 		modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ 		// Flag the module as loaded
/******/ 		module.l = true;
/******/
/******/ 		// Return the exports of the module
/******/ 		return module.exports;
/******/ 	}
/******/
/******/
/******/ 	// expose the modules object (__webpack_modules__)
/******/ 	__webpack_require__.m = modules;
/******/
/******/ 	// expose the module cache
/******/ 	__webpack_require__.c = installedModules;
/******/
/******/ 	// define getter function for harmony exports
/******/ 	__webpack_require__.d = function(exports, name, getter) {
/******/ 		if(!__webpack_require__.o(exports, name)) {
/******/ 			Object.defineProperty(exports, name, { enumerable: true, get: getter });
/******/ 		}
/******/ 	};
/******/
/******/ 	// define __esModule on exports
/******/ 	__webpack_require__.r = function(exports) {
/******/ 		if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
/******/ 			Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
/******/ 		}
/******/ 		Object.defineProperty(exports, '__esModule', { value: true });
/******/ 	};
/******/
/******/ 	// create a fake namespace object
/******/ 	// mode & 1: value is a module id, require it
/******/ 	// mode & 2: merge all properties of value into the ns
/******/ 	// mode & 4: return value when already ns object
/******/ 	// mode & 8|1: behave like require
/******/ 	__webpack_require__.t = function(value, mode) {
/******/ 		if(mode & 1) value = __webpack_require__(value);
/******/ 		if(mode & 8) return value;
/******/ 		if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;
/******/ 		var ns = Object.create(null);
/******/ 		__webpack_require__.r(ns);
/******/ 		Object.defineProperty(ns, 'default', { enumerable: true, value: value });
/******/ 		if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));
/******/ 		return ns;
/******/ 	};
/******/
/******/ 	// getDefaultExport function for compatibility with non-harmony modules
/******/ 	__webpack_require__.n = function(module) {
/******/ 		var getter = module && module.__esModule ?
/******/ 			function getDefault() { return module['default']; } :
/******/ 			function getModuleExports() { return module; };
/******/ 		__webpack_require__.d(getter, 'a', getter);
/******/ 		return getter;
/******/ 	};
/******/
/******/ 	// Object.prototype.hasOwnProperty.call
/******/ 	__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/ 	// __webpack_public_path__
/******/ 	__webpack_require__.p = "";
/******/
/******/
/******/ 	// Load entry module and return exports
/******/ 	return __webpack_require__(__webpack_require__.s = "./src/core/cartesian/decimator/worker.ts");
/******/ })
/************************************************************************/
/******/ ({

/***/ "./src/core/cartesian/decimator/decimator.ts":
/*!***************************************************!*\
  !*** ./src/core/cartesian/decimator/decimator.ts ***!
  \***************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

"use strict";
eval("\nObject.defineProperty(exports, \"__esModule\", { value: true });\nconst data_1 = __webpack_require__(/*! ../../data */ \"./src/core/data.ts\");\nconst utilities_1 = __webpack_require__(/*! ../../utilities */ \"./src/core/utilities.ts\");\nexports.findFirstInsertionIdx = utilities_1.bisectBuffer(function (xy) { return xy.x; }).left;\nexports.findLastInsertionIdx = utilities_1.bisectBuffer(function (xy) { return xy.x; }).right;\nclass XYDummyDecimator {\n    constructor() {\n        this._values = [];\n    }\n    initialize(xValueToCoord, xCoordToValue, yValueToCoord) {\n    }\n    getKey() {\n        return '';\n    }\n    getName() {\n        return '';\n    }\n    /**\n     * Returns the decimated list of data\n     */\n    getValues() {\n        return this._values;\n    }\n    /**\n     * Values to be decimated\n     *\n     * @param xStart - start time of the region\n     * @param xEnd - start time of the region\n     * @param values - Values to be decimated.\n     */\n    decimateValues(xStart, xEnd, values) {\n        if (Array.isArray(values)) {\n            values.forEach((data) => {\n                this._values.push(data.getData());\n            });\n        }\n        else {\n            this._values = values.getData();\n        }\n        return this._values;\n    }\n} // interface IDecimator\nexports.XYDummyDecimator = XYDummyDecimator;\n/**\n * this class allows a decimation function to be passed in to allow for\n * generic decimation\n */\nclass CustomPointXYDecimator {\n    constructor() {\n        this._name = 'Simple Unimplemented Decimator';\n    }\n    /**\n     * construct a generic decimator using a custom user function\n     *\n     * @param xValueToCoord converts the x value to a GUI x coordinate\n     * @param yValueToCoord converts the y value to a GUI y coordinate\n     * @param decimationFunc convert a list of data to a for rendering smaller list\n     */\n    initialize(xValueToCoord, xCoordToValue, yValueToCoord) {\n        this._xValueToCoord = xValueToCoord;\n        this._xCoordToValue = xCoordToValue;\n        this._yValueToCoord = yValueToCoord;\n    }\n    /**\n     * Returns the key of this decimator\n     */\n    getKey() {\n        return this._key;\n    }\n    /**\n     * Returns the name of this decimator\n     */\n    getName() {\n        return this._name;\n    }\n    /**\n     * Returns the decimated list of buckets\n     */\n    getValues() {\n        return this._decimatedValues;\n    }\n    /**\n     * Values to be decimated\n     *\n     * @param xStart - start time of the region\n     * @param xEnd - start time of the region\n     * @param values - Values to be decimated.\n     */\n    decimateValues(xStart, xEnd, inputValues) {\n        // loop over the data samples\n        this._decimatedValues = [];\n        if (inputValues.length() === 0) {\n            return this._decimatedValues;\n        }\n        let left = exports.findFirstInsertionIdx(inputValues, xStart);\n        let right = exports.findLastInsertionIdx(inputValues, xEnd);\n        if (left > 0) {\n            --left;\n        }\n        if (right < inputValues.length()) {\n            ++right;\n        }\n        let lastX;\n        if (left < inputValues.length()) {\n            lastX = Math.floor(this._xValueToCoord(inputValues.get(left).x));\n            --lastX;\n        }\n        let xStartCoord;\n        if (xStart) {\n            xStartCoord = Math.floor(this._xValueToCoord(xStart));\n        }\n        else {\n            xStartCoord = Math.floor(this._xValueToCoord(inputValues.get(left).x));\n        }\n        let lastIdx = left;\n        let endIdx;\n        for (let index = left; index < right; ++index) {\n            let inputValue = inputValues.get(index);\n            let xEndCoord = Math.floor(this._xValueToCoord(inputValue.x));\n            endIdx = index;\n            if (xEndCoord !== lastX) {\n                this._decimatedValues = this._decimatedValues.concat(this._customFunc(inputValues, lastIdx, endIdx, this._yValueToCoord, this._xValueToCoord, this._xCoordToValue(xStartCoord), this._xCoordToValue(xEndCoord)));\n                xStartCoord = xEndCoord;\n                lastX = xEndCoord;\n                lastIdx = endIdx;\n            }\n        }\n        if (lastIdx !== inputValues.length()) {\n            this._decimatedValues = this._decimatedValues.concat(this._customFunc(inputValues, lastIdx, endIdx + 1, this._yValueToCoord, this._xValueToCoord, this._xCoordToValue(xStartCoord), Number.MAX_VALUE));\n        }\n        return this._decimatedValues;\n    }\n}\nexports.CustomPointXYDecimator = CustomPointXYDecimator;\n/** used to compute the min values for a set of data */\nclass MinPointDecimator extends CustomPointXYDecimator {\n    constructor() {\n        super();\n        this._key = MinPointDecimator.KEY;\n        this._name = 'Min';\n        this._customFunc = function (values, startIdx, endIdx, yValueToCoord) {\n            if (values.length() > 0 && startIdx !== endIdx) {\n                let minY = Number.MAX_VALUE;\n                let minValue;\n                for (let i = startIdx; i < endIdx; ++i) {\n                    let value = values.get(i);\n                    let y = value.y;\n                    if (y < minY) {\n                        minValue = value;\n                        minY = y;\n                    }\n                }\n                return [minValue];\n            }\n            return [];\n        };\n    }\n}\nexports.MinPointDecimator = MinPointDecimator;\nMinPointDecimator.KEY = 'MinPointDecimator';\n;\nfunction computeAvg(values, startIdx, endIdx, yValueToCoord) {\n    if (values.length() > 0 && startIdx !== endIdx) {\n        let total = 0;\n        for (let i = startIdx; i < endIdx; ++i) {\n            let value = values.get(i);\n            total += value.y;\n        }\n        return [new data_1.XYValue(values.get(endIdx - 1).x, total / (endIdx - startIdx))];\n    }\n    return [];\n}\n/** used to compute the avg values for a set of data */\nclass AvgPointDecimator extends CustomPointXYDecimator {\n    constructor() {\n        super();\n        this._key = AvgPointDecimator.KEY;\n        this._name = 'Avg';\n        this._customFunc = computeAvg;\n    }\n}\nexports.AvgPointDecimator = AvgPointDecimator;\nAvgPointDecimator.KEY = 'AvgPointDecimator';\n;\n/** used to compute the min values for a set of data */\nclass MaxPointDecimator extends CustomPointXYDecimator {\n    constructor() {\n        super();\n        this._key = MaxPointDecimator.KEY;\n        this._name = 'Max';\n        this._customFunc = function (values, startIdx, endIdx, yValueToCoord) {\n            if (values.length() > 0 && startIdx !== endIdx) {\n                let maxY = -Number.MAX_VALUE;\n                let maxValue;\n                for (let i = startIdx; i < endIdx; ++i) {\n                    let value = values.get(i);\n                    let y = value.y;\n                    if (y > maxY) {\n                        maxValue = value;\n                        maxY = y;\n                    }\n                }\n                return [maxValue];\n            }\n            return [];\n        };\n    }\n}\nexports.MaxPointDecimator = MaxPointDecimator;\nMaxPointDecimator.KEY = 'MaxPointDecimator';\n;\n/**\n * Data decimation to fit information to onto the graph.\n *\n * This class divides the x-Axis time range into a set of buckets.  Each\n * bucket provides the average of the values, the minimum & maximum\n * values, and the values upon entry & exit.\n * It assumes that the DB values are increase over the time.\n */\nclass XYPointDecimator extends CustomPointXYDecimator {\n    constructor() {\n        super();\n        this._key = XYPointDecimator.KEY;\n        this._name = 'XYPointDecimator';\n        this._customFunc = function (values, startIdx, endIdx, yValueToCoord) {\n            let yMap = {};\n            let reducedValues = [];\n            for (let i = startIdx; i < endIdx; ++i) {\n                let value = values.get(i);\n                let yCoord = Math.floor(yValueToCoord(value.y));\n                if (!yMap.hasOwnProperty(yCoord.toString())) {\n                    reducedValues.push(value);\n                    yMap[yCoord] = true;\n                }\n            }\n            return reducedValues;\n        };\n    }\n} // class VerticalDecimator\nexports.XYPointDecimator = XYPointDecimator;\nXYPointDecimator.KEY = 'XYPointDecimator';\n/**\n * this class allows a decimation function to be passed in to allow for\n * generic decimation\n */\nclass CustomContinuousXYDecimator {\n    constructor() {\n        this._name = 'Simple Unimplemented Decimator';\n    }\n    /**\n     * construct a generic decimator using a custom user function\n     *\n     * @param xValueToCoord converts the x value to a GUI x coordinate\n     * @param yValueToCoord converts the y value to a GUI y coordinate\n     * @param decimationFunc convert a list of data to a for rendering smaller list\n     */\n    initialize(xValueToCoord, xCoordToValue, yValueToCoord) {\n        this._xValueToCoord = xValueToCoord;\n        this._xCoordToValue = xCoordToValue;\n        this._yValueToCoord = yValueToCoord;\n    }\n    /**\n     * Returns the key of this decimator\n     */\n    getKey() {\n        return this._key;\n    }\n    /**\n     * Returns the name of this decimator\n     */\n    getName() {\n        return this._name;\n    }\n    /**\n     * Returns the decimated list of buckets\n     */\n    getValues() {\n        return this._decimatedValues;\n    }\n    /**\n     * Values to be decimated\n     *\n     * @param xStart - start time of the region\n     * @param xEnd - start time of the region\n     * @param values - Values to be decimated.\n     */\n    decimateValues(xStart, xEnd, inputValues) {\n        // loop over the data samples\n        this._decimatedValues = [];\n        if (inputValues.length() === 0) {\n            return this._decimatedValues;\n        }\n        let left = exports.findFirstInsertionIdx(inputValues, xStart);\n        let right = exports.findLastInsertionIdx(inputValues, xEnd);\n        if (left > 0) {\n            --left;\n        }\n        if (right < inputValues.length()) {\n            ++right;\n        }\n        let lastX;\n        if (left < inputValues.length()) {\n            lastX = Math.floor(this._xValueToCoord(inputValues.get(left).x));\n            --lastX;\n        }\n        let xStartCoord;\n        if (xStart) {\n            xStartCoord = this._xValueToCoord(xStart);\n        }\n        else {\n            xStartCoord = left;\n        }\n        let lastIdx = left;\n        for (let index = left; index < right; ++index) {\n            let inputValue = inputValues.get(index);\n            let xEndCoord = Math.floor(this._xValueToCoord(inputValue.x));\n            let endIdx = index + 1;\n            if (xEndCoord !== lastX) {\n                this._decimatedValues = this._decimatedValues.concat(this._customFunc(inputValues, lastIdx, endIdx, this._yValueToCoord, this._xValueToCoord, this._xCoordToValue(xStartCoord), this._xCoordToValue(xEndCoord)));\n                xStartCoord = xEndCoord;\n                lastX = xEndCoord;\n                lastIdx = endIdx;\n            }\n        }\n        if (lastIdx !== inputValues.length()) {\n            this._decimatedValues = this._decimatedValues.concat(this._customFunc(inputValues, lastIdx, lastIdx + 1, this._yValueToCoord, this._xValueToCoord, this._xCoordToValue(xStartCoord), Number.MAX_VALUE));\n        }\n        return this._decimatedValues;\n    }\n}\nexports.CustomContinuousXYDecimator = CustomContinuousXYDecimator;\n/** used to compute the avg values for a set of data */\nclass AvgContinuousDecimator extends CustomContinuousXYDecimator {\n    constructor() {\n        super();\n        this._key = AvgContinuousDecimator.KEY;\n        this._name = 'Avg';\n        this._customFunc = computeAvg;\n    }\n}\nexports.AvgContinuousDecimator = AvgContinuousDecimator;\nAvgContinuousDecimator.KEY = 'AvgContinuousDecimator';\n;\n/** this is a helper function class that computes the summed values for each\n * Y state per each X bucket\n */\nfunction sumMultiXYSeriesValues(_xValueToCoord, _xCoordToValue, _yValueToCoord, xStart, xEnd, values) {\n    let ret = [];\n    // first this is total weighted sum per x, then used to store percentage per x\n    let tempValues = [];\n    let globalStartBucket = 0;\n    let globalEndBucket = Math.ceil(_xValueToCoord(Number.MAX_VALUE));\n    if (globalEndBucket < globalStartBucket) {\n        return undefined;\n    }\n    // NOTE: I do this up here so I can cheat and use the x values here\n    // so later I don't keep calling _xCoordToValue\n    let xBucketValues = [];\n    for (let bucket = 0; bucket <= globalEndBucket + 1; ++bucket) {\n        xBucketValues.push(_xCoordToValue(bucket));\n    }\n    // for a series get the weighted sum for the number of buckets xStart to xEnd\n    for (let stateIdx = 0; stateIdx < values.length; ++stateIdx) {\n        let perStateData = values[stateIdx];\n        let value;\n        let nextValue;\n        let start = exports.findFirstInsertionIdx(values[stateIdx], xStart);\n        let end = exports.findLastInsertionIdx(values[stateIdx], xEnd);\n        if (start > 0) {\n            --start;\n        }\n        // the last element would be caught by the algorithm already\n        if (end === perStateData.length()) {\n            --end;\n        }\n        // pad endBucket + 1 so we get data past the last point in the bucket\n        // so we can graph to the first value in the next bucket\n        tempValues[stateIdx] = Array.apply(null, Array(globalEndBucket)).\n            map(Number.prototype.valueOf, 0);\n        // get weighted sum of the values for each bucket\n        for (let rawDataIdx = start; rawDataIdx < end; ++rawDataIdx) {\n            value = perStateData.get(rawDataIdx);\n            nextValue = perStateData.get(rawDataIdx + 1);\n            let startBucket = Math.floor(_xValueToCoord(value.x));\n            let endBucket = Math.floor(_xValueToCoord(nextValue.x));\n            let totalX = (nextValue.x - value.x);\n            let valuePerX = totalX === 0 ? 0 : nextValue.y / totalX;\n            if (startBucket === endBucket) {\n                if (xStart === undefined || (value.x > xStart && nextValue.x < xEnd)) {\n                    // here it's all in the existing bucket\n                    tempValues[stateIdx][startBucket] += valuePerX;\n                }\n                else {\n                    let bucketScalar = 1 / (xBucketValues[startBucket + 1] - xBucketValues[startBucket]);\n                    if (nextValue.x < xEnd) {\n                        // here the back half is in the bucket\n                        tempValues[stateIdx][startBucket] +=\n                            (nextValue.x - xBucketValues[startBucket]) * valuePerX * bucketScalar;\n                    }\n                    else {\n                        // here the front half is in the bucket\n                        tempValues[stateIdx][startBucket] +=\n                            (xBucketValues[startBucket + 1] - value.x) * valuePerX * bucketScalar;\n                    }\n                }\n            }\n            else {\n                let bucketScalar = 1 / (xBucketValues[startBucket + 1] - xBucketValues[startBucket]);\n                let startX = xStart ? Math.max(xStart, value.x) : value.x;\n                let endStartBucket = xBucketValues[startBucket + 1];\n                tempValues[stateIdx][startBucket] +=\n                    (endStartBucket - startX) * valuePerX * bucketScalar;\n                // add in all the bucket values in between\n                for (let currBucket = startBucket + 1; currBucket < endBucket; ++currBucket) {\n                    tempValues[stateIdx][currBucket] += valuePerX;\n                }\n                // add in end bucket amount\n                bucketScalar = 1 / (xBucketValues[endBucket] - xBucketValues[endBucket - 1]);\n                let endX = xEnd ? Math.min(xEnd, nextValue.x) : nextValue.x;\n                let startEndBucket = xBucketValues[endBucket];\n                tempValues[stateIdx][endBucket] +=\n                    (endX - startEndBucket) * valuePerX * bucketScalar;\n            }\n        }\n        ret[stateIdx] = [];\n        let buckets = tempValues[stateIdx];\n        for (let bucket = 0; bucket < buckets.length; ++bucket) {\n            ret[stateIdx][bucket] = {\n                x: xBucketValues[bucket],\n                y: tempValues[stateIdx][bucket]\n            };\n        }\n    }\n    return ret;\n}\nexports.sumMultiXYSeriesValues = sumMultiXYSeriesValues;\n/** class that computes the summed values for each Y state per each X bucket */\nclass SummedValueMultiXYSeriesDecimator {\n    constructor() {\n    }\n    /**\n     * construct a generic decimator using a custom user function\n     *\n     * @param xValueToCoord converts the x value to a GUI x coordinate\n     * @param yValueToCoord converts the y value to a GUI y coordinate\n     * @param decimationFunc convert a list of data to a for rendering smaller list\n     */\n    initialize(xValueToCoord, xCoordToValue, yValueToCoord) {\n        this._xValueToCoord = xValueToCoord;\n        this._xCoordToValue = xCoordToValue;\n        this._yValueToCoord = yValueToCoord;\n    }\n    /**\n     * Returns the key of this decimator\n     */\n    getKey() {\n        return SummedValueMultiXYSeriesDecimator.KEY;\n    }\n    /**\n     * Returns the decimated list of buckets\n     */\n    getName() {\n        return '';\n    }\n    /**\n     * Returns the decimated list of buckets\n     */\n    getValues() {\n        return this._decimatedValues;\n    }\n    /**\n     * Values to be decimated\n     *\n     * @param xStart - start time of the region\n     * @param xEnd - start time of the region\n     * @param values - Values to be decimated.\n     */\n    decimateValues(xStart, xEnd, values) {\n        this._decimatedValues = sumMultiXYSeriesValues(this._xValueToCoord, this._xCoordToValue, this._yValueToCoord, xStart, xEnd, values);\n        return this._decimatedValues;\n    }\n}\nexports.SummedValueMultiXYSeriesDecimator = SummedValueMultiXYSeriesDecimator;\nSummedValueMultiXYSeriesDecimator.KEY = 'SummedValueMultiXYSeriesDecimator';\n;\n/** class that computes the residency values for each Y state per each X bucket.\n * This means the sum of all values within an output bucket is 100.\n*/\nclass ResidencyDecimator extends SummedValueMultiXYSeriesDecimator {\n    constructor() {\n        super();\n    }\n    /**\n     * Returns the key of this decimator\n     */\n    getKey() {\n        return ResidencyDecimator.KEY;\n    }\n    /**\n     * Returns the decimated list of buckets\n     */\n    getName() {\n        return '';\n    }\n    /**\n     * Values to be decimated\n     *\n     * @param xStart - start time of the region\n     * @param xEnd - start time of the region\n     * @param values - Values to be decimated.\n     */\n    decimateValues(xStart, xEnd, values) {\n        this._decimatedValues = sumMultiXYSeriesValues(this._xValueToCoord, this._xCoordToValue, this._yValueToCoord, xStart, xEnd, values);\n        // normalize all values to 100%\n        for (let bucket = 0; bucket < this._decimatedValues[0].length; ++bucket) {\n            let total = 0;\n            for (let stateIdx = 0; stateIdx < this._decimatedValues.length; ++stateIdx) {\n                if (this._decimatedValues[stateIdx][bucket].y) {\n                    total += this._decimatedValues[stateIdx][bucket].y;\n                }\n            }\n            if (total > 0) {\n                let scalar = 100 / total;\n                for (let stateIdx = 0; stateIdx < values.length; ++stateIdx) {\n                    if (this._decimatedValues[stateIdx][bucket].y) {\n                        this._decimatedValues[stateIdx][bucket].y =\n                            this._decimatedValues[stateIdx][bucket].y * scalar;\n                    }\n                }\n            }\n        }\n        return this._decimatedValues;\n    }\n}\nexports.ResidencyDecimator = ResidencyDecimator;\nResidencyDecimator.KEY = 'ResidencyDecimator';\n;\n/** class that computes the summed Y value per each X bucket */\nclass SummedValueXYSeriesDecimator {\n    constructor() {\n    }\n    /**\n     * construct a generic decimator using a custom user function\n     *\n     * @param xValueToCoord converts the x value to a GUI x coordinate\n     * @param yValueToCoord converts the y value to a GUI y coordinate\n     * @param decimationFunc convert a list of data to a for rendering smaller list\n     */\n    initialize(xValueToCoord, xCoordToValue, yValueToCoord) {\n        this._xValueToCoord = xValueToCoord;\n        this._xCoordToValue = xCoordToValue;\n        this._yValueToCoord = yValueToCoord;\n    }\n    /**\n     * Returns the name of this decimator\n     */\n    getKey() {\n        return SummedValueXYSeriesDecimator.KEY;\n    }\n    /**\n     * Returns the name of this decimator\n     */\n    getName() {\n        return '';\n    }\n    /**\n     * Returns the decimated list of buckets\n     */\n    getValues() {\n        return this._decimatedValues;\n    }\n    /**\n     * Values to be decimated\n     *\n     * @param xStart - start time of the region\n     * @param xEnd - start time of the region\n     * @param values - Values to be decimated.\n     */\n    decimateValues(xStart, xEnd, values) {\n        this._decimatedValues = sumMultiXYSeriesValues(this._xValueToCoord, this._xCoordToValue, this._yValueToCoord, xStart, xEnd, [values])[0];\n        return this._decimatedValues;\n    }\n}\nexports.SummedValueXYSeriesDecimator = SummedValueXYSeriesDecimator;\nSummedValueXYSeriesDecimator.KEY = 'SummedValueXYSeriesDecimator';\n/*************************************************************\n * NEWS (Min/Max/Entry/Exit) CHART DECIMATORS\n */\n/**\n * Internally used class for the array of values\n */\nclass NEWSDecimationValue extends data_1.CandlestickValue {\n    /**\n     * Construct a DecimationValue instance\n     *\n     * @param value - an XYValue to initialize the decimation value\n     */\n    constructor(x) {\n        super(x, undefined, undefined, undefined, undefined);\n        this._bucketPts = 0;\n    } // constructor\n} // class DecimationValue\nexports.NEWSDecimationValue = NEWSDecimationValue;\n/**\n * Data decimation to fit information to onto the graph.\n *\n * This class divides the x-Axis time range into a set of buckets.  Each\n * bucket provides the average of the values, the minimum & maximum\n * values, and the values upon entry & exit.\n * It assumes that the DB values are increase over the time.\n */\nclass NEWSBaseDecimator {\n    initialize(xValueToCoord, xCoordToValue, yValueToCoord) {\n        this._xValueToCoord = xValueToCoord;\n        this._xCoordToValue = xCoordToValue;\n        this._yValueToCoord = yValueToCoord;\n    }\n    /**\n     * Returns the key of this decimator\n     */\n    getKey() {\n        return this._key;\n    }\n    getName() {\n        return '';\n    }\n    /**\n     * Get the accumulated buckets\n     *\n     * @returns the accumulated buckets\n     */\n    getValues() {\n        return this._buckets;\n    }\n    /**\n     * Bucket dumper\n     */\n    _dumpBucket(firstTimeStamp, bucket, valuesInBucket) {\n        let details = \"valuesInBucket = \" + valuesInBucket.toFixed(0) + \", \";\n        details += \"([avg]Time delta, avgValue) = (\" +\n            (bucket.x - firstTimeStamp).toFixed(2) + \", \" + bucket.y.toFixed(2) + \"), \";\n        details += \"(entry, min, max, exit) = (\" + (bucket.entry).toFixed(2) + \", \" +\n            (bucket.min).toFixed(2) + \", \" + (bucket.max).toFixed(2) + \", \" +\n            (bucket.exit).toFixed(2) + \")\";\n        return details;\n    }\n    /**\n     * Values to be decimated\n     *\n     * @param xStart - start time of the region\n     * @param xEnd - start time of the region\n     * @param values - Values to be decimated.\n     */\n    decimateValues(xStart, xEnd, inputValues) {\n        throw 'Error need to implement decimate code';\n    }\n}\nexports.NEWSBaseDecimator = NEWSBaseDecimator;\n/** this class takes a series x, y points and using for each X bucket provides\n * the Y entry/exit/min/max/average for that X bucket\n */\nclass NEWSPointDecimator extends NEWSBaseDecimator {\n    constructor() {\n        super();\n        this._key = NEWSPointDecimator.KEY;\n    }\n    createNewBucket(decimatedValue, value) {\n        decimatedValue.entry = value.y;\n        decimatedValue.exit = value.y;\n        decimatedValue.min = value.y;\n        decimatedValue.max = value.y;\n        decimatedValue.x = 0;\n        decimatedValue.y = 0;\n        decimatedValue._bucketPts = 0;\n        this.addToBucket(decimatedValue, value);\n    }\n    /**\n     * Add an x/y value pair to this value. Both the time (x) and\n     * value (y) are added to this point/bucket\n     *\n     * @param dbPoint - The x/y value pair to add to this value.\n    */\n    addToBucket(decimatedValue, value) {\n        decimatedValue.x += value.x;\n        decimatedValue.y += value.y;\n        decimatedValue.min = Math.min(decimatedValue.min, value.y);\n        decimatedValue.max = Math.max(decimatedValue.max, value.y);\n        decimatedValue.exit = value.y;\n        decimatedValue._bucketPts++;\n    }\n    finalizeBucket(decimatedValue, pointsInBucket) {\n        if (undefined !== pointsInBucket) {\n            if (pointsInBucket !== decimatedValue._bucketPts) {\n                console.log(\"AverageTime: mismatching pt calculation\");\n            }\n        }\n        if (decimatedValue._bucketPts === 0) {\n            console.log(\"AverageTime: 0 points\");\n        }\n        decimatedValue.x = decimatedValue.x / decimatedValue._bucketPts;\n        decimatedValue.y = decimatedValue.y / decimatedValue._bucketPts;\n    }\n    /**\n     * Values to be decimated\n     *\n     * @param xStart - start time of the region\n     * @param xEnd - start time of the region\n     * @param values - Values to be decimated.\n     */\n    decimateValues(xStart, xEnd, inputValues) {\n        // loop over the data samples\n        this._buckets = [];\n        if (inputValues.length() === 0) {\n            return this._buckets;\n        }\n        let currentPoint;\n        let left = exports.findFirstInsertionIdx(inputValues, xStart);\n        let right = exports.findLastInsertionIdx(inputValues, xEnd);\n        if (left > 0) {\n            --left;\n        }\n        if (right < inputValues.length()) {\n            ++right;\n        }\n        let lastX = 0;\n        if (left < inputValues.length()) {\n            lastX = Math.floor(this._xValueToCoord(inputValues.get(left).x));\n            --lastX;\n        }\n        for (let index = left; index < right; ++index) {\n            let inputValue = inputValues.get(index);\n            let xCoord = Math.floor(this._xValueToCoord(inputValue.x));\n            if (xCoord !== lastX) {\n                if (currentPoint) {\n                    this.finalizeBucket(currentPoint);\n                    this._buckets.push(currentPoint);\n                }\n                currentPoint = new NEWSDecimationValue();\n                this.createNewBucket(currentPoint, inputValue);\n                lastX = xCoord;\n            }\n            else {\n                this.addToBucket(currentPoint, inputValue);\n            }\n        }\n        if (currentPoint) {\n            this.finalizeBucket(currentPoint);\n            this._buckets.push(currentPoint);\n        }\n        return this._buckets;\n    } // decimateValues()\n} // class NEWSDecimator\nexports.NEWSPointDecimator = NEWSPointDecimator;\nNEWSPointDecimator.KEY = 'NEWSPointDecimator';\n/** this class takes a series x, y points and using for each X bucket provides\n * the Y entry/exit/min/max/average for that X bucket\n */\nclass NEWSStateDecimator extends NEWSBaseDecimator {\n    constructor(states) {\n        super();\n        this._weightedSums = {};\n        this._prevX = 0;\n        this._prevX = 0;\n        this._key = NEWSStateDecimator.KEY;\n        if (states) {\n            this._states = states;\n        }\n    }\n    createNewBucket(decimatedValue, value) {\n        this._weightedSums = {};\n        decimatedValue._bucketPts = 0;\n        let defaultValue;\n        if (!this._isYObject) {\n            defaultValue = value.y;\n            decimatedValue.x = 0;\n            decimatedValue.y = defaultValue;\n            decimatedValue.entry = defaultValue;\n            decimatedValue.exit = defaultValue;\n            decimatedValue.min = defaultValue;\n            decimatedValue.max = defaultValue;\n        }\n        this.addToBucket(decimatedValue, value);\n    }\n    ;\n    addToStateValueToBucket(state, value) {\n        if (value === 0) {\n            return;\n        }\n        if (!this._weightedSums[state]) {\n            this._weightedSums[state] = 0;\n        }\n        this._weightedSums[state] += value;\n    }\n    addToBucket(decimatedValue, value) {\n        if (this._isYObject) {\n            if (this._states) {\n                // take prevX and currentX\n                for (let stateKey in value.y) {\n                    this.addToStateValueToBucket(this._states[stateKey], (value.x - this._prevX) * value.y[stateKey]);\n                }\n            }\n            else {\n                // take prevX and currentX\n                for (let state in value.y) {\n                    this.addToStateValueToBucket(state, (value.x - this._prevX) * value.y[state]);\n                }\n            }\n        }\n        else {\n            let state;\n            if (this._states) {\n                state = this._states[value.y];\n            }\n            else {\n                state = value.y;\n            }\n            decimatedValue.exit = state;\n            this.addToStateValueToBucket(state, (value.x - this._prevX));\n        }\n        decimatedValue.x += value.x;\n        decimatedValue._bucketPts++;\n        this._prevX = value.x;\n    }\n    finalizeBucket(decimatedValue, pointsInBucket) {\n        if (undefined !== pointsInBucket) {\n            if (pointsInBucket !== decimatedValue._bucketPts) {\n                console.log(\"AverageTime: mismatching pt calculation\");\n            }\n        }\n        if (decimatedValue._bucketPts === 0) {\n            console.log(\"AverageTime: 0 points\");\n        }\n        decimatedValue.x = decimatedValue.x / decimatedValue._bucketPts;\n        // find the maximum value by weightedSums\n        var maxWeightedKey;\n        var maxWeightValue = -Number.MAX_VALUE;\n        let minState = -Number.MAX_VALUE;\n        let maxState = Number.MAX_VALUE;\n        for (let state in this._weightedSums) {\n            if (this._weightedSums[state] !== undefined) {\n                let stateWeight = this._weightedSums[state];\n                if (stateWeight > maxWeightValue) {\n                    maxWeightedKey = state;\n                    maxWeightValue = stateWeight;\n                }\n            }\n            // min is bigger since Y values increase as you go down the axis\n            let yOffset = this._yValueToCoord(state);\n            if (yOffset > minState) {\n                decimatedValue.min = state;\n                minState = yOffset;\n            }\n            if (yOffset < maxState) {\n                decimatedValue.max = state;\n                maxState = yOffset;\n            }\n        }\n        let hasValues = maxWeightedKey !== undefined;\n        if (hasValues) {\n            decimatedValue.y = maxWeightedKey;\n        }\n        else {\n            // no values so set a default a y value\n            if (!this._isYObject) {\n                decimatedValue.min = decimatedValue.y;\n                decimatedValue.max = decimatedValue.y;\n            }\n        }\n    } // finalize );\n    /**\n     * Values to be decimated\n     *\n     * @param xStart - start time of the region\n     * @param xEnd - start time of the region\n     * @param values - Values to be decimated.\n     */\n    decimateValues(xStart, xEnd, inputValues) {\n        // loop over the data samples\n        this._buckets = [];\n        if (inputValues.length() === 0) {\n            return this._buckets;\n        }\n        let currentPoint;\n        let left = exports.findFirstInsertionIdx(inputValues, xStart);\n        let right = exports.findLastInsertionIdx(inputValues, xEnd);\n        if (left > 0) {\n            --left;\n        }\n        if (right < inputValues.length()) {\n            ++right;\n        }\n        let lastX = 0;\n        if (left < inputValues.length()) {\n            this._isYObject = typeof (inputValues.get(left).y) === 'object';\n            lastX = Math.floor(this._xValueToCoord(inputValues.get(left).x));\n            --lastX;\n        }\n        for (let index = left; index < right; ++index) {\n            let inputValue = inputValues.get(index);\n            let xCoord = Math.floor(this._xValueToCoord(inputValue.x));\n            if (xCoord !== lastX) {\n                if (currentPoint) {\n                    this.finalizeBucket(currentPoint);\n                    this._buckets.push(currentPoint);\n                }\n                // add in buckets between the previous bucket and the new bucket since\n                // the state spans the whole time\n                if (lastX + 1 < xCoord) {\n                    let point = new NEWSDecimationValue();\n                    this.createNewBucket(point, inputValue);\n                    this.finalizeBucket(point);\n                    point.x = this._xCoordToValue(xCoord - 1);\n                    this._buckets.push(point);\n                    this._prevX = point.x;\n                }\n                currentPoint = new NEWSDecimationValue();\n                this.createNewBucket(currentPoint, inputValue);\n                lastX = xCoord;\n            }\n            else {\n                this.addToBucket(currentPoint, inputValue);\n            }\n        }\n        if (currentPoint) {\n            this.finalizeBucket(currentPoint);\n            this._buckets.push(currentPoint);\n        }\n        return this._buckets;\n    } // decimateValues()\n}\nexports.NEWSStateDecimator = NEWSStateDecimator;\nNEWSStateDecimator.KEY = 'NEWSStateDecimator';\n;\nclass FlameChartRectLimitDecimator {\n    initialize(xValueToCoord, xCoordToValue, yValueToCoord) {\n        this._data = [];\n        this._xValueToCoord = xValueToCoord;\n        this._xCoordToValue = xCoordToValue;\n        this._yValueToCoord = yValueToCoord;\n    }\n    /**\n     * Returns the key of this decimator\n     */\n    getKey() {\n        return FlameChartRectLimitDecimator.KEY;\n    }\n    /**\n     * the name of this decimation scheme\n     */\n    getName() {\n        return '';\n    }\n    /**\n     * Returns the decimated list of data\n     */\n    getValues() {\n        return this._data;\n    }\n    setRectLimit(rectLimit) {\n        this._rectLimit = rectLimit;\n        return this;\n    }\n    /**\n     * Values to be decimated\n     *\n     * @param xStart - start time of the region\n     * @param xEnd - start time of the region\n     * @param values - Values to be decimated.\n     */\n    decimateValues(xStart, xEnd, values) {\n        // using the whole view\n        this._data = [];\n        let rects = values.getData();\n        for (let i = 0; i < rects.length; ++i) {\n            this._data = this._data.concat(rects[i]);\n        }\n        if (this._rectLimit) {\n            this._data.sort(function (a, b) {\n                if (a.traceValue.dx > b.traceValue.dx) {\n                    return -1;\n                }\n                if (a.traceValue.dx < b.traceValue.dx) {\n                    return 1;\n                }\n                return 0;\n            });\n            this._data = this._data.splice(0, this._rectLimit);\n        }\n        return this._data;\n    }\n}\nexports.FlameChartRectLimitDecimator = FlameChartRectLimitDecimator;\nFlameChartRectLimitDecimator.KEY = 'FlameChartRectLimitDecimator';\n;\n/** this decimator merges the rectangles in a flame chart to combine\n * identical rectangles that are touching on a left/right pixel basis so\n * we can merge them for rendering\n */\nclass FlameChartMergeRectDecimator {\n    constructor() {\n        this._minRectDelta = 1;\n    }\n    initialize(xValueToCoord, xCoordToValue, yValueToCoord) {\n        this._data = [];\n        this._xValueToCoord = xValueToCoord;\n        this._xCoordToValue = xCoordToValue;\n        this._yValueToCoord = yValueToCoord;\n    }\n    /**\n     * Returns the key of this decimator\n     */\n    getKey() {\n        return FlameChartMergeRectDecimator.KEY;\n    }\n    /**\n     * the name of this decimation scheme\n     */\n    getName() {\n        return '';\n    }\n    /**\n     * Returns the decimated list of data\n     */\n    getValues() {\n        return this._data;\n    }\n    /**\n     * Set the minimum width of a rectangle.  If there is multiple trace points\n     * within the the minimum width then the data is merged together into\n     * a single rectangle.  Once all data in a rectangle is merged then we call\n     * the [setUserPixelFunction] callback so the the user can modify the value\n     * to be rendered if needed\n     *\n     * @param width the minimum width of a pixel in which data is grouped together\n     */\n    setPixelWidth(width) {\n        this._minRectDelta = width - 1;\n        return this;\n    }\n    setUserPixelFunction(cb) {\n        this._userPixelFunction = cb;\n    }\n    /**\n     * used to generate a list of all rects that could be drawn sorted by duration\n     */\n    mergeRects(values) {\n        let ret = [];\n        // get the width of a pixel\n        let buckets = Math.ceil(this._xValueToCoord(Number.MAX_VALUE)) + 1;\n        // NOTE: I do this up here so I can cheat and use the x values here\n        // so later I don't keep calling this._xCoordToValue\n        let xBucketValues = [];\n        for (let bucket = 0; bucket <= buckets; ++bucket) {\n            xBucketValues.push(this._xCoordToValue(bucket));\n        }\n        // get the width of a pixel so we can force it to be visible by\n        // making the rect width value 1 full pixel delta wide\n        let bucketValueWidth = 0;\n        if (buckets > 1) {\n            bucketValueWidth = this._xCoordToValue(1) - this._xCoordToValue(0);\n        }\n        // compute merged rects\n        for (let i = 0; i < values.length; ++i) {\n            let perLevelData = values[i];\n            if (perLevelData === undefined) {\n                continue;\n            }\n            let mergedLevelData = [];\n            let prevValue;\n            let mergeBucketEnd = -Number.MAX_VALUE;\n            let startXCoord;\n            let endXCoord;\n            // first we walk over all the data and create rects with at least\n            // the minimum width which is specified by this._minPixelWidth\n            let len = perLevelData.length;\n            for (let j = 0; j < len; j++) {\n                let value = perLevelData[j];\n                // check if you need to do a simple merge with the previous identical rectangle\n                if (prevValue && prevValue.traceValue.key === value.traceValue.key &&\n                    prevValue.traceValue.x + prevValue.traceValue.dx === value.traceValue.x) {\n                    prevValue.traceValue.dx += value.traceValue.dx;\n                    continue;\n                }\n                startXCoord = Math.floor(this._xValueToCoord(value.traceValue.x));\n                // check if we already partially counted this sample\n                if (mergeBucketEnd > startXCoord) {\n                    startXCoord = mergeBucketEnd;\n                }\n                endXCoord = Math.floor(this._xValueToCoord(value.traceValue.x + value.traceValue.dx));\n                let fcValue;\n                if (endXCoord - startXCoord > this._minRectDelta) {\n                    // if this single trace value rectangle is wide enough to be rendered by itself\n                    fcValue = {\n                        traceValue: {\n                            x: xBucketValues[startXCoord],\n                            dx: xBucketValues[endXCoord] - xBucketValues[startXCoord],\n                            key: value.traceValue.key,\n                            name: value.traceValue.name,\n                            desc: value.traceValue.desc,\n                        },\n                        decimatedValues: [value.traceValue],\n                        depth: value.depth\n                    };\n                }\n                else {\n                    // might have to merge with other rectangles\n                    let subpixelMap = {};\n                    let valueList = [];\n                    // set this so we know when to stop merging data for this rectangle\n                    mergeBucketEnd = startXCoord + this._minRectDelta;\n                    // add in the initial weight\n                    if (value.traceValue.x < xBucketValues[startXCoord]) {\n                        subpixelMap[value.traceValue.name] = value.traceValue.x + value.traceValue.dx - xBucketValues[startXCoord];\n                    }\n                    else {\n                        subpixelMap[value.traceValue.name] = value.traceValue.dx;\n                    }\n                    valueList.push(value.traceValue);\n                    // before adding the next item iterate to a point where the next\n                    // value starts in the next pixel for the given depth`\n                    for (++j; j < len; ++j) {\n                        value = perLevelData[j];\n                        let localStartXCoord = Math.floor(this._xValueToCoord(value.traceValue.x));\n                        if (localStartXCoord >= mergeBucketEnd) {\n                            // back up to the last item that broke the subpixel\n                            // iteration loop so it can be handled by the outer loop\n                            --j;\n                            break;\n                        }\n                        else {\n                            valueList.push(value.traceValue);\n                            // if we have multiple items in the end pixel add up the\n                            // the durations and find the one with the most weight\n                            if (!subpixelMap.hasOwnProperty(value.traceValue.name)) {\n                                subpixelMap[value.traceValue.name] = 0;\n                            }\n                            if (value.traceValue.x + value.traceValue.dx > xBucketValues[mergeBucketEnd]) {\n                                subpixelMap[value.traceValue.name] += xBucketValues[mergeBucketEnd] - value.traceValue.x;\n                                // back up to the last item that broke the subpixel\n                                // iteration loop so it can be handled by the outer loop\n                                --j;\n                                break;\n                            }\n                            else {\n                                subpixelMap[value.traceValue.name] += value.traceValue.dx;\n                            }\n                        }\n                    }\n                    let lastTraceValue = valueList[valueList.length - 1];\n                    if (valueList.length === 1) {\n                        // if we have just one item just add it to the trace\n                        fcValue = {\n                            traceValue: {\n                                x: xBucketValues[startXCoord],\n                                dx: xBucketValues[endXCoord] - xBucketValues[startXCoord],\n                                key: lastTraceValue.key,\n                                name: lastTraceValue.name,\n                                desc: lastTraceValue.desc,\n                            },\n                            decimatedValues: valueList,\n                            depth: value.depth\n                        };\n                    }\n                    else {\n                        // find the subpixel value with the most weight\n                        let pixelName;\n                        let max = 0;\n                        for (let name in subpixelMap) {\n                            let groupWeight = subpixelMap[name];\n                            if (groupWeight > max) {\n                                pixelName = name;\n                                max = groupWeight;\n                            }\n                        }\n                        fcValue = {\n                            traceValue: {\n                                x: xBucketValues[startXCoord],\n                                dx: mergeBucketEnd < xBucketValues.length ? xBucketValues[mergeBucketEnd] - xBucketValues[startXCoord] :\n                                    xBucketValues[startXCoord] + bucketValueWidth,\n                                key: 'merged',\n                                name: pixelName,\n                                desc: lastTraceValue.desc,\n                            },\n                            decimatedValues: valueList,\n                            depth: value.depth\n                        };\n                    }\n                }\n                mergedLevelData.push(fcValue);\n                // update the last value for this level\n                prevValue = fcValue;\n            }\n            // now that we have computed rects and their the subpixel values\n            // if applicable we actually go through and clean things up and then\n            // merge the rects for rendering performance\n            prevValue = undefined;\n            let lastTs = 0;\n            let isNewValue = true;\n            for (let j = 0; j < mergedLevelData.length; ++j) {\n                isNewValue = true;\n                let value = mergedLevelData[j];\n                if (value.traceValue.dx < bucketValueWidth) {\n                    // first make the rectangles at least 1 pixel wide\n                    value.traceValue.dx = bucketValueWidth;\n                }\n                if (this._userPixelFunction) {\n                    // let the user clean up the flame chart value if they want\n                    value = this._userPixelFunction(value);\n                }\n                // now actually merge the rects\n                if (prevValue && prevValue.traceValue.key === value.traceValue.key &&\n                    prevValue.traceValue.name === value.traceValue.name) {\n                    lastTs = prevValue.traceValue.x + prevValue.traceValue.dx;\n                    if (lastTs >= value.traceValue.x) {\n                        prevValue.traceValue.dx = value.traceValue.x + value.traceValue.dx - prevValue.traceValue.x;\n                        prevValue.decimatedValues.concat(value.decimatedValues);\n                        isNewValue = false;\n                    }\n                }\n                if (isNewValue) {\n                    ret.push(value);\n                    prevValue = value;\n                }\n            }\n        }\n        return ret;\n    }\n    /**\n     * Values to be decimated\n     *\n     * @param xStart - start time of the region\n     * @param xEnd - start time of the region\n     * @param values - Values to be decimated.\n     */\n    decimateValues(xStart, xEnd, values) {\n        // using the whole view\n        this._data = this.mergeRects(values.getData());\n        return this._data;\n    }\n}\nexports.FlameChartMergeRectDecimator = FlameChartMergeRectDecimator;\nFlameChartMergeRectDecimator.KEY = 'FlameChartMergeRectDecimator';\n;\n/**\n * Takes ITraceValue data and for each bucket returns a residency value\n * by ITracevalue.name. This means the sum of all values within an output bucket is 100.\n */\nclass TraceResidencyDecimator {\n    initialize(xValueToCoord, xCoordToValue, yValueToCoord, states) {\n        this._decimatedValues = [];\n        this._xValueToCoord = xValueToCoord;\n        this._xCoordToValue = xCoordToValue;\n        this._yValueToCoord = yValueToCoord;\n        this._states = states;\n    }\n    /**\n     * Returns the key of this decimator\n     */\n    getKey() {\n        return TraceResidencyDecimator.KEY;\n    }\n    /**\n     * the name of this decimation scheme\n     */\n    getName() {\n        return '';\n    }\n    /**\n     * Returns the decimated list of data\n     */\n    getValues() {\n        return this._decimatedValues;\n    }\n    /**\n   * Values to be decimated\n   *\n   * @param xStart - start time of the region\n   * @param xEnd - start time of the region\n   * @param values - Values to be decimated.\n   */\n    decimateValues(xStart, xEnd, values) {\n        this._decimatedValues = new Array(this._states.length).fill(0).map(() => new Array());\n        let globalStartBucket = 0;\n        let globalEndBucket = Math.ceil(this._xValueToCoord(Number.MAX_VALUE));\n        if (globalEndBucket < globalStartBucket) {\n            return undefined;\n        }\n        // this is total weighted sum for each state per x, then used to store percentage per x\n        let tempValues = {};\n        // map states to return index\n        let stateMap = {};\n        this._states.forEach((state, index) => {\n            stateMap[state] = index;\n            tempValues[state] = Array.apply(null, Array(globalEndBucket)).\n                map(Number.prototype.valueOf, 0);\n        });\n        // set up the values for iteration\n        // for a series get the weighted sum for the number of buckets xStart to xEnd\n        let value;\n        let traceEndX;\n        let start = exports.findFirstInsertionIdx(values, xStart);\n        let end = exports.findLastInsertionIdx(values, xEnd);\n        if (start > 0) {\n            --start;\n        }\n        // NOTE: I do this up here so I can cheat and use the x values here\n        // so later I don't keep calling this._xCoordToValue\n        let xBucketValues = [];\n        for (let bucket = 0; bucket <= globalEndBucket; ++bucket) {\n            xBucketValues.push(this._xCoordToValue(bucket));\n        }\n        // this is the amount of x values within a given bucket\n        let bucketScalar = 1 / (xBucketValues[globalStartBucket + 1] - xBucketValues[globalStartBucket]);\n        // get weighted sum of the values for each bucket\n        // note this is forward looking data unlike most of our data so\n        // the algorithm is a little different\n        for (let rawDataIdx = start; rawDataIdx < end; ++rawDataIdx) {\n            value = values.get(rawDataIdx);\n            traceEndX = value.x + value.dx;\n            let startBucket = Math.floor(this._xValueToCoord(value.x));\n            let endBucket = Math.floor(this._xValueToCoord(traceEndX));\n            if (startBucket === endBucket) {\n                tempValues[value.name][startBucket] += value.dx * bucketScalar;\n                // TODO consider we should/can fix this corner case\n                // Code below is technically more correct as it handles some edge cases\n                // but it's about 3x slower?\n                // if (xStart === undefined || (value.x > xStart && traceEndX < xEnd)) {\n                //     // here it's all in the existing bucket\n                //     tempValues[value.name][startBucket] += value.dx * bucketScalar;\n                // } else if (traceEndX > xStart) {\n                //     if (traceEndX < xEnd) {\n                //         // here the back half is in the bucket\n                //         tempValues[value.name][startBucket] += (traceEndX - xStart) * bucketScalar;\n                //     } else {\n                //         // here the front half is in the bucket\n                //         tempValues[value.name][startBucket] += (xEnd - value.x) * bucketScalar;\n                //     }\n                // }\n            }\n            else {\n                // add in start bucket amount\n                let startX = xStart ? Math.max(xStart, value.x) : value.x;\n                let endStartBucket = xBucketValues[startBucket + 1];\n                tempValues[value.name][startBucket] += (endStartBucket - startX) * bucketScalar;\n                // add in all the bucket values in between\n                for (let currBucket = startBucket + 1; currBucket < endBucket; ++currBucket) {\n                    tempValues[value.name][currBucket] += 1;\n                }\n                // add in end bucket amount\n                let endX = xEnd ? Math.min(xEnd, traceEndX) : traceEndX;\n                let startEndBucket = xBucketValues[endBucket];\n                tempValues[value.name][endBucket] += (endX - startEndBucket) * bucketScalar;\n            }\n        }\n        // create an array that is used when this state wasn't seen at\n        // all in the time region.\n        let emptyArray = [];\n        for (let bucket = 0; bucket < globalEndBucket; ++bucket) {\n            emptyArray[bucket] = {\n                x: xBucketValues[bucket],\n                y: 0\n            };\n        }\n        for (let stateIdx = 0; stateIdx < this._states.length; ++stateIdx) {\n            let buckets = tempValues[this._states[stateIdx]];\n            if (buckets) {\n                for (let bucket = 0; bucket < buckets.length; ++bucket) {\n                    let y = tempValues[this._states[stateIdx]][bucket] ?\n                        tempValues[this._states[stateIdx]][bucket] : 0;\n                    this._decimatedValues[stateIdx][bucket] = {\n                        x: xBucketValues[bucket],\n                        y: y * 100\n                    };\n                }\n            }\n            else {\n                this._decimatedValues[stateIdx] = emptyArray;\n            }\n        }\n        return this._decimatedValues;\n    }\n}\nexports.TraceResidencyDecimator = TraceResidencyDecimator;\nTraceResidencyDecimator.KEY = 'TraceResidencyDecimator';\n;\n/**\n* Takes ITraceValue data and for each bucket returns a sum by ITracevalue.name.\n* This means the sum of all values within an output bucket is 100.\n*/\nclass TraceStateDecimator {\n    initialize(xValueToCoord, xCoordToValue, yValueToCoord, states) {\n        this._decimatedValues = [];\n        this._xValueToCoord = xValueToCoord;\n        this._xCoordToValue = xCoordToValue;\n        this._yValueToCoord = yValueToCoord;\n        this._states = states;\n    }\n    /**\n     * Returns the key of this decimator\n     */\n    getKey() {\n        return TraceStateDecimator.KEY;\n    }\n    /**\n     * the name of this decimation scheme\n     */\n    getName() {\n        return '';\n    }\n    /**\n     * Returns the decimated list of data\n     */\n    getValues() {\n        return this._decimatedValues;\n    }\n    /**\n   * Values to be decimated\n   *\n   * @param xStart - start time of the region\n   * @param xEnd - start time of the region\n   * @param values - Values to be decimated.\n   */\n    decimateValues(xStart, xEnd, values) {\n        let globalStartBucket = 0;\n        let globalEndBucket = Math.ceil(this._xValueToCoord(Number.MAX_VALUE));\n        if (globalEndBucket < globalStartBucket) {\n            return undefined;\n        }\n        // set up the values for iteration\n        // for a series get the weighted sum for the number of buckets xStart to xEnd\n        let value;\n        let traceEndX;\n        let start = exports.findFirstInsertionIdx(values, xStart);\n        let end = exports.findLastInsertionIdx(values, xEnd);\n        if (start > 0) {\n            --start;\n        }\n        // NOTE: I do this up here so I can cheat and use the x values here\n        // so later I don't keep calling this._xCoordToValue\n        this._decimatedValues = [];\n        for (let bucket = 0; bucket <= globalEndBucket; ++bucket) {\n            this._decimatedValues[bucket] = new NEWSDecimationValue(this._xCoordToValue(bucket));\n        }\n        let states = {};\n        this._states.forEach((state, i) => {\n            states[state] = i;\n        });\n        // store the entry/exit/min/max of each bucket\n        // min and max are based on the state index\n        for (let rawDataIdx = start; rawDataIdx < end; ++rawDataIdx) {\n            value = values.get(rawDataIdx);\n            traceEndX = value.x + value.dx;\n            let startBucket = Math.floor(this._xValueToCoord(value.x));\n            let endBucket = Math.floor(this._xValueToCoord(traceEndX));\n            if (!this._decimatedValues[startBucket].entry) {\n                this._decimatedValues[startBucket].entry = states[value.name];\n                this._decimatedValues[startBucket].exit = states[value.name];\n                this._decimatedValues[startBucket].min = states[value.name];\n                this._decimatedValues[startBucket].max = states[value.name];\n            }\n            if (startBucket === endBucket) {\n                this._decimatedValues[startBucket].exit = states[value.name];\n                this._decimatedValues[startBucket].min =\n                    Math.min(this._decimatedValues[startBucket].min, states[value.name]);\n                this._decimatedValues[startBucket].max =\n                    Math.max(this._decimatedValues[startBucket].max, states[value.name]);\n            }\n            else {\n                // start bucket exit\n                this._decimatedValues[startBucket].exit = states[value.name];\n                this._decimatedValues[startBucket].min =\n                    Math.min(this._decimatedValues[startBucket].min, states[value.name]);\n                this._decimatedValues[startBucket].max =\n                    Math.max(this._decimatedValues[startBucket].max, states[value.name]);\n                // add in all the bucket values in between\n                for (let currBucket = startBucket + 1; currBucket <= endBucket; ++currBucket) {\n                    this._decimatedValues[currBucket].entry = states[value.name];\n                    this._decimatedValues[currBucket].exit = states[value.name];\n                    this._decimatedValues[currBucket].min = states[value.name];\n                    this._decimatedValues[currBucket].max = states[value.name];\n                }\n            }\n        }\n        // convert state index to actual state names for rendering\n        for (let i = 0; i < this._decimatedValues.length; ++i) {\n            let newsValue = this._decimatedValues[i];\n            let exit = newsValue.exit;\n            newsValue.entry = this._states[newsValue.entry];\n            newsValue.exit = this._states[exit];\n            newsValue.y = this._states[exit];\n            newsValue.min = this._states[newsValue.min];\n            newsValue.max = this._states[newsValue.max];\n        }\n        return this._decimatedValues;\n    }\n}\nexports.TraceStateDecimator = TraceStateDecimator;\nTraceStateDecimator.KEY = 'TraceStateDecimator';\n;\n/**\n * For a marker layer just removes markers that have the same X value\n */\nclass SimpleMarkerDecimator {\n    initialize(xValueToCoord, xCoordToValue, yValueToCoord) {\n        this._data = [];\n        this._xValueToCoord = xValueToCoord;\n        this._xCoordToValue = xCoordToValue;\n        this._yValueToCoord = yValueToCoord;\n    }\n    /**\n     * Returns the key of this decimator\n     */\n    getKey() {\n        return SimpleMarkerDecimator.KEY;\n    }\n    /**\n     * the name of this decimation scheme\n     */\n    getName() {\n        return '';\n    }\n    /**\n     * Returns the decimated list of data\n     */\n    getValues() {\n        return this._data;\n    }\n    mergeMarkers(values) {\n        let ret = [];\n        let lastCoord = -Number.MAX_VALUE;\n        for (let i = 0; i < values.length; ++i) {\n            let value = values[i];\n            let coord = this._xValueToCoord(value.x);\n            if (coord !== lastCoord) {\n                ret.push(value);\n                lastCoord = coord;\n            }\n        }\n        return ret;\n    }\n    /**\n     * Values to be decimated\n     *\n     * @param xStart - start time of the region\n     * @param xEnd - start time of the region\n     * @param values - Values to be decimated.\n     */\n    decimateValues(xStart, xEnd, values) {\n        let allData = values.getData();\n        // using the whole view\n        if (xStart !== undefined && xEnd !== undefined) {\n            let filteredData = [];\n            for (let i = 0; i < allData.length; ++i) {\n                let value = allData[i];\n                if (value.x < xEnd && value.x > xStart) {\n                    filteredData.push(value);\n                }\n                else if (value.dx && value.x + value.dx < xEnd &&\n                    value.x + value.dx > xStart) {\n                    filteredData.push(value);\n                }\n            }\n            this._data = this.mergeMarkers(filteredData);\n        }\n        else {\n            this._data = this.mergeMarkers(allData);\n        }\n        return this._data;\n    }\n}\nexports.SimpleMarkerDecimator = SimpleMarkerDecimator;\nSimpleMarkerDecimator.KEY = 'SimpleMarkerDecimator';\n;\n/** */\nclass XYHeatMapDecimator {\n    constructor() {\n    }\n    /**\n     * construct a generic decimator using a custom user function\n     *\n     * @param xValueToCoord converts the x value to a GUI x coordinate\n     * @param yValueToCoord converts the y value to a GUI y coordinate\n     * @param decimationFunc convert a list of data to a for rendering smaller list\n     */\n    initialize(xValueToCoord, xCoordToValue, yValueToCoord) {\n        this._xValueToCoord = xValueToCoord;\n        this._xCoordToValue = xCoordToValue;\n        this._yValueToCoord = yValueToCoord;\n    }\n    /**\n     * Returns the key of this decimator\n     */\n    getKey() {\n        return SummedValueMultiXYSeriesDecimator.KEY;\n    }\n    /**\n     * Returns the decimated list of buckets\n     */\n    getName() {\n        return '';\n    }\n    /**\n     * Returns the decimated list of buckets\n     */\n    getValues() {\n        return this._decimatedValues;\n    }\n    /**\n     * Values to be decimated\n     *\n     * @param xStart - start time of the region\n     * @param xEnd - start time of the region\n     * @param values - Values to be decimated.\n     */\n    decimateValues(xStart, xEnd, values) {\n        this._decimatedValues = [];\n        // first this is total weighted sum per x, then used to store percentage per x\n        let tempValues = [];\n        let globalStartBucket = 0;\n        let globalEndBucket = Math.ceil(this._xValueToCoord(Number.MAX_VALUE));\n        if (globalEndBucket < globalStartBucket) {\n            return undefined;\n        }\n        // NOTE: I do this up here so I can cheat and use the x values here\n        // so later I don't keep calling _xCoordToValue\n        let xBucketValues = [];\n        for (let bucket = 0; bucket <= globalEndBucket + 1; ++bucket) {\n            xBucketValues.push(this._xCoordToValue(bucket));\n        }\n        // for a series get the weighted sum for the number of buckets xStart to xEnd\n        for (let stateIdx = 0; stateIdx < values.length; ++stateIdx) {\n            let perStateData = values[stateIdx];\n            let value;\n            let nextValue;\n            let start = exports.findFirstInsertionIdx(values[stateIdx], xStart);\n            let end = exports.findLastInsertionIdx(values[stateIdx], xEnd);\n            if (start > 0) {\n                --start;\n            }\n            // the last element would be caught by the algorithm already\n            if (end === perStateData.length()) {\n                --end;\n            }\n            // pad endBucket + 1 so we get data past the last point in the bucket\n            // so we can graph to the first value in the next bucket\n            tempValues[stateIdx] = Array.apply(null, Array(globalEndBucket)).\n                map(Number.prototype.valueOf, 0);\n            // get weighted sum of the values for each bucket\n            for (let rawDataIdx = start; rawDataIdx < end; ++rawDataIdx) {\n                value = perStateData.get(rawDataIdx);\n                nextValue = perStateData.get(rawDataIdx + 1);\n                let startBucket = Math.floor(this._xValueToCoord(value.x));\n                let endBucket = Math.floor(this._xValueToCoord(nextValue.x));\n                let totalX = (nextValue.x - value.x);\n                let valuePerX = totalX === 0 ? 0 : nextValue.y / totalX;\n                if (startBucket === endBucket) {\n                    if (xStart === undefined || (value.x > xStart && nextValue.x < xEnd)) {\n                        // here it's all in the existing bucket\n                        tempValues[stateIdx][startBucket] += valuePerX;\n                    }\n                    else {\n                        let bucketScalar = 1 / (xBucketValues[startBucket + 1] - xBucketValues[startBucket]);\n                        if (nextValue.x < xEnd) {\n                            // here the back half is in the bucket\n                            tempValues[stateIdx][startBucket] +=\n                                (nextValue.x - xBucketValues[startBucket]) * valuePerX * bucketScalar;\n                        }\n                        else {\n                            // here the front half is in the bucket\n                            tempValues[stateIdx][startBucket] +=\n                                (xBucketValues[startBucket + 1] - value.x) * valuePerX * bucketScalar;\n                        }\n                    }\n                }\n                else {\n                    let bucketScalar = 1 / (xBucketValues[startBucket + 1] - xBucketValues[startBucket]);\n                    let startX = xStart ? Math.max(xStart, value.x) : value.x;\n                    let endStartBucket = xBucketValues[startBucket + 1];\n                    tempValues[stateIdx][startBucket] +=\n                        (endStartBucket - startX) * valuePerX * bucketScalar;\n                    // add in all the bucket values in between\n                    for (let currBucket = startBucket + 1; currBucket < endBucket; ++currBucket) {\n                        tempValues[stateIdx][currBucket] += valuePerX;\n                    }\n                    // add in end bucket amount\n                    bucketScalar = 1 / (xBucketValues[endBucket] - xBucketValues[endBucket - 1]);\n                    let endX = xEnd ? Math.min(xEnd, nextValue.x) : nextValue.x;\n                    let startEndBucket = xBucketValues[endBucket];\n                    tempValues[stateIdx][endBucket] +=\n                        (endX - startEndBucket) * valuePerX * bucketScalar;\n                }\n            }\n            this._decimatedValues[stateIdx] = [];\n            let buckets = tempValues[stateIdx];\n            for (let bucket = 0; bucket < buckets.length; ++bucket) {\n                this._decimatedValues[stateIdx][bucket] = {\n                    x: xBucketValues[bucket],\n                    y: tempValues[stateIdx][bucket] ? tempValues[stateIdx][bucket] : 0\n                };\n            }\n        }\n        return this._decimatedValues;\n    }\n}\nexports.XYHeatMapDecimator = XYHeatMapDecimator;\nXYHeatMapDecimator.KEY = 'XYHeatMapDecimator';\n;\nlet decimatorList = [\n    new ResidencyDecimator(), new MinPointDecimator(),\n    new AvgPointDecimator(), new MaxPointDecimator(), new AvgContinuousDecimator(),\n    new FlameChartMergeRectDecimator(), new FlameChartRectLimitDecimator(),\n    new NEWSPointDecimator(), new NEWSStateDecimator(), new SimpleMarkerDecimator(),\n    new XYPointDecimator(), new SummedValueXYSeriesDecimator(),\n    new SummedValueMultiXYSeriesDecimator(), new TraceResidencyDecimator()\n];\nexports.InternalDecimatorMap = {};\ndecimatorList.forEach(function (decimator) {\n    exports.InternalDecimatorMap[decimator.getKey()] = decimator;\n});\n\n\n//# sourceURL=webpack://UWT/./src/core/cartesian/decimator/decimator.ts?");

/***/ }),

/***/ "./src/core/cartesian/decimator/worker.ts":
/*!************************************************!*\
  !*** ./src/core/cartesian/decimator/worker.ts ***!
  \************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

"use strict";
eval("\nObject.defineProperty(exports, \"__esModule\", { value: true });\nconst axis_1 = __webpack_require__(/*! ../../../interface/chart/axis */ \"./src/interface/chart/axis.ts\");\nconst utilities_1 = __webpack_require__(/*! ../../utilities */ \"./src/core/utilities.ts\");\nconst decimator_1 = __webpack_require__(/*! ./decimator */ \"./src/core/cartesian/decimator/decimator.ts\");\nconst d3 = __webpack_require__(/*! d3 */ \"d3\");\n// Worker.ts\nconst ctx = self;\n// Respond to message from parent thread\nctx.addEventListener(\"message\", (message) => {\n    let xScale;\n    let yScale;\n    let def = message.data;\n    if (def.xAxis.axisDesc.scaleType === axis_1.AxisType.Ordinal) {\n        xScale = d3.scaleBand().range([0, def.xRange]).padding(0.1)\n            .align(0.5).domain(def.xDomain);\n    }\n    else {\n        if (def.xAxis.axisDesc.scaleType === axis_1.AxisType.Linear) {\n            xScale = d3.scaleLinear().domain(def.xDomain).clamp(true);\n        }\n        else if (def.xAxis.axisDesc.scaleType === axis_1.AxisType.Logarithmic) {\n            xScale = d3.scaleLog().domain(def.xDomain).clamp(true);\n        }\n        xScale.range([0, def.xRange]);\n    }\n    if (def.yAxis) {\n        if (def.yAxis.axisDesc.scaleType === axis_1.AxisType.Ordinal) {\n            yScale = d3.scaleBand().range([0, def.yRange]).padding(0.1)\n                .align(0.5).domain(def.yDomain);\n        }\n        else {\n            if (def.yAxis.axisDesc.scaleType === axis_1.AxisType.Linear) {\n                yScale = d3.scaleLinear().domain(def.yDomain).clamp(true);\n            }\n            else if (def.yAxis.axisDesc.scaleType === axis_1.AxisType.Logarithmic) {\n                yScale = d3.scaleLog().domain(def.yDomain).clamp(true);\n            }\n            yScale.range([def.yRange, 0]);\n        }\n    }\n    let decimator = decimator_1.InternalDecimatorMap[def.decimatorName];\n    decimator.initialize(xScale, xScale.invert, yScale, def.names);\n    // ugly hardcode for now\n    let values;\n    if (!def.names) {\n        values = new utilities_1.SimpleBuffer(def.values);\n    }\n    else {\n        values = [];\n        for (let i = 0; i < def.values.length; ++i) {\n            values[i] = new utilities_1.SimpleBuffer(def.values[i]);\n        }\n    }\n    let data = decimator.decimateValues(def.xStart, def.xEnd, values);\n    ctx.postMessage(data, undefined);\n});\n\n\n//# sourceURL=webpack://UWT/./src/core/cartesian/decimator/worker.ts?");

/***/ }),

/***/ "./src/core/data.ts":
/*!**************************!*\
  !*** ./src/core/data.ts ***!
  \**************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

"use strict";
eval("\nObject.defineProperty(exports, \"__esModule\", { value: true });\n/**\n* XYValue\n*\n* Class for simple data that will be rendered as part of a chart\n*/\nclass XYValue {\n    /**\n     * Creates a XYValue instance\n     *\n     * @param x the independent axis coordinate\n     * @param y the dependent axis coordinate\n     */\n    constructor(x, y) {\n        this.x = x;\n        this.y = y;\n    }\n} // XYValue\nexports.XYValue = XYValue;\n/**\n * MinMaxValue\n *\n * Class for candlestick data that will be rendered as part of a chart\n */\nclass MinMaxValue {\n    /**\n     * Creates a MinMaxValue instance\n     *\n     * @param key - the axis co-ordinate which will be x co-ordinate\n     * @param min - the minimum value of metric for the axis co-ordinate\n     * @param max - the maximum value of metric for the axis co-ordinate\n     * @param misc - a misc value of metric for the axis co-ordinate\n     */\n    constructor(x, min, max, misc) {\n        this.x = x;\n        this.min = min;\n        this.max = max;\n        this.y = misc;\n    }\n} // MinMaxValue\nexports.MinMaxValue = MinMaxValue;\n/**\n * CandlestickValue\n *\n * Class for candlestick data that will be rendered as part of a chart\n */\nclass CandlestickValue {\n    /**\n     * Creates a CandlestickValue instance\n     *\n     * @param x - the axis co-ordinate which will be x co-ordinate\n     * @param min - the minimum value of metric for the axis co-ordinate\n     * @param max - the maximum value of metric for the axis co-ordinate\n     * @param entry - the entry value of metric for the axis co-ordinate\n     * @param exit - the exit value of metric for the axis co-ordinate\n     */\n    constructor(x, min, max, entry, exit) {\n        this.x = x;\n        this.min = min;\n        this.max = max;\n        this.entry = entry;\n        this.exit = exit;\n    }\n} // CandlestickValue\nexports.CandlestickValue = CandlestickValue;\n/**\n * SummaryValue class\n */\nclass SummaryValue {\n    /**\n     * SummaryValue class\n     *\n     * @param primaryKey - key for the data\n     * @param value - value for this key\n     * @param secondaryKey - optional secondary key for the data\n     */\n    constructor(key, value = {}) {\n        this.key = key;\n        this.data = value;\n    }\n    /**\n     * Value getter\n     *\n     * @returns add a value to this key\n     */\n    addValue(key, value) {\n        let data = this.data;\n        if (data.hasOwnProperty(key)) {\n            data[key] += value;\n        }\n        else {\n            data[key] = value;\n        }\n        return this;\n    }\n} // class SummaryValue\nexports.SummaryValue = SummaryValue;\n\n\n//# sourceURL=webpack://UWT/./src/core/data.ts?");

/***/ }),

/***/ "./src/core/utilities.ts":
/*!*******************************!*\
  !*** ./src/core/utilities.ts ***!
  \*******************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

"use strict";
eval("\nObject.defineProperty(exports, \"__esModule\", { value: true });\nfunction getSelectionName(className) {\n    if (typeof (className) === 'number') {\n        return 'n' + className;\n    }\n    if (!className) {\n        return '';\n    }\n    if (className.length > 0 && !isNaN(Number(className[0]))) {\n        className = 'z' + className;\n    }\n    className = className.replace(/[\\*\\%\\#\\[\\]\\/\\>\\<\\s\\+\\(\\)\\;\\@\\:\\?\\\"=.,]/g, '-');\n    return className;\n}\nexports.getSelectionName = getSelectionName;\nfunction removeFromList(value, arr) {\n    if (value) {\n        let index = arr.indexOf(value);\n        if (index !== -1) {\n            arr.splice(index, 1);\n        }\n    }\n}\nexports.removeFromList = removeFromList;\n/** taken from d3-array */\nfunction ascending(a, b) {\n    return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN;\n}\n/** taken from d3-array */\nfunction ascendingComparator(f) {\n    return function (d, x) {\n        return ascending(f(d), x);\n    };\n}\n/** modified from d3-array */\nfunction bisect(compare) {\n    if (!compare)\n        compare = ascending;\n    if (compare.length === 1)\n        compare = ascendingComparator(compare);\n    return {\n        left: function (a, x, lo, hi) {\n            if (lo == null)\n                lo = 0;\n            if (hi == null)\n                hi = a.length;\n            while (lo < hi) {\n                var mid = lo + hi >>> 1;\n                if (compare(a[mid], x) < 0)\n                    lo = mid + 1;\n                else\n                    hi = mid;\n            }\n            return lo;\n        },\n        right: function (a, x, lo, hi) {\n            if (lo == null)\n                lo = 0;\n            if (hi == null)\n                hi = a.length;\n            while (lo < hi) {\n                var mid = lo + hi >>> 1;\n                if (compare(a[mid], x) > 0)\n                    hi = mid;\n                else\n                    lo = mid + 1;\n            }\n            return lo;\n        }\n    };\n}\nexports.bisect = bisect;\n/** puts all raw data into buckets based on thresholds and values */\nfunction bucketData(values, thresholds, accessor) {\n    let findRight = bisect().right;\n    let buckets = [];\n    // need one less bucket than thresholds\n    for (let i = 0; i < thresholds.length - 1; ++i) {\n        buckets[i] = [];\n    }\n    let min = thresholds[0];\n    let max = thresholds[thresholds.length - 1];\n    let usedThresholds = thresholds.slice(1);\n    for (let i = 0; i < values.length; ++i) {\n        let compareValue = accessor(values[i]);\n        if (compareValue < min || compareValue > max) {\n            continue;\n        }\n        let valueIdx = findRight(usedThresholds, compareValue);\n        buckets[valueIdx].push(values[i]);\n    }\n    // name the return buckets\n    let ret = {};\n    for (let i = 0; i < thresholds.length - 1; ++i) {\n        let bucketName = thresholds[i] + '-' + thresholds[i + 1];\n        ret[bucketName] = buckets[i];\n    }\n    return ret;\n}\nexports.bucketData = bucketData;\nfunction copy(obj) {\n    let ret = {};\n    for (let key in obj) {\n        ret[key] = obj[key];\n    }\n    return ret;\n}\nexports.copy = copy;\nfunction merge(obj1, obj2) {\n    for (let key in obj2) {\n        obj1[key] = obj2[key];\n    }\n}\nexports.merge = merge;\nfunction convertTraceToTrees(input) {\n    let roots = [];\n    let stack = []; // used to represent the current stack state\n    let nodeStack = []; // used to represent the current stack state\n    for (let i = 0; i < input.length; i++) {\n        let value = input[i];\n        let parent = stack[stack.length - 1];\n        // pop stuff off the stack\n        while (stack.length && value.x > parent.x + parent.dx) {\n            --stack.length;\n            --nodeStack.length;\n            parent = stack[stack.length - 1];\n        }\n        let parentNode = nodeStack[nodeStack.length - 1];\n        let node = {\n            key: value.key,\n            value: value.dx,\n            children: [],\n            parent: parentNode\n        };\n        if (value.name) {\n            node.name = value.name;\n        }\n        if (parentNode) {\n            parentNode.children.push(node);\n        }\n        else {\n            roots.push(node);\n        }\n        stack.push(value);\n        nodeStack.push(node);\n    }\n    return roots;\n}\nexports.convertTraceToTrees = convertTraceToTrees;\nclass SimpleBuffer {\n    constructor(data) {\n        if (data) {\n            this._data = data;\n        }\n        else {\n            this._data = [];\n        }\n    }\n    push(d) {\n        this._data.push(d);\n    }\n    get(index) {\n        return this._data[index];\n    }\n    length() {\n        return this._data.length;\n    }\n    getData() {\n        return this._data;\n    }\n}\nexports.SimpleBuffer = SimpleBuffer;\nclass RingBuffer {\n    constructor(size) {\n        this._data = new Array(size);\n        this._startIdx = 0;\n        this._count = 0;\n        this._isRotating = false;\n    }\n    /** add a new value to the buffer */\n    push(d) {\n        if (this._isRotating) {\n            // the buffer is rotating\n            this._data[this._startIdx] = d;\n            ++this._startIdx;\n            if (this._startIdx === this._count) {\n                this._startIdx = 0;\n            }\n            this._isRotating = true;\n        }\n        else if (this._count === this._data.length - 1) {\n            // here the buffer will start rotating as the buffer is full\n            this._data[this._count] = d;\n            ++this._count;\n            this._isRotating = true;\n        }\n        else {\n            // here the buffer has not been filled yet\n            this._data[this._count] = d;\n            ++this._count;\n        }\n    }\n    /** return the value offset index from the start index\n     * @param index the offset from the start of the buffer\n     */\n    get(index) {\n        if (this._isRotating) {\n            // the buffer is rotating\n            index = index + this._startIdx;\n            if (index >= this._count) {\n                index = index - this._count;\n            }\n        }\n        return this._data[index];\n    }\n    /** get the number of items in the buffer */\n    length() {\n        return this._count;\n    }\n    getData() {\n        if (this._isRotating) {\n            // the buffer is rotating\n            let ret = [];\n            for (let i = this._startIdx; i < this._data.length; ++i) {\n                ret.push(this._data[i]);\n            }\n            for (let i = 0; i < this._startIdx; ++i) {\n                ret.push(this._data[i]);\n            }\n            return ret;\n        }\n        return this._data;\n    }\n}\nexports.RingBuffer = RingBuffer;\nfunction bisectBuffer(compare) {\n    if (!compare)\n        compare = ascending;\n    if (compare.length === 1)\n        compare = ascendingComparator(compare);\n    return {\n        left: function (a, x, lo, hi) {\n            if (lo == null)\n                lo = 0;\n            if (hi == null)\n                hi = a.length();\n            while (lo < hi) {\n                var mid = lo + hi >>> 1;\n                if (compare(a.get(mid), x) < 0)\n                    lo = mid + 1;\n                else\n                    hi = mid;\n            }\n            return lo;\n        },\n        right: function (a, x, lo, hi) {\n            if (lo == null)\n                lo = 0;\n            if (hi == null)\n                hi = a.length();\n            while (lo < hi) {\n                var mid = lo + hi >>> 1;\n                if (compare(a.get(mid), x) > 0)\n                    hi = mid;\n                else\n                    lo = mid + 1;\n            }\n            return lo;\n        }\n    };\n}\nexports.bisectBuffer = bisectBuffer;\nfunction transposeKeys(data) {\n    // this is used to map the keys to their indicies in the output summary data\n    let keyIdxMapping = {};\n    function transposeHelper(output, parentKeys, value, level) {\n        let myKeys = [];\n        for (let i = 0; i < parentKeys.length; ++i) {\n            myKeys[i] = parentKeys[i];\n        }\n        myKeys.push(value.key);\n        if (Array.isArray(value.data)) {\n            for (let i = 0; i < value.data.length; ++i) {\n                transposeHelper(output, myKeys, value.data[i], level + 1);\n            }\n        }\n        else {\n            let currSummaryArray = output;\n            for (let keyIdx = myKeys.length - 1; keyIdx >= 0; --keyIdx) {\n                let key = myKeys[keyIdx];\n                let dataIdx;\n                if (!keyIdxMapping.hasOwnProperty(key)) {\n                    dataIdx = currSummaryArray.length;\n                    keyIdxMapping[key] = dataIdx;\n                }\n                else {\n                    dataIdx = keyIdxMapping[key];\n                }\n                // create the summary data if it doesn't exist yet\n                if (!currSummaryArray[dataIdx]) {\n                    currSummaryArray[dataIdx] = { key: key, data: [] };\n                }\n                // if we are the leaf add the data, else just move to the next level\n                if (keyIdx === 0) {\n                    currSummaryArray[dataIdx].data = value.data;\n                }\n                else {\n                    currSummaryArray = currSummaryArray[dataIdx].data;\n                }\n            }\n        }\n    }\n    let output = [];\n    for (let i = 0; i < data.length; ++i) {\n        transposeHelper(output, [], data[i], 0);\n    }\n    return output;\n}\nexports.transposeKeys = transposeKeys;\nfunction runFunctionOnLeaf(node, func) {\n    if (node && node.children && node.children.length > 0) {\n        for (let i = 0; i < node.children.length; ++i) {\n            runFunctionOnLeaf(node.children[i], func);\n        }\n    }\n    else {\n        func(node);\n    }\n}\nexports.runFunctionOnLeaf = runFunctionOnLeaf;\nfunction isOverlapping(rect1, rect2) {\n    return rect1.x <= rect2.right && rect1.right >= rect2.x &&\n        rect1.y <= rect2.bottom && rect1.bottom >= rect2.y;\n}\nexports.isOverlapping = isOverlapping;\n\n\n//# sourceURL=webpack://UWT/./src/core/utilities.ts?");

/***/ }),

/***/ "./src/interface/chart/axis.ts":
/*!*************************************!*\
  !*** ./src/interface/chart/axis.ts ***!
  \*************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

"use strict";
eval("\nObject.defineProperty(exports, \"__esModule\", { value: true });\n/**\n * defines what type of axis scaling to use\n *\n * @enum {number}\n */\nvar AxisType;\n(function (AxisType) {\n    /** continuous axis of data with a linear scale */\n    AxisType[AxisType[\"Linear\"] = 0] = \"Linear\";\n    /** continuous axis of data with a logarithmic (base 10) scale */\n    AxisType[AxisType[\"Logarithmic\"] = 1] = \"Logarithmic\";\n    /** axis of data with discrete values that are enumerated or derived from the data */\n    AxisType[AxisType[\"Ordinal\"] = 2] = \"Ordinal\";\n})(AxisType = exports.AxisType || (exports.AxisType = {})); // enum AxisType\n\n\n//# sourceURL=webpack://UWT/./src/interface/chart/axis.ts?");

/***/ }),

/***/ "d3":
/*!*********************!*\
  !*** external "d3" ***!
  \*********************/
/*! no static exports found */
/***/ (function(module, exports) {

eval("module.exports = __WEBPACK_EXTERNAL_MODULE_d3__;\n\n//# sourceURL=webpack://UWT/external_%22d3%22?");

/***/ })

/******/ });
});