vis-graph3d
Version:
Create interactive, animated 3d graphs. Surfaces, lines, dots and block styling out of the box.
1 lines • 215 kB
Source Map (JSON)
{"version":3,"file":"vis-graph3d.min.mjs","sources":["../../lib/graph3d/Point3d.js","../../lib/graph3d/Camera.js","../../lib/graph3d/Filter.js","../../lib/graph3d/Range.js","../../lib/graph3d/Settings.js","../../lib/graph3d/DataGroup.js","../../lib/graph3d/options.js","../../lib/graph3d/Point2d.js","../../lib/graph3d/Slider.js","../../lib/graph3d/StepNumber.js","../../lib/graph3d/Graph3d.js"],"sourcesContent":["/**\n * @param {number} [x]\n * @param {number} [y]\n * @param {number} [z]\n */\nfunction Point3d(x, y, z) {\n this.x = x !== undefined ? x : 0;\n this.y = y !== undefined ? y : 0;\n this.z = z !== undefined ? z : 0;\n}\n\n/**\n * Subtract the two provided points, returns a-b\n * @param {Point3d} a\n * @param {Point3d} b\n * @returns {Point3d} a-b\n */\nPoint3d.subtract = function (a, b) {\n const sub = new Point3d();\n sub.x = a.x - b.x;\n sub.y = a.y - b.y;\n sub.z = a.z - b.z;\n return sub;\n};\n\n/**\n * Add the two provided points, returns a+b\n * @param {Point3d} a\n * @param {Point3d} b\n * @returns {Point3d} a+b\n */\nPoint3d.add = function (a, b) {\n const sum = new Point3d();\n sum.x = a.x + b.x;\n sum.y = a.y + b.y;\n sum.z = a.z + b.z;\n return sum;\n};\n\n/**\n * Calculate the average of two 3d points\n * @param {Point3d} a\n * @param {Point3d} b\n * @returns {Point3d} The average, (a+b)/2\n */\nPoint3d.avg = function (a, b) {\n return new Point3d((a.x + b.x) / 2, (a.y + b.y) / 2, (a.z + b.z) / 2);\n};\n\n/**\n * Scale the provided point by a scalar, returns p*c\n * @param {Point3d} p\n * @param {number} c\n * @returns {Point3d} p*c\n */\nPoint3d.scalarProduct = function (p, c) {\n return new Point3d(p.x * c, p.y * c, p.z * c);\n};\n\n/**\n * Calculate the dot product of the two provided points, returns a.b\n * Documentation: http://en.wikipedia.org/wiki/Dot_product\n * @param {Point3d} a\n * @param {Point3d} b\n * @returns {Point3d} dot product a.b\n */\nPoint3d.dotProduct = function (a, b) {\n return a.x * b.x + a.y * b.y + a.z * b.z;\n};\n\n/**\n * Calculate the cross product of the two provided points, returns axb\n * Documentation: http://en.wikipedia.org/wiki/Cross_product\n * @param {Point3d} a\n * @param {Point3d} b\n * @returns {Point3d} cross product axb\n */\nPoint3d.crossProduct = function (a, b) {\n const crossproduct = new Point3d();\n\n crossproduct.x = a.y * b.z - a.z * b.y;\n crossproduct.y = a.z * b.x - a.x * b.z;\n crossproduct.z = a.x * b.y - a.y * b.x;\n\n return crossproduct;\n};\n\n/**\n * Retrieve the length of the vector (or the distance from this point to the origin\n * @returns {number} length\n */\nPoint3d.prototype.length = function () {\n return Math.sqrt(this.x * this.x + this.y * this.y + this.z * this.z);\n};\n\n/**\n * Return a normalized vector pointing in the same direction.\n * @returns {Point3d} normalized\n */\nPoint3d.prototype.normalize = function () {\n return Point3d.scalarProduct(this, 1 / this.length());\n};\n\nexport default Point3d;\n","import Point3d from \"./Point3d.js\";\n\n/**\n * The camera is mounted on a (virtual) camera arm. The camera arm can rotate\n * The camera is always looking in the direction of the origin of the arm.\n * This way, the camera always rotates around one fixed point, the location\n * of the camera arm.\n *\n * Documentation:\n * http://en.wikipedia.org/wiki/3D_projection\n * @class Camera\n */\nfunction Camera() {\n this.armLocation = new Point3d();\n this.armRotation = {};\n this.armRotation.horizontal = 0;\n this.armRotation.vertical = 0;\n this.armLength = 1.7;\n this.cameraOffset = new Point3d();\n this.offsetMultiplier = 0.6;\n\n this.cameraLocation = new Point3d();\n this.cameraRotation = new Point3d(0.5 * Math.PI, 0, 0);\n\n this.calculateCameraOrientation();\n}\n\n/**\n * Set offset camera in camera coordinates\n * @param {number} x offset by camera horisontal\n * @param {number} y offset by camera vertical\n */\nCamera.prototype.setOffset = function (x, y) {\n const abs = Math.abs,\n sign = Math.sign,\n mul = this.offsetMultiplier,\n border = this.armLength * mul;\n\n if (abs(x) > border) {\n x = sign(x) * border;\n }\n if (abs(y) > border) {\n y = sign(y) * border;\n }\n this.cameraOffset.x = x;\n this.cameraOffset.y = y;\n this.calculateCameraOrientation();\n};\n\n/**\n * Get camera offset by horizontal and vertical\n * @returns {number}\n */\nCamera.prototype.getOffset = function () {\n return this.cameraOffset;\n};\n\n/**\n * Set the location (origin) of the arm\n * @param {number} x Normalized value of x\n * @param {number} y Normalized value of y\n * @param {number} z Normalized value of z\n */\nCamera.prototype.setArmLocation = function (x, y, z) {\n this.armLocation.x = x;\n this.armLocation.y = y;\n this.armLocation.z = z;\n\n this.calculateCameraOrientation();\n};\n\n/**\n * Set the rotation of the camera arm\n * @param {number} horizontal The horizontal rotation, between 0 and 2*PI.\n * Optional, can be left undefined.\n * @param {number} vertical The vertical rotation, between 0 and 0.5*PI\n * if vertical=0.5*PI, the graph is shown from the\n * top. Optional, can be left undefined.\n */\nCamera.prototype.setArmRotation = function (horizontal, vertical) {\n if (horizontal !== undefined) {\n this.armRotation.horizontal = horizontal;\n }\n\n if (vertical !== undefined) {\n this.armRotation.vertical = vertical;\n if (this.armRotation.vertical < 0) this.armRotation.vertical = 0;\n if (this.armRotation.vertical > 0.5 * Math.PI)\n this.armRotation.vertical = 0.5 * Math.PI;\n }\n\n if (horizontal !== undefined || vertical !== undefined) {\n this.calculateCameraOrientation();\n }\n};\n\n/**\n * Retrieve the current arm rotation\n * @returns {object} An object with parameters horizontal and vertical\n */\nCamera.prototype.getArmRotation = function () {\n const rot = {};\n rot.horizontal = this.armRotation.horizontal;\n rot.vertical = this.armRotation.vertical;\n\n return rot;\n};\n\n/**\n * Set the (normalized) length of the camera arm.\n * @param {number} length A length between 0.71 and 5.0\n */\nCamera.prototype.setArmLength = function (length) {\n if (length === undefined) return;\n\n this.armLength = length;\n\n // Radius must be larger than the corner of the graph,\n // which has a distance of sqrt(0.5^2+0.5^2) = 0.71 from the center of the\n // graph\n if (this.armLength < 0.71) this.armLength = 0.71;\n if (this.armLength > 5.0) this.armLength = 5.0;\n\n this.setOffset(this.cameraOffset.x, this.cameraOffset.y);\n this.calculateCameraOrientation();\n};\n\n/**\n * Retrieve the arm length\n * @returns {number} length\n */\nCamera.prototype.getArmLength = function () {\n return this.armLength;\n};\n\n/**\n * Retrieve the camera location\n * @returns {Point3d} cameraLocation\n */\nCamera.prototype.getCameraLocation = function () {\n return this.cameraLocation;\n};\n\n/**\n * Retrieve the camera rotation\n * @returns {Point3d} cameraRotation\n */\nCamera.prototype.getCameraRotation = function () {\n return this.cameraRotation;\n};\n\n/**\n * Calculate the location and rotation of the camera based on the\n * position and orientation of the camera arm\n */\nCamera.prototype.calculateCameraOrientation = function () {\n // calculate location of the camera\n this.cameraLocation.x =\n this.armLocation.x -\n this.armLength *\n Math.sin(this.armRotation.horizontal) *\n Math.cos(this.armRotation.vertical);\n this.cameraLocation.y =\n this.armLocation.y -\n this.armLength *\n Math.cos(this.armRotation.horizontal) *\n Math.cos(this.armRotation.vertical);\n this.cameraLocation.z =\n this.armLocation.z + this.armLength * Math.sin(this.armRotation.vertical);\n\n // calculate rotation of the camera\n this.cameraRotation.x = Math.PI / 2 - this.armRotation.vertical;\n this.cameraRotation.y = 0;\n this.cameraRotation.z = -this.armRotation.horizontal;\n\n const xa = this.cameraRotation.x;\n const za = this.cameraRotation.z;\n const dx = this.cameraOffset.x;\n const dy = this.cameraOffset.y;\n const sin = Math.sin,\n cos = Math.cos;\n\n this.cameraLocation.x =\n this.cameraLocation.x + dx * cos(za) + dy * -sin(za) * cos(xa);\n this.cameraLocation.y =\n this.cameraLocation.y + dx * sin(za) + dy * cos(za) * cos(xa);\n this.cameraLocation.z = this.cameraLocation.z + dy * sin(xa);\n};\n\nexport default Camera;\n","import { DataView } from \"vis-data/esnext\";\n\n/**\n * @class Filter\n * @param {DataGroup} dataGroup the data group\n * @param {number} column The index of the column to be filtered\n * @param {Graph3d} graph The graph\n */\nfunction Filter(dataGroup, column, graph) {\n this.dataGroup = dataGroup;\n this.column = column;\n this.graph = graph; // the parent graph\n\n this.index = undefined;\n this.value = undefined;\n\n // read all distinct values and select the first one\n this.values = dataGroup.getDistinctValues(this.column);\n\n if (this.values.length > 0) {\n this.selectValue(0);\n }\n\n // create an array with the filtered datapoints. this will be loaded afterwards\n this.dataPoints = [];\n\n this.loaded = false;\n this.onLoadCallback = undefined;\n\n if (graph.animationPreload) {\n this.loaded = false;\n this.loadInBackground();\n } else {\n this.loaded = true;\n }\n}\n\n/**\n * Return the label\n * @returns {string} label\n */\nFilter.prototype.isLoaded = function () {\n return this.loaded;\n};\n\n/**\n * Return the loaded progress\n * @returns {number} percentage between 0 and 100\n */\nFilter.prototype.getLoadedProgress = function () {\n const len = this.values.length;\n\n let i = 0;\n while (this.dataPoints[i]) {\n i++;\n }\n\n return Math.round((i / len) * 100);\n};\n\n/**\n * Return the label\n * @returns {string} label\n */\nFilter.prototype.getLabel = function () {\n return this.graph.filterLabel;\n};\n\n/**\n * Return the columnIndex of the filter\n * @returns {number} columnIndex\n */\nFilter.prototype.getColumn = function () {\n return this.column;\n};\n\n/**\n * Return the currently selected value. Returns undefined if there is no selection\n * @returns {*} value\n */\nFilter.prototype.getSelectedValue = function () {\n if (this.index === undefined) return undefined;\n\n return this.values[this.index];\n};\n\n/**\n * Retrieve all values of the filter\n * @returns {Array} values\n */\nFilter.prototype.getValues = function () {\n return this.values;\n};\n\n/**\n * Retrieve one value of the filter\n * @param {number} index\n * @returns {*} value\n */\nFilter.prototype.getValue = function (index) {\n if (index >= this.values.length) throw new Error(\"Index out of range\");\n\n return this.values[index];\n};\n\n/**\n * Retrieve the (filtered) dataPoints for the currently selected filter index\n * @param {number} [index] (optional)\n * @returns {Array} dataPoints\n */\nFilter.prototype._getDataPoints = function (index) {\n if (index === undefined) index = this.index;\n\n if (index === undefined) return [];\n\n let dataPoints;\n if (this.dataPoints[index]) {\n dataPoints = this.dataPoints[index];\n } else {\n const f = {};\n f.column = this.column;\n f.value = this.values[index];\n\n const dataView = new DataView(this.dataGroup.getDataSet(), {\n filter: function (item) {\n return item[f.column] == f.value;\n },\n }).get();\n dataPoints = this.dataGroup._getDataPoints(dataView);\n\n this.dataPoints[index] = dataPoints;\n }\n\n return dataPoints;\n};\n\n/**\n * Set a callback function when the filter is fully loaded.\n * @param {Function} callback\n */\nFilter.prototype.setOnLoadCallback = function (callback) {\n this.onLoadCallback = callback;\n};\n\n/**\n * Add a value to the list with available values for this filter\n * No double entries will be created.\n * @param {number} index\n */\nFilter.prototype.selectValue = function (index) {\n if (index >= this.values.length) throw new Error(\"Index out of range\");\n\n this.index = index;\n this.value = this.values[index];\n};\n\n/**\n * Load all filtered rows in the background one by one\n * Start this method without providing an index!\n * @param {number} [index]\n */\nFilter.prototype.loadInBackground = function (index) {\n if (index === undefined) index = 0;\n\n const frame = this.graph.frame;\n\n if (index < this.values.length) {\n // create a progress box\n if (frame.progress === undefined) {\n frame.progress = document.createElement(\"DIV\");\n frame.progress.style.position = \"absolute\";\n frame.progress.style.color = \"gray\";\n frame.appendChild(frame.progress);\n }\n const progress = this.getLoadedProgress();\n frame.progress.innerHTML = \"Loading animation... \" + progress + \"%\";\n // TODO: this is no nice solution...\n frame.progress.style.bottom = 60 + \"px\"; // TODO: use height of slider\n frame.progress.style.left = 10 + \"px\";\n\n const me = this;\n setTimeout(function () {\n me.loadInBackground(index + 1);\n }, 10);\n this.loaded = false;\n } else {\n this.loaded = true;\n\n // remove the progress box\n if (frame.progress !== undefined) {\n frame.removeChild(frame.progress);\n frame.progress = undefined;\n }\n\n if (this.onLoadCallback) this.onLoadCallback();\n }\n};\n\nexport default Filter;\n","/**\n * Helper class to make working with related min and max values easier.\n *\n * The range is inclusive; a given value is considered part of the range if:\n *\n * this.min <= value <= this.max\n */\nfunction Range() {\n this.min = undefined;\n this.max = undefined;\n}\n\n/**\n * Adjust the range so that the passed value fits in it.\n *\n * If the value is outside of the current extremes, adjust\n * the min or max so that the value is within the range.\n * @param {number} value Numeric value to fit in range\n */\nRange.prototype.adjust = function (value) {\n if (value === undefined) return;\n\n if (this.min === undefined || this.min > value) {\n this.min = value;\n }\n\n if (this.max === undefined || this.max < value) {\n this.max = value;\n }\n};\n\n/**\n * Adjust the current range so that the passed range fits in it.\n * @param {Range} range Range instance to fit in current instance\n */\nRange.prototype.combine = function (range) {\n this.add(range.min);\n this.add(range.max);\n};\n\n/**\n * Expand the range by the given value\n *\n * min will be lowered by given value;\n * max will be raised by given value\n *\n * Shrinking by passing a negative value is allowed.\n * @param {number} val Amount by which to expand or shrink current range with\n */\nRange.prototype.expand = function (val) {\n if (val === undefined) {\n return;\n }\n\n const newMin = this.min - val;\n const newMax = this.max + val;\n\n // Note that following allows newMin === newMax.\n // This should be OK, since method expand() allows this also.\n if (newMin > newMax) {\n throw new Error(\"Passed expansion value makes range invalid\");\n }\n\n this.min = newMin;\n this.max = newMax;\n};\n\n/**\n * Determine the full range width of current instance.\n * @returns {num} The calculated width of this range\n */\nRange.prototype.range = function () {\n return this.max - this.min;\n};\n\n/**\n * Determine the central point of current instance.\n * @returns {number} the value in the middle of min and max\n */\nRange.prototype.center = function () {\n return (this.min + this.max) / 2;\n};\n\nexport default Range;\n","////////////////////////////////////////////////////////////////////////////////\n// This modules handles the options for Graph3d.\n//\n////////////////////////////////////////////////////////////////////////////////\nimport * as util from \"vis-util/esnext\";\n\nimport Camera from \"./Camera.js\";\nimport Point3d from \"./Point3d.js\";\n\n// enumerate the available styles\nconst STYLE = {\n BAR: 0,\n BARCOLOR: 1,\n BARSIZE: 2,\n DOT: 3,\n DOTLINE: 4,\n DOTCOLOR: 5,\n DOTSIZE: 6,\n GRID: 7,\n LINE: 8,\n SURFACE: 9,\n};\n\n// The string representations of the styles\nconst STYLENAME = {\n dot: STYLE.DOT,\n \"dot-line\": STYLE.DOTLINE,\n \"dot-color\": STYLE.DOTCOLOR,\n \"dot-size\": STYLE.DOTSIZE,\n line: STYLE.LINE,\n grid: STYLE.GRID,\n surface: STYLE.SURFACE,\n bar: STYLE.BAR,\n \"bar-color\": STYLE.BARCOLOR,\n \"bar-size\": STYLE.BARSIZE,\n};\n\n/**\n * Field names in the options hash which are of relevance to the user.\n *\n * Specifically, these are the fields which require no special handling,\n * and can be directly copied over.\n */\nconst OPTIONKEYS = [\n \"width\",\n \"height\",\n \"filterLabel\",\n \"legendLabel\",\n \"xLabel\",\n \"yLabel\",\n \"zLabel\",\n \"xValueLabel\",\n \"yValueLabel\",\n \"zValueLabel\",\n \"showXAxis\",\n \"showYAxis\",\n \"showZAxis\",\n \"showGrayBottom\",\n \"showGrid\",\n \"showPerspective\",\n \"showShadow\",\n \"showSurfaceGrid\",\n \"keepAspectRatio\",\n \"rotateAxisLabels\",\n \"verticalRatio\",\n \"dotSizeRatio\",\n \"dotSizeMinFraction\",\n \"dotSizeMaxFraction\",\n \"showAnimationControls\",\n \"animationInterval\",\n \"animationPreload\",\n \"animationAutoStart\",\n \"axisColor\",\n \"axisFontSize\",\n \"axisFontType\",\n \"gridColor\",\n \"xCenter\",\n \"yCenter\",\n \"zoomable\",\n \"tooltipDelay\",\n \"ctrlToZoom\",\n];\n\n/**\n * Field names in the options hash which are of relevance to the user.\n *\n * Same as OPTIONKEYS, but internally these fields are stored with\n * prefix 'default' in the name.\n */\nconst PREFIXEDOPTIONKEYS = [\n \"xBarWidth\",\n \"yBarWidth\",\n \"valueMin\",\n \"valueMax\",\n \"xMin\",\n \"xMax\",\n \"xStep\",\n \"yMin\",\n \"yMax\",\n \"yStep\",\n \"zMin\",\n \"zMax\",\n \"zStep\",\n];\n\n// Placeholder for DEFAULTS reference\nlet DEFAULTS = undefined;\n\n/**\n * Check if given hash is empty.\n *\n * Source: http://stackoverflow.com/a/679937\n * @param {object} obj\n * @returns {boolean}\n */\nfunction isEmpty(obj) {\n for (const prop in obj) {\n if (Object.prototype.hasOwnProperty.call(obj, prop)) return false;\n }\n\n return true;\n}\n\n/**\n * Make first letter of parameter upper case.\n *\n * Source: http://stackoverflow.com/a/1026087\n * @param {string} str\n * @returns {string}\n */\nfunction capitalize(str) {\n if (str === undefined || str === \"\" || typeof str != \"string\") {\n return str;\n }\n\n return str.charAt(0).toUpperCase() + str.slice(1);\n}\n\n/**\n * Add a prefix to a field name, taking style guide into account\n * @param {string} prefix\n * @param {string} fieldName\n * @returns {string}\n */\nfunction prefixFieldName(prefix, fieldName) {\n if (prefix === undefined || prefix === \"\") {\n return fieldName;\n }\n\n return prefix + capitalize(fieldName);\n}\n\n/**\n * Forcibly copy fields from src to dst in a controlled manner.\n *\n * A given field in dst will always be overwitten. If this field\n * is undefined or not present in src, the field in dst will\n * be explicitly set to undefined.\n *\n * The intention here is to be able to reset all option fields.\n *\n * Only the fields mentioned in array 'fields' will be handled.\n * @param {object} src\n * @param {object} dst\n * @param {Array<string>} fields array with names of fields to copy\n * @param {string} [prefix] prefix to use for the target fields.\n */\nfunction forceCopy(src, dst, fields, prefix) {\n let srcKey;\n let dstKey;\n\n for (let i = 0; i < fields.length; ++i) {\n srcKey = fields[i];\n dstKey = prefixFieldName(prefix, srcKey);\n\n dst[dstKey] = src[srcKey];\n }\n}\n\n/**\n * Copy fields from src to dst in a safe and controlled manner.\n *\n * Only the fields mentioned in array 'fields' will be copied over,\n * and only if these are actually defined.\n * @param {object} src\n * @param {object} dst\n * @param {Array<string>} fields array with names of fields to copy\n * @param {string} [prefix] prefix to use for the target fields.\n */\nfunction safeCopy(src, dst, fields, prefix) {\n let srcKey;\n let dstKey;\n\n for (let i = 0; i < fields.length; ++i) {\n srcKey = fields[i];\n if (src[srcKey] === undefined) continue;\n\n dstKey = prefixFieldName(prefix, srcKey);\n\n dst[dstKey] = src[srcKey];\n }\n}\n\n/**\n * Initialize dst with the values in src.\n *\n * src is the hash with the default values.\n * A reference DEFAULTS to this hash is stored locally for\n * further handling.\n *\n * For now, dst is assumed to be a Graph3d instance.\n * @param {object} src\n * @param {object} dst\n */\nfunction setDefaults(src, dst) {\n if (src === undefined || isEmpty(src)) {\n throw new Error(\"No DEFAULTS passed\");\n }\n if (dst === undefined) {\n throw new Error(\"No dst passed\");\n }\n\n // Remember defaults for future reference\n DEFAULTS = src;\n\n // Handle the defaults which can be simply copied over\n forceCopy(src, dst, OPTIONKEYS);\n forceCopy(src, dst, PREFIXEDOPTIONKEYS, \"default\");\n\n // Handle the more complex ('special') fields\n setSpecialSettings(src, dst);\n\n // Following are internal fields, not part of the user settings\n dst.margin = 10; // px\n dst.showTooltip = false;\n dst.onclick_callback = null;\n dst.eye = new Point3d(0, 0, -1); // TODO: set eye.z about 3/4 of the width of the window?\n}\n\n/**\n *\n * @param {object} options\n * @param {object} dst\n */\nfunction setOptions(options, dst) {\n if (options === undefined) {\n return;\n }\n if (dst === undefined) {\n throw new Error(\"No dst passed\");\n }\n\n if (DEFAULTS === undefined || isEmpty(DEFAULTS)) {\n throw new Error(\"DEFAULTS not set for module Settings\");\n }\n\n // Handle the parameters which can be simply copied over\n safeCopy(options, dst, OPTIONKEYS);\n safeCopy(options, dst, PREFIXEDOPTIONKEYS, \"default\");\n\n // Handle the more complex ('special') fields\n setSpecialSettings(options, dst);\n}\n\n/**\n * Special handling for certain parameters\n *\n * 'Special' here means: setting requires more than a simple copy\n * @param {object} src\n * @param {object} dst\n */\nfunction setSpecialSettings(src, dst) {\n if (src.backgroundColor !== undefined) {\n setBackgroundColor(src.backgroundColor, dst);\n }\n\n setDataColor(src.dataColor, dst);\n setStyle(src.style, dst);\n if (src.surfaceColors !== undefined) {\n console.warn(\n \"`options.surfaceColors` is deprecated and may be removed in a future \" +\n \"version. Please use `options.colormap` instead. Note that the `colormap` \" +\n \"option uses the inverse array ordering (running from vMin to vMax).\",\n );\n if (src.colormap !== undefined) {\n throw new Error(\n \"The `colormap` and `surfaceColors` options are mutually exclusive.\",\n );\n }\n if (dst.style !== \"surface\") {\n console.warn(\n \"Ignoring `surfaceColors` in graph style `\" +\n dst.style +\n \"` for \" +\n \"backward compatibility (only effective in `surface` plots).\",\n );\n } else {\n setSurfaceColor(src.surfaceColors, dst);\n }\n } else {\n setColormap(src.colormap, dst);\n }\n setShowLegend(src.showLegend, dst);\n setCameraPosition(src.cameraPosition, dst);\n\n // As special fields go, this is an easy one; just a translation of the name.\n // Can't use this.tooltip directly, because that field exists internally\n if (src.tooltip !== undefined) {\n dst.showTooltip = src.tooltip;\n }\n if (src.onclick != undefined) {\n dst.onclick_callback = src.onclick;\n console.warn(\n \"`options.onclick` is deprecated and may be removed in a future version.\" +\n \" Please use `Graph3d.on('click', handler)` instead.\",\n );\n }\n\n if (src.tooltipStyle !== undefined) {\n util.selectiveDeepExtend([\"tooltipStyle\"], dst, src);\n }\n}\n\n/**\n * Set the value of setting 'showLegend'\n *\n * This depends on the value of the style fields, so it must be called\n * after the style field has been initialized.\n * @param {boolean} showLegend\n * @param {object} dst\n */\nfunction setShowLegend(showLegend, dst) {\n if (showLegend === undefined) {\n // If the default was auto, make a choice for this field\n const isAutoByDefault = DEFAULTS.showLegend === undefined;\n\n if (isAutoByDefault) {\n // these styles default to having legends\n const isLegendGraphStyle =\n dst.style === STYLE.DOTCOLOR || dst.style === STYLE.DOTSIZE;\n\n dst.showLegend = isLegendGraphStyle;\n } else {\n // Leave current value as is\n }\n } else {\n dst.showLegend = showLegend;\n }\n}\n\n/**\n * Retrieve the style index from given styleName\n * @param {string} styleName Style name such as 'dot', 'grid', 'dot-line'\n * @returns {number} styleNumber Enumeration value representing the style, or -1\n * when not found\n */\nfunction getStyleNumberByName(styleName) {\n const number = STYLENAME[styleName];\n\n if (number === undefined) {\n return -1;\n }\n\n return number;\n}\n\n/**\n * Check if given number is a valid style number.\n * @param {string | number} style\n * @returns {boolean} true if valid, false otherwise\n */\nfunction checkStyleNumber(style) {\n let valid = false;\n\n for (const n in STYLE) {\n if (STYLE[n] === style) {\n valid = true;\n break;\n }\n }\n\n return valid;\n}\n\n/**\n *\n * @param {string | number} style\n * @param {object} dst\n */\nfunction setStyle(style, dst) {\n if (style === undefined) {\n return; // Nothing to do\n }\n\n let styleNumber;\n\n if (typeof style === \"string\") {\n styleNumber = getStyleNumberByName(style);\n\n if (styleNumber === -1) {\n throw new Error(\"Style '\" + style + \"' is invalid\");\n }\n } else {\n // Do a pedantic check on style number value\n if (!checkStyleNumber(style)) {\n throw new Error(\"Style '\" + style + \"' is invalid\");\n }\n\n styleNumber = style;\n }\n\n dst.style = styleNumber;\n}\n\n/**\n * Set the background styling for the graph\n * @param {string | {fill: string, stroke: string, strokeWidth: string}} backgroundColor\n * @param {object} dst\n */\nfunction setBackgroundColor(backgroundColor, dst) {\n let fill = \"white\";\n let stroke = \"gray\";\n let strokeWidth = 1;\n\n if (typeof backgroundColor === \"string\") {\n fill = backgroundColor;\n stroke = \"none\";\n strokeWidth = 0;\n } else if (typeof backgroundColor === \"object\") {\n if (backgroundColor.fill !== undefined) fill = backgroundColor.fill;\n if (backgroundColor.stroke !== undefined) stroke = backgroundColor.stroke;\n if (backgroundColor.strokeWidth !== undefined)\n strokeWidth = backgroundColor.strokeWidth;\n } else {\n throw new Error(\"Unsupported type of backgroundColor\");\n }\n\n dst.frame.style.backgroundColor = fill;\n dst.frame.style.borderColor = stroke;\n dst.frame.style.borderWidth = strokeWidth + \"px\";\n dst.frame.style.borderStyle = \"solid\";\n}\n\n/**\n *\n * @param {string | object} dataColor\n * @param {object} dst\n */\nfunction setDataColor(dataColor, dst) {\n if (dataColor === undefined) {\n return; // Nothing to do\n }\n\n if (dst.dataColor === undefined) {\n dst.dataColor = {};\n }\n\n if (typeof dataColor === \"string\") {\n dst.dataColor.fill = dataColor;\n dst.dataColor.stroke = dataColor;\n } else {\n if (dataColor.fill) {\n dst.dataColor.fill = dataColor.fill;\n }\n if (dataColor.stroke) {\n dst.dataColor.stroke = dataColor.stroke;\n }\n if (dataColor.strokeWidth !== undefined) {\n dst.dataColor.strokeWidth = dataColor.strokeWidth;\n }\n }\n}\n\n/**\n *\n * @param {object | Array<string>} surfaceColors Either an object that describes the HUE, or an array of HTML hex color codes\n * @param {object} dst\n */\nfunction setSurfaceColor(surfaceColors, dst) {\n if (surfaceColors === undefined || surfaceColors === true) {\n return; // Nothing to do\n }\n if (surfaceColors === false) {\n dst.surfaceColors = undefined;\n return;\n }\n\n if (dst.surfaceColors === undefined) {\n dst.surfaceColors = {};\n }\n\n let rgbColors;\n if (Array.isArray(surfaceColors)) {\n rgbColors = parseColorArray(surfaceColors);\n } else if (typeof surfaceColors === \"object\") {\n rgbColors = parseColorObject(surfaceColors.hue);\n } else {\n throw new Error(\"Unsupported type of surfaceColors\");\n }\n // for some reason surfaceColors goes from vMax to vMin:\n rgbColors.reverse();\n dst.colormap = rgbColors;\n}\n\n/**\n *\n * @param {object | Array<string>} colormap Either an object that describes the HUE, or an array of HTML hex color codes\n * @param {object} dst\n */\nfunction setColormap(colormap, dst) {\n if (colormap === undefined) {\n return;\n }\n\n let rgbColors;\n if (Array.isArray(colormap)) {\n rgbColors = parseColorArray(colormap);\n } else if (typeof colormap === \"object\") {\n rgbColors = parseColorObject(colormap.hue);\n } else if (typeof colormap === \"function\") {\n rgbColors = colormap;\n } else {\n throw new Error(\"Unsupported type of colormap\");\n }\n dst.colormap = rgbColors;\n}\n\n/**\n *\n * @param {Array} colormap\n */\nfunction parseColorArray(colormap) {\n if (colormap.length < 2) {\n throw new Error(\"Colormap array length must be 2 or above.\");\n }\n return colormap.map(function (colorCode) {\n if (!util.isValidHex(colorCode)) {\n throw new Error(`Invalid hex color code supplied to colormap.`);\n }\n return util.hexToRGB(colorCode);\n });\n}\n\n/**\n * Converts an object to a certain amount of hex color stops. At which point:\n * the HTML hex color codes is converted into an RGB color object.\n * @param {object} hues\n */\nfunction parseColorObject(hues) {\n if (hues === undefined) {\n throw new Error(\"Unsupported type of colormap\");\n }\n if (!(hues.saturation >= 0 && hues.saturation <= 100)) {\n throw new Error(\"Saturation is out of bounds. Expected range is 0-100.\");\n }\n if (!(hues.brightness >= 0 && hues.brightness <= 100)) {\n throw new Error(\"Brightness is out of bounds. Expected range is 0-100.\");\n }\n if (!(hues.colorStops >= 2)) {\n throw new Error(\"colorStops is out of bounds. Expected 2 or above.\");\n }\n\n const hueStep = (hues.end - hues.start) / (hues.colorStops - 1);\n\n const rgbColors = [];\n for (let i = 0; i < hues.colorStops; ++i) {\n const hue = ((hues.start + hueStep * i) % 360) / 360;\n rgbColors.push(\n util.HSVToRGB(\n hue < 0 ? hue + 1 : hue,\n hues.saturation / 100,\n hues.brightness / 100,\n ),\n );\n }\n return rgbColors;\n}\n\n/**\n *\n * @param {object} cameraPosition\n * @param {object} dst\n */\nfunction setCameraPosition(cameraPosition, dst) {\n const camPos = cameraPosition;\n if (camPos === undefined) {\n return;\n }\n\n if (dst.camera === undefined) {\n dst.camera = new Camera();\n }\n\n dst.camera.setArmRotation(camPos.horizontal, camPos.vertical);\n dst.camera.setArmLength(camPos.distance);\n}\n\nexport { STYLE, setCameraPosition, setDefaults, setOptions };\n","import { DataSet, DataView } from \"vis-data/esnext\";\n\nimport Filter from \"./Filter.js\";\nimport Point3d from \"./Point3d.js\";\nimport Range from \"./Range.js\";\nimport { STYLE } from \"./Settings.js\";\n\n/**\n * Creates a container for all data of one specific 3D-graph.\n *\n * On construction, the container is totally empty; the data\n * needs to be initialized with method initializeData().\n * Failure to do so will result in the following exception begin thrown\n * on instantiation of Graph3D:\n *\n * Error: Array, DataSet, or DataView expected\n * @function Object() { [native code] } DataGroup\n */\nfunction DataGroup() {\n this.dataTable = null; // The original data table\n}\n\n/**\n * Initializes the instance from the passed data.\n *\n * Calculates minimum and maximum values and column index values.\n *\n * The graph3d instance is used internally to access the settings for\n * the given instance.\n * TODO: Pass settings only instead.\n * @param {vis.Graph3d} graph3d Reference to the calling Graph3D instance.\n * @param {Array | DataSet | DataView} rawData The data containing the items for\n * the Graph.\n * @param {number} style Style Number\n * @returns {Array.<object>}\n */\nDataGroup.prototype.initializeData = function (graph3d, rawData, style) {\n if (rawData === undefined) return;\n\n if (Array.isArray(rawData)) {\n rawData = new DataSet(rawData);\n }\n\n let data;\n if (rawData instanceof DataSet || rawData instanceof DataView) {\n data = rawData.get();\n } else {\n throw new Error(\"Array, DataSet, or DataView expected\");\n }\n\n if (data.length == 0) return;\n\n this.style = style;\n\n // unsubscribe from the dataTable\n if (this.dataSet) {\n this.dataSet.off(\"*\", this._onChange);\n }\n\n this.dataSet = rawData;\n this.dataTable = data;\n\n // subscribe to changes in the dataset\n const me = this;\n this._onChange = function () {\n graph3d.setData(me.dataSet);\n };\n this.dataSet.on(\"*\", this._onChange);\n\n // determine the location of x,y,z,value,filter columns\n this.colX = \"x\";\n this.colY = \"y\";\n this.colZ = \"z\";\n\n const withBars = graph3d.hasBars(style);\n\n // determine barWidth from data\n if (withBars) {\n if (graph3d.defaultXBarWidth !== undefined) {\n this.xBarWidth = graph3d.defaultXBarWidth;\n } else {\n this.xBarWidth = this.getSmallestDifference(data, this.colX) || 1;\n }\n\n if (graph3d.defaultYBarWidth !== undefined) {\n this.yBarWidth = graph3d.defaultYBarWidth;\n } else {\n this.yBarWidth = this.getSmallestDifference(data, this.colY) || 1;\n }\n }\n\n // calculate minima and maxima\n this._initializeRange(data, this.colX, graph3d, withBars);\n this._initializeRange(data, this.colY, graph3d, withBars);\n this._initializeRange(data, this.colZ, graph3d, false);\n\n if (Object.prototype.hasOwnProperty.call(data[0], \"style\")) {\n this.colValue = \"style\";\n const valueRange = this.getColumnRange(data, this.colValue);\n this._setRangeDefaults(\n valueRange,\n graph3d.defaultValueMin,\n graph3d.defaultValueMax,\n );\n this.valueRange = valueRange;\n } else {\n this.colValue = \"z\";\n this.valueRange = this.zRange;\n }\n\n // Initialize data filter if a filter column is provided\n const table = this.getDataTable();\n if (Object.prototype.hasOwnProperty.call(table[0], \"filter\")) {\n if (this.dataFilter === undefined) {\n this.dataFilter = new Filter(this, \"filter\", graph3d);\n this.dataFilter.setOnLoadCallback(function () {\n graph3d.redraw();\n });\n }\n }\n\n let dataPoints;\n if (this.dataFilter) {\n // apply filtering\n dataPoints = this.dataFilter._getDataPoints();\n } else {\n // no filtering. load all data\n dataPoints = this._getDataPoints(this.getDataTable());\n }\n return dataPoints;\n};\n\n/**\n * Collect the range settings for the given data column.\n *\n * This internal method is intended to make the range\n * initalization more generic.\n *\n * TODO: if/when combined settings per axis defined, get rid of this.\n * @private\n * @param {'x'|'y'|'z'} column The data column to process\n * @param {vis.Graph3d} graph3d Reference to the calling Graph3D instance;\n * required for access to settings\n * @returns {object}\n */\nDataGroup.prototype._collectRangeSettings = function (column, graph3d) {\n const index = [\"x\", \"y\", \"z\"].indexOf(column);\n\n if (index == -1) {\n throw new Error(\"Column '\" + column + \"' invalid\");\n }\n\n const upper = column.toUpperCase();\n\n return {\n barWidth: this[column + \"BarWidth\"],\n min: graph3d[\"default\" + upper + \"Min\"],\n max: graph3d[\"default\" + upper + \"Max\"],\n step: graph3d[\"default\" + upper + \"Step\"],\n range_label: column + \"Range\", // Name of instance field to write to\n step_label: column + \"Step\", // Name of instance field to write to\n };\n};\n\n/**\n * Initializes the settings per given column.\n *\n * TODO: if/when combined settings per axis defined, rewrite this.\n * @private\n * @param {DataSet | DataView} data The data containing the items for the Graph\n * @param {'x'|'y'|'z'} column The data column to process\n * @param {vis.Graph3d} graph3d Reference to the calling Graph3D instance;\n * required for access to settings\n * @param {boolean} withBars True if initializing for bar graph\n */\nDataGroup.prototype._initializeRange = function (\n data,\n column,\n graph3d,\n withBars,\n) {\n const NUMSTEPS = 5;\n const settings = this._collectRangeSettings(column, graph3d);\n\n const range = this.getColumnRange(data, column);\n if (withBars && column != \"z\") {\n // Safeguard for 'z'; it doesn't have a bar width\n range.expand(settings.barWidth / 2);\n }\n\n this._setRangeDefaults(range, settings.min, settings.max);\n this[settings.range_label] = range;\n this[settings.step_label] =\n settings.step !== undefined ? settings.step : range.range() / NUMSTEPS;\n};\n\n/**\n * Creates a list with all the different values in the data for the given column.\n *\n * If no data passed, use the internal data of this instance.\n * @param {'x'|'y'|'z'} column The data column to process\n * @param {DataSet|DataView|undefined} data The data containing the items for the Graph\n * @returns {Array} All distinct values in the given column data, sorted ascending.\n */\nDataGroup.prototype.getDistinctValues = function (column, data) {\n if (data === undefined) {\n data = this.dataTable;\n }\n\n const values = [];\n\n for (let i = 0; i < data.length; i++) {\n const value = data[i][column] || 0;\n if (values.indexOf(value) === -1) {\n values.push(value);\n }\n }\n\n return values.toSorted(function (a, b) {\n return a - b;\n });\n};\n\n/**\n * Determine the smallest difference between the values for given\n * column in the passed data set.\n * @param {DataSet|DataView|undefined} data The data containing the items for the Graph\n * @param {'x'|'y'|'z'} column The data column to process\n * @returns {number|null} Smallest difference value or\n * null, if it can't be determined.\n */\nDataGroup.prototype.getSmallestDifference = function (data, column) {\n const values = this.getDistinctValues(data, column);\n\n // Get all the distinct diffs\n // Array values is assumed to be sorted here\n let smallest_diff = null;\n\n for (let i = 1; i < values.length; i++) {\n const diff = values[i] - values[i - 1];\n\n if (smallest_diff == null || smallest_diff > diff) {\n smallest_diff = diff;\n }\n }\n\n return smallest_diff;\n};\n\n/**\n * Get the absolute min/max values for the passed data column.\n * @param {DataSet|DataView|undefined} data The data containing the items for the Graph\n * @param {'x'|'y'|'z'} column The data column to process\n * @returns {Range} A Range instance with min/max members properly set.\n */\nDataGroup.prototype.getColumnRange = function (data, column) {\n const range = new Range();\n\n // Adjust the range so that it covers all values in the passed data elements.\n for (let i = 0; i < data.length; i++) {\n const item = data[i][column];\n range.adjust(item);\n }\n\n return range;\n};\n\n/**\n * Determines the number of rows in the current data.\n * @returns {number}\n */\nDataGroup.prototype.getNumberOfRows = function () {\n return this.dataTable.length;\n};\n\n/**\n * Set default values for range\n *\n * The default values override the range values, if defined.\n *\n * Because it's possible that only defaultMin or defaultMax is set, it's better\n * to pass in a range already set with the min/max set from the data. Otherwise,\n * it's quite hard to process the min/max properly.\n * @param {vis.Range} range\n * @param {number} [defaultMin]\n * @param {number} [defaultMax]\n * @private\n */\nDataGroup.prototype._setRangeDefaults = function (\n range,\n defaultMin,\n defaultMax,\n) {\n if (defaultMin !== undefined) {\n range.min = defaultMin;\n }\n\n if (defaultMax !== undefined) {\n range.max = defaultMax;\n }\n\n // This is the original way that the default min/max values were adjusted.\n // TODO: Perhaps it's better if an error is thrown if the values do not agree.\n // But this will change the behaviour.\n if (range.max <= range.min) range.max = range.min + 1;\n};\n\nDataGroup.prototype.getDataTable = function () {\n return this.dataTable;\n};\n\nDataGroup.prototype.getDataSet = function () {\n return this.dataSet;\n};\n\n/**\n * Return all data values as a list of Point3d objects\n * @param {Array.<object>} data\n * @returns {Array.<object>}\n */\nDataGroup.prototype.getDataPoints = function (data) {\n const dataPoints = [];\n\n for (let i = 0; i < data.length; i++) {\n const point = new Point3d();\n point.x = data[i][this.colX] || 0;\n point.y = data[i][this.colY] || 0;\n point.z = data[i][this.colZ] || 0;\n point.data = data[i];\n point.value = data[i][this.colValue] || 0;\n\n const obj = {};\n obj.point = point;\n obj.bottom = new Point3d(point.x, point.y, this.zRange.min);\n obj.trans = undefined;\n obj.screen = undefined;\n\n dataPoints.push(obj);\n }\n\n return dataPoints;\n};\n\n/**\n * Copy all values from the data table to a matrix.\n *\n * The provided values are supposed to form a grid of (x,y) positions.\n * @param {Array.<object>} data\n * @returns {Array.<object>}\n * @private\n */\nDataGroup.prototype.initDataAsMatrix = function (data) {\n // TODO: store the created matrix dataPoints in the filters instead of\n // reloading each time.\n let x, y, i, obj;\n\n // create two lists with all present x and y values\n const dataX = this.getDistinctValues(this.colX, data);\n const dataY = this.getDistinctValues(this.colY, data);\n\n const dataPoints = this.getDataPoints(data);\n\n // create a grid, a 2d matrix, with all values.\n const dataMatrix = []; // temporary data matrix\n for (i = 0; i < dataPoints.length; i++) {\n obj = dataPoints[i];\n\n // TODO: implement Array().indexOf() for Internet Explorer\n const xIndex = dataX.indexOf(obj.point.x);\n const yIndex = dataY.indexOf(obj.point.y);\n\n if (dataMatrix[xIndex] === undefined) {\n dataMatrix[xIndex] = [];\n }\n\n dataMatrix[xIndex][yIndex] = obj;\n }\n\n // fill in the pointers to the neighbors.\n for (x = 0; x < dataMatrix.length; x++) {\n for (y = 0; y < dataMatrix[x].length; y++) {\n if (dataMatrix[x][y]) {\n dataMatrix[x][y].pointRight =\n x < dataMatrix.length - 1 ? dataMatrix[x + 1][y] : undefined;\n dataMatrix[x][y].pointTop =\n y < dataMatrix[x].length - 1 ? dataMatrix[x][y + 1] : undefined;\n dataMatrix[x][y].pointCross =\n x < dataMatrix.length - 1 && y < dataMatrix[x].length - 1\n ? dataMatrix[x + 1][y + 1]\n : undefined;\n }\n }\n }\n\n return dataPoints;\n};\n\n/**\n * Return common information, if present\n * @returns {string}\n */\nDataGroup.prototype.getInfo = function () {\n const dataFilter = this.dataFilter;\n if (!dataFilter) return undefined;\n\n return dataFilter.getLabel() + \": \" + dataFilter.getSelectedValue();\n};\n\n/**\n * Reload the data\n */\nDataGroup.prototype.reload = function () {\n if (this.dataTable) {\n this.setData(this.dataTable);\n }\n};\n\n/**\n * Filter the data based on the current filter\n * @param {Array} data\n * @returns {Array} dataPoints Array with point objects which can be drawn on\n * screen\n */\nDataGroup.prototype._getDataPoints = function (data) {\n let dataPoints = [];\n\n if (this.style === STYLE.GRID || this.style === STYLE.SURFACE) {\n dataPoints = this.initDataAsMatrix(data);\n } else {\n // 'dot', 'dot-line', etc.\n dataPoints = this.getDataPoints(data);\n\n if (this.style === STYLE.LINE) {\n // Add next member points for line drawing\n for (let i = 0; i < dataPoints.length; i++) {\n if (i > 0) {\n dataPoints[i - 1].pointNext = dataPoints[i];\n }\n }\n }\n }\n\n return dataPoints;\n};\n\nexport default DataGroup;\n","/**\n * This object contains all possible options. It will check if the types are correct, if required if the option is one\n * of the allowed values.\n *\n * __any__ means that the name of the property does not matter.\n * __type__ is a required field for all objects and contains the allowed types of all objects\n */\nconst string = \"string\";\nconst bool = \"boolean\";\nconst number = \"number\";\nconst object = \"object\"; // should only be in a __type__ property\nconst array = \"array\";\n// Following not used here, but useful for reference\n//let dom = 'dom';\n//let any = 'any';\n\nconst colorOptions = {\n fill: { string },\n stroke: { string },\n strokeWidth: { number },\n __type__: { string, object, undefined: \"undefined\" },\n};\n\nconst surfaceColorsOptions = {\n hue: {\n start: { number },\n end: { number },\n saturation: { number },\n brightness: { number },\n colorStops: { number },\n __type__: { object },\n },\n __type__: { boolean: bool, array, object, undefined: \"undefined\" },\n};\n\nconst colormapOptions = {\n hue: {\n start: { number },\n end: { number },\n saturation: { number },\n brightness: { number },\n colorStops: { number },\n __type__: { object },\n },\n __type__: { array, object, function: \"function\", undefined: \"undefined\" },\n};\n\n/**\n * Order attempted to be alphabetical.\n * - x/y/z-prefixes ignored in sorting\n * - __type__ always at end\n * - globals at end\n */\nconst allOptions = {\n animationAutoStart: { boolean: bool, undefined: \"undefined\" },\n animationInterval: { number },\n animationPreload: { boolean: bool },\n axisColor: { string },\n axisFontSize: { number: number },\n axisFontType: { string: string },\n backgroundColor: colorOptions,\n xBarWidth: { number, undefined: \"undefined\" },\n yBarWidth: { number, undefined: \"undefined\" },\n cameraPosition: {\n distance: { number },\n horizontal: { number },\n vertical: { number },\n __type__: { object },\n },\n zoomable: { boolean: bool },\n ctrlToZoom: { boolean: bool },\n xCenter: { string },\n yCenter: { string },\n colormap: colormapOptions,\n dataColor: colorOptions,\n dotSizeMinFraction: { number },\n dotSizeMaxFraction: { number },\n dotSizeRatio: { number },\n filterLabel: { string },\n gridColor: { string },\n onclick: { function: \"function\" },\n keepAspectRatio: { boolean: bool },\n xLabel: { string },\n yLabel: { string },\n zLabel: { string },\n legendLabel: { string },\n xMin: { number, undefined: \"undefined\" },\n yMin: { number, undefined: \"undefined\" },\n zMin: { number, undefined: \"undefined\" },\n xMax: { number, undefined: \"undefined\" },\n yMax: { number, undefined: \"undefined\" },\n zMax: { number, undefined: \"undefined\" },\n showAnimationControls: { boolean: bool, undefined: \"undefined\" },\n showGrayBottom: { boolean: bool },\n showGrid: { boolean: bool },\n showLegend: { boolean: bool, undefined: \"undefined\" },\n showPerspective: { boolean: bool },\n showShadow: { boolean: bool },\n showSurfaceGrid: { boolean: bool },\n showXAxis: { boolean: bool },\n showYAxis: { boolean: bool },\n showZAxis: { boolean: bool },\n rotateAxisLabels: { boolean: bool },\n surfaceColors: surfaceColorsOptions,\n xStep: { number, undefined: \"undefined\" },\n yStep: { number, undefined: \"undefined\" },\n zStep: { number, undefined: \"undefined\" },\n style: {\n number, // TODO: either Graph3d.DEFAULT has string, or number allowed in documentation\n string: [\n \"bar\",\n \"bar-color\",\n \"bar-size\",\n \"dot\",\n \"dot-line\",\n \"dot-color\",\n \"dot-size\",\n \"line\",\n \"grid\",\n \"surface\",\n ],\n },\n tooltip: { boolean: bool, function: \"function\" },\n tooltipDelay: { number: number },\n tooltipStyle: {\n content: {\n color: { string },\n background: { string },\n border: { string },\n borderRadius: { string },\n boxShadow: { string },\n padding: { string },\n __type__: { object },\n },\n line: {\n borderLeft: { string },\n height: { string },\n width: { string },\n pointerEvents: { string },\n __type__: { object },\n },\n dot: {\n border: { string },\n borderRadius: { string },\n height: { string },\n width: { string },\n pointerEvents: { string },\n __type__: { object },\n },\n __type__: { object },\n },\n xValueLabel: { function: \"function\" },\n yValueLabel: { function: \"function\" },\n zValueLabel: { function: \"function\" },\n valueMax: { number, undefined: \"undefined\" },\n valueMin: { number, undefined: \"undefined\" },\n verticalRatio: { number },\n\n //globals :\n height: { string },\n width: { string },\n __type__: { object },\n};\n\nexport { allOptions };\n","/**\n * @param {number} [x]\n * @param {number} [y]\n */\nfunction Point2d(x, y) {\n this.x = x !== undefined ? x : 0;\n this.y = y !== undefined ? y : 0;\n}\n\nexport default Point2d;\n","import * as util from \"vis-util/esnext\";\n\n/**\n * An html slider control with start/stop/prev/next buttons\n * @function Object() { [native code] } Slider\n * @param {Element} container The element where the slider will be created\n * @param {object} options Available options:\n * {boolean} visible If true (default) the\n * slider is visible.\n */\nfunction Slider(container, options) {\n if (container === undefined) {\n throw new Error(\"No container element defined\");\n }\n this.container = container;\n this.visible =\n options && options.visible != undefined ? options.visible : true;\n\n if (this.visible) {\n this.frame = document.createElement(\"DIV\");\n //this.frame.style.backgroundColor = '#E5E5E5';\n this.frame.style.width = \"100%\";\n this.frame.style.position = \"relative\";\n this.container.appendChild(this.frame);\n\n this.frame.prev = document.createElement(\"INPUT\");\n this.frame.prev.type = \"BUTTON\";\n this.frame.prev.value = \"Prev\";\n this.frame.appendChild(this.frame.prev);\n\n this.frame.play = document.createElement(\"INPUT\");\n this.frame.play.type = \"BUTTON\";\n this.frame.play.value = \"Play\";\n this.frame.appendChild(this.frame.play);\n\n this.frame.next = document.createElement(\"INPUT\");\n this.frame.next.type = \"BUTTON\";\n this.frame.next.value = \"Next\";\n this.frame.appendChild(this.frame.next);\n\n this.frame.bar = document.createElement(\"INPUT\");\n this.frame.bar.type = \"BUTTON\";\n this.frame.bar.style.position = \"absolute\";\n this.frame.bar.style.border = \"1px solid red\";\n this.frame.bar.style.width = \"100px\";\n this.frame.bar.style.height = \"6px\";\n this.frame.bar.style.borderRadius = \"2px\";\n this.frame.bar.style.MozBorderRadius = \"2px\";\n this.frame.bar.style.border = \"1px solid #7F7F7F\";\n this.frame.bar.style.backgroundColor = \"#E5E5E5\";\n this.frame.appendChild(this.frame.bar);\n\n this.frame.slide = document.createElement(\"INPUT\");\n this.frame.slide.type = \"BUTTON\";\n this.frame.slide.style.margin = \"0px\";\n this.frame.slide.value = \" \";\n this.frame.slide.style.position = \"relative\";\n this.frame.slide.style.left = \"-100px\";\n this.frame.appendChild(this.frame.slide);\n\n // create events\n const me = this;\n this.frame.slide.onmousedown = function (event) {\n me._onMouseDown(event);\n };\n this.frame.prev.onclick = function (event) {\n me.prev(event);\n };\n this.frame.play.onclick = function (event) {\n me.togglePlay(event);\n };\n this.frame.next.onclick = function (event) {\n me.next(event);\n };\n }\n\n this.onChangeCallback = undefined;\n\n this.values = [];\n this.index = undefined;\n\n this.playTimeout = undefined;\n this.playInterval = 1000; // milliseconds\n this.playLoop = true;\n}\n\n/**\n * Select the previous index\n */\nSlider.prototype.prev = function () {\n let index = this.getIndex();\n if (index > 0) {\n index--;\n this.setIndex(index);\n }\n};\n\n/**\n * Select the next index\n */\nSlider.prototype.next = function () {\n let index = this.getIndex();\n if (index < this.values.length - 1) {\n index++;\n this.setIndex(index);\n }\n};\n\n/**\n * Select the next index\n */\nSlider.prototype.playNext = function () {\n const start = new Date();\n\n let index = this.getIndex();\n if (index < this.values.length - 1) {\n index++;\n this.setIndex(index);\n } else if (this.playLoop) {\n // jump to the start\n index = 0;\n this.setIndex(index);\n }\n\n const end = new Date();\n const diff = end - start;\n\n // calculate how much time it to to set the index and to execute the callback\n // function.\n const interval = Math.max(this.playInterval - diff, 0);\n // document.title = diff // TODO: cleanup\n\n const me = this;\n this.playTimeout = setTimeout(function () {\n me.playNext();\n }, interval);\n};\n\n/**\n * Toggle start or stop playing\n */\nSlider.prototype.togglePlay = function () {\n if (this.playTimeout === undefined) {\n this.play();\n } else {\n this.stop();\n }\n};\n\n/**\n * Start playing\n */\nSlider.prototype.play = function () {\n // Test whether already playing\n if (this.playTimeout) return;\n\n this.playNext();\n\n if (this.frame) {\n this.frame.play.value = \"Stop\";\n }\n};\n\n/**\n * Stop playing\n */\nSlider.prototype.stop = function () {\n clearInterval(this.playTimeout);\n this.playTimeout = undefined;\n\n if (this.frame) {\n this.frame.play.value = \"Play\";\n }\n};\n\n/**\n * Set a callback function which will be triggered when the value of the\n * slider bar has changed.\n * @param {Function} callback\n */\nSlider.prototype.setOnChangeCallback = function (callback) {\n this.onChangeCallback = callback;\n};\n\n/**\n * Set the interval for playing the list\n * @param {number} interval The interval in milliseconds\n */\nSlider.prototype.setPlayInterval = function (interval) {\n this.playInterval = interval;\n};\n\n/**\n * Retrieve the current play interval\n * @returns {number} interval The interval in milliseconds\n */\nSlider.prototype.getPlayInterval = function () {\n return this.playInterval;\n};\n\n/**\n * Set looping on or off\n * @param {boolean} doLoop If true, the slider will jump to the start when\n * the end is passed, and will jump to the end\n * when the start is passed.\n */\nSlider.prototype.setPlayLoop = function (doLoop) {\n this.playLoop = doLoop;\n};\n\n/**\n * Execute the onchange callback function\n */\nSlider.prototype.onChange = function () {\n if (this.onChangeCallback !== undefined) {\n this.onChangeCallback();\n }\n};\n\n/**\n * redraw the slider on the correct place\n */\nSlider.prototype.redraw = function () {\n if (this.frame) {\n // resize the bar\n this.frame.bar.style.top =\n this.frame.clientHeight / 2 - this.frame.bar.offsetHeight / 2 + \"px\";\n this.frame.bar.style.width =\n this.frame.clientWidth -\n this.frame.prev.clientWidth -\n this.frame.play.clientWidth -\n this.frame.next.clientWidth -\n 30 +\n \"px\";\n\n // position the slider button\n const left = this.indexToLeft(this.index);\n this.frame.slide.style.left = left + \"px\";\n }\n};\n\n/**\n * Set the list with values for the slider\n * @param {Array} values A javascript array with values (any type)\n */\nSlider.prototype.setValues = function (values) {\n this.values = values;\n\n if (this.values.length > 0) this.setIndex(0);\n else this.index = undefined;\n};\n\n/**\n * Select a value by its index\n * @param {number} index\n */\nSlider.prototype.setIndex = function (index) {\n if (index < this.values.length) {\n this.index = index;\n\n this.redraw();\n this.onChange();\n } else {\n throw new Error(\"Index out of range\");\n }\n};\n\n/**\n * retrieve the index of the currently selected vaue\n * @returns {number} index\n */\nSlider.prototype.getIndex = function () {\n return this.index;\n};\n\n/**\n * retrieve the currently selected value\n * @returns {*} value\n */\nSlider.prototype.get = function () {\n return this.values[this.index];\n};\n\nSlider.prototype._onMouseDown = function (event) {\n // only react on left mouse button down\n const leftButtonDown = event.which ? event.which === 1 : event.button === 1;\n if (!leftButtonDown) return;\n\n this.startClientX = event.clientX;\n this.startSlideX = parseFloat(this.frame.slide.style.left);\n\n this.frame.style.cursor = \"move\";\n\n // add event listeners to handle moving the contents\n // we store the function onmousemove and onmouseup in the graph, so we can\n // remove the eventlisteners lateron in the function mouseUp()\n const me = this;\n this.onmousemove = function (event) {\n me._onMouseMove(event);\n };\n this.onmouseup = function (event) {\n me._onMouseUp(event);\n };\n document.addEventListener(\"mousemove\", this.onmousemove);\n document.addEventListener(\"mouseup\", this.onmouseup);\n util.preventDefault(event);\n};\n\nSlider.prototype.leftToIndex = function (left) {\n const width =\n parseFloat(this.frame.bar.style.width) - this.frame.slide.clientWidth - 10;\n const x = left - 3;\n\n let index = Math.round((x / width) * (this.values.length - 1));\n if (index < 0) index = 0;\n if (index > this.values.length - 1) index = this.values.length - 1;\n\n return index;\n};\n\nSlider.prototype.indexToLeft = function (index) {\n const width =\n parseFloat(this.frame.bar.style.width) - this.frame.slide.clientWidth - 10;\n\n const x = (index / (this.values.length - 1)) * width;\n const left = x + 3;\n\n return left;\n};\n\nSlider.prototype._onMouseMove = function (event) {\n const diff = event.clientX - this.startClientX;\n const x = this.startSlideX + diff;\n\n const index = this.leftToIndex(x);\n\n this.setIndex(index);\n\n util.preventDefault();\n};\n\nSlider.prototype._onMouseUp = function () {\n this.frame.style.cursor = \"auto\";\n\n // remove event listeners\n document.removeEventListener(\"mousemove\", this.onmousemove);\n document.removeEventListener(\"mouseup\", this.onmouseup);\n\n util.preventDefault();\n};\n\nexport default Slider;\n","/**\n * The class StepNumber is an iterator for Numbers. You provide a start and end\n * value, and a best step size. StepNumber itself rounds to fixed values and\n * a finds the step that best fits the provided step.\n *\n * If prettyStep is true, the step size is chosen as close as possible to the\n * provided step, but being a round value like 1, 2, 5, 10, 20, 50, ....\n *\n * Example usage:\n * var step = new StepNumber(0, 10, 2.5, true);\n * step.start();\n * while (!step.end()) {\n * alert(step.getCurrent());\n * step.next();\n * }\n *\n * Version: 1.0\n * @param {number} start The start value\n * @param {number} end The end value\n * @param {number} step Optional. Step size. Must be a positive value.\n * @param {boolean} prettyStep Optional. If true, the step size is rounded\n * To a pretty step size (like 1, 2, 5, 10, 20, 50, ...)\n */\nfunction StepNumber(start, end, step, prettyStep) {\n // set default values\n this._start = 0;\n this._end = 0;\n this._step = 1;\n this.prettyStep = true;\n this.precision = 5;\n\n this._current = 0;\n this.setRange(start, end, step, prettyStep);\n}\n\n/**\n * Check for input values, to prevent disasters from happening\n *\n * Source: http://stackoverflow.com/a/1830844\n * @param {string} n\n * @returns {boolean}\n */\nStepNumber.prototype.isNumeric = function (n) {\n return !isNaN(parseFloat(n)) && isFinite(n);\n};\n\n/**\n * Set a new range: start, end and step.\n * @param {number} start The start value\n * @param {number} end The end value\n * @param {number} step Optional. Step size. Must be a positive value.\n * @param {boolean} prettyStep Optional. If true, the step size is rounded\n * To a pretty step size (like 1, 2, 5, 10, 20, 50, ...)\n */\nStepNumber.prototype.setRange = function (start, end, step, prettyStep) {\n if (!this.isNumeric(start)) {\n throw new Error(\"Parameter 'start' is not numeric; value: \" + start);\n }\n if (!this.isNumeric(end)) {\n throw new Error(\"Parameter 'end' is not numeric; value: \" + start);\n }\n if (!this.isNumeric(step)) {\n throw new Error(\"Parameter 'step' is not numeric; value: \" + start);\n }\n\n this._start = start ? start : 0;\n this._end = end ? end : 0;\n\n this.setStep(step, prettyStep);\n};\n\n/**\n * Set a new step size\n * @param {number} step New step size. Must be a positive value\n * @param {boolean} prettyStep Optional. If true, the provided step is rounded\n * to a pretty step size (like 1, 2, 5, 10, 20, 50, ...)\n */\nStepNumber.prototype.setStep = function (step, prettyStep) {\n if (step === undefined || step <= 0) return;\n\n if (prettyStep !== undefined) this.prettyStep = prettyStep;\n\n if (this.prettyStep === true)\n this._step = StepNumber.calculatePrettyStep(step);\n else this._step = step;\n};\n\n/**\n * Calculate a nice step size, closest to the desired step size.\n * Returns a value in one of the ranges 1*10^n, 2*10^n, or 5*10^n, where n is an\n * integer Number. For example 1, 2, 5, 10, 20, 50, etc...\n * @param {number} step Desired step size\n * @returns {number} Nice step size\n */\nStepNumber.calculatePrettyStep = function (step) {\n const log10 = function (x) {\n return Math.log(x) / Math.LN10;\n };\n\n // try three steps (multiple of 1, 2, or 5\n const step1 = Math.pow(10, Math.round(log10(step))),\n step2 = 2 * Math.pow(10, Math.round(log10(step / 2))),\n step5 = 5 * Math.pow(10, Math.round(log10(step / 5)));\n\n // choose the best step (closest to minimum step)\n let prettyStep = step1;\n if (Math.abs(step2 - step) <= Math.abs(prettyStep - step)) prettyStep = step2;\n if (Math.abs(step5 - step) <= Math.abs(prettyStep - step)) prettyStep = step5;\n\n // for safety\n if (prettyStep <= 0) {\n prettyStep = 1;\n }\n\n return prettyStep;\n};\n\n/**\n * returns the current value of the step\n * @returns {number} current value\n */\nStepNumber.prototype.getCurrent = function () {\n return parseFloat(this._current.toPrecision(this.precision));\n};\n\n/**\n * returns the current step size\n * @returns {number} current step size\n */\nStepNumber.prototype.getStep = function () {\n return this._step;\n};\n\n/**\n * Set the current to its starting value.\n *\n * By default, this will be the largest value smaller than start, which\n * is a multiple of the step size.\n *\n * Parameters checkFirst is optional, default false.\n * If set to true, move the current value one step if smaller than start.\n * @param {boolean} [checkFirst]\n */\nStepNumber.prototype.start = function (checkFirst) {\n if (checkFirst === undefined) {\n checkFirst = false;\n }\n\n this._current = this._start - (this._start % this._step);\n\n if (checkFirst) {\n if (this.getCurrent() < this._start) {\n this.next();\n }\n }\n};\n\n/**\n * Do a step, add the step size to the current value\n */\nStepNumber.prototype.next = function () {\n this._current += this._step;\n};\n\n/**\n * Returns true whether the end is reached\n * @returns {boolean} True if the current value has passed the end value.\n */\nStepNumber.prototype.end = function () {\n return this._current > this._end;\n};\n\nexport default StepNumber;\n","import Emitter from \"component-emitter\";\nimport * as util from \"vis-util/esnext\";\nimport { VALIDATOR_PRINT_STYLE, Validator } from \"vis-util/esnext\";\n\nimport DataGroup from \"./DataGroup.js\";\nimport { allOptions } from \"./options.js\";\nimport Point2d from \"./Point2d.js\";\nimport Point3d from \"./Point3d.js\";\nimport {\n STYLE,\n setCameraPosition,\n setDefaults,\n setOptions,\n} from \"./Settings.js\";\nimport Slider from \"./Slider.js\";\nimport StepNumber from \"./StepNumber.js\";\n\n/// enumerate the available styles\nGraph3d.STYLE = STYLE;\n\n/**\n * Following label is used in the settings to describe values which should be\n * determined by the code while running, from the current data and graph style.\n *\n * Using 'undefined' directly achieves the same thing, but this is more\n * descriptive by describing the intent.\n */\nconst autoByDefault = undefined;\n\n/**\n * Default values for option settings.\n *\n * These are the values used when a Graph3d instance is initialized without\n * custom settings.\n *\n * If a field is not in this list, a default value of 'autoByDefault' is assumed,\n * which is just an alias for 'undefined'.\n */\nGraph3d.DEFAULTS = {\n width: \"400px\",\n height: \"400px\",\n filterLabel: \"time\",\n legendLabel: \"value\",\n xLabel: \"x\",\n yLabel: \"y\",\n zLabel: \"z\",\n xValueLabel: function (v) {\n return v;\n },\n yValueLabel: function (v) {\n return v;\n },\n zValueLabel: function (v) {\n return v;\n },\n showXAxis: true,\n showYAxis: true,\n showZAxis: true,\n showGrayBottom: false,\n showGrid: true,\n showPerspective: true,\n showShadow: false,\n showSurfaceGrid: true,\n keepAspectRatio: true,\n rotateAxisLabels: true,\n verticalRatio: 0.5, // 0.1 to 1.0, where 1.0 results in a 'cube'\n\n dotSizeRatio: 0.02, // size of the dots as a fraction of the graph width\n dotSizeMinFraction: 0.5, // size of min-value dot as a fraction of dotSizeRatio\n dotSizeMaxFraction: 2.5, // size of max-value dot as a fraction of dotSizeRatio\n\n showAnimationControls: autoByDefault,\n animationInterval: 1000, // milliseconds\n animationPreload: false,\n animationAutoStart: autoByDefault,\n\n axisFontSize: 14,\n axisFontType: \"arial\",\n axisColor: \"#4D4D4D\",\n gridColor: \"#D3D3D3\",\n xCenter: \"55%\",\n yCenter: \"50%\",\n\n style: Graph3d.STYLE.DOT,\n tooltip: false,\n tooltipDelay: 300, // milliseconds\n\n tooltipStyle: {\n content: {\n padding: \"10px\",\n border: \"1px solid #4d4d4d\",\n color: \"#1a1a1a\",\n background: \"rgba(255,255,255,0.7)\",\n borderRadius: \"2px\",\n boxShadow: \"5px 5px 10px rgba(128,128,128,0.5)\",\n },\n line: {\n height: \"40px\",\n width: \"0\",\n borderLeft: \"1px solid #4d4d4d\",\n pointerEvents: \"none\",\n },\n dot: {\n height: \"0\",\n width: \"0\",\n border: \"5px solid #4d4d4d\",\n borderRadius: \"5px\",\n pointerEvents: \"none\",\n },\n },\n\n dataColor: {\n fill: \"#7DC1FF\",\n stroke: \"#3267D2\",\n strokeWidth: 1, // px\n },\n\n surfaceColors: autoByDefault,\n colormap: autoByDefault,\n\n cameraPosition: {\n horizontal: 1.0,\n vertical: 0.5,\n distance: 1.7,\n },\n\n zoomable: true,\n ctrlToZoom: false,\n\n /*\n The following fields are 'auto by default', see above.\n */\n showLegend: autoByDefault, // determined by graph style\n backgroundColor: autoByDefault,\n\n xBarWidth: autoByDefault,\n yBarWidth: autoByDefault,\n valueMin: autoByDefault,\n valueMax: autoByDefault,\n xMin: autoByDefault,\n xMax: autoByDefault,\n xStep: autoByDefault,\n yMin: autoByDefault,\n yMax: autoByDefault,\n yStep: autoByDefault,\n zMin: autoByDefault,\n zMax: autoByDefault,\n zStep: autoByDefault,\n};\n\n// -----------------------------------------------------------------------------\n// Class Graph3d\n// -----------------------------------------------------------------------------\n\n/**\n * Graph3d displays data in 3d.\n *\n * Graph3d is developed in javascript as a Google Visualization Chart.\n * @function Object() { [native code] } Graph3d\n * @param {Element} container The DOM element in which the Graph3d will\n * be created. Normally a div element.\n * @param {DataSet | DataView | Array} [data]\n * @param {object} [options]\n */\nfunction Graph3d(container, data, options) {\n if (!(this instanceof Graph3d)) {\n throw new SyntaxError(\"Constructor must be called with the new operator\");\n }\n\n // create variables and set default values\n this.containerElement = container;\n\n this.dataGroup = new DataGroup();\n this.dataPoints = null; // The table with point objects\n\n // create a frame and canvas\n this.create();\n\n setDefaults(Graph3d.DEFAULTS, this);\n\n // the column indexes\n this.colX = undefined;\n this.colY = undefined;\n this.colZ = undefined;\n this.colValue = undefined;\n\n // TODO: customize axis range\n\n // apply options (also when undefined)\n this.setOptions(options);\n\n // apply data\n this.setData(data);\n}\n\n// Extend Graph3d with an Emitter mixin\nEmitter(Graph3d.prototype);\n\n/**\n * Calculate the scaling values, dependent on the range in x, y, and z direction\n */\nGraph3d.prototype._setScale = function () {\n this.scale = new Point3d(\n 1 / this.xRange.range(),\n 1 / this.yRange.range(),\n 1 / this.zRange.range(),\n );\n\n // keep aspect ration between x and y scale if desired\n if (this.keepAspectRatio) {\n if (this.scale.x < this.scale.y) {\n //noinspection JSSuspiciousNameCombination\n this.scale.y = this.scale.x;\n } else {\n //noinspection JSSuspiciousNameCombination\n this.scale.x = this.scale.y;\n }\n }\n\n // scale the vertical axis\n this.scale.z *= this.verticalRatio;\n // TODO: can this be automated? verticalRatio?\n\n // determine scale for (optional) value\n if (this.valueRange !== undefined) {\n this.scale.value = 1 / this.valueRange.range();\n }\n\n // position the camera arm\n const xCenter = this.xRange.center() * this.scale.x;\n const yCenter = this.yRange.center() * this.scale.y;\n const zCenter = this.zRange.center() * this.scale.z;\n this.camera.setArmLocation(xCenter, yCenter, zCenter);\n};\n\n/**\n * Convert a 3D location to a 2D location on screen\n * Source: ttp://en.wikipedia.org/wiki/3D_projection\n * @param {Point3d} point3d A 3D point with parameters x, y, z\n * @returns {Point2d} point2d A 2D point with parameters x, y\n */\nGraph3d.prototype._convert3Dto2D = function (point3d) {\n const translation = this._convertPointToTranslation(point3d);\n return this._convertTranslationToScreen(translation);\n};\n\n/**\n * Convert a 3D location its translation seen from the camera\n * Source: http://en.wikipedia.org/wiki/3D_projection\n * @param {Point3d} point3d A 3D point with parameters x, y, z\n * @returns {Point3d} translation A 3D point with parameters x, y, z This is\n * the translation of the point, seen from the\n * camera.\n */\nGraph3d.prototype._convertPointToTranslation = function (point3d) {\n const cameraLocation = this.camera.getCameraLocation(),\n cameraRotation = this.camera.getCameraRotation(),\n ax = point3d.x * this.scale.x,\n ay = point3d.y * this.scale.y,\n az = point3d.z * this.scale.z,\n cx = cameraLocation.x,\n cy = cameraLocation.y,\n cz = cameraLocation.z,\n // calculate angles\n sinTx = Math.sin(cameraRotation.x),\n cosTx = Math.cos(cameraRotation.x),\n sinTy = Math.sin(cameraRotation.y),\n cosTy = Math.cos(cameraRotation.y),\n sinTz = Math.sin(cameraRotation.z),\n cosTz = Math.cos(cameraRotation.z),\n // calculate translation\n dx = cosTy * (sinTz * (ay - cy) + cosTz * (ax - cx)) - sinTy * (az - cz),\n dy =\n sinTx *\n (cosTy * (az - cz) + sinTy * (sinTz * (ay - cy) + cosTz * (ax - cx))) +\n cosTx * (cosTz * (ay - cy) - sinTz * (ax - cx)),\n dz =\n cosTx *\n (cosTy * (az - cz) + sinTy * (sinTz * (ay - cy) + cosTz * (ax - cx))) -\n sinTx * (cosTz * (ay - cy) - sinTz * (ax - cx));\n\n return new Point3d(dx, dy, dz);\n};\n\n/**\n * Convert a translation point to a point on the screen\n * @param {Point3d} translation A 3D point with parameters x, y, z This is\n * the translation of the point, seen from the\n * camera.\n * @returns {Point2d} point2d A 2D point with parameters x, y\n */\nGraph3d.prototype._convertTranslationToScreen = function (translation) {\n const ex = this.eye.x,\n ey = this.eye.y,\n ez = this.eye.z,\n dx = translation.x,\n dy = translation.y,\n dz = translation.z;\n\n // calculate position on screen from translation\n let bx;\n let by;\n if (this.showPerspective) {\n bx = (dx - ex) * (ez / dz);\n by = (dy - ey) * (ez / dz);\n } else {\n bx = dx * -(ez / this.camera.getArmLength());\n by = dy * -(ez / this.camera.getArmLength());\n }\n\n // shift and scale the point to the center of the screen\n // use the width of the graph to scale both horizontally and vertically.\n return new Point2d(\n this.currentXCenter + bx * this.frame.canvas.clientWidth,\n this.currentYCenter - by * this.frame.canvas.clientWidth,\n );\n};\n\n/**\n * Calculate the translations and screen positions of all points\n * @param {Array.<Point3d>} points\n * @private\n */\nGraph3d.prototype._calcTranslations = function (points) {\n for (let i = 0; i < points.length; i++) {\n const point = points[i];\n point.trans = this._convertPointToTranslation(point.point);\n point.screen = this._convertTranslationToScreen(point.trans);\n\n // calculate the translation of the point at the bottom (needed for sorting)\n const transBottom = this._convertPointToTranslation(point.bottom);\n point.dist = this.showPerspective ? transBottom.length() : -transBottom.z;\n }\n\n // sort the points on depth of their (x,y) position (not on z)\n const sortDepth = function (a, b) {\n return b.dist - a.dist;\n };\n points.sort(sortDepth);\n};\n\n/**\n * Transfer min/max values to the Graph3d instance.\n */\nGraph3d.prototype._initializeRanges = function () {\n // TODO: later on, all min/maxes of all datagroups will be combined here\n const dg = this.dataGroup;\n this.xRange = dg.xRange;\n this.yRange = dg.yRange;\n this.zRange = dg.zRange;\n this.valueRange = dg.valueRange;\n\n // Values currently needed but which need to be sorted out for\n // the multiple graph case.\n this.xStep = dg.xStep;\n this.yStep = dg.yStep;\n this.zStep = dg.zStep;\n this.xBarWidth = dg.xBarWidth;\n this.yBarWidth = dg.yBarWidth;\n this.colX = dg.colX;\n this.colY = dg.colY;\n this.colZ = dg.colZ;\n this.colValue = dg.colValue;\n\n // set the scale dependent on the ranges.\n this._setScale();\n};\n\n/**\n * Return all data values as a list of Point3d objects\n * @param {vis.DataSet} data\n * @returns {Array.<object>}\n */\nGraph3d.prototype.getDataPoints = function (data) {\n const dataPoints = [];\n\n for (let i = 0; i < data.length; i++) {\n const point = new Point3d();\n point.x = data[i][this.colX] || 0;\n point.y = data[i][this.colY] || 0;\n point.z = data[i][this.colZ] || 0;\n point.data = data[i];\n point.value = data[i][this.colValue] || 0;\n\n const obj = {};\n obj.point = point;\n obj.bottom = new Point3d(point.x, point.y, this.zRange.min);\n obj.trans = undefined;\n obj.screen = undefined;\n\n dataPoints.push(obj);\n }\n\n return dataPoints;\n};\n\n/**\n * Filter the data based on the current filter\n * @param {Array} data\n * @returns {Array} dataPoints Array with point objects which can be drawn on\n * screen\n */\nGraph3d.prototype._getDataPoints = function (data) {\n // TODO: store the created matrix dataPoints in the filters instead of\n // reloading each time.\n let x, y, i, obj;\n\n let dataPoints = [];\n\n if (\n this.style === Graph3d.STYLE.GRID ||\n this.style === Graph3d.STYLE.SURFACE\n ) {\n // copy all values from the data table to a matrix\n // the provided values are supposed to form a grid of (x,y) positions\n\n // create two lists with all present x and y values\n const dataX = this.dataGroup.getDistinctValues(this.colX, data);\n const dataY = this.dataGroup.getDistinctValues(this.colY, data);\n\n dataPoints = this.getDataPoints(data);\n\n // create a grid, a 2d matrix, with all values.\n const dataMatrix = []; // temporary data matrix\n for (i = 0; i < dataPoints.length; i++) {\n obj = dataPoints[i];\n\n // TODO: implement Array().indexOf() for Internet Explorer\n const xIndex = dataX.indexOf(obj.point.x);\n const yIndex = dataY.indexOf(obj.point.y);\n\n if (dataMatrix[xIndex] === undefined) {\n dataMatrix[xIndex] = [];\n }\n\n dataMatrix[xIndex][yIndex] = obj;\n }\n\n // fill in the pointers to the neighbors.\n for (x = 0; x < dataMatrix.length; x++) {\n for (y = 0; y < dataMatrix[x].length; y++) {\n if (dataMatrix[x][y]) {\n dataMatrix[x][y].pointRight =\n x < dataMatrix.length - 1 ? dataMatrix[x + 1][y] : undefined;\n dataMatrix[x][y].pointTop =\n y < dataMatrix[x].length - 1 ? dataMatrix[x][y + 1] : undefined;\n dataMatrix[x][y].pointCross =\n x < dataMatrix.length - 1 && y < dataMatrix[x].length - 1\n ? dataMatrix[x + 1][y + 1]\n : undefined;\n }\n }\n }\n } else {\n // 'dot', 'dot-line', etc.\n dataPoints = this.getDataPoints(data);\n\n if (this.style === Graph3d.STYLE.LINE) {\n // Add next member points for line drawing\n for (i = 0; i < dataPoints.length; i++) {\n if (i > 0) {\n dataPoints[i - 1].pointNext = dataPoints[i];\n }\n }\n }\n }\n\n return dataPoints;\n};\n\n/**\n * Create the main frame for the Graph3d.\n *\n * This function is executed once when a Graph3d object is created. The frame\n * contains a canvas, and this canvas contains all objects like the axis and\n * nodes.\n */\nGraph3d.prototype.create = function () {\n // remove all elements from the container element.\n while (this.containerElement.hasChildNodes()) {\n this.containerElement.removeChild(this.containerElement.firstChild);\n }\n\n this.frame = document.createElement(\"div\");\n this.frame.style.position = \"relative\";\n this.frame.style.overflow = \"hidden\";\n\n // create the graph canvas (HTML canvas element)\n this.frame.canvas = document.createElement(\"canvas\");\n this.frame.canvas.style.position = \"relative\";\n this.frame.appendChild(this.frame.canvas);\n //if (!this.frame.canvas.getContext) {\n {\n const noCanvas = document.createElement(\"DIV\");\n noCanvas.style.color = \"red\";\n noCanvas.style.fontWeight = \"bold\";\n noCanvas.style.padding = \"10px\";\n noCanvas.innerHTML = \"Error: your browser does not support HTML canvas\";\n this.frame.canvas.appendChild(noCanvas);\n }\n\n this.frame.filter = document.createElement(\"div\");\n this.frame.filter.style.position = \"absolute\";\n this.frame.filter.style.bottom = \"0px\";\n this.frame.filter.style.left = \"0px\";\n this.frame.filter.style.width = \"100%\";\n this.frame.appendChild(this.frame.filter);\n\n // add event listeners to handle moving and zooming the contents\n const me = this;\n const onmousedown = function (event) {\n me._onMouseDown(event);\n };\n const ontouchstart = function (event) {\n me._onTouchStart(event);\n };\n const onmousewheel = function (event) {\n me._onWheel(event);\n };\n const ontooltip = function (event) {\n me._onTooltip(event);\n };\n const onclick = function (event) {\n me._onClick(event);\n };\n // TODO: these events are never cleaned up... can give a 'memory leakage'\n\n this.frame.canvas.addEventListener(\"mousedown\", onmousedown);\n this.frame.canvas.addEventListener(\"touchstart\", ontouchstart);\n this.frame.canvas.addEventListener(\"mousewheel\", onmousewheel);\n this.frame.canvas.addEventListener(\"mousemove\", ontooltip);\n this.frame.canvas.addEventListener(\"click\", onclick);\n\n // add the new graph to the container element\n this.containerElement.appendChild(this.frame);\n};\n\n/**\n * Set a new size for the graph\n * @param {number} width\n * @param {number} height\n * @private\n */\nGraph3d.prototype._setSize = function (width, height) {\n this.frame.style.width = width;\n this.frame.style.height = height;\n\n this._resizeCanvas();\n};\n\n/**\n * Resize the canvas to the current size of the frame\n */\nGraph3d.prototype._resizeCanvas = function () {\n this.frame.canvas.style.width = \"100%\";\n this.frame.canvas.style.height = \"100%\";\n\n this.frame.canvas.width = this.frame.canvas.clientWidth;\n this.frame.canvas.height = this.frame.canvas.clientHeight;\n\n // adjust with for margin\n this.frame.filter.style.width = this.frame.canvas.clientWidth - 2 * 10 + \"px\";\n};\n\n/**\n * Start playing the animation, if requested and filter present. Only applicable\n * when animation data is available.\n */\nGraph3d.prototype.animationStart = function () {\n // start animation when option is true\n if (!this.animationAutoStart || !this.dataGroup.dataFilter) return;\n\n if (!this.frame.filter || !this.frame.filter.slider)\n throw new Error(\"No animation available\");\n\n this.frame.filter.slider.play();\n};\n\n/**\n * Stop animation\n */\nGraph3d.prototype.animationStop = function () {\n if (!this.frame.filter || !this.frame.filter.slider) return;\n\n this.frame.filter.slider.stop();\n};\n\n/**\n * Resize the center position based on the current values in this.xCenter\n * and this.yCenter (which are strings with a percentage or a value\n * in pixels). The center positions are the variables this.currentXCenter\n * and this.currentYCenter\n */\nGraph3d.prototype._resizeCenter = function () {\n // calculate the horizontal center position\n if (this.xCenter.charAt(this.xCenter.length - 1) === \"%\") {\n this.currentXCenter =\n (parseFloat(this.xCenter) / 100) * this.frame.canvas.clientWidth;\n } else {\n this.currentXCenter = parseFloat(this.xCenter); // supposed to be in px\n }\n\n // calculate the vertical center position\n if (this.yCenter.charAt(this.yCenter.length - 1) === \"%\") {\n this.currentYCenter =\n (parseFloat(this.yCenter) / 100) *\n (this.frame.canvas.clientHeight - this.frame.filter.clientHeight);\n } else {\n this.currentYCenter = parseFloat(this.yCenter); // supposed to be in px\n }\n};\n\n/**\n * Retrieve the current camera rotation\n * @returns {object} An object with parameters horizontal, vertical, and\n * distance\n */\nGraph3d.prototype.getCameraPosition = function () {\n const pos = this.camera.getArmRotation();\n pos.distance = this.camera.getArmLength();\n return pos;\n};\n\n/**\n * Load data into the 3D Graph\n * @param {vis.DataSet} data\n * @private\n */\nGraph3d.prototype._readData = function (data) {\n // read the data\n this.dataPoints = this.dataGroup.initializeData(this, data, this.style);\n\n this._initializeRanges();\n this._redrawFilter();\n};\n\n/**\n * Replace the dataset of the Graph3d\n * @param {Array | DataSet | DataView} data\n */\nGraph3d.prototype.setData = function (data) {\n if (data === undefined || data === null) return;\n\n this._readData(data);\n this.redraw();\n this.animationStart();\n};\n\n/**\n * Update the options. Options will be merged with current options\n * @param {object} options\n */\nGraph3d.prototype.setOptions = function (options) {\n if (options === undefined) return;\n\n const errorFound = Validator.validate(options, allOptions);\n if (errorFound === true) {\n console.error(\n \"%cErrors have been found in the supplied options object.\",\n VALIDATOR_PRINT_STYLE,\n );\n }\n\n this.animationStop();\n\n setOptions(options, this);\n this.setPointDrawingMethod();\n this._setSize(this.width, this.height);\n this.setAxisLabelMethod();\n\n this.setData(this.dataGroup.getDataTable());\n this.animationStart();\n};\n\n/**\n * Determine which point drawing method to use for the current graph style.\n */\nGraph3d.prototype.setPointDrawingMethod = function () {\n let method = undefined;\n\n switch (this.style) {\n case Graph3d.STYLE.BAR:\n method = this._redrawBarGraphPoint;\n break;\n case Graph3d.STYLE.BARCOLOR:\n method = this._redrawBarColorGraphPoint;\n break;\n case Graph3d.STYLE.BARSIZE:\n method = this._redrawBarSizeGraphPoint;\n break;\n case Graph3d.STYLE.DOT:\n method = this._redrawDotGraphPoint;\n break;\n case Graph3d.STYLE.DOTLINE:\n method = this._redrawDotLineGraphPoint;\n break;\n case Graph3d.STYLE.DOTCOLOR:\n method = this._redrawDotColorGraphPoint;\n break;\n case Graph3d.STYLE.DOTSIZE:\n method = this._redrawDotSizeGraphPoint;\n break;\n case Graph3d.STYLE.SURFACE:\n method = this._redrawSurfaceGraphPoint;\n break;\n case Graph3d.STYLE.GRID:\n method = this._redrawGridGraphPoint;\n break;\n case Graph3d.STYLE.LINE:\n method = this._redrawLineGraphPoint;\n break;\n default:\n throw new Error(\n \"Can not determine point drawing method \" +\n \"for graph style '\" +\n this.style +\n \"'\",\n );\n }\n\n this._pointDrawingMethod = method;\n};\n\n/**\n * Determine which functions to use to draw axis labels.\n */\nGraph3d.prototype.setAxisLabelMethod = function () {\n if (this.rotateAxisLabels) {\n this._drawAxisLabelX = this.drawAxisLabelXRotate;\n this._drawAxisLabelY = this.drawAxisLabelYRotate;\n this._drawAxisLabelZ = this.drawAxisLabelZRotate;\n } else {\n this._drawAxisLabelX = this.drawAxisLabelX;\n this._drawAxisLabelY = this.drawAxisLabelY;\n this._drawAxisLabelZ = this.drawAxisLabelZ;\n }\n};\n\n/**\n * Redraw the Graph.\n */\nGraph3d.prototype.redraw = function () {\n if (this.dataPoints === undefined) {\n throw new Error(\"Graph data not initialized\");\n }\n\n this._resizeCanvas();\n this._resizeCenter();\n this._redrawSlider();\n this._redrawClear();\n this._redrawAxis();\n\n this._redrawDataGraph();\n\n this._redrawInfo();\n this._redrawLegend();\n};\n\n/**\n * Get drawing context without exposing canvas\n * @returns {CanvasRenderingContext2D}\n * @private\n */\nGraph3d.prototype._getContext = function () {\n const canvas = this.frame.canvas;\n const ctx = canvas.getContext(\"2d\");\n\n ctx.lineJoin = \"round\";\n ctx.lineCap = \"round\";\n\n return ctx;\n};\n\n/**\n * Clear the canvas before redrawing\n */\nGraph3d.prototype._redrawClear = function () {\n const canvas = this.frame.canvas;\n const ctx = canvas.getContext(\"2d\");\n\n ctx.clearRect(0, 0, canvas.width, canvas.height);\n};\n\nGraph3d.prototype._dotSize = function () {\n return this.frame.clientWidth * this.dotSizeRatio;\n};\n\n/**\n * Get legend width\n * @returns {*}\n * @private\n */\nGraph3d.prototype._getLegendWidth = function () {\n let width;\n\n if (this.style === Graph3d.STYLE.DOTSIZE) {\n const dotSize = this._dotSize();\n //width = dotSize / 2 + dotSize * 2;\n width = dotSize * this.dotSizeMaxFraction;\n } else if (this.style === Graph3d.STYLE.BARSIZE) {\n width = this.xBarWidth;\n } else {\n width = 20;\n }\n return width;\n};\n\n/**\n * Redraw the legend based on size, dot color, or surface height\n */\nGraph3d.prototype._redrawLegend = function () {\n //Return without drawing anything, if no legend is specified\n if (this.showLegend !== true) {\n return;\n }\n\n // Do not draw legend when graph style does not support\n if (\n this.style === Graph3d.STYLE.LINE ||\n this.style === Graph3d.STYLE.BARSIZE //TODO add legend support for BARSIZE\n ) {\n return;\n }\n\n // Legend types - size and color. Determine if size legend.\n const isSizeLegend =\n this.style === Graph3d.STYLE.BARSIZE ||\n this.style === Graph3d.STYLE.DOTSIZE;\n\n // Legend is either tracking z values or style values. This flag if false means use z values.\n const isValueLegend =\n this.style === Graph3d.STYLE.DOTSIZE ||\n this.style === Graph3d.STYLE.DOTCOLOR ||\n this.style === Graph3d.STYLE.SURFACE ||\n this.style === Graph3d.STYLE.BARCOLOR;\n\n const height = Math.max(this.frame.clientHeight * 0.25, 100);\n const top = this.margin;\n const width = this._getLegendWidth(); // px - overwritten by size legend\n const right = this.frame.clientWidth - this.margin;\n const left = right - width;\n const bottom = top + height;\n\n const ctx = this._getContext();\n ctx.lineWidth = 1;\n ctx.font = \"14px arial\"; // TODO: put in options\n\n if (isSizeLegend === false) {\n // draw the color bar\n const ymin = 0;\n const ymax = height; // Todo: make height customizable\n let y;\n\n for (y = ymin; y < ymax; y++) {\n // Need (1 - x) because y runs from top to bottom:\n const f = 1 - (y - ymin) / (ymax - ymin);\n const color = this._colormap(f, 1);\n\n ctx.strokeStyle = color;\n ctx.beginPath();\n ctx.moveTo(left, top + y);\n ctx.lineTo(right, top + y);\n ctx.stroke();\n }\n ctx.strokeStyle = this.axisColor;\n ctx.strokeRect(left, top, width, height);\n } else {\n // draw the size legend box\n let widthMin;\n if (this.style === Graph3d.STYLE.DOTSIZE) {\n // Get the proportion to max and min right\n widthMin = width * (this.dotSizeMinFraction / this.dotSizeMaxFraction);\n } else if (this.style === Graph3d.STYLE.BARSIZE) {\n //widthMin = this.xBarWidth * 0.2 this is wrong - barwidth measures in terms of xvalues\n }\n ctx.strokeStyle = this.axisColor;\n ctx.fillStyle = this.dataColor.fill;\n ctx.beginPath();\n ctx.moveTo(left, top);\n ctx.lineTo(right, top);\n ctx.lineTo(left + widthMin, bottom);\n ctx.lineTo(left, bottom);\n ctx.closePath();\n ctx.fill();\n ctx.stroke();\n }\n\n // print value text along the legend edge\n const gridLineLen = 5; // px\n\n const legendMin = isValueLegend ? this.valueRange.min : this.zRange.min;\n const legendMax = isValueLegend ? this.valueRange.max : this.zRange.max;\n const step = new StepNumber(\n legendMin,\n legendMax,\n (legendMax - legendMin) / 5,\n true,\n );\n step.start(true);\n\n while (!step.end()) {\n const y =\n bottom -\n ((step.getCurrent() - legendMin) / (legendMax - legendMin)) * height;\n const from = new Point2d(left - gridLineLen, y);\n const to = new Point2d(left, y);\n this._line(ctx, from, to);\n\n ctx.textAlign = \"right\";\n ctx.textBaseline = \"middle\";\n ctx.fillStyle = this.axisColor;\n ctx.fillText(step.getCurrent(), left - 2 * gridLineLen, y);\n\n step.next();\n }\n\n ctx.textAlign = \"right\";\n ctx.textBaseline = \"top\";\n const label = this.legendLabel;\n ctx.fillText(label, right, bottom + this.margin);\n};\n\n/**\n * Redraw the filter\n */\nGraph3d.prototype._redrawFilter = function () {\n const dataFilter = this.dataGroup.dataFilter;\n const filter = this.frame.filter;\n filter.innerHTML = \"\";\n\n if (!dataFilter) {\n filter.slider = undefined;\n return;\n }\n\n const options = {\n visible: this.showAnimationControls,\n };\n const slider = new Slider(filter, options);\n filter.slider = slider;\n\n // TODO: css here is not nice here...\n filter.style.padding = \"10px\";\n //this.frame.filter.style.backgroundColor = '#EFEFEF';\n\n slider.setValues(dataFilter.values);\n slider.setPlayInterval(this.animationInterval);\n\n // create an event handler\n const me = this;\n const onchange = function () {\n const dataFilter = me.dataGroup.dataFilter;\n const index = slider.getIndex();\n\n dataFilter.selectValue(index);\n me.dataPoints = dataFilter._getDataPoints();\n\n me.redraw();\n };\n\n slider.setOnChangeCallback(onchange);\n};\n\n/**\n * Redraw the slider\n */\nGraph3d.prototype._redrawSlider = function () {\n if (this.frame.filter.slider !== undefined) {\n this.frame.filter.slider.redraw();\n }\n};\n\n/**\n * Redraw common information\n */\nGraph3d.prototype._redrawInfo = function () {\n const info = this.dataGroup.getInfo();\n if (info === undefined) return;\n\n const ctx = this._getContext();\n\n ctx.font = \"14px arial\"; // TODO: put in options\n ctx.lineStyle = \"gray\";\n ctx.fillStyle = \"gray\";\n ctx.textAlign = \"left\";\n ctx.textBaseline = \"top\";\n\n const x = this.margin;\n const y = this.margin;\n ctx.fillText(info, x, y);\n};\n\n/**\n * Draw a line between 2d points 'from' and 'to'.\n *\n * If stroke style specified, set that as well.\n * @param {CanvasRenderingContext2D} ctx\n * @param {vis.Point2d} from\n * @param {vis.Point2d} to\n * @param {string} [strokeStyle]\n * @private\n */\nGraph3d.prototype._line = function (ctx, from, to, strokeStyle) {\n if (strokeStyle !== undefined) {\n ctx.strokeStyle = strokeStyle;\n }\n\n ctx.beginPath();\n ctx.moveTo(from.x, from.y);\n ctx.lineTo(to.x, to.y);\n ctx.stroke();\n};\n\n/**\n *\n * @param {CanvasRenderingContext2D} ctx\n * @param {vis.Point3d} point3d\n * @param {string} text\n * @param {number} armAngle\n * @param {number} [yMargin]\n */\nGraph3d.prototype.drawAxisLabelX = function (\n ctx,\n point3d,\n text,\n armAngle,\n yMargin,\n) {\n if (yMargin === undefined) {\n yMargin = 0;\n }\n\n const point2d = this._convert3Dto2D(point3d);\n\n if (Math.cos(armAngle * 2) > 0) {\n ctx.textAlign = \"center\";\n ctx.textBaseline = \"top\";\n point2d.y += yMargin;\n } else if (Math.sin(armAngle * 2) < 0) {\n ctx.textAlign = \"right\";\n ctx.textBaseline = \"middle\";\n } else {\n ctx.textAlign = \"left\";\n ctx.textBaseline = \"middle\";\n }\n\n ctx.fillStyle = this.axisColor;\n ctx.fillText(text, point2d.x, point2d.y);\n};\n\n/**\n *\n * @param {CanvasRenderingContext2D} ctx\n * @param {vis.Point3d} point3d\n * @param {string} text\n * @param {number} armAngle\n * @param {number} [yMargin]\n */\nGraph3d.prototype.drawAxisLabelY = function (\n ctx,\n point3d,\n text,\n armAngle,\n yMargin,\n) {\n if (yMargin === undefined) {\n yMargin = 0;\n }\n\n const point2d = this._convert3Dto2D(point3d);\n\n if (Math.cos(armAngle * 2) < 0) {\n ctx.textAlign = \"center\";\n ctx.textBaseline = \"top\";\n point2d.y += yMargin;\n } else if (Math.sin(armAngle * 2) > 0) {\n ctx.textAlign = \"right\";\n ctx.textBaseline = \"middle\";\n } else {\n ctx.textAlign = \"left\";\n ctx.textBaseline = \"middle\";\n }\n\n ctx.fillStyle = this.axisColor;\n ctx.fillText(text, point2d.x, point2d.y);\n};\n\n/**\n *\n * @param {CanvasRenderingContext2D} ctx\n * @param {vis.Point3d} point3d\n * @param {string} text\n * @param {number} [offset]\n */\nGraph3d.prototype.drawAxisLabelZ = function (ctx, point3d, text, offset) {\n if (offset === undefined) {\n offset = 0;\n }\n\n const point2d = this._convert3Dto2D(point3d);\n ctx.textAlign = \"right\";\n ctx.textBaseline = \"middle\";\n ctx.fillStyle = this.axisColor;\n ctx.fillText(text, point2d.x - offset, point2d.y);\n};\n\n/**\n *\n * @param {CanvasRenderingContext2D} ctx\n * @param {vis.Point3d} point3d\n * @param {string} text\n * @param {number} armAngle\n * @param {number} [yMargin]\n */\nGraph3d.prototype.drawAxisLabelXRotate = function (\n ctx,\n point3d,\n text,\n armAngle,\n yMargin,\n) {\n if (yMargin === undefined) {\n yMargin = 0;\n }\n\n const point2d = this._convert3Dto2D(point3d);\n if (Math.cos(armAngle * 2) > 0) {\n ctx.save();\n ctx.translate(point2d.x, point2d.y);\n ctx.rotate(-Math.PI / 2);\n ctx.textAlign = \"right\";\n ctx.textBaseline = \"middle\";\n ctx.fillStyle = this.axisColor;\n ctx.fillText(text, 0, 0);\n ctx.restore();\n } else if (Math.sin(armAngle * 2) < 0) {\n ctx.textAlign = \"right\";\n ctx.textBaseline = \"middle\";\n ctx.fillStyle = this.axisColor;\n ctx.fillText(text, point2d.x, point2d.y);\n } else {\n ctx.textAlign = \"left\";\n ctx.textBaseline = \"middle\";\n ctx.fillStyle = this.axisColor;\n ctx.fillText(text, point2d.x, point2d.y);\n }\n};\n\n/**\n *\n * @param {CanvasRenderingContext2D} ctx\n * @param {vis.Point3d} point3d\n * @param {string} text\n * @param {number} armAngle\n * @param {number} [yMargin]\n */\nGraph3d.prototype.drawAxisLabelYRotate = function (\n ctx,\n point3d,\n text,\n armAngle,\n yMargin,\n) {\n if (yMargin === undefined) {\n yMargin = 0;\n }\n\n const point2d = this._convert3Dto2D(point3d);\n if (Math.cos(armAngle * 2) < 0) {\n ctx.save();\n ctx.translate(point2d.x, point2d.y);\n ctx.rotate(-Math.PI / 2);\n ctx.textAlign = \"right\";\n ctx.textBaseline = \"middle\";\n ctx.fillStyle = this.axisColor;\n ctx.fillText(text, 0, 0);\n ctx.restore();\n } else if (Math.sin(armAngle * 2) > 0) {\n ctx.textAlign = \"right\";\n ctx.textBaseline = \"middle\";\n ctx.fillStyle = this.axisColor;\n ctx.fillText(text, point2d.x, point2d.y);\n } else {\n ctx.textAlign = \"left\";\n ctx.textBaseline = \"middle\";\n ctx.fillStyle = this.axisColor;\n ctx.fillText(text, point2d.x, point2d.y);\n }\n};\n\n/**\n *\n * @param {CanvasRenderingContext2D} ctx\n * @param {vis.Point3d} point3d\n * @param {string} text\n * @param {number} [offset]\n */\nGraph3d.prototype.drawAxisLabelZRotate = function (ctx, point3d, text, offset) {\n if (offset === undefined) {\n offset = 0;\n }\n\n const point2d = this._convert3Dto2D(point3d);\n ctx.textAlign = \"right\";\n ctx.textBaseline = \"middle\";\n ctx.fillStyle = this.axisColor;\n ctx.fillText(text, point2d.x - offset, point2d.y);\n};\n\n/**\n \n \n /**\n Draw a line between 2d points 'from' and 'to'.\n \n If stroke style specified, set that as well.\n * @param {CanvasRenderingContext2D} ctx\n * @param {vis.Point2d} from\n * @param {vis.Point2d} to\n * @param {string} [strokeStyle]\n * @private\n */\nGraph3d.prototype._line3d = function (ctx, from, to, strokeStyle) {\n const from2d = this._convert3Dto2D(from);\n const to2d = this._convert3Dto2D(to);\n\n this._line(ctx, from2d, to2d, strokeStyle);\n};\n\n/**\n * Redraw the axis\n */\nGraph3d.prototype._redrawAxis = function () {\n const ctx = this._getContext();\n let from,\n to,\n step,\n prettyStep,\n text,\n xText,\n yText,\n zText,\n offset,\n xOffset,\n yOffset;\n\n // TODO: get the actual rendered style of the containerElement\n //ctx.font = this.containerElement.style.font;\n //ctx.font = 24 / this.camera.getArmLength() + 'px arial';\n ctx.font =\n this.axisFontSize / this.camera.getArmLength() + \"px \" + this.axisFontType;\n\n // calculate the length for the short grid lines\n const gridLenX = 0.025 / this.scale.x;\n const gridLenY = 0.025 / this.scale.y;\n const textMargin = 5 / this.camera.getArmLength(); // px\n const armAngle = this.camera.getArmRotation().horizontal;\n const armVector = new Point2d(Math.cos(armAngle), Math.sin(armAngle));\n\n const xRange = this.xRange;\n const yRange = this.yRange;\n const zRange = this.zRange;\n let point3d;\n\n // draw x-grid lines\n ctx.lineWidth = 1;\n prettyStep = this.defaultXStep === undefined;\n step = new StepNumber(xRange.min, xRange.max, this.xStep, prettyStep);\n step.start(true);\n\n while (!step.end()) {\n const x = step.getCurrent();\n\n if (this.showGrid) {\n from = new Point3d(x, yRange.min, zRange.min);\n to = new Point3d(x, yRange.max, zRange.min);\n this._line3d(ctx, from, to, this.gridColor);\n } else if (this.showXAxis) {\n from = new Point3d(x, yRange.min, zRange.min);\n to = new Point3d(x, yRange.min + gridLenX, zRange.min);\n this._line3d(ctx, from, to, this.axisColor);\n\n from = new Point3d(x, yRange.max, zRange.min);\n to = new Point3d(x, yRange.max - gridLenX, zRange.min);\n this._line3d(ctx, from, to, this.axisColor);\n }\n\n if (this.showXAxis) {\n yText = armVector.x > 0 ? yRange.min : yRange.max;\n point3d = new Point3d(x, yText, zRange.min);\n const msg = \" \" + this.xValueLabel(x) + \" \";\n this._drawAxisLabelX.call(this, ctx, point3d, msg, armAngle, textMargin);\n }\n\n step.next();\n }\n\n // draw y-grid lines\n ctx.lineWidth = 1;\n prettyStep = this.defaultYStep === undefined;\n step = new StepNumber(yRange.min, yRange.max, this.yStep, prettyStep);\n step.start(true);\n\n while (!step.end()) {\n const y = step.getCurrent();\n\n if (this.showGrid) {\n from = new Point3d(xRange.min, y, zRange.min);\n to = new Point3d(xRange.max, y, zRange.min);\n this._line3d(ctx, from, to, this.gridColor);\n } else if (this.showYAxis) {\n from = new Point3d(xRange.min, y, zRange.min);\n to = new Point3d(xRange.min + gridLenY, y, zRange.min);\n this._line3d(ctx, from, to, this.axisColor);\n\n from = new Point3d(xRange.max, y, zRange.min);\n to = new Point3d(xRange.max - gridLenY, y, zRange.min);\n this._line3d(ctx, from, to, this.axisColor);\n }\n\n if (this.showYAxis) {\n xText = armVector.y > 0 ? xRange.min : xRange.max;\n point3d = new Point3d(xText, y, zRange.min);\n const msg = \" \" + this.yValueLabel(y) + \" \";\n this._drawAxisLabelY.call(this, ctx, point3d, msg, armAngle, textMargin);\n }\n\n step.next();\n }\n\n // draw z-grid lines and axis\n if (this.showZAxis) {\n ctx.lineWidth = 1;\n prettyStep = this.defaultZStep === undefined;\n step = new StepNumber(zRange.min, zRange.max, this.zStep, prettyStep);\n step.start(true);\n\n xText = armVector.x > 0 ? xRange.min : xRange.max;\n yText = armVector.y < 0 ? yRange.min : yRange.max;\n\n while (!step.end()) {\n const z = step.getCurrent();\n\n // TODO: make z-grid lines really 3d?\n const from3d = new Point3d(xText, yText, z);\n const from2d = this._convert3Dto2D(from3d);\n to = new Point2d(from2d.x - textMargin, from2d.y);\n this._line(ctx, from2d, to, this.axisColor);\n\n const msg = this.zValueLabel(z) + \" \";\n this._drawAxisLabelZ.call(this, ctx, from3d, msg, 5);\n\n step.next();\n }\n\n ctx.lineWidth = 1;\n from = new Point3d(xText, yText, zRange.min);\n to = new Point3d(xText, yText, zRange.max);\n this._line3d(ctx, from, to, this.axisColor);\n }\n\n // draw x-axis\n if (this.showXAxis) {\n let xMin2d;\n let xMax2d;\n ctx.lineWidth = 1;\n\n // line at yMin\n xMin2d = new Point3d(xRange.min, yRange.min, zRange.min);\n xMax2d = new Point3d(xRange.max, yRange.min, zRange.min);\n this._line3d(ctx, xMin2d, xMax2d, this.axisColor);\n // line at ymax\n xMin2d = new Point3d(xRange.min, yRange.max, zRange.min);\n xMax2d = new Point3d(xRange.max, yRange.max, zRange.min);\n this._line3d(ctx, xMin2d, xMax2d, this.axisColor);\n }\n\n // draw y-axis\n if (this.showYAxis) {\n ctx.lineWidth = 1;\n // line at xMin\n from = new Point3d(xRange.min, yRange.min, zRange.min);\n to = new Point3d(xRange.min, yRange.max, zRange.min);\n this._line3d(ctx, from, to, this.axisColor);\n // line at xMax\n from = new Point3d(xRange.max, yRange.min, zRange.min);\n to = new Point3d(xRange.max, yRange.max, zRange.min);\n this._line3d(ctx, from, to, this.axisColor);\n }\n\n // draw x-label\n const xLabel = this.xLabel;\n if (xLabel.length > 0 && this.showXAxis) {\n yOffset = 0.1 / this.scale.y;\n xText = (xRange.max + 3 * xRange.min) / 4;\n yText = armVector.x > 0 ? yRange.min - yOffset : yRange.max + yOffset;\n text = new Point3d(xText, yText, zRange.min);\n this.drawAxisLabelX(ctx, text, xLabel, armAngle);\n }\n\n // draw y-label\n const yLabel = this.yLabel;\n if (yLabel.length > 0 && this.showYAxis) {\n xOffset = 0.1 / this.scale.x;\n xText = armVector.y > 0 ? xRange.min - xOffset : xRange.max + xOffset;\n yText = (yRange.max + 3 * yRange.min) / 4;\n text = new Point3d(xText, yText, zRange.min);\n\n this.drawAxisLabelY(ctx, text, yLabel, armAngle);\n }\n\n // draw z-label\n const zLabel = this.zLabel;\n if (zLabel.length > 0 && this.showZAxis) {\n offset = 30; // pixels. // TODO: relate to the max width of the values on the z axis?\n xText = armVector.x > 0 ? xRange.min : xRange.max;\n yText = armVector.y < 0 ? yRange.min : yRange.max;\n zText = (zRange.max + 3 * zRange.min) / 4;\n text = new Point3d(xText, yText, zText);\n\n this.drawAxisLabelZ(ctx, text, zLabel, offset);\n }\n};\n\n/**\n *\n * @param {vis.Point3d} point\n * @returns {*}\n * @private\n */\nGraph3d.prototype._getStrokeWidth = function (point) {\n if (point !== undefined) {\n if (this.showPerspective) {\n return (1 / -point.trans.z) * this.dataColor.strokeWidth;\n } else {\n return (\n -(this.eye.z / this.camera.getArmLength()) * this.dataColor.strokeWidth\n );\n }\n }\n\n return this.dataColor.strokeWidth;\n};\n\n// -----------------------------------------------------------------------------\n// Drawing primitives for the graphs\n// -----------------------------------------------------------------------------\n\n/**\n * Draw a bar element in the view with the given properties.\n * @param {CanvasRenderingContext2D} ctx\n * @param {object} point\n * @param {number} xWidth\n * @param {number} yWidth\n * @param {string} color\n * @param {string} borderColor\n * @private\n */\nGraph3d.prototype._redrawBar = function (\n ctx,\n point,\n xWidth,\n yWidth,\n color,\n borderColor,\n) {\n let surface;\n\n // calculate all corner points\n const me = this;\n const point3d = point.point;\n const zMin = this.zRange.min;\n const top = [\n { point: new Point3d(point3d.x - xWidth, point3d.y - yWidth, point3d.z) },\n { point: new Point3d(point3d.x + xWidth, point3d.y - yWidth, point3d.z) },\n { point: new Point3d(point3d.x + xWidth, point3d.y + yWidth, point3d.z) },\n { point: new Point3d(point3d.x - xWidth, point3d.y + yWidth, point3d.z) },\n ];\n const bottom = [\n { point: new Point3d(point3d.x - xWidth, point3d.y - yWidth, zMin) },\n { point: new Point3d(point3d.x + xWidth, point3d.y - yWidth, zMin) },\n { point: new Point3d(point3d.x + xWidth, point3d.y + yWidth, zMin) },\n { point: new Point3d(point3d.x - xWidth, point3d.y + yWidth, zMin) },\n ];\n\n // calculate screen location of the points\n top.forEach(function (obj) {\n obj.screen = me._convert3Dto2D(obj.point);\n });\n bottom.forEach(function (obj) {\n obj.screen = me._convert3Dto2D(obj.point);\n });\n\n // create five sides, calculate both corner points and center points\n const surfaces = [\n { corners: top, center: Point3d.avg(bottom[0].point, bottom[2].point) },\n {\n corners: [top[0], top[1], bottom[1], bottom[0]],\n center: Point3d.avg(bottom[1].point, bottom[0].point),\n },\n {\n corners: [top[1], top[2], bottom[2], bottom[1]],\n center: Point3d.avg(bottom[2].point, bottom[1].point),\n },\n {\n corners: [top[2], top[3], bottom[3], bottom[2]],\n center: Point3d.avg(bottom[3].point, bottom[2].point),\n },\n {\n corners: [top[3], top[0], bottom[0], bottom[3]],\n center: Point3d.avg(bottom[0].point, bottom[3].point),\n },\n ];\n point.surfaces = surfaces;\n\n // calculate the distance of each of the surface centers to the camera\n for (let j = 0; j < surfaces.length; j++) {\n surface = surfaces[j];\n const transCenter = this._convertPointToTranslation(surface.center);\n surface.dist = this.showPerspective ? transCenter.length() : -transCenter.z;\n // TODO: this dept calculation doesn't work 100% of the cases due to perspective,\n // but the current solution is fast/simple and works in 99.9% of all cases\n // the issue is visible in example 14, with graph.setCameraPosition({horizontal: 2.97, vertical: 0.5, distance: 0.9})\n }\n\n // order the surfaces by their (translated) depth\n surfaces.sort(function (a, b) {\n const diff = b.dist - a.dist;\n if (diff) return diff;\n\n // if equal depth, sort the top surface last\n if (a.corners === top) return 1;\n if (b.corners === top) return -1;\n\n // both are equal\n return 0;\n });\n\n // draw the ordered surfaces\n ctx.lineWidth = this._getStrokeWidth(point);\n ctx.strokeStyle = borderColor;\n ctx.fillStyle = color;\n // NOTE: we start at j=2 instead of j=0 as we don't need to draw the two surfaces at the backside\n for (let j = 2; j < surfaces.length; j++) {\n surface = surfaces[j];\n this._polygon(ctx, surface.corners);\n }\n};\n\n/**\n * Draw a polygon using the passed points and fill it with the passed style and stroke.\n * @param {CanvasRenderingContext2D} ctx\n * @param {Array.<vis.Point3d>} points an array of points.\n * @param {string} [fillStyle] the fill style to set\n * @param {string} [strokeStyle] the stroke style to set\n */\nGraph3d.prototype._polygon = function (ctx, points, fillStyle, strokeStyle) {\n if (points.length < 2) {\n return;\n }\n\n if (fillStyle !== undefined) {\n ctx.fillStyle = fillStyle;\n }\n if (strokeStyle !== undefined) {\n ctx.strokeStyle = strokeStyle;\n }\n ctx.beginPath();\n ctx.moveTo(points[0].screen.x, points[0].screen.y);\n\n for (let i = 1; i < points.length; ++i) {\n const point = points[i];\n ctx.lineTo(point.screen.x, point.screen.y);\n }\n\n ctx.closePath();\n ctx.fill();\n ctx.stroke(); // TODO: only draw stroke when strokeWidth > 0\n};\n\n/**\n * @param {CanvasRenderingContext2D} ctx\n * @param {object} point\n * @param {string} color\n * @param {string} borderColor\n * @param {number} [size]\n * @private\n */\nGraph3d.prototype._drawCircle = function (\n ctx,\n point,\n color,\n borderColor,\n size,\n) {\n const radius = this._calcRadius(point, size);\n\n ctx.lineWidth = this._getStrokeWidth(point);\n ctx.strokeStyle = borderColor;\n ctx.fillStyle = color;\n ctx.beginPath();\n ctx.arc(point.screen.x, point.screen.y, radius, 0, Math.PI * 2, true);\n ctx.fill();\n ctx.stroke();\n};\n\n/**\n * Determine the colors for the 'regular' graph styles.\n * @param {object} point\n * @returns {{fill, border}}\n * @private\n */\nGraph3d.prototype._getColorsRegular = function (point) {\n const f = (point.point.value - this.valueRange.min) * this.scale.value;\n const color = this._colormap(f, 1);\n const borderColor = this._colormap(f, 0.8);\n return {\n fill: color,\n border: borderColor,\n };\n};\n\n/**\n * Get the colors for the 'color' graph styles.\n * These styles are currently: 'bar-color' and 'dot-color'\n * Color may be set as a string representation of HTML color, like #ff00ff,\n * or calculated from a number, for example, distance from this point\n * The first option is useful when we have some pre-given legend, to which we have to adjust ourselves\n * The second option is useful when we are interested in automatically setting the color, from some value,\n * using some color scale\n * @param {object} point\n * @returns {{fill: *, border: *}}\n * @private\n */\nGraph3d.prototype._getColorsColor = function (point) {\n // calculate the color based on the value\n let color, borderColor, pointStyle;\n if (point && point.point && point.point.data && point.point.data.style) {\n pointStyle = point.point.data.style;\n }\n if (\n pointStyle &&\n typeof pointStyle === \"object\" &&\n pointStyle.fill &&\n pointStyle.stroke\n ) {\n return {\n fill: pointStyle.fill,\n border: pointStyle.stroke,\n };\n }\n\n if (typeof point.point.value === \"string\") {\n color = point.point.value;\n borderColor = point.point.value;\n } else {\n const f = (point.point.value - this.valueRange.min) * this.scale.value;\n color = this._colormap(f, 1);\n borderColor = this._colormap(f, 0.8);\n }\n return {\n fill: color,\n border: borderColor,\n };\n};\n\n/**\n * Get the colors for the 'size' graph styles.\n * These styles are currently: 'bar-size' and 'dot-size'\n * @returns {{fill: *, border: (string|colorOptions.stroke|{string, undefined}|string|colorOptions.stroke|{string}|*)}}\n * @private\n */\nGraph3d.prototype._getColorsSize = function () {\n return {\n fill: this.dataColor.fill,\n border: this.dataColor.stroke,\n };\n};\n\n/**\n * Determine the color corresponding to a given value on the color scale.\n * @param {number} [x] the data value to be mapped running from 0 to 1\n * @param {number} [v] scale factor between 0 and 1 for the color brightness\n * @returns {string}\n * @private\n */\nGraph3d.prototype._colormap = function (x, v = 1) {\n let r, g, b, a;\n const colormap = this.colormap;\n if (Array.isArray(colormap)) {\n const maxIndex = colormap.length - 1;\n const startIndex = Math.max(Math.floor(x * maxIndex), 0);\n const endIndex = Math.min(startIndex + 1, maxIndex);\n const innerRatio = x * maxIndex - startIndex;\n const min = colormap[startIndex];\n const max = colormap[endIndex];\n r = min.r + innerRatio * (max.r - min.r);\n g = min.g + innerRatio * (max.g - min.g);\n b = min.b + innerRatio * (max.b - min.b);\n } else if (typeof colormap === \"function\") {\n ({ r, g, b, a } = colormap(x));\n } else {\n const hue = (1 - x) * 240;\n ({ r, g, b } = util.HSVToRGB(hue / 360, 1, 1));\n }\n if (typeof a === \"number\" && !Number.isNaN(a)) {\n return `RGBA(${Math.round(r * v)}, ${Math.round(g * v)}, ${Math.round(\n b * v,\n )}, ${a})`;\n } else {\n return `RGB(${Math.round(r * v)}, ${Math.round(g * v)}, ${Math.round(\n b * v,\n )})`;\n }\n};\n\n/**\n * Determine the size of a point on-screen, as determined by the\n * distance to the camera.\n * @param {object} point\n * @param {number} [size] the size that needs to be translated to screen coordinates.\n * optional; if not passed, use the default point size.\n * @returns {number}\n * @private\n */\nGraph3d.prototype._calcRadius = function (point, size) {\n if (size === undefined) {\n size = this._dotSize();\n }\n\n let radius;\n if (this.showPerspective) {\n radius = size / -point.trans.z;\n } else {\n radius = size * -(this.eye.z / this.camera.getArmLength());\n }\n if (radius < 0) {\n radius = 0;\n }\n\n return radius;\n};\n\n// -----------------------------------------------------------------------------\n// Methods for drawing points per graph style.\n// -----------------------------------------------------------------------------\n\n/**\n * Draw single datapoint for graph style 'bar'.\n * @param {CanvasRenderingContext2D} ctx\n * @param {object} point\n * @private\n */\nGraph3d.prototype._redrawBarGraphPoint = function (ctx, point) {\n const xWidth = this.xBarWidth / 2;\n const yWidth = this.yBarWidth / 2;\n const colors = this._getColorsRegular(point);\n\n this._redrawBar(ctx, point, xWidth, yWidth, colors.fill, colors.border);\n};\n\n/**\n * Draw single datapoint for graph style 'bar-color'.\n * @param {CanvasRenderingContext2D} ctx\n * @param {object} point\n * @private\n */\nGraph3d.prototype._redrawBarColorGraphPoint = function (ctx, point) {\n const xWidth = this.xBarWidth / 2;\n const yWidth = this.yBarWidth / 2;\n const colors = this._getColorsColor(point);\n\n this._redrawBar(ctx, point, xWidth, yWidth, colors.fill, colors.border);\n};\n\n/**\n * Draw single datapoint for graph style 'bar-size'.\n * @param {CanvasRenderingContext2D} ctx\n * @param {object} point\n * @private\n */\nGraph3d.prototype._redrawBarSizeGraphPoint = function (ctx, point) {\n // calculate size for the bar\n const fraction =\n (point.point.value - this.valueRange.min) / this.valueRange.range();\n const xWidth = (this.xBarWidth / 2) * (fraction * 0.8 + 0.2);\n const yWidth = (this.yBarWidth / 2) * (fraction * 0.8 + 0.2);\n\n const colors = this._getColorsSize();\n\n this._redrawBar(ctx, point, xWidth, yWidth, colors.fill, colors.border);\n};\n\n/**\n * Draw single datapoint for graph style 'dot'.\n * @param {CanvasRenderingContext2D} ctx\n * @param {object} point\n * @private\n */\nGraph3d.prototype._redrawDotGraphPoint = function (ctx, point) {\n const colors = this._getColorsRegular(point);\n\n this._drawCircle(ctx, point, colors.fill, colors.border);\n};\n\n/**\n * Draw single datapoint for graph style 'dot-line'.\n * @param {CanvasRenderingContext2D} ctx\n * @param {object} point\n * @private\n */\nGraph3d.prototype._redrawDotLineGraphPoint = function (ctx, point) {\n // draw a vertical line from the XY-plane to the graph value\n const from = this._convert3Dto2D(point.bottom);\n ctx.lineWidth = 1;\n this._line(ctx, from, point.screen, this.gridColor);\n\n this._redrawDotGraphPoint(ctx, point);\n};\n\n/**\n * Draw single datapoint for graph style 'dot-color'.\n * @param {CanvasRenderingContext2D} ctx\n * @param {object} point\n * @private\n */\nGraph3d.prototype._redrawDotColorGraphPoint = function (ctx, point) {\n const colors = this._getColorsColor(point);\n\n this._drawCircle(ctx, point, colors.fill, colors.border);\n};\n\n/**\n * Draw single datapoint for graph style 'dot-size'.\n * @param {CanvasRenderingContext2D} ctx\n * @param {object} point\n * @private\n */\nGraph3d.prototype._redrawDotSizeGraphPoint = function (ctx, point) {\n const dotSize = this._dotSize();\n const fraction =\n (point.point.value - this.valueRange.min) / this.valueRange.range();\n\n const sizeMin = dotSize * this.dotSizeMinFraction;\n const sizeRange = dotSize * this.dotSizeMaxFraction - sizeMin;\n const size = sizeMin + sizeRange * fraction;\n\n const colors = this._getColorsSize();\n\n this._drawCircle(ctx, point, colors.fill, colors.border, size);\n};\n\n/**\n * Draw single datapoint for graph style 'surface'.\n * @param {CanvasRenderingContext2D} ctx\n * @param {object} point\n * @private\n */\nGraph3d.prototype._redrawSurfaceGraphPoint = function (ctx, point) {\n const right = point.pointRight;\n const top = point.pointTop;\n const cross = point.pointCross;\n\n if (\n point === undefined ||\n right === undefined ||\n top === undefined ||\n cross === undefined\n ) {\n return;\n }\n\n let topSideVisible = true;\n let fillStyle;\n let strokeStyle;\n let cosViewAngle;\n\n if (this.showGrayBottom || this.showShadow) {\n // calculate the cross product of the two vectors from center\n // to left and right, in order to know whether we are looking at the\n // bottom or at the top side. We can also use the cross product\n // for calculating light intensity\n const aDiff = Point3d.subtract(cross.trans, point.trans);\n const bDiff = Point3d.subtract(top.trans, right.trans);\n const surfaceNormal = Point3d.crossProduct(aDiff, bDiff);\n\n if (this.showPerspective) {\n const surfacePosition = Point3d.avg(\n Point3d.avg(point.trans, cross.trans),\n Point3d.avg(right.trans, top.trans),\n );\n // This corresponds to diffuse lighting with light source at (0, 0, 0).\n // More generally, we would need `surfacePosition - lightPosition`:\n cosViewAngle = -Point3d.dotProduct(\n surfaceNormal.normalize(),\n surfacePosition.normalize(),\n );\n } else {\n cosViewAngle = surfaceNormal.z / surfaceNormal.length();\n }\n topSideVisible = cosViewAngle > 0;\n }\n\n if (topSideVisible || !this.showGrayBottom) {\n const vAvg =\n (point.point.value +\n right.point.value +\n top.point.value +\n cross.point.value) /\n 4;\n const ratio = (vAvg - this.valueRange.min) * this.scale.value;\n // lighting factor. TODO: let user specify lighting model as function(?)\n const v = this.showShadow ? (1 + cosViewAngle) / 2 : 1;\n fillStyle = this._colormap(ratio, v);\n } else {\n fillStyle = \"gray\";\n }\n\n if (this.showSurfaceGrid) {\n strokeStyle = this.axisColor; // TODO: should be customizable\n } else {\n strokeStyle = fillStyle;\n }\n\n ctx.lineWidth = this._getStrokeWidth(point);\n // TODO: only draw stroke when strokeWidth > 0\n\n const points = [point, right, cross, top];\n this._polygon(ctx, points, fillStyle, strokeStyle);\n};\n\n/**\n * Helper method for _redrawGridGraphPoint()\n * @param {CanvasRenderingContext2D} ctx\n * @param {object} from\n * @param {object} to\n * @private\n */\nGraph3d.prototype._drawGridLine = function (ctx, from, to) {\n if (from === undefined || to === undefined) {\n return;\n }\n\n const vAvg = (from.point.value + to.point.value) / 2;\n const f = (vAvg - this.valueRange.min) * this.scale.value;\n\n ctx.lineWidth = this._getStrokeWidth(from) * 2;\n ctx.strokeStyle = this._colormap(f, 1);\n this._line(ctx, from.screen, to.screen);\n};\n\n/**\n * Draw single datapoint for graph style 'Grid'.\n * @param {CanvasRenderingContext2D} ctx\n * @param {object} point\n * @private\n */\nGraph3d.prototype._redrawGridGraphPoint = function (ctx, point) {\n this._drawGridLine(ctx, point, point.pointRight);\n this._drawGridLine(ctx, point, point.pointTop);\n};\n\n/**\n * Draw single datapoint for graph style 'line'.\n * @param {CanvasRenderingContext2D} ctx\n * @param {object} point\n * @private\n */\nGraph3d.prototype._redrawLineGraphPoint = function (ctx, point) {\n if (point.pointNext === undefined) {\n return;\n }\n\n ctx.lineWidth = this._getStrokeWidth(point);\n ctx.strokeStyle = this.dataColor.stroke;\n\n this._line(ctx, point.screen, point.pointNext.screen);\n};\n\n/**\n * Draw all datapoints for currently selected graph style.\n *\n */\nGraph3d.prototype._redrawDataGraph = function () {\n const ctx = this._getContext();\n let i;\n\n if (this.dataPoints === undefined || this.dataPoints.length <= 0) return; // TODO: throw exception?\n\n this._calcTranslations(this.dataPoints);\n\n for (i = 0; i < this.dataPoints.length; i++) {\n const point = this.dataPoints[i];\n\n // Using call() ensures that the correct context is used\n this._pointDrawingMethod.call(this, ctx, point);\n }\n};\n\n// -----------------------------------------------------------------------------\n// End methods for drawing points per graph style.\n// -----------------------------------------------------------------------------\n\n/**\n * Store startX, startY and startOffset for mouse operations\n * @param {Event} event The event that occurred\n */\nGraph3d.prototype._storeMousePosition = function (event) {\n // get mouse position (different code for IE and all other browsers)\n this.startMouseX = getMouseX(event);\n this.startMouseY = getMouseY(event);\n\n this._startCameraOffset = this.camera.getOffset();\n};\n\n/**\n * Start a moving operation inside the provided parent element\n * @param {Event} event The event that occurred (required for\n * retrieving the mouse position)\n */\nGraph3d.prototype._onMouseDown = function (event) {\n event = event || window.event;\n\n // check if mouse is still down (may be up when focus is lost for example\n // in an iframe)\n if (this.leftButtonDown) {\n this._onMouseUp(event);\n }\n\n // only react on left mouse button down\n this.leftButtonDown = event.which ? event.which === 1 : event.button === 1;\n if (!this.leftButtonDown && !this.touchDown) return;\n\n this._storeMousePosition(event);\n\n this.startStart = new Date(this.start);\n this.startEnd = new Date(this.end);\n this.startArmRotation = this.camera.getArmRotation();\n\n this.frame.style.cursor = \"move\";\n\n // add event listeners to handle moving the contents\n // we store the function onmousemove and onmouseup in the graph, so we can\n // remove the eventlisteners lateron in the function mouseUp()\n const me = this;\n this.onmousemove = function (event) {\n me._onMouseMove(event);\n };\n this.onmouseup = function (event) {\n me._onMouseUp(event);\n };\n document.addEventListener(\"mousemove\", me.onmousemove);\n document.addEventListener(\"mouseup\", me.onmouseup);\n util.preventDefault(event);\n};\n\n/**\n * Perform moving operating.\n * This function activated from within the funcion Graph.mouseDown().\n * @param {Event} event Well, eehh, the event\n */\nGraph3d.prototype._onMouseMove = function (event) {\n this.moving = true;\n event = event || window.event;\n\n // calculate change in mouse position\n const diffX = parseFloat(getMouseX(event)) - this.startMouseX;\n const diffY = parseFloat(getMouseY(event)) - this.startMouseY;\n\n // move with ctrl or rotate by other\n if (event && event.ctrlKey === true) {\n // calculate change in mouse position\n const scaleX = this.frame.clientWidth * 0.5;\n const scaleY = this.frame.clientHeight * 0.5;\n\n const offXNew =\n (this._startCameraOffset.x || 0) -\n (diffX / scaleX) * this.camera.armLength * 0.8;\n const offYNew =\n (this._startCameraOffset.y || 0) +\n (diffY / scaleY) * this.camera.armLength * 0.8;\n\n this.camera.setOffset(offXNew, offYNew);\n this._storeMousePosition(event);\n } else {\n let horizontalNew = this.startArmRotation.horizontal + diffX / 200;\n let verticalNew = this.startArmRotation.vertical + diffY / 200;\n\n const snapAngle = 4; // degrees\n const snapValue = Math.sin((snapAngle / 360) * 2 * Math.PI);\n\n // snap horizontally to nice angles at 0pi, 0.5pi, 1pi, 1.5pi, etc...\n // the -0.001 is to take care that the vertical axis is always drawn at the left front corner\n if (Math.abs(Math.sin(horizontalNew)) < snapValue) {\n horizontalNew = Math.round(horizontalNew / Math.PI) * Math.PI - 0.001;\n }\n if (Math.abs(Math.cos(horizontalNew)) < snapValue) {\n horizontalNew =\n (Math.round(horizontalNew / Math.PI - 0.5) + 0.5) * Math.PI - 0.001;\n }\n\n // snap vertically to nice angles\n if (Math.abs(Math.sin(verticalNew)) < snapValue) {\n verticalNew = Math.round(verticalNew / Math.PI) * Math.PI;\n }\n if (Math.abs(Math.cos(verticalNew)) < snapValue) {\n verticalNew = (Math.round(verticalNew / Math.PI - 0.5) + 0.5) * Math.PI;\n }\n this.camera.setArmRotation(horizontalNew, verticalNew);\n }\n\n this.redraw();\n\n // fire a cameraPositionChange event\n const parameters = this.getCameraPosition();\n this.emit(\"cameraPositionChange\", parameters);\n\n util.preventDefault(event);\n};\n\n/**\n * Stop moving operating.\n * This function activated from within the funcion Graph.mouseDown().\n * @param {Event} event The event\n */\nGraph3d.prototype._onMouseUp = function (event) {\n this.frame.style.cursor = \"auto\";\n this.leftButtonDown = false;\n\n // remove event listeners here\n document.removeEventListener(\"mousemove\", this.onmousemove);\n document.removeEventListener(\"mouseup\", this.onmouseup);\n\n util.preventDefault(event);\n};\n\n/**\n * @param {Event} event The event\n */\nGraph3d.prototype._onClick = function (event) {\n // NOTE: onclick_callback is deprecated and may be removed in a future version.\n if (!this.onclick_callback && !this.hasListeners(\"click\")) return;\n if (!this.moving) {\n const boundingRect = this.frame.getBoundingClientRect();\n const mouseX = getMouseX(event) - boundingRect.left;\n const mouseY = getMouseY(event) - boundingRect.top;\n const dataPoint = this._dataPointFromXY(mouseX, mouseY);\n if (dataPoint) {\n if (this.onclick_callback) this.onclick_callback(dataPoint.point.data);\n this.emit(\"click\", dataPoint.point.data);\n }\n } else {\n // disable onclick callback, if it came immediately after rotate/pan\n this.moving = false;\n }\n util.preventDefault(event);\n};\n\n/**\n * After having moved the mouse, a tooltip should pop up when the mouse is resting on a data point\n * @param {Event} event A mouse move event\n */\nGraph3d.prototype._onTooltip = function (event) {\n const delay = this.tooltipDelay; // ms\n const boundingRect = this.frame.getBoundingClientRect();\n const mouseX = getMouseX(event) - boundingRect.left;\n const mouseY = getMouseY(event) - boundingRect.top;\n\n if (!this.showTooltip) {\n return;\n }\n\n if (this.tooltipTimeout) {\n clearTimeout(this.tooltipTimeout);\n }\n\n // (delayed) display of a tooltip only if no mouse button is down\n if (this.leftButtonDown) {\n this._hideTooltip();\n return;\n }\n\n if (this.tooltip && this.tooltip.dataPoint) {\n // tooltip is currently visible\n const dataPoint = this._dataPointFromXY(mouseX, mouseY);\n if (dataPoint !== this.tooltip.dataPoint) {\n // datapoint changed\n if (dataPoint) {\n this._showTooltip(dataPoint);\n } else {\n this._hideTooltip();\n }\n }\n } else {\n // tooltip is currently not visible\n const me = this;\n this.tooltipTimeout = setTimeout(function () {\n me.tooltipTimeout = null;\n\n // show a tooltip if we have a data point\n const dataPoint = me._dataPointFromXY(mouseX, mouseY);\n if (dataPoint) {\n me._showTooltip(dataPoint);\n }\n }, delay);\n }\n};\n\n/**\n * Event handler for touchstart event on mobile devices\n * @param {Event} event The event\n */\nGraph3d.prototype._onTouchStart = function (event) {\n this.touchDown = true;\n\n const me = this;\n this.ontouchmove = function (event) {\n me._onTouchMove(event);\n };\n this.ontouchend = function (event) {\n me._onTouchEnd(event);\n };\n document.addEventListener(\"touchmove\", me.ontouchmove);\n document.addEventListener(\"touchend\", me.ontouchend);\n\n this._onMouseDown(event);\n};\n\n/**\n * Event handler for touchmove event on mobile devices\n * @param {Event} event The event\n */\nGraph3d.prototype._onTouchMove = function (event) {\n this._onMouseMove(event);\n};\n\n/**\n * Event handler for touchend event on mobile devices\n * @param {Event} event The event\n */\nGraph3d.prototype._onTouchEnd = function (event) {\n this.touchDown = false;\n\n document.removeEventListener(\"touchmove\", this.ontouchmove);\n document.removeEventListener(\"touchend\", this.ontouchend);\n\n this._onMouseUp(event);\n};\n\n/**\n * Event handler for mouse wheel event, used to zoom the graph\n * Code from http://adomas.org/javascript-mouse-wheel/\n * @param {Event} event The event\n */\nGraph3d.prototype._onWheel = function (event) {\n if (!event) /* For IE. */ event = window.event;\n if (this.zoomable && (!this.ctrlToZoom || event.ctrlKey)) {\n // retrieve delta\n let delta = 0;\n if (event.wheelDelta) {\n /* IE/Opera. */\n delta = event.wheelDelta / 120;\n } else if (event.detail) {\n /* Mozilla case. */\n // In Mozilla, sign of delta is different than in IE.\n // Also, delta is multiple of 3.\n delta = -event.detail / 3;\n }\n\n // If delta is nonzero, handle it.\n // Basically, delta is now positive if wheel was scrolled up,\n // and negative, if wheel was scrolled down.\n if (delta) {\n const oldLength = this.camera.getArmLength();\n const newLength = oldLength * (1 - delta / 10);\n\n this.camera.setArmLength(newLength);\n this.redraw();\n\n this._hideTooltip();\n }\n\n // fire a cameraPositionChange event\n const parameters = this.getCameraPosition();\n this.emit(\"cameraPositionChange\", parameters);\n\n // Prevent default actions caused by mouse wheel.\n // That might be ugly, but we handle scrolls somehow\n // anyway, so don't bother here..\n util.preventDefault(event);\n }\n};\n\n/**\n * Test whether a point lies inside given 2D triangle\n * @param {vis.Point2d} point\n * @param {vis.Point2d[]} triangle\n * @returns {boolean} true if given point lies inside or on the edge of the\n * triangle, false otherwise\n * @private\n */\nGraph3d.prototype._insideTriangle = function (point, triangle) {\n const a = triangle[0],\n b = triangle[1],\n c = triangle[2];\n\n /**\n *\n * @param {number} x\n * @returns {number}\n */\n function sign(x) {\n return x > 0 ? 1 : x < 0 ? -1 : 0;\n }\n\n const as = sign(\n (b.x - a.x) * (point.y - a.y) - (b.y - a.y) * (point.x - a.x),\n );\n const bs = sign(\n (c.x - b.x) * (point.y - b.y) - (c.y - b.y) * (point.x - b.x),\n );\n const cs = sign(\n (a.x - c.x) * (point.y - c.y) - (a.y - c.y) * (point.x - c.x),\n );\n\n // each of the three signs must be either equal to each other or zero\n return (\n (as == 0 || bs == 0 || as == bs) &&\n (bs == 0 || cs == 0 || bs == cs) &&\n (as == 0 || cs == 0 || as == cs)\n );\n};\n\n/**\n * Find a data point close to given screen position (x, y)\n * @param {number} x\n * @param {number} y\n * @returns {object | null} The closest data point or null if not close to any\n * data point\n * @private\n */\nGraph3d.prototype._dataPointFromXY = function (x, y) {\n const distMax = 100; // px\n const center = new Point2d(x, y);\n let i,\n dataPoint = null,\n closestDataPoint = null,\n closestDist = null;\n\n if (\n this.style === Graph3d.STYLE.BAR ||\n this.style === Graph3d.STYLE.BARCOLOR ||\n this.style === Graph3d.STYLE.BARSIZE\n ) {\n // the data points are ordered from far away to closest\n for (i = this.dataPoints.length - 1; i >= 0; i--) {\n dataPoint = this.dataPoints[i];\n const surfaces = dataPoint.surfaces;\n if (surfaces) {\n for (let s = surfaces.length - 1; s >= 0; s--) {\n // split each surface in two triangles, and see if the center point is inside one of these\n const surface = surfaces[s];\n const corners = surface.corners;\n const triangle1 = [\n corners[0].screen,\n corners[1].screen,\n corners[2].screen,\n ];\n const triangle2 = [\n corners[2].screen,\n corners[3].screen,\n corners[0].screen,\n ];\n if (\n this._insideTriangle(center, triangle1) ||\n this._insideTriangle(center, triangle2)\n ) {\n // return immediately at the first hit\n return dataPoint;\n }\n }\n }\n }\n } else {\n // find the closest data point, using distance to the center of the point on 2d screen\n for (i = 0; i < this.dataPoints.length; i++) {\n dataPoint = this.dataPoints[i];\n const point = dataPoint.screen;\n if (point) {\n const distX = Math.abs(x - point.x);\n const distY = Math.abs(y - point.y);\n const dist = Math.sqrt(distX * distX + distY * distY);\n\n if ((closestDist === null || dist < closestDist) && dist < distMax) {\n closestDist = dist;\n closestDataPoint = dataPoint;\n }\n }\n }\n }\n\n return closestDataPoint;\n};\n\n/**\n * Determine if the given style has bars\n * @param {number} style the style to check\n * @returns {boolean} true if bar style, false otherwise\n */\nGraph3d.prototype.hasBars = function (style) {\n return (\n style == Graph3d.STYLE.BAR ||\n style == Graph3d.STYLE.BARCOLOR ||\n style == Graph3d.STYLE.BARSIZE\n );\n};\n\n/**\n * Display a tooltip for given data point\n * @param {object} dataPoint\n * @private\n */\nGraph3d.prototype._showTooltip = function (dataPoint) {\n let content, line, dot;\n\n if (!this.tooltip) {\n content = document.createElement(\"div\");\n Object.assign(content.style, {}, this.tooltipStyle.content);\n content.style.position = \"absolute\";\n\n line = document.createElement(\"div\");\n Object.assign(line.style, {}, this.tooltipStyle.line);\n line.style.position = \"absolute\";\n\n dot = document.createElement(\"div\");\n Object.assign(dot.style, {}, this.tooltipStyle.dot);\n dot.style.position = \"absolute\";\n\n this.tooltip = {\n dataPoint: null,\n dom: {\n content: content,\n line: line,\n dot: dot,\n },\n };\n } else {\n content = this.tooltip.dom.content;\n line = this.tooltip.dom.line;\n dot = this.tooltip.dom.dot;\n }\n\n this._hideTooltip();\n\n this.tooltip.dataPoint = dataPoint;\n if (typeof this.showTooltip === \"function\") {\n content.innerHTML = this.showTooltip(dataPoint.point);\n } else {\n content.innerHTML =\n \"<table>\" +\n \"<tr><td>\" +\n this.xLabel +\n \":</td><td>\" +\n dataPoint.point.x +\n \"</td></tr>\" +\n \"<tr><td>\" +\n this.yLabel +\n \":</td><td>\" +\n dataPoint.point.y +\n \"</td></tr>\" +\n \"<tr><td>\" +\n this.zLabel +\n \":</td><td>\" +\n dataPoint.point.z +\n \"</td></tr>\" +\n \"</table>\";\n }\n\n content.style.left = \"0\";\n content.style.top = \"0\";\n this.frame.appendChild(content);\n this.frame.appendChild(line);\n this.frame.appendChild(dot);\n\n // calculate sizes\n const contentWidth = content.offsetWidth;\n const contentHeight = content.offsetHeight;\n const lineHeight = line.offsetHeight;\n const dotWidth = dot.offsetWidth;\n const dotHeight = dot.offsetHeight;\n\n let left = dataPoint.screen.x - contentWidth / 2;\n left = Math.min(\n Math.max(left, 10),\n this.frame.clientWidth - 10 - contentWidth,\n );\n\n line.style.left = dataPoint.screen.x + \"px\";\n line.style.top = dataPoint.screen.y - lineHeight + \"px\";\n content.style.left = left + \"px\";\n content.style.top = dataPoint.screen.y - lineHeight - contentHeight + \"px\";\n dot.style.left = dataPoint.screen.x - dotWidth / 2 + \"px\";\n dot.style.top = dataPoint.screen.y - dotHeight / 2 + \"px\";\n};\n\n/**\n * Hide the tooltip when displayed\n * @private\n */\nGraph3d.prototype._hideTooltip = function () {\n if (this.tooltip) {\n this.tooltip.dataPoint = null;\n\n for (const prop in this.tooltip.dom) {\n if (Object.prototype.hasOwnProperty.call(this.tooltip.dom, prop)) {\n const elem = this.tooltip.dom[prop];\n if (elem && elem.parentNode) {\n elem.parentNode.removeChild(elem);\n }\n }\n }\n }\n};\n\n/**--------------------------------------------------------------------------**/\n\n/**\n * Get the horizontal mouse position from a mouse event\n * @param {Event} event\n * @returns {number} mouse x\n */\nfunction getMouseX(event) {\n if (\"clientX\" in event) return event.clientX;\n return (event.targetTouches[0] && event.targetTouches[0].clientX) || 0;\n}\n\n/**\n * Get the vertical mouse position from a mouse event\n * @param {Event} event\n * @returns {number} mouse y\n */\nfunction getMouseY(event) {\n if (\"clientY\" in event) return event.clientY;\n return (event.targetTouches[0] && event.targetTouches[0].clientY) || 0;\n}\n\n// -----------------------------------------------------------------------------\n// Public methods for specific settings\n// -----------------------------------------------------------------------------\n\n/**\n * Set the rotation and distance of the camera\n * @param {object} pos An object with the camera position\n * @param {number} [pos.horizontal] The horizontal rotation, between 0 and 2*PI.\n * Optional, can be left undefined.\n * @param {number} [pos.vertical] The vertical rotation, between 0 and 0.5*PI.\n * if vertical=0.5*PI, the graph is shown from\n * the top. Optional, can be left undefined.\n * @param {number} [pos.distance] The (normalized) distance of the camera to the\n * center of the graph, a value between 0.71 and\n * 5.0. Optional, can be left undefined.\n */\nGraph3d.prototype.setCameraPosition = function (pos) {\n setCameraPosition(pos, this);\n this.redraw();\n};\n\n/**\n * Set a new size for the graph\n * @param {string} width Width in pixels or percentage (for example '800px'\n * or '50%')\n * @param {string} height Height in pixels or percentage (for example '400px'\n * or '30%')\n */\nGraph3d.prototype.setSize = function (width, height) {\n this._setSize(width, height);\n this.redraw();\n};\n\n// -----------------------------------------------------------------------------\n// End public methods for specific settings\n// -----------------------------------------------------------------------------\n\nexport default Graph3d;\n"],"names":["Point3d","x","y","z","this","undefined","Camera","armLocation","armRotation","horizontal","vertical","armLength","cameraOffset","offsetMultiplier","cameraLocation","cameraRotation","Math","PI","calculateCameraOrientation","Filter","dataGroup","column","graph","index","value","values","getDistinctValues","length","selectValue","dataPoints","loaded","onLoadCallback","animationPreload","loadInBackground","Range","min","max","subtract","a","b","sub","add","sum","avg","scalarProduct","p","c","dotProduct","crossProduct","crossproduct","prototype","sqrt","normalize","setOffset","abs","sign","mul","border","getOffset","setArmLocation","setArmRotation","getArmRotation","rot","setArmLength","getArmLength","getCameraLocation","getCameraRotation","sin","cos","xa","za","dx","dy","isLoaded","getLoadedProgress","len","i","round","getLabel","filterLabel","getColumn","getSelectedValue","getValues","getValue","Error","_getDataPoints","f","dataView","DataView","getDataSet","filter","item","get","setOnLoadCallback","callback","frame","progress","document","createElement","style","position","color","appendChild","innerHTML","bottom","left","me","setTimeout","removeChild","adjust","combine","range","expand","val","newMin","newMax","center","STYLE","BAR","BARCOLOR","BARSIZE","DOT","DOTLINE","DOTCOLOR","DOTSIZE","GRID","LINE","SURFACE","STYLENAME","dot","line","grid","surface","bar","OPTIONKEYS","PREFIXEDOPTIONKEYS","DEFAULTS","isEmpty","obj","prop","Object","hasOwnProperty","call","prefixFieldName","prefix","fieldName","str","charAt","toUpperCase","slice","forceCopy","src","dst","fields","srcKey","dstKey","safeCopy","setSpecialSettings","backgroundColor","fill","stroke","strokeWidth","borderColor","borderWidth","borderStyle","setBackgroundColor","dataColor","setDataColor","styleNumber","styleName","number","getStyleNumberByName","valid","n","checkStyleNumber","setStyle","surfaceColors","console","warn","colormap","rgbColors","Array","isArray","parseColorArray","parseColorObject","hue","reverse","setSurfaceColor","setColormap","showLegend","isLegendGraphStyle","setShowLegend","setCameraPosition","cameraPosition","tooltip","showTooltip","onclick","onclick_callback","tooltipStyle","util","selectiveDeepExtend","map","colorCode","isValidHex","hexToRGB","hues","saturation","brightness","colorStops","hueStep","end","start","push","HSVToRGB","camPos","camera","distance","DataGroup","dataTable","initializeData","graph3d","rawData","data","DataSet","dataSet","off","_onChange","setData","on","colX","colY","colZ","withBars","hasBars","defaultXBarWidth","xBarWidth","getSmallestDifference","defaultYBarWidth","yBarWidth","_initializeRange","colValue","valueRange","getColumnRange","_setRangeDefaults","defaultValueMin","defaultValueMax","zRange","table","getDataTable","dataFilter","redraw","_collectRangeSettings","indexOf","upper","barWidth","step","range_label","step_label","settings","toSorted","smallest_diff","diff","getNumberOfRows","defaultMin","defaultMax","getDataPoints","point","trans","screen","initDataAsMatrix","dataX","dataY","dataMatrix","xIndex","yIndex","pointRight","pointTop","pointCross","getInfo","reload","pointNext","string","bool","object","array","colorOptions","__type__","allOptions","animationAutoStart","boolean","animationInterval","axisColor","axisFontSize","axisFontType","zoomable","ctrlToZoom","xCenter","yCenter","function","dotSizeMinFraction","dotSizeMaxFraction","dotSizeRatio","gridColor","keepAspectRatio","xLabel","yLabel","zLabel","legendLabel","xMin","yMin","zMin","xMax","yMax","zMax","showAnimationControls","showGrayBottom","showGrid","showPerspective","showShadow","showSurfaceGrid","showXAxis","showYAxis","showZAxis","rotateAxisLabels","xStep","yStep","zStep","tooltipDelay","content","background","borderRadius","boxShadow","padding","borderLeft","height","width","pointerEvents","xValueLabel","yValueLabel","zValueLabel","valueMax","valueMin","verticalRatio","Point2d","Slider","container","options","visible","prev","type","play","next","MozBorderRadius","slide","margin","onmousedown","event","_onMouseDown","togglePlay","onChangeCallback","playTimeout","playInterval","playLoop","StepNumber","prettyStep","_start","_end","_step","precision","_current","setRange","getIndex","setIndex","playNext","Date","interval","stop","clearInterval","setOnChangeCallback","setPlayInterval","getPlayInterval","setPlayLoop","doLoop","onChange","top","clientHeight","offsetHeight","clientWidth","indexToLeft","setValues","which","button","startClientX","clientX","startSlideX","parseFloat","cursor","onmousemove","_onMouseMove","onmouseup","_onMouseUp","addEventListener","preventDefault","leftToIndex","removeEventListener","isNumeric","isNaN","isFinite","setStep","calculatePrettyStep","log10","log","LN10","step1","pow","step2","step5","getCurrent","toPrecision","getStep","checkFirst","Graph3d","autoByDefault","SyntaxError","containerElement","create","eye","setDefaults","setOptions","getMouseX","targetTouches","getMouseY","clientY","v","Emitter","_setScale","scale","xRange","yRange","zCenter","_convert3Dto2D","point3d","translation","_convertPointToTranslation","_convertTranslationToScreen","ax","ay","az","cx","cy","cz","sinTx","cosTx","sinTy","cosTy","sinTz","cosTz","ex","ey","ez","dz","bx","by","currentXCenter","canvas","currentYCenter","_calcTranslations","points","transBottom","dist","sort","_initializeRanges","dg","hasChildNodes","firstChild","overflow","noCanvas","fontWeight","_onTouchStart","_onWheel","_onTooltip","_onClick","_setSize","_resizeCanvas","animationStart","slider","animationStop","_resizeCenter","getCameraPosition","pos","_readData","_redrawFilter","Validator","validate","error","VALIDATOR_PRINT_STYLE","setPointDrawingMethod","setAxisLabelMethod","method","_redrawBarGraphPoint","_redrawBarColorGraphPoint","_redrawBarSizeGraphPoint","_redrawDotGraphPoint","_redrawDotLineGraphPoint","_redrawDotColorGraphPoint","_redrawDotSizeGraphPoint","_redrawSurfaceGraphPoint","_redrawGridGraphPoint","_redrawLineGraphPoint","_pointDrawingMethod","_drawAxisLabelX","drawAxisLabelXRotate","_drawAxisLabelY","drawAxisLabelYRotate","_drawAxisLabelZ","drawAxisLabelZRotate","drawAxisLabelX","drawAxisLabelY","drawAxisLabelZ","_redrawSlider","_redrawClear","_redrawAxis","_redrawDataGraph","_redrawInfo","_redrawLegend","_getContext","ctx","getContext","lineJoin","lineCap","clearRect","_dotSize","_getLegendWidth","isSizeLegend","isValueLegend","right","lineWidth","font","ymin","ymax","_colormap","strokeStyle","beginPath","moveTo","lineTo","strokeRect","widthMin","fillStyle","closePath","legendMin","legendMax","from","to","_line","textAlign","textBaseline","fillText","label","info","lineStyle","text","armAngle","yMargin","point2d","offset","save","translate","rotate","restore","_line3d","from2d","to2d","xText","yText","zText","xOffset","yOffset","gridLenX","gridLenY","textMargin","armVector","defaultXStep","msg","defaultYStep","defaultZStep","from3d","xMin2d","xMax2d","_getStrokeWidth","_redrawBar","xWidth","yWidth","forEach","surfaces","corners","j","transCenter","_polygon","_drawCircle","size","radius","_calcRadius","arc","_getColorsRegular","_getColorsColor","pointStyle","_getColorsSize","r","g","maxIndex","startIndex","floor","endIndex","innerRatio","Number","colors","fraction","dotSize","sizeMin","cross","cosViewAngle","topSideVisible","aDiff","bDiff","surfaceNormal","surfacePosition","ratio","_drawGridLine","_storeMousePosition","startMouseX","startMouseY","_startCameraOffset","window","leftButtonDown","touchDown","startStart","startEnd","startArmRotation","moving","diffX","diffY","ctrlKey","scaleX","scaleY","offXNew","offYNew","horizontalNew","verticalNew","snapAngle","snapValue","parameters","emit","hasListeners","boundingRect","getBoundingClientRect","mouseX","mouseY","dataPoint","_dataPointFromXY","delay","tooltipTimeout","clearTimeout","_hideTooltip","_showTooltip","ontouchmove","_onTouchMove","ontouchend","_onTouchEnd","delta","wheelDelta","detail","newLength","_insideTriangle","triangle","as","bs","cs","closestDataPoint","closestDist","s","triangle1","triangle2","distX","distY","dom","assign","contentWidth","offsetWidth","contentHeight","lineHeight","dotWidth","dotHeight","elem","parentNode","setSize"],"mappings":"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"}