initial commit
This commit is contained in:
@@ -0,0 +1,267 @@
|
||||
import Animations from '../modules/Animations'
|
||||
import Fill from '../modules/Fill'
|
||||
import Filters from '../modules/Filters'
|
||||
import Graphics from '../modules/Graphics'
|
||||
import Markers from '../modules/Markers'
|
||||
|
||||
/**
|
||||
* ApexCharts Scatter Class.
|
||||
* This Class also handles bubbles chart as currently there is no major difference in drawing them,
|
||||
* @module Scatter
|
||||
**/
|
||||
export default class Scatter {
|
||||
constructor(ctx) {
|
||||
this.ctx = ctx
|
||||
this.w = ctx.w
|
||||
|
||||
this.initialAnim = this.w.config.chart.animations.enabled
|
||||
this.dynamicAnim =
|
||||
this.initialAnim &&
|
||||
this.w.config.chart.animations.dynamicAnimation.enabled
|
||||
}
|
||||
|
||||
draw(elSeries, j, opts) {
|
||||
let w = this.w
|
||||
|
||||
let graphics = new Graphics(this.ctx)
|
||||
|
||||
let realIndex = opts.realIndex
|
||||
let pointsPos = opts.pointsPos
|
||||
let zRatio = opts.zRatio
|
||||
let elPointsMain = opts.elParent
|
||||
|
||||
let elPointsWrap = graphics.group({
|
||||
class: `apexcharts-series-markers apexcharts-series-${w.config.chart.type}`
|
||||
})
|
||||
|
||||
elPointsWrap.attr('clip-path', `url(#gridRectMarkerMask${w.globals.cuid})`)
|
||||
|
||||
if (Array.isArray(pointsPos.x)) {
|
||||
for (let q = 0; q < pointsPos.x.length; q++) {
|
||||
let dataPointIndex = j + 1
|
||||
let shouldDraw = true
|
||||
|
||||
// a small hack as we have 2 points for the first val to connect it
|
||||
if (j === 0 && q === 0) dataPointIndex = 0
|
||||
if (j === 0 && q === 1) dataPointIndex = 1
|
||||
|
||||
let radius = 0
|
||||
let finishRadius = w.globals.markers.size[realIndex]
|
||||
|
||||
if (zRatio !== Infinity) {
|
||||
// means we have a bubble
|
||||
finishRadius = w.globals.seriesZ[realIndex][dataPointIndex] / zRatio
|
||||
|
||||
const bubble = w.config.plotOptions.bubble
|
||||
if (bubble.minBubbleRadius && finishRadius < bubble.minBubbleRadius) {
|
||||
finishRadius = bubble.minBubbleRadius
|
||||
}
|
||||
|
||||
if (bubble.maxBubbleRadius && finishRadius > bubble.maxBubbleRadius) {
|
||||
finishRadius = bubble.maxBubbleRadius
|
||||
}
|
||||
}
|
||||
|
||||
if (!w.config.chart.animations.enabled) {
|
||||
radius = finishRadius
|
||||
}
|
||||
|
||||
let x = pointsPos.x[q]
|
||||
let y = pointsPos.y[q]
|
||||
|
||||
radius = radius || 0
|
||||
|
||||
if (
|
||||
y === null ||
|
||||
typeof w.globals.series[realIndex][dataPointIndex] === 'undefined'
|
||||
) {
|
||||
shouldDraw = false
|
||||
}
|
||||
|
||||
if (shouldDraw) {
|
||||
const point = this.drawPoint(
|
||||
x,
|
||||
y,
|
||||
radius,
|
||||
finishRadius,
|
||||
realIndex,
|
||||
dataPointIndex,
|
||||
j
|
||||
)
|
||||
elPointsWrap.add(point)
|
||||
}
|
||||
|
||||
elPointsMain.add(elPointsWrap)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
drawPoint(x, y, radius, finishRadius, realIndex, dataPointIndex, j) {
|
||||
const w = this.w
|
||||
|
||||
let i = realIndex
|
||||
let anim = new Animations(this.ctx)
|
||||
let filters = new Filters(this.ctx)
|
||||
let fill = new Fill(this.ctx)
|
||||
let markers = new Markers(this.ctx)
|
||||
const graphics = new Graphics(this.ctx)
|
||||
|
||||
const markerConfig = markers.getMarkerConfig({
|
||||
cssClass: 'apexcharts-marker',
|
||||
seriesIndex: i,
|
||||
dataPointIndex,
|
||||
finishRadius:
|
||||
w.config.chart.type === 'bubble' ||
|
||||
(w.globals.comboCharts &&
|
||||
w.config.series[realIndex] &&
|
||||
w.config.series[realIndex].type === 'bubble')
|
||||
? finishRadius
|
||||
: null
|
||||
})
|
||||
|
||||
finishRadius = markerConfig.pSize
|
||||
|
||||
let pathFillCircle = fill.fillPath({
|
||||
seriesNumber: realIndex,
|
||||
dataPointIndex,
|
||||
color: markerConfig.pointFillColor,
|
||||
patternUnits: 'objectBoundingBox',
|
||||
value: w.globals.series[realIndex][j]
|
||||
})
|
||||
|
||||
let el
|
||||
if (markerConfig.shape === 'circle') {
|
||||
el = graphics.drawCircle(radius)
|
||||
} else if (
|
||||
markerConfig.shape === 'square' ||
|
||||
markerConfig.shape === 'rect'
|
||||
) {
|
||||
el = graphics.drawRect(
|
||||
0,
|
||||
0,
|
||||
markerConfig.width - markerConfig.pointStrokeWidth / 2,
|
||||
markerConfig.height - markerConfig.pointStrokeWidth / 2,
|
||||
markerConfig.pRadius
|
||||
)
|
||||
}
|
||||
|
||||
if (w.config.series[i].data[dataPointIndex]) {
|
||||
if (w.config.series[i].data[dataPointIndex].fillColor) {
|
||||
pathFillCircle = w.config.series[i].data[dataPointIndex].fillColor
|
||||
}
|
||||
}
|
||||
|
||||
el.attr({
|
||||
x: x - markerConfig.width / 2 - markerConfig.pointStrokeWidth / 2,
|
||||
y: y - markerConfig.height / 2 - markerConfig.pointStrokeWidth / 2,
|
||||
cx: x,
|
||||
cy: y,
|
||||
fill: pathFillCircle,
|
||||
'fill-opacity': markerConfig.pointFillOpacity,
|
||||
stroke: markerConfig.pointStrokeColor,
|
||||
r: finishRadius,
|
||||
'stroke-width': markerConfig.pointStrokeWidth,
|
||||
'stroke-dasharray': markerConfig.pointStrokeDashArray,
|
||||
'stroke-opacity': markerConfig.pointStrokeOpacity
|
||||
})
|
||||
|
||||
if (w.config.chart.dropShadow.enabled) {
|
||||
const dropShadow = w.config.chart.dropShadow
|
||||
filters.dropShadow(el, dropShadow, realIndex)
|
||||
}
|
||||
|
||||
if (this.initialAnim && !w.globals.dataChanged && !w.globals.resized) {
|
||||
let speed = w.config.chart.animations.speed
|
||||
|
||||
anim.animateMarker(
|
||||
el,
|
||||
0,
|
||||
markerConfig.shape === 'circle'
|
||||
? finishRadius
|
||||
: { width: markerConfig.width, height: markerConfig.height },
|
||||
speed,
|
||||
w.globals.easing,
|
||||
() => {
|
||||
window.setTimeout(() => {
|
||||
anim.animationCompleted(el)
|
||||
}, 100)
|
||||
}
|
||||
)
|
||||
} else {
|
||||
w.globals.animationEnded = true
|
||||
}
|
||||
|
||||
if (w.globals.dataChanged && markerConfig.shape === 'circle') {
|
||||
if (this.dynamicAnim) {
|
||||
let speed = w.config.chart.animations.dynamicAnimation.speed
|
||||
let prevX, prevY, prevR
|
||||
|
||||
let prevPathJ = null
|
||||
|
||||
prevPathJ =
|
||||
w.globals.previousPaths[realIndex] &&
|
||||
w.globals.previousPaths[realIndex][j]
|
||||
|
||||
if (typeof prevPathJ !== 'undefined' && prevPathJ !== null) {
|
||||
// series containing less elements will ignore these values and revert to 0
|
||||
prevX = prevPathJ.x
|
||||
prevY = prevPathJ.y
|
||||
prevR =
|
||||
typeof prevPathJ.r !== 'undefined' ? prevPathJ.r : finishRadius
|
||||
}
|
||||
|
||||
for (let cs = 0; cs < w.globals.collapsedSeries.length; cs++) {
|
||||
if (w.globals.collapsedSeries[cs].index === realIndex) {
|
||||
speed = 1
|
||||
finishRadius = 0
|
||||
}
|
||||
}
|
||||
|
||||
if (x === 0 && y === 0) finishRadius = 0
|
||||
|
||||
anim.animateCircle(
|
||||
el,
|
||||
{
|
||||
cx: prevX,
|
||||
cy: prevY,
|
||||
r: prevR
|
||||
},
|
||||
{
|
||||
cx: x,
|
||||
cy: y,
|
||||
r: finishRadius
|
||||
},
|
||||
speed,
|
||||
w.globals.easing
|
||||
)
|
||||
} else {
|
||||
el.attr({
|
||||
r: finishRadius
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
el.attr({
|
||||
rel: dataPointIndex,
|
||||
j: dataPointIndex,
|
||||
index: realIndex,
|
||||
'default-marker-size': finishRadius
|
||||
})
|
||||
|
||||
filters.setSelectionFilter(el, realIndex, dataPointIndex)
|
||||
markers.addEvents(el)
|
||||
|
||||
el.node.classList.add('apexcharts-marker')
|
||||
|
||||
return el
|
||||
}
|
||||
|
||||
centerTextInBubble(y) {
|
||||
let w = this.w
|
||||
y = y + parseInt(w.config.dataLabels.style.fontSize, 10) / 4
|
||||
|
||||
return {
|
||||
y
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user