ikizmet-apexcharts
Version:
iKizmet fork of Apex Charts library
291 lines (240 loc) • 7.25 kB
JavaScript
/**
* ApexCharts Tooltip.Utils Class to support Tooltip functionality.
*
* @module Tooltip.Utils
**/
import CoreUtils from '../CoreUtils'
export default class Utils {
constructor(tooltipContext) {
this.w = tooltipContext.w
this.ttCtx = tooltipContext
this.ctx = tooltipContext.ctx
}
/**
** When hovering over series, you need to capture which series is being hovered on.
** This function will return both capturedseries index as well as inner index of that series
* @memberof Utils
* @param {object}
* - hoverArea = the rect on which user hovers
* - elGrid = dimensions of the hover rect (it can be different than hoverarea)
*/
getNearestValues({ hoverArea, elGrid, clientX, clientY, hasBars }) {
let w = this.w
const hoverWidth = w.globals.gridWidth
let xDivisor = hoverWidth / (w.globals.dataPoints - 1)
const seriesBound = elGrid.getBoundingClientRect()
if ((hasBars && w.globals.comboCharts) || hasBars) {
xDivisor = hoverWidth / w.globals.dataPoints
}
let hoverX = clientX - seriesBound.left
let hoverY = clientY - seriesBound.top
const inRect =
hoverX < 0 ||
hoverY < 0 ||
hoverX > w.globals.gridWidth ||
hoverY > w.globals.gridHeight
if (inRect) {
hoverArea.classList.remove('hovering-zoom')
hoverArea.classList.remove('hovering-pan')
} else {
if (w.globals.zoomEnabled) {
hoverArea.classList.remove('hovering-pan')
hoverArea.classList.add('hovering-zoom')
} else if (w.globals.panEnabled) {
hoverArea.classList.remove('hovering-zoom')
hoverArea.classList.add('hovering-pan')
}
}
let j = Math.round(hoverX / xDivisor)
if (hasBars) {
j = Math.ceil(hoverX / xDivisor)
j = j - 1
}
let capturedSeries = null
let closest = null
let seriesXValArr = []
let seriesYValArr = []
for (let s = 0; s < w.globals.seriesXvalues.length; s++) {
seriesXValArr.push(
[w.globals.seriesXvalues[s][0] - 0.000001].concat(
w.globals.seriesXvalues[s]
)
)
}
seriesXValArr = seriesXValArr.map((seriesXVal) => {
return seriesXVal.filter((s) => {
return s
})
})
seriesYValArr = w.globals.seriesYvalues.map((seriesYVal) => {
return seriesYVal.filter((s) => {
return s
})
})
// if X axis type is not category and tooltip is not shared, then we need to find the cursor position and get the nearest value
if (w.globals.isXNumeric) {
closest = this.closestInMultiArray(
hoverX,
hoverY,
seriesXValArr,
seriesYValArr
)
capturedSeries = closest.index
j = closest.j
if (capturedSeries !== null) {
// initial push, it should be a little smaller than the 1st val
seriesXValArr = w.globals.seriesXvalues[capturedSeries]
closest = this.closestInArray(hoverX, seriesXValArr)
j = closest.index
}
}
if (!j || j < 1) j = 0
return {
capturedSeries,
j,
hoverX,
hoverY
}
}
closestInMultiArray(hoverX, hoverY, Xarrays, Yarrays) {
let w = this.w
let activeIndex = 0
let currIndex = null
let j = -1
if (w.globals.series.length > 1) {
activeIndex = this.getFirstActiveXArray(Xarrays)
} else {
currIndex = 0
}
let currY = Yarrays[activeIndex][0]
let currX = Xarrays[activeIndex][0]
let diffX = Math.abs(hoverX - currX)
let diffY = Math.abs(hoverY - currY)
let diff = diffY + diffX
Yarrays.map((arrY, arrIndex) => {
arrY.map((y, innerKey) => {
let newdiffY = Math.abs(hoverY - Yarrays[arrIndex][innerKey])
let newdiffX = Math.abs(hoverX - Xarrays[arrIndex][innerKey])
let newdiff = newdiffX + newdiffY
if (newdiff < diff) {
diff = newdiff
diffX = newdiffX
diffY = newdiffY
currIndex = arrIndex
j = innerKey
}
})
})
return {
index: currIndex,
j
}
}
getFirstActiveXArray(Xarrays) {
let activeIndex = 0
const coreUtils = new CoreUtils(this.ctx)
let firstActiveSeriesIndex = Xarrays.map((xarr, index) => {
if (xarr.length > 0) {
return index
} else {
return -1
}
})
for (let a = 0; a < firstActiveSeriesIndex.length; a++) {
const total = coreUtils.getSeriesTotalByIndex(a)
if (
firstActiveSeriesIndex[a] !== -1 &&
(total !== 0 && !coreUtils.seriesHaveSameValues(a))
) {
activeIndex = firstActiveSeriesIndex[a]
break
}
}
return activeIndex
}
closestInArray(val, arr) {
let curr = arr[0]
let currIndex = null
let diff = Math.abs(val - curr)
for (let i = 0; i < arr.length; i++) {
let newdiff = Math.abs(val - arr[i])
if (newdiff < diff) {
diff = newdiff
curr = arr[i]
currIndex = i
}
}
return {
index: currIndex
}
}
/**
* When there are multiple series, it is possible to have different x values for each series.
* But it may be possible in those multiple series, that there is same x value for 2 or more
* series.
* @memberof Utils
* @param {int}
* - j = is the inner index of series -> (series[i][j])
* @return {bool}
*/
isXoverlap(j) {
let w = this.w
let xSameForAllSeriesJArr = []
const seriesX = w.globals.seriesX.filter((s) => {
return typeof s[0] !== 'undefined'
})
if (seriesX.length > 0) {
for (let i = 0; i < seriesX.length - 1; i++) {
if (
typeof seriesX[i][j] !== 'undefined' &&
typeof seriesX[i + 1][j] !== 'undefined'
) {
if (seriesX[i][j] !== seriesX[i + 1][j]) {
xSameForAllSeriesJArr.push('unEqual')
}
}
}
}
if (xSameForAllSeriesJArr.length === 0) {
return true
}
return false
}
isinitialSeriesSameLen() {
let sameLen = true
const initialSeries = this.w.globals.initialSeries
for (let i = 0; i < initialSeries.length - 1; i++) {
if (initialSeries[i].data.length !== initialSeries[i + 1].data.length) {
sameLen = false
break
}
}
return sameLen
}
getBarsHeight(allbars) {
let bars = [...allbars]
const totalHeight = bars.reduce((acc, bar) => {
return acc + bar.getBBox().height
}, 0)
return totalHeight
}
toggleAllTooltipSeriesGroups(state) {
let w = this.w
const ttCtx = this.ttCtx
if (ttCtx.allTooltipSeriesGroups.length === 0) {
ttCtx.allTooltipSeriesGroups = w.globals.dom.baseEl.querySelectorAll(
'.apexcharts-tooltip-series-group'
)
}
let allTooltipSeriesGroups = ttCtx.allTooltipSeriesGroups
for (let i = 0; i < allTooltipSeriesGroups.length; i++) {
if (state === 'enable') {
allTooltipSeriesGroups[i].classList.add('active')
allTooltipSeriesGroups[i].style.display = w.config.tooltip.items.display
} else {
allTooltipSeriesGroups[i].classList.remove('active')
allTooltipSeriesGroups[i].style.display = 'none'
}
}
}
}