700 lines
19 KiB
JavaScript
700 lines
19 KiB
JavaScript
import Fill from '../../../modules/Fill'
|
|
import Graphics from '../../../modules/Graphics'
|
|
import Series from '../../../modules/Series'
|
|
import Utils from '../../../utils/Utils'
|
|
|
|
export default class Helpers {
|
|
constructor(barCtx) {
|
|
this.w = barCtx.w
|
|
this.barCtx = barCtx
|
|
}
|
|
|
|
initVariables(series) {
|
|
const w = this.w
|
|
this.barCtx.series = series
|
|
this.barCtx.totalItems = 0
|
|
this.barCtx.seriesLen = 0
|
|
this.barCtx.visibleI = -1 // visible Series
|
|
this.barCtx.visibleItems = 1 // number of visible bars after user zoomed in/out
|
|
|
|
for (let sl = 0; sl < series.length; sl++) {
|
|
if (series[sl].length > 0) {
|
|
this.barCtx.seriesLen = this.barCtx.seriesLen + 1
|
|
this.barCtx.totalItems += series[sl].length
|
|
}
|
|
if (w.globals.isXNumeric) {
|
|
// get max visible items
|
|
for (let j = 0; j < series[sl].length; j++) {
|
|
if (
|
|
w.globals.seriesX[sl][j] > w.globals.minX &&
|
|
w.globals.seriesX[sl][j] < w.globals.maxX
|
|
) {
|
|
this.barCtx.visibleItems++
|
|
}
|
|
}
|
|
} else {
|
|
this.barCtx.visibleItems = w.globals.dataPoints
|
|
}
|
|
}
|
|
|
|
if (this.barCtx.seriesLen === 0) {
|
|
// A small adjustment when combo charts are used
|
|
this.barCtx.seriesLen = 1
|
|
}
|
|
this.barCtx.zeroSerieses = []
|
|
|
|
if (!w.globals.comboCharts) {
|
|
this.checkZeroSeries({ series })
|
|
}
|
|
}
|
|
|
|
initialPositions() {
|
|
let w = this.w
|
|
let x, y, yDivision, xDivision, barHeight, barWidth, zeroH, zeroW
|
|
|
|
let dataPoints = w.globals.dataPoints
|
|
if (this.barCtx.isRangeBar) {
|
|
// timeline rangebar chart
|
|
dataPoints = w.globals.labels.length
|
|
}
|
|
|
|
let seriesLen = this.barCtx.seriesLen
|
|
if (w.config.plotOptions.bar.rangeBarGroupRows) {
|
|
seriesLen = 1
|
|
}
|
|
|
|
if (this.barCtx.isHorizontal) {
|
|
// height divided into equal parts
|
|
yDivision = w.globals.gridHeight / dataPoints
|
|
barHeight = yDivision / seriesLen
|
|
|
|
if (w.globals.isXNumeric) {
|
|
yDivision = w.globals.gridHeight / this.barCtx.totalItems
|
|
barHeight = yDivision / this.barCtx.seriesLen
|
|
}
|
|
|
|
barHeight =
|
|
(barHeight * parseInt(this.barCtx.barOptions.barHeight, 10)) / 100
|
|
|
|
if (String(this.barCtx.barOptions.barHeight).indexOf('%') === -1) {
|
|
barHeight = parseInt(this.barCtx.barOptions.barHeight, 10)
|
|
}
|
|
|
|
zeroW =
|
|
this.barCtx.baseLineInvertedY +
|
|
w.globals.padHorizontal +
|
|
(this.barCtx.isReversed ? w.globals.gridWidth : 0) -
|
|
(this.barCtx.isReversed ? this.barCtx.baseLineInvertedY * 2 : 0)
|
|
|
|
if (this.barCtx.isFunnel) {
|
|
zeroW = w.globals.gridWidth / 2
|
|
}
|
|
y = (yDivision - barHeight * this.barCtx.seriesLen) / 2
|
|
} else {
|
|
// width divided into equal parts
|
|
xDivision = w.globals.gridWidth / this.barCtx.visibleItems
|
|
if (w.config.xaxis.convertedCatToNumeric) {
|
|
xDivision = w.globals.gridWidth / w.globals.dataPoints
|
|
}
|
|
barWidth =
|
|
((xDivision / seriesLen) *
|
|
parseInt(this.barCtx.barOptions.columnWidth, 10)) /
|
|
100
|
|
|
|
if (w.globals.isXNumeric) {
|
|
// max barwidth should be equal to minXDiff to avoid overlap
|
|
let xRatio = this.barCtx.xRatio
|
|
|
|
if (
|
|
w.globals.minXDiff &&
|
|
w.globals.minXDiff !== 0.5 &&
|
|
w.globals.minXDiff / xRatio > 0
|
|
) {
|
|
xDivision = w.globals.minXDiff / xRatio
|
|
}
|
|
|
|
barWidth =
|
|
((xDivision / seriesLen) *
|
|
parseInt(this.barCtx.barOptions.columnWidth, 10)) /
|
|
100
|
|
|
|
if (barWidth < 1) {
|
|
barWidth = 1
|
|
}
|
|
}
|
|
if (String(this.barCtx.barOptions.columnWidth).indexOf('%') === -1) {
|
|
barWidth = parseInt(this.barCtx.barOptions.columnWidth, 10)
|
|
}
|
|
|
|
zeroH =
|
|
w.globals.gridHeight -
|
|
this.barCtx.baseLineY[this.barCtx.yaxisIndex] -
|
|
(this.barCtx.isReversed ? w.globals.gridHeight : 0) +
|
|
(this.barCtx.isReversed
|
|
? this.barCtx.baseLineY[this.barCtx.yaxisIndex] * 2
|
|
: 0)
|
|
|
|
x =
|
|
w.globals.padHorizontal +
|
|
(xDivision - barWidth * this.barCtx.seriesLen) / 2
|
|
}
|
|
|
|
w.globals.barHeight = barHeight
|
|
w.globals.barWidth = barWidth
|
|
|
|
return {
|
|
x,
|
|
y,
|
|
yDivision,
|
|
xDivision,
|
|
barHeight,
|
|
barWidth,
|
|
zeroH,
|
|
zeroW,
|
|
}
|
|
}
|
|
|
|
initializeStackedPrevVars(ctx) {
|
|
const w = ctx.w
|
|
if (w.globals.hasSeriesGroups) {
|
|
w.globals.seriesGroups.forEach((group) => {
|
|
if (!ctx[group]) ctx[group] = {}
|
|
|
|
ctx[group].prevY = []
|
|
ctx[group].prevX = []
|
|
ctx[group].prevYF = []
|
|
ctx[group].prevXF = []
|
|
ctx[group].prevYVal = []
|
|
ctx[group].prevXVal = []
|
|
})
|
|
} else {
|
|
ctx.prevY = [] // y position on chart (in columns)
|
|
ctx.prevX = [] // x position on chart (in horz bars)
|
|
ctx.prevYF = [] // starting y and ending y (height) in columns
|
|
ctx.prevXF = [] // starting x and ending x (width) in bars
|
|
ctx.prevYVal = [] // y values (series[i][j]) in columns
|
|
ctx.prevXVal = [] // x values (series[i][j]) in bars
|
|
}
|
|
}
|
|
|
|
initializeStackedXYVars(ctx) {
|
|
const w = ctx.w
|
|
|
|
if (w.globals.hasSeriesGroups) {
|
|
w.globals.seriesGroups.forEach((group) => {
|
|
if (!ctx[group]) ctx[group] = {}
|
|
|
|
ctx[group].xArrj = []
|
|
ctx[group].xArrjF = []
|
|
ctx[group].xArrjVal = []
|
|
ctx[group].yArrj = []
|
|
ctx[group].yArrjF = []
|
|
ctx[group].yArrjVal = []
|
|
})
|
|
} else {
|
|
ctx.xArrj = [] // xj indicates x position on graph in bars
|
|
ctx.xArrjF = [] // xjF indicates bar's x position + x2 positions in bars
|
|
ctx.xArrjVal = [] // x val means the actual series's y values in horizontal/bars
|
|
ctx.yArrj = [] // yj indicates y position on graph in columns
|
|
ctx.yArrjF = [] // yjF indicates bar's y position + y2 positions in columns
|
|
ctx.yArrjVal = [] // y val means the actual series's y values in columns
|
|
}
|
|
}
|
|
|
|
getPathFillColor(series, i, j, realIndex) {
|
|
const w = this.w
|
|
let fill = new Fill(this.barCtx.ctx)
|
|
|
|
let fillColor = null
|
|
let seriesNumber = this.barCtx.barOptions.distributed ? j : i
|
|
|
|
if (this.barCtx.barOptions.colors.ranges.length > 0) {
|
|
const colorRange = this.barCtx.barOptions.colors.ranges
|
|
colorRange.map((range) => {
|
|
if (series[i][j] >= range.from && series[i][j] <= range.to) {
|
|
fillColor = range.color
|
|
}
|
|
})
|
|
}
|
|
|
|
if (w.config.series[i].data[j] && w.config.series[i].data[j].fillColor) {
|
|
fillColor = w.config.series[i].data[j].fillColor
|
|
}
|
|
|
|
let pathFill = fill.fillPath({
|
|
seriesNumber: this.barCtx.barOptions.distributed
|
|
? seriesNumber
|
|
: realIndex,
|
|
dataPointIndex: j,
|
|
color: fillColor,
|
|
value: series[i][j],
|
|
fillConfig: w.config.series[i].data[j]?.fill,
|
|
fillType: w.config.series[i].data[j]?.fill?.type
|
|
? w.config.series[i].data[j]?.fill.type
|
|
: Array.isArray(w.config.fill.type)
|
|
? w.config.fill.type[i]
|
|
: w.config.fill.type,
|
|
})
|
|
|
|
return pathFill
|
|
}
|
|
|
|
getStrokeWidth(i, j, realIndex) {
|
|
let strokeWidth = 0
|
|
const w = this.w
|
|
|
|
if (
|
|
typeof this.barCtx.series[i][j] === 'undefined' ||
|
|
this.barCtx.series[i][j] === null
|
|
) {
|
|
this.barCtx.isNullValue = true
|
|
} else {
|
|
this.barCtx.isNullValue = false
|
|
}
|
|
if (w.config.stroke.show) {
|
|
if (!this.barCtx.isNullValue) {
|
|
strokeWidth = Array.isArray(this.barCtx.strokeWidth)
|
|
? this.barCtx.strokeWidth[realIndex]
|
|
: this.barCtx.strokeWidth
|
|
}
|
|
}
|
|
return strokeWidth
|
|
}
|
|
|
|
shouldApplyRadius(realIndex) {
|
|
const w = this.w
|
|
let applyRadius = false
|
|
|
|
if (w.config.plotOptions.bar.borderRadius > 0) {
|
|
if (w.config.chart.stacked) {
|
|
if (w.config.plotOptions.bar.borderRadiusWhenStacked === 'last') {
|
|
if (this.barCtx.lastActiveBarSerieIndex === realIndex) {
|
|
applyRadius = true
|
|
}
|
|
} else {
|
|
applyRadius = true
|
|
}
|
|
} else {
|
|
applyRadius = true
|
|
}
|
|
}
|
|
return applyRadius
|
|
}
|
|
|
|
barBackground({ j, i, x1, x2, y1, y2, elSeries }) {
|
|
const w = this.w
|
|
const graphics = new Graphics(this.barCtx.ctx)
|
|
|
|
const sr = new Series(this.barCtx.ctx)
|
|
let activeSeriesIndex = sr.getActiveConfigSeriesIndex()
|
|
|
|
if (
|
|
this.barCtx.barOptions.colors.backgroundBarColors.length > 0 &&
|
|
activeSeriesIndex === i
|
|
) {
|
|
if (j >= this.barCtx.barOptions.colors.backgroundBarColors.length) {
|
|
j %= this.barCtx.barOptions.colors.backgroundBarColors.length
|
|
}
|
|
|
|
let bcolor = this.barCtx.barOptions.colors.backgroundBarColors[j]
|
|
let rect = graphics.drawRect(
|
|
typeof x1 !== 'undefined' ? x1 : 0,
|
|
typeof y1 !== 'undefined' ? y1 : 0,
|
|
typeof x2 !== 'undefined' ? x2 : w.globals.gridWidth,
|
|
typeof y2 !== 'undefined' ? y2 : w.globals.gridHeight,
|
|
this.barCtx.barOptions.colors.backgroundBarRadius,
|
|
bcolor,
|
|
this.barCtx.barOptions.colors.backgroundBarOpacity
|
|
)
|
|
elSeries.add(rect)
|
|
rect.node.classList.add('apexcharts-backgroundBar')
|
|
}
|
|
}
|
|
|
|
getColumnPaths({
|
|
barWidth,
|
|
barXPosition,
|
|
y1,
|
|
y2,
|
|
strokeWidth,
|
|
seriesGroup,
|
|
realIndex,
|
|
i,
|
|
j,
|
|
w,
|
|
}) {
|
|
const graphics = new Graphics(this.barCtx.ctx)
|
|
strokeWidth = Array.isArray(strokeWidth)
|
|
? strokeWidth[realIndex]
|
|
: strokeWidth
|
|
if (!strokeWidth) strokeWidth = 0
|
|
|
|
let bW = barWidth
|
|
let bXP = barXPosition
|
|
|
|
if (w.config.series[realIndex].data[j]?.columnWidthOffset) {
|
|
bXP =
|
|
barXPosition - w.config.series[realIndex].data[j].columnWidthOffset / 2
|
|
bW = barWidth + w.config.series[realIndex].data[j].columnWidthOffset
|
|
}
|
|
|
|
const x1 = bXP
|
|
const x2 = bXP + bW
|
|
|
|
// append tiny pixels to avoid exponentials (which cause issues in border-radius)
|
|
y1 += 0.001
|
|
y2 += 0.001
|
|
|
|
let pathTo = graphics.move(x1, y1)
|
|
let pathFrom = graphics.move(x1, y1)
|
|
|
|
const sl = graphics.line(x2 - strokeWidth, y1)
|
|
if (w.globals.previousPaths.length > 0) {
|
|
pathFrom = this.barCtx.getPreviousPath(realIndex, j, false)
|
|
}
|
|
|
|
pathTo =
|
|
pathTo +
|
|
graphics.line(x1, y2) +
|
|
graphics.line(x2 - strokeWidth, y2) +
|
|
graphics.line(x2 - strokeWidth, y1) +
|
|
(w.config.plotOptions.bar.borderRadiusApplication === 'around'
|
|
? ' Z'
|
|
: ' z')
|
|
|
|
// the lines in pathFrom are repeated to equal it to the points of pathTo
|
|
// this is to avoid weird animation (bug in svg.js)
|
|
pathFrom =
|
|
pathFrom +
|
|
graphics.line(x1, y1) +
|
|
sl +
|
|
sl +
|
|
sl +
|
|
sl +
|
|
sl +
|
|
graphics.line(x1, y1) +
|
|
(w.config.plotOptions.bar.borderRadiusApplication === 'around'
|
|
? ' Z'
|
|
: ' z')
|
|
|
|
if (this.shouldApplyRadius(realIndex)) {
|
|
pathTo = graphics.roundPathCorners(
|
|
pathTo,
|
|
w.config.plotOptions.bar.borderRadius
|
|
)
|
|
}
|
|
|
|
if (w.config.chart.stacked) {
|
|
let _ctx = this.barCtx
|
|
if (w.globals.hasSeriesGroups && seriesGroup) {
|
|
_ctx = this.barCtx[seriesGroup]
|
|
}
|
|
_ctx.yArrj.push(y2)
|
|
_ctx.yArrjF.push(Math.abs(y1 - y2))
|
|
_ctx.yArrjVal.push(this.barCtx.series[i][j])
|
|
}
|
|
|
|
return {
|
|
pathTo,
|
|
pathFrom,
|
|
}
|
|
}
|
|
|
|
getBarpaths({
|
|
barYPosition,
|
|
barHeight,
|
|
x1,
|
|
x2,
|
|
strokeWidth,
|
|
seriesGroup,
|
|
realIndex,
|
|
i,
|
|
j,
|
|
w,
|
|
}) {
|
|
const graphics = new Graphics(this.barCtx.ctx)
|
|
strokeWidth = Array.isArray(strokeWidth)
|
|
? strokeWidth[realIndex]
|
|
: strokeWidth
|
|
if (!strokeWidth) strokeWidth = 0
|
|
|
|
let bYP = barYPosition
|
|
let bH = barHeight
|
|
|
|
if (w.config.series[realIndex].data[j]?.barHeightOffset) {
|
|
bYP =
|
|
barYPosition - w.config.series[realIndex].data[j].barHeightOffset / 2
|
|
bH = barHeight + w.config.series[realIndex].data[j].barHeightOffset
|
|
}
|
|
|
|
const y1 = bYP
|
|
const y2 = bYP + bH
|
|
|
|
// append tiny pixels to avoid exponentials (which cause issues in border-radius)
|
|
x1 += 0.001
|
|
x2 += 0.001
|
|
|
|
let pathTo = graphics.move(x1, y1)
|
|
let pathFrom = graphics.move(x1, y1)
|
|
|
|
if (w.globals.previousPaths.length > 0) {
|
|
pathFrom = this.barCtx.getPreviousPath(realIndex, j, false)
|
|
}
|
|
|
|
const sl = graphics.line(x1, y2 - strokeWidth)
|
|
pathTo =
|
|
pathTo +
|
|
graphics.line(x2, y1) +
|
|
graphics.line(x2, y2 - strokeWidth) +
|
|
sl +
|
|
(w.config.plotOptions.bar.borderRadiusApplication === 'around'
|
|
? ' Z'
|
|
: ' z')
|
|
|
|
pathFrom =
|
|
pathFrom +
|
|
graphics.line(x1, y1) +
|
|
sl +
|
|
sl +
|
|
sl +
|
|
sl +
|
|
sl +
|
|
graphics.line(x1, y1) +
|
|
(w.config.plotOptions.bar.borderRadiusApplication === 'around'
|
|
? ' Z'
|
|
: ' z')
|
|
|
|
if (this.shouldApplyRadius(realIndex)) {
|
|
pathTo = graphics.roundPathCorners(
|
|
pathTo,
|
|
w.config.plotOptions.bar.borderRadius
|
|
)
|
|
}
|
|
|
|
if (w.config.chart.stacked) {
|
|
let _ctx = this.barCtx
|
|
if (w.globals.hasSeriesGroups && seriesGroup) {
|
|
_ctx = this.barCtx[seriesGroup]
|
|
}
|
|
|
|
_ctx.xArrj.push(x2)
|
|
_ctx.xArrjF.push(Math.abs(x1 - x2))
|
|
_ctx.xArrjVal.push(this.barCtx.series[i][j])
|
|
}
|
|
return {
|
|
pathTo,
|
|
pathFrom,
|
|
}
|
|
}
|
|
|
|
checkZeroSeries({ series }) {
|
|
let w = this.w
|
|
for (let zs = 0; zs < series.length; zs++) {
|
|
let total = 0
|
|
for (
|
|
let zsj = 0;
|
|
zsj < series[w.globals.maxValsInArrayIndex].length;
|
|
zsj++
|
|
) {
|
|
total += series[zs][zsj]
|
|
}
|
|
if (total === 0) {
|
|
this.barCtx.zeroSerieses.push(zs)
|
|
}
|
|
}
|
|
}
|
|
|
|
getXForValue(value, zeroW, zeroPositionForNull = true) {
|
|
let xForVal = zeroPositionForNull ? zeroW : null
|
|
if (typeof value !== 'undefined' && value !== null) {
|
|
xForVal =
|
|
zeroW +
|
|
value / this.barCtx.invertedYRatio -
|
|
(this.barCtx.isReversed ? value / this.barCtx.invertedYRatio : 0) * 2
|
|
}
|
|
return xForVal
|
|
}
|
|
|
|
getYForValue(value, zeroH, zeroPositionForNull = true) {
|
|
let yForVal = zeroPositionForNull ? zeroH : null
|
|
if (typeof value !== 'undefined' && value !== null) {
|
|
yForVal =
|
|
zeroH -
|
|
value / this.barCtx.yRatio[this.barCtx.yaxisIndex] +
|
|
(this.barCtx.isReversed
|
|
? value / this.barCtx.yRatio[this.barCtx.yaxisIndex]
|
|
: 0) *
|
|
2
|
|
}
|
|
return yForVal
|
|
}
|
|
|
|
getGoalValues(type, zeroW, zeroH, i, j) {
|
|
const w = this.w
|
|
|
|
let goals = []
|
|
|
|
const pushGoal = (value, attrs) => {
|
|
goals.push({
|
|
[type]:
|
|
type === 'x'
|
|
? this.getXForValue(value, zeroW, false)
|
|
: this.getYForValue(value, zeroH, false),
|
|
attrs,
|
|
})
|
|
}
|
|
if (
|
|
w.globals.seriesGoals[i] &&
|
|
w.globals.seriesGoals[i][j] &&
|
|
Array.isArray(w.globals.seriesGoals[i][j])
|
|
) {
|
|
w.globals.seriesGoals[i][j].forEach((goal) => {
|
|
pushGoal(goal.value, goal)
|
|
})
|
|
}
|
|
if (this.barCtx.barOptions.isDumbbell && w.globals.seriesRange.length) {
|
|
let colors = this.barCtx.barOptions.dumbbellColors
|
|
? this.barCtx.barOptions.dumbbellColors
|
|
: w.globals.colors
|
|
const commonAttrs = {
|
|
strokeHeight: type === 'x' ? 0 : w.globals.markers.size[i],
|
|
strokeWidth: type === 'x' ? w.globals.markers.size[i] : 0,
|
|
strokeDashArray: 0,
|
|
strokeLineCap: 'round',
|
|
strokeColor: Array.isArray(colors[i]) ? colors[i][0] : colors[i],
|
|
}
|
|
|
|
pushGoal(w.globals.seriesRangeStart[i][j], commonAttrs)
|
|
pushGoal(w.globals.seriesRangeEnd[i][j], {
|
|
...commonAttrs,
|
|
strokeColor: Array.isArray(colors[i]) ? colors[i][1] : colors[i],
|
|
})
|
|
}
|
|
return goals
|
|
}
|
|
|
|
drawGoalLine({
|
|
barXPosition,
|
|
barYPosition,
|
|
goalX,
|
|
goalY,
|
|
barWidth,
|
|
barHeight,
|
|
}) {
|
|
let graphics = new Graphics(this.barCtx.ctx)
|
|
const lineGroup = graphics.group({
|
|
className: 'apexcharts-bar-goals-groups',
|
|
})
|
|
|
|
lineGroup.node.classList.add('apexcharts-element-hidden')
|
|
this.barCtx.w.globals.delayedElements.push({
|
|
el: lineGroup.node,
|
|
})
|
|
|
|
lineGroup.attr(
|
|
'clip-path',
|
|
`url(#gridRectMarkerMask${this.barCtx.w.globals.cuid})`
|
|
)
|
|
|
|
let line = null
|
|
if (this.barCtx.isHorizontal) {
|
|
if (Array.isArray(goalX)) {
|
|
goalX.forEach((goal) => {
|
|
let sHeight =
|
|
typeof goal.attrs.strokeHeight !== 'undefined'
|
|
? goal.attrs.strokeHeight
|
|
: barHeight / 2
|
|
let y = barYPosition + sHeight + barHeight / 2
|
|
|
|
line = graphics.drawLine(
|
|
goal.x,
|
|
y - sHeight * 2,
|
|
goal.x,
|
|
y,
|
|
goal.attrs.strokeColor ? goal.attrs.strokeColor : undefined,
|
|
goal.attrs.strokeDashArray,
|
|
goal.attrs.strokeWidth ? goal.attrs.strokeWidth : 2,
|
|
goal.attrs.strokeLineCap
|
|
)
|
|
lineGroup.add(line)
|
|
})
|
|
}
|
|
} else {
|
|
if (Array.isArray(goalY)) {
|
|
goalY.forEach((goal) => {
|
|
let sWidth =
|
|
typeof goal.attrs.strokeWidth !== 'undefined'
|
|
? goal.attrs.strokeWidth
|
|
: barWidth / 2
|
|
let x = barXPosition + sWidth + barWidth / 2
|
|
|
|
line = graphics.drawLine(
|
|
x - sWidth * 2,
|
|
goal.y,
|
|
x,
|
|
goal.y,
|
|
goal.attrs.strokeColor ? goal.attrs.strokeColor : undefined,
|
|
goal.attrs.strokeDashArray,
|
|
goal.attrs.strokeHeight ? goal.attrs.strokeHeight : 2,
|
|
goal.attrs.strokeLineCap
|
|
)
|
|
lineGroup.add(line)
|
|
})
|
|
}
|
|
}
|
|
|
|
return lineGroup
|
|
}
|
|
|
|
drawBarShadow({ prevPaths, currPaths, color }) {
|
|
const w = this.w
|
|
const { x: prevX2, x1: prevX1, barYPosition: prevY1 } = prevPaths
|
|
const { x: currX2, x1: currX1, barYPosition: currY1 } = currPaths
|
|
|
|
const prevY2 = prevY1 + currPaths.barHeight
|
|
|
|
const graphics = new Graphics(this.barCtx.ctx)
|
|
const utils = new Utils()
|
|
|
|
const shadowPath =
|
|
graphics.move(prevX1, prevY2) +
|
|
graphics.line(prevX2, prevY2) +
|
|
graphics.line(currX2, currY1) +
|
|
graphics.line(currX1, currY1) +
|
|
graphics.line(prevX1, prevY2) +
|
|
(w.config.plotOptions.bar.borderRadiusApplication === 'around'
|
|
? ' Z'
|
|
: ' z')
|
|
|
|
return graphics.drawPath({
|
|
d: shadowPath,
|
|
fill: utils.shadeColor(0.5, Utils.rgb2hex(color)),
|
|
stroke: 'none',
|
|
strokeWidth: 0,
|
|
fillOpacity: 1,
|
|
classes: 'apexcharts-bar-shadows',
|
|
})
|
|
}
|
|
|
|
getZeroValueEncounters({ i, j }) {
|
|
const w = this.w
|
|
|
|
let nonZeroColumns = 0
|
|
let zeroEncounters = 0
|
|
w.globals.seriesPercent.forEach((_s, _si) => {
|
|
if (_s[j]) {
|
|
nonZeroColumns++
|
|
}
|
|
|
|
if (_si < i && _s[j] === 0) {
|
|
zeroEncounters++
|
|
}
|
|
})
|
|
|
|
return {
|
|
nonZeroColumns,
|
|
zeroEncounters,
|
|
}
|
|
}
|
|
}
|