telegram-tt/dist/6.2a86679c910dccf735ed.js.map
Alexander Zinchuk bedd3d2119 [Build]
2021-04-29 13:10:42 +03:00

1 line
141 KiB
Plaintext

{"version":3,"sources":["webpack:///./src/lib/lovely-chart/utils.js","webpack:///./src/lib/lovely-chart/TransitionManager.js","webpack:///./src/lib/lovely-chart/formulas.js","webpack:///./src/lib/lovely-chart/StateManager.js","webpack:///./src/lib/lovely-chart/minifiers.js","webpack:///./src/lib/lovely-chart/toggleText.js","webpack:///./src/lib/lovely-chart/format.js","webpack:///./src/lib/lovely-chart/skin.js","webpack:///./src/lib/lovely-chart/Projection.js","webpack:///./src/lib/lovely-chart/Axes.js","webpack:///./src/lib/lovely-chart/canvas.js","webpack:///./src/lib/lovely-chart/preparePoints.js","webpack:///./src/lib/lovely-chart/simplify.js","webpack:///./src/lib/lovely-chart/drawDatasets.js","webpack:///./src/lib/lovely-chart/captureEvents.js","webpack:///./src/lib/lovely-chart/Minimap.js","webpack:///./src/lib/lovely-chart/Tooltip.js","webpack:///./src/lib/lovely-chart/data.js","webpack:///./src/lib/lovely-chart/Zoomer.js","webpack:///./src/lib/lovely-chart/hideOnScroll.js","webpack:///./src/lib/lovely-chart/LovelyChart.js","webpack:///./src/lib/lovely-chart/Header.js","webpack:///./src/lib/lovely-chart/Tools.js"],"names":["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","shouldRunFirst","isPending","args","interval","_args","window","setInterval","clearInterval","throttleWithRaf","waiting","requestAnimationFrame","debounce","shouldRunLast","waitingTimeout","clearTimeout","setTimeout","createTransitionManager","onTick","_transitions","_nextFrame","_testStartedAt","_fps","_testingFps","_slowDetectedAt","_startedAsSlow","remove","isRunning","cancelAnimationFrame","Boolean","Object","keys","isFast","forceCheck","SPEED_TEST_FAST_FPS","_tick","isSlow","Date","now","SPEED_TEST_INTERVAL","state","forEach","startedAt","from","to","duration","TRANSITION_DEFAULT_DURATION","options","progress","Math","current","t","pow","includes","ceil","floor","add","_resetSpeedTest","getState","SCALE_LEVELS","yScaleLevelToStep","scaleLevel","applyYEdgeOpacity","opacity","xPx","plotWidth","edgeOffset","GUTTER","applyXEdgeOpacity","yPx","getPieRadius","projection","getSize","PLOT_PIE_RADIUS_FACTOR","isDataRange","labelFrom","labelTo","abs","MILISECONDS_IN_DAY","getSimplificationDelta","pointsLength","SIMPLIFIER_MIN_POINTS","createStateManager","data","viewportSize","callback","_range","begin","end","_filter","filter","datasets","key","_buildDefaultFilter","_transitionConfig","transitionConfig","datasetVisibilities","map","ANIMATE_PROPS","transition","split","push","_buildTransitionConfig","_runCallback","_runCallbackOnRaf","_state","static","update","range","focusOn","minimapDelta","noTransition","assign","prevState","totalXWidth","xLabels","labelFromIndex","labelToIndex","xAxisScale","viewportLabelsCount","maxColumns","AXES_MAX_COLUMN_WIDTH","step","log2","calculateXAxisScale","width","yRanges","isStacked","filteredValues","d","values","yMaxMinimap","yMaxViewport","slice","yMinViewport","yMinMinimap","calculateYRangesStacked","secondaryYAxisDataset","hasSecondYAxis","filteredDatasets","calculateYRangesForGroup","yMinViewportSecond","yMaxViewportSecond","yMinMinimapSecond","yMaxMinimapSecond","calculateYRanges","yAxisScale","calculateYAxisScale","height","yAxisScaleSecond","yStep","yStepSecond","datasetsOpacity","calculateState","currentTarget","hasAnimations","yMinMinimapReal","yMax","yMin","Y_AXIS_ZERO_BASED_THRESHOLD","viewportValues","viewportMaxMin","yMinViewportReal","plotHeight","availableHeight","X_AXIS_HEIGHT","maxRows","AXES_MAX_ROW_HEIGHT","neededStep","findIndex","createElement","tagName","document","addEventListener","element","event","cb","removeEventListener","toggleText","newText","className","inverse","container","parentNode","classList","newElement","innerHTML","selector","join","querySelectorAll","e","insertBefore","nextSibling","toggleElementIn","toggleElementOut","humanize","decimals","keepThreeDigits","toFixed","replace","formatInteger","String","getFullLabelDate","label","isShort","getLabelDate","displayWeekDay","displayYear","displayHours","date","weekDaysArray","WEEK_DAYS_SHORT","WEEK_DAYS","string","getUTCDate","MONTHS","getUTCMonth","getUTCDay","getUTCFullYear","getUTCHours","getUTCMinutes","detectSkin","documentElement","contains","skin","COLORS","styleElement","type","appendChild","createTextNode","head","styleSheet","sheet","createColors","datasetColors","colors","baseClass","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","toPixels","labelIndex","createAxes","context","plotSize","_drawYAxisScaled","colorKey","isSecondary","firstVisibleValue","lastVisibleValue","font","AXES_FONT","textAlign","textBaseline","lineWidth","beginPath","textOpacity","fillStyle","fillText","strokeStyle","moveTo","lineTo","stroke","drawXAxis","clearRect","topOffset","xScaleLevelToStep","opacityFactor","shiftedI","X_AXIS_SHIFT_START","text","drawYAxis","secondaryProjection","yAxisScaleFrom","yAxisScaleTo","yAxisScaleProgress","yMinViewportFrom","yMinViewportTo","yMaxViewportFrom","yMaxViewportTo","yMinViewportSecondFrom","yMinViewportSecondTo","yMaxViewportSecondFrom","yMaxViewportSecondTo","isYChanging","isPercentage","PLOT_TOP_PADDING","_drawYAxisPercents","yAxisScaleSecondFrom","yAxisScaleSecondTo","yAxisScaleSecondProgress","secondaryColorKey","setupCanvas","canvas","DPR","style","getContext","scale","clearCanvas","preparePoints","visibilities","bounds","pieToArea","isPie","datasetValues","reduce","sum","prepareSumsByX","points","visibleValue","stackOffset","stackValue","sumsByY","datasetPoints","getSumsByY","point","percent","preparePercentage","accum","prepareStacked","simplify","E1","pointToSegmentDistanceSquare","p","v1","v2","dv","dvlen_1","vx","vy","indexes","fixedPoints","removed","worker","maximumDelta","len","distances","queue","subdivisionTree","tick","request","pop","result","start","record","currentLimit","usedDistance","usedIndex","vector","fixId","vectorLength_1","segmentDistance","index","distance","left","parent","parentProperty","right","delta","precalculate","resultIndexes","delta2","markers","drawDatasets","secondaryPoints","pieToBar","simplification","hasOwnYAxis","color","datasetType","datasetProjection","yHeight","bottomLine","topLine","center","radius","pointerVector","x0","x1","pixels","simplifierFn","x","y","save","globalAlpha","lineJoin","lineCap","restore","drawDatasetLine","yFrom","yTo","rectX","rectY","rectW","PLOT_BARS_WIDTH_SHIFT","rectH","fillRect","drawDatasetBars","fill","drawDatasetArea","percentFactor","beginAngle","PI","endAngle","shift","angle","PLOT_PIE_SHIFT","shiftAngle","directionX","cos","directionY","sin","shiftX","shiftY","arc","getPieTextSize","textShift","log","getPieTextShift","drawDatasetPie","drawDataset","isBars","xCenter","yCenter","drawBarsMask","captureEvents","captureEvent","longPressTimeout","onCapture","onMove","onRelease","pageX","touches","draggingCursor","onLongPress","LONG_PRESS_TIMEOUT","onDrag","dragOffsetX","createMinimap","rangeCallback","_element","_canvas","_context","_canvasSize","_ruler","_slider","_capturedOffset","_updateRulerOnRaf","children","_onDragCapture","preventDefault","target","offsetLeft","_onDragRelease","_onSliderDrag","moveEvent","maxX1","offsetWidth","newX1","MINIMAP_EAR_WIDTH","newX2","_updateRange","_onLeftEarDrag","_onRightEarDrag","minX2","maxX2","isExternal","nextRange","_adjustDiscreteRange","MINIMAP_HEIGHT","MINIMAP_MARGIN","_setupCanvas","offsetHeight","DEFAULT_RANGE","newState","MINIMAP_MAX_ANIMATED_DATASETS","some","_isStateChanged","boundsAndParams","secondaryDataset","find","SIMPLIFIER_MINIMAP_FACTOR","MINIMAP_LINE_WIDTH","_drawDatasets","toggle","shouldShow","createTooltip","onZoom","onFocus","_points","_projection","_secondaryPoints","_secondaryProjection","_balloon","_offsetX","_offsetY","_clickedOnLabel","_isZoomed","_isZooming","_selectLabelOnRaf","_selectLabel","_throttledUpdateContent","_updateContent","_onMouseMove","pageOffset","getBoundingClientRect","clientX","clientY","top","_onDocumentMove","_clear","_onClick","oldLabelIndex","newLabelIndex","_getLabelIndex","_onBalloonClick","_hideBalloon","getPointerVector","shouldShowBalloon","getValue","statistics","name","originalIndex","transform","meanLabel","BALLOON_OFFSET","_getBalloonLeftOffset","_getBalloonTopOffset","labelType","_getTitle","_updateBalloon","isLines","isAreas","pointIndex","strokeColor","fillColor","_drawCircle","_drawCircles","_drawTail","_renderPercentageValue","dataSet","totalValue","Array","percentageValue","percentageElement","querySelector","newPercentageTitle","prepend","_updateDataSets","dataSetContainer","setAttribute","offset","_isPieSectorSelected","statItem","currentDataSet","_updateDataSet","newDataSet","totalText","_insertNewDataSet","newTotalText","_renderTotal","title","titleContainer","display","currentTitle","_updateTitle","atan2","sqrt","isZoomable","_setupBalloon","_setupLayout","toggleLoading","isLoading","toggleIsZoomed","isZoomed","analyzeData","labels","cloneArray","prepareDatasets","totalYMin","Infinity","totalYMax","hours","minutes","buildTimeLabels","buildTextLabels","getDate","getMonth","buildDayLabels","analyzed","shouldZoomToPie","createZoomer","overviewData","stateManager","header","minimap","tooltip","tools","_stateBeforeZoomIn","_stateBeforeZoomOut","_replaceData","newRawData","zoomInLabel","labelWidth","labelMiddle","newData","shouldZoomToLines","redraw","scrollWidth","scrollHeight","ZOOM_RANGE_MIDDLE","ZOOM_RANGE_DELTA","halfDayWidth","zoom","toggleIsZooming","ZOOM_TIMEOUT","zoomIn","Promise","resolve","dataset","_generatePieData","then","zoomOut","chartEls","showAllDebounced","chartEl","hideScrolledDebounced","bottom","shouldHide","innerHeight","create","originalData","_stateManager","_plot","_plotSize","_header","_axes","_minimap","_tooltip","_tools","_zoomer","_windowWidth","innerWidth","_data","_colors","_redrawDebounced","_setupComponents","zoomOutCallback","_titleElement","_zoomOutElement","_captionElement","setCaptionThrottled","setCaption","caption","_onZoomOut","isZooming","createHeader","clientWidth","PLOT_HEIGHT","_setupPlotCanvas","_onStateUpdate","_onRangeChange","_onZoomIn","_onFocus","filterCallback","control","href","clickPrevented","_updateFilter","button","isLongPress","buttons","getElementsByTagName","isSingleChecked","input","oldElement","removeChild","createTools","_onFilterChange","startIndex","endIndex","_getCaption","SIMPLIFIER_PLOT_FACTOR","PLOT_LINE_WIDTH"],"mappings":"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","file":"6.2a86679c910dccf735ed.js","sourcesContent":["// 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 { 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, 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 group = filter[secondaryYAxisDataset.key] ? [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 buildDayLabels(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 buildTimeLabels(labels) {\n return labels.map((value) => {\n const date = new Date(value);\n const hours = date.getUTCHours();\n const minutes = date.getUTCMinutes();\n\n return ({\n value,\n text: `${hours < 10 ? '0' : ''}${hours}:${minutes < 10 ? '0' : ''}${minutes}`,\n });\n });\n}\n\nexport function buildTextLabels(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() + 1}`;\n }\n if (displayHours) {\n string += `, ${('0' + date.getUTCHours()).slice(-2)}:${('0' + date.getUTCMinutes()).slice(-2)}`\n }\n\n return string;\n}\n","function detectSkin() {\n return document.documentElement.classList.contains('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 { 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 { 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 } 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) {\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: 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 '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 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 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 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 { 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(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 { setupCanvas, clearCanvas } from './canvas';\nimport { BALLOON_OFFSET, X_AXIS_HEIGHT } from './constants';\nimport { getPieRadius, isDataRange } from './formulas';\nimport { formatInteger, getLabelDate, getFullLabelDate } 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 (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 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\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 return shouldPlaceRight\n ? _offsetX + BALLOON_OFFSET\n : _offsetX - (_balloon.offsetWidth + BALLOON_OFFSET);\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 if (data.labelType === 'text') {\n return data.xLabels[labelIndex].text;\n }\n\n if (_isZoomed) {\n if (isDataRange(data.xLabels[_state.labelFromIndex + 1], data.xLabels[_state.labelToIndex - 1])) {\n return getLabelDate(data.xLabels[labelIndex], { isShort: true, displayYear: false, displayHours: true });\n }\n\n return data.xLabels[labelIndex].text;\n }\n\n return getFullLabelDate(data.xLabels[labelIndex], { isShort: true });\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 = Math.round(value / totalValue * 100);\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.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 { buildDayLabels, buildTimeLabels, buildTextLabels } from './format';\n\nexport function analyzeData(data) {\n const { title, labelType, isStacked, isPercentage, hasSecondYAxis, onZoom } = 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 (labelType) {\n case 'hour':\n xLabels = buildTimeLabels(labels);\n break;\n case 'text':\n xLabels = buildTextLabels(labels);\n break;\n default:\n xLabels = buildDayLabels(labels);\n break;\n }\n\n const analyzed = {\n title,\n labelType,\n xLabels,\n datasets,\n isStacked,\n isPercentage,\n hasSecondYAxis,\n onZoom,\n isLines: data.type === 'line',\n isBars: data.type === 'bar',\n isAreas: data.type === 'area',\n isPie: data.type === 'pie',\n yMin: totalYMin,\n yMax: totalYMax,\n colors,\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 { 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: date } = label;\n const dataPromise = data.shouldZoomToPie ? Promise.resolve(_generatePieData(labelIndex)) : data.onZoom(date);\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 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 if (shouldZoomToLines) {\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 = {\n begin: ZOOM_RANGE_MIDDLE - halfDayWidth,\n end: ZOOM_RANGE_MIDDLE + halfDayWidth,\n };\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","import { debounce } from './utils';\n\nexport const hideOnScroll = (() => {\n const chartEls = [];\n const showAllDebounced = debounce(showAll, 500, true, false);\n const hideScrolledDebounced = debounce(hideScrolled, 500, false, true);\n\n function setup(chartEl) {\n chartEls.push(chartEl);\n\n if (chartEls.length === 1) {\n window.onscroll = () => {\n showAllDebounced();\n hideScrolledDebounced();\n };\n } else {\n hideScrolledDebounced();\n }\n }\n\n function showAll() {\n chartEls.forEach((chartEl) => {\n chartEl.classList.remove('lovely-chart--state-invisible');\n });\n }\n\n function hideScrolled() {\n chartEls.forEach((chartEl) => {\n const { top, bottom } = chartEl.getBoundingClientRect();\n const shouldHide = bottom < 0 || top > window.innerHeight;\n\n if (!chartEl.classList.contains('lovely-chart--state-invisible')) {\n chartEl.style.width = `${chartEl.scrollWidth}px`;\n chartEl.style.height = `${chartEl.scrollHeight}px`;\n }\n\n chartEl.classList.toggle('lovely-chart--state-invisible', shouldHide);\n });\n }\n\n return setup;\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 { hideOnScroll } from './hideOnScroll';\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, _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 _header.setCaption(_getCaption(state));\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) {\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, 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, 'Zoom Out', '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\n zoomOutCallback();\n }\n\n return {\n setCaption: setCaptionThrottled,\n zoom,\n toggleIsZooming,\n };\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"],"sourceRoot":""}