mirror of
https://github.com/flarum/framework.git
synced 2024-12-12 22:53:37 +08:00
1 line
179 KiB
Plaintext
1 line
179 KiB
Plaintext
{"version":3,"sources":["webpack://@flarum/statistics/webpack/bootstrap","webpack://@flarum/statistics/external \"flarum.core.compat['utils/abbreviateNumber']\"","webpack://@flarum/statistics/external \"flarum.core.compat['app']\"","webpack://@flarum/statistics/external \"flarum.core.compat['extend']\"","webpack://@flarum/statistics/external \"flarum.core.compat['components/DashboardPage']\"","webpack://@flarum/statistics/external \"flarum.core.compat['components/DashboardWidget']\"","webpack://@flarum/statistics/external \"flarum.core.compat['components/SelectDropdown']\"","webpack://@flarum/statistics/external \"flarum.core.compat['components/Button']\"","webpack://@flarum/statistics/external \"flarum.core.compat['helpers/icon']\"","webpack://@flarum/statistics/./node_modules/frappe-charts/dist/frappe-charts.esm.js","webpack://@flarum/statistics/./src/admin/components/StatisticsWidget.js","webpack://@flarum/statistics/./node_modules/@babel/runtime/helpers/esm/inheritsLoose.js","webpack://@flarum/statistics/./src/admin/index.js"],"names":["installedModules","__webpack_require__","moduleId","exports","module","i","l","modules","call","m","c","d","name","getter","o","Object","defineProperty","enumerable","get","r","Symbol","toStringTag","value","t","mode","__esModule","ns","create","key","bind","n","object","property","prototype","hasOwnProperty","p","s","flarum","core","compat","$","expr","con","document","querySelector","getOffset","element","rect","getBoundingClientRect","top","documentElement","scrollTop","body","left","scrollLeft","tag","createElement","val","appendChild","ref","parentNode","insertBefore","keys","map","prop","style","setAttribute","BASE_MEASURES","margins","bottom","right","paddings","baseHeight","titleHeight","legendHeight","titleFontSize","getTopOffset","getLeftOffset","getExtraHeight","getExtraWidth","INIT_CHART_UPDATE_TIMEOUT","CHART_POST_ANIMATE_TIMEOUT","AXIS_DATASET_CHART_TYPES","AXIS_LEGEND_BAR_SIZE","BAR_CHART_SPACE_RATIO","MIN_BAR_PERCENT_HEIGHT","LINE_CHART_DOT_SIZE","PERCENTAGE_BAR_DEFAULT_HEIGHT","PERCENTAGE_BAR_DEFAULT_DEPTH","HEATMAP_DISTRIBUTION_SIZE","HEATMAP_SQUARE_SIZE","DEFAULT_CHAR_WIDTH","TOOLTIP_POINTER_TRIANGLE_HEIGHT","DEFAULT_CHART_COLORS","DEFAULT_COLORS","bar","line","pie","percentage","heatmap","ANGLE_RATIO","Math","PI","FULL_ANGLE","SvgTip","parent","colors","this","titleName","titleValue","listValues","titleValueFirst","x","y","setup","makeTooltip","fill","calcPosition","container","inside","className","innerHTML","hideTip","title","dataPointList","addEventListener","index","set","color","formatted","li","styles","width","offsetWidth","offsetHeight","maxLeft","pointer","pointerOffset","valueFirst","refresh","opacity","floatTwo","parseFloat","toFixed","fillArray","array","count","start","length","fillerArray","Array","abs","concat","getStringWidth","string","charWidth","getPositionByAngle","angle","radius","sin","cos","getBarHeightAndYAttr","yTop","zeroLine","height","equilizeNoOfElements","array1","array2","extraCount","PRESET_COLOR_MAP","limitColor","lightenDarkenColor","amt","col","getColor","usePound","slice","num","parseInt","b","toString","AXIS_TICK_LENGTH","LABEL_MARGIN","FONT_SIZE","BASE_LINE_COLOR","FONT_FILL","$$1","createSVG","createElementNS","setGradientStop","gradElem","offset","makeSVGGroup","transform","args","makePath","pathStr","stroke","makeGradient","svgDefElem","lighter","gradientId","gradientDef","id","x1","x2","y1","y2","renderVerticalGradient","opacities","heatSquare","size","data","makeText","content","options","fontSize","dy","undefined","textAnchor","makeHoriLine","label","lineType","text","xLine","pos","makeVertLine","makeOverlay","unit","transformValue","nodeName","getAttribute","childNodes","overlay","cloneNode","updateOverlay","attributes","values","filter","attr","includes","specified","nodeValue","UNIT_ANIM_DUR","PATH_ANIM_DUR","MARKER_LINE_ANIM_DUR","REPLACE_ALL_NEW_DUR","STD_EASING","translate","oldCoord","newCoord","duration","old","join","translateHoriLine","yLine","newY","oldY","EASING","ease","linear","easein","easeout","easeinout","webkitTransform","msTransform","mozTransform","oTransform","animateSVG","svgContainer","elements","newElements","animElements","animElement","newElement","props","dur","easingType","type","oldValues","attributeName","animateElement","currentValue","animAttr","from","to","begin","keySplines","keyTimes","calcMode","animateSVGElement","push","replaceChild","animSvg","CSSTEXT","BOUND_DRAW_FN","BaseChart","HTMLElement","Error","rawChartArgs","realData","prepareData","prepareFirstData","validateColors","config","showTooltip","showLegend","isNavigable","animate","measures","JSON","parse","stringify","setMeasures","argHeight","state","initTimeout","overlays","configure","validColors","forEach","test","isValidColor","console","warn","boundDrawFn","window","draw","removeEventListener","makeContainer","updateWidth","independentWidth","tip","bindTooltip","onlyWidthChange","init","calc","makeChartArea","setupComponents","components","drawArea","render","setTimeout","update","renderLegend","setupNavigation","padding","baseWidth","getComputedStyle","paddingLeft","paddingRight","clientWidth","svg","removeChild","svgDefs","titleEL","legendArea","updateTipOffset","Map","error","elementsToAnimate","svgElement","animSvgElement","runSMILAnimation","make","updateNav","bindUnits","bindOverlay","keyActions","onEnterKey","onLeftArrow","onUpArrow","onRightArrow","onDownArrow","e","el","innerHeight","clientHeight","innerWidth","isElementInViewport","event","keyCode","chartSvg","clone","classList","add","styleEl","firstChild","prepareForExport","filename","a","blob","Blob","url","URL","createObjectURL","href","download","click","revokeObjectURL","downloadFile","AggregationChart","super","maxSlices","maxLegendPoints","sliceTotals","allTotals","labels","total","datasets","totals","sort","remaining","sumOfRemaining","grandTotal","reduce","center","textContent","legendTotals","divisor","floor","dot","cx","cy","dx","group","legendDot","NO_OF_YEAR_MONTHS","NO_OF_DAYS_IN_WEEK","NO_OF_MILLIS","SEC_IN_DAY","MONTH_NAMES","DAY_NAMES_SHORT","treatAsUtc","date","result","Date","setMinutes","getMinutes","getTimezoneOffset","getYyyyMmDd","dd","getDate","mm","getMonth","getFullYear","getTime","getWeeksBetween","startDate","endDate","weekStartDate","setDayToSunday","ceil","millisecondsPerDay","getDaysBetween","areInSameMonth","getMonthName","short","monthName","getLastDateInMonth","month","year","newDate","day","getDay","addDays","numberOfDays","setDate","ChartComponent","layerClass","layerTransform","constants","getData","makeElements","animateElements","store","layer","oldData","componentConfigs","pieSlices","sliceStrings","transition","newData","oldPath","animatePathStr","percentageBars","xPositions","depth","percentageBar","widths","barHeight","barDepth","yAxis","positions","position","newPos","newLabels","oldPos","oldLabels","xAxis","calcLabels","newX","oldX","translateVertLine","yMarkers","labelPos","labelSvg","yMarker","newOptions","yRegions","region","yRegion","startPos","endPos","newStarts","oldStarts","rectGroup","newY1","newY2","oldY2","newHeight","animateRegion","heatDomain","colWidth","rowHeight","squareSize","xTranslate","serializedSubDomains","cols","week","weekNo","toUpperCase","yyyyMmDd","dataValue","square","barGraph","unitType","units","yPositions","j","meta","minHeight","datasetBar","barWidth","offsets","barsWidth","newXPos","newYPos","newOffsets","oldXPos","oldYPos","oldOffsets","rectAnim","oldCoordStr","split","animateBar","lineGraph","paths","hideLine","xList","yList","pointsStr","path","heatline","gradient_id","regionFill","gradient_id_region","getPaths","hideDots","datasetDot","valuesOverPoints","newValues","newXList","newYList","pathComponents","animPath","regStartPt","regEndPt","animRegion","animatePath","animateDot","getComponent","k","assign","normalize","isNaN","mantissa","exponent","sig","isFinite","exp","log10","pow","getChartIntervals","maxValue","minValue","normalMaxValue","normalMinValue","intervals","max","min","upperBound","lowerBound","range","noOfParts","partSize","getChartRangeIntervals","getIntervalSize","orderedArray","scale","scaleMultiplier","COL_WIDTH","ROW_HEIGHT","AxisChart","barOptions","lineOptions","axisOptions","tooltipOptions","xAxisMode","yAxisMode","xIsSeries","formatTooltipX","formatTooltipY","datasetLength","zeroArray","vals","chartType","end","dataPrep","zeroData","zeroDataPrep","calcXPositions","calcYAxisParameters","getAllYValues","makeDataByIndex","unitWidth","xOffset","dataValues","withMinimum","yPts","getPositiveFirstIntervals","absMinValue","intervalSize","unshift","pseudoMaxValue","pseudoMinValue","reverse","calcChartIntervals","intervalHeight","zeroIndex","interval","indexOf","getZeroIndex","calcDatasetPoints","calcYExtremes","calcYRegions","scaleAll","cumulativeYs","cumulativeYPos","stacked","yExtremes","cumulative","allValueLists","chartWidth","isSeries","allowedSpace","allowedLetters","getShortenedLabels","barDatasets","lineDatasets","barsConfigs","spaceRatio","lineConfigs","minLine","dotSize","markerConfigs","optionals","dataUnitComponents","component","dataByIndex","formatX","formatY","yPos","formattedLabel","xPos","yExtreme","relX","pageX","relY","pageY","mapTooltipXPosition","goal","arr","closest","prev","curr","getClosestInArray","dbi","setValues","showTip","legendBar","overlayGuides","g","currentIndex","currentUnit","setCurrentDataPoint","target","properties","evt","createEvent","initEvent","dispatchEvent","fire","getDataPoint","datasetValues","addDataPoint","splice","removeDataPoint","chartTypes","bars","gOff","pOff","formattedLabels","fraction","countLabel","validStarts","startSubDomain","startSubDomainIndex","discreteDomains","spacing","noOfWeeks","setFullYear","dataPoints","points","timestampSec$$1","firstWeekStart","distribution","distributionSize","dataMaxValue","distributionStep","checkpoint","calcDistribution","domainConfigs","getDomains","lessCol","dayName","dayText","comp","daySquares","daySquare","dateParts","lessText","moreText","startMonth","startYear","endMonth","endYear","noOfMonths","startOfMonth","getDomainConfig","startOfWeek","domainConfig","noOfMonthWeeks","getCol","empty","currentDate","currentDateWithinData","getSubDomainConfig","mouseMove","mouseLeave","hoverRadio","startAngle","clockWise","prevSlicesProperties","slicesProperties","curAngle","originDiffAngle","diffAngle","endAngle","startPosition","endPosition","prevProperty","curStart","curEnd","curPath","arcStartX","arcStartY","arcEndX","arcEndY","makeArcPathStr","flag","calTranslateByAngle","g_off","formatted_labels","percent","slices","prevIndex","curActiveSliceIndex","prevAcitve","curActiveSlice","hoverSlice","Chart","getChartByType","StatisticsWidget","subClass","superClass","constructor","__proto__","today","setTime","app","statistics","timezoneOffset","setUTCHours","entities","periods","step","last_7_days","last_28_days","last_12_months","selectedEntity","selectedPeriod","thisPeriod","translator","trans","buttonClassName","caretIcon","period","active","onclick","changePeriod","icon","entity","totalCount","getTotalCount","thisPeriodCount","getPeriodCount","lastPeriodCount","getLastPeriod","periodChange","changeEntity","abbreviateNumber","drawChart","elm","isInitialized","context","chart","periodLength","lastPeriod","moment","unix","utc","format","forum","attribute","timed","time","DashboardWidget","initializers","extend","DashboardPage","widgets"],"mappings":"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","file":"admin.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 8);\n","module.exports = flarum.core.compat['utils/abbreviateNumber'];","module.exports = flarum.core.compat['app'];","module.exports = flarum.core.compat['extend'];","module.exports = flarum.core.compat['components/DashboardPage'];","module.exports = flarum.core.compat['components/DashboardWidget'];","module.exports = flarum.core.compat['components/SelectDropdown'];","module.exports = flarum.core.compat['components/Button'];","module.exports = flarum.core.compat['helpers/icon'];","function $(expr, con) {\n\treturn typeof expr === \"string\"? (con || document).querySelector(expr) : expr || null;\n}\n\n\n\n$.create = (tag, o) => {\n\tvar element = document.createElement(tag);\n\n\tfor (var i in o) {\n\t\tvar val = o[i];\n\n\t\tif (i === \"inside\") {\n\t\t\t$(val).appendChild(element);\n\t\t}\n\t\telse if (i === \"around\") {\n\t\t\tvar ref = $(val);\n\t\t\tref.parentNode.insertBefore(element, ref);\n\t\t\telement.appendChild(ref);\n\n\t\t} else if (i === \"styles\") {\n\t\t\tif(typeof val === \"object\") {\n\t\t\t\tObject.keys(val).map(prop => {\n\t\t\t\t\telement.style[prop] = val[prop];\n\t\t\t\t});\n\t\t\t}\n\t\t} else if (i in element ) {\n\t\t\telement[i] = val;\n\t\t}\n\t\telse {\n\t\t\telement.setAttribute(i, val);\n\t\t}\n\t}\n\n\treturn element;\n};\n\nfunction getOffset(element) {\n\tlet rect = element.getBoundingClientRect();\n\treturn {\n\t\t// https://stackoverflow.com/a/7436602/6495043\n\t\t// rect.top varies with scroll, so we add whatever has been\n\t\t// scrolled to it to get absolute distance from actual page top\n\t\ttop: rect.top + (document.documentElement.scrollTop || document.body.scrollTop),\n\t\tleft: rect.left + (document.documentElement.scrollLeft || document.body.scrollLeft)\n\t};\n}\n\nfunction isElementInViewport(el) {\n\t// Although straightforward: https://stackoverflow.com/a/7557433/6495043\n\tvar rect = el.getBoundingClientRect();\n\n\treturn (\n\t\trect.top >= 0 &&\n rect.left >= 0 &&\n rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) && /*or $(window).height() */\n rect.right <= (window.innerWidth || document.documentElement.clientWidth) /*or $(window).width() */\n\t);\n}\n\nfunction getElementContentWidth(element) {\n\tvar styles = window.getComputedStyle(element);\n\tvar padding = parseFloat(styles.paddingLeft) +\n\t\tparseFloat(styles.paddingRight);\n\n\treturn element.clientWidth - padding;\n}\n\n\n\n\n\nfunction fire(target, type, properties) {\n\tvar evt = document.createEvent(\"HTMLEvents\");\n\n\tevt.initEvent(type, true, true );\n\n\tfor (var j in properties) {\n\t\tevt[j] = properties[j];\n\t}\n\n\treturn target.dispatchEvent(evt);\n}\n\n// https://css-tricks.com/snippets/javascript/loop-queryselectorall-matches/\n\nconst BASE_MEASURES = {\n\tmargins: {\n\t\ttop: 10,\n\t\tbottom: 10,\n\t\tleft: 20,\n\t\tright: 20\n\t},\n\tpaddings: {\n\t\ttop: 20,\n\t\tbottom: 40,\n\t\tleft: 30,\n\t\tright: 10\n\t},\n\n\tbaseHeight: 240,\n\ttitleHeight: 20,\n\tlegendHeight: 30,\n\n\ttitleFontSize: 12,\n};\n\nfunction getTopOffset(m) {\n\treturn m.titleHeight + m.margins.top + m.paddings.top;\n}\n\nfunction getLeftOffset(m) {\n\treturn m.margins.left + m.paddings.left;\n}\n\nfunction getExtraHeight(m) {\n\tlet totalExtraHeight = m.margins.top + m.margins.bottom\n\t\t+ m.paddings.top + m.paddings.bottom\n\t\t+ m.titleHeight + m.legendHeight;\n\treturn totalExtraHeight;\n}\n\nfunction getExtraWidth(m) {\n\tlet totalExtraWidth = m.margins.left + m.margins.right\n\t\t+ m.paddings.left + m.paddings.right;\n\n\treturn totalExtraWidth;\n}\n\nconst INIT_CHART_UPDATE_TIMEOUT = 700;\nconst CHART_POST_ANIMATE_TIMEOUT = 400;\n\nconst DEFAULT_AXIS_CHART_TYPE = 'line';\nconst AXIS_DATASET_CHART_TYPES = ['line', 'bar'];\n\nconst AXIS_LEGEND_BAR_SIZE = 100;\n\nconst BAR_CHART_SPACE_RATIO = 0.5;\nconst MIN_BAR_PERCENT_HEIGHT = 0.01;\n\nconst LINE_CHART_DOT_SIZE = 4;\nconst DOT_OVERLAY_SIZE_INCR = 4;\n\nconst PERCENTAGE_BAR_DEFAULT_HEIGHT = 20;\nconst PERCENTAGE_BAR_DEFAULT_DEPTH = 2;\n\n// Fixed 5-color theme,\n// More colors are difficult to parse visually\nconst HEATMAP_DISTRIBUTION_SIZE = 5;\n\nconst HEATMAP_SQUARE_SIZE = 10;\nconst HEATMAP_GUTTER_SIZE = 2;\n\nconst DEFAULT_CHAR_WIDTH = 7;\n\nconst TOOLTIP_POINTER_TRIANGLE_HEIGHT = 5;\n\nconst DEFAULT_CHART_COLORS = ['light-blue', 'blue', 'violet', 'red', 'orange',\n\t'yellow', 'green', 'light-green', 'purple', 'magenta', 'light-grey', 'dark-grey'];\nconst HEATMAP_COLORS_GREEN = ['#ebedf0', '#c6e48b', '#7bc96f', '#239a3b', '#196127'];\n\n\n\nconst DEFAULT_COLORS = {\n\tbar: DEFAULT_CHART_COLORS,\n\tline: DEFAULT_CHART_COLORS,\n\tpie: DEFAULT_CHART_COLORS,\n\tpercentage: DEFAULT_CHART_COLORS,\n\theatmap: HEATMAP_COLORS_GREEN\n};\n\n// Universal constants\nconst ANGLE_RATIO = Math.PI / 180;\nconst FULL_ANGLE = 360;\n\nclass SvgTip {\n\tconstructor({\n\t\tparent = null,\n\t\tcolors = []\n\t}) {\n\t\tthis.parent = parent;\n\t\tthis.colors = colors;\n\t\tthis.titleName = '';\n\t\tthis.titleValue = '';\n\t\tthis.listValues = [];\n\t\tthis.titleValueFirst = 0;\n\n\t\tthis.x = 0;\n\t\tthis.y = 0;\n\n\t\tthis.top = 0;\n\t\tthis.left = 0;\n\n\t\tthis.setup();\n\t}\n\n\tsetup() {\n\t\tthis.makeTooltip();\n\t}\n\n\trefresh() {\n\t\tthis.fill();\n\t\tthis.calcPosition();\n\t}\n\n\tmakeTooltip() {\n\t\tthis.container = $.create('div', {\n\t\t\tinside: this.parent,\n\t\t\tclassName: 'graph-svg-tip comparison',\n\t\t\tinnerHTML: `<span class=\"title\"></span>\n\t\t\t\t<ul class=\"data-point-list\"></ul>\n\t\t\t\t<div class=\"svg-pointer\"></div>`\n\t\t});\n\t\tthis.hideTip();\n\n\t\tthis.title = this.container.querySelector('.title');\n\t\tthis.dataPointList = this.container.querySelector('.data-point-list');\n\n\t\tthis.parent.addEventListener('mouseleave', () => {\n\t\t\tthis.hideTip();\n\t\t});\n\t}\n\n\tfill() {\n\t\tlet title;\n\t\tif(this.index) {\n\t\t\tthis.container.setAttribute('data-point-index', this.index);\n\t\t}\n\t\tif(this.titleValueFirst) {\n\t\t\ttitle = `<strong>${this.titleValue}</strong>${this.titleName}`;\n\t\t} else {\n\t\t\ttitle = `${this.titleName}<strong>${this.titleValue}</strong>`;\n\t\t}\n\t\tthis.title.innerHTML = title;\n\t\tthis.dataPointList.innerHTML = '';\n\n\t\tthis.listValues.map((set, i) => {\n\t\t\tconst color = this.colors[i] || 'black';\n\t\t\tlet value = set.formatted === 0 || set.formatted ? set.formatted : set.value;\n\n\t\t\tlet li = $.create('li', {\n\t\t\t\tstyles: {\n\t\t\t\t\t'border-top': `3px solid ${color}`\n\t\t\t\t},\n\t\t\t\tinnerHTML: `<strong style=\"display: block;\">${ value === 0 || value ? value : '' }</strong>\n\t\t\t\t\t${set.title ? set.title : '' }`\n\t\t\t});\n\n\t\t\tthis.dataPointList.appendChild(li);\n\t\t});\n\t}\n\n\tcalcPosition() {\n\t\tlet width = this.container.offsetWidth;\n\n\t\tthis.top = this.y - this.container.offsetHeight\n\t\t\t- TOOLTIP_POINTER_TRIANGLE_HEIGHT;\n\t\tthis.left = this.x - width/2;\n\t\tlet maxLeft = this.parent.offsetWidth - width;\n\n\t\tlet pointer = this.container.querySelector('.svg-pointer');\n\n\t\tif(this.left < 0) {\n\t\t\tpointer.style.left = `calc(50% - ${-1 * this.left}px)`;\n\t\t\tthis.left = 0;\n\t\t} else if(this.left > maxLeft) {\n\t\t\tlet delta = this.left - maxLeft;\n\t\t\tlet pointerOffset = `calc(50% + ${delta}px)`;\n\t\t\tpointer.style.left = pointerOffset;\n\n\t\t\tthis.left = maxLeft;\n\t\t} else {\n\t\t\tpointer.style.left = `50%`;\n\t\t}\n\t}\n\n\tsetValues(x, y, title = {}, listValues = [], index = -1) {\n\t\tthis.titleName = title.name;\n\t\tthis.titleValue = title.value;\n\t\tthis.listValues = listValues;\n\t\tthis.x = x;\n\t\tthis.y = y;\n\t\tthis.titleValueFirst = title.valueFirst || 0;\n\t\tthis.index = index;\n\t\tthis.refresh();\n\t}\n\n\thideTip() {\n\t\tthis.container.style.top = '0px';\n\t\tthis.container.style.left = '0px';\n\t\tthis.container.style.opacity = '0';\n\t}\n\n\tshowTip() {\n\t\tthis.container.style.top = this.top + 'px';\n\t\tthis.container.style.left = this.left + 'px';\n\t\tthis.container.style.opacity = '1';\n\t}\n}\n\nfunction floatTwo(d) {\n\treturn parseFloat(d.toFixed(2));\n}\n\n/**\n * Returns whether or not two given arrays are equal.\n * @param {Array} arr1 First array\n * @param {Array} arr2 Second array\n */\n\n\n/**\n * Shuffles array in place. ES6 version\n * @param {Array} array An array containing the items.\n */\n\n\n/**\n * Fill an array with extra points\n * @param {Array} array Array\n * @param {Number} count number of filler elements\n * @param {Object} element element to fill with\n * @param {Boolean} start fill at start?\n */\nfunction fillArray(array, count, element, start=false) {\n\tif(!element) {\n\t\telement = start ? array[0] : array[array.length - 1];\n\t}\n\tlet fillerArray = new Array(Math.abs(count)).fill(element);\n\tarray = start ? fillerArray.concat(array) : array.concat(fillerArray);\n\treturn array;\n}\n\n/**\n * Returns pixel width of string.\n * @param {String} string\n * @param {Number} charWidth Width of single char in pixels\n */\nfunction getStringWidth(string, charWidth) {\n\treturn (string+\"\").length * charWidth;\n}\n\n\n\n// https://stackoverflow.com/a/29325222\n\n\nfunction getPositionByAngle(angle, radius) {\n\treturn {\n\t\tx: Math.sin(angle * ANGLE_RATIO) * radius,\n\t\ty: Math.cos(angle * ANGLE_RATIO) * radius,\n\t};\n}\n\nfunction getBarHeightAndYAttr(yTop, zeroLine) {\n\tlet height, y;\n\tif (yTop <= zeroLine) {\n\t\theight = zeroLine - yTop;\n\t\ty = yTop;\n\t} else {\n\t\theight = yTop - zeroLine;\n\t\ty = zeroLine;\n\t}\n\n\treturn [height, y];\n}\n\nfunction equilizeNoOfElements(array1, array2,\n\textraCount = array2.length - array1.length) {\n\n\t// Doesn't work if either has zero elements.\n\tif(extraCount > 0) {\n\t\tarray1 = fillArray(array1, extraCount);\n\t} else {\n\t\tarray2 = fillArray(array2, extraCount);\n\t}\n\treturn [array1, array2];\n}\n\nconst PRESET_COLOR_MAP = {\n\t'light-blue': '#7cd6fd',\n\t'blue': '#5e64ff',\n\t'violet': '#743ee2',\n\t'red': '#ff5858',\n\t'orange': '#ffa00a',\n\t'yellow': '#feef72',\n\t'green': '#28a745',\n\t'light-green': '#98d85b',\n\t'purple': '#b554ff',\n\t'magenta': '#ffa3ef',\n\t'black': '#36114C',\n\t'grey': '#bdd3e6',\n\t'light-grey': '#f0f4f7',\n\t'dark-grey': '#b8c2cc'\n};\n\nfunction limitColor(r){\n\tif (r > 255) return 255;\n\telse if (r < 0) return 0;\n\treturn r;\n}\n\nfunction lightenDarkenColor(color, amt) {\n\tlet col = getColor(color);\n\tlet usePound = false;\n\tif (col[0] == \"#\") {\n\t\tcol = col.slice(1);\n\t\tusePound = true;\n\t}\n\tlet num = parseInt(col,16);\n\tlet r = limitColor((num >> 16) + amt);\n\tlet b = limitColor(((num >> 8) & 0x00FF) + amt);\n\tlet g = limitColor((num & 0x0000FF) + amt);\n\treturn (usePound?\"#\":\"\") + (g | (b << 8) | (r << 16)).toString(16);\n}\n\nfunction isValidColor(string) {\n\t// https://stackoverflow.com/a/8027444/6495043\n\treturn /(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)/i.test(string);\n}\n\nconst getColor = (color) => {\n\treturn PRESET_COLOR_MAP[color] || color;\n};\n\nconst AXIS_TICK_LENGTH = 6;\nconst LABEL_MARGIN = 4;\nconst FONT_SIZE = 10;\nconst BASE_LINE_COLOR = '#dadada';\nconst FONT_FILL = '#555b51';\n\nfunction $$1(expr, con) {\n\treturn typeof expr === \"string\"? (con || document).querySelector(expr) : expr || null;\n}\n\nfunction createSVG(tag, o) {\n\tvar element = document.createElementNS(\"http://www.w3.org/2000/svg\", tag);\n\n\tfor (var i in o) {\n\t\tvar val = o[i];\n\n\t\tif (i === \"inside\") {\n\t\t\t$$1(val).appendChild(element);\n\t\t}\n\t\telse if (i === \"around\") {\n\t\t\tvar ref = $$1(val);\n\t\t\tref.parentNode.insertBefore(element, ref);\n\t\t\telement.appendChild(ref);\n\n\t\t} else if (i === \"styles\") {\n\t\t\tif(typeof val === \"object\") {\n\t\t\t\tObject.keys(val).map(prop => {\n\t\t\t\t\telement.style[prop] = val[prop];\n\t\t\t\t});\n\t\t\t}\n\t\t} else {\n\t\t\tif(i === \"className\") { i = \"class\"; }\n\t\t\tif(i === \"innerHTML\") {\n\t\t\t\telement['textContent'] = val;\n\t\t\t} else {\n\t\t\t\telement.setAttribute(i, val);\n\t\t\t}\n\t\t}\n\t}\n\n\treturn element;\n}\n\nfunction renderVerticalGradient(svgDefElem, gradientId) {\n\treturn createSVG('linearGradient', {\n\t\tinside: svgDefElem,\n\t\tid: gradientId,\n\t\tx1: 0,\n\t\tx2: 0,\n\t\ty1: 0,\n\t\ty2: 1\n\t});\n}\n\nfunction setGradientStop(gradElem, offset, color, opacity) {\n\treturn createSVG('stop', {\n\t\t'inside': gradElem,\n\t\t'style': `stop-color: ${color}`,\n\t\t'offset': offset,\n\t\t'stop-opacity': opacity\n\t});\n}\n\nfunction makeSVGContainer(parent, className, width, height) {\n\treturn createSVG('svg', {\n\t\tclassName: className,\n\t\tinside: parent,\n\t\twidth: width,\n\t\theight: height\n\t});\n}\n\nfunction makeSVGDefs(svgContainer) {\n\treturn createSVG('defs', {\n\t\tinside: svgContainer,\n\t});\n}\n\nfunction makeSVGGroup(className, transform='', parent=undefined) {\n\tlet args = {\n\t\tclassName: className,\n\t\ttransform: transform\n\t};\n\tif(parent) args.inside = parent;\n\treturn createSVG('g', args);\n}\n\n\n\nfunction makePath(pathStr, className='', stroke='none', fill='none') {\n\treturn createSVG('path', {\n\t\tclassName: className,\n\t\td: pathStr,\n\t\tstyles: {\n\t\t\tstroke: stroke,\n\t\t\tfill: fill\n\t\t}\n\t});\n}\n\nfunction makeArcPathStr(startPosition, endPosition, center, radius, clockWise=1){\n\tlet [arcStartX, arcStartY] = [center.x + startPosition.x, center.y + startPosition.y];\n\tlet [arcEndX, arcEndY] = [center.x + endPosition.x, center.y + endPosition.y];\n\n\treturn `M${center.x} ${center.y}\n\t\tL${arcStartX} ${arcStartY}\n\t\tA ${radius} ${radius} 0 0 ${clockWise ? 1 : 0}\n\t\t${arcEndX} ${arcEndY} z`;\n}\n\nfunction makeGradient(svgDefElem, color, lighter = false) {\n\tlet gradientId ='path-fill-gradient' + '-' + color + '-' +(lighter ? 'lighter' : 'default');\n\tlet gradientDef = renderVerticalGradient(svgDefElem, gradientId);\n\tlet opacities = [1, 0.6, 0.2];\n\tif(lighter) {\n\t\topacities = [0.4, 0.2, 0];\n\t}\n\n\tsetGradientStop(gradientDef, \"0%\", color, opacities[0]);\n\tsetGradientStop(gradientDef, \"50%\", color, opacities[1]);\n\tsetGradientStop(gradientDef, \"100%\", color, opacities[2]);\n\n\treturn gradientId;\n}\n\nfunction percentageBar(x, y, width, height,\n\tdepth=PERCENTAGE_BAR_DEFAULT_DEPTH, fill='none') {\n\n\tlet args = {\n\t\tclassName: 'percentage-bar',\n\t\tx: x,\n\t\ty: y,\n\t\twidth: width,\n\t\theight: height,\n\t\tfill: fill,\n\t\tstyles: {\n\t\t\t'stroke': lightenDarkenColor(fill, -25),\n\t\t\t// Diabolically good: https://stackoverflow.com/a/9000859\n\t\t\t// https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/stroke-dasharray\n\t\t\t'stroke-dasharray': `0, ${height + width}, ${width}, ${height}`,\n\t\t\t'stroke-width': depth\n\t\t},\n\t};\n\n\treturn createSVG(\"rect\", args);\n}\n\nfunction heatSquare(className, x, y, size, fill='none', data={}) {\n\tlet args = {\n\t\tclassName: className,\n\t\tx: x,\n\t\ty: y,\n\t\twidth: size,\n\t\theight: size,\n\t\tfill: fill\n\t};\n\n\tObject.keys(data).map(key => {\n\t\targs[key] = data[key];\n\t});\n\n\treturn createSVG(\"rect\", args);\n}\n\nfunction legendBar(x, y, size, fill='none', label) {\n\tlet args = {\n\t\tclassName: 'legend-bar',\n\t\tx: 0,\n\t\ty: 0,\n\t\twidth: size,\n\t\theight: '2px',\n\t\tfill: fill\n\t};\n\tlet text = createSVG('text', {\n\t\tclassName: 'legend-dataset-text',\n\t\tx: 0,\n\t\ty: 0,\n\t\tdy: (FONT_SIZE * 2) + 'px',\n\t\t'font-size': (FONT_SIZE * 1.2) + 'px',\n\t\t'text-anchor': 'start',\n\t\tfill: FONT_FILL,\n\t\tinnerHTML: label\n\t});\n\n\tlet group = createSVG('g', {\n\t\ttransform: `translate(${x}, ${y})`\n\t});\n\tgroup.appendChild(createSVG(\"rect\", args));\n\tgroup.appendChild(text);\n\n\treturn group;\n}\n\nfunction legendDot(x, y, size, fill='none', label) {\n\tlet args = {\n\t\tclassName: 'legend-dot',\n\t\tcx: 0,\n\t\tcy: 0,\n\t\tr: size,\n\t\tfill: fill\n\t};\n\tlet text = createSVG('text', {\n\t\tclassName: 'legend-dataset-text',\n\t\tx: 0,\n\t\ty: 0,\n\t\tdx: (FONT_SIZE) + 'px',\n\t\tdy: (FONT_SIZE/3) + 'px',\n\t\t'font-size': (FONT_SIZE * 1.2) + 'px',\n\t\t'text-anchor': 'start',\n\t\tfill: FONT_FILL,\n\t\tinnerHTML: label\n\t});\n\n\tlet group = createSVG('g', {\n\t\ttransform: `translate(${x}, ${y})`\n\t});\n\tgroup.appendChild(createSVG(\"circle\", args));\n\tgroup.appendChild(text);\n\n\treturn group;\n}\n\nfunction makeText(className, x, y, content, options = {}) {\n\tlet fontSize = options.fontSize || FONT_SIZE;\n\tlet dy = options.dy !== undefined ? options.dy : (fontSize / 2);\n\tlet fill = options.fill || FONT_FILL;\n\tlet textAnchor = options.textAnchor || 'start';\n\treturn createSVG('text', {\n\t\tclassName: className,\n\t\tx: x,\n\t\ty: y,\n\t\tdy: dy + 'px',\n\t\t'font-size': fontSize + 'px',\n\t\tfill: fill,\n\t\t'text-anchor': textAnchor,\n\t\tinnerHTML: content\n\t});\n}\n\nfunction makeVertLine(x, label, y1, y2, options={}) {\n\tif(!options.stroke) options.stroke = BASE_LINE_COLOR;\n\tlet l = createSVG('line', {\n\t\tclassName: 'line-vertical ' + options.className,\n\t\tx1: 0,\n\t\tx2: 0,\n\t\ty1: y1,\n\t\ty2: y2,\n\t\tstyles: {\n\t\t\tstroke: options.stroke\n\t\t}\n\t});\n\n\tlet text = createSVG('text', {\n\t\tx: 0,\n\t\ty: y1 > y2 ? y1 + LABEL_MARGIN : y1 - LABEL_MARGIN - FONT_SIZE,\n\t\tdy: FONT_SIZE + 'px',\n\t\t'font-size': FONT_SIZE + 'px',\n\t\t'text-anchor': 'middle',\n\t\tinnerHTML: label + \"\"\n\t});\n\n\tlet line = createSVG('g', {\n\t\ttransform: `translate(${ x }, 0)`\n\t});\n\n\tline.appendChild(l);\n\tline.appendChild(text);\n\n\treturn line;\n}\n\nfunction makeHoriLine(y, label, x1, x2, options={}) {\n\tif(!options.stroke) options.stroke = BASE_LINE_COLOR;\n\tif(!options.lineType) options.lineType = '';\n\tlet className = 'line-horizontal ' + options.className +\n\t\t(options.lineType === \"dashed\" ? \"dashed\": \"\");\n\n\tlet l = createSVG('line', {\n\t\tclassName: className,\n\t\tx1: x1,\n\t\tx2: x2,\n\t\ty1: 0,\n\t\ty2: 0,\n\t\tstyles: {\n\t\t\tstroke: options.stroke\n\t\t}\n\t});\n\n\tlet text = createSVG('text', {\n\t\tx: x1 < x2 ? x1 - LABEL_MARGIN : x1 + LABEL_MARGIN,\n\t\ty: 0,\n\t\tdy: (FONT_SIZE / 2 - 2) + 'px',\n\t\t'font-size': FONT_SIZE + 'px',\n\t\t'text-anchor': x1 < x2 ? 'end' : 'start',\n\t\tinnerHTML: label+\"\"\n\t});\n\n\tlet line = createSVG('g', {\n\t\ttransform: `translate(0, ${y})`,\n\t\t'stroke-opacity': 1\n\t});\n\n\tif(text === 0 || text === '0') {\n\t\tline.style.stroke = \"rgba(27, 31, 35, 0.6)\";\n\t}\n\n\tline.appendChild(l);\n\tline.appendChild(text);\n\n\treturn line;\n}\n\nfunction yLine(y, label, width, options={}) {\n\tif(!options.pos) options.pos = 'left';\n\tif(!options.offset) options.offset = 0;\n\tif(!options.mode) options.mode = 'span';\n\tif(!options.stroke) options.stroke = BASE_LINE_COLOR;\n\tif(!options.className) options.className = '';\n\n\tlet x1 = -1 * AXIS_TICK_LENGTH;\n\tlet x2 = options.mode === 'span' ? width + AXIS_TICK_LENGTH : 0;\n\n\tif(options.mode === 'tick' && options.pos === 'right') {\n\t\tx1 = width + AXIS_TICK_LENGTH;\n\t\tx2 = width;\n\t}\n\n\t// let offset = options.pos === 'left' ? -1 * options.offset : options.offset;\n\n\tx1 += options.offset;\n\tx2 += options.offset;\n\n\treturn makeHoriLine(y, label, x1, x2, {\n\t\tstroke: options.stroke,\n\t\tclassName: options.className,\n\t\tlineType: options.lineType\n\t});\n}\n\nfunction xLine(x, label, height, options={}) {\n\tif(!options.pos) options.pos = 'bottom';\n\tif(!options.offset) options.offset = 0;\n\tif(!options.mode) options.mode = 'span';\n\tif(!options.stroke) options.stroke = BASE_LINE_COLOR;\n\tif(!options.className) options.className = '';\n\n\t// Draw X axis line in span/tick mode with optional label\n\t// \ty2(span)\n\t// \t\t\t\t\t\t|\n\t// \t\t\t\t\t\t|\n\t//\t\t\t\tx line\t|\n\t//\t\t\t\t\t\t|\n\t// \t\t\t\t\t \t|\n\t// ---------------------+-- y2(tick)\n\t//\t\t\t\t\t\t|\n\t//\t\t\t\t\t\t\ty1\n\n\tlet y1 = height + AXIS_TICK_LENGTH;\n\tlet y2 = options.mode === 'span' ? -1 * AXIS_TICK_LENGTH : height;\n\n\tif(options.mode === 'tick' && options.pos === 'top') {\n\t\t// top axis ticks\n\t\ty1 = -1 * AXIS_TICK_LENGTH;\n\t\ty2 = 0;\n\t}\n\n\treturn makeVertLine(x, label, y1, y2, {\n\t\tstroke: options.stroke,\n\t\tclassName: options.className,\n\t\tlineType: options.lineType\n\t});\n}\n\nfunction yMarker(y, label, width, options={}) {\n\tif(!options.labelPos) options.labelPos = 'right';\n\tlet x = options.labelPos === 'left' ? LABEL_MARGIN\n\t\t: width - getStringWidth(label, 5) - LABEL_MARGIN;\n\n\tlet labelSvg = createSVG('text', {\n\t\tclassName: 'chart-label',\n\t\tx: x,\n\t\ty: 0,\n\t\tdy: (FONT_SIZE / -2) + 'px',\n\t\t'font-size': FONT_SIZE + 'px',\n\t\t'text-anchor': 'start',\n\t\tinnerHTML: label+\"\"\n\t});\n\n\tlet line = makeHoriLine(y, '', 0, width, {\n\t\tstroke: options.stroke || BASE_LINE_COLOR,\n\t\tclassName: options.className || '',\n\t\tlineType: options.lineType\n\t});\n\n\tline.appendChild(labelSvg);\n\n\treturn line;\n}\n\nfunction yRegion(y1, y2, width, label, options={}) {\n\t// return a group\n\tlet height = y1 - y2;\n\n\tlet rect = createSVG('rect', {\n\t\tclassName: `bar mini`, // remove class\n\t\tstyles: {\n\t\t\tfill: `rgba(228, 234, 239, 0.49)`,\n\t\t\tstroke: BASE_LINE_COLOR,\n\t\t\t'stroke-dasharray': `${width}, ${height}`\n\t\t},\n\t\t// 'data-point-index': index,\n\t\tx: 0,\n\t\ty: 0,\n\t\twidth: width,\n\t\theight: height\n\t});\n\n\tif(!options.labelPos) options.labelPos = 'right';\n\tlet x = options.labelPos === 'left' ? LABEL_MARGIN\n\t\t: width - getStringWidth(label+\"\", 4.5) - LABEL_MARGIN;\n\n\tlet labelSvg = createSVG('text', {\n\t\tclassName: 'chart-label',\n\t\tx: x,\n\t\ty: 0,\n\t\tdy: (FONT_SIZE / -2) + 'px',\n\t\t'font-size': FONT_SIZE + 'px',\n\t\t'text-anchor': 'start',\n\t\tinnerHTML: label+\"\"\n\t});\n\n\tlet region = createSVG('g', {\n\t\ttransform: `translate(0, ${y2})`\n\t});\n\n\tregion.appendChild(rect);\n\tregion.appendChild(labelSvg);\n\n\treturn region;\n}\n\nfunction datasetBar(x, yTop, width, color, label='', index=0, offset=0, meta={}) {\n\tlet [height, y] = getBarHeightAndYAttr(yTop, meta.zeroLine);\n\ty -= offset;\n\n\tif(height === 0) {\n\t\theight = meta.minHeight;\n\t\ty -= meta.minHeight;\n\t}\n\n\tlet rect = createSVG('rect', {\n\t\tclassName: `bar mini`,\n\t\tstyle: `fill: ${color}`,\n\t\t'data-point-index': index,\n\t\tx: x,\n\t\ty: y,\n\t\twidth: width,\n\t\theight: height\n\t});\n\n\tlabel += \"\";\n\n\tif(!label && !label.length) {\n\t\treturn rect;\n\t} else {\n\t\trect.setAttribute('y', 0);\n\t\trect.setAttribute('x', 0);\n\t\tlet text = createSVG('text', {\n\t\t\tclassName: 'data-point-value',\n\t\t\tx: width/2,\n\t\t\ty: 0,\n\t\t\tdy: (FONT_SIZE / 2 * -1) + 'px',\n\t\t\t'font-size': FONT_SIZE + 'px',\n\t\t\t'text-anchor': 'middle',\n\t\t\tinnerHTML: label\n\t\t});\n\n\t\tlet group = createSVG('g', {\n\t\t\t'data-point-index': index,\n\t\t\ttransform: `translate(${x}, ${y})`\n\t\t});\n\t\tgroup.appendChild(rect);\n\t\tgroup.appendChild(text);\n\n\t\treturn group;\n\t}\n}\n\nfunction datasetDot(x, y, radius, color, label='', index=0) {\n\tlet dot = createSVG('circle', {\n\t\tstyle: `fill: ${color}`,\n\t\t'data-point-index': index,\n\t\tcx: x,\n\t\tcy: y,\n\t\tr: radius\n\t});\n\n\tlabel += \"\";\n\n\tif(!label && !label.length) {\n\t\treturn dot;\n\t} else {\n\t\tdot.setAttribute('cy', 0);\n\t\tdot.setAttribute('cx', 0);\n\n\t\tlet text = createSVG('text', {\n\t\t\tclassName: 'data-point-value',\n\t\t\tx: 0,\n\t\t\ty: 0,\n\t\t\tdy: (FONT_SIZE / 2 * -1 - radius) + 'px',\n\t\t\t'font-size': FONT_SIZE + 'px',\n\t\t\t'text-anchor': 'middle',\n\t\t\tinnerHTML: label\n\t\t});\n\n\t\tlet group = createSVG('g', {\n\t\t\t'data-point-index': index,\n\t\t\ttransform: `translate(${x}, ${y})`\n\t\t});\n\t\tgroup.appendChild(dot);\n\t\tgroup.appendChild(text);\n\n\t\treturn group;\n\t}\n}\n\nfunction getPaths(xList, yList, color, options={}, meta={}) {\n\tlet pointsList = yList.map((y, i) => (xList[i] + ',' + y));\n\tlet pointsStr = pointsList.join(\"L\");\n\tlet path = makePath(\"M\"+pointsStr, 'line-graph-path', color);\n\n\t// HeatLine\n\tif(options.heatline) {\n\t\tlet gradient_id = makeGradient(meta.svgDefs, color);\n\t\tpath.style.stroke = `url(#${gradient_id})`;\n\t}\n\n\tlet paths = {\n\t\tpath: path\n\t};\n\n\t// Region\n\tif(options.regionFill) {\n\t\tlet gradient_id_region = makeGradient(meta.svgDefs, color, true);\n\n\t\tlet pathStr = \"M\" + `${xList[0]},${meta.zeroLine}L` + pointsStr + `L${xList.slice(-1)[0]},${meta.zeroLine}`;\n\t\tpaths.region = makePath(pathStr, `region-fill`, 'none', `url(#${gradient_id_region})`);\n\t}\n\n\treturn paths;\n}\n\nlet makeOverlay = {\n\t'bar': (unit) => {\n\t\tlet transformValue;\n\t\tif(unit.nodeName !== 'rect') {\n\t\t\ttransformValue = unit.getAttribute('transform');\n\t\t\tunit = unit.childNodes[0];\n\t\t}\n\t\tlet overlay = unit.cloneNode();\n\t\toverlay.style.fill = '#000000';\n\t\toverlay.style.opacity = '0.4';\n\n\t\tif(transformValue) {\n\t\t\toverlay.setAttribute('transform', transformValue);\n\t\t}\n\t\treturn overlay;\n\t},\n\n\t'dot': (unit) => {\n\t\tlet transformValue;\n\t\tif(unit.nodeName !== 'circle') {\n\t\t\ttransformValue = unit.getAttribute('transform');\n\t\t\tunit = unit.childNodes[0];\n\t\t}\n\t\tlet overlay = unit.cloneNode();\n\t\tlet radius = unit.getAttribute('r');\n\t\tlet fill = unit.getAttribute('fill');\n\t\toverlay.setAttribute('r', parseInt(radius) + DOT_OVERLAY_SIZE_INCR);\n\t\toverlay.setAttribute('fill', fill);\n\t\toverlay.style.opacity = '0.6';\n\n\t\tif(transformValue) {\n\t\t\toverlay.setAttribute('transform', transformValue);\n\t\t}\n\t\treturn overlay;\n\t},\n\n\t'heat_square': (unit) => {\n\t\tlet transformValue;\n\t\tif(unit.nodeName !== 'circle') {\n\t\t\ttransformValue = unit.getAttribute('transform');\n\t\t\tunit = unit.childNodes[0];\n\t\t}\n\t\tlet overlay = unit.cloneNode();\n\t\tlet radius = unit.getAttribute('r');\n\t\tlet fill = unit.getAttribute('fill');\n\t\toverlay.setAttribute('r', parseInt(radius) + DOT_OVERLAY_SIZE_INCR);\n\t\toverlay.setAttribute('fill', fill);\n\t\toverlay.style.opacity = '0.6';\n\n\t\tif(transformValue) {\n\t\t\toverlay.setAttribute('transform', transformValue);\n\t\t}\n\t\treturn overlay;\n\t}\n};\n\nlet updateOverlay = {\n\t'bar': (unit, overlay) => {\n\t\tlet transformValue;\n\t\tif(unit.nodeName !== 'rect') {\n\t\t\ttransformValue = unit.getAttribute('transform');\n\t\t\tunit = unit.childNodes[0];\n\t\t}\n\t\tlet attributes = ['x', 'y', 'width', 'height'];\n\t\tObject.values(unit.attributes)\n\t\t\t.filter(attr => attributes.includes(attr.name) && attr.specified)\n\t\t\t.map(attr => {\n\t\t\t\toverlay.setAttribute(attr.name, attr.nodeValue);\n\t\t\t});\n\n\t\tif(transformValue) {\n\t\t\toverlay.setAttribute('transform', transformValue);\n\t\t}\n\t},\n\n\t'dot': (unit, overlay) => {\n\t\tlet transformValue;\n\t\tif(unit.nodeName !== 'circle') {\n\t\t\ttransformValue = unit.getAttribute('transform');\n\t\t\tunit = unit.childNodes[0];\n\t\t}\n\t\tlet attributes = ['cx', 'cy'];\n\t\tObject.values(unit.attributes)\n\t\t\t.filter(attr => attributes.includes(attr.name) && attr.specified)\n\t\t\t.map(attr => {\n\t\t\t\toverlay.setAttribute(attr.name, attr.nodeValue);\n\t\t\t});\n\n\t\tif(transformValue) {\n\t\t\toverlay.setAttribute('transform', transformValue);\n\t\t}\n\t},\n\n\t'heat_square': (unit, overlay) => {\n\t\tlet transformValue;\n\t\tif(unit.nodeName !== 'circle') {\n\t\t\ttransformValue = unit.getAttribute('transform');\n\t\t\tunit = unit.childNodes[0];\n\t\t}\n\t\tlet attributes = ['cx', 'cy'];\n\t\tObject.values(unit.attributes)\n\t\t\t.filter(attr => attributes.includes(attr.name) && attr.specified)\n\t\t\t.map(attr => {\n\t\t\t\toverlay.setAttribute(attr.name, attr.nodeValue);\n\t\t\t});\n\n\t\tif(transformValue) {\n\t\t\toverlay.setAttribute('transform', transformValue);\n\t\t}\n\t},\n};\n\nconst UNIT_ANIM_DUR = 350;\nconst PATH_ANIM_DUR = 350;\nconst MARKER_LINE_ANIM_DUR = UNIT_ANIM_DUR;\nconst REPLACE_ALL_NEW_DUR = 250;\n\nconst STD_EASING = 'easein';\n\nfunction translate(unit, oldCoord, newCoord, duration) {\n\tlet old = typeof oldCoord === 'string' ? oldCoord : oldCoord.join(', ');\n\treturn [\n\t\tunit,\n\t\t{transform: newCoord.join(', ')},\n\t\tduration,\n\t\tSTD_EASING,\n\t\t\"translate\",\n\t\t{transform: old}\n\t];\n}\n\nfunction translateVertLine(xLine, newX, oldX) {\n\treturn translate(xLine, [oldX, 0], [newX, 0], MARKER_LINE_ANIM_DUR);\n}\n\nfunction translateHoriLine(yLine, newY, oldY) {\n\treturn translate(yLine, [0, oldY], [0, newY], MARKER_LINE_ANIM_DUR);\n}\n\nfunction animateRegion(rectGroup, newY1, newY2, oldY2) {\n\tlet newHeight = newY1 - newY2;\n\tlet rect = rectGroup.childNodes[0];\n\tlet width = rect.getAttribute(\"width\");\n\tlet rectAnim = [\n\t\trect,\n\t\t{ height: newHeight, 'stroke-dasharray': `${width}, ${newHeight}` },\n\t\tMARKER_LINE_ANIM_DUR,\n\t\tSTD_EASING\n\t];\n\n\tlet groupAnim = translate(rectGroup, [0, oldY2], [0, newY2], MARKER_LINE_ANIM_DUR);\n\treturn [rectAnim, groupAnim];\n}\n\nfunction animateBar(bar, x, yTop, width, offset=0, meta={}) {\n\tlet [height, y] = getBarHeightAndYAttr(yTop, meta.zeroLine);\n\ty -= offset;\n\tif(bar.nodeName !== 'rect') {\n\t\tlet rect = bar.childNodes[0];\n\t\tlet rectAnim = [\n\t\t\trect,\n\t\t\t{width: width, height: height},\n\t\t\tUNIT_ANIM_DUR,\n\t\t\tSTD_EASING\n\t\t];\n\n\t\tlet oldCoordStr = bar.getAttribute(\"transform\").split(\"(\")[1].slice(0, -1);\n\t\tlet groupAnim = translate(bar, oldCoordStr, [x, y], MARKER_LINE_ANIM_DUR);\n\t\treturn [rectAnim, groupAnim];\n\t} else {\n\t\treturn [[bar, {width: width, height: height, x: x, y: y}, UNIT_ANIM_DUR, STD_EASING]];\n\t}\n\t// bar.animate({height: args.newHeight, y: yTop}, UNIT_ANIM_DUR, mina.easein);\n}\n\nfunction animateDot(dot, x, y) {\n\tif(dot.nodeName !== 'circle') {\n\t\tlet oldCoordStr = dot.getAttribute(\"transform\").split(\"(\")[1].slice(0, -1);\n\t\tlet groupAnim = translate(dot, oldCoordStr, [x, y], MARKER_LINE_ANIM_DUR);\n\t\treturn [groupAnim];\n\t} else {\n\t\treturn [[dot, {cx: x, cy: y}, UNIT_ANIM_DUR, STD_EASING]];\n\t}\n\t// dot.animate({cy: yTop}, UNIT_ANIM_DUR, mina.easein);\n}\n\nfunction animatePath(paths, newXList, newYList, zeroLine) {\n\tlet pathComponents = [];\n\n\tlet pointsStr = newYList.map((y, i) => (newXList[i] + ',' + y));\n\tlet pathStr = pointsStr.join(\"L\");\n\n\tconst animPath = [paths.path, {d:\"M\"+pathStr}, PATH_ANIM_DUR, STD_EASING];\n\tpathComponents.push(animPath);\n\n\tif(paths.region) {\n\t\tlet regStartPt = `${newXList[0]},${zeroLine}L`;\n\t\tlet regEndPt = `L${newXList.slice(-1)[0]}, ${zeroLine}`;\n\n\t\tconst animRegion = [\n\t\t\tpaths.region,\n\t\t\t{d:\"M\" + regStartPt + pathStr + regEndPt},\n\t\t\tPATH_ANIM_DUR,\n\t\t\tSTD_EASING\n\t\t];\n\t\tpathComponents.push(animRegion);\n\t}\n\n\treturn pathComponents;\n}\n\nfunction animatePathStr(oldPath, pathStr) {\n\treturn [oldPath, {d: pathStr}, UNIT_ANIM_DUR, STD_EASING];\n}\n\n// Leveraging SMIL Animations\n\nconst EASING = {\n\tease: \"0.25 0.1 0.25 1\",\n\tlinear: \"0 0 1 1\",\n\t// easein: \"0.42 0 1 1\",\n\teasein: \"0.1 0.8 0.2 1\",\n\teaseout: \"0 0 0.58 1\",\n\teaseinout: \"0.42 0 0.58 1\"\n};\n\nfunction animateSVGElement(element, props, dur, easingType=\"linear\", type=undefined, oldValues={}) {\n\n\tlet animElement = element.cloneNode(true);\n\tlet newElement = element.cloneNode(true);\n\n\tfor(var attributeName in props) {\n\t\tlet animateElement;\n\t\tif(attributeName === 'transform') {\n\t\t\tanimateElement = document.createElementNS(\"http://www.w3.org/2000/svg\", \"animateTransform\");\n\t\t} else {\n\t\t\tanimateElement = document.createElementNS(\"http://www.w3.org/2000/svg\", \"animate\");\n\t\t}\n\t\tlet currentValue = oldValues[attributeName] || element.getAttribute(attributeName);\n\t\tlet value = props[attributeName];\n\n\t\tlet animAttr = {\n\t\t\tattributeName: attributeName,\n\t\t\tfrom: currentValue,\n\t\t\tto: value,\n\t\t\tbegin: \"0s\",\n\t\t\tdur: dur/1000 + \"s\",\n\t\t\tvalues: currentValue + \";\" + value,\n\t\t\tkeySplines: EASING[easingType],\n\t\t\tkeyTimes: \"0;1\",\n\t\t\tcalcMode: \"spline\",\n\t\t\tfill: 'freeze'\n\t\t};\n\n\t\tif(type) {\n\t\t\tanimAttr[\"type\"] = type;\n\t\t}\n\n\t\tfor (var i in animAttr) {\n\t\t\tanimateElement.setAttribute(i, animAttr[i]);\n\t\t}\n\n\t\tanimElement.appendChild(animateElement);\n\n\t\tif(type) {\n\t\t\tnewElement.setAttribute(attributeName, `translate(${value})`);\n\t\t} else {\n\t\t\tnewElement.setAttribute(attributeName, value);\n\t\t}\n\t}\n\n\treturn [animElement, newElement];\n}\n\nfunction transform(element, style) { // eslint-disable-line no-unused-vars\n\telement.style.transform = style;\n\telement.style.webkitTransform = style;\n\telement.style.msTransform = style;\n\telement.style.mozTransform = style;\n\telement.style.oTransform = style;\n}\n\nfunction animateSVG(svgContainer, elements) {\n\tlet newElements = [];\n\tlet animElements = [];\n\n\telements.map(element => {\n\t\tlet unit = element[0];\n\t\tlet parent = unit.parentNode;\n\n\t\tlet animElement, newElement;\n\n\t\telement[0] = unit;\n\t\t[animElement, newElement] = animateSVGElement(...element);\n\n\t\tnewElements.push(newElement);\n\t\tanimElements.push([animElement, parent]);\n\n\t\tparent.replaceChild(animElement, unit);\n\t});\n\n\tlet animSvg = svgContainer.cloneNode(true);\n\n\tanimElements.map((animElement, i) => {\n\t\tanimElement[1].replaceChild(newElements[i], animElement[0]);\n\t\telements[i][0] = newElements[i];\n\t});\n\n\treturn animSvg;\n}\n\nfunction runSMILAnimation(parent, svgElement, elementsToAnimate) {\n\tif(elementsToAnimate.length === 0) return;\n\n\tlet animSvgElement = animateSVG(svgElement, elementsToAnimate);\n\tif(svgElement.parentNode == parent) {\n\t\tparent.removeChild(svgElement);\n\t\tparent.appendChild(animSvgElement);\n\n\t}\n\n\t// Replace the new svgElement (data has already been replaced)\n\tsetTimeout(() => {\n\t\tif(animSvgElement.parentNode == parent) {\n\t\t\tparent.removeChild(animSvgElement);\n\t\t\tparent.appendChild(svgElement);\n\t\t}\n\t}, REPLACE_ALL_NEW_DUR);\n}\n\nconst CSSTEXT = \".chart-container{position:relative;font-family:-apple-system,BlinkMacSystemFont,'Segoe UI','Roboto','Oxygen','Ubuntu','Cantarell','Fira Sans','Droid Sans','Helvetica Neue',sans-serif}.chart-container .axis,.chart-container .chart-label{fill:#555b51}.chart-container .axis line,.chart-container .chart-label line{stroke:#dadada}.chart-container .dataset-units circle{stroke:#fff;stroke-width:2}.chart-container .dataset-units path{fill:none;stroke-opacity:1;stroke-width:2px}.chart-container .dataset-path{stroke-width:2px}.chart-container .path-group path{fill:none;stroke-opacity:1;stroke-width:2px}.chart-container line.dashed{stroke-dasharray:5,3}.chart-container .axis-line .specific-value{text-anchor:start}.chart-container .axis-line .y-line{text-anchor:end}.chart-container .axis-line .x-line{text-anchor:middle}.chart-container .legend-dataset-text{fill:#6c7680;font-weight:600}.graph-svg-tip{position:absolute;z-index:99999;padding:10px;font-size:12px;color:#959da5;text-align:center;background:rgba(0,0,0,.8);border-radius:3px}.graph-svg-tip ul{padding-left:0;display:flex}.graph-svg-tip ol{padding-left:0;display:flex}.graph-svg-tip ul.data-point-list li{min-width:90px;flex:1;font-weight:600}.graph-svg-tip strong{color:#dfe2e5;font-weight:600}.graph-svg-tip .svg-pointer{position:absolute;height:5px;margin:0 0 0 -5px;content:' ';border:5px solid transparent;border-top-color:rgba(0,0,0,.8)}.graph-svg-tip.comparison{padding:0;text-align:left;pointer-events:none}.graph-svg-tip.comparison .title{display:block;padding:10px;margin:0;font-weight:600;line-height:1;pointer-events:none}.graph-svg-tip.comparison ul{margin:0;white-space:nowrap;list-style:none}.graph-svg-tip.comparison li{display:inline-block;padding:5px 10px}\";\n\nfunction downloadFile(filename, data) {\n\tvar a = document.createElement('a');\n\ta.style = \"display: none\";\n\tvar blob = new Blob(data, {type: \"image/svg+xml; charset=utf-8\"});\n\tvar url = window.URL.createObjectURL(blob);\n\ta.href = url;\n\ta.download = filename;\n\tdocument.body.appendChild(a);\n\ta.click();\n\tsetTimeout(function(){\n\t\tdocument.body.removeChild(a);\n\t\twindow.URL.revokeObjectURL(url);\n\t}, 300);\n}\n\nfunction prepareForExport(svg) {\n\tlet clone = svg.cloneNode(true);\n\tclone.classList.add('chart-container');\n\tclone.setAttribute('xmlns', \"http://www.w3.org/2000/svg\");\n\tclone.setAttribute('xmlns:xlink', \"http://www.w3.org/1999/xlink\");\n\tlet styleEl = $.create('style', {\n\t\t'innerHTML': CSSTEXT\n\t});\n\tclone.insertBefore(styleEl, clone.firstChild);\n\n\tlet container = $.create('div');\n\tcontainer.appendChild(clone);\n\n\treturn container.innerHTML;\n}\n\nlet BOUND_DRAW_FN;\n\nclass BaseChart {\n\tconstructor(parent, options) {\n\n\t\tthis.parent = typeof parent === 'string'\n\t\t\t? document.querySelector(parent)\n\t\t\t: parent;\n\n\t\tif (!(this.parent instanceof HTMLElement)) {\n\t\t\tthrow new Error('No `parent` element to render on was provided.');\n\t\t}\n\n\t\tthis.rawChartArgs = options;\n\n\t\tthis.title = options.title || '';\n\t\tthis.type = options.type || '';\n\n\t\tthis.realData = this.prepareData(options.data);\n\t\tthis.data = this.prepareFirstData(this.realData);\n\n\t\tthis.colors = this.validateColors(options.colors, this.type);\n\n\t\tthis.config = {\n\t\t\tshowTooltip: 1, // calculate\n\t\t\tshowLegend: 1, // calculate\n\t\t\tisNavigable: options.isNavigable || 0,\n\t\t\tanimate: 1\n\t\t};\n\n\t\tthis.measures = JSON.parse(JSON.stringify(BASE_MEASURES));\n\t\tlet m = this.measures;\n\t\tthis.setMeasures(options);\n\t\tif(!this.title.length) { m.titleHeight = 0; }\n\t\tif(!this.config.showLegend) m.legendHeight = 0;\n\t\tthis.argHeight = options.height || m.baseHeight;\n\n\t\tthis.state = {};\n\t\tthis.options = {};\n\n\t\tthis.initTimeout = INIT_CHART_UPDATE_TIMEOUT;\n\n\t\tif(this.config.isNavigable) {\n\t\t\tthis.overlays = [];\n\t\t}\n\n\t\tthis.configure(options);\n\t}\n\n\tprepareData(data) {\n\t\treturn data;\n\t}\n\n\tprepareFirstData(data) {\n\t\treturn data;\n\t}\n\n\tvalidateColors(colors, type) {\n\t\tconst validColors = [];\n\t\tcolors = (colors || []).concat(DEFAULT_COLORS[type]);\n\t\tcolors.forEach((string) => {\n\t\t\tconst color = getColor(string);\n\t\t\tif(!isValidColor(color)) {\n\t\t\t\tconsole.warn('\"' + string + '\" is not a valid color.');\n\t\t\t} else {\n\t\t\t\tvalidColors.push(color);\n\t\t\t}\n\t\t});\n\t\treturn validColors;\n\t}\n\n\tsetMeasures() {\n\t\t// Override measures, including those for title and legend\n\t\t// set config for legend and title\n\t}\n\n\tconfigure() {\n\t\tlet height = this.argHeight;\n\t\tthis.baseHeight = height;\n\t\tthis.height = height - getExtraHeight(this.measures);\n\n\t\t// Bind window events\n\t\tBOUND_DRAW_FN = this.boundDrawFn.bind(this);\n\t\twindow.addEventListener('resize', BOUND_DRAW_FN);\n\t\twindow.addEventListener('orientationchange', this.boundDrawFn.bind(this));\n\t}\n\n\tboundDrawFn() {\n\t\tthis.draw(true);\n\t}\n\n\tunbindWindowEvents() {\n\t\twindow.removeEventListener('resize', BOUND_DRAW_FN);\n\t\twindow.removeEventListener('orientationchange', this.boundDrawFn.bind(this));\n\t}\n\n\t// Has to be called manually\n\tsetup() {\n\t\tthis.makeContainer();\n\t\tthis.updateWidth();\n\t\tthis.makeTooltip();\n\n\t\tthis.draw(false, true);\n\t}\n\n\tmakeContainer() {\n\t\t// Chart needs a dedicated parent element\n\t\tthis.parent.innerHTML = '';\n\n\t\tlet args = {\n\t\t\tinside: this.parent,\n\t\t\tclassName: 'chart-container'\n\t\t};\n\n\t\tif(this.independentWidth) {\n\t\t\targs.styles = { width: this.independentWidth + 'px' };\n\t\t}\n\n\t\tthis.container = $.create('div', args);\n\t}\n\n\tmakeTooltip() {\n\t\tthis.tip = new SvgTip({\n\t\t\tparent: this.container,\n\t\t\tcolors: this.colors\n\t\t});\n\t\tthis.bindTooltip();\n\t}\n\n\tbindTooltip() {}\n\n\tdraw(onlyWidthChange=false, init=false) {\n\t\tthis.updateWidth();\n\n\t\tthis.calc(onlyWidthChange);\n\t\tthis.makeChartArea();\n\t\tthis.setupComponents();\n\n\t\tthis.components.forEach(c => c.setup(this.drawArea));\n\t\t// this.components.forEach(c => c.make());\n\t\tthis.render(this.components, false);\n\n\t\tif(init) {\n\t\t\tthis.data = this.realData;\n\t\t\tsetTimeout(() => {this.update(this.data);}, this.initTimeout);\n\t\t}\n\n\t\tthis.renderLegend();\n\n\t\tthis.setupNavigation(init);\n\t}\n\n\tcalc() {} // builds state\n\n\tupdateWidth() {\n\t\tthis.baseWidth = getElementContentWidth(this.parent);\n\t\tthis.width = this.baseWidth - getExtraWidth(this.measures);\n\t}\n\n\tmakeChartArea() {\n\t\tif(this.svg) {\n\t\t\tthis.container.removeChild(this.svg);\n\t\t}\n\t\tlet m = this.measures;\n\n\t\tthis.svg = makeSVGContainer(\n\t\t\tthis.container,\n\t\t\t'frappe-chart chart',\n\t\t\tthis.baseWidth,\n\t\t\tthis.baseHeight\n\t\t);\n\t\tthis.svgDefs = makeSVGDefs(this.svg);\n\n\t\tif(this.title.length) {\n\t\t\tthis.titleEL = makeText(\n\t\t\t\t'title',\n\t\t\t\tm.margins.left,\n\t\t\t\tm.margins.top,\n\t\t\t\tthis.title,\n\t\t\t\t{\n\t\t\t\t\tfontSize: m.titleFontSize,\n\t\t\t\t\tfill: '#666666',\n\t\t\t\t\tdy: m.titleFontSize\n\t\t\t\t}\n\t\t\t);\n\t\t}\n\n\t\tlet top = getTopOffset(m);\n\t\tthis.drawArea = makeSVGGroup(\n\t\t\tthis.type + '-chart chart-draw-area',\n\t\t\t`translate(${getLeftOffset(m)}, ${top})`\n\t\t);\n\n\t\tif(this.config.showLegend) {\n\t\t\ttop += this.height + m.paddings.bottom;\n\t\t\tthis.legendArea = makeSVGGroup(\n\t\t\t\t'chart-legend',\n\t\t\t\t`translate(${getLeftOffset(m)}, ${top})`\n\t\t\t);\n\t\t}\n\n\t\tif(this.title.length) { this.svg.appendChild(this.titleEL); }\n\t\tthis.svg.appendChild(this.drawArea);\n\t\tif(this.config.showLegend) { this.svg.appendChild(this.legendArea); }\n\n\t\tthis.updateTipOffset(getLeftOffset(m), getTopOffset(m));\n\t}\n\n\tupdateTipOffset(x, y) {\n\t\tthis.tip.offset = {\n\t\t\tx: x,\n\t\t\ty: y\n\t\t};\n\t}\n\n\tsetupComponents() { this.components = new Map(); }\n\n\tupdate(data) {\n\t\tif(!data) {\n\t\t\tconsole.error('No data to update.');\n\t\t}\n\t\tthis.data = this.prepareData(data);\n\t\tthis.calc(); // builds state\n\t\tthis.render();\n\t}\n\n\trender(components=this.components, animate=true) {\n\t\tif(this.config.isNavigable) {\n\t\t\t// Remove all existing overlays\n\t\t\tthis.overlays.map(o => o.parentNode.removeChild(o));\n\t\t\t// ref.parentNode.insertBefore(element, ref);\n\t\t}\n\t\tlet elementsToAnimate = [];\n\t\t// Can decouple to this.refreshComponents() first to save animation timeout\n\t\tcomponents.forEach(c => {\n\t\t\telementsToAnimate = elementsToAnimate.concat(c.update(animate));\n\t\t});\n\t\tif(elementsToAnimate.length > 0) {\n\t\t\trunSMILAnimation(this.container, this.svg, elementsToAnimate);\n\t\t\tsetTimeout(() => {\n\t\t\t\tcomponents.forEach(c => c.make());\n\t\t\t\tthis.updateNav();\n\t\t\t}, CHART_POST_ANIMATE_TIMEOUT);\n\t\t} else {\n\t\t\tcomponents.forEach(c => c.make());\n\t\t\tthis.updateNav();\n\t\t}\n\t}\n\n\tupdateNav() {\n\t\tif(this.config.isNavigable) {\n\t\t\tthis.makeOverlay();\n\t\t\tthis.bindUnits();\n\t\t}\n\t}\n\n\trenderLegend() {}\n\n\tsetupNavigation(init=false) {\n\t\tif(!this.config.isNavigable) return;\n\n\t\tif(init) {\n\t\t\tthis.bindOverlay();\n\n\t\t\tthis.keyActions = {\n\t\t\t\t'13': this.onEnterKey.bind(this),\n\t\t\t\t'37': this.onLeftArrow.bind(this),\n\t\t\t\t'38': this.onUpArrow.bind(this),\n\t\t\t\t'39': this.onRightArrow.bind(this),\n\t\t\t\t'40': this.onDownArrow.bind(this),\n\t\t\t};\n\n\t\t\tdocument.addEventListener('keydown', (e) => {\n\t\t\t\tif(isElementInViewport(this.container)) {\n\t\t\t\t\te = e || window.event;\n\t\t\t\t\tif(this.keyActions[e.keyCode]) {\n\t\t\t\t\t\tthis.keyActions[e.keyCode]();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t}\n\n\tmakeOverlay() {}\n\tupdateOverlay() {}\n\tbindOverlay() {}\n\tbindUnits() {}\n\n\tonLeftArrow() {}\n\tonRightArrow() {}\n\tonUpArrow() {}\n\tonDownArrow() {}\n\tonEnterKey() {}\n\n\taddDataPoint() {}\n\tremoveDataPoint() {}\n\n\tgetDataPoint() {}\n\tsetCurrentDataPoint() {}\n\n\tupdateDataset() {}\n\n\texport() {\n\t\tlet chartSvg = prepareForExport(this.svg);\n\t\tdownloadFile(this.title || 'Chart', [chartSvg]);\n\t}\n}\n\nclass AggregationChart extends BaseChart {\n\tconstructor(parent, args) {\n\t\tsuper(parent, args);\n\t}\n\n\tconfigure(args) {\n\t\tsuper.configure(args);\n\n\t\tthis.config.maxSlices = args.maxSlices || 20;\n\t\tthis.config.maxLegendPoints = args.maxLegendPoints || 20;\n\t}\n\n\tcalc() {\n\t\tlet s = this.state;\n\t\tlet maxSlices = this.config.maxSlices;\n\t\ts.sliceTotals = [];\n\n\t\tlet allTotals = this.data.labels.map((label, i) => {\n\t\t\tlet total = 0;\n\t\t\tthis.data.datasets.map(e => {\n\t\t\t\ttotal += e.values[i];\n\t\t\t});\n\t\t\treturn [total, label];\n\t\t}).filter(d => { return d[0] >= 0; }); // keep only positive results\n\n\t\tlet totals = allTotals;\n\t\tif(allTotals.length > maxSlices) {\n\t\t\t// Prune and keep a grey area for rest as per maxSlices\n\t\t\tallTotals.sort((a, b) => { return b[0] - a[0]; });\n\n\t\t\ttotals = allTotals.slice(0, maxSlices-1);\n\t\t\tlet remaining = allTotals.slice(maxSlices-1);\n\n\t\t\tlet sumOfRemaining = 0;\n\t\t\tremaining.map(d => {sumOfRemaining += d[0];});\n\t\t\ttotals.push([sumOfRemaining, 'Rest']);\n\t\t\tthis.colors[maxSlices-1] = 'grey';\n\t\t}\n\n\t\ts.labels = [];\n\t\ttotals.map(d => {\n\t\t\ts.sliceTotals.push(d[0]);\n\t\t\ts.labels.push(d[1]);\n\t\t});\n\n\t\ts.grandTotal = s.sliceTotals.reduce((a, b) => a + b, 0);\n\n\t\tthis.center = {\n\t\t\tx: this.width / 2,\n\t\t\ty: this.height / 2\n\t\t};\n\t}\n\n\trenderLegend() {\n\t\tlet s = this.state;\n\t\tthis.legendArea.textContent = '';\n\t\tthis.legendTotals = s.sliceTotals.slice(0, this.config.maxLegendPoints);\n\n\t\tlet count = 0;\n\t\tlet y = 0;\n\t\tthis.legendTotals.map((d, i) => {\n\t\t\tlet barWidth = 110;\n\t\t\tlet divisor = Math.floor(\n\t\t\t\t(this.width - getExtraWidth(this.measures))/barWidth\n\t\t\t);\n\t\t\tif(count > divisor) {\n\t\t\t\tcount = 0;\n\t\t\t\ty += 20;\n\t\t\t}\n\t\t\tlet x = barWidth * count + 5;\n\t\t\tlet dot = legendDot(\n\t\t\t\tx,\n\t\t\t\ty,\n\t\t\t\t5,\n\t\t\t\tthis.colors[i],\n\t\t\t\t`${s.labels[i]}: ${d}`\n\t\t\t);\n\t\t\tthis.legendArea.appendChild(dot);\n\t\t\tcount++;\n\t\t});\n\t}\n}\n\n// Playing around with dates\n\nconst NO_OF_YEAR_MONTHS = 12;\nconst NO_OF_DAYS_IN_WEEK = 7;\n\nconst NO_OF_MILLIS = 1000;\nconst SEC_IN_DAY = 86400;\n\nconst MONTH_NAMES = [\"January\", \"February\", \"March\", \"April\", \"May\",\n\t\"June\", \"July\", \"August\", \"September\", \"October\", \"November\", \"December\"];\n\n\nconst DAY_NAMES_SHORT = [\"Sun\", \"Mon\", \"Tue\", \"Wed\", \"Thu\", \"Fri\", \"Sat\"];\n\n\n// https://stackoverflow.com/a/11252167/6495043\nfunction treatAsUtc(date) {\n\tlet result = new Date(date);\n\tresult.setMinutes(result.getMinutes() - result.getTimezoneOffset());\n\treturn result;\n}\n\nfunction getYyyyMmDd(date) {\n\tlet dd = date.getDate();\n\tlet mm = date.getMonth() + 1; // getMonth() is zero-based\n\treturn [\n\t\tdate.getFullYear(),\n\t\t(mm>9 ? '' : '0') + mm,\n\t\t(dd>9 ? '' : '0') + dd\n\t].join('-');\n}\n\nfunction clone(date) {\n\treturn new Date(date.getTime());\n}\n\n\n\n\n\n// export function getMonthsBetween(startDate, endDate) {}\n\nfunction getWeeksBetween(startDate, endDate) {\n\tlet weekStartDate = setDayToSunday(startDate);\n\treturn Math.ceil(getDaysBetween(weekStartDate, endDate) / NO_OF_DAYS_IN_WEEK);\n}\n\nfunction getDaysBetween(startDate, endDate) {\n\tlet millisecondsPerDay = SEC_IN_DAY * NO_OF_MILLIS;\n\treturn (treatAsUtc(endDate) - treatAsUtc(startDate)) / millisecondsPerDay;\n}\n\nfunction areInSameMonth(startDate, endDate) {\n\treturn startDate.getMonth() === endDate.getMonth()\n\t\t&& startDate.getFullYear() === endDate.getFullYear();\n}\n\nfunction getMonthName(i, short=false) {\n\tlet monthName = MONTH_NAMES[i];\n\treturn short ? monthName.slice(0, 3) : monthName;\n}\n\nfunction getLastDateInMonth (month, year) {\n\treturn new Date(year, month + 1, 0); // 0: last day in previous month\n}\n\n// mutates\nfunction setDayToSunday(date) {\n\tlet newDate = clone(date);\n\tconst day = newDate.getDay();\n\tif(day !== 0) {\n\t\taddDays(newDate, (-1) * day);\n\t}\n\treturn newDate;\n}\n\n// mutates\nfunction addDays(date, numberOfDays) {\n\tdate.setDate(date.getDate() + numberOfDays);\n}\n\nclass ChartComponent {\n\tconstructor({\n\t\tlayerClass = '',\n\t\tlayerTransform = '',\n\t\tconstants,\n\n\t\tgetData,\n\t\tmakeElements,\n\t\tanimateElements\n\t}) {\n\t\tthis.layerTransform = layerTransform;\n\t\tthis.constants = constants;\n\n\t\tthis.makeElements = makeElements;\n\t\tthis.getData = getData;\n\n\t\tthis.animateElements = animateElements;\n\n\t\tthis.store = [];\n\t\tthis.labels = [];\n\n\t\tthis.layerClass = layerClass;\n\t\tthis.layerClass = typeof(this.layerClass) === 'function'\n\t\t\t? this.layerClass() : this.layerClass;\n\n\t\tthis.refresh();\n\t}\n\n\trefresh(data) {\n\t\tthis.data = data || this.getData();\n\t}\n\n\tsetup(parent) {\n\t\tthis.layer = makeSVGGroup(this.layerClass, this.layerTransform, parent);\n\t}\n\n\tmake() {\n\t\tthis.render(this.data);\n\t\tthis.oldData = this.data;\n\t}\n\n\trender(data) {\n\t\tthis.store = this.makeElements(data);\n\n\t\tthis.layer.textContent = '';\n\t\tthis.store.forEach(element => {\n\t\t\tthis.layer.appendChild(element);\n\t\t});\n\t\tthis.labels.forEach(element => {\n\t\t\tthis.layer.appendChild(element);\n\t\t});\n\t}\n\n\tupdate(animate = true) {\n\t\tthis.refresh();\n\t\tlet animateElements = [];\n\t\tif(animate) {\n\t\t\tanimateElements = this.animateElements(this.data) || [];\n\t\t}\n\t\treturn animateElements;\n\t}\n}\n\nlet componentConfigs = {\n\tpieSlices: {\n\t\tlayerClass: 'pie-slices',\n\t\tmakeElements(data) {\n\t\t\treturn data.sliceStrings.map((s, i) =>{\n\t\t\t\tlet slice = makePath(s, 'pie-path', 'none', data.colors[i]);\n\t\t\t\tslice.style.transition = 'transform .3s;';\n\t\t\t\treturn slice;\n\t\t\t});\n\t\t},\n\n\t\tanimateElements(newData) {\n\t\t\treturn this.store.map((slice, i) =>\n\t\t\t\tanimatePathStr(slice, newData.sliceStrings[i])\n\t\t\t);\n\t\t}\n\t},\n\tpercentageBars: {\n\t\tlayerClass: 'percentage-bars',\n\t\tmakeElements(data) {\n\t\t\treturn data.xPositions.map((x, i) =>{\n\t\t\t\tlet y = 0;\n\t\t\t\tlet bar = percentageBar(x, y, data.widths[i],\n\t\t\t\t\tthis.constants.barHeight, this.constants.barDepth, data.colors[i]);\n\t\t\t\treturn bar;\n\t\t\t});\n\t\t},\n\n\t\tanimateElements(newData) {\n\t\t\tif(newData) return [];\n\t\t}\n\t},\n\tyAxis: {\n\t\tlayerClass: 'y axis',\n\t\tmakeElements(data) {\n\t\t\treturn data.positions.map((position, i) =>\n\t\t\t\tyLine(position, data.labels[i], this.constants.width,\n\t\t\t\t\t{mode: this.constants.mode, pos: this.constants.pos})\n\t\t\t);\n\t\t},\n\n\t\tanimateElements(newData) {\n\t\t\tlet newPos = newData.positions;\n\t\t\tlet newLabels = newData.labels;\n\t\t\tlet oldPos = this.oldData.positions;\n\t\t\tlet oldLabels = this.oldData.labels;\n\n\t\t\t[oldPos, newPos] = equilizeNoOfElements(oldPos, newPos);\n\t\t\t[oldLabels, newLabels] = equilizeNoOfElements(oldLabels, newLabels);\n\n\t\t\tthis.render({\n\t\t\t\tpositions: oldPos,\n\t\t\t\tlabels: newLabels\n\t\t\t});\n\n\t\t\treturn this.store.map((line, i) => {\n\t\t\t\treturn translateHoriLine(\n\t\t\t\t\tline, newPos[i], oldPos[i]\n\t\t\t\t);\n\t\t\t});\n\t\t}\n\t},\n\n\txAxis: {\n\t\tlayerClass: 'x axis',\n\t\tmakeElements(data) {\n\t\t\treturn data.positions.map((position, i) =>\n\t\t\t\txLine(position, data.calcLabels[i], this.constants.height,\n\t\t\t\t\t{mode: this.constants.mode, pos: this.constants.pos})\n\t\t\t);\n\t\t},\n\n\t\tanimateElements(newData) {\n\t\t\tlet newPos = newData.positions;\n\t\t\tlet newLabels = newData.calcLabels;\n\t\t\tlet oldPos = this.oldData.positions;\n\t\t\tlet oldLabels = this.oldData.calcLabels;\n\n\t\t\t[oldPos, newPos] = equilizeNoOfElements(oldPos, newPos);\n\t\t\t[oldLabels, newLabels] = equilizeNoOfElements(oldLabels, newLabels);\n\n\t\t\tthis.render({\n\t\t\t\tpositions: oldPos,\n\t\t\t\tcalcLabels: newLabels\n\t\t\t});\n\n\t\t\treturn this.store.map((line, i) => {\n\t\t\t\treturn translateVertLine(\n\t\t\t\t\tline, newPos[i], oldPos[i]\n\t\t\t\t);\n\t\t\t});\n\t\t}\n\t},\n\n\tyMarkers: {\n\t\tlayerClass: 'y-markers',\n\t\tmakeElements(data) {\n\t\t\treturn data.map(m =>\n\t\t\t\tyMarker(m.position, m.label, this.constants.width,\n\t\t\t\t\t{labelPos: m.options.labelPos, mode: 'span', lineType: 'dashed'})\n\t\t\t);\n\t\t},\n\t\tanimateElements(newData) {\n\t\t\t[this.oldData, newData] = equilizeNoOfElements(this.oldData, newData);\n\n\t\t\tlet newPos = newData.map(d => d.position);\n\t\t\tlet newLabels = newData.map(d => d.label);\n\t\t\tlet newOptions = newData.map(d => d.options);\n\n\t\t\tlet oldPos = this.oldData.map(d => d.position);\n\n\t\t\tthis.render(oldPos.map((pos, i) => {\n\t\t\t\treturn {\n\t\t\t\t\tposition: oldPos[i],\n\t\t\t\t\tlabel: newLabels[i],\n\t\t\t\t\toptions: newOptions[i]\n\t\t\t\t};\n\t\t\t}));\n\n\t\t\treturn this.store.map((line, i) => {\n\t\t\t\treturn translateHoriLine(\n\t\t\t\t\tline, newPos[i], oldPos[i]\n\t\t\t\t);\n\t\t\t});\n\t\t}\n\t},\n\n\tyRegions: {\n\t\tlayerClass: 'y-regions',\n\t\tmakeElements(data) {\n\t\t\treturn data.map(r =>\n\t\t\t\tyRegion(r.startPos, r.endPos, this.constants.width,\n\t\t\t\t\tr.label, {labelPos: r.options.labelPos})\n\t\t\t);\n\t\t},\n\t\tanimateElements(newData) {\n\t\t\t[this.oldData, newData] = equilizeNoOfElements(this.oldData, newData);\n\n\t\t\tlet newPos = newData.map(d => d.endPos);\n\t\t\tlet newLabels = newData.map(d => d.label);\n\t\t\tlet newStarts = newData.map(d => d.startPos);\n\t\t\tlet newOptions = newData.map(d => d.options);\n\n\t\t\tlet oldPos = this.oldData.map(d => d.endPos);\n\t\t\tlet oldStarts = this.oldData.map(d => d.startPos);\n\n\t\t\tthis.render(oldPos.map((pos, i) => {\n\t\t\t\treturn {\n\t\t\t\t\tstartPos: oldStarts[i],\n\t\t\t\t\tendPos: oldPos[i],\n\t\t\t\t\tlabel: newLabels[i],\n\t\t\t\t\toptions: newOptions[i]\n\t\t\t\t};\n\t\t\t}));\n\n\t\t\tlet animateElements = [];\n\n\t\t\tthis.store.map((rectGroup, i) => {\n\t\t\t\tanimateElements = animateElements.concat(animateRegion(\n\t\t\t\t\trectGroup, newStarts[i], newPos[i], oldPos[i]\n\t\t\t\t));\n\t\t\t});\n\n\t\t\treturn animateElements;\n\t\t}\n\t},\n\n\theatDomain: {\n\t\tlayerClass: function() { return 'heat-domain domain-' + this.constants.index; },\n\t\tmakeElements(data) {\n\t\t\tlet {index, colWidth, rowHeight, squareSize, xTranslate} = this.constants;\n\t\t\tlet monthNameHeight = -12;\n\t\t\tlet x = xTranslate, y = 0;\n\n\t\t\tthis.serializedSubDomains = [];\n\n\t\t\tdata.cols.map((week, weekNo) => {\n\t\t\t\tif(weekNo === 1) {\n\t\t\t\t\tthis.labels.push(\n\t\t\t\t\t\tmakeText('domain-name', x, monthNameHeight, getMonthName(index, true).toUpperCase(),\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tfontSize: 9\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t)\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tweek.map((day, i) => {\n\t\t\t\t\tif(day.fill) {\n\t\t\t\t\t\tlet data = {\n\t\t\t\t\t\t\t'data-date': day.yyyyMmDd,\n\t\t\t\t\t\t\t'data-value': day.dataValue,\n\t\t\t\t\t\t\t'data-day': i\n\t\t\t\t\t\t};\n\t\t\t\t\t\tlet square = heatSquare('day', x, y, squareSize, day.fill, data);\n\t\t\t\t\t\tthis.serializedSubDomains.push(square);\n\t\t\t\t\t}\n\t\t\t\t\ty += rowHeight;\n\t\t\t\t});\n\t\t\t\ty = 0;\n\t\t\t\tx += colWidth;\n\t\t\t});\n\n\t\t\treturn this.serializedSubDomains;\n\t\t},\n\n\t\tanimateElements(newData) {\n\t\t\tif(newData) return [];\n\t\t}\n\t},\n\n\tbarGraph: {\n\t\tlayerClass: function() { return 'dataset-units dataset-bars dataset-' + this.constants.index; },\n\t\tmakeElements(data) {\n\t\t\tlet c = this.constants;\n\t\t\tthis.unitType = 'bar';\n\t\t\tthis.units = data.yPositions.map((y, j) => {\n\t\t\t\treturn datasetBar(\n\t\t\t\t\tdata.xPositions[j],\n\t\t\t\t\ty,\n\t\t\t\t\tdata.barWidth,\n\t\t\t\t\tc.color,\n\t\t\t\t\tdata.labels[j],\n\t\t\t\t\tj,\n\t\t\t\t\tdata.offsets[j],\n\t\t\t\t\t{\n\t\t\t\t\t\tzeroLine: data.zeroLine,\n\t\t\t\t\t\tbarsWidth: data.barsWidth,\n\t\t\t\t\t\tminHeight: c.minHeight\n\t\t\t\t\t}\n\t\t\t\t);\n\t\t\t});\n\t\t\treturn this.units;\n\t\t},\n\t\tanimateElements(newData) {\n\t\t\tlet newXPos = newData.xPositions;\n\t\t\tlet newYPos = newData.yPositions;\n\t\t\tlet newOffsets = newData.offsets;\n\t\t\tlet newLabels = newData.labels;\n\n\t\t\tlet oldXPos = this.oldData.xPositions;\n\t\t\tlet oldYPos = this.oldData.yPositions;\n\t\t\tlet oldOffsets = this.oldData.offsets;\n\t\t\tlet oldLabels = this.oldData.labels;\n\n\t\t\t[oldXPos, newXPos] = equilizeNoOfElements(oldXPos, newXPos);\n\t\t\t[oldYPos, newYPos] = equilizeNoOfElements(oldYPos, newYPos);\n\t\t\t[oldOffsets, newOffsets] = equilizeNoOfElements(oldOffsets, newOffsets);\n\t\t\t[oldLabels, newLabels] = equilizeNoOfElements(oldLabels, newLabels);\n\n\t\t\tthis.render({\n\t\t\t\txPositions: oldXPos,\n\t\t\t\tyPositions: oldYPos,\n\t\t\t\toffsets: oldOffsets,\n\t\t\t\tlabels: newLabels,\n\n\t\t\t\tzeroLine: this.oldData.zeroLine,\n\t\t\t\tbarsWidth: this.oldData.barsWidth,\n\t\t\t\tbarWidth: this.oldData.barWidth,\n\t\t\t});\n\n\t\t\tlet animateElements = [];\n\n\t\t\tthis.store.map((bar, i) => {\n\t\t\t\tanimateElements = animateElements.concat(animateBar(\n\t\t\t\t\tbar, newXPos[i], newYPos[i], newData.barWidth, newOffsets[i],\n\t\t\t\t\t{zeroLine: newData.zeroLine}\n\t\t\t\t));\n\t\t\t});\n\n\t\t\treturn animateElements;\n\t\t}\n\t},\n\n\tlineGraph: {\n\t\tlayerClass: function() { return 'dataset-units dataset-line dataset-' + this.constants.index; },\n\t\tmakeElements(data) {\n\t\t\tlet c = this.constants;\n\t\t\tthis.unitType = 'dot';\n\t\t\tthis.paths = {};\n\t\t\tif(!c.hideLine) {\n\t\t\t\tthis.paths = getPaths(\n\t\t\t\t\tdata.xPositions,\n\t\t\t\t\tdata.yPositions,\n\t\t\t\t\tc.color,\n\t\t\t\t\t{\n\t\t\t\t\t\theatline: c.heatline,\n\t\t\t\t\t\tregionFill: c.regionFill\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tsvgDefs: c.svgDefs,\n\t\t\t\t\t\tzeroLine: data.zeroLine\n\t\t\t\t\t}\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tthis.units = [];\n\t\t\tif(!c.hideDots) {\n\t\t\t\tthis.units = data.yPositions.map((y, j) => {\n\t\t\t\t\treturn datasetDot(\n\t\t\t\t\t\tdata.xPositions[j],\n\t\t\t\t\t\ty,\n\t\t\t\t\t\tdata.radius,\n\t\t\t\t\t\tc.color,\n\t\t\t\t\t\t(c.valuesOverPoints ? data.values[j] : ''),\n\t\t\t\t\t\tj\n\t\t\t\t\t);\n\t\t\t\t});\n\t\t\t}\n\n\t\t\treturn Object.values(this.paths).concat(this.units);\n\t\t},\n\t\tanimateElements(newData) {\n\t\t\tlet newXPos = newData.xPositions;\n\t\t\tlet newYPos = newData.yPositions;\n\t\t\tlet newValues = newData.values;\n\n\t\t\tlet oldXPos = this.oldData.xPositions;\n\t\t\tlet oldYPos = this.oldData.yPositions;\n\t\t\tlet oldValues = this.oldData.values;\n\n\t\t\t[oldXPos, newXPos] = equilizeNoOfElements(oldXPos, newXPos);\n\t\t\t[oldYPos, newYPos] = equilizeNoOfElements(oldYPos, newYPos);\n\t\t\t[oldValues, newValues] = equilizeNoOfElements(oldValues, newValues);\n\n\t\t\tthis.render({\n\t\t\t\txPositions: oldXPos,\n\t\t\t\tyPositions: oldYPos,\n\t\t\t\tvalues: newValues,\n\n\t\t\t\tzeroLine: this.oldData.zeroLine,\n\t\t\t\tradius: this.oldData.radius,\n\t\t\t});\n\n\t\t\tlet animateElements = [];\n\n\t\t\tif(Object.keys(this.paths).length) {\n\t\t\t\tanimateElements = animateElements.concat(animatePath(\n\t\t\t\t\tthis.paths, newXPos, newYPos, newData.zeroLine));\n\t\t\t}\n\n\t\t\tif(this.units.length) {\n\t\t\t\tthis.units.map((dot, i) => {\n\t\t\t\t\tanimateElements = animateElements.concat(animateDot(\n\t\t\t\t\t\tdot, newXPos[i], newYPos[i]));\n\t\t\t\t});\n\t\t\t}\n\n\t\t\treturn animateElements;\n\t\t}\n\t}\n};\n\nfunction getComponent(name, constants, getData) {\n\tlet keys = Object.keys(componentConfigs).filter(k => name.includes(k));\n\tlet config = componentConfigs[keys[0]];\n\tObject.assign(config, {\n\t\tconstants: constants,\n\t\tgetData: getData\n\t});\n\treturn new ChartComponent(config);\n}\n\nclass PercentageChart extends AggregationChart {\n\tconstructor(parent, args) {\n\t\tsuper(parent, args);\n\t\tthis.type = 'percentage';\n\t\tthis.setup();\n\t}\n\n\tsetMeasures(options) {\n\t\tlet m = this.measures;\n\t\tthis.barOptions = options.barOptions || {};\n\n\t\tlet b = this.barOptions;\n\t\tb.height = b.height || PERCENTAGE_BAR_DEFAULT_HEIGHT;\n\t\tb.depth = b.depth || PERCENTAGE_BAR_DEFAULT_DEPTH;\n\n\t\tm.paddings.right = 30;\n\t\tm.legendHeight = 80;\n\t\tm.baseHeight = (b.height + b.depth * 0.5) * 8;\n\t}\n\n\tsetupComponents() {\n\t\tlet s = this.state;\n\n\t\tlet componentConfigs = [\n\t\t\t[\n\t\t\t\t'percentageBars',\n\t\t\t\t{\n\t\t\t\t\tbarHeight: this.barOptions.height,\n\t\t\t\t\tbarDepth: this.barOptions.depth,\n\t\t\t\t},\n\t\t\t\tfunction() {\n\t\t\t\t\treturn {\n\t\t\t\t\t\txPositions: s.xPositions,\n\t\t\t\t\t\twidths: s.widths,\n\t\t\t\t\t\tcolors: this.colors\n\t\t\t\t\t};\n\t\t\t\t}.bind(this)\n\t\t\t]\n\t\t];\n\n\t\tthis.components = new Map(componentConfigs\n\t\t\t.map(args => {\n\t\t\t\tlet component = getComponent(...args);\n\t\t\t\treturn [args[0], component];\n\t\t\t}));\n\t}\n\n\tcalc() {\n\t\tsuper.calc();\n\t\tlet s = this.state;\n\n\t\ts.xPositions = [];\n\t\ts.widths = [];\n\n\t\tlet xPos = 0;\n\t\ts.sliceTotals.map((value) => {\n\t\t\tlet width = this.width * value / s.grandTotal;\n\t\t\ts.widths.push(width);\n\t\t\ts.xPositions.push(xPos);\n\t\t\txPos += width;\n\t\t});\n\t}\n\n\tmakeDataByIndex() { }\n\n\tbindTooltip() {\n\t\tlet s = this.state;\n\t\tthis.container.addEventListener('mousemove', (e) => {\n\t\t\tlet bars = this.components.get('percentageBars').store;\n\t\t\tlet bar = e.target;\n\t\t\tif(bars.includes(bar)) {\n\n\t\t\t\tlet i = bars.indexOf(bar);\n\t\t\t\tlet gOff = getOffset(this.container), pOff = getOffset(bar);\n\n\t\t\t\tlet x = pOff.left - gOff.left + parseInt(bar.getAttribute('width'))/2;\n\t\t\t\tlet y = pOff.top - gOff.top;\n\t\t\t\tlet title = (this.formattedLabels && this.formattedLabels.length>0\n\t\t\t\t\t? this.formattedLabels[i] : this.state.labels[i]) + ': ';\n\t\t\t\tlet fraction = s.sliceTotals[i]/s.grandTotal;\n\n\t\t\t\tthis.tip.setValues(x, y, {name: title, value: (fraction*100).toFixed(1) + \"%\"});\n\t\t\t\tthis.tip.showTip();\n\t\t\t}\n\t\t});\n\t}\n}\n\nclass PieChart extends AggregationChart {\n\tconstructor(parent, args) {\n\t\tsuper(parent, args);\n\t\tthis.type = 'pie';\n\t\tthis.initTimeout = 0;\n\t\tthis.init = 1;\n\n\t\tthis.setup();\n\t}\n\n\tconfigure(args) {\n\t\tsuper.configure(args);\n\t\tthis.mouseMove = this.mouseMove.bind(this);\n\t\tthis.mouseLeave = this.mouseLeave.bind(this);\n\n\t\tthis.hoverRadio = args.hoverRadio || 0.1;\n\t\tthis.config.startAngle = args.startAngle || 0;\n\n\t\tthis.clockWise = args.clockWise || false;\n\t}\n\n\tcalc() {\n\t\tsuper.calc();\n\t\tlet s = this.state;\n\t\tthis.radius = (this.height > this.width ? this.center.x : this.center.y);\n\n\t\tconst { radius, clockWise } = this;\n\n\t\tconst prevSlicesProperties = s.slicesProperties || [];\n\t\ts.sliceStrings = [];\n\t\ts.slicesProperties = [];\n\t\tlet curAngle = 180 - this.config.startAngle;\n\n\t\ts.sliceTotals.map((total, i) => {\n\t\t\tconst startAngle = curAngle;\n\t\t\tconst originDiffAngle = (total / s.grandTotal) * FULL_ANGLE;\n\t\t\tconst diffAngle = clockWise ? -originDiffAngle : originDiffAngle;\n\t\t\tconst endAngle = curAngle = curAngle + diffAngle;\n\t\t\tconst startPosition = getPositionByAngle(startAngle, radius);\n\t\t\tconst endPosition = getPositionByAngle(endAngle, radius);\n\n\t\t\tconst prevProperty = this.init && prevSlicesProperties[i];\n\n\t\t\tlet curStart,curEnd;\n\t\t\tif(this.init) {\n\t\t\t\tcurStart = prevProperty ? prevProperty.startPosition : startPosition;\n\t\t\t\tcurEnd = prevProperty ? prevProperty.endPosition : startPosition;\n\t\t\t} else {\n\t\t\t\tcurStart = startPosition;\n\t\t\t\tcurEnd = endPosition;\n\t\t\t}\n\t\t\tconst curPath = makeArcPathStr(curStart, curEnd, this.center, this.radius, this.clockWise);\n\n\t\t\ts.sliceStrings.push(curPath);\n\t\t\ts.slicesProperties.push({\n\t\t\t\tstartPosition,\n\t\t\t\tendPosition,\n\t\t\t\tvalue: total,\n\t\t\t\ttotal: s.grandTotal,\n\t\t\t\tstartAngle,\n\t\t\t\tendAngle,\n\t\t\t\tangle: diffAngle\n\t\t\t});\n\n\t\t});\n\t\tthis.init = 0;\n\t}\n\n\tsetupComponents() {\n\t\tlet s = this.state;\n\n\t\tlet componentConfigs = [\n\t\t\t[\n\t\t\t\t'pieSlices',\n\t\t\t\t{ },\n\t\t\t\tfunction() {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tsliceStrings: s.sliceStrings,\n\t\t\t\t\t\tcolors: this.colors\n\t\t\t\t\t};\n\t\t\t\t}.bind(this)\n\t\t\t]\n\t\t];\n\n\t\tthis.components = new Map(componentConfigs\n\t\t\t.map(args => {\n\t\t\t\tlet component = getComponent(...args);\n\t\t\t\treturn [args[0], component];\n\t\t\t}));\n\t}\n\n\tcalTranslateByAngle(property){\n\t\tconst{radius,hoverRadio} = this;\n\t\tconst position = getPositionByAngle(property.startAngle+(property.angle / 2),radius);\n\t\treturn `translate3d(${(position.x) * hoverRadio}px,${(position.y) * hoverRadio}px,0)`;\n\t}\n\n\thoverSlice(path,i,flag,e){\n\t\tif(!path) return;\n\t\tconst color = this.colors[i];\n\t\tif(flag) {\n\t\t\ttransform(path, this.calTranslateByAngle(this.state.slicesProperties[i]));\n\t\t\tpath.style.fill = lightenDarkenColor(color, 50);\n\t\t\tlet g_off = getOffset(this.svg);\n\t\t\tlet x = e.pageX - g_off.left + 10;\n\t\t\tlet y = e.pageY - g_off.top - 10;\n\t\t\tlet title = (this.formatted_labels && this.formatted_labels.length > 0\n\t\t\t\t? this.formatted_labels[i] : this.state.labels[i]) + ': ';\n\t\t\tlet percent = (this.state.sliceTotals[i] * 100 / this.state.grandTotal).toFixed(1);\n\t\t\tthis.tip.setValues(x, y, {name: title, value: percent + \"%\"});\n\t\t\tthis.tip.showTip();\n\t\t} else {\n\t\t\ttransform(path,'translate3d(0,0,0)');\n\t\t\tthis.tip.hideTip();\n\t\t\tpath.style.fill = color;\n\t\t}\n\t}\n\n\tbindTooltip() {\n\t\tthis.container.addEventListener('mousemove', this.mouseMove);\n\t\tthis.container.addEventListener('mouseleave', this.mouseLeave);\n\t}\n\n\tmouseMove(e){\n\t\tconst target = e.target;\n\t\tlet slices = this.components.get('pieSlices').store;\n\t\tlet prevIndex = this.curActiveSliceIndex;\n\t\tlet prevAcitve = this.curActiveSlice;\n\t\tif(slices.includes(target)) {\n\t\t\tlet i = slices.indexOf(target);\n\t\t\tthis.hoverSlice(prevAcitve, prevIndex,false);\n\t\t\tthis.curActiveSlice = target;\n\t\t\tthis.curActiveSliceIndex = i;\n\t\t\tthis.hoverSlice(target, i, true, e);\n\t\t} else {\n\t\t\tthis.mouseLeave();\n\t\t}\n\t}\n\n\tmouseLeave(){\n\t\tthis.hoverSlice(this.curActiveSlice,this.curActiveSliceIndex,false);\n\t}\n}\n\nfunction normalize(x) {\n\t// Calculates mantissa and exponent of a number\n\t// Returns normalized number and exponent\n\t// https://stackoverflow.com/q/9383593/6495043\n\n\tif(x===0) {\n\t\treturn [0, 0];\n\t}\n\tif(isNaN(x)) {\n\t\treturn {mantissa: -6755399441055744, exponent: 972};\n\t}\n\tvar sig = x > 0 ? 1 : -1;\n\tif(!isFinite(x)) {\n\t\treturn {mantissa: sig * 4503599627370496, exponent: 972};\n\t}\n\n\tx = Math.abs(x);\n\tvar exp = Math.floor(Math.log10(x));\n\tvar man = x/Math.pow(10, exp);\n\n\treturn [sig * man, exp];\n}\n\nfunction getChartRangeIntervals(max, min=0) {\n\tlet upperBound = Math.ceil(max);\n\tlet lowerBound = Math.floor(min);\n\tlet range = upperBound - lowerBound;\n\n\tlet noOfParts = range;\n\tlet partSize = 1;\n\n\t// To avoid too many partitions\n\tif(range > 5) {\n\t\tif(range % 2 !== 0) {\n\t\t\tupperBound++;\n\t\t\t// Recalc range\n\t\t\trange = upperBound - lowerBound;\n\t\t}\n\t\tnoOfParts = range/2;\n\t\tpartSize = 2;\n\t}\n\n\t// Special case: 1 and 2\n\tif(range <= 2) {\n\t\tnoOfParts = 4;\n\t\tpartSize = range/noOfParts;\n\t}\n\n\t// Special case: 0\n\tif(range === 0) {\n\t\tnoOfParts = 5;\n\t\tpartSize = 1;\n\t}\n\n\tlet intervals = [];\n\tfor(var i = 0; i <= noOfParts; i++){\n\t\tintervals.push(lowerBound + partSize * i);\n\t}\n\treturn intervals;\n}\n\nfunction getChartIntervals(maxValue, minValue=0) {\n\tlet [normalMaxValue, exponent] = normalize(maxValue);\n\tlet normalMinValue = minValue ? minValue/Math.pow(10, exponent): 0;\n\n\t// Allow only 7 significant digits\n\tnormalMaxValue = normalMaxValue.toFixed(6);\n\n\tlet intervals = getChartRangeIntervals(normalMaxValue, normalMinValue);\n\tintervals = intervals.map(value => value * Math.pow(10, exponent));\n\treturn intervals;\n}\n\nfunction calcChartIntervals(values, withMinimum=false) {\n\t//*** Where the magic happens ***\n\n\t// Calculates best-fit y intervals from given values\n\t// and returns the interval array\n\n\tlet maxValue = Math.max(...values);\n\tlet minValue = Math.min(...values);\n\n\t// Exponent to be used for pretty print\n\tlet exponent = 0, intervals = []; // eslint-disable-line no-unused-vars\n\n\tfunction getPositiveFirstIntervals(maxValue, absMinValue) {\n\t\tlet intervals = getChartIntervals(maxValue);\n\n\t\tlet intervalSize = intervals[1] - intervals[0];\n\n\t\t// Then unshift the negative values\n\t\tlet value = 0;\n\t\tfor(var i = 1; value < absMinValue; i++) {\n\t\t\tvalue += intervalSize;\n\t\t\tintervals.unshift((-1) * value);\n\t\t}\n\t\treturn intervals;\n\t}\n\n\t// CASE I: Both non-negative\n\n\tif(maxValue >= 0 && minValue >= 0) {\n\t\texponent = normalize(maxValue)[1];\n\t\tif(!withMinimum) {\n\t\t\tintervals = getChartIntervals(maxValue);\n\t\t} else {\n\t\t\tintervals = getChartIntervals(maxValue, minValue);\n\t\t}\n\t}\n\n\t// CASE II: Only minValue negative\n\n\telse if(maxValue > 0 && minValue < 0) {\n\t\t// `withMinimum` irrelevant in this case,\n\t\t// We'll be handling both sides of zero separately\n\t\t// (both starting from zero)\n\t\t// Because ceil() and floor() behave differently\n\t\t// in those two regions\n\n\t\tlet absMinValue = Math.abs(minValue);\n\n\t\tif(maxValue >= absMinValue) {\n\t\t\texponent = normalize(maxValue)[1];\n\t\t\tintervals = getPositiveFirstIntervals(maxValue, absMinValue);\n\t\t} else {\n\t\t\t// Mirror: maxValue => absMinValue, then change sign\n\t\t\texponent = normalize(absMinValue)[1];\n\t\t\tlet posIntervals = getPositiveFirstIntervals(absMinValue, maxValue);\n\t\t\tintervals = posIntervals.map(d => d * (-1));\n\t\t}\n\n\t}\n\n\t// CASE III: Both non-positive\n\n\telse if(maxValue <= 0 && minValue <= 0) {\n\t\t// Mirrored Case I:\n\t\t// Work with positives, then reverse the sign and array\n\n\t\tlet pseudoMaxValue = Math.abs(minValue);\n\t\tlet pseudoMinValue = Math.abs(maxValue);\n\n\t\texponent = normalize(pseudoMaxValue)[1];\n\t\tif(!withMinimum) {\n\t\t\tintervals = getChartIntervals(pseudoMaxValue);\n\t\t} else {\n\t\t\tintervals = getChartIntervals(pseudoMaxValue, pseudoMinValue);\n\t\t}\n\n\t\tintervals = intervals.reverse().map(d => d * (-1));\n\t}\n\n\treturn intervals;\n}\n\nfunction getZeroIndex(yPts) {\n\tlet zeroIndex;\n\tlet interval = getIntervalSize(yPts);\n\tif(yPts.indexOf(0) >= 0) {\n\t\t// the range has a given zero\n\t\t// zero-line on the chart\n\t\tzeroIndex = yPts.indexOf(0);\n\t} else if(yPts[0] > 0) {\n\t\t// Minimum value is positive\n\t\t// zero-line is off the chart: below\n\t\tlet min = yPts[0];\n\t\tzeroIndex = (-1) * min / interval;\n\t} else {\n\t\t// Maximum value is negative\n\t\t// zero-line is off the chart: above\n\t\tlet max = yPts[yPts.length - 1];\n\t\tzeroIndex = (-1) * max / interval + (yPts.length - 1);\n\t}\n\treturn zeroIndex;\n}\n\n\n\nfunction getIntervalSize(orderedArray) {\n\treturn orderedArray[1] - orderedArray[0];\n}\n\nfunction getValueRange(orderedArray) {\n\treturn orderedArray[orderedArray.length-1] - orderedArray[0];\n}\n\nfunction scale(val, yAxis) {\n\treturn floatTwo(yAxis.zeroLine - val * yAxis.scaleMultiplier);\n}\n\n\n\n\n\nfunction getClosestInArray(goal, arr, index = false) {\n\tlet closest = arr.reduce(function(prev, curr) {\n\t\treturn (Math.abs(curr - goal) < Math.abs(prev - goal) ? curr : prev);\n\t});\n\n\treturn index ? arr.indexOf(closest) : closest;\n}\n\nfunction calcDistribution(values, distributionSize) {\n\t// Assume non-negative values,\n\t// implying distribution minimum at zero\n\n\tlet dataMaxValue = Math.max(...values);\n\n\tlet distributionStep = 1 / (distributionSize - 1);\n\tlet distribution = [];\n\n\tfor(var i = 0; i < distributionSize; i++) {\n\t\tlet checkpoint = dataMaxValue * (distributionStep * i);\n\t\tdistribution.push(checkpoint);\n\t}\n\n\treturn distribution;\n}\n\nfunction getMaxCheckpoint(value, distribution) {\n\treturn distribution.filter(d => d < value).length;\n}\n\nconst COL_WIDTH = HEATMAP_SQUARE_SIZE + HEATMAP_GUTTER_SIZE;\nconst ROW_HEIGHT = COL_WIDTH;\n// const DAY_INCR = 1;\n\nclass Heatmap extends BaseChart {\n\tconstructor(parent, options) {\n\t\tsuper(parent, options);\n\t\tthis.type = 'heatmap';\n\n\t\tthis.countLabel = options.countLabel || '';\n\n\t\tlet validStarts = ['Sunday', 'Monday'];\n\t\tlet startSubDomain = validStarts.includes(options.startSubDomain)\n\t\t\t? options.startSubDomain : 'Sunday';\n\t\tthis.startSubDomainIndex = validStarts.indexOf(startSubDomain);\n\n\t\tthis.setup();\n\t}\n\n\tsetMeasures(options) {\n\t\tlet m = this.measures;\n\t\tthis.discreteDomains = options.discreteDomains === 0 ? 0 : 1;\n\n\t\tm.paddings.top = ROW_HEIGHT * 3;\n\t\tm.paddings.bottom = 0;\n\t\tm.legendHeight = ROW_HEIGHT * 2;\n\t\tm.baseHeight = ROW_HEIGHT * NO_OF_DAYS_IN_WEEK\n\t\t\t+ getExtraHeight(m);\n\n\t\tlet d = this.data;\n\t\tlet spacing = this.discreteDomains ? NO_OF_YEAR_MONTHS : 0;\n\t\tthis.independentWidth = (getWeeksBetween(d.start, d.end)\n\t\t\t+ spacing) * COL_WIDTH + getExtraWidth(m);\n\t}\n\n\tupdateWidth() {\n\t\tlet spacing = this.discreteDomains ? NO_OF_YEAR_MONTHS : 0;\n\t\tlet noOfWeeks = this.state.noOfWeeks ? this.state.noOfWeeks : 52;\n\t\tthis.baseWidth = (noOfWeeks + spacing) * COL_WIDTH\n\t\t\t+ getExtraWidth(this.measures);\n\t}\n\n\tprepareData(data=this.data) {\n\t\tif(data.start && data.end && data.start > data.end) {\n\t\t\tthrow new Error('Start date cannot be greater than end date.');\n\t\t}\n\n\t\tif(!data.start) {\n\t\t\tdata.start = new Date();\n\t\t\tdata.start.setFullYear( data.start.getFullYear() - 1 );\n\t\t}\n\t\tif(!data.end) { data.end = new Date(); }\n\t\tdata.dataPoints = data.dataPoints || {};\n\n\t\tif(parseInt(Object.keys(data.dataPoints)[0]) > 100000) {\n\t\t\tlet points = {};\n\t\t\tObject.keys(data.dataPoints).forEach(timestampSec$$1 => {\n\t\t\t\tlet date = new Date(timestampSec$$1 * NO_OF_MILLIS);\n\t\t\t\tpoints[getYyyyMmDd(date)] = data.dataPoints[timestampSec$$1];\n\t\t\t});\n\t\t\tdata.dataPoints = points;\n\t\t}\n\n\t\treturn data;\n\t}\n\n\tcalc() {\n\t\tlet s = this.state;\n\n\t\ts.start = clone(this.data.start);\n\t\ts.end = clone(this.data.end);\n\n\t\ts.firstWeekStart = clone(s.start);\n\t\ts.noOfWeeks = getWeeksBetween(s.start, s.end);\n\t\ts.distribution = calcDistribution(\n\t\t\tObject.values(this.data.dataPoints), HEATMAP_DISTRIBUTION_SIZE);\n\n\t\ts.domainConfigs = this.getDomains();\n\t}\n\n\tsetupComponents() {\n\t\tlet s = this.state;\n\t\tlet lessCol = this.discreteDomains ? 0 : 1;\n\n\t\tlet componentConfigs = s.domainConfigs.map((config, i) => [\n\t\t\t'heatDomain',\n\t\t\t{\n\t\t\t\tindex: config.index,\n\t\t\t\tcolWidth: COL_WIDTH,\n\t\t\t\trowHeight: ROW_HEIGHT,\n\t\t\t\tsquareSize: HEATMAP_SQUARE_SIZE,\n\t\t\t\txTranslate: s.domainConfigs\n\t\t\t\t\t.filter((config, j) => j < i)\n\t\t\t\t\t.map(config => config.cols.length - lessCol)\n\t\t\t\t\t.reduce((a, b) => a + b, 0)\n\t\t\t\t\t* COL_WIDTH\n\t\t\t},\n\t\t\tfunction() {\n\t\t\t\treturn s.domainConfigs[i];\n\t\t\t}.bind(this)\n\n\t\t]);\n\n\t\tthis.components = new Map(componentConfigs\n\t\t\t.map((args, i) => {\n\t\t\t\tlet component = getComponent(...args);\n\t\t\t\treturn [args[0] + '-' + i, component];\n\t\t\t})\n\t\t);\n\n\t\tlet y = 0;\n\t\tDAY_NAMES_SHORT.forEach((dayName, i) => {\n\t\t\tif([1, 3, 5].includes(i)) {\n\t\t\t\tlet dayText = makeText('subdomain-name', -COL_WIDTH/2, y, dayName,\n\t\t\t\t\t{\n\t\t\t\t\t\tfontSize: HEATMAP_SQUARE_SIZE,\n\t\t\t\t\t\tdy: 8,\n\t\t\t\t\t\ttextAnchor: 'end'\n\t\t\t\t\t}\n\t\t\t\t);\n\t\t\t\tthis.drawArea.appendChild(dayText);\n\t\t\t}\n\t\t\ty += ROW_HEIGHT;\n\t\t});\n\t}\n\n\tupdate(data) {\n\t\tif(!data) {\n\t\t\tconsole.error('No data to update.');\n\t\t}\n\n\t\tthis.data = this.prepareData(data);\n\t\tthis.draw();\n\t\tthis.bindTooltip();\n\t}\n\n\tbindTooltip() {\n\t\tthis.container.addEventListener('mousemove', (e) => {\n\t\t\tthis.components.forEach(comp => {\n\t\t\t\tlet daySquares = comp.store;\n\t\t\t\tlet daySquare = e.target;\n\t\t\t\tif(daySquares.includes(daySquare)) {\n\n\t\t\t\t\tlet count = daySquare.getAttribute('data-value');\n\t\t\t\t\tlet dateParts = daySquare.getAttribute('data-date').split('-');\n\n\t\t\t\t\tlet month = getMonthName(parseInt(dateParts[1])-1, true);\n\n\t\t\t\t\tlet gOff = this.container.getBoundingClientRect(), pOff = daySquare.getBoundingClientRect();\n\n\t\t\t\t\tlet width = parseInt(e.target.getAttribute('width'));\n\t\t\t\t\tlet x = pOff.left - gOff.left + width/2;\n\t\t\t\t\tlet y = pOff.top - gOff.top;\n\t\t\t\t\tlet value = count + ' ' + this.countLabel;\n\t\t\t\t\tlet name = ' on ' + month + ' ' + dateParts[0] + ', ' + dateParts[2];\n\n\t\t\t\t\tthis.tip.setValues(x, y, {name: name, value: value, valueFirst: 1}, []);\n\t\t\t\t\tthis.tip.showTip();\n\t\t\t\t}\n\t\t\t});\n\t\t});\n\t}\n\n\trenderLegend() {\n\t\tthis.legendArea.textContent = '';\n\t\tlet x = 0;\n\t\tlet y = ROW_HEIGHT;\n\n\t\tlet lessText = makeText('subdomain-name', x, y, 'Less',\n\t\t\t{\n\t\t\t\tfontSize: HEATMAP_SQUARE_SIZE + 1,\n\t\t\t\tdy: 9\n\t\t\t}\n\t\t);\n\t\tx = (COL_WIDTH * 2) + COL_WIDTH/2;\n\t\tthis.legendArea.appendChild(lessText);\n\n\t\tthis.colors.slice(0, HEATMAP_DISTRIBUTION_SIZE).map((color, i) => {\n\t\t\tconst square = heatSquare('heatmap-legend-unit', x + (COL_WIDTH + 3) * i,\n\t\t\t\ty, HEATMAP_SQUARE_SIZE, color);\n\t\t\tthis.legendArea.appendChild(square);\n\t\t});\n\n\t\tlet moreTextX = x + HEATMAP_DISTRIBUTION_SIZE * (COL_WIDTH + 3) + COL_WIDTH/4;\n\t\tlet moreText = makeText('subdomain-name', moreTextX, y, 'More',\n\t\t\t{\n\t\t\t\tfontSize: HEATMAP_SQUARE_SIZE + 1,\n\t\t\t\tdy: 9\n\t\t\t}\n\t\t);\n\t\tthis.legendArea.appendChild(moreText);\n\t}\n\n\tgetDomains() {\n\t\tlet s = this.state;\n\t\tconst [startMonth, startYear] = [s.start.getMonth(), s.start.getFullYear()];\n\t\tconst [endMonth, endYear] = [s.end.getMonth(), s.end.getFullYear()];\n\n\t\tconst noOfMonths = (endMonth - startMonth + 1) + (endYear - startYear) * 12;\n\n\t\tlet domainConfigs = [];\n\n\t\tlet startOfMonth = clone(s.start);\n\t\tfor(var i = 0; i < noOfMonths; i++) {\n\t\t\tlet endDate = s.end;\n\t\t\tif(!areInSameMonth(startOfMonth, s.end)) {\n\t\t\t\tlet [month, year] = [startOfMonth.getMonth(), startOfMonth.getFullYear()];\n\t\t\t\tendDate = getLastDateInMonth(month, year);\n\t\t\t}\n\t\t\tdomainConfigs.push(this.getDomainConfig(startOfMonth, endDate));\n\n\t\t\taddDays(endDate, 1);\n\t\t\tstartOfMonth = endDate;\n\t\t}\n\n\t\treturn domainConfigs;\n\t}\n\n\tgetDomainConfig(startDate, endDate='') {\n\t\tlet [month, year] = [startDate.getMonth(), startDate.getFullYear()];\n\t\tlet startOfWeek = setDayToSunday(startDate); // TODO: Monday as well\n\t\tendDate = clone(endDate) || getLastDateInMonth(month, year);\n\n\t\tlet domainConfig = {\n\t\t\tindex: month,\n\t\t\tcols: []\n\t\t};\n\n\t\taddDays(endDate, 1);\n\t\tlet noOfMonthWeeks = getWeeksBetween(startOfWeek, endDate);\n\n\t\tlet cols = [], col;\n\t\tfor(var i = 0; i < noOfMonthWeeks; i++) {\n\t\t\tcol = this.getCol(startOfWeek, month);\n\t\t\tcols.push(col);\n\n\t\t\tstartOfWeek = new Date(col[NO_OF_DAYS_IN_WEEK - 1].yyyyMmDd);\n\t\t\taddDays(startOfWeek, 1);\n\t\t}\n\n\t\tif(col[NO_OF_DAYS_IN_WEEK - 1].dataValue !== undefined) {\n\t\t\taddDays(startOfWeek, 1);\n\t\t\tcols.push(this.getCol(startOfWeek, month, true));\n\t\t}\n\n\t\tdomainConfig.cols = cols;\n\n\t\treturn domainConfig;\n\t}\n\n\tgetCol(startDate, month, empty = false) {\n\t\tlet s = this.state;\n\n\t\t// startDate is the start of week\n\t\tlet currentDate = clone(startDate);\n\t\tlet col = [];\n\n\t\tfor(var i = 0; i < NO_OF_DAYS_IN_WEEK; i++, addDays(currentDate, 1)) {\n\t\t\tlet config = {};\n\n\t\t\t// Non-generic adjustment for entire heatmap, needs state\n\t\t\tlet currentDateWithinData = currentDate >= s.start && currentDate <= s.end;\n\n\t\t\tif(empty || currentDate.getMonth() !== month || !currentDateWithinData) {\n\t\t\t\tconfig.yyyyMmDd = getYyyyMmDd(currentDate);\n\t\t\t} else {\n\t\t\t\tconfig = this.getSubDomainConfig(currentDate);\n\t\t\t}\n\t\t\tcol.push(config);\n\t\t}\n\n\t\treturn col;\n\t}\n\n\tgetSubDomainConfig(date) {\n\t\tlet yyyyMmDd = getYyyyMmDd(date);\n\t\tlet dataValue = this.data.dataPoints[yyyyMmDd];\n\t\tlet config = {\n\t\t\tyyyyMmDd: yyyyMmDd,\n\t\t\tdataValue: dataValue || 0,\n\t\t\tfill: this.colors[getMaxCheckpoint(dataValue, this.state.distribution)]\n\t\t};\n\t\treturn config;\n\t}\n}\n\nfunction dataPrep(data, type) {\n\tdata.labels = data.labels || [];\n\n\tlet datasetLength = data.labels.length;\n\n\t// Datasets\n\tlet datasets = data.datasets;\n\tlet zeroArray = new Array(datasetLength).fill(0);\n\tif(!datasets) {\n\t\t// default\n\t\tdatasets = [{\n\t\t\tvalues: zeroArray\n\t\t}];\n\t}\n\n\tdatasets.map(d=> {\n\t\t// Set values\n\t\tif(!d.values) {\n\t\t\td.values = zeroArray;\n\t\t} else {\n\t\t\t// Check for non values\n\t\t\tlet vals = d.values;\n\t\t\tvals = vals.map(val => (!isNaN(val) ? val : 0));\n\n\t\t\t// Trim or extend\n\t\t\tif(vals.length > datasetLength) {\n\t\t\t\tvals = vals.slice(0, datasetLength);\n\t\t\t} else {\n\t\t\t\tvals = fillArray(vals, datasetLength - vals.length, 0);\n\t\t\t}\n\t\t}\n\n\t\t// Set labels\n\t\t//\n\n\t\t// Set type\n\t\tif(!d.chartType ) {\n\t\t\tif(!AXIS_DATASET_CHART_TYPES.includes(type)) type === DEFAULT_AXIS_CHART_TYPE;\n\t\t\td.chartType = type;\n\t\t}\n\n\t});\n\n\t// Markers\n\n\t// Regions\n\t// data.yRegions = data.yRegions || [];\n\tif(data.yRegions) {\n\t\tdata.yRegions.map(d => {\n\t\t\tif(d.end < d.start) {\n\t\t\t\t[d.start, d.end] = [d.end, d.start];\n\t\t\t}\n\t\t});\n\t}\n\n\treturn data;\n}\n\nfunction zeroDataPrep(realData) {\n\tlet datasetLength = realData.labels.length;\n\tlet zeroArray = new Array(datasetLength).fill(0);\n\n\tlet zeroData = {\n\t\tlabels: realData.labels.slice(0, -1),\n\t\tdatasets: realData.datasets.map(d => {\n\t\t\treturn {\n\t\t\t\tname: '',\n\t\t\t\tvalues: zeroArray.slice(0, -1),\n\t\t\t\tchartType: d.chartType\n\t\t\t};\n\t\t}),\n\t};\n\n\tif(realData.yMarkers) {\n\t\tzeroData.yMarkers = [\n\t\t\t{\n\t\t\t\tvalue: 0,\n\t\t\t\tlabel: ''\n\t\t\t}\n\t\t];\n\t}\n\n\tif(realData.yRegions) {\n\t\tzeroData.yRegions = [\n\t\t\t{\n\t\t\t\tstart: 0,\n\t\t\t\tend: 0,\n\t\t\t\tlabel: ''\n\t\t\t}\n\t\t];\n\t}\n\n\treturn zeroData;\n}\n\nfunction getShortenedLabels(chartWidth, labels=[], isSeries=true) {\n\tlet allowedSpace = chartWidth / labels.length;\n\tif(allowedSpace <= 0) allowedSpace = 1;\n\tlet allowedLetters = allowedSpace / DEFAULT_CHAR_WIDTH;\n\n\tlet calcLabels = labels.map((label, i) => {\n\t\tlabel += \"\";\n\t\tif(label.length > allowedLetters) {\n\n\t\t\tif(!isSeries) {\n\t\t\t\tif(allowedLetters-3 > 0) {\n\t\t\t\t\tlabel = label.slice(0, allowedLetters-3) + \" ...\";\n\t\t\t\t} else {\n\t\t\t\t\tlabel = label.slice(0, allowedLetters) + '..';\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tlet multiple = Math.ceil(label.length/allowedLetters);\n\t\t\t\tif(i % multiple !== 0) {\n\t\t\t\t\tlabel = \"\";\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn label;\n\t});\n\n\treturn calcLabels;\n}\n\nclass AxisChart extends BaseChart {\n\tconstructor(parent, args) {\n\t\tsuper(parent, args);\n\n\t\tthis.barOptions = args.barOptions || {};\n\t\tthis.lineOptions = args.lineOptions || {};\n\n\t\tthis.type = args.type || 'line';\n\t\tthis.init = 1;\n\n\t\tthis.setup();\n\t}\n\n\tsetMeasures() {\n\t\tif(this.data.datasets.length <= 1) {\n\t\t\tthis.config.showLegend = 0;\n\t\t\tthis.measures.paddings.bottom = 30;\n\t\t}\n\t}\n\n\tconfigure(options) {\n\t\tsuper.configure(options);\n\n\t\toptions.axisOptions = options.axisOptions || {};\n\t\toptions.tooltipOptions = options.tooltipOptions || {};\n\n\t\tthis.config.xAxisMode = options.axisOptions.xAxisMode || 'span';\n\t\tthis.config.yAxisMode = options.axisOptions.yAxisMode || 'span';\n\t\tthis.config.xIsSeries = options.axisOptions.xIsSeries || 0;\n\n\t\tthis.config.formatTooltipX = options.tooltipOptions.formatTooltipX;\n\t\tthis.config.formatTooltipY = options.tooltipOptions.formatTooltipY;\n\n\t\tthis.config.valuesOverPoints = options.valuesOverPoints;\n\t}\n\n\tprepareData(data=this.data) {\n\t\treturn dataPrep(data, this.type);\n\t}\n\n\tprepareFirstData(data=this.data) {\n\t\treturn zeroDataPrep(data);\n\t}\n\n\tcalc(onlyWidthChange = false) {\n\t\tthis.calcXPositions();\n\t\tif(!onlyWidthChange) {\n\t\t\tthis.calcYAxisParameters(this.getAllYValues(), this.type === 'line');\n\t\t}\n\t\tthis.makeDataByIndex();\n\t}\n\n\tcalcXPositions() {\n\t\tlet s = this.state;\n\t\tlet labels = this.data.labels;\n\t\ts.datasetLength = labels.length;\n\n\t\ts.unitWidth = this.width/(s.datasetLength);\n\t\t// Default, as per bar, and mixed. Only line will be a special case\n\t\ts.xOffset = s.unitWidth/2;\n\n\t\t// // For a pure Line Chart\n\t\t// s.unitWidth = this.width/(s.datasetLength - 1);\n\t\t// s.xOffset = 0;\n\n\t\ts.xAxis = {\n\t\t\tlabels: labels,\n\t\t\tpositions: labels.map((d, i) =>\n\t\t\t\tfloatTwo(s.xOffset + i * s.unitWidth)\n\t\t\t)\n\t\t};\n\t}\n\n\tcalcYAxisParameters(dataValues, withMinimum = 'false') {\n\t\tconst yPts = calcChartIntervals(dataValues, withMinimum);\n\t\tconst scaleMultiplier = this.height / getValueRange(yPts);\n\t\tconst intervalHeight = getIntervalSize(yPts) * scaleMultiplier;\n\t\tconst zeroLine = this.height - (getZeroIndex(yPts) * intervalHeight);\n\n\t\tthis.state.yAxis = {\n\t\t\tlabels: yPts,\n\t\t\tpositions: yPts.map(d => zeroLine - d * scaleMultiplier),\n\t\t\tscaleMultiplier: scaleMultiplier,\n\t\t\tzeroLine: zeroLine,\n\t\t};\n\n\t\t// Dependent if above changes\n\t\tthis.calcDatasetPoints();\n\t\tthis.calcYExtremes();\n\t\tthis.calcYRegions();\n\t}\n\n\tcalcDatasetPoints() {\n\t\tlet s = this.state;\n\t\tlet scaleAll = values => values.map(val => scale(val, s.yAxis));\n\n\t\ts.datasets = this.data.datasets.map((d, i) => {\n\t\t\tlet values = d.values;\n\t\t\tlet cumulativeYs = d.cumulativeYs || [];\n\t\t\treturn {\n\t\t\t\tname: d.name,\n\t\t\t\tindex: i,\n\t\t\t\tchartType: d.chartType,\n\n\t\t\t\tvalues: values,\n\t\t\t\tyPositions: scaleAll(values),\n\n\t\t\t\tcumulativeYs: cumulativeYs,\n\t\t\t\tcumulativeYPos: scaleAll(cumulativeYs),\n\t\t\t};\n\t\t});\n\t}\n\n\tcalcYExtremes() {\n\t\tlet s = this.state;\n\t\tif(this.barOptions.stacked) {\n\t\t\ts.yExtremes = s.datasets[s.datasets.length - 1].cumulativeYPos;\n\t\t\treturn;\n\t\t}\n\t\ts.yExtremes = new Array(s.datasetLength).fill(9999);\n\t\ts.datasets.map(d => {\n\t\t\td.yPositions.map((pos, j) => {\n\t\t\t\tif(pos < s.yExtremes[j]) {\n\t\t\t\t\ts.yExtremes[j] = pos;\n\t\t\t\t}\n\t\t\t});\n\t\t});\n\t}\n\n\tcalcYRegions() {\n\t\tlet s = this.state;\n\t\tif(this.data.yMarkers) {\n\t\t\tthis.state.yMarkers = this.data.yMarkers.map(d => {\n\t\t\t\td.position = scale(d.value, s.yAxis);\n\t\t\t\tif(!d.options) d.options = {};\n\t\t\t\t// if(!d.label.includes(':')) {\n\t\t\t\t// \td.label += ': ' + d.value;\n\t\t\t\t// }\n\t\t\t\treturn d;\n\t\t\t});\n\t\t}\n\t\tif(this.data.yRegions) {\n\t\t\tthis.state.yRegions = this.data.yRegions.map(d => {\n\t\t\t\td.startPos = scale(d.start, s.yAxis);\n\t\t\t\td.endPos = scale(d.end, s.yAxis);\n\t\t\t\tif(!d.options) d.options = {};\n\t\t\t\treturn d;\n\t\t\t});\n\t\t}\n\t}\n\n\tgetAllYValues() {\n\t\tlet key = 'values';\n\n\t\tif(this.barOptions.stacked) {\n\t\t\tkey = 'cumulativeYs';\n\t\t\tlet cumulative = new Array(this.state.datasetLength).fill(0);\n\t\t\tthis.data.datasets.map((d, i) => {\n\t\t\t\tlet values = this.data.datasets[i].values;\n\t\t\t\td[key] = cumulative = cumulative.map((c, i) => c + values[i]);\n\t\t\t});\n\t\t}\n\n\t\tlet allValueLists = this.data.datasets.map(d => d[key]);\n\t\tif(this.data.yMarkers) {\n\t\t\tallValueLists.push(this.data.yMarkers.map(d => d.value));\n\t\t}\n\t\tif(this.data.yRegions) {\n\t\t\tthis.data.yRegions.map(d => {\n\t\t\t\tallValueLists.push([d.end, d.start]);\n\t\t\t});\n\t\t}\n\n\t\treturn [].concat(...allValueLists);\n\t}\n\n\tsetupComponents() {\n\t\tlet componentConfigs = [\n\t\t\t[\n\t\t\t\t'yAxis',\n\t\t\t\t{\n\t\t\t\t\tmode: this.config.yAxisMode,\n\t\t\t\t\twidth: this.width,\n\t\t\t\t\t// pos: 'right'\n\t\t\t\t},\n\t\t\t\tfunction() {\n\t\t\t\t\treturn this.state.yAxis;\n\t\t\t\t}.bind(this)\n\t\t\t],\n\n\t\t\t[\n\t\t\t\t'xAxis',\n\t\t\t\t{\n\t\t\t\t\tmode: this.config.xAxisMode,\n\t\t\t\t\theight: this.height,\n\t\t\t\t\t// pos: 'right'\n\t\t\t\t},\n\t\t\t\tfunction() {\n\t\t\t\t\tlet s = this.state;\n\t\t\t\t\ts.xAxis.calcLabels = getShortenedLabels(this.width,\n\t\t\t\t\t\ts.xAxis.labels, this.config.xIsSeries);\n\n\t\t\t\t\treturn s.xAxis;\n\t\t\t\t}.bind(this)\n\t\t\t],\n\n\t\t\t[\n\t\t\t\t'yRegions',\n\t\t\t\t{\n\t\t\t\t\twidth: this.width,\n\t\t\t\t\tpos: 'right'\n\t\t\t\t},\n\t\t\t\tfunction() {\n\t\t\t\t\treturn this.state.yRegions;\n\t\t\t\t}.bind(this)\n\t\t\t],\n\t\t];\n\n\t\tlet barDatasets = this.state.datasets.filter(d => d.chartType === 'bar');\n\t\tlet lineDatasets = this.state.datasets.filter(d => d.chartType === 'line');\n\n\t\tlet barsConfigs = barDatasets.map(d => {\n\t\t\tlet index = d.index;\n\t\t\treturn [\n\t\t\t\t'barGraph' + '-' + d.index,\n\t\t\t\t{\n\t\t\t\t\tindex: index,\n\t\t\t\t\tcolor: this.colors[index],\n\t\t\t\t\tstacked: this.barOptions.stacked,\n\n\t\t\t\t\t// same for all datasets\n\t\t\t\t\tvaluesOverPoints: this.config.valuesOverPoints,\n\t\t\t\t\tminHeight: this.height * MIN_BAR_PERCENT_HEIGHT,\n\t\t\t\t},\n\t\t\t\tfunction() {\n\t\t\t\t\tlet s = this.state;\n\t\t\t\t\tlet d = s.datasets[index];\n\t\t\t\t\tlet stacked = this.barOptions.stacked;\n\n\t\t\t\t\tlet spaceRatio = this.barOptions.spaceRatio || BAR_CHART_SPACE_RATIO;\n\t\t\t\t\tlet barsWidth = s.unitWidth * (1 - spaceRatio);\n\t\t\t\t\tlet barWidth = barsWidth/(stacked ? 1 : barDatasets.length);\n\n\t\t\t\t\tlet xPositions = s.xAxis.positions.map(x => x - barsWidth/2);\n\t\t\t\t\tif(!stacked) {\n\t\t\t\t\t\txPositions = xPositions.map(p => p + barWidth * index);\n\t\t\t\t\t}\n\n\t\t\t\t\tlet labels = new Array(s.datasetLength).fill('');\n\t\t\t\t\tif(this.config.valuesOverPoints) {\n\t\t\t\t\t\tif(stacked && d.index === s.datasets.length - 1) {\n\t\t\t\t\t\t\tlabels = d.cumulativeYs;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tlabels = d.values;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tlet offsets = new Array(s.datasetLength).fill(0);\n\t\t\t\t\tif(stacked) {\n\t\t\t\t\t\toffsets = d.yPositions.map((y, j) => y - d.cumulativeYPos[j]);\n\t\t\t\t\t}\n\n\t\t\t\t\treturn {\n\t\t\t\t\t\txPositions: xPositions,\n\t\t\t\t\t\tyPositions: d.yPositions,\n\t\t\t\t\t\toffsets: offsets,\n\t\t\t\t\t\t// values: d.values,\n\t\t\t\t\t\tlabels: labels,\n\n\t\t\t\t\t\tzeroLine: s.yAxis.zeroLine,\n\t\t\t\t\t\tbarsWidth: barsWidth,\n\t\t\t\t\t\tbarWidth: barWidth,\n\t\t\t\t\t};\n\t\t\t\t}.bind(this)\n\t\t\t];\n\t\t});\n\n\t\tlet lineConfigs = lineDatasets.map(d => {\n\t\t\tlet index = d.index;\n\t\t\treturn [\n\t\t\t\t'lineGraph' + '-' + d.index,\n\t\t\t\t{\n\t\t\t\t\tindex: index,\n\t\t\t\t\tcolor: this.colors[index],\n\t\t\t\t\tsvgDefs: this.svgDefs,\n\t\t\t\t\theatline: this.lineOptions.heatline,\n\t\t\t\t\tregionFill: this.lineOptions.regionFill,\n\t\t\t\t\thideDots: this.lineOptions.hideDots,\n\t\t\t\t\thideLine: this.lineOptions.hideLine,\n\n\t\t\t\t\t// same for all datasets\n\t\t\t\t\tvaluesOverPoints: this.config.valuesOverPoints,\n\t\t\t\t},\n\t\t\t\tfunction() {\n\t\t\t\t\tlet s = this.state;\n\t\t\t\t\tlet d = s.datasets[index];\n\t\t\t\t\tlet minLine = s.yAxis.positions[0] < s.yAxis.zeroLine\n\t\t\t\t\t\t? s.yAxis.positions[0] : s.yAxis.zeroLine;\n\n\t\t\t\t\treturn {\n\t\t\t\t\t\txPositions: s.xAxis.positions,\n\t\t\t\t\t\tyPositions: d.yPositions,\n\n\t\t\t\t\t\tvalues: d.values,\n\n\t\t\t\t\t\tzeroLine: minLine,\n\t\t\t\t\t\tradius: this.lineOptions.dotSize || LINE_CHART_DOT_SIZE,\n\t\t\t\t\t};\n\t\t\t\t}.bind(this)\n\t\t\t];\n\t\t});\n\n\t\tlet markerConfigs = [\n\t\t\t[\n\t\t\t\t'yMarkers',\n\t\t\t\t{\n\t\t\t\t\twidth: this.width,\n\t\t\t\t\tpos: 'right'\n\t\t\t\t},\n\t\t\t\tfunction() {\n\t\t\t\t\treturn this.state.yMarkers;\n\t\t\t\t}.bind(this)\n\t\t\t]\n\t\t];\n\n\t\tcomponentConfigs = componentConfigs.concat(barsConfigs, lineConfigs, markerConfigs);\n\n\t\tlet optionals = ['yMarkers', 'yRegions'];\n\t\tthis.dataUnitComponents = [];\n\n\t\tthis.components = new Map(componentConfigs\n\t\t\t.filter(args => !optionals.includes(args[0]) || this.state[args[0]])\n\t\t\t.map(args => {\n\t\t\t\tlet component = getComponent(...args);\n\t\t\t\tif(args[0].includes('lineGraph') || args[0].includes('barGraph')) {\n\t\t\t\t\tthis.dataUnitComponents.push(component);\n\t\t\t\t}\n\t\t\t\treturn [args[0], component];\n\t\t\t}));\n\t}\n\n\tmakeDataByIndex() {\n\t\tthis.dataByIndex = {};\n\n\t\tlet s = this.state;\n\t\tlet formatX = this.config.formatTooltipX;\n\t\tlet formatY = this.config.formatTooltipY;\n\t\tlet titles = s.xAxis.labels;\n\n\t\ttitles.map((label, index) => {\n\t\t\tlet values = this.state.datasets.map((set, i) => {\n\t\t\t\tlet value = set.values[index];\n\t\t\t\treturn {\n\t\t\t\t\ttitle: set.name,\n\t\t\t\t\tvalue: value,\n\t\t\t\t\tyPos: set.yPositions[index],\n\t\t\t\t\tcolor: this.colors[i],\n\t\t\t\t\tformatted: formatY ? formatY(value) : value,\n\t\t\t\t};\n\t\t\t});\n\n\t\t\tthis.dataByIndex[index] = {\n\t\t\t\tlabel: label,\n\t\t\t\tformattedLabel: formatX ? formatX(label) : label,\n\t\t\t\txPos: s.xAxis.positions[index],\n\t\t\t\tvalues: values,\n\t\t\t\tyExtreme: s.yExtremes[index],\n\t\t\t};\n\t\t});\n\t}\n\n\tbindTooltip() {\n\t\t// NOTE: could be in tooltip itself, as it is a given functionality for its parent\n\t\tthis.container.addEventListener('mousemove', (e) => {\n\t\t\tlet m = this.measures;\n\t\t\tlet o = getOffset(this.container);\n\t\t\tlet relX = e.pageX - o.left - getLeftOffset(m);\n\t\t\tlet relY = e.pageY - o.top;\n\n\t\t\tif(relY < this.height + getTopOffset(m)\n\t\t\t\t&& relY > getTopOffset(m)) {\n\t\t\t\tthis.mapTooltipXPosition(relX);\n\t\t\t} else {\n\t\t\t\tthis.tip.hideTip();\n\t\t\t}\n\t\t});\n\t}\n\n\tmapTooltipXPosition(relX) {\n\t\tlet s = this.state;\n\t\tif(!s.yExtremes) return;\n\n\t\tlet index = getClosestInArray(relX, s.xAxis.positions, true);\n\t\tlet dbi = this.dataByIndex[index];\n\n\t\tthis.tip.setValues(\n\t\t\tdbi.xPos + this.tip.offset.x,\n\t\t\tdbi.yExtreme + this.tip.offset.y,\n\t\t\t{name: dbi.formattedLabel, value: ''},\n\t\t\tdbi.values,\n\t\t\tindex\n\t\t);\n\n\t\tthis.tip.showTip();\n\t}\n\n\trenderLegend() {\n\t\tlet s = this.data;\n\t\tif(s.datasets.length > 1) {\n\t\t\tthis.legendArea.textContent = '';\n\t\t\ts.datasets.map((d, i) => {\n\t\t\t\tlet barWidth = AXIS_LEGEND_BAR_SIZE;\n\t\t\t\t// let rightEndPoint = this.baseWidth - this.measures.margins.left - this.measures.margins.right;\n\t\t\t\t// let multiplier = s.datasets.length - i;\n\t\t\t\tlet rect = legendBar(\n\t\t\t\t\t// rightEndPoint - multiplier * barWidth,\t// To right align\n\t\t\t\t\tbarWidth * i,\n\t\t\t\t\t'0',\n\t\t\t\t\tbarWidth,\n\t\t\t\t\tthis.colors[i],\n\t\t\t\t\td.name);\n\t\t\t\tthis.legendArea.appendChild(rect);\n\t\t\t});\n\t\t}\n\t}\n\n\n\n\t// Overlay\n\tmakeOverlay() {\n\t\tif(this.init) {\n\t\t\tthis.init = 0;\n\t\t\treturn;\n\t\t}\n\t\tif(this.overlayGuides) {\n\t\t\tthis.overlayGuides.forEach(g => {\n\t\t\t\tlet o = g.overlay;\n\t\t\t\to.parentNode.removeChild(o);\n\t\t\t});\n\t\t}\n\n\t\tthis.overlayGuides = this.dataUnitComponents.map(c => {\n\t\t\treturn {\n\t\t\t\ttype: c.unitType,\n\t\t\t\toverlay: undefined,\n\t\t\t\tunits: c.units,\n\t\t\t};\n\t\t});\n\n\t\tif(this.state.currentIndex === undefined) {\n\t\t\tthis.state.currentIndex = this.state.datasetLength - 1;\n\t\t}\n\n\t\t// Render overlays\n\t\tthis.overlayGuides.map(d => {\n\t\t\tlet currentUnit = d.units[this.state.currentIndex];\n\n\t\t\td.overlay = makeOverlay[d.type](currentUnit);\n\t\t\tthis.drawArea.appendChild(d.overlay);\n\t\t});\n\t}\n\n\tupdateOverlayGuides() {\n\t\tif(this.overlayGuides) {\n\t\t\tthis.overlayGuides.forEach(g => {\n\t\t\t\tlet o = g.overlay;\n\t\t\t\to.parentNode.removeChild(o);\n\t\t\t});\n\t\t}\n\t}\n\n\tbindOverlay() {\n\t\tthis.parent.addEventListener('data-select', () => {\n\t\t\tthis.updateOverlay();\n\t\t});\n\t}\n\n\tbindUnits() {\n\t\tthis.dataUnitComponents.map(c => {\n\t\t\tc.units.map(unit => {\n\t\t\t\tunit.addEventListener('click', () => {\n\t\t\t\t\tlet index = unit.getAttribute('data-point-index');\n\t\t\t\t\tthis.setCurrentDataPoint(index);\n\t\t\t\t});\n\t\t\t});\n\t\t});\n\n\t\t// Note: Doesn't work as tooltip is absolutely positioned\n\t\tthis.tip.container.addEventListener('click', () => {\n\t\t\tlet index = this.tip.container.getAttribute('data-point-index');\n\t\t\tthis.setCurrentDataPoint(index);\n\t\t});\n\t}\n\n\tupdateOverlay() {\n\t\tthis.overlayGuides.map(d => {\n\t\t\tlet currentUnit = d.units[this.state.currentIndex];\n\t\t\tupdateOverlay[d.type](currentUnit, d.overlay);\n\t\t});\n\t}\n\n\tonLeftArrow() {\n\t\tthis.setCurrentDataPoint(this.state.currentIndex - 1);\n\t}\n\n\tonRightArrow() {\n\t\tthis.setCurrentDataPoint(this.state.currentIndex + 1);\n\t}\n\n\tgetDataPoint(index=this.state.currentIndex) {\n\t\tlet s = this.state;\n\t\tlet data_point = {\n\t\t\tindex: index,\n\t\t\tlabel: s.xAxis.labels[index],\n\t\t\tvalues: s.datasets.map(d => d.values[index])\n\t\t};\n\t\treturn data_point;\n\t}\n\n\tsetCurrentDataPoint(index) {\n\t\tlet s = this.state;\n\t\tindex = parseInt(index);\n\t\tif(index < 0) index = 0;\n\t\tif(index >= s.xAxis.labels.length) index = s.xAxis.labels.length - 1;\n\t\tif(index === s.currentIndex) return;\n\t\ts.currentIndex = index;\n\t\tfire(this.parent, \"data-select\", this.getDataPoint());\n\t}\n\n\n\n\t// API\n\taddDataPoint(label, datasetValues, index=this.state.datasetLength) {\n\t\tsuper.addDataPoint(label, datasetValues, index);\n\t\tthis.data.labels.splice(index, 0, label);\n\t\tthis.data.datasets.map((d, i) => {\n\t\t\td.values.splice(index, 0, datasetValues[i]);\n\t\t});\n\t\tthis.update(this.data);\n\t}\n\n\tremoveDataPoint(index = this.state.datasetLength-1) {\n\t\tif (this.data.labels.length <= 1) {\n\t\t\treturn;\n\t\t}\n\t\tsuper.removeDataPoint(index);\n\t\tthis.data.labels.splice(index, 1);\n\t\tthis.data.datasets.map(d => {\n\t\t\td.values.splice(index, 1);\n\t\t});\n\t\tthis.update(this.data);\n\t}\n\n\tupdateDataset(datasetValues, index=0) {\n\t\tthis.data.datasets[index].values = datasetValues;\n\t\tthis.update(this.data);\n\t}\n\t// addDataset(dataset, index) {}\n\t// removeDataset(index = 0) {}\n\n\tupdateDatasets(datasets) {\n\t\tthis.data.datasets.map((d, i) => {\n\t\t\tif(datasets[i]) {\n\t\t\t\td.values = datasets[i];\n\t\t\t}\n\t\t});\n\t\tthis.update(this.data);\n\t}\n\n\t// updateDataPoint(dataPoint, index = 0) {}\n\t// addDataPoint(dataPoint, index = 0) {}\n\t// removeDataPoint(index = 0) {}\n}\n\nconst chartTypes = {\n\tbar: AxisChart,\n\tline: AxisChart,\n\t// multiaxis: MultiAxisChart,\n\tpercentage: PercentageChart,\n\theatmap: Heatmap,\n\tpie: PieChart\n};\n\nfunction getChartByType(chartType = 'line', parent, options) {\n\tif (chartType === 'axis-mixed') {\n\t\toptions.type = 'line';\n\t\treturn new AxisChart(parent, options);\n\t}\n\n\tif (!chartTypes[chartType]) {\n\t\tconsole.error(\"Undefined chart type: \" + chartType);\n\t\treturn;\n\t}\n\n\treturn new chartTypes[chartType](parent, options);\n}\n\nclass Chart {\n\tconstructor(parent, options) {\n\t\treturn getChartByType(options.type, parent, options);\n\t}\n}\n\nexport { Chart, PercentageChart, PieChart, Heatmap, AxisChart };\n","/*\n * This file is part of Flarum.\n *\n * (c) Toby Zerner <toby.zerner@gmail.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nimport DashboardWidget from 'flarum/components/DashboardWidget';\nimport SelectDropdown from 'flarum/components/SelectDropdown';\nimport Button from 'flarum/components/Button';\nimport icon from 'flarum/helpers/icon';\nimport abbreviateNumber from 'flarum/utils/abbreviateNumber';\n\nimport { Chart } from 'frappe-charts/dist/frappe-charts.esm.js';\n\nexport default class StatisticsWidget extends DashboardWidget {\n init() {\n super.init();\n\n // Create a Date object which represents the start of the day in the\n // configured timezone. To do this we convert a UTC time into that timezone,\n // reset to the first hour of the day, and then convert back into UTC time.\n // We'll be working with seconds rather than milliseconds throughout too.\n let today = new Date();\n today.setTime(today.getTime() + app.data.statistics.timezoneOffset * 1000);\n today.setUTCHours(0, 0, 0, 0);\n today.setTime(today.getTime() - app.data.statistics.timezoneOffset * 1000);\n today = today / 1000;\n\n this.entities = ['users', 'discussions', 'posts'];\n this.periods = {\n today: {start: today, end: today + 86400, step: 3600},\n last_7_days: {start: today - 86400 * 7, end: today, step: 86400},\n last_28_days: {start: today - 86400 * 28, end: today, step: 86400},\n last_12_months: {start: today - 86400 * 364, end: today, step: 86400 * 7}\n };\n\n this.selectedEntity = 'users';\n this.selectedPeriod = 'last_7_days';\n }\n\n className() {\n return 'StatisticsWidget';\n }\n\n content() {\n const thisPeriod = this.periods[this.selectedPeriod];\n\n return (\n <div className=\"StatisticsWidget-table\">\n <div className=\"StatisticsWidget-labels\">\n <div className=\"StatisticsWidget-label\">{app.translator.trans('flarum-statistics.admin.statistics.total_label')}</div>\n <div className=\"StatisticsWidget-label\">\n <SelectDropdown buttonClassName=\"Button Button--text\" caretIcon=\"fas fa-caret-down\">\n {Object.keys(this.periods).map(period => (\n <Button\n active={period === this.selectedPeriod}\n onclick={this.changePeriod.bind(this, period)}\n icon={period === this.selectedPeriod ? 'fas fa-check' : true}>\n {app.translator.trans(`flarum-statistics.admin.statistics.${period}_label`)}\n </Button>\n ))}\n </SelectDropdown>\n </div>\n </div>\n\n {this.entities.map(entity => {\n const totalCount = this.getTotalCount(entity);\n const thisPeriodCount = this.getPeriodCount(entity, thisPeriod);\n const lastPeriodCount = this.getPeriodCount(entity, this.getLastPeriod(thisPeriod));\n const periodChange = lastPeriodCount > 0 && (thisPeriodCount - lastPeriodCount) / lastPeriodCount * 100;\n\n return (\n <a className={'StatisticsWidget-entity'+(this.selectedEntity === entity ? ' active' : '')} onclick={this.changeEntity.bind(this, entity)}>\n <h3 className=\"StatisticsWidget-heading\">{app.translator.trans('flarum-statistics.admin.statistics.'+entity+'_heading')}</h3>\n <div className=\"StatisticsWidget-total\" title={totalCount}>{abbreviateNumber(totalCount)}</div>\n <div className=\"StatisticsWidget-period\" title={thisPeriodCount}>\n {abbreviateNumber(thisPeriodCount)}{' '}\n {periodChange ? (\n <span className={'StatisticsWidget-change StatisticsWidget-change--'+(periodChange > 0 ? 'up' : 'down')}>\n {icon('fas fa-arrow-'+(periodChange > 0 ? 'up' : 'down'))}\n {Math.abs(periodChange.toFixed(1))}%\n </span>\n ) : ''}\n </div>\n </a>\n );\n })}\n\n <div className=\"StatisticsWidget-chart\" config={this.drawChart.bind(this)}/>\n </div>\n );\n }\n\n drawChart(elm, isInitialized, context) {\n if (context.chart && context.entity === this.selectedEntity && context.period === this.selectedPeriod) {\n return;\n }\n\n const offset = app.data.statistics.timezoneOffset;\n const period = this.periods[this.selectedPeriod];\n const periodLength = period.end - period.start;\n const labels = [];\n const thisPeriod = [];\n const lastPeriod = [];\n\n for (let i = period.start; i < period.end; i += period.step) {\n let label;\n\n if (period.step < 86400) {\n label = moment.unix(i + offset).utc().format('h A');\n } else {\n label = moment.unix(i + offset).utc().format('D MMM');\n\n if (period.step > 86400) {\n label += ' - ' + moment.unix(i + offset + period.step - 1).utc().format('D MMM');\n }\n }\n\n labels.push(label);\n\n thisPeriod.push(this.getPeriodCount(this.selectedEntity, {start: i, end: i + period.step}));\n\n lastPeriod.push(this.getPeriodCount(this.selectedEntity, {start: i - periodLength, end: i - periodLength + period.step}));\n }\n\n const datasets = [\n {values: lastPeriod},\n {values: thisPeriod}\n ];\n const data = {\n labels,\n datasets\n };\n\n if (!context.chart) {\n context.chart = new Chart(elm, {\n data,\n type: 'line',\n height: 280,\n axisOptions: {\n xAxisMode: 'tick',\n yAxisMode: 'span',\n xIsSeries: true\n },\n lineOptions: {\n hideDots: 1\n },\n colors: ['black', app.forum.attribute('themePrimaryColor')]\n });\n } else {\n context.chart.update(data);\n }\n\n context.entity = this.selectedEntity;\n context.period = this.selectedPeriod;\n }\n\n changeEntity(entity) {\n this.selectedEntity = entity;\n }\n\n changePeriod(period) {\n this.selectedPeriod = period;\n }\n\n getTotalCount(entity) {\n return app.data.statistics[entity].total;\n }\n\n getPeriodCount(entity, period) {\n const timed = app.data.statistics[entity].timed;\n let count = 0;\n\n for (const time in timed) {\n if (time >= period.start && time < period.end) {\n count += timed[time];\n }\n }\n\n return count;\n }\n\n getLastPeriod(thisPeriod) {\n return {\n start: thisPeriod.start - (thisPeriod.end - thisPeriod.start),\n end: thisPeriod.start\n };\n }\n}\n","export default function _inheritsLoose(subClass, superClass) {\n subClass.prototype = Object.create(superClass.prototype);\n subClass.prototype.constructor = subClass;\n subClass.__proto__ = superClass;\n}","import app from 'flarum/app';\nimport { extend } from 'flarum/extend';\n\nimport DashboardPage from 'flarum/components/DashboardPage';\n\nimport StatisticsWidget from './components/StatisticsWidget';\n\napp.initializers.add('flarum-statistics', () => {\n extend(DashboardPage.prototype, 'availableWidgets', widgets => {\n widgets.push(<StatisticsWidget/>);\n });\n});\n"],"sourceRoot":""} |