ikizmet-apexcharts
Version:
iKizmet fork of Apex Charts library
442 lines (371 loc) • 11.5 kB
JavaScript
import Animations from '../Animations'
import CoreUtils from '../CoreUtils'
import Graphics from '../Graphics'
import XAxis from './XAxis'
import YAxis from './YAxis'
/**
* ApexCharts Grid Class for drawing Cartesian Grid.
*
* @module Grid
**/
class Grid {
constructor(ctx) {
this.ctx = ctx
this.w = ctx.w
const w = this.w
this.anim = new Animations(this.ctx)
this.xaxisLabels = w.globals.labels.slice()
this.animX =
w.config.grid.xaxis.lines.animate && w.config.chart.animations.enabled
this.animY =
w.config.grid.yaxis.lines.animate && w.config.chart.animations.enabled
if (w.globals.timelineLabels.length > 0) {
// timeline labels are there
this.xaxisLabels = w.globals.timelineLabels.slice()
}
}
// .when using sparklines or when showing no grid, we need to have a grid area which is reused at many places for other calculations as well
drawGridArea(elGrid = null) {
let w = this.w
let graphics = new Graphics(this.ctx)
if (elGrid === null) {
elGrid = graphics.group({
class: 'apexcharts-grid'
})
}
let elVerticalLine = graphics.drawLine(
w.globals.padHorizontal,
1,
w.globals.padHorizontal,
w.globals.gridHeight,
'transparent'
)
let elHorzLine = graphics.drawLine(
w.globals.padHorizontal,
w.globals.gridHeight,
w.globals.gridWidth,
w.globals.gridHeight,
'transparent'
)
elGrid.add(elHorzLine)
elGrid.add(elVerticalLine)
return elGrid
}
drawGrid() {
let w = this.w
let xAxis = new XAxis(this.ctx)
let yaxis = new YAxis(this.ctx)
let gl = this.w.globals
let elgrid = null
if (gl.axisCharts) {
if (w.config.grid.show) {
// grid is drawn after xaxis and yaxis are drawn
elgrid = this.renderGrid()
gl.dom.elGraphical.add(elgrid.el)
this.drawGridArea(elgrid.el)
} else {
let elgridArea = this.drawGridArea()
gl.dom.elGraphical.add(elgridArea)
}
if (elgrid !== null) {
xAxis.xAxisLabelCorrections(elgrid.xAxisTickWidth)
}
yaxis.setYAxisTextAlignments()
}
}
// This mask will clip off overflowing graphics from the drawable area
createGridMask() {
let w = this.w
let gl = w.globals
const graphics = new Graphics(this.ctx)
let strokeSize = Array.isArray(w.config.stroke.width)
? 0
: w.config.stroke.width
if (Array.isArray(w.config.stroke.width)) {
let strokeMaxSize = 0
w.config.stroke.width.forEach(function(m) {
strokeMaxSize = Math.max(strokeMaxSize, m)
})
strokeSize = strokeMaxSize
}
gl.dom.elGridRectMask = document.createElementNS(gl.SVGNS, 'clipPath')
gl.dom.elGridRectMask.setAttribute('id', `gridRectMask${gl.cuid}`)
gl.dom.elGridRectMarkerMask = document.createElementNS(gl.SVGNS, 'clipPath')
gl.dom.elGridRectMarkerMask.setAttribute(
'id',
`gridRectMarkerMask${gl.cuid}`
)
gl.dom.elGridRect = graphics.drawRect(
-strokeSize / 2,
-strokeSize / 2,
gl.gridWidth + strokeSize,
gl.gridHeight + strokeSize,
0,
'#fff'
)
const coreUtils = new CoreUtils(this)
coreUtils.getLargestMarkerSize()
let markerSize =
w.globals.markers.largestSize + w.config.markers.hover.sizeOffset + 1
if (markerSize < 10) markerSize = 10
gl.dom.elGridRectMarker = graphics.drawRect(
-markerSize * 2,
-markerSize * 2,
gl.gridWidth + markerSize * 4,
gl.gridHeight + markerSize * 4,
0,
'#fff'
)
gl.dom.elGridRectMask.appendChild(gl.dom.elGridRect.node)
gl.dom.elGridRectMarkerMask.appendChild(gl.dom.elGridRectMarker.node)
let defs = gl.dom.baseEl.querySelector('defs')
defs.appendChild(gl.dom.elGridRectMask)
defs.appendChild(gl.dom.elGridRectMarkerMask)
}
// actual grid rendering
renderGrid() {
let w = this.w
let graphics = new Graphics(this.ctx)
let strokeDashArray = w.config.grid.strokeDashArray
let elg = graphics.group({
class: 'apexcharts-grid'
})
let elgridLinesH = graphics.group({
class: 'apexcharts-gridlines-horizontal'
})
let elgridLinesV = graphics.group({
class: 'apexcharts-gridlines-vertical'
})
elg.add(elgridLinesH)
elg.add(elgridLinesV)
let tickAmount = 8
for (let i = 0; i < w.globals.series.length; i++) {
if (typeof w.globals.yAxisScale[i] !== 'undefined') {
tickAmount = w.globals.yAxisScale[i].result.length - 1
}
if (tickAmount > 2) break
}
let xCount
if (!w.globals.isBarHorizontal) {
xCount = this.xaxisLabels.length
// draw vertical lines
if (w.config.grid.xaxis.lines.show || w.config.xaxis.axisTicks.show) {
let x1 = w.globals.padHorizontal
let y1 = 0
let x2
let y2 = w.globals.gridHeight
if (w.globals.timelineLabels.length > 0) {
for (let i = 0; i < xCount; i++) {
x1 = this.xaxisLabels[i].position
x2 = this.xaxisLabels[i].position
if (
w.config.grid.xaxis.lines.show &&
x1 > 0 &&
x1 < w.globals.gridWidth
) {
let line = graphics.drawLine(
x1,
y1,
x2,
y2,
w.config.grid.borderColor,
strokeDashArray
)
line.node.classList.add('apexcharts-gridline')
elgridLinesV.add(line)
if (this.animX) {
this.animateLine(line, { x1: 0, x2: 0 }, { x1: x1, x2 })
}
}
let xAxis = new XAxis(this.ctx)
xAxis.drawXaxisTicks(x1, elg)
}
} else {
let xCountForCategoryCharts = xCount
for (let i = 0; i < xCountForCategoryCharts; i++) {
let x1Count = xCountForCategoryCharts
if (w.globals.isXNumeric && w.config.chart.type !== 'bar') {
x1Count -= 1
}
x1 = x1 + w.globals.gridWidth / x1Count
x2 = x1
// skip the last line
if (i === x1Count - 1) break
if (w.config.grid.xaxis.lines.show) {
let line = graphics.drawLine(
x1,
y1,
x2,
y2,
w.config.grid.borderColor,
strokeDashArray
)
line.node.classList.add('apexcharts-gridline')
elgridLinesV.add(line)
if (this.animX) {
this.animateLine(line, { x1: 0, x2: 0 }, { x1: x1, x2 })
}
}
let xAxis = new XAxis(this.ctx)
xAxis.drawXaxisTicks(x1, elg)
}
}
}
// draw horizontal lines
if (w.config.grid.yaxis.lines.show) {
let x1 = 0
let y1 = 0
let y2 = 0
let x2 = w.globals.gridWidth
for (let i = 0; i < tickAmount + 1; i++) {
let line = graphics.drawLine(
x1,
y1,
x2,
y2,
w.config.grid.borderColor,
strokeDashArray
)
elgridLinesH.add(line)
line.node.classList.add('apexcharts-gridline')
if (this.animY) {
this.animateLine(line, { y1: y1 + 20, y2: y2 + 20 }, { y1: y1, y2 })
}
y1 = y1 + w.globals.gridHeight / tickAmount
y2 = y1
}
}
} else {
xCount = tickAmount
// draw vertical lines
if (w.config.grid.xaxis.lines.show || w.config.xaxis.axisTicks.show) {
let x1 = w.globals.padHorizontal
let y1 = 0
let x2
let y2 = w.globals.gridHeight
for (let i = 0; i < xCount + 1; i++) {
x1 = x1 + w.globals.gridWidth / xCount + 0.3
x2 = x1
// skip the last vertical line
if (i === xCount - 1) break
if (w.config.grid.xaxis.lines.show) {
let line = graphics.drawLine(
x1,
y1,
x2,
y2,
w.config.grid.borderColor,
strokeDashArray
)
line.node.classList.add('apexcharts-gridline')
elgridLinesV.add(line)
if (this.animX) {
this.animateLine(line, { x1: 0, x2: 0 }, { x1: x1, x2 })
}
}
// skip the first vertical line
let xAxis = new XAxis(this.ctx)
xAxis.drawXaxisTicks(x1, elg)
}
}
// draw horizontal lines
if (w.config.grid.yaxis.lines.show) {
let x1 = 0
let y1 = 0
let y2 = 0
let x2 = w.globals.gridWidth
for (let i = 0; i < w.globals.dataPoints + 1; i++) {
let line = graphics.drawLine(
x1,
y1,
x2,
y2,
w.config.grid.borderColor,
strokeDashArray
)
elgridLinesH.add(line)
line.node.classList.add('apexcharts-gridline')
if (this.animY) {
this.animateLine(line, { y1: y1 + 20, y2: y2 + 20 }, { y1: y1, y2 })
}
y1 = y1 + w.globals.gridHeight / w.globals.dataPoints
y2 = y1
}
}
}
this.drawGridBands(elg, xCount, tickAmount)
return {
el: elg,
xAxisTickWidth: w.globals.gridWidth / xCount
}
}
drawGridBands(elg, xCount, tickAmount) {
const w = this.w
const graphics = new Graphics(this.ctx)
// rows background bands
if (
w.config.grid.row.colors !== undefined &&
w.config.grid.row.colors.length > 0
) {
let x1 = 0
let y1 = 0
let y2 = w.globals.gridHeight / tickAmount
let x2 = w.globals.gridWidth
for (let i = 0, c = 0; i < tickAmount; i++, c++) {
if (c >= w.config.grid.row.colors.length) {
c = 0
}
const color = w.config.grid.row.colors[c]
let rect = graphics.drawRect(
x1,
y1,
x2,
y2,
0,
color,
w.config.grid.row.opacity
)
elg.add(rect)
rect.node.classList.add('apexcharts-gridRow')
y1 = y1 + w.globals.gridHeight / tickAmount
}
}
// columns background bands
if (
w.config.grid.column.colors !== undefined &&
w.config.grid.column.colors.length > 0
) {
let x1 = w.globals.padHorizontal
let y1 = 0
let x2 = w.globals.padHorizontal + w.globals.gridWidth / xCount
let y2 = w.globals.gridHeight
for (let i = 0, c = 0; i < xCount; i++, c++) {
if (c >= w.config.grid.column.colors.length) {
c = 0
}
const color = w.config.grid.column.colors[c]
let rect = graphics.drawRect(
x1,
y1,
x2,
y2,
0,
color,
w.config.grid.column.opacity
)
rect.node.classList.add('apexcharts-gridColumn')
elg.add(rect)
x1 = x1 + w.globals.gridWidth / xCount
}
}
}
animateLine(line, from, to) {
const w = this.w
let initialAnim = w.config.chart.animations
if (initialAnim && !w.globals.resized && !w.globals.dataChanged) {
let speed = initialAnim.speed
this.anim.animateLine(line, from, to, speed)
}
}
}
export default Grid