mirror of
https://github.com/flarum/framework.git
synced 2024-12-12 14:13:37 +08:00
b1415b4d3c
Includes transpiled JS/TS. [skip ci]
1 line
205 KiB
Plaintext
Generated
1 line
205 KiB
Plaintext
Generated
{"version":3,"sources":["webpack://@flarum/statistics/webpack/bootstrap","webpack://@flarum/statistics/external \"flarum.core.compat['admin/app']\"","webpack://@flarum/statistics/external \"flarum.core.compat['common/utils/abbreviateNumber']\"","webpack://@flarum/statistics/external \"flarum.core.compat['common/extend']\"","webpack://@flarum/statistics/external \"flarum.core.compat['admin/components/DashboardPage']\"","webpack://@flarum/statistics/external \"flarum.core.compat['admin/components/DashboardWidget']\"","webpack://@flarum/statistics/external \"flarum.core.compat['common/components/SelectDropdown']\"","webpack://@flarum/statistics/external \"flarum.core.compat['common/components/Button']\"","webpack://@flarum/statistics/external \"flarum.core.compat['common/helpers/icon']\"","webpack://@flarum/statistics/./node_modules/@babel/runtime/helpers/esm/setPrototypeOf.js","webpack://@flarum/statistics/./node_modules/@babel/runtime/helpers/esm/inheritsLoose.js","webpack://@flarum/statistics/./node_modules/frappe-charts/dist/frappe-charts.esm.js","webpack://@flarum/statistics/./src/admin/components/StatisticsWidget.js","webpack://@flarum/statistics/./src/admin/index.tsx"],"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","_setPrototypeOf","setPrototypeOf","__proto__","_inheritsLoose","subClass","superClass","constructor","$","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","AXIS_DATASET_CHART_TYPES","DEFAULT_CHART_COLORS","DEFAULT_COLORS","bar","line","pie","percentage","heatmap","donut","ANGLE_RATIO","Math","PI","SvgTip","parent","colors","this","titleName","titleValue","listValues","titleValueFirst","x","y","setup","makeTooltip","refresh","fill","calcPosition","container","inside","className","innerHTML","hideTip","title","dataPointList","addEventListener","index","set","color","formatted","li","styles","width","offsetWidth","offsetHeight","maxLeft","pointer","pointerOffset","setValues","valueFirst","opacity","showTip","floatTwo","parseFloat","toFixed","fillArray","array","count","start","length","fillerArray","Array","abs","concat","getStringWidth","string","charWidth","getPositionByAngle","angle","radius","sin","cos","isValidNumber","candidate","nonNegative","Number","isNaN","undefined","isFinite","getBarHeightAndYAttr","yTop","zeroLine","height","equilizeNoOfElements","array1","array2","extraCount","truncateString","txt","len","slice","getSplineCurvePointsStr","xList","yList","points","push","controlPoint","current","previous","next","reverse","pointA","pointB","lengthX","lengthY","sqrt","pow","atan2","command","reduce","acc","point","a","pointStr","cps","cpe","PRESET_COLOR_MAP","limitColor","lightenDarkenColor","amt","col","getColor","usePound","num","parseInt","b","toString","test","exec","ch","$$1","createSVG","createElementNS","setGradientStop","gradElem","offset","makeSVGGroup","transform","args","makePath","pathStr","stroke","strokeWidth","makeGradient","svgDefElem","lighter","gradientId","gradientDef","id","x1","x2","y1","y2","renderVerticalGradient","opacities","heatSquare","size","data","rx","makeText","content","options","fontSize","dy","textAnchor","makeHoriLine","label","lineType","shortenNumbers","number","floor","log10","shortened","round","shortenLargeNumber","text","FONT_SIZE","xLine","pos","makeVertLine","makeOverlay","unit","transformValue","nodeName","getAttribute","childNodes","overlay","cloneNode","updateOverlay","attributes","values","filter","attr","includes","specified","nodeValue","translate","oldCoord","newCoord","duration","old","join","translateHoriLine","yLine","newY","oldY","animatePathStr","oldPath","EASING","ease","linear","easein","easeout","easeinout","animateSVGElement","props","dur","easingType","type","oldValues","animElement","newElement","attributeName","animateElement","currentValue","animAttr","from","to","begin","keySplines","keyTimes","calcMode","webkitTransform","msTransform","mozTransform","oTransform","animateSVG","svgContainer","elements","newElements","animElements","replaceChild","animSvg","BaseChart","deepClone","cloned","Date","getTime","isArray","HTMLElement","Error","rawChartArgs","realData","prepareData","prepareFirstData","validateColors","config","showTooltip","showLegend","isNavigable","animate","truncateLegends","measures","JSON","parse","stringify","setMeasures","argHeight","state","initTimeout","overlays","configure","validColors","forEach","isValidColor","console","warn","boundDrawFn","draw","ResizeObserver","resizeObserver","observe","window","destroy","disconnect","removeEventListener","makeContainer","updateWidth","independentWidth","tip","bindTooltip","onlyWidthChange","init","offsetParent","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","event","keyCode","addDataPoint","removeDataPoint","getDataPoint","setCurrentDataPoint","updateDataset","chartSvg","clone","classList","add","styleEl","firstChild","prepareForExport","filename","blob","Blob","url","URL","createObjectURL","href","download","click","revokeObjectURL","downloadFile","AggregationChart","formatTooltipY","tooltipOptions","maxSlices","maxLegendPoints","sliceTotals","allTotals","labels","total","datasets","totals","sort","remaining","sumOfRemaining","grandTotal","center","textContent","legendTotals","barWidth","divisor","dot","truncate","cx","cy","dx","group","legendDot","MONTH_NAMES","DAY_NAMES_SHORT","treatAsUtc","date","result","setMinutes","getMinutes","getTimezoneOffset","getYyyyMmDd","dd","getDate","mm","getMonth","getFullYear","getWeeksBetween","startDate","endDate","weekStartDate","setDayToSunday","ceil","SEC_IN_DAY","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","donutSlices","sliceStrings","transition","newData","pieSlices","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","offsets","barsWidth","newXPos","newYPos","newOffsets","oldXPos","oldYPos","oldOffsets","rectAnim","oldCoordStr","split","animateBar","lineGraph","paths","hideLine","pointsStr","spline","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","PercentageChart","barOptions","component","xPos","makeDataByIndex","bars","target","indexOf","gOff","pOff","formattedLabels","fraction","PieChart","mouseMove","mouseLeave","hoverRadio","startAngle","clockWise","prevSlicesProperties","slicesProperties","curAngle","curStart","curEnd","originDiffAngle","largeArc","diffAngle","endAngle","startPosition","endPosition","prevProperty","curPath","arcStartX","arcStartY","arcEndX","midArc","arcEndY","makeCircleStr","makeArcPathStr","calTranslateByAngle","hoverSlice","flag","g_off","pageX","pageY","formatted_labels","percent","slices","prevIndex","curActiveSliceIndex","prevAcitve","curActiveSlice","normalize","mantissa","exponent","sig","exp","getChartIntervals","maxValue","minValue","normalMaxValue","normalMinValue","intervals","max","min","upperBound","lowerBound","range","noOfParts","partSize","getChartRangeIntervals","getIntervalSize","orderedArray","scale","scaleMultiplier","Heatmap","countLabel","validStarts","startSubDomain","startSubDomainIndex","discreteDomains","ROW_HEIGHT","spacing","HEATMAP_SQUARE_SIZE","end","noOfWeeks","setFullYear","dataPoints","timestampSec$$1","firstWeekStart","distribution","distributionSize","dataMaxValue","distributionStep","checkpoint","calcDistribution","domainConfigs","getDomains","lessCol","dayName","dayText","comp","daySquares","daySquare","dateParts","lessText","COL_WIDTH","moreText","HEATMAP_DISTRIBUTION_SIZE","startMonth","startYear","noOfMonths","startOfMonth","getDomainConfig","startOfWeek","domainConfig","noOfMonthWeeks","getCol","NO_OF_DAYS_IN_WEEK","empty","currentDate","currentDateWithinData","getSubDomainConfig","AxisChart","lineOptions","axisOptions","xAxisMode","yAxisMode","xIsSeries","shortenYAxisNumbers","formatTooltipX","datasetLength","zeroArray","vals","chartType","dataPrep","zeroData","calcXPositions","calcYAxisParameters","getAllYValues","unitWidth","xOffset","dataValues","withMinimum","yPts","getPositiveFirstIntervals","absMinValue","intervalSize","unshift","pseudoMaxValue","pseudoMinValue","calcChartIntervals","intervalHeight","zeroIndex","interval","getZeroIndex","calcDatasetPoints","calcYExtremes","calcYRegions","scaleAll","cumulativeYs","replace","char","cumulativeYPos","stacked","yExtremes","cumulative","allValueLists","chartWidth","isSeries","allowedSpace","seriesMultiple","allowedLetters","maxLabelLength","getShortenedLabels","barDatasets","lineDatasets","barsConfigs","spaceRatio","lineConfigs","minLine","dotSize","markerConfigs","optionals","dataUnitComponents","dataByIndex","formatX","formatY","yPos","formattedLabel","yExtreme","relX","relY","mapTooltipXPosition","goal","arr","closest","prev","curr","getClosestInArray","dbi","legendBar","overlayGuides","g","currentIndex","currentUnit","updateOverlayGuides","properties","evt","createEvent","initEvent","dispatchEvent","fire","datasetValues","splice","updateDatasets","chartTypes","makeStrokeCircleStr","makeArcStrokePathStr","Chart","getChartByType","StatisticsWidget","oninit","vnode","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","oncreate","drawChart","onupdate","chart","periodLength","lastPeriod","dayjs","unix","format","dom","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['admin/app'];","module.exports = flarum.core.compat['common/utils/abbreviateNumber'];","module.exports = flarum.core.compat['common/extend'];","module.exports = flarum.core.compat['admin/components/DashboardPage'];","module.exports = flarum.core.compat['admin/components/DashboardWidget'];","module.exports = flarum.core.compat['common/components/SelectDropdown'];","module.exports = flarum.core.compat['common/components/Button'];","module.exports = flarum.core.compat['common/helpers/icon'];","export default function _setPrototypeOf(o, p) {\n _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) {\n o.__proto__ = p;\n return o;\n };\n\n return _setPrototypeOf(o, p);\n}","import setPrototypeOf from \"./setPrototypeOf.js\";\nexport default function _inheritsLoose(subClass, superClass) {\n subClass.prototype = Object.create(superClass.prototype);\n subClass.prototype.constructor = subClass;\n setPrototypeOf(subClass, superClass);\n}","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\n// https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/offsetParent\n// an element's offsetParent property will return null whenever it, or any of its parents,\n// is hidden via the display style property.\nfunction isHidden(el) {\n\treturn (el.offsetParent === null);\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.00;\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\tdonut: DEFAULT_CHART_COLORS\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\n/**\n * Returns the value of a number upto 2 decimal places.\n * @param {Number} d Any number\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\n/**\n * Check if a number is valid for svg attributes\n * @param {object} candidate Candidate to test\n * @param {Boolean} nonNegative flag to treat negative number as invalid\n */\nfunction isValidNumber(candidate, nonNegative=false) {\n\tif (Number.isNaN(candidate)) return false;\n\telse if (candidate === undefined) return false;\n\telse if (!Number.isFinite(candidate)) return false;\n\telse if (nonNegative && candidate < 0) return false;\n\telse return true;\n}\n\n/**\n * Round a number to the closes precision, max max precision 4\n * @param {Number} d Any Number\n */\nfunction round(d) {\n\t// https://floating-point-gui.de/\n\t// https://www.jacklmoore.com/notes/rounding-in-javascript/\n\treturn Number(Math.round(d + 'e4') + 'e-4');\n}\n\n/**\n * Creates a deep clone of an object\n * @param {Object} candidate Any Object\n */\n function deepClone(candidate) {\n\tlet cloned, value, key;\n \n\tif (candidate instanceof Date) {\n\t return new Date(candidate.getTime());\n\t}\n \n\tif (typeof candidate !== \"object\" || candidate === null) {\n\t return candidate;\n\t}\n \n\tcloned = Array.isArray(candidate) ? [] : {};\n \n\tfor (key in candidate) {\n\t value = candidate[key];\n \n\t cloned[key] = deepClone(value);\n\t}\n \n\treturn cloned;\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\nfunction truncateString(txt, len) {\n\tif (!txt) {\n\t\treturn;\n\t}\n\tif (txt.length > len) {\n\t\treturn txt.slice(0, len-3) + '...';\n\t} else {\n\t\treturn txt;\n\t}\n}\n\nfunction shortenLargeNumber(label) {\n\tlet number;\n\tif (typeof label === 'number') number = label;\n\telse if (typeof label === 'string') {\n\t\tnumber = Number(label);\n\t\tif (Number.isNaN(number)) return label;\n\t}\n\n\t// Using absolute since log wont work for negative numbers\n\tlet p = Math.floor(Math.log10(Math.abs(number)));\n\tif (p <= 2) return number; // Return as is for a 3 digit number of less\n\tlet\tl = Math.floor(p / 3);\n\tlet shortened = (Math.pow(10, p - l * 3) * +(number / Math.pow(10, p)).toFixed(1));\n\n\t// Correct for floating point error upto 2 decimal places\n\treturn Math.round(shortened*100)/100 + ' ' + ['', 'K', 'M', 'B', 'T'][l];\n}\n\n// cubic bezier curve calculation (from example by François Romain)\nfunction getSplineCurvePointsStr(xList, yList) {\n\n\tlet points=[];\n\tfor(let i=0;i<xList.length;i++){\n\t\tpoints.push([xList[i], yList[i]]);\n\t}\n\n\tlet smoothing = 0.2;\n\tlet line = (pointA, pointB) => {\n\t\tlet lengthX = pointB[0] - pointA[0];\n\t\tlet lengthY = pointB[1] - pointA[1];\n\t\treturn {\n\t\t\tlength: Math.sqrt(Math.pow(lengthX, 2) + Math.pow(lengthY, 2)),\n\t\t\tangle: Math.atan2(lengthY, lengthX)\n\t\t};\n\t};\n \n\tlet controlPoint = (current, previous, next, reverse) => {\n\t\tlet p = previous || current;\n\t\tlet n = next || current;\n\t\tlet o = line(p, n);\n\t\tlet angle = o.angle + (reverse ? Math.PI : 0);\n\t\tlet length = o.length * smoothing;\n\t\tlet x = current[0] + Math.cos(angle) * length;\n\t\tlet y = current[1] + Math.sin(angle) * length;\n\t\treturn [x, y];\n\t};\n \n\tlet bezierCommand = (point, i, a) => {\n\t\tlet cps = controlPoint(a[i - 1], a[i - 2], point);\n\t\tlet cpe = controlPoint(point, a[i - 1], a[i + 1], true);\n\t\treturn `C ${cps[0]},${cps[1]} ${cpe[0]},${cpe[1]} ${point[0]},${point[1]}`;\n\t};\n \n\tlet pointStr = (points, command) => {\n\t\treturn points.reduce((acc, point, i, a) => i === 0\n\t\t\t? `${point[0]},${point[1]}`\n\t\t\t: `${acc} ${command(point, i, a)}`, '');\n\t};\n \n\treturn pointStr(points, bezierCommand);\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/32685393\n\tlet HEX_RE = /(^\\s*)(#)((?:[A-Fa-f0-9]{3}){1,2})$/i;\n\tlet RGB_RE = /(^\\s*)(rgb|hsl)(a?)[(]\\s*([\\d.]+\\s*%?)\\s*,\\s*([\\d.]+\\s*%?)\\s*,\\s*([\\d.]+\\s*%?)\\s*(?:,\\s*([\\d.]+)\\s*)?[)]$/i;\n\treturn HEX_RE.test(string) || RGB_RE.test(string);\n}\n\nconst getColor = (color) => {\n\t// When RGB color, convert to hexadecimal (alpha value is omitted)\n\tif((/rgb[a]{0,1}\\([\\d, ]+\\)/gim).test(color)) {\n\t\treturn (/\\D+(\\d*)\\D+(\\d*)\\D+(\\d*)/gim).exec(color)\n\t\t\t.map((x, i) => (i !== 0 ? Number(x).toString(16) : '#'))\n\t\t\t.reduce((c, ch) => `${c}${ch}`);\n\t}\n\treturn PRESET_COLOR_MAP[color] || color;\n};\n\nconst AXIS_TICK_LENGTH = 6;\nconst LABEL_MARGIN = 4;\nconst LABEL_MAX_CHARS = 15;\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', strokeWidth=2) {\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\t'stroke-width': strokeWidth\n\t\t}\n\t});\n}\n\nfunction makeArcPathStr(startPosition, endPosition, center, radius, clockWise=1, largeArc=0){\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\treturn `M${center.x} ${center.y}\n\t\tL${arcStartX} ${arcStartY}\n\t\tA ${radius} ${radius} 0 ${largeArc} ${clockWise ? 1 : 0}\n\t\t${arcEndX} ${arcEndY} z`;\n}\n\nfunction makeCircleStr(startPosition, endPosition, center, radius, clockWise=1, largeArc=0){\n\tlet [arcStartX, arcStartY] = [center.x + startPosition.x, center.y + startPosition.y];\n\tlet [arcEndX, midArc, arcEndY] = [center.x + endPosition.x, center.y * 2, center.y + endPosition.y];\n\treturn `M${center.x} ${center.y}\n\t\tL${arcStartX} ${arcStartY}\n\t\tA ${radius} ${radius} 0 ${largeArc} ${clockWise ? 1 : 0}\n\t\t${arcEndX} ${midArc} z\n\t\tL${arcStartX} ${midArc}\n\t\tA ${radius} ${radius} 0 ${largeArc} ${clockWise ? 1 : 0}\n\t\t${arcEndX} ${arcEndY} z`;\n}\n\nfunction makeArcStrokePathStr(startPosition, endPosition, center, radius, clockWise=1, largeArc=0){\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${arcStartX} ${arcStartY}\n\t\tA ${radius} ${radius} 0 ${largeArc} ${clockWise ? 1 : 0}\n\t\t${arcEndX} ${arcEndY}`;\n}\n\nfunction makeStrokeCircleStr(startPosition, endPosition, center, radius, clockWise=1, largeArc=0){\n\tlet [arcStartX, arcStartY] = [center.x + startPosition.x, center.y + startPosition.y];\n\tlet [arcEndX, midArc, arcEndY] = [center.x + endPosition.x, radius * 2 + arcStartY, center.y + startPosition.y];\n\n\treturn `M${arcStartX} ${arcStartY}\n\t\tA ${radius} ${radius} 0 ${largeArc} ${clockWise ? 1 : 0}\n\t\t${arcEndX} ${midArc}\n\t\tM${arcStartX} ${midArc}\n\t\tA ${radius} ${radius} 0 ${largeArc} ${clockWise ? 1 : 0}\n\t\t${arcEndX} ${arcEndY}`;\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, radius, 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\trx: radius,\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, truncate=false) {\n\tlabel = truncate ? truncateString(label, LABEL_MAX_CHARS) : label;\n\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, truncate=false) {\n\tlabel = truncate ? truncateString(label, LABEL_MAX_CHARS) : label;\n\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\tif (options.shortenNumbers) label = shortenLargeNumber(label);\n\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 (!isValidNumber(y)) y = 0;\n\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\tshortenNumbers: options.shortenNumbers\n\t});\n}\n\nfunction xLine(x, label, height, options={}) {\n\tif (!isValidNumber(x)) x = 0;\n\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\t// Preprocess numbers to avoid svg building errors\n\tif (!isValidNumber(x)) x = 0;\n\tif (!isValidNumber(y)) y = 0;\n\tif (!isValidNumber(height, true)) height = 0;\n\tif (!isValidNumber(width, true)) width = 0;\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\n\t// Spline\n\tif (options.spline)\n\t\tpointsStr = getSplineCurvePointsStr(xList, yList);\n\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, spline) {\n\tlet pathComponents = [];\n\tlet pointsStr = newYList.map((y, i) => (newXList[i] + ',' + y)).join(\"L\");\n\n\tif (spline)\n\t\tpointsStr = getSplineCurvePointsStr(newXList, newYList);\n\n\tconst animPath = [paths.path, {d:\"M\" + pointsStr}, 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 + pointsStr + 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\t\t\n\t\tif (parent) {\n\t\t\tparent.replaceChild(animElement, unit);\n\t\t}\n\t});\n\n\tlet animSvg = svgContainer.cloneNode(true);\n\n\tanimElements.map((animElement, i) => {\n\t\tif (animElement[1]) {\n\t\t\tanimElement[1].replaceChild(newElements[i], animElement[0]);\n\t\t\telements[i][0] = newElements[i];\n\t\t}\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\nclass BaseChart {\n\tconstructor(parent, options) {\n\t\t// deepclone options to avoid making changes to orignal object\n\t\toptions = deepClone(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: (typeof options.animate !== 'undefined') ? options.animate : 1,\n\t\t\ttruncateLegends: options.truncateLegends || 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\tthis.boundDrawFn = () => this.draw(true);\n\t\tif (ResizeObserver) {\n\t\t\tthis.resizeObserver = new ResizeObserver(this.boundDrawFn);\n\t\t\tthis.resizeObserver.observe(this.parent);\n\t\t}\n\t\twindow.addEventListener('resize', this.boundDrawFn);\n\t\twindow.addEventListener('orientationchange', this.boundDrawFn);\n\t}\n\n\tdestroy() {\n\t\tif (this.resizeObserver) this.resizeObserver.disconnect();\n\t\twindow.removeEventListener('resize', this.boundDrawFn);\n\t\twindow.removeEventListener('orientationchange', this.boundDrawFn);\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\tif (onlyWidthChange && isHidden(this.parent)) {\n\t\t\t// Don't update anything if the chart is hidden\n\t\t\treturn;\n\t\t}\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(this.components, this.config.animate);\n\t\tthis.renderLegend();\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.formatTooltipY = (args.tooltipOptions || {}).formatTooltipY;\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(round(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 = 150;\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 (this.legendTotals.length < divisor) {\n\t\t\t\tbarWidth = this.width/this.legendTotals.length;\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 label = this.config.truncateLegends ? truncateString(s.labels[i], barWidth/10) : s.labels[i];\n\t\t\tlet formatted = this.config.formatTooltipY ? this.config.formatTooltipY(d) : d;\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`${label}: ${formatted}`,\n\t\t\t\tfalse\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\tdonutSlices: {\n\t\tlayerClass: 'donut-slices',\n\t\tmakeElements(data) {\n\t\t\treturn data.sliceStrings.map((s, i) => {\n\t\t\t\tlet slice = makePath(s, 'donut-path', data.colors[i], 'none', data.strokeWidth);\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) => animatePathStr(slice, newData.sliceStrings[i]));\n\t\t},\n\t},\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, shortenNumbers: this.constants.shortenNumbers})\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, radius, 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, radius, 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\tspline: c.spline\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, this.constants.spline));\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 = 60;\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\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 largeArc = originDiffAngle > 180 ? 1: 0;\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 =\n\t\t\t\toriginDiffAngle === 360\n\t\t\t\t\t? makeCircleStr(curStart, curEnd, this.center, this.radius, clockWise, largeArc)\n\t\t\t\t\t: makeArcPathStr(curStart, curEnd, this.center, this.radius, clockWise, largeArc);\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.reverse().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\tradius: this.rawChartArgs.radius || 0,\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\t\tlet radius = this.rawChartArgs.radius || 0;\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, radius, 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\td.values = vals;\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 seriesMultiple;\n\tif(isSeries) {\n\t\t// Find the maximum label length for spacing calculations\n\t\tlet maxLabelLength = Math.max(...labels.map(label => label.length));\n\t\tseriesMultiple = Math.ceil(maxLabelLength/allowedLetters);\n\t}\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\tif(i % seriesMultiple !== 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\t\tthis.config.shortenYAxisNumbers = options.axisOptions.shortenYAxisNumbers || 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 && d.name.replace(/<|>|&/g, (char) => char == '&' ? '&' : char == '<' ? '<' : '>'),\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\tshortenNumbers: this.config.shortenYAxisNumbers\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\tspline: this.lineOptions.spline,\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\tif (index >= 0) {\n\t\t\tlet dbi = this.dataByIndex[index];\n\n\t\t\tthis.tip.setValues(\n\t\t\t\tdbi.xPos + this.tip.offset.x,\n\t\t\t\tdbi.yExtreme + this.tip.offset.y,\n\t\t\t\t{name: dbi.formattedLabel, value: ''},\n\t\t\t\tdbi.values,\n\t\t\t\tindex\n\t\t\t);\n\n\t\t\tthis.tip.showTip();\n\t\t}\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\t\tthis.config.truncateLegends);\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\nclass DonutChart extends AggregationChart {\n\tconstructor(parent, args) {\n\t\tsuper(parent, args);\n\t\tthis.type = 'donut';\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\tthis.strokeWidth = args.strokeWidth || 30;\n\t}\n\n\tcalc() {\n\t\tsuper.calc();\n\t\tlet s = this.state;\n\t\tthis.radius =\n\t\t\tthis.height > this.width\n\t\t\t\t? this.center.x - this.strokeWidth / 2\n\t\t\t\t: this.center.y - this.strokeWidth / 2;\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 largeArc = originDiffAngle > 180 ? 1: 0;\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 =\n\t\t\t\toriginDiffAngle === 360\n\t\t\t\t\t? makeStrokeCircleStr(curStart, curEnd, this.center, this.radius, this.clockWise, largeArc)\n\t\t\t\t\t: makeArcStrokePathStr(curStart, curEnd, this.center, this.radius, this.clockWise, largeArc);\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'donutSlices',\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\tstrokeWidth: this.strokeWidth,\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.stroke = 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.stroke = 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('donutSlices').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\n// import MultiAxisChart from './charts/MultiAxisChart';\nconst chartTypes = {\n\tbar: AxisChart,\n\tline: AxisChart,\n\t// multiaxis: MultiAxisChart,\n\tpercentage: PercentageChart,\n\theatmap: Heatmap,\n\tpie: PieChart,\n\tdonut: DonutChart,\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 app from 'flarum/admin/app';\nimport DashboardWidget from 'flarum/admin/components/DashboardWidget';\nimport SelectDropdown from 'flarum/common/components/SelectDropdown';\nimport Button from 'flarum/common/components/Button';\nimport icon from 'flarum/common/helpers/icon';\nimport abbreviateNumber from 'flarum/common/utils/abbreviateNumber';\n\nimport { Chart } from 'frappe-charts/dist/frappe-charts.esm.js';\n\nexport default class StatisticsWidget extends DashboardWidget {\n oninit(vnode) {\n super.oninit(vnode);\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 >\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\n className={'StatisticsWidget-entity' + (this.selectedEntity === entity ? ' active' : '')}\n onclick={this.changeEntity.bind(this, entity)}\n >\n <h3 className=\"StatisticsWidget-heading\">{app.translator.trans('flarum-statistics.admin.statistics.' + entity + '_heading')}</h3>\n <div className=\"StatisticsWidget-total\" title={totalCount}>\n {abbreviateNumber(totalCount)}\n </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 ''\n )}\n </div>\n </a>\n );\n })}\n\n <div className=\"StatisticsWidget-chart\" oncreate={this.drawChart.bind(this)} onupdate={this.drawChart.bind(this)} />\n </div>\n );\n }\n\n drawChart(vnode) {\n if (this.chart && this.entity === this.selectedEntity && this.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 = dayjs.unix(i + offset).format('h A');\n } else {\n label = dayjs.unix(i + offset).format('D MMM');\n\n if (period.step > 86400) {\n label += ' - ' + dayjs.unix(i + offset + period.step - 1).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 = [{ values: lastPeriod }, { values: thisPeriod }];\n const data = {\n labels,\n datasets,\n };\n\n if (!this.chart) {\n this.chart = new Chart(vnode.dom, {\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 this.chart.update(data);\n }\n\n this.entity = this.selectedEntity;\n this.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 += parseInt(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","import app from 'flarum/admin/app';\nimport { extend } from 'flarum/common/extend';\n\nimport DashboardPage from 'flarum/admin/components/DashboardPage';\n\nimport StatisticsWidget from './components/StatisticsWidget';\nimport ItemList from 'flarum/common/utils/ItemList';\n\napp.initializers.add('flarum-statistics', () => {\n extend(DashboardPage.prototype, 'availableWidgets', function (widgets: ItemList) {\n widgets.add('statistics', <StatisticsWidget />, 20);\n });\n});\n"],"sourceRoot":""} |