mirror of
https://github.com/danog/telegram-tt.git
synced 2024-12-14 18:27:10 +01:00
1 line
146 KiB
Plaintext
1 line
146 KiB
Plaintext
{"version":3,"file":"8878.a7b117d54d54258e5f26.js","mappings":"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","sources":["webpack://telegram-t/./src/lib/lovely-chart/constants.js","webpack://telegram-t/./src/lib/lovely-chart/utils.js","webpack://telegram-t/./src/lib/lovely-chart/formulas.js","webpack://telegram-t/./src/lib/lovely-chart/StateManager.js","webpack://telegram-t/./src/lib/lovely-chart/minifiers.js","webpack://telegram-t/./src/lib/lovely-chart/toggleText.js","webpack://telegram-t/./src/lib/lovely-chart/format.js","webpack://telegram-t/./src/lib/lovely-chart/skin.js","webpack://telegram-t/./src/lib/lovely-chart/Projection.js","webpack://telegram-t/./src/lib/lovely-chart/canvas.js","webpack://telegram-t/./src/lib/lovely-chart/preparePoints.js","webpack://telegram-t/./src/lib/lovely-chart/simplify.js","webpack://telegram-t/./src/lib/lovely-chart/drawDatasets.js","webpack://telegram-t/./src/lib/lovely-chart/captureEvents.js","webpack://telegram-t/./src/lib/lovely-chart/Tooltip.js","webpack://telegram-t/./src/lib/lovely-chart/data.js","webpack://telegram-t/./src/lib/lovely-chart/LovelyChart.js","webpack://telegram-t/./src/lib/lovely-chart/Header.js","webpack://telegram-t/./src/lib/lovely-chart/TransitionManager.js","webpack://telegram-t/./src/lib/lovely-chart/Axes.js","webpack://telegram-t/./src/lib/lovely-chart/Minimap.js","webpack://telegram-t/./src/lib/lovely-chart/Tools.js","webpack://telegram-t/./src/lib/lovely-chart/Zoomer.js"],"sourcesContent":["export const DPR = window.devicePixelRatio || 1;\n\nexport const DEFAULT_RANGE = { begin: 0.8, end: 1 };\nexport const TRANSITION_DEFAULT_DURATION = 300;\nexport const LONG_PRESS_TIMEOUT = 500;\n\nexport const GUTTER = 10;\nexport const PLOT_HEIGHT = 320;\nexport const PLOT_TOP_PADDING = 15;\nexport const PLOT_LINE_WIDTH = 2;\nexport const PLOT_PIE_RADIUS_FACTOR = 0.9 / 2;\nexport const PLOT_PIE_SHIFT = 10;\nexport const PLOT_BARS_WIDTH_SHIFT = 0.5;\n\nexport const PIE_MINIMUM_VISIBLE_PERCENT = 0.02;\n\nexport const BALLOON_OFFSET = 20;\n\nexport const AXES_FONT = '300 10px Helvetica, Arial, sans-serif';\nexport const AXES_MAX_COLUMN_WIDTH = 45;\nexport const AXES_MAX_ROW_HEIGHT = 50;\nexport const X_AXIS_HEIGHT = 30;\nexport const X_AXIS_SHIFT_START = 1;\nexport const Y_AXIS_ZERO_BASED_THRESHOLD = 0.1;\n\nexport const MINIMAP_HEIGHT = 40;\nexport const MINIMAP_MARGIN = 10;\nexport const MINIMAP_LINE_WIDTH = 1;\nexport const MINIMAP_EAR_WIDTH = 8;\nexport const MINIMAP_MAX_ANIMATED_DATASETS = 4;\n\nexport const ZOOM_TIMEOUT = TRANSITION_DEFAULT_DURATION;\nexport const ZOOM_RANGE_DELTA = 0.1;\nexport const ZOOM_RANGE_MIDDLE = .5;\n\nexport const MONTHS = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];\nexport const WEEK_DAYS = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];\nexport const WEEK_DAYS_SHORT = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];\n\nexport const MILISECONDS_IN_DAY = 24 * 60 * 60 * 1000;\n\nexport const SPEED_TEST_INTERVAL = 200;\nexport const SPEED_TEST_FAST_FPS = 4;\n\nexport const SIMPLIFIER_MIN_POINTS = 1000;\nexport const SIMPLIFIER_PLOT_FACTOR = 1;\nexport const SIMPLIFIER_MINIMAP_FACTOR = 0.5;\n\nexport const ANIMATE_PROPS = [\n // Viewport X-axis\n 'begin 200 fast', 'end 200 fast', 'labelFromIndex 200 fast floor', 'labelToIndex 200 fast ceil',\n\n // X-axis labels\n 'xAxisScale 400',\n\n // Viewport Y-axis\n 'yMinViewport', 'yMaxViewport', 'yMinViewportSecond', 'yMaxViewportSecond',\n\n // Minimap Y-axis\n 'yMinMinimap', 'yMaxMinimap', 'yMinMinimapSecond', 'yMaxMinimapSecond',\n\n // Y-axis labels\n 'yAxisScale', 'yAxisScaleSecond',\n];\n","// https://jsperf.com/finding-maximum-element-in-an-array\nexport function getMaxMin(array) {\n const length = array.length;\n let max = array[0];\n let min = array[0];\n\n for (let i = 0; i < length; i++) {\n const value = array[i];\n\n if (value > max) {\n max = value;\n } else if (value < min) {\n min = value;\n }\n }\n\n return { max, min };\n}\n\n// https://jsperf.com/multi-array-concat/24\nexport function mergeArrays(arrays) {\n return [].concat.apply([], arrays);\n}\n\nexport function sumArrays(arrays) {\n const sums = [];\n const n = arrays.length;\n\n for (let i = 0, l = arrays[0].length; i < l; i++) {\n sums[i] = 0;\n\n for (let j = 0; j < n; j++) {\n sums[i] += arrays[j][i];\n }\n }\n\n return sums;\n}\n\nexport function proxyMerge(obj1, obj2) {\n return new Proxy({}, {\n get: (obj, prop) => {\n if (obj[prop] !== undefined) {\n return obj[prop];\n } else if (obj2[prop] !== undefined) {\n return obj2[prop];\n } else {\n return obj1[prop];\n }\n },\n });\n}\n\nexport function throttle(\n fn,\n ms,\n shouldRunFirst = true,\n) {\n let interval = null;\n let isPending;\n let args;\n\n return (..._args) => {\n isPending = true;\n args = _args;\n\n if (!interval) {\n if (shouldRunFirst) {\n isPending = false;\n // @ts-ignore\n fn(...args);\n }\n\n interval = window.setInterval(() => {\n if (!isPending) {\n window.clearInterval(interval);\n interval = null;\n return;\n }\n\n isPending = false;\n // @ts-ignore\n fn(...args);\n }, ms);\n }\n };\n}\n\nexport function throttleWithRaf(fn) {\n let waiting = false;\n let args;\n\n return function (..._args) {\n args = _args;\n\n if (!waiting) {\n waiting = true;\n\n requestAnimationFrame(() => {\n waiting = false;\n fn(...args);\n });\n }\n };\n}\n\nexport function debounce(fn, ms, shouldRunFirst = true, shouldRunLast = true) {\n let waitingTimeout = null;\n\n return function () {\n if (waitingTimeout) {\n clearTimeout(waitingTimeout);\n waitingTimeout = null;\n } else if (shouldRunFirst) {\n fn();\n }\n\n waitingTimeout = setTimeout(() => {\n if (shouldRunLast) {\n fn();\n }\n\n waitingTimeout = null;\n }, ms);\n };\n}\n","import { GUTTER, PLOT_PIE_RADIUS_FACTOR, MILISECONDS_IN_DAY, SIMPLIFIER_MIN_POINTS } from './constants';\n\nexport function xScaleLevelToStep(scaleLevel) {\n return Math.pow(2, scaleLevel);\n}\n\nexport function xStepToScaleLevel(step) {\n return Math.ceil(Math.log2(step || 1));\n}\n\nconst SCALE_LEVELS = [\n 1, 2, 8, 18, 50, 100, 250, 500, 1000, 2500, 5000, 10000, 25000, 50000, 100000,\n 250000, 500000, 1000000, 2500000, 5000000, 10000000, 25000000, 50000000, 100000000,\n];\n\nexport function yScaleLevelToStep(scaleLevel) {\n return SCALE_LEVELS[scaleLevel] || SCALE_LEVELS[SCALE_LEVELS.length - 1];\n}\n\nexport function yStepToScaleLevel(neededStep) {\n return SCALE_LEVELS.findIndex((step) => step >= neededStep) || SCALE_LEVELS.length - 1;\n}\n\nexport function applyYEdgeOpacity(opacity, xPx, plotWidth) {\n const edgeOffset = Math.min(xPx + GUTTER, plotWidth - xPx);\n if (edgeOffset <= GUTTER * 4) {\n opacity = Math.min(1, opacity, edgeOffset / (GUTTER * 4));\n }\n return opacity;\n}\n\nexport function applyXEdgeOpacity(opacity, yPx) {\n return (yPx - GUTTER <= GUTTER * 2)\n ? Math.min(1, opacity, (yPx - GUTTER) / (GUTTER * 2))\n : opacity;\n}\n\nexport function getPieRadius(projection) {\n return Math.min(...projection.getSize()) * PLOT_PIE_RADIUS_FACTOR;\n}\n\nexport function getPieTextSize(percent, radius) {\n return (radius + percent * 200) / 10;\n}\n\nexport function getPieTextShift(percent, radius, shift) {\n return percent >= 0.99 ? 0 : Math.min(1 - Math.log(percent * 30) / 5, 4 / 5) * radius;\n}\n\nexport function isDataRange(labelFrom, labelTo) {\n return Math.abs(labelTo.value - labelFrom.value) > MILISECONDS_IN_DAY;\n}\n\nexport function getSimplificationDelta(pointsLength) {\n return pointsLength >= SIMPLIFIER_MIN_POINTS ? Math.min((pointsLength / 1000), 1) : 0;\n}\n","import { createTransitionManager } from './TransitionManager';\nimport { throttleWithRaf, getMaxMin, mergeArrays, proxyMerge, sumArrays } from './utils';\nimport {\n AXES_MAX_COLUMN_WIDTH,\n AXES_MAX_ROW_HEIGHT,\n X_AXIS_HEIGHT,\n ANIMATE_PROPS,\n Y_AXIS_ZERO_BASED_THRESHOLD,\n} from './constants';\nimport { xStepToScaleLevel, yScaleLevelToStep, yStepToScaleLevel } from './formulas';\n\nexport function createStateManager(data, viewportSize, callback) {\n const _range = { begin: 0, end: 1 };\n const _filter = _buildDefaultFilter();\n const _transitionConfig = _buildTransitionConfig();\n const _transitions = createTransitionManager(_runCallback);\n const _runCallbackOnRaf = throttleWithRaf(_runCallback);\n\n let _state = {};\n\n function update({ range = {}, filter = {}, focusOn, minimapDelta } = {}, noTransition) {\n Object.assign(_range, range);\n Object.assign(_filter, filter);\n\n const prevState = _state;\n _state = calculateState(data, viewportSize, _range, _filter, focusOn, minimapDelta, prevState);\n\n if (!noTransition) {\n _transitionConfig.forEach(({ prop, duration, options }) => {\n const transition = _transitions.get(prop);\n const currentTarget = transition ? transition.to : prevState[prop];\n\n if (currentTarget !== undefined && currentTarget !== _state[prop]) {\n const current = transition\n ? (options.includes('fast') ? prevState[prop] : transition.current)\n : prevState[prop];\n\n if (transition) {\n _transitions.remove(prop);\n }\n\n _transitions.add(prop, current, _state[prop], duration, options);\n }\n });\n }\n\n if (!_transitions.isRunning() || !_transitions.isFast()) {\n _runCallbackOnRaf();\n }\n }\n\n function hasAnimations() {\n return _transitions.isFast();\n }\n\n function _buildTransitionConfig() {\n const transitionConfig = [];\n const datasetVisibilities = data.datasets.map(({ key }) => `opacity#${key} 300`);\n\n mergeArrays([\n ANIMATE_PROPS,\n datasetVisibilities,\n ]).forEach((transition) => {\n const [prop, duration, ...options] = transition.split(' ');\n transitionConfig.push({ prop, duration, options });\n });\n\n return transitionConfig;\n }\n\n function _buildDefaultFilter() {\n const filter = {};\n\n data.datasets.forEach(({ key }) => {\n filter[key] = true;\n });\n\n return filter;\n }\n\n function _runCallback() {\n const state = _transitions.isFast() ? proxyMerge(_state, _transitions.getState()) : _state;\n state.static = _state;\n callback(state);\n }\n\n return { update, hasAnimations };\n}\n\nfunction calculateState(data, viewportSize, range, filter, focusOn, minimapDelta, prevState) {\n const { begin, end } = range;\n const totalXWidth = data.xLabels.length - 1;\n\n const labelFromIndex = Math.max(0, Math.ceil(totalXWidth * begin));\n const labelToIndex = Math.min(Math.floor(totalXWidth * end), totalXWidth);\n\n const xAxisScale = calculateXAxisScale(viewportSize.width, labelFromIndex, labelToIndex);\n\n const yRanges = data.isStacked\n ? calculateYRangesStacked(data, filter, labelFromIndex, labelToIndex, prevState)\n : calculateYRanges(data, filter, labelFromIndex, labelToIndex, prevState);\n\n const yAxisScale = calculateYAxisScale(viewportSize.height, yRanges.yMinViewport, yRanges.yMaxViewport);\n const yAxisScaleSecond = data.hasSecondYAxis &&\n calculateYAxisScale(viewportSize.height, yRanges.yMinViewportSecond, yRanges.yMaxViewportSecond);\n\n const yStep = yScaleLevelToStep(yAxisScale);\n yRanges.yMinViewport -= yRanges.yMinViewport % yStep;\n\n if (yAxisScaleSecond) {\n const yStepSecond = yScaleLevelToStep(yAxisScaleSecond);\n yRanges.yMinViewportSecond -= yRanges.yMinViewportSecond % yStepSecond;\n }\n\n const datasetsOpacity = {};\n data.datasets.forEach(({ key }) => {\n datasetsOpacity[`opacity#${key}`] = filter[key] ? 1 : 0;\n });\n\n // TODO perf\n return Object.assign(\n {\n totalXWidth,\n xAxisScale,\n yAxisScale,\n yAxisScaleSecond,\n labelFromIndex: Math.max(0, labelFromIndex - 1),\n labelToIndex: Math.min(labelToIndex + 1, totalXWidth),\n filter: Object.assign({}, filter),\n focusOn: focusOn !== undefined ? focusOn : prevState.focusOn,\n minimapDelta: minimapDelta !== undefined ? minimapDelta : prevState.minimapDelta,\n },\n yRanges,\n datasetsOpacity,\n range,\n );\n}\n\nfunction calculateYRanges(data, filter, labelFromIndex, labelToIndex, prevState) {\n const secondaryYAxisDataset = data.hasSecondYAxis && data.datasets.slice(-1)[0];\n const filteredDatasets = data.datasets.filter((d) => filter[d.key] && d !== secondaryYAxisDataset);\n\n const yRanges = calculateYRangesForGroup(data, labelFromIndex, labelToIndex, prevState, filteredDatasets);\n\n if (secondaryYAxisDataset) {\n const {\n yMinViewport: yMinViewportSecond,\n yMaxViewport: yMaxViewportSecond,\n yMinMinimap: yMinMinimapSecond,\n yMaxMinimap: yMaxMinimapSecond,\n } = calculateYRangesForGroup(data, labelFromIndex, labelToIndex, prevState, [secondaryYAxisDataset]);\n\n Object.assign(yRanges, {\n yMinViewportSecond,\n yMaxViewportSecond,\n yMinMinimapSecond,\n yMaxMinimapSecond,\n });\n }\n\n return yRanges;\n}\n\nfunction calculateYRangesForGroup(data, labelFromIndex, labelToIndex, prevState, datasets) {\n const { min: yMinMinimapReal = prevState.yMinMinimap, max: yMaxMinimap = prevState.yMaxMinimap }\n = getMaxMin(mergeArrays(datasets.map(({ yMax, yMin }) => [yMax, yMin])));\n const yMinMinimap = yMinMinimapReal / yMaxMinimap > Y_AXIS_ZERO_BASED_THRESHOLD ? yMinMinimapReal : 0;\n\n let yMinViewport;\n let yMaxViewport;\n\n if (labelFromIndex === 0 && labelToIndex === data.xLabels.length - 1) {\n yMinViewport = yMinMinimap;\n yMaxViewport = yMaxMinimap;\n } else {\n const filteredValues = datasets.map(({ values }) => values);\n const viewportValues = filteredValues.map((values) => values.slice(labelFromIndex, labelToIndex + 1));\n const viewportMaxMin = getMaxMin(mergeArrays(viewportValues));\n const yMinViewportReal = viewportMaxMin.min !== undefined ? viewportMaxMin.min : prevState.yMinViewport;\n yMaxViewport = viewportMaxMin.max !== undefined ? viewportMaxMin.max : prevState.yMaxViewport;\n yMinViewport = yMinViewportReal / yMaxViewport > Y_AXIS_ZERO_BASED_THRESHOLD ? yMinViewportReal : 0;\n }\n\n return {\n yMinViewport,\n yMaxViewport,\n yMinMinimap,\n yMaxMinimap,\n };\n}\n\nfunction calculateYRangesStacked(data, filter, labelFromIndex, labelToIndex, prevState) {\n const filteredDatasets = data.datasets.filter((d) => filter[d.key]);\n const filteredValues = filteredDatasets.map(({ values }) => values);\n\n const sums = filteredValues.length ? sumArrays(filteredValues) : [];\n const { max: yMaxMinimap = prevState.yMaxMinimap } = getMaxMin(sums);\n const { max: yMaxViewport = prevState.yMaxViewport } = getMaxMin(sums.slice(labelFromIndex, labelToIndex + 1));\n\n return {\n yMinViewport: 0,\n yMaxViewport,\n yMinMinimap: 0,\n yMaxMinimap,\n };\n}\n\nfunction calculateXAxisScale(plotWidth, labelFromIndex, labelToIndex) {\n const viewportLabelsCount = labelToIndex - labelFromIndex;\n const maxColumns = Math.floor(plotWidth / AXES_MAX_COLUMN_WIDTH);\n\n return xStepToScaleLevel(viewportLabelsCount / maxColumns);\n}\n\nfunction calculateYAxisScale(plotHeight, yMin, yMax) {\n const availableHeight = plotHeight - X_AXIS_HEIGHT;\n const viewportLabelsCount = yMax - yMin;\n const maxRows = Math.floor(availableHeight / AXES_MAX_ROW_HEIGHT);\n\n return yStepToScaleLevel(viewportLabelsCount / maxRows);\n}\n","export const createElement = (tagName = 'div') => {\n return document.createElement(tagName);\n};\n\nexport function addEventListener(element, event, cb) {\n element.addEventListener(event, cb);\n}\n\nexport function removeEventListener(element, event, cb) {\n element.removeEventListener(event, cb);\n}\n","import { createElement } from './minifiers';\n\nexport function toggleText(element, newText, className = '', inverse = false) {\n const container = element.parentNode;\n container.classList.add('lovely-chart--transition-container');\n\n const newElement = createElement(element.tagName);\n newElement.className = `${className} lovely-chart--transition lovely-chart--position-${inverse ? 'top' : 'bottom'} lovely-chart--state-hidden`;\n newElement.innerHTML = newText;\n\n const selector = className.length ? `.${className.split(' ').join('.')}` : '';\n const oldElements = container.querySelectorAll(`${selector}.lovely-chart--state-hidden`);\n oldElements.forEach(e => e.remove());\n\n element.classList.add('lovely-chart--transition');\n element.classList.remove('lovely-chart--position-bottom', 'lovely-chart--position-top');\n element.classList.add(inverse ? 'lovely-chart--position-bottom' : 'lovely-chart--position-top');\n container.insertBefore(newElement, element.nextSibling);\n\n toggleElementIn(newElement);\n toggleElementOut(element);\n\n return newElement;\n}\n\nfunction toggleElementIn(element) {\n // Remove and add `animated` class to re-trigger animation\n element.classList.remove('lovely-chart--state-animated');\n element.classList.add('lovely-chart--state-animated');\n element.classList.remove('lovely-chart--state-hidden');\n}\n\nfunction toggleElementOut(element) {\n // Remove and add `animated` class to re-trigger animation\n element.classList.remove('lovely-chart--state-animated');\n element.classList.add('lovely-chart--state-animated');\n element.classList.add('lovely-chart--state-hidden');\n}\n","import { MONTHS, WEEK_DAYS, WEEK_DAYS_SHORT } from './constants';\n\nexport function statsFormatDayHour(labels) {\n return labels.map((value) => ({\n value,\n text: `${value}:00`,\n }));\n}\n\nexport function statsFormatDayHourFull(value) {\n return `${value}:00`;\n}\n\nexport function statsFormatDay(labels) {\n return labels.map((value) => {\n const date = new Date(value);\n const day = date.getDate();\n const month = MONTHS[date.getMonth()];\n\n return ({\n value,\n text: `${day} ${month}`,\n });\n });\n}\n\nexport function statsFormatMin(labels) {\n return labels.map((value) => ({\n value,\n text: new Date(value).toString().match(/(\\d+:\\d+):/)[1],\n }));\n}\n\nexport function statsFormatText(labels) {\n return labels.map((value, i) => {\n return ({\n value: i,\n text: value,\n });\n });\n}\n\nexport function humanize(value, decimals = 1) {\n if (value >= 1e6) {\n return keepThreeDigits(value / 1e6, decimals) + 'M';\n } else if (value >= 1e3) {\n return keepThreeDigits(value / 1e3, decimals) + 'K';\n }\n\n return value;\n}\n\n// TODO perf\nfunction keepThreeDigits(value, decimals) {\n return value\n .toFixed(decimals)\n .replace(/(\\d{3,})\\.\\d+/, '$1')\n .replace(/\\.0+$/, '');\n}\n\nexport function formatInteger(n) {\n return String(n).replace(/\\d(?=(\\d{3})+$)/g, '$& ');\n}\n\nexport function getFullLabelDate(label, { isShort = false } = {}) {\n return getLabelDate(label, { isShort, displayWeekDay: true });\n}\n\nexport function getLabelDate(label, { isShort = false, displayWeekDay = false, displayYear = true, displayHours = false } = {}) {\n const { value } = label;\n const date = new Date(value);\n const weekDaysArray = isShort ? WEEK_DAYS_SHORT : WEEK_DAYS;\n\n let string = `${date.getUTCDate()} ${MONTHS[date.getUTCMonth()]}`;\n if (displayWeekDay) {\n string = `${weekDaysArray[date.getUTCDay()]}, ` + string;\n }\n if (displayYear) {\n string += ` ${date.getUTCFullYear()}`;\n }\n if (displayHours) {\n string += `, ${('0' + date.getUTCHours()).slice(-2)}:${('0' + date.getUTCMinutes()).slice(-2)}`\n }\n\n return string;\n}\n\nexport function getLabelTime(label) {\n return new Date(label.value).toString().match(/(\\d+:\\d+):/)[1];\n}\n","function detectSkin() {\n return document.documentElement.classList.contains('theme-dark') ? 'skin-night' : 'skin-day';\n}\n\nlet skin = detectSkin();\n\nconst COLORS = {\n 'skin-day': {\n 'background': '#FFFFFF',\n 'text-color': '#222222',\n 'minimap-mask': '#E2EEF9/0.6',\n 'minimap-slider': '#C0D1E1',\n 'grid-lines': '#182D3B/0.1',\n 'zoom-out-text': '#108BE3',\n 'tooltip-background': '#FFFFFF',\n 'tooltip-arrow': '#D2D5D7',\n 'mask': '#FFFFFF/0.5',\n 'x-axis-text': '#252529/0.6',\n 'y-axis-text': '#252529/0.6',\n },\n 'skin-night': {\n 'background': '#242F3E',\n 'text-color': '#FFFFFF',\n 'minimap-mask': '#304259/0.6',\n 'minimap-slider': '#56626D',\n 'grid-lines': '#FFFFFF/0.1',\n 'zoom-out-text': '#48AAF0',\n 'tooltip-background': '#1c2533',\n 'tooltip-arrow': '#D2D5D7',\n 'mask': '#242F3E/0.5',\n 'x-axis-text': '#A3B1C2/0.6',\n 'y-axis-text': '#A3B1C2/0.6',\n },\n};\n\nconst styleElement = document.createElement('style');\nstyleElement.type = 'text/css';\nstyleElement.appendChild(document.createTextNode(''));\ndocument.head.appendChild(styleElement);\nconst styleSheet = styleElement.sheet;\n\ndocument.documentElement.addEventListener('darkmode', () => {\n skin = detectSkin();\n});\n\nexport function createColors(datasetColors) {\n const colors = {};\n const baseClass = `.lovely-chart--color`;\n\n ['skin-day', 'skin-night'].forEach((skin) => {\n colors[skin] = {};\n\n Object.keys(COLORS[skin]).forEach((prop) => {\n colors[skin][prop] = hexToChannels(COLORS[skin][prop]);\n });\n\n Object.keys(datasetColors).forEach((key) => {\n colors[skin][`dataset#${key}`] = hexToChannels(datasetColors[key]);\n\n addCssRule(styleSheet, `.lovely-chart--tooltip-dataset-value${baseClass}-${datasetColors[key].slice(1)}`, `color: ${datasetColors[key]}`);\n addCssRule(styleSheet, `.lovely-chart--button${baseClass}-${datasetColors[key].slice(1)}`, `border-color: ${datasetColors[key]}; color: ${datasetColors[key]}`);\n addCssRule(styleSheet, `.lovely-chart--button.lovely-chart--state-checked${baseClass}-${datasetColors[key].slice(1)}`, `background-color: ${datasetColors[key]}`);\n });\n });\n\n return colors;\n}\n\nexport function getCssColor(colors, key, opacity) {\n return buildCssColor(colors[skin][key], opacity);\n}\n\nfunction hexToChannels(hexWithAlpha) {\n const [hex, alpha] = hexWithAlpha.replace('#', '').split('/');\n\n return [\n parseInt(hex.slice(0, 2), 16),\n parseInt(hex.slice(2, 4), 16),\n parseInt(hex.slice(4, 6), 16),\n alpha ? parseFloat(alpha) : 1,\n ];\n}\n\nfunction buildCssColor([r, g, b, a = 1], opacity = 1) {\n return `rgba(${r}, ${g}, ${b}, ${a * opacity})`;\n}\n\nfunction addCssRule(sheet, selector, rule) {\n sheet.insertRule(`${selector} { ${rule} }`, sheet.cssRules.length);\n}\n","import { proxyMerge } from './utils';\n\nexport function createProjection(params) {\n const {\n begin,\n end,\n totalXWidth,\n yMin,\n yMax,\n availableWidth,\n availableHeight,\n xPadding = 0,\n yPadding = 0,\n } = params;\n\n let effectiveWidth = availableWidth;\n\n // TODO bug get rid of padding jumps\n if (begin === 0) {\n effectiveWidth -= xPadding;\n }\n if (end === 1) {\n effectiveWidth -= xPadding;\n }\n const xFactor = effectiveWidth / ((end - begin) * totalXWidth);\n let xOffsetPx = (begin * totalXWidth) * xFactor;\n if (begin === 0) {\n xOffsetPx -= xPadding;\n }\n\n const effectiveHeight = availableHeight - yPadding;\n const yFactor = effectiveHeight / (yMax - yMin);\n const yOffsetPx = yMin * yFactor;\n\n function getState() {\n return { xFactor, xOffsetPx, availableHeight, yFactor, yOffsetPx };\n }\n\n function findClosestLabelIndex(xPx) {\n return Math.round((xPx + xOffsetPx) / xFactor);\n }\n\n function copy(overrides, cons) {\n return createProjection(proxyMerge(params, overrides), cons);\n }\n\n function getCenter() {\n return [\n availableWidth / 2,\n availableHeight - effectiveHeight / 2,\n ];\n }\n\n function getSize() {\n return [availableWidth, effectiveHeight];\n }\n\n function getParams() {\n return params;\n }\n\n return {\n findClosestLabelIndex,\n copy,\n getCenter,\n getSize,\n getParams,\n getState,\n };\n}\n\nexport function toPixels(projection, labelIndex, value) {\n const { xFactor, xOffsetPx, availableHeight, yFactor, yOffsetPx } = projection.getState();\n\n return [\n labelIndex * xFactor - xOffsetPx,\n availableHeight - (value * yFactor - yOffsetPx),\n ];\n}\n","import { DPR } from './constants';\nimport { createElement } from './minifiers';\n\nexport function setupCanvas(container, { width, height }) {\n const canvas = createElement('canvas');\n\n canvas.width = width * DPR;\n canvas.height = height * DPR;\n canvas.style.width = '100%';\n canvas.style.height = `${height}px`;\n\n const context = canvas.getContext('2d');\n context.scale(DPR, DPR);\n\n container.appendChild(canvas);\n\n return { canvas, context };\n}\n\nexport function clearCanvas(canvas, context) {\n context.clearRect(0, 0, canvas.width, canvas.height);\n}\n","import { sumArrays } from './utils';\n\nexport function preparePoints(data, datasets, range, visibilities, bounds, pieToArea) {\n let values = datasets.map(({ values }) => (\n values.slice(range.from, range.to + 1)\n ));\n\n if (data.isPie && !pieToArea) {\n values = prepareSumsByX(values);\n }\n\n const points = values.map((datasetValues, i) => (\n datasetValues.map((value, j) => {\n let visibleValue = value;\n\n if (data.isStacked) {\n visibleValue *= visibilities[i];\n }\n\n return {\n labelIndex: range.from + j,\n value,\n visibleValue,\n stackOffset: 0,\n stackValue: visibleValue,\n };\n })\n ));\n\n if (data.isPercentage) {\n preparePercentage(points, bounds);\n }\n\n if (data.isStacked) {\n prepareStacked(points);\n }\n\n return points;\n}\n\nfunction getSumsByY(points) {\n return sumArrays(points.map((datasetPoints) => (\n datasetPoints.map(({ visibleValue }) => visibleValue)\n )));\n}\n\n// TODO perf cache for [0..1], use in state\nfunction preparePercentage(points, bounds) {\n const sumsByY = getSumsByY(points);\n\n points.forEach((datasetPoints) => {\n datasetPoints.forEach((point, j) => {\n point.percent = point.visibleValue / sumsByY[j];\n point.visibleValue = point.percent * bounds.yMax;\n });\n });\n}\n\nfunction prepareStacked(points) {\n const accum = [];\n\n points.forEach((datasetPoints) => {\n datasetPoints.forEach((point, j) => {\n if (accum[j] === undefined) {\n accum[j] = 0;\n }\n\n point.stackOffset = accum[j];\n accum[j] += point.visibleValue;\n point.stackValue = accum[j];\n });\n });\n}\n\nfunction prepareSumsByX(values) {\n return values.map((datasetValues) => (\n [datasetValues.reduce((sum, value) => sum + value, 0)]\n ));\n}\n","export const simplify = (() => {\n function simplify(points, indexes, fixedPoints) {\n if (points.length < 6) {\n return function () {\n return {\n points: points,\n indexes: indexes,\n removed: [],\n };\n };\n }\n\n let worker = precalculate(points, fixedPoints);\n\n return function (delta) {\n let result = [],\n resultIndexes = [],\n removed = [];\n\n let delta2 = delta * delta,\n markers = worker(delta2);\n\n for (let i = 0, l = points.length; i < l; i++) {\n if (markers[i] >= delta2 || i == 0 || i == l - 1) {\n result.push(points[i]);\n resultIndexes.push(indexes ? indexes[i] : i);\n } else {\n removed.push(i);\n }\n }\n return {\n points: result,\n indexes: resultIndexes,\n removed: removed,\n };\n };\n }\n\n let E1 = 1.0 / Math.pow(2, 22), // максимальная дельта\n MAXLIMIT = 100000;\n\n function precalculate(points, fixedPoints) {\n\n let len = points.length,\n distances = [],\n queue = [],\n maximumDelta;\n for (let i = 0, l = points.length; i < l; ++i) {\n distances[i] = 0;\n }\n\n if (!fixedPoints) {\n fixedPoints = [];\n }\n\n //инициализируем дерево срединным значением\n //чтобы не попадает в ситуации когда начало линии близко к концу(те полигон)\n //и правильные расчеты сложны\n let subdivisionTree = 0;\n\n for (let i = 0, l = fixedPoints.length; i < l; ++i) {\n distances[fixedPoints[i]] = MAXLIMIT;\n }\n\n\n function worker(params) {\n\n let start = params.start,\n end = params.end,\n record = params.record,\n currentLimit = params.currentLimit,\n usedDistance = 0;\n\n if (!record) {\n //let deltaShifts = getDeltaShifts(points);\n let usedIndex = -1,\n vector = [\n points[end][0] - points[start][0],\n points[end][1] - points[start][1],\n ];\n for (let i = 0, l = fixedPoints.length; i < l; ++i) {\n let fixId = fixedPoints[i];\n if (fixId > start) {\n if (fixId < end) {\n usedIndex = fixId;\n usedDistance = MAXLIMIT;\n break;\n } else {\n break;\n }\n }\n }\n if (usedIndex < 0) {\n if (Math.abs(vector[0]) > E1 || Math.abs(vector[1]) > E1) {\n let vectorLength = vector[0] * vector[0] + vector[1] * vector[1],\n vectorLength_1 = +1.0 / vectorLength;\n\n for (let i = start + 1; i < end; ++i) {\n let segmentDistance = pointToSegmentDistanceSquare(points[i], points[start], points[end], vector, vectorLength_1);\n\n if (segmentDistance > usedDistance) {\n usedIndex = i;\n usedDistance = segmentDistance;\n }\n }\n\n } else {\n //фиксируем на среднинной точке\n usedIndex = Math.round((start + end) * 0.5);\n usedDistance = currentLimit;\n }\n distances[usedIndex] = usedDistance;\n }\n record = {\n start: start,\n end: end,\n index: usedIndex,\n distance: usedDistance,\n };\n }\n\n if (record.index && record.distance > maximumDelta) {\n if (record.index - start >= 2) {\n queue.push({\n start: start,\n end: record.index,\n record: record.left,\n currentLimit: record.distance,\n parent: record,\n parentProperty: 'left',\n });\n }\n if (end - record.index >= 2) {\n queue.push({\n start: record.index,\n end: end,\n record: record.right,\n currentLimit: record.distance,\n parent: record,\n parentProperty: 'right',\n });\n }\n }\n\n return record;\n }\n\n function tick() {\n let request = queue.pop(),\n result = worker(request);\n\n if (request.parent && request.parentProperty) {\n request.parent[request.parentProperty] = result;\n }\n\n return result;\n }\n\n return function (delta) {\n maximumDelta = delta;\n queue.push({\n start: 0,\n end: len - 1,\n record: subdivisionTree,\n currentLimit: MAXLIMIT,\n });\n subdivisionTree = tick();\n\n while (queue.length) {\n tick();\n }\n\n return distances;\n };\n\n }\n\n function pointToSegmentDistanceSquare(p, v1, v2, dv, dvlen_1) {\n\n let t;\n let vx = +v1[0],\n vy = +v1[1];\n\n t = +((p[0] - vx) * dv[0] + (p[1] - vy) * dv[1]) * (dvlen_1);\n\n if (t > 1) {\n vx = +v2[0];\n vy = +v2[1];\n } else if (t > 0) {\n vx += +dv[0] * t;\n vy += +dv[1] * t;\n }\n\n let a = +p[0] - vx,\n b = +p[1] - vy;\n\n return +a * a + b * b;\n }\n\n return simplify;\n})();\n","import { getCssColor } from './skin';\nimport { mergeArrays } from './utils';\nimport { getPieRadius, getPieTextShift, getPieTextSize } from './formulas';\nimport { PLOT_BARS_WIDTH_SHIFT, PLOT_PIE_SHIFT, PIE_MINIMUM_VISIBLE_PERCENT } from './constants';\nimport { simplify } from './simplify';\nimport { toPixels } from './Projection';\n\nexport function drawDatasets(\n context, state, data,\n range, points, projection, secondaryPoints, secondaryProjection,\n lineWidth, visibilities, colors, pieToBar, simplification,\n) {\n data.datasets.forEach(({ key, type, hasOwnYAxis }, i) => {\n if (!visibilities[i]) {\n return;\n }\n\n const options = {\n color: getCssColor(colors, `dataset#${key}`),\n lineWidth,\n opacity: data.isStacked ? 1 : visibilities[i],\n simplification,\n };\n\n const datasetType = type === 'pie' && pieToBar ? 'bar' : type;\n let datasetPoints = hasOwnYAxis ? secondaryPoints : points[i];\n let datasetProjection = hasOwnYAxis ? secondaryProjection : projection;\n\n if (datasetType === 'area') {\n const { yMin, yMax } = projection.getParams();\n const yHeight = yMax - yMin;\n const bottomLine = [\n { labelIndex: range.from, stackValue: 0 },\n { labelIndex: range.to, stackValue: 0 },\n ];\n const topLine = [\n { labelIndex: range.to, stackValue: yHeight },\n { labelIndex: range.from, stackValue: yHeight },\n ];\n\n datasetPoints = mergeArrays([points[i - 1] || bottomLine, topLine]);\n }\n\n if (datasetType === 'pie') {\n options.center = projection.getCenter();\n options.radius = getPieRadius(projection);\n options.pointerVector = state.focusOn;\n }\n\n if (datasetType === 'bar') {\n const [x0] = toPixels(projection, 0, 0);\n const [x1] = toPixels(projection, 1, 0);\n\n options.lineWidth = x1 - x0;\n options.focusOn = state.focusOn;\n }\n\n drawDataset(datasetType, context, datasetPoints, datasetProjection, options);\n });\n\n if (state.focusOn && (data.isBars || data.isSteps)) {\n const [x0] = toPixels(projection, 0, 0);\n const [x1] = toPixels(projection, 1, 0);\n\n drawBarsMask(context, projection, {\n focusOn: state.focusOn,\n color: getCssColor(colors, 'mask'),\n lineWidth: data.isSteps ? x1 - x0 + lineWidth : x1 - x0,\n });\n }\n}\n\nfunction drawDataset(type, ...args) {\n switch (type) {\n case 'line':\n return drawDatasetLine(...args);\n case 'bar':\n return drawDatasetBars(...args);\n case 'step':\n return drawDatasetSteps(...args);\n case 'area':\n return drawDatasetArea(...args);\n case 'pie':\n return drawDatasetPie(...args);\n }\n}\n\nfunction drawDatasetLine(context, points, projection, options) {\n context.beginPath();\n\n let pixels = [];\n\n for (let j = 0, l = points.length; j < l; j++) {\n const { labelIndex, stackValue } = points[j];\n pixels.push(toPixels(projection, labelIndex, stackValue));\n }\n\n if (options.simplification) {\n const simplifierFn = simplify(pixels);\n pixels = simplifierFn(options.simplification).points;\n }\n\n pixels.forEach(([x, y]) => {\n context.lineTo(x, y);\n });\n\n context.save();\n context.strokeStyle = options.color;\n context.lineWidth = options.lineWidth;\n context.globalAlpha = options.opacity;\n context.lineJoin = 'bevel';\n context.lineCap = 'butt';\n context.stroke();\n context.restore();\n}\n\n// TODO try areas\nfunction drawDatasetBars(context, points, projection, options) {\n const { yMin } = projection.getParams();\n\n context.save();\n context.globalAlpha = options.opacity;\n context.fillStyle = options.color;\n\n for (let j = 0, l = points.length; j < l; j++) {\n const { labelIndex, stackValue, stackOffset = 0 } = points[j];\n\n const [, yFrom] = toPixels(projection, labelIndex, Math.max(stackOffset, yMin));\n const [x, yTo] = toPixels(projection, labelIndex, stackValue);\n const rectX = x - options.lineWidth / 2;\n const rectY = yTo;\n const rectW = options.opacity === 1 ?\n options.lineWidth + PLOT_BARS_WIDTH_SHIFT :\n options.lineWidth + PLOT_BARS_WIDTH_SHIFT * options.opacity;\n const rectH = yFrom - yTo;\n\n context.fillRect(rectX, rectY, rectW, rectH);\n }\n\n context.restore();\n}\n\nfunction drawDatasetSteps(context, points, projection, options) {\n context.beginPath();\n\n let pixels = [];\n\n for (let j = 0, l = points.length; j < l; j++) {\n const { labelIndex, stackValue } = points[j];\n pixels.push(\n toPixels(projection, labelIndex - PLOT_BARS_WIDTH_SHIFT, stackValue),\n toPixels(projection, labelIndex + PLOT_BARS_WIDTH_SHIFT, stackValue),\n );\n }\n\n pixels.forEach(([x, y]) => {\n context.lineTo(x, y);\n });\n\n context.save();\n context.strokeStyle = options.color;\n context.lineWidth = options.lineWidth;\n context.globalAlpha = options.opacity;\n context.stroke();\n context.restore();\n}\n\nfunction drawBarsMask(context, projection, options) {\n const [xCenter, yCenter] = projection.getCenter();\n const [width, height] = projection.getSize();\n\n const [x] = toPixels(projection, options.focusOn, 0);\n\n context.fillStyle = options.color;\n context.fillRect(xCenter - width / 2, yCenter - height / 2, x - options.lineWidth / 2 + PLOT_BARS_WIDTH_SHIFT, height);\n context.fillRect(x + options.lineWidth / 2, yCenter - height / 2, width - (x + options.lineWidth / 2), height);\n}\n\nfunction drawDatasetArea(context, points, projection, options) {\n context.beginPath();\n\n let pixels = [];\n\n for (let j = 0, l = points.length; j < l; j++) {\n const { labelIndex, stackValue } = points[j];\n pixels.push(toPixels(projection, labelIndex, stackValue));\n }\n\n if (options.simplification) {\n const simplifierFn = simplify(pixels);\n pixels = simplifierFn(options.simplification).points;\n }\n\n pixels.forEach(([x, y]) => {\n context.lineTo(x, y);\n });\n\n context.save();\n context.fillStyle = options.color;\n context.lineWidth = options.lineWidth;\n context.globalAlpha = options.opacity;\n context.lineJoin = 'bevel';\n context.lineCap = 'butt';\n context.fill();\n context.restore();\n}\n\nfunction drawDatasetPie(context, points, projection, options) {\n const { visibleValue, stackValue, stackOffset = 0 } = points[0];\n\n if (!visibleValue) {\n return;\n }\n\n const { yMin, yMax } = projection.getParams();\n const percentFactor = 1 / (yMax - yMin);\n const percent = visibleValue * percentFactor;\n\n const beginAngle = stackOffset * percentFactor * Math.PI * 2 - Math.PI / 2;\n const endAngle = stackValue * percentFactor * Math.PI * 2 - Math.PI / 2;\n\n const { radius = 120, center: [x, y], pointerVector } = options;\n\n const shift = (\n pointerVector &&\n beginAngle <= pointerVector.angle &&\n pointerVector.angle < endAngle &&\n pointerVector.distance <= radius\n ) ? PLOT_PIE_SHIFT : 0;\n\n const shiftAngle = (beginAngle + endAngle) / 2;\n const directionX = Math.cos(shiftAngle);\n const directionY = Math.sin(shiftAngle);\n const shiftX = directionX * shift;\n const shiftY = directionY * shift;\n\n context.save();\n\n context.beginPath();\n context.fillStyle = options.color;\n context.moveTo(x + shiftX, y + shiftY);\n context.arc(x + shiftX, y + shiftY, radius, beginAngle, endAngle);\n context.lineTo(x + shiftX, y + shiftY);\n context.fill();\n\n if (percent >= PIE_MINIMUM_VISIBLE_PERCENT) {\n context.font = `700 ${getPieTextSize(percent, radius)}px Helvetica, Arial, sans-serif`;\n context.textAlign = 'center';\n context.textBaseline = 'middle';\n context.fillStyle = 'white';\n const textShift = getPieTextShift(percent, radius);\n context.fillText(\n `${Math.round(percent * 100)}%`, x + directionX * textShift + shiftX, y + directionY * textShift + shiftY,\n );\n }\n\n context.restore();\n}\n","import { addEventListener, removeEventListener } from './minifiers';\nimport { LONG_PRESS_TIMEOUT } from './constants';\n\nexport function captureEvents(element, options) {\n let captureEvent = null;\n let longPressTimeout = null;\n\n function onCapture(e) {\n captureEvent = e;\n\n if (e.type === 'mousedown') {\n addEventListener(document, 'mousemove', onMove);\n addEventListener(document, 'mouseup', onRelease);\n } else if (e.type === 'touchstart') {\n addEventListener(document, 'touchmove', onMove);\n addEventListener(document, 'touchend', onRelease);\n addEventListener(document, 'touchcancel', onRelease);\n\n // https://stackoverflow.com/questions/11287877/how-can-i-get-e-offsetx-on-mobile-ipad\n // Android does not have this value, and iOS has it but as read-only.\n if (e.pageX === undefined) {\n e.pageX = e.touches[0].pageX;\n }\n }\n\n if (options.draggingCursor) {\n document.documentElement.classList.add(`cursor-${options.draggingCursor}`);\n }\n\n options.onCapture && options.onCapture(e);\n\n if (options.onLongPress) {\n longPressTimeout = setTimeout(() => options.onLongPress(), LONG_PRESS_TIMEOUT);\n }\n }\n\n function onRelease(e) {\n if (captureEvent) {\n if (longPressTimeout) {\n clearTimeout(longPressTimeout);\n longPressTimeout = null;\n }\n\n if (options.draggingCursor) {\n document.documentElement.classList.remove(`cursor-${options.draggingCursor}`);\n }\n\n removeEventListener(document, 'mouseup', onRelease);\n removeEventListener(document, 'mousemove', onMove);\n removeEventListener(document, 'touchcancel', onRelease);\n removeEventListener(document, 'touchend', onRelease);\n removeEventListener(document, 'touchmove', onMove);\n\n captureEvent = null;\n\n options.onRelease && options.onRelease(e);\n }\n }\n\n function onMove(e) {\n if (captureEvent) {\n if (longPressTimeout) {\n clearTimeout(longPressTimeout);\n longPressTimeout = null;\n }\n\n if (e.type === 'touchmove' && e.pageX === undefined) {\n e.pageX = e.touches[0].pageX;\n }\n\n options.onDrag && options.onDrag(e, captureEvent, {\n dragOffsetX: e.pageX - captureEvent.pageX,\n });\n }\n }\n\n addEventListener(element, 'mousedown', onCapture);\n addEventListener(element, 'touchstart', onCapture);\n}\n","import { setupCanvas, clearCanvas } from './canvas';\nimport { BALLOON_OFFSET, X_AXIS_HEIGHT } from './constants';\nimport { getPieRadius } from './formulas';\nimport { formatInteger, getLabelDate, getLabelTime, statsFormatDayHourFull } from './format';\nimport { getCssColor } from './skin';\nimport { throttle, throttleWithRaf } from './utils';\nimport { addEventListener, createElement } from './minifiers';\nimport { toPixels } from './Projection';\n\nexport function createTooltip(container, data, plotSize, colors, onZoom, onFocus) {\n let _state;\n let _points;\n let _projection;\n let _secondaryPoints;\n let _secondaryProjection;\n\n let _element;\n let _canvas;\n let _context;\n let _balloon;\n\n let _offsetX;\n let _offsetY;\n let _clickedOnLabel = null;\n\n let _isZoomed = false;\n let _isZooming = false;\n\n const _selectLabelOnRaf = throttleWithRaf(_selectLabel);\n const _throttledUpdateContent = throttle(_updateContent, 100, true, true);\n\n _setupLayout();\n\n function update(state, points, projection, secondaryPoints, secondaryProjection) {\n _state = state;\n _points = points;\n _projection = projection;\n _secondaryPoints = secondaryPoints;\n _secondaryProjection = secondaryProjection;\n _selectLabel(true);\n }\n\n function toggleLoading(isLoading) {\n _balloon.classList.toggle('lovely-chart--state-loading', isLoading);\n\n if (!isLoading) {\n _clear();\n }\n }\n\n function toggleIsZoomed(isZoomed) {\n if (isZoomed !== _isZoomed) {\n _isZooming = true;\n }\n _isZoomed = isZoomed;\n _balloon.classList.toggle('lovely-chart--state-inactive', isZoomed);\n }\n\n function _setupLayout() {\n _element = createElement();\n _element.className = `lovely-chart--tooltip`;\n\n _setupCanvas();\n _setupBalloon();\n\n if ('ontouchstart' in window) {\n addEventListener(_element, 'touchmove', _onMouseMove);\n addEventListener(_element, 'touchstart', _onMouseMove);\n addEventListener(document, 'touchstart', _onDocumentMove);\n } else {\n addEventListener(_element, 'mousemove', _onMouseMove);\n addEventListener(_element, 'click', _onClick);\n addEventListener(document, 'mousemove', _onDocumentMove);\n }\n\n container.appendChild(_element);\n }\n\n function _setupCanvas() {\n const { canvas, context } = setupCanvas(_element, plotSize);\n\n _canvas = canvas;\n _context = context;\n }\n\n function _setupBalloon() {\n _balloon = createElement();\n _balloon.className = `lovely-chart--tooltip-balloon${!data.isZoomable ? ' lovely-chart--state-inactive' : ''}`;\n _balloon.innerHTML = '<div class=\"lovely-chart--tooltip-title\"></div><div class=\"lovely-chart--tooltip-legend\"></div><div class=\"lovely-chart--spinner\"></div>';\n\n if ('ontouchstart' in window && data.isZoomable) {\n addEventListener(_balloon, 'click', _onBalloonClick);\n }\n\n _element.appendChild(_balloon);\n }\n\n function _onMouseMove(e) {\n if (e.target === _balloon || _balloon.contains(e.target) || _clickedOnLabel) {\n return;\n }\n\n _isZooming = false;\n\n const pageOffset = _getPageOffset(_element);\n _offsetX = (e.touches ? e.touches[0].clientX : e.clientX) - pageOffset.left;\n _offsetY = (e.touches ? e.touches[0].clientY : e.clientY) - pageOffset.top;\n\n _selectLabelOnRaf();\n }\n\n function _onDocumentMove(e) {\n if (_offsetX !== null && e.target !== _element && !_element.contains(e.target)) {\n _clear();\n }\n }\n\n function _onClick(e) {\n if (_isZooming) {\n return;\n }\n\n if (data.isZoomable) {\n const oldLabelIndex = _clickedOnLabel;\n\n _clickedOnLabel = null;\n _onMouseMove(e, true);\n\n const newLabelIndex = _getLabelIndex();\n if (newLabelIndex !== oldLabelIndex) {\n _clickedOnLabel = newLabelIndex;\n }\n\n onZoom(newLabelIndex);\n }\n }\n\n function _onBalloonClick() {\n if (_balloon.classList.contains('lovely-chart--state-inactive')) {\n return;\n }\n\n const labelIndex = _projection.findClosestLabelIndex(_offsetX);\n onZoom(labelIndex);\n }\n\n function _clear(isExternal) {\n _offsetX = null;\n _clickedOnLabel = null;\n clearCanvas(_canvas, _context);\n _hideBalloon();\n\n if (!isExternal && onFocus) {\n onFocus(null);\n }\n }\n\n function _getLabelIndex() {\n const labelIndex = _projection.findClosestLabelIndex(_offsetX);\n return labelIndex < _state.labelFromIndex || labelIndex > _state.labelToIndex ? null : labelIndex;\n }\n\n function _selectLabel(isExternal) {\n if (!_offsetX || !_state || _isZooming) {\n return;\n }\n\n const labelIndex = _getLabelIndex();\n if (labelIndex === null) {\n _clear(isExternal);\n return;\n }\n\n const pointerVector = getPointerVector();\n const shouldShowBalloon = data.isPie ? pointerVector.distance <= getPieRadius(_projection) : true;\n\n if (!isExternal && onFocus) {\n if (data.isPie) {\n onFocus(pointerVector);\n } else {\n onFocus(labelIndex);\n }\n }\n\n function getValue(values, labelIndex) {\n if (data.isPie) {\n return values.slice(_state.labelFromIndex, _state.labelToIndex + 1).reduce((a, x) => a + x, 0);\n }\n\n return values[labelIndex];\n }\n\n const [xPx] = toPixels(_projection, labelIndex, 0);\n const statistics = data.datasets\n .map(({ key, name, values, hasOwnYAxis }, i) => ({\n key,\n name,\n value: getValue(values, labelIndex),\n hasOwnYAxis,\n originalIndex: i,\n }))\n .filter(({ key }) => _state.filter[key]);\n\n if (statistics.length && shouldShowBalloon) {\n _updateBalloon(statistics, labelIndex);\n } else {\n _hideBalloon();\n }\n\n clearCanvas(_canvas, _context);\n if (data.isLines || data.isAreas) {\n if (data.isLines) {\n _drawCircles(statistics, labelIndex);\n }\n\n _drawTail(xPx, plotSize.height - X_AXIS_HEIGHT, getCssColor(colors, 'grid-lines'));\n }\n }\n\n function _drawCircles(statistics, labelIndex) {\n statistics.forEach(({ value, key, hasOwnYAxis, originalIndex }) => {\n const pointIndex = labelIndex - _state.labelFromIndex;\n const point = hasOwnYAxis ? _secondaryPoints[pointIndex] : _points[originalIndex][pointIndex];\n\n if (!point) {\n return;\n }\n\n const [x, y] = hasOwnYAxis\n ? toPixels(_secondaryProjection, labelIndex, point.stackValue)\n : toPixels(_projection, labelIndex, point.stackValue);\n\n // TODO animate\n _drawCircle(\n [x, y],\n getCssColor(colors, `dataset#${key}`),\n getCssColor(colors, 'background'),\n );\n });\n }\n\n function _drawCircle([xPx, yPx], strokeColor, fillColor) {\n _context.strokeStyle = strokeColor;\n _context.fillStyle = fillColor;\n _context.lineWidth = 2;\n\n _context.beginPath();\n _context.arc(xPx, yPx, 4, 0, 2 * Math.PI);\n _context.fill();\n _context.stroke();\n }\n\n function _drawTail(xPx, height, color) {\n _context.strokeStyle = color;\n _context.lineWidth = 1;\n\n _context.beginPath();\n _context.moveTo(xPx, 0);\n _context.lineTo(xPx, height);\n _context.stroke();\n }\n\n function _getBalloonLeftOffset(labelIndex) {\n const meanLabel = (_state.labelFromIndex + _state.labelToIndex) / 2;\n const { angle } = getPointerVector();\n\n const shouldPlaceRight = data.isPie ? angle > Math.PI / 2 : labelIndex < meanLabel;\n\n const leftOffset = shouldPlaceRight ? _offsetX + BALLOON_OFFSET : _offsetX - (_balloon.offsetWidth + BALLOON_OFFSET);\n\n return Math.min(Math.max(0, leftOffset), container.offsetWidth - _balloon.offsetWidth);\n }\n\n function _getBalloonTopOffset() {\n return data.isPie ? `${_offsetY}px` : 0;\n }\n\n function _updateBalloon(statistics, labelIndex) {\n _balloon.style.transform = `translate3D(${_getBalloonLeftOffset(labelIndex)}px, ${_getBalloonTopOffset()}, 0)`;\n _balloon.classList.add('lovely-chart--state-shown');\n\n if (data.isPie) {\n _updateContent(null, statistics);\n } else {\n _throttledUpdateContent(_getTitle(data, labelIndex), statistics);\n }\n }\n\n function _getTitle(data, labelIndex) {\n switch (data.tooltipFormatter) {\n case 'statsFormatDayHourFull':\n return statsFormatDayHourFull(data.xLabels[labelIndex].value);\n case 'statsTooltipFormat(\\'day\\')':\n return getLabelDate(data.xLabels[labelIndex]);\n case 'statsTooltipFormat(\\'hour\\')':\n case 'statsTooltipFormat(\\'5min\\')':\n return getLabelTime(data.xLabels[labelIndex]);\n default:\n return data.xLabels[labelIndex].text;\n }\n }\n\n function _isPieSectorSelected(statistics, value, totalValue, index, pointerVector) {\n const offset = index > 0 ? statistics.slice(0, index).reduce((a, x) => a + x.value, 0) : 0;\n const beginAngle = offset / totalValue * Math.PI * 2 - Math.PI / 2;\n const endAngle = (offset + value) / totalValue * Math.PI * 2 - Math.PI / 2;\n\n return pointerVector &&\n beginAngle <= pointerVector.angle &&\n pointerVector.angle < endAngle &&\n pointerVector.distance <= getPieRadius(_projection);\n }\n\n function _updateTitle(title) {\n const titleContainer = _balloon.children[0];\n\n if (data.isPie) {\n if (titleContainer) {\n titleContainer.style.display = 'none';\n }\n } else {\n if (titleContainer.style.display === 'none') {\n titleContainer.style.display = '';\n }\n const currentTitle = titleContainer.querySelector(':not(.lovely-chart--state-hidden)');\n\n if (!titleContainer.innerHTML || !currentTitle) {\n titleContainer.innerHTML = `<span>${title}</span>`;\n } else {\n currentTitle.innerHTML = title;\n }\n }\n }\n\n function _insertNewDataSet(dataSetContainer, { name, key, value }, totalValue) {\n const className = `lovely-chart--tooltip-dataset-value lovely-chart--position-right lovely-chart--color-${data.colors[key].slice(1)}`;\n const newDataSet = createElement();\n newDataSet.className = 'lovely-chart--tooltip-dataset';\n newDataSet.setAttribute('data-present', 'true');\n newDataSet.setAttribute('data-name', name);\n newDataSet.innerHTML = `<span class=\"lovely-chart--dataset-title\">${name}</span><span class=\"${className}\">${formatInteger(value)}</span>`;\n _renderPercentageValue(newDataSet, value, totalValue);\n\n const totalText = dataSetContainer.querySelector(`[data-total=\"true\"]`);\n if (totalText) {\n dataSetContainer.insertBefore(newDataSet, totalText);\n } else {\n dataSetContainer.appendChild(newDataSet);\n }\n }\n\n function _updateDataSet(currentDataSet, { key, value } = {}, totalValue) {\n currentDataSet.setAttribute('data-present', 'true');\n\n const valueElement = currentDataSet.querySelector(`.lovely-chart--tooltip-dataset-value.lovely-chart--color-${data.colors[key].slice(1)}:not(.lovely-chart--state-hidden)`);\n valueElement.innerHTML = formatInteger(value);\n\n _renderPercentageValue(currentDataSet, value, totalValue);\n }\n\n function _renderPercentageValue(dataSet, value, totalValue) {\n if (!data.isPercentage) {\n return;\n }\n\n if (data.isPie) {\n Array.from(dataSet.querySelectorAll(`.lovely-chart--percentage-title`)).forEach(e => e.remove());\n return;\n }\n\n const percentageValue = totalValue ? Math.round(value / totalValue * 100) : 0;\n const percentageElement = dataSet.querySelector(`.lovely-chart--percentage-title:not(.lovely-chart--state-hidden)`);\n\n if (!percentageElement) {\n const newPercentageTitle = createElement('span');\n newPercentageTitle.className = 'lovely-chart--percentage-title lovely-chart--position-left';\n newPercentageTitle.innerHTML = `${percentageValue}%`;\n dataSet.prepend(newPercentageTitle);\n } else {\n percentageElement.innerHTML = `${percentageValue}%`;\n }\n }\n\n function _updateDataSets(statistics) {\n const dataSetContainer = _balloon.children[1];\n if (data.isPie) {\n dataSetContainer.classList.add('lovely-chart--tooltip-legend-pie');\n }\n\n Array.from(dataSetContainer.children).forEach((dataSet) => {\n if (!data.isPie && dataSetContainer.classList.contains('lovely-chart--tooltip-legend-pie')) {\n dataSet.remove();\n } else {\n dataSet.setAttribute('data-present', 'false');\n }\n });\n\n const totalValue = statistics.reduce((a, x) => a + x.value, 0);\n const pointerVector = getPointerVector();\n const finalStatistics = data.isPie ? statistics.filter(({ value }, index) => _isPieSectorSelected(statistics, value, totalValue, index, pointerVector)) : statistics;\n\n finalStatistics.forEach((statItem) => {\n const currentDataSet = dataSetContainer.querySelector(`[data-name=\"${statItem.name}\"]`);\n\n if (!currentDataSet) {\n _insertNewDataSet(dataSetContainer, statItem, totalValue);\n } else {\n _updateDataSet(currentDataSet, statItem, totalValue);\n }\n });\n\n if ((data.isBars || data.isSteps) && data.isStacked) {\n _renderTotal(dataSetContainer, formatInteger(totalValue));\n }\n\n Array.from(dataSetContainer.querySelectorAll('[data-present=\"false\"]'))\n .forEach((dataSet) => {\n dataSet.remove();\n });\n }\n\n function _updateContent(title, statistics) {\n _updateTitle(title);\n _updateDataSets(statistics);\n }\n\n function _renderTotal(dataSetContainer, totalValue) {\n const totalText = dataSetContainer.querySelector(`[data-total=\"true\"]`);\n const className = `lovely-chart--tooltip-dataset-value lovely-chart--position-right`;\n if (!totalText) {\n const newTotalText = createElement();\n newTotalText.className = 'lovely-chart--tooltip-dataset';\n newTotalText.setAttribute('data-present', 'true');\n newTotalText.setAttribute('data-total', 'true');\n newTotalText.innerHTML = `<span>All</span><span class=\"${className}\">${totalValue}</span>`;\n dataSetContainer.appendChild(newTotalText);\n } else {\n totalText.setAttribute('data-present', 'true');\n\n const valueElement = totalText.querySelector(`.lovely-chart--tooltip-dataset-value:not(.lovely-chart--state-hidden)`);\n valueElement.innerHTML = totalValue;\n }\n }\n\n function _hideBalloon() {\n _balloon.classList.remove('lovely-chart--state-shown');\n }\n\n function getPointerVector() {\n const { width, height } = _element.getBoundingClientRect();\n\n const center = [width / 2, height / 2];\n const angle = Math.atan2(_offsetY - center[1], _offsetX - center[0]);\n const distance = Math.sqrt((_offsetX - center[0]) ** 2 + (_offsetY - center[1]) ** 2);\n\n return {\n angle: angle >= -Math.PI / 2 ? angle : 2 * Math.PI + angle,\n distance,\n };\n }\n\n function _getPageOffset(el) {\n return el.getBoundingClientRect();\n }\n\n return { update, toggleLoading, toggleIsZoomed };\n}\n\n","import { getMaxMin } from './utils';\nimport { statsFormatHour, statsFormatDay, statsFormatDayHour, statsFormatText, statsFormatMin } from './format';\n\nexport function analyzeData(data) {\n const { title, labelFormatter, tooltipFormatter, isStacked, isPercentage, hasSecondYAxis, onZoom, minimapRange, hideCaption, zoomOutLabel } = data;\n const { datasets, labels } = prepareDatasets(data);\n\n const colors = {};\n let totalYMin = Infinity;\n let totalYMax = -Infinity;\n datasets.forEach(({ key, color, yMin, yMax }) => {\n colors[key] = color;\n\n if (yMin < totalYMin) {\n totalYMin = yMin;\n }\n\n if (yMax > totalYMax) {\n totalYMax = yMax;\n }\n });\n\n let xLabels;\n switch (labelFormatter) {\n case 'statsFormatDayHour':\n xLabels = statsFormatDayHour(labels);\n break;\n case 'statsFormat(\\'day\\')':\n xLabels = statsFormatDay(labels);\n break;\n case 'statsFormat(\\'hour\\')':\n case 'statsFormat(\\'5min\\')':\n xLabels = statsFormatMin(labels);\n break;\n default:\n xLabels = statsFormatText(labels);\n break;\n }\n\n const analyzed = {\n title,\n labelFormatter,\n tooltipFormatter,\n xLabels,\n datasets,\n isStacked,\n isPercentage,\n hasSecondYAxis,\n onZoom,\n isLines: data.type === 'line',\n isBars: data.type === 'bar',\n isSteps: data.type === 'step',\n isAreas: data.type === 'area',\n isPie: data.type === 'pie',\n yMin: totalYMin,\n yMax: totalYMax,\n colors,\n minimapRange,\n hideCaption,\n zoomOutLabel,\n };\n\n analyzed.shouldZoomToPie = !analyzed.onZoom && analyzed.isPercentage;\n analyzed.isZoomable = analyzed.onZoom || analyzed.shouldZoomToPie;\n\n return analyzed;\n}\n\nfunction prepareDatasets(data) {\n const { type, labels, datasets, hasSecondYAxis } = data;\n\n return {\n labels: cloneArray(labels),\n datasets: datasets.map(({ name, color, values }, i) => {\n const { min: yMin, max: yMax } = getMaxMin(values);\n\n return {\n type,\n key: `y${i}`,\n name,\n color,\n values: cloneArray(values),\n hasOwnYAxis: hasSecondYAxis && i === datasets.length - 1,\n yMin,\n yMax,\n };\n }),\n };\n}\n\nfunction cloneArray(array) {\n return array.slice(0);\n}\n","import { createStateManager } from './StateManager';\nimport { createHeader } from './Header';\nimport { createAxes } from './Axes';\nimport { createMinimap } from './Minimap';\nimport { createTooltip } from './Tooltip';\nimport { createTools } from './Tools';\nimport { createZoomer } from './Zoomer';\nimport { createColors } from './skin';\nimport { analyzeData } from './data';\nimport { setupCanvas, clearCanvas } from './canvas';\nimport { preparePoints } from './preparePoints';\nimport { createProjection } from './Projection';\nimport { drawDatasets } from './drawDatasets';\nimport { createElement } from './minifiers';\nimport { getFullLabelDate, getLabelDate } from './format';\nimport {\n X_AXIS_HEIGHT,\n GUTTER,\n PLOT_TOP_PADDING,\n PLOT_HEIGHT,\n PLOT_LINE_WIDTH,\n SIMPLIFIER_PLOT_FACTOR,\n} from './constants';\nimport { getSimplificationDelta, isDataRange } from './formulas';\nimport { debounce } from './utils';\nimport './styles/index.scss';\n\nfunction create(container, originalData) {\n let _stateManager;\n\n let _element;\n let _plot;\n let _context;\n let _plotSize;\n\n let _header;\n let _axes;\n let _minimap;\n let _tooltip;\n let _tools;\n let _zoomer;\n\n let _state;\n let _windowWidth = window.innerWidth;\n\n const _data = analyzeData(originalData);\n const _colors = createColors(_data.colors);\n const _redrawDebounced = debounce(_redraw, 500, false, true);\n\n _setupComponents();\n _setupGlobalListeners();\n\n function _setupComponents() {\n _setupContainer();\n _header = createHeader(_element, _data.title, _data.zoomOutLabel, _onZoomOut);\n _setupPlotCanvas();\n _stateManager = createStateManager(_data, _plotSize, _onStateUpdate);\n _axes = createAxes(_context, _data, _plotSize, _colors);\n _minimap = createMinimap(_element, _data, _colors, _onRangeChange);\n _tooltip = createTooltip(_element, _data, _plotSize, _colors, _onZoomIn, _onFocus);\n _tools = createTools(_element, _data, _onFilterChange);\n _zoomer = _data.isZoomable && createZoomer(_data, originalData, _colors, _stateManager, _element, _header, _minimap, _tooltip, _tools);\n // hideOnScroll(_element);\n }\n\n function _setupContainer() {\n _element = createElement();\n _element.className = `lovely-chart--container${_data.shouldZoomToPie ? ' lovely-chart--container-type-pie' : ''}`;\n\n container.appendChild(_element);\n }\n\n function _setupPlotCanvas() {\n const { canvas, context } = setupCanvas(_element, {\n width: _element.clientWidth,\n height: PLOT_HEIGHT,\n });\n\n _plot = canvas;\n _context = context;\n\n _plotSize = {\n width: _plot.offsetWidth,\n height: _plot.offsetHeight,\n };\n }\n\n function _onStateUpdate(state) {\n _state = state;\n\n const { datasets } = _data;\n const range = {\n from: state.labelFromIndex,\n to: state.labelToIndex,\n };\n const boundsAndParams = {\n begin: state.begin,\n end: state.end,\n totalXWidth: state.totalXWidth,\n yMin: state.yMinViewport,\n yMax: state.yMaxViewport,\n availableWidth: _plotSize.width,\n availableHeight: _plotSize.height - X_AXIS_HEIGHT,\n xPadding: GUTTER,\n yPadding: PLOT_TOP_PADDING,\n };\n const visibilities = datasets.map(({ key }) => state[`opacity#${key}`]);\n const points = preparePoints(_data, datasets, range, visibilities, boundsAndParams);\n const projection = createProjection(boundsAndParams);\n\n let secondaryPoints = null;\n let secondaryProjection = null;\n if (_data.hasSecondYAxis) {\n const secondaryDataset = datasets.find((d) => d.hasOwnYAxis);\n const bounds = {\n yMin: state.yMinViewportSecond,\n yMax: state.yMaxViewportSecond,\n };\n secondaryPoints = preparePoints(_data, [secondaryDataset], range, visibilities, bounds)[0];\n secondaryProjection = projection.copy(bounds);\n }\n\n if (!_data.hideCaption) {\n _header.setCaption(_getCaption(state));\n }\n\n clearCanvas(_plot, _context);\n\n const totalPoints = points.reduce((a, p) => a + p.length, 0);\n const simplification = getSimplificationDelta(totalPoints) * SIMPLIFIER_PLOT_FACTOR;\n\n drawDatasets(\n _context, state, _data,\n range, points, projection, secondaryPoints, secondaryProjection,\n PLOT_LINE_WIDTH, visibilities, _colors, false, simplification,\n );\n if (!_data.isPie) {\n _axes.drawYAxis(state, projection, secondaryProjection);\n // TODO check isChanged\n _axes.drawXAxis(state, projection);\n }\n _minimap.update(state);\n _tooltip.update(state, points, projection, secondaryPoints, secondaryProjection);\n }\n\n function _onRangeChange(range) {\n _stateManager.update({ range });\n }\n\n function _onFilterChange(filter) {\n _stateManager.update({ filter });\n }\n\n function _onFocus(focusOn) {\n if (_data.isBars || _data.isPie || _data.isSteps) {\n // TODO animate\n _stateManager.update({ focusOn });\n }\n }\n\n function _onZoomIn(labelIndex) {\n _zoomer.zoomIn(_state, labelIndex);\n }\n\n function _onZoomOut() {\n _zoomer.zoomOut(_state);\n }\n\n function _setupGlobalListeners() {\n document.documentElement.addEventListener('darkmode', () => {\n _stateManager.update();\n });\n\n window.addEventListener('resize', () => {\n if (window.innerWidth !== _windowWidth) {\n _windowWidth = window.innerWidth;\n _redrawDebounced();\n }\n });\n\n window.addEventListener('orientationchange', () => {\n _redrawDebounced();\n });\n }\n\n function _redraw() {\n Object.assign(_data, analyzeData(originalData));\n _element.remove();\n _setupComponents();\n }\n\n function _getCaption(state) {\n let startIndex;\n let endIndex;\n\n if (_zoomer && _zoomer.isZoomed()) {\n // TODO Fix label\n startIndex = state.labelFromIndex === 0 ? 0 : state.labelFromIndex + 1;\n endIndex = state.labelToIndex === state.totalXWidth - 1 ? state.labelToIndex : state.labelToIndex - 1;\n } else {\n startIndex = state.labelFromIndex;\n endIndex = state.labelToIndex;\n }\n\n return isDataRange(_data.xLabels[startIndex], _data.xLabels[endIndex])\n ? (\n `${getLabelDate(_data.xLabels[startIndex])}` +\n ' — ' +\n `${getLabelDate(_data.xLabels[endIndex])}`\n )\n : getFullLabelDate(_data.xLabels[startIndex]);\n }\n}\n\nexport { create };\n","import { createElement, addEventListener } from './minifiers';\nimport { toggleText } from './toggleText';\nimport { throttle } from './utils';\n\nexport function createHeader(container, title, zoomOutLabel = 'Zoom out', zoomOutCallback) {\n let _element;\n let _titleElement;\n let _zoomOutElement;\n let _captionElement;\n let _isZooming;\n\n const setCaptionThrottled = throttle(setCaption, 100, false);\n\n _setupLayout();\n\n function setCaption(caption) {\n if (_isZooming) {\n return;\n }\n\n _captionElement.innerHTML = caption;\n }\n\n function zoom(caption) {\n _zoomOutElement = toggleText(_titleElement, zoomOutLabel, 'lovely-chart--header-title lovely-chart--header-zoom-out-control');\n setTimeout(() => {\n addEventListener(_zoomOutElement, 'click', _onZoomOut);\n }, 500);\n\n setCaption(caption);\n }\n\n function toggleIsZooming(isZooming) {\n _isZooming = isZooming;\n }\n\n function _setupLayout() {\n _element = createElement();\n _element.className = 'lovely-chart--header';\n\n _titleElement = createElement();\n _titleElement.className = 'lovely-chart--header-title';\n _titleElement.innerHTML = title;\n _element.appendChild(_titleElement);\n\n _captionElement = createElement();\n _captionElement.className = 'lovely-chart--header-caption lovely-chart--position-right';\n _element.appendChild(_captionElement);\n\n container.appendChild(_element);\n }\n\n function _onZoomOut() {\n _titleElement = toggleText(_zoomOutElement, title, 'lovely-chart--header-title', true);\n _titleElement.classList.remove('lovely-chart--transition');\n\n zoomOutCallback();\n }\n\n return {\n setCaption: setCaptionThrottled,\n zoom,\n toggleIsZooming,\n };\n}\n","import { SPEED_TEST_FAST_FPS, SPEED_TEST_INTERVAL, TRANSITION_DEFAULT_DURATION } from './constants';\n\nfunction transition(t) {\n // faster\n // return -t * (t - 2);\n // easeOut\n return 1 - Math.pow(1 - t, 1.675);\n}\n\nexport function createTransitionManager(onTick) {\n const _transitions = {};\n\n let _nextFrame = null;\n\n let _testStartedAt = null;\n let _fps = null;\n let _testingFps = null;\n let _slowDetectedAt = null;\n let _startedAsSlow = null;\n\n function add(prop, from, to, duration, options) {\n _transitions[prop] = {\n from,\n to,\n duration,\n options,\n current: from,\n startedAt: Date.now(),\n progress: 0,\n };\n\n if (!_nextFrame) {\n _resetSpeedTest();\n _nextFrame = requestAnimationFrame(_tick);\n }\n }\n\n function remove(prop) {\n delete _transitions[prop];\n\n if (!isRunning()) {\n cancelAnimationFrame(_nextFrame);\n _nextFrame = null;\n }\n }\n\n function get(prop) {\n return _transitions[prop];\n }\n\n function getState() {\n const state = {};\n\n Object.keys(_transitions).forEach((prop) => {\n const { current, from, to, progress } = _transitions[prop];\n state[prop] = current;\n // TODO perf lazy\n state[`${prop}From`] = from;\n state[`${prop}To`] = to;\n state[`${prop}Progress`] = progress;\n });\n\n return state;\n }\n\n function isRunning() {\n return Boolean(Object.keys(_transitions).length);\n }\n\n function isFast(forceCheck) {\n if (!forceCheck && (_startedAsSlow || _slowDetectedAt)) {\n return false;\n }\n\n return _fps === null || _fps >= SPEED_TEST_FAST_FPS;\n }\n\n function _tick() {\n const isSlow = !isFast();\n _speedTest();\n\n const state = {};\n\n Object.keys(_transitions).forEach((prop) => {\n const { startedAt, from, to, duration = TRANSITION_DEFAULT_DURATION, options } = _transitions[prop];\n const progress = Math.min(1, (Date.now() - startedAt) / duration);\n let current = from + (to - from) * transition(progress);\n\n if (options.includes('ceil')) {\n current = Math.ceil(current);\n } else if (options.includes('floor')) {\n current = Math.floor(current);\n }\n\n _transitions[prop].current = current;\n _transitions[prop].progress = progress;\n state[prop] = current;\n\n if (progress === 1) {\n remove(prop);\n }\n });\n\n if (!isSlow) {\n onTick(state);\n }\n\n if (isRunning()) {\n _nextFrame = requestAnimationFrame(_tick);\n }\n }\n\n function _resetSpeedTest() {\n _testStartedAt = null;\n _testingFps = null;\n if (_slowDetectedAt && Date.now() - _slowDetectedAt > 5000) {\n _slowDetectedAt = null;\n }\n _startedAsSlow = Boolean(_slowDetectedAt) || !isFast(true);\n }\n\n function _speedTest() {\n if (!_testStartedAt || (Date.now() - _testStartedAt) >= SPEED_TEST_INTERVAL) {\n if (_testingFps) {\n _fps = _testingFps;\n if (!_slowDetectedAt && !isFast(true)) {\n _slowDetectedAt = Date.now();\n }\n }\n _testStartedAt = Date.now();\n _testingFps = 0;\n } else {\n _testingFps++;\n }\n }\n\n return { add, remove, get, getState, isRunning, isFast };\n}\n","import { GUTTER, AXES_FONT, X_AXIS_HEIGHT, X_AXIS_SHIFT_START, PLOT_TOP_PADDING } from './constants';\nimport { humanize } from './format';\nimport { getCssColor } from './skin';\nimport { applyXEdgeOpacity, applyYEdgeOpacity, xScaleLevelToStep, yScaleLevelToStep } from './formulas';\nimport { toPixels } from './Projection';\n\nexport function createAxes(context, data, plotSize, colors) {\n function drawXAxis(state, projection) {\n context.clearRect(0, plotSize.height - X_AXIS_HEIGHT + 1, plotSize.width, X_AXIS_HEIGHT + 1);\n\n const topOffset = plotSize.height - X_AXIS_HEIGHT / 2;\n const scaleLevel = Math.floor(state.xAxisScale);\n const step = xScaleLevelToStep(scaleLevel);\n const opacityFactor = 1 - (state.xAxisScale - scaleLevel);\n\n context.font = AXES_FONT;\n context.textAlign = 'center';\n context.textBaseline = 'middle';\n\n for (let i = state.labelFromIndex; i <= state.labelToIndex; i++) {\n const shiftedI = i - X_AXIS_SHIFT_START;\n\n if (shiftedI % step !== 0) {\n continue;\n }\n\n const label = data.xLabels[i];\n const [xPx] = toPixels(projection, i, 0);\n let opacity = shiftedI % (step * 2) === 0 ? 1 : opacityFactor;\n opacity = applyYEdgeOpacity(opacity, xPx, plotSize.width);\n\n context.fillStyle = getCssColor(colors, 'x-axis-text', opacity);\n context.fillText(label.text, xPx, topOffset);\n }\n }\n\n function drawYAxis(state, projection, secondaryProjection) {\n const {\n yAxisScale, yAxisScaleFrom, yAxisScaleTo, yAxisScaleProgress = 0,\n yMinViewport, yMinViewportFrom, yMinViewportTo,\n yMaxViewport, yMaxViewportFrom, yMaxViewportTo,\n yMinViewportSecond, yMinViewportSecondFrom, yMinViewportSecondTo,\n yMaxViewportSecond, yMaxViewportSecondFrom, yMaxViewportSecondTo,\n } = state;\n const colorKey = secondaryProjection && `dataset#${data.datasets[0].key}`;\n const isYChanging = yMinViewportFrom !== undefined || yMaxViewportFrom !== undefined;\n\n if (data.isPercentage) {\n _drawYAxisPercents(projection);\n } else {\n _drawYAxisScaled(\n state,\n projection,\n Math.round(yAxisScaleTo || yAxisScale),\n yMinViewportTo !== undefined ? yMinViewportTo : yMinViewport,\n yMaxViewportTo !== undefined ? yMaxViewportTo : yMaxViewport,\n yAxisScaleFrom ? yAxisScaleProgress : 1,\n colorKey,\n );\n }\n\n if (yAxisScaleProgress > 0 && isYChanging) {\n _drawYAxisScaled(\n state,\n projection,\n Math.round(yAxisScaleFrom),\n yMinViewportFrom !== undefined ? yMinViewportFrom : yMinViewport,\n yMaxViewportFrom !== undefined ? yMaxViewportFrom : yMaxViewport,\n 1 - yAxisScaleProgress,\n colorKey,\n );\n }\n\n if (secondaryProjection) {\n const { yAxisScaleSecond, yAxisScaleSecondFrom, yAxisScaleSecondTo, yAxisScaleSecondProgress = 0 } = state;\n const secondaryColorKey = `dataset#${data.datasets[data.datasets.length - 1].key}`;\n const isYChanging = yMinViewportSecondFrom !== undefined || yMaxViewportSecondFrom !== undefined;\n\n _drawYAxisScaled(\n state,\n secondaryProjection,\n Math.round(yAxisScaleSecondTo || yAxisScaleSecond),\n yMinViewportSecondTo !== undefined ? yMinViewportSecondTo : yMinViewportSecond,\n yMaxViewportSecondTo !== undefined ? yMaxViewportSecondTo : yMaxViewportSecond,\n yAxisScaleSecondFrom ? yAxisScaleSecondProgress : 1,\n secondaryColorKey,\n true,\n );\n\n if (yAxisScaleSecondProgress > 0 && isYChanging) {\n _drawYAxisScaled(\n state,\n secondaryProjection,\n Math.round(yAxisScaleSecondFrom),\n yMinViewportSecondFrom !== undefined ? yMinViewportSecondFrom : yMinViewportSecond,\n yMaxViewportSecondFrom !== undefined ? yMaxViewportSecondFrom : yMaxViewportSecond,\n 1 - yAxisScaleSecondProgress,\n secondaryColorKey,\n true,\n );\n }\n }\n }\n\n function _drawYAxisScaled(state, projection, scaleLevel, yMin, yMax, opacity = 1, colorKey = null, isSecondary = false) {\n const step = yScaleLevelToStep(scaleLevel);\n const firstVisibleValue = Math.ceil(yMin / step) * step;\n const lastVisibleValue = Math.floor(yMax / step) * step;\n\n context.font = AXES_FONT;\n context.textAlign = isSecondary ? 'right' : 'left';\n context.textBaseline = 'bottom';\n\n context.lineWidth = 1;\n\n context.beginPath();\n\n for (let value = firstVisibleValue; value <= lastVisibleValue; value += step) {\n const [, yPx] = toPixels(projection, 0, value);\n const textOpacity = applyXEdgeOpacity(opacity, yPx);\n\n context.fillStyle = colorKey\n ? getCssColor(colors, colorKey, textOpacity)\n : getCssColor(colors, 'y-axis-text', textOpacity);\n\n if (!isSecondary) {\n context.fillText(humanize(value), GUTTER, yPx - GUTTER / 2);\n } else {\n context.fillText(humanize(value), plotSize.width - GUTTER, yPx - GUTTER / 2);\n }\n\n if (isSecondary) {\n context.strokeStyle = getCssColor(colors, colorKey, opacity);\n\n context.moveTo(plotSize.width - GUTTER, yPx);\n context.lineTo(plotSize.width - GUTTER * 2, yPx);\n } else {\n context.moveTo(GUTTER, yPx);\n context.strokeStyle = getCssColor(colors, 'grid-lines', opacity);\n context.lineTo(plotSize.width - GUTTER, yPx);\n }\n }\n\n context.stroke();\n }\n\n function _drawYAxisPercents(projection) {\n const percentValues = [0, 0.25, 0.50, 0.75, 1];\n const [, height] = projection.getSize();\n\n context.font = AXES_FONT;\n context.textAlign = 'left';\n context.textBaseline = 'bottom';\n context.lineWidth = 1;\n\n context.beginPath();\n\n percentValues.forEach((value) => {\n const yPx = height - height * value + PLOT_TOP_PADDING;\n\n context.fillStyle = getCssColor(colors, 'y-axis-text', 1);\n context.fillText(`${value * 100}%`, GUTTER, yPx - GUTTER / 4);\n\n context.moveTo(GUTTER, yPx);\n context.strokeStyle = getCssColor(colors, 'grid-lines', 1);\n context.lineTo(plotSize.width - GUTTER, yPx);\n });\n\n context.stroke();\n }\n\n return { drawXAxis, drawYAxis };\n}\n","import { setupCanvas, clearCanvas } from './canvas';\nimport { preparePoints } from './preparePoints';\nimport { createProjection } from './Projection';\nimport { drawDatasets } from './drawDatasets';\nimport { captureEvents } from './captureEvents';\nimport {\n DEFAULT_RANGE,\n MINIMAP_HEIGHT,\n MINIMAP_EAR_WIDTH,\n MINIMAP_MARGIN,\n MINIMAP_LINE_WIDTH,\n MINIMAP_MAX_ANIMATED_DATASETS,\n SIMPLIFIER_MINIMAP_FACTOR,\n} from './constants';\nimport { proxyMerge, throttleWithRaf } from './utils';\nimport { createElement } from './minifiers';\nimport { getSimplificationDelta } from './formulas';\n\nexport function createMinimap(container, data, colors, rangeCallback) {\n let _element;\n let _canvas;\n let _context;\n let _canvasSize;\n let _ruler;\n let _slider;\n\n let _capturedOffset;\n let _range = {};\n let _state;\n\n const _updateRulerOnRaf = throttleWithRaf(_updateRuler);\n\n _setupLayout();\n _updateRange(data.minimapRange || DEFAULT_RANGE);\n\n function update(newState) {\n const { begin, end } = newState;\n if (!_capturedOffset) {\n _updateRange({ begin, end }, true);\n }\n\n if (data.datasets.length >= MINIMAP_MAX_ANIMATED_DATASETS) {\n newState = newState.static;\n }\n\n if (!_isStateChanged(newState)) {\n return;\n }\n\n _state = proxyMerge(newState, { focusOn: null });\n clearCanvas(_canvas, _context);\n\n _drawDatasets(_state);\n }\n\n function toggle(shouldShow) {\n _element.classList.toggle('lovely-chart--state-hidden', !shouldShow);\n\n requestAnimationFrame(() => {\n _element.classList.toggle('lovely-chart--state-transparent', !shouldShow);\n });\n }\n\n function _setupLayout() {\n _element = createElement();\n\n _element.className = 'lovely-chart--minimap';\n _element.style.height = `${MINIMAP_HEIGHT}px`;\n\n _setupCanvas();\n _setupRuler();\n\n container.appendChild(_element);\n\n _canvasSize = {\n width: _canvas.offsetWidth,\n height: _canvas.offsetHeight,\n };\n }\n\n function _getSize() {\n return {\n width: container.offsetWidth - MINIMAP_MARGIN * 2,\n height: MINIMAP_HEIGHT,\n };\n }\n\n function _setupCanvas() {\n const { canvas, context } = setupCanvas(_element, _getSize());\n\n _canvas = canvas;\n _context = context;\n }\n\n function _setupRuler() {\n _ruler = createElement();\n _ruler.className = 'lovely-chart--minimap-ruler';\n _ruler.innerHTML =\n '<div class=\"lovely-chart--minimap-mask\"></div>' +\n '<div class=\"lovely-chart--minimap-slider\">' +\n '<div class=\"lovely-chart--minimap-slider-handle\"><span class=\"lovely-chart--minimap-slider-handle-pin\"></span></div>' +\n '<div class=\"lovely-chart--minimap-slider-inner\"></div>' +\n '<div class=\"lovely-chart--minimap-slider-handle\"><span class=\"lovely-chart--minimap-slider-handle-pin\"></span></div>' +\n '</div>' +\n '<div class=\"lovely-chart--minimap-mask\"></div>';\n\n _slider = _ruler.children[1];\n\n captureEvents(\n _slider.children[1],\n {\n onCapture: _onDragCapture,\n onDrag: _onSliderDrag,\n onRelease: _onDragRelease,\n draggingCursor: 'grabbing',\n },\n );\n\n captureEvents(\n _slider.children[0],\n {\n onCapture: _onDragCapture,\n onDrag: _onLeftEarDrag,\n onRelease: _onDragRelease,\n draggingCursor: 'ew-resize',\n },\n );\n\n captureEvents(\n _slider.children[2],\n {\n onCapture: _onDragCapture,\n onDrag: _onRightEarDrag,\n onRelease: _onDragRelease,\n draggingCursor: 'ew-resize',\n },\n );\n\n _element.appendChild(_ruler);\n }\n\n function _isStateChanged(newState) {\n if (!_state) {\n return true;\n }\n\n const { datasets } = data;\n\n if (datasets.some(({ key }) => _state[`opacity#${key}`] !== newState[`opacity#${key}`])) {\n return true;\n }\n\n if (_state.yMaxMinimap !== newState.yMaxMinimap) {\n return true;\n }\n\n return false;\n }\n\n function _drawDatasets(state = {}) {\n const { datasets } = data;\n const range = {\n from: 0,\n to: state.totalXWidth,\n };\n const boundsAndParams = {\n begin: 0,\n end: 1,\n totalXWidth: state.totalXWidth,\n yMin: state.yMinMinimap,\n yMax: state.yMaxMinimap,\n availableWidth: _canvasSize.width,\n availableHeight: _canvasSize.height,\n yPadding: 1,\n };\n const visibilities = datasets.map(({ key }) => _state[`opacity#${key}`]);\n const points = preparePoints(data, datasets, range, visibilities, boundsAndParams, true);\n const projection = createProjection(boundsAndParams);\n\n let secondaryPoints = null;\n let secondaryProjection = null;\n if (data.hasSecondYAxis) {\n const secondaryDataset = datasets.find((d) => d.hasOwnYAxis);\n const bounds = { yMin: state.yMinMinimapSecond, yMax: state.yMaxMinimapSecond };\n secondaryPoints = preparePoints(data, [secondaryDataset], range, visibilities, bounds)[0];\n secondaryProjection = projection.copy(bounds);\n }\n\n const totalPoints = points.reduce((a, p) => a + p.length, 0);\n const simplification = getSimplificationDelta(totalPoints) * SIMPLIFIER_MINIMAP_FACTOR;\n\n drawDatasets(\n _context, state, data,\n range, points, projection, secondaryPoints, secondaryProjection,\n MINIMAP_LINE_WIDTH, visibilities, colors, true, simplification,\n );\n }\n\n function _onDragCapture(e) {\n e.preventDefault();\n _capturedOffset = e.target.offsetLeft;\n }\n\n function _onDragRelease() {\n _capturedOffset = null;\n }\n\n function _onSliderDrag(moveEvent, captureEvent, { dragOffsetX }) {\n const minX1 = 0;\n const maxX1 = _canvasSize.width - _slider.offsetWidth;\n\n const newX1 = Math.max(minX1, Math.min(_capturedOffset + dragOffsetX - MINIMAP_EAR_WIDTH, maxX1));\n const newX2 = newX1 + _slider.offsetWidth;\n const begin = newX1 / _canvasSize.width;\n const end = newX2 / _canvasSize.width;\n\n _updateRange({ begin, end });\n }\n\n function _onLeftEarDrag(moveEvent, captureEvent, { dragOffsetX }) {\n const minX1 = 0;\n const maxX1 = _slider.offsetLeft + _slider.offsetWidth - MINIMAP_EAR_WIDTH * 2;\n\n const newX1 = Math.min(maxX1, Math.max(minX1, _capturedOffset + dragOffsetX));\n const begin = newX1 / _canvasSize.width;\n\n _updateRange({ begin });\n }\n\n function _onRightEarDrag(moveEvent, captureEvent, { dragOffsetX }) {\n const minX2 = _slider.offsetLeft + MINIMAP_EAR_WIDTH * 2;\n const maxX2 = _canvasSize.width;\n\n const newX2 = Math.max(minX2, Math.min(_capturedOffset + MINIMAP_EAR_WIDTH + dragOffsetX, maxX2));\n const end = newX2 / _canvasSize.width;\n\n _updateRange({ end });\n }\n\n function _updateRange(range, isExternal) {\n let nextRange = Object.assign({}, _range, range);\n\n if (_state && _state.minimapDelta && !isExternal) {\n nextRange = _adjustDiscreteRange(nextRange);\n }\n\n if (nextRange.begin === _range.begin && nextRange.end === _range.end) {\n return;\n }\n\n _range = nextRange;\n _updateRulerOnRaf();\n\n if (!isExternal) {\n rangeCallback(_range);\n }\n }\n\n function _adjustDiscreteRange(nextRange) {\n // TODO sometimes beginChange and endChange are different for slider drag because of pixels division\n const begin = Math.round(nextRange.begin / _state.minimapDelta) * _state.minimapDelta;\n const end = Math.round(nextRange.end / _state.minimapDelta) * _state.minimapDelta;\n\n return { begin, end };\n }\n\n function _updateRuler() {\n const { begin, end } = _range;\n\n _ruler.children[0].style.width = `${begin * 100}%`;\n _ruler.children[1].style.width = `${(end - begin) * 100}%`;\n _ruler.children[2].style.width = `${(1 - end) * 100}%`;\n }\n\n return { update, toggle };\n}\n","import { createElement } from './minifiers';\nimport { captureEvents } from './captureEvents';\n\nexport function createTools(container, data, filterCallback) {\n let _element;\n\n _setupLayout();\n _updateFilter();\n\n function redraw() {\n if (_element) {\n const oldElement = _element;\n oldElement.classList.add('lovely-chart--state-hidden');\n setTimeout(() => {\n oldElement.parentNode.removeChild(oldElement);\n }, 500);\n }\n\n _setupLayout();\n _element.classList.add('lovely-chart--state-transparent');\n requestAnimationFrame(() => {\n _element.classList.remove('lovely-chart--state-transparent');\n });\n }\n\n function _setupLayout() {\n _element = createElement();\n _element.className = 'lovely-chart--tools';\n\n if (data.datasets.length < 2) {\n _element.className += ' lovely-chart--state-hidden';\n }\n\n data.datasets.forEach(({ key, name }) => {\n const control = createElement('a');\n control.href = '#';\n control.dataset.key = key;\n control.className = `lovely-chart--button lovely-chart--color-${data.colors[key].slice(1)} lovely-chart--state-checked`;\n control.innerHTML = `<span class=\"lovely-chart--button-check\"></span><span class=\"lovely-chart--button-label\">${name}</span>`;\n\n control.addEventListener('click', (e) => {\n e.preventDefault();\n\n if (!control.dataset.clickPrevented) {\n _updateFilter(control);\n }\n\n delete control.dataset.clickPrevented;\n });\n\n captureEvents(control, {\n onLongPress: () => {\n control.dataset.clickPrevented = 'true';\n\n _updateFilter(control, true);\n },\n });\n\n _element.appendChild(control);\n });\n\n container.appendChild(_element);\n }\n\n function _updateFilter(button, isLongPress = false) {\n const buttons = Array.from(_element.getElementsByTagName('a'));\n const isSingleChecked = _element.querySelectorAll('.lovely-chart--state-checked').length === 1;\n\n if (button) {\n if (button.classList.contains('lovely-chart--state-checked') && isSingleChecked) {\n if (isLongPress) {\n buttons.forEach((b) => b.classList.add('lovely-chart--state-checked'));\n button.classList.remove('lovely-chart--state-checked');\n } else {\n button.classList.remove('lovely-chart--state-shake');\n requestAnimationFrame(() => {\n button.classList.add('lovely-chart--state-shake');\n });\n }\n } else if (isLongPress) {\n buttons.forEach((b) => b.classList.remove('lovely-chart--state-checked'));\n button.classList.add('lovely-chart--state-checked');\n } else {\n button.classList.toggle('lovely-chart--state-checked');\n }\n }\n\n const filter = {};\n\n buttons.forEach((input) => {\n filter[input.dataset.key] = input.classList.contains('lovely-chart--state-checked');\n });\n\n filterCallback(filter);\n }\n\n return {\n redraw,\n };\n}\n","import { analyzeData } from './data';\nimport { getFullLabelDate } from './format';\nimport { ZOOM_RANGE_DELTA, ZOOM_RANGE_MIDDLE, ZOOM_TIMEOUT } from './constants';\nimport { createColors } from './skin';\n\nexport function createZoomer(data, overviewData, colors, stateManager, container, header, minimap, tooltip, tools) {\n let _isZoomed = false;\n let _stateBeforeZoomIn;\n let _stateBeforeZoomOut;\n\n function zoomIn(state, labelIndex) {\n if (_isZoomed) {\n return;\n }\n\n const label = data.xLabels[labelIndex];\n\n _stateBeforeZoomIn = state;\n header.toggleIsZooming(true);\n tooltip.toggleLoading(true);\n tooltip.toggleIsZoomed(true);\n if (data.shouldZoomToPie) {\n container.classList.add('lovely-chart--state-zoomed-in');\n container.classList.add('lovely-chart--state-animating');\n }\n\n const { value } = label;\n const dataPromise = data.shouldZoomToPie ? Promise.resolve(_generatePieData(labelIndex)) : data.onZoom(value);\n dataPromise.then((newData) => _replaceData(newData, labelIndex, label));\n }\n\n function zoomOut(state) {\n if (!_isZoomed) {\n return;\n }\n\n _stateBeforeZoomOut = state;\n header.toggleIsZooming(true);\n tooltip.toggleLoading(true);\n tooltip.toggleIsZoomed(false);\n if (data.shouldZoomToPie) {\n container.classList.remove('lovely-chart--state-zoomed-in');\n container.classList.add('lovely-chart--state-animating');\n }\n\n const labelIndex = Math.round((state.labelFromIndex + state.labelToIndex) / 2);\n _replaceData(overviewData, labelIndex);\n }\n\n function isZoomed() {\n return _isZoomed;\n }\n\n function _replaceData(newRawData, labelIndex, zoomInLabel) {\n if (!newRawData) {\n tooltip.toggleLoading(false);\n tooltip.toggleIsZoomed(false);\n header.toggleIsZooming(false);\n\n return;\n }\n\n tooltip.toggleLoading(false);\n\n const labelWidth = 1 / data.xLabels.length;\n const labelMiddle = labelIndex / (data.xLabels.length - 1);\n const filter = {};\n data.datasets.forEach(({ key }) => filter[key] = false);\n const newData = analyzeData(newRawData, _isZoomed || data.shouldZoomToPie ? 'day' : 'hour');\n const shouldZoomToLines = Object.keys(data.datasets).length !== Object.keys(newData.datasets).length;\n\n stateManager.update({\n range: {\n begin: labelMiddle - labelWidth / 2,\n end: labelMiddle + labelWidth / 2,\n },\n filter,\n });\n\n setTimeout(() => {\n Object.assign(data, newData);\n\n if (shouldZoomToLines && newRawData.colors) {\n Object.assign(colors, createColors(newRawData.colors));\n }\n\n if (shouldZoomToLines) {\n minimap.toggle(_isZoomed);\n tools.redraw();\n container.style.width = `${container.scrollWidth}px`;\n container.style.height = `${container.scrollHeight}px`;\n }\n\n stateManager.update({\n range: {\n begin: ZOOM_RANGE_MIDDLE - ZOOM_RANGE_DELTA,\n end: ZOOM_RANGE_MIDDLE + ZOOM_RANGE_DELTA,\n },\n focusOn: null,\n }, true);\n\n const daysCount = _isZoomed || data.shouldZoomToPie ? data.xLabels.length : data.xLabels.length / 24;\n const halfDayWidth = (1 / daysCount) / 2;\n\n let range;\n let filter;\n\n if (_isZoomed) {\n range = {\n begin: _stateBeforeZoomIn.begin,\n end: _stateBeforeZoomIn.end,\n };\n filter = shouldZoomToLines ? _stateBeforeZoomIn.filter : _stateBeforeZoomOut.filter;\n } else {\n if (shouldZoomToLines) {\n range = {\n begin: 0,\n end: 1,\n };\n filter = {};\n data.datasets.forEach(({ key }) => filter[key] = true);\n } else {\n range = data.shouldZoomToPie ? {\n begin: ZOOM_RANGE_MIDDLE - halfDayWidth,\n end: ZOOM_RANGE_MIDDLE + halfDayWidth,\n } : newData.minimapRange;\n filter = _stateBeforeZoomIn.filter;\n }\n }\n\n stateManager.update({\n range,\n filter,\n minimapDelta: _isZoomed ? null : range.end - range.begin,\n });\n\n if (zoomInLabel) {\n header.zoom(getFullLabelDate(zoomInLabel));\n }\n\n _isZoomed = !_isZoomed;\n header.toggleIsZooming(false);\n }, stateManager.hasAnimations() ? ZOOM_TIMEOUT : 0);\n\n setTimeout(() => {\n if (data.shouldZoomToPie) {\n container.classList.remove('lovely-chart--state-animating');\n }\n }, stateManager.hasAnimations() ? 1000 : 0);\n }\n\n function _generatePieData(labelIndex) {\n return Object.assign(\n {},\n overviewData,\n {\n type: 'pie',\n labels: overviewData.labels.slice(labelIndex - 3, labelIndex + 4),\n datasets: overviewData.datasets.map((dataset) => {\n return {\n ...dataset,\n values: dataset.values.slice(labelIndex - 3, labelIndex + 4),\n };\n }),\n },\n );\n }\n\n return { zoomIn, zoomOut, isZoomed };\n}\n"],"names":["DPR","window","devicePixelRatio","DEFAULT_RANGE","begin","end","TRANSITION_DEFAULT_DURATION","GUTTER","PLOT_BARS_WIDTH_SHIFT","AXES_FONT","ZOOM_TIMEOUT","MONTHS","WEEK_DAYS","WEEK_DAYS_SHORT","ANIMATE_PROPS","getMaxMin","array","length","max","min","i","value","mergeArrays","arrays","concat","apply","sumArrays","sums","n","l","j","proxyMerge","obj1","obj2","Proxy","get","obj","prop","undefined","throttle","fn","ms","isPending","args","shouldRunFirst","interval","_args","setInterval","clearInterval","throttleWithRaf","waiting","requestAnimationFrame","SCALE_LEVELS","yScaleLevelToStep","scaleLevel","applyYEdgeOpacity","opacity","xPx","plotWidth","edgeOffset","Math","applyXEdgeOpacity","yPx","getPieRadius","projection","getSize","getSimplificationDelta","pointsLength","calculateState","data","viewportSize","range","filter","focusOn","minimapDelta","prevState","totalXWidth","xLabels","labelFromIndex","ceil","labelToIndex","floor","xAxisScale","step","log2","calculateXAxisScale","width","yRanges","isStacked","filteredValues","datasets","d","key","map","values","yMaxMinimap","yMaxViewport","slice","yMinViewport","yMinMinimap","calculateYRangesStacked","secondaryYAxisDataset","hasSecondYAxis","filteredDatasets","calculateYRangesForGroup","yMinViewportSecond","yMaxViewportSecond","yMinMinimapSecond","yMaxMinimapSecond","Object","assign","calculateYRanges","yAxisScale","calculateYAxisScale","height","yAxisScaleSecond","yStep","yStepSecond","datasetsOpacity","forEach","yMinMinimapReal","yMax","yMin","viewportMaxMin","yMinViewportReal","plotHeight","availableHeight","viewportLabelsCount","maxRows","neededStep","findIndex","createElement","tagName","document","addEventListener","element","event","cb","removeEventListener","toggleText","newText","className","inverse","container","parentNode","classList","add","newElement","innerHTML","selector","split","join","oldElements","querySelectorAll","e","remove","insertBefore","nextSibling","toggleElementIn","toggleElementOut","humanize","decimals","keepThreeDigits","toFixed","replace","formatInteger","String","getFullLabelDate","label","isShort","getLabelDate","displayWeekDay","displayYear","displayHours","date","Date","weekDaysArray","string","getUTCDate","getUTCMonth","getUTCDay","getUTCFullYear","getUTCHours","getUTCMinutes","detectSkin","documentElement","contains","skin","COLORS","styleElement","type","appendChild","createTextNode","head","styleSheet","sheet","createColors","datasetColors","colors","baseClass","keys","hexToChannels","addCssRule","getCssColor","r","g","b","a","buildCssColor","hexWithAlpha","hex","alpha","parseInt","parseFloat","rule","insertRule","cssRules","createProjection","params","availableWidth","xPadding","yPadding","effectiveWidth","xFactor","xOffsetPx","effectiveHeight","yFactor","yOffsetPx","findClosestLabelIndex","round","copy","overrides","cons","getCenter","getParams","getState","toPixels","labelIndex","setupCanvas","canvas","style","context","getContext","scale","clearCanvas","clearRect","preparePoints","visibilities","bounds","pieToArea","from","to","isPie","datasetValues","reduce","sum","prepareSumsByX","points","visibleValue","stackOffset","stackValue","isPercentage","sumsByY","datasetPoints","getSumsByY","point","percent","preparePercentage","accum","prepareStacked","simplify","E1","pow","MAXLIMIT","pointToSegmentDistanceSquare","p","v1","v2","dv","dvlen_1","t","vx","vy","indexes","fixedPoints","removed","worker","maximumDelta","len","distances","queue","subdivisionTree","tick","request","pop","result","start","record","currentLimit","usedDistance","usedIndex","vector","fixId","abs","vectorLength_1","segmentDistance","index","distance","push","left","parent","parentProperty","right","delta","precalculate","resultIndexes","delta2","markers","drawDatasets","state","secondaryPoints","secondaryProjection","lineWidth","pieToBar","simplification","hasOwnYAxis","options","color","datasetType","datasetProjection","yHeight","bottomLine","topLine","center","radius","pointerVector","x0","x1","drawDatasetLine","drawDatasetBars","drawDatasetSteps","drawDatasetArea","drawDatasetPie","drawDataset","isBars","isSteps","xCenter","yCenter","x","fillStyle","fillRect","drawBarsMask","beginPath","pixels","simplifierFn","y","lineTo","save","strokeStyle","globalAlpha","lineJoin","lineCap","stroke","restore","yFrom","yTo","rectX","rectY","rectW","rectH","fill","percentFactor","beginAngle","PI","endAngle","shift","angle","shiftAngle","directionX","cos","directionY","sin","shiftX","shiftY","moveTo","arc","font","getPieTextSize","textAlign","textBaseline","textShift","log","getPieTextShift","fillText","captureEvents","captureEvent","longPressTimeout","onCapture","onMove","onRelease","pageX","touches","draggingCursor","onLongPress","setTimeout","clearTimeout","onDrag","dragOffsetX","createTooltip","plotSize","onZoom","onFocus","_state","_points","_projection","_secondaryPoints","_secondaryProjection","_element","_canvas","_context","_balloon","_offsetX","_offsetY","_clickedOnLabel","_isZoomed","_isZooming","_selectLabelOnRaf","_selectLabel","_throttledUpdateContent","_updateContent","_onMouseMove","target","pageOffset","getBoundingClientRect","clientX","clientY","top","_onDocumentMove","_clear","_onClick","isZoomable","oldLabelIndex","newLabelIndex","_getLabelIndex","_onBalloonClick","isExternal","_hideBalloon","getPointerVector","shouldShowBalloon","getValue","statistics","name","originalIndex","transform","meanLabel","leftOffset","offsetWidth","_getBalloonLeftOffset","tooltipFormatter","toString","match","text","_getTitle","_updateBalloon","isLines","isAreas","pointIndex","strokeColor","fillColor","_drawCircle","_drawCircles","_drawTail","_renderPercentageValue","dataSet","totalValue","Array","percentageValue","percentageElement","querySelector","newPercentageTitle","prepend","title","titleContainer","children","display","currentTitle","_updateTitle","dataSetContainer","setAttribute","finalStatistics","offset","_isPieSectorSelected","statItem","currentDataSet","_updateDataSet","newDataSet","totalText","_insertNewDataSet","newTotalText","_renderTotal","_updateDataSets","atan2","sqrt","_setupCanvas","update","toggleLoading","isLoading","toggle","toggleIsZoomed","isZoomed","analyzeData","labelFormatter","minimapRange","hideCaption","zoomOutLabel","labels","cloneArray","prepareDatasets","totalYMin","Infinity","totalYMax","statsFormatDayHour","getDate","getMonth","statsFormatDay","statsFormatMin","statsFormatText","analyzed","shouldZoomToPie","create","originalData","_stateManager","_plot","_plotSize","_header","_axes","_minimap","_tooltip","_tools","_zoomer","_windowWidth","innerWidth","_data","_colors","_redrawDebounced","shouldRunLast","waitingTimeout","debounce","_setupComponents","_titleElement","_zoomOutElement","_captionElement","zoomOutCallback","setCaptionThrottled","setCaption","caption","zoom","_onZoomOut","toggleIsZooming","isZooming","_setupLayout","createHeader","clientWidth","offsetHeight","_setupPlotCanvas","callback","_range","_filter","_buildDefaultFilter","_transitionConfig","transitionConfig","datasetVisibilities","transition","duration","_buildTransitionConfig","_transitions","onTick","_nextFrame","_testStartedAt","_fps","_testingFps","_slowDetectedAt","_startedAsSlow","isRunning","cancelAnimationFrame","Boolean","isFast","forceCheck","_tick","isSlow","now","startedAt","progress","current","includes","createTransitionManager","_runCallback","_runCallbackOnRaf","static","noTransition","currentTarget","hasAnimations","createStateManager","_onStateUpdate","_drawYAxisScaled","colorKey","isSecondary","firstVisibleValue","lastVisibleValue","textOpacity","drawXAxis","X_AXIS_HEIGHT","topOffset","xScaleLevelToStep","opacityFactor","shiftedI","drawYAxis","yAxisScaleFrom","yAxisScaleTo","yAxisScaleProgress","yMinViewportFrom","yMinViewportTo","yMaxViewportFrom","yMaxViewportTo","yMinViewportSecondFrom","yMinViewportSecondTo","yMaxViewportSecondFrom","yMaxViewportSecondTo","isYChanging","_drawYAxisPercents","yAxisScaleSecondFrom","yAxisScaleSecondTo","yAxisScaleSecondProgress","secondaryColorKey","createAxes","rangeCallback","_canvasSize","_ruler","_slider","_capturedOffset","_updateRulerOnRaf","_onDragCapture","preventDefault","offsetLeft","_onDragRelease","_updateRange","nextRange","_adjustDiscreteRange","MINIMAP_MARGIN","moveEvent","maxX1","newX1","newX2","MINIMAP_EAR_WIDTH","minX2","maxX2","newState","some","_isStateChanged","boundsAndParams","secondaryDataset","find","_drawDatasets","shouldShow","createMinimap","_onRangeChange","_onZoomIn","_onFocus","filterCallback","control","href","dataset","clickPrevented","_updateFilter","button","isLongPress","buttons","getElementsByTagName","isSingleChecked","input","redraw","oldElement","removeChild","createTools","_onFilterChange","overviewData","stateManager","header","minimap","tooltip","tools","_stateBeforeZoomIn","_stateBeforeZoomOut","_replaceData","newRawData","zoomInLabel","labelWidth","labelMiddle","newData","shouldZoomToLines","scrollWidth","scrollHeight","ZOOM_RANGE_MIDDLE","halfDayWidth","zoomIn","dataPromise","Promise","resolve","_generatePieData","then","zoomOut","createZoomer","startIndex","endIndex","labelFrom","labelTo","_getCaption"],"sourceRoot":""} |