apexcharts
Advanced tools
Comparing version 3.48.0 to 3.49.0
@@ -46,3 +46,3 @@ { | ||
"exportToCSV": "下載 CSV", | ||
"menu": "菜單", | ||
"menu": "選單", | ||
"selection": "選擇", | ||
@@ -49,0 +49,0 @@ "selectionZoom": "選擇縮放", |
{ | ||
"name": "apexcharts", | ||
"version": "3.48.0", | ||
"version": "3.49.0", | ||
"description": "A JavaScript Chart Library", | ||
@@ -5,0 +5,0 @@ "repository": { |
@@ -163,3 +163,3 @@ import Annotations from './modules/annotations/Annotations' | ||
if (ser.length === 0 || allSeriesAreEmpty) { | ||
if (ser.length === 0 || allSeriesAreEmpty && gl.collapsedSeries.length < 1) { | ||
this.series.handleNoData() | ||
@@ -166,0 +166,0 @@ } |
@@ -322,6 +322,30 @@ import BarDataLabels from './common/bar/DataLabels' | ||
if (!lineFill) { | ||
// if user provided a function in colors, we need to eval here | ||
// Note: the position of this function logic (ex. stroke: { colors: ["",function(){}] }) i.e array index 1 depicts the realIndex/seriesIndex. | ||
function fetchColor(i) { | ||
const exp = w.config.stroke.colors | ||
let c | ||
if (Array.isArray(exp) && exp.length > 0) { | ||
c = exp[i] | ||
if (!c) c = '' | ||
if (typeof c === 'function') { | ||
return c({ | ||
value: w.globals.series[i][j], | ||
dataPointIndex: j, | ||
w, | ||
}) | ||
} | ||
} | ||
return c | ||
} | ||
const checkAvailableColor = | ||
typeof w.globals.stroke.colors[realIndex] === 'function' | ||
? fetchColor(realIndex) | ||
: w.globals.stroke.colors[realIndex] | ||
/* fix apexcharts#341 */ | ||
lineFill = this.barOptions.distributed | ||
? w.globals.stroke.colors[j] | ||
: w.globals.stroke.colors[realIndex] | ||
: checkAvailableColor | ||
} | ||
@@ -549,3 +573,7 @@ | ||
y = this.barHelpers.getYForValue(this.series[i][j], zeroH, translationsIndex) | ||
y = this.barHelpers.getYForValue( | ||
this.series[i][j], | ||
zeroH, | ||
translationsIndex | ||
) | ||
@@ -583,3 +611,10 @@ const paths = this.barHelpers.getColumnPaths({ | ||
y, | ||
goalY: this.barHelpers.getGoalValues('y', null, zeroH, i, j, translationsIndex), | ||
goalY: this.barHelpers.getGoalValues( | ||
'y', | ||
null, | ||
zeroH, | ||
i, | ||
j, | ||
translationsIndex | ||
), | ||
barXPosition, | ||
@@ -586,0 +621,0 @@ barWidth, |
@@ -50,3 +50,7 @@ import CoreUtils from '../modules/CoreUtils' | ||
w.globals.seriesGroups.forEach((group, gIndex) => { | ||
if (group.indexOf(w.config.series[i].name) > -1) { | ||
// w.config.series[i].name may be undefined, so use | ||
// w.globals.seriesNames[i], which has auto-generated names for those | ||
// series. w.globals.seriesGroups[] uses the same auto-gen naming, so | ||
// these will match. | ||
if (group.indexOf(w.globals.seriesNames[i]) > -1) { | ||
groupIndex = gIndex | ||
@@ -271,2 +275,6 @@ } | ||
} | ||
let subDivisions = | ||
w.globals.barGroups.length ? w.globals.barGroups.length : 1 | ||
return { | ||
@@ -277,8 +285,4 @@ x, | ||
xDivision, | ||
barHeight: w.globals.seriesGroups?.length | ||
? barHeight / w.globals.seriesGroups.length | ||
: barHeight, | ||
barWidth: w.globals.seriesGroups?.length | ||
? barWidth / w.globals.seriesGroups.length | ||
: barWidth, | ||
barHeight: barHeight / subDivisions, | ||
barWidth: barWidth / subDivisions, | ||
zeroH, | ||
@@ -408,6 +412,6 @@ zeroW, | ||
if (w.globals.seriesGroups.length) { | ||
if (w.globals.barGroups.length) { | ||
x = | ||
(seriesVal - w.globals.minX) / this.xRatio - | ||
(barWidth / 2) * w.globals.seriesGroups.length | ||
(barWidth / 2) * w.globals.barGroups.length | ||
} | ||
@@ -430,3 +434,3 @@ } | ||
if (seriesGroup) { | ||
gsi = seriesGroup.indexOf(w.config.series[i].name) | ||
gsi = seriesGroup.indexOf(w.globals.seriesNames[i]) | ||
} | ||
@@ -491,3 +495,5 @@ if ( | ||
} else { | ||
// the first series will not have prevY values, also if the prev index's series X doesn't matches the current index's series X, then start from zero | ||
// the first series will not have prevY values, also if the prev index's | ||
// series X doesn't matches the current index's series X, then start from | ||
// zero | ||
barYPosition = zeroH | ||
@@ -494,0 +500,0 @@ } |
@@ -105,3 +105,3 @@ import CoreUtils from '../../../modules/CoreUtils' | ||
determineFirstPrevY({ i, series, prevY, lineYPosition, translationsIndex }) { | ||
determineFirstPrevY({ i, realIndex, series, prevY, lineYPosition, translationsIndex }) { | ||
let w = this.w | ||
@@ -113,3 +113,4 @@ let stackSeries = | ||
(!this.w.config.chart.stackOnlyBar || | ||
this.w.config.series[i]?.type === 'bar')) | ||
this.w.config.series[realIndex]?.type === 'bar' | ||
|| this.w.config.series[realIndex]?.type === 'column')) | ||
@@ -116,0 +117,0 @@ if (typeof series[i]?.[0] !== 'undefined') { |
@@ -99,2 +99,3 @@ import CoreUtils from '../modules/CoreUtils' | ||
i, | ||
realIndex, | ||
series, | ||
@@ -106,4 +107,5 @@ prevY, | ||
prevY = firstPrevY.prevY | ||
if (w.config.stroke.curve === 'monotonCubic' && series[i][0] === null) { | ||
// we have to discard the y position if 1st dataPoint is null as it causes issues with monotoneCubic path creation | ||
if (w.config.stroke.curve === 'monotoneCubic' && series[i][0] === null) { | ||
// we have to discard the y position if 1st dataPoint is null as it | ||
// causes issues with monotoneCubic path creation | ||
yArrj.push(null) | ||
@@ -121,2 +123,3 @@ } else { | ||
i, | ||
realIndex, | ||
series: seriesRangeEnd, | ||
@@ -129,3 +132,3 @@ prevY: prevY2, | ||
pY2 = prevY2 | ||
y2Arrj.push(prevY2) | ||
y2Arrj.push(yArrj[0] !== null ? prevY2 : null) | ||
} | ||
@@ -138,2 +141,3 @@ | ||
realIndex, | ||
translationsIndex, | ||
prevX, | ||
@@ -144,2 +148,6 @@ prevY, | ||
// RangeArea will resume with these for the upper path creation | ||
let rYArrj = [yArrj[0]] | ||
let rY2Arrj = [y2Arrj[0]] | ||
const iteratingOpts = { | ||
@@ -183,3 +191,7 @@ type, | ||
series: seriesRangeEnd, | ||
xArrj: [x], | ||
yArrj: rYArrj, | ||
y2Arrj: rY2Arrj, | ||
pY: pY2, | ||
areaPaths: paths.areaPaths, | ||
pathsFrom: pathsFrom2, | ||
@@ -190,3 +202,14 @@ iterations: seriesRangeEnd[i].length - 1, | ||
paths.linePaths[0] = rangePaths.linePath + paths.linePath | ||
// Path may be segmented by nulls in data. | ||
// paths.linePaths should hold (segments * 2) paths (upper and lower) | ||
// the first n segments belong to the lower and the last n segments | ||
// belong to the upper. | ||
// paths.linePaths and rangePaths.linepaths are actually equivalent | ||
// but we retain the distinction below for consistency with the | ||
// unsegmented paths conditional branch. | ||
let segments = paths.linePaths.length / 2 | ||
for (let s = 0; s < segments; s++) { | ||
paths.linePaths[s] = rangePaths.linePaths[s + segments] + paths.linePaths[s] | ||
} | ||
paths.linePaths.splice(segments) | ||
paths.pathFromLine = rangePaths.pathFromLine + paths.pathFromLine | ||
@@ -296,3 +319,3 @@ } | ||
_calculatePathsFrom({ type, series, i, realIndex, prevX, prevY, prevY2 }) { | ||
_calculatePathsFrom({ type, series, i, realIndex, translationsIndex, prevX, prevY, prevY2 }) { | ||
const w = this.w | ||
@@ -307,3 +330,3 @@ const graphics = new Graphics(this.ctx) | ||
prevX = this.xDivision * s | ||
prevY = this.zeroY - series[i][s] / this.yRatio[realIndex] | ||
prevY = this.zeroY - series[i][s] / this.yRatio[translationsIndex] | ||
linePath = graphics.move(prevX, prevY) | ||
@@ -546,4 +569,17 @@ areaPath = graphics.move(prevX, this.areaBottomY) | ||
(!this.w.config.chart.stackOnlyBar || | ||
this.w.config.series[realIndex]?.type === 'bar')) | ||
this.w.config.series[realIndex]?.type === 'bar' | ||
|| this.w.config.series[realIndex]?.type === 'column')) | ||
let curve = w.config.stroke.curve | ||
if (Array.isArray(curve)) { | ||
if (Array.isArray(seriesIndex)) { | ||
curve = curve[seriesIndex[i]] | ||
} else { | ||
curve = curve[i] | ||
} | ||
} | ||
let pathState = 0 | ||
let segmentStartX | ||
for (let j = 0; j < iterations; j++) { | ||
@@ -569,3 +605,5 @@ const isNull = | ||
) { | ||
// a collapsed series in a stacked bar chart may provide wrong result for the next series, hence find the prevIndex of prev series which is not collapsed - fixes apexcharts.js#1372 | ||
// a collapsed series in a stacked chart may provide wrong result | ||
// for the next series, hence find the prevIndex of prev series | ||
// which is not collapsed - fixes apexcharts.js#1372 | ||
const prevIndex = (pi) => { | ||
@@ -605,8 +643,12 @@ let pii = pi | ||
// push current Y that will be used as next series's bottom position | ||
if (isNull && w.config.stroke.curve === 'smooth') { | ||
if (isNull | ||
&& (w.config.stroke.curve === 'smooth' | ||
|| w.config.stroke.curve === 'monotoneCubic') | ||
) { | ||
yArrj.push(null) | ||
y2Arrj.push(null) | ||
} else { | ||
yArrj.push(y) | ||
y2Arrj.push(y2) | ||
} | ||
y2Arrj.push(y2) | ||
@@ -637,2 +679,4 @@ let pointsPos = this.lineHelpers.calculatePoints({ | ||
pY, | ||
pathState, | ||
segmentStartX, | ||
linePath, | ||
@@ -642,3 +686,3 @@ areaPath, | ||
areaPaths, | ||
seriesIndex, | ||
curve, | ||
isRangeStart, | ||
@@ -651,2 +695,4 @@ }) | ||
pY = calculatedPaths.pY | ||
pathState = calculatedPaths.pathState | ||
segmentStartX = calculatedPaths.segmentStartX | ||
areaPath = calculatedPaths.areaPath | ||
@@ -657,3 +703,3 @@ linePath = calculatedPaths.linePath | ||
this.appendPathFrom && | ||
!(w.config.stroke.curve === 'monotoneCubic' && type === 'rangeArea') | ||
!(curve === 'monotoneCubic' && type === 'rangeArea') | ||
) { | ||
@@ -741,2 +787,4 @@ pathFromLine = pathFromLine + graphics.line(x, this.zeroY) | ||
pY, | ||
pathState, | ||
segmentStartX, | ||
linePath, | ||
@@ -746,3 +794,3 @@ areaPath, | ||
areaPaths, | ||
seriesIndex, | ||
curve, | ||
isRangeStart, | ||
@@ -752,106 +800,206 @@ }) { | ||
let graphics = new Graphics(this.ctx) | ||
let curve = w.config.stroke.curve | ||
const areaBottomY = this.areaBottomY | ||
let rangeArea = type === 'rangeArea' | ||
let isLowerRangeAreaPath = (type === 'rangeArea' && isRangeStart) | ||
if (Array.isArray(w.config.stroke.curve)) { | ||
if (Array.isArray(seriesIndex)) { | ||
curve = w.config.stroke.curve[seriesIndex[i]] | ||
} else { | ||
curve = w.config.stroke.curve[i] | ||
switch (curve) { | ||
case 'monotoneCubic': | ||
let yAj = isRangeStart ? yArrj : y2Arrj | ||
let getSmoothInputs = (xArr, yArr) => { | ||
return xArr.map((_, i) => { | ||
return [_, yArr[i]] | ||
}) | ||
.filter((_) => _[1] !== null) | ||
} | ||
} | ||
if ( | ||
type === 'rangeArea' && | ||
(w.globals.hasNullValues || w.config.forecastDataPoints.count > 0) && | ||
curve === 'monotoneCubic' | ||
) { | ||
curve = 'straight' | ||
} | ||
if (curve === 'monotoneCubic') { | ||
const shouldRenderMonotone = | ||
type === 'rangeArea' | ||
? xArrj.length === w.globals.dataPoints | ||
: j === series[i].length - 2 | ||
const smoothInputs = xArrj | ||
.map((_, i) => { | ||
return [xArrj[i], yArrj[i]] | ||
let getSegmentLengths = (yArr) => { | ||
// Get the segment lengths so the segments can be extracted from | ||
// the null-filtered smoothInputs array | ||
let segLens = [] | ||
let count = 0 | ||
yArr.forEach((_) => { | ||
if (_ !== null) { | ||
count++ | ||
} else if (count > 0) { | ||
segLens.push(count) | ||
count = 0 | ||
} | ||
}) | ||
.filter((_) => _[1] !== null) | ||
if (count > 0) { | ||
segLens.push(count) | ||
} | ||
return segLens | ||
} | ||
let getSegments = (yArr, points) => { | ||
let segLens = getSegmentLengths(yArr) | ||
let segments = [] | ||
for (let i = 0, len = 0; i < segLens.length; len += segLens[i++]) { | ||
segments[i] = spline.slice(points, len, len + segLens[i]) | ||
} | ||
return segments | ||
} | ||
if (shouldRenderMonotone && smoothInputs.length > 1) { | ||
const points = spline.points(smoothInputs) | ||
linePath += svgPath(points) | ||
if (series[i][0] === null) { | ||
// if the first dataPoint is null, we use the linePath directly | ||
areaPath = linePath | ||
} else { | ||
// else, we append the areaPath | ||
areaPath += svgPath(points) | ||
switch (pathState) { | ||
case 0: | ||
// Find start of segment | ||
if (yAj[j + 1] === null) { | ||
break | ||
} | ||
pathState = 1 | ||
// continue through to pathState 1 | ||
case 1: | ||
if (!(rangeArea | ||
? xArrj.length === series[i].length | ||
: (j === series[i].length - 2)) | ||
) { | ||
break | ||
} | ||
// continue through to pathState 2 | ||
case 2: | ||
// Interpolate the full series with nulls excluded then extract the | ||
// null delimited segments with interpolated points included. | ||
const _xAj = isRangeStart ? xArrj : xArrj.slice().reverse() | ||
const _yAj = isRangeStart ? yAj : yAj.slice().reverse() | ||
if (type === 'rangeArea' && isRangeStart) { | ||
// draw the line to connect y with y2; then draw the other end of range | ||
linePath += graphics.line( | ||
xArrj[xArrj.length - 1], | ||
y2Arrj[y2Arrj.length - 1] | ||
) | ||
const smoothInputs = getSmoothInputs(_xAj, _yAj) | ||
const points = smoothInputs.length > 1 | ||
? spline.points(smoothInputs) | ||
: smoothInputs | ||
const xArrjInversed = xArrj.slice().reverse() | ||
const y2ArrjInversed = y2Arrj.slice().reverse() | ||
const smoothInputsY2 = xArrjInversed.map((_, i) => { | ||
return [xArrjInversed[i], y2ArrjInversed[i]] | ||
}) | ||
let smoothInputsLower = [] | ||
if (rangeArea) { | ||
if (isLowerRangeAreaPath) { | ||
// As we won't be needing it, borrow areaPaths to retain our | ||
// rangeArea lower points. | ||
areaPaths = smoothInputs | ||
} else { | ||
// Retrieve the corresponding lower raw interpolated points so we | ||
// can join onto its end points. Note: the upper Y2 segments will | ||
// be in the reverse order relative to the lower segments. | ||
smoothInputsLower = areaPaths.reverse() | ||
} | ||
} | ||
const pointsY2 = spline.points(smoothInputsY2) | ||
let segmentCount = 0 | ||
let smoothInputsIndex = 0 | ||
getSegments(_yAj, points).forEach((_) => { | ||
segmentCount++ | ||
let svgPoints = svgPath(_) | ||
let _start = smoothInputsIndex | ||
smoothInputsIndex += _.length | ||
let _end = smoothInputsIndex - 1 | ||
if (isLowerRangeAreaPath) { | ||
linePath = | ||
graphics.move( | ||
smoothInputs[_start][0], | ||
smoothInputs[_start][1] | ||
) | ||
+ svgPoints | ||
} else if (rangeArea) { | ||
linePath = | ||
graphics.move( | ||
smoothInputsLower[_start][0], | ||
smoothInputsLower[_start][1] | ||
) | ||
+ graphics.line( | ||
smoothInputs[_start][0], | ||
smoothInputs[_start][1] | ||
) | ||
+ svgPoints | ||
+ graphics.line( | ||
smoothInputsLower[_end][0], | ||
smoothInputsLower[_end][1] | ||
) | ||
} else { | ||
linePath = | ||
graphics.move( | ||
smoothInputs[_start][0], | ||
smoothInputs[_start][1] | ||
) | ||
+ svgPoints | ||
areaPath = | ||
linePath | ||
+ graphics.line(smoothInputs[_end][0], areaBottomY) | ||
+ graphics.line(smoothInputs[_start][0], areaBottomY) | ||
+ 'z' | ||
areaPaths.push(areaPath) | ||
} | ||
linePaths.push(linePath) | ||
}) | ||
linePath += svgPath(pointsY2) | ||
// in range area, we don't have separate line and area path | ||
areaPath = linePath | ||
} else { | ||
areaPath += | ||
graphics.line( | ||
smoothInputs[smoothInputs.length - 1][0], | ||
areaBottomY | ||
) + | ||
graphics.line(smoothInputs[0][0], areaBottomY) + | ||
graphics.move(smoothInputs[0][0], smoothInputs[0][1]) + | ||
'z' | ||
if (rangeArea && segmentCount > 1 && !isLowerRangeAreaPath) { | ||
// Reverse the order of the upper path segments | ||
let upperLinePaths = linePaths.slice(segmentCount).reverse() | ||
linePaths.splice(segmentCount) | ||
upperLinePaths.forEach((u) => linePaths.push(u)) | ||
} | ||
linePaths.push(linePath) | ||
areaPaths.push(areaPath) | ||
pathState = 0 | ||
break | ||
} | ||
} else if (curve === 'smooth') { | ||
break | ||
case 'smooth': | ||
let length = (x - pX) * 0.35 | ||
if (w.globals.hasNullValues) { | ||
if (series[i][j] !== null) { | ||
if (series[i][j + 1] !== null) { | ||
linePath = | ||
graphics.move(pX, pY) + | ||
graphics.curve(pX + length, pY, x - length, y, x + 1, y) | ||
areaPath = | ||
graphics.move(pX + 1, pY) + | ||
graphics.curve(pX + length, pY, x - length, y, x + 1, y) + | ||
graphics.line(x, areaBottomY) + | ||
graphics.line(pX, areaBottomY) + | ||
'z' | ||
if (series[i][j] === null) { | ||
pathState = 0 | ||
} else { | ||
switch (pathState) { | ||
case 0: | ||
// Beginning of segment | ||
segmentStartX = pX | ||
if (isLowerRangeAreaPath) { | ||
// Need to add path portion that will join to the upper path | ||
linePath = | ||
graphics.move(pX, y2Arrj[j]) | ||
+ graphics.line(pX, pY) | ||
} else { | ||
linePath = graphics.move(pX, pY) | ||
} | ||
areaPath = graphics.move(pX, pY) | ||
pathState = 1 | ||
if (j < series[i].length - 2) { | ||
let p = graphics.curve(pX + length, pY, x - length, y, x, y) | ||
linePath += p | ||
areaPath += p | ||
break | ||
} | ||
// Continue on with pathState 1 to finish the path and exit | ||
case 1: | ||
// Continuing with segment | ||
if (series[i][j + 1] === null) { | ||
// Segment ends here | ||
if (isLowerRangeAreaPath) { | ||
linePath += graphics.line(pX, y2) | ||
} else { | ||
linePath += graphics.move(pX, pY) | ||
} | ||
areaPath += | ||
graphics.line(pX, areaBottomY) | ||
+ graphics.line(segmentStartX, areaBottomY) | ||
+ 'z' | ||
linePaths.push(linePath) | ||
areaPaths.push(areaPath) | ||
} else { | ||
linePath = graphics.move(pX, pY) | ||
areaPath = graphics.move(pX, pY) + 'z' | ||
let p = graphics.curve(pX + length, pY, x - length, y, x, y) | ||
linePath += p | ||
areaPath += p | ||
if (j >= series[i].length - 2) { | ||
if (isLowerRangeAreaPath) { | ||
// Need to add path portion that will join to the upper path | ||
linePath += | ||
graphics.curve(x, y, x, y, x, y2) | ||
+ graphics.move(x, y2) | ||
} else { | ||
linePath += | ||
graphics.move(x, y) | ||
} | ||
areaPath += | ||
graphics.curve(x, y, x, y, x, areaBottomY) | ||
+ graphics.line(segmentStartX, areaBottomY) | ||
+ 'z' | ||
linePaths.push(linePath) | ||
areaPaths.push(areaPath) | ||
} | ||
} | ||
break | ||
} | ||
linePaths.push(linePath) | ||
areaPaths.push(areaPath) | ||
} else { | ||
linePath = | ||
linePath + graphics.curve(pX + length, pY, x - length, y, x, y) | ||
areaPath = | ||
areaPath + graphics.curve(pX + length, pY, x - length, y, x, y) | ||
} | ||
@@ -862,69 +1010,86 @@ | ||
if (j === series[i].length - 2) { | ||
// last loop, close path | ||
areaPath = | ||
areaPath + | ||
graphics.curve(pX, pY, x, y, x, areaBottomY) + | ||
graphics.move(x, y) + | ||
'z' | ||
break | ||
default: | ||
let pathToPoint = (curve, x, y) => { | ||
let path = [] | ||
switch (curve) { | ||
case 'stepline': | ||
path = graphics.line(x, null, 'H') + graphics.line(null, y, 'V') | ||
break | ||
case 'linestep': | ||
path = graphics.line(null, y, 'V') + graphics.line(x, null, 'H') | ||
break | ||
case 'straight': | ||
path = graphics.line(x, y) | ||
break | ||
} | ||
return path | ||
} | ||
if (series[i][j] === null) { | ||
pathState = 0 | ||
} else { | ||
switch (pathState) { | ||
case 0: | ||
// Beginning of segment | ||
segmentStartX = pX | ||
if (isLowerRangeAreaPath) { | ||
// Need to add path portion that will join to the upper path | ||
linePath = | ||
graphics.move(pX, y2Arrj[j]) | ||
+ graphics.line(pX, pY) | ||
} else { | ||
linePath = graphics.move(pX, pY) | ||
} | ||
areaPath = graphics.move(pX, pY) | ||
if (type === 'rangeArea' && isRangeStart) { | ||
linePath = | ||
linePath + | ||
graphics.curve(pX, pY, x, y, x, y2) + | ||
graphics.move(x, y2) + | ||
'z' | ||
} else { | ||
if (!w.globals.hasNullValues) { | ||
pathState = 1 | ||
if (j < series[i].length - 2) { | ||
let p = pathToPoint(curve, x, y) | ||
linePath += p | ||
areaPath += p | ||
break | ||
} | ||
// Continue on with pathState 1 to finish the path and exit | ||
case 1: | ||
// Continuing with segment | ||
if (series[i][j + 1] === null) { | ||
// Segment ends here | ||
if (isLowerRangeAreaPath) { | ||
linePath += graphics.line(pX, y2) | ||
} else { | ||
linePath += graphics.move(pX, pY) | ||
} | ||
areaPath += | ||
graphics.line(pX, areaBottomY) | ||
+ graphics.line(segmentStartX, areaBottomY) | ||
+ 'z' | ||
linePaths.push(linePath) | ||
areaPaths.push(areaPath) | ||
} else { | ||
let p = pathToPoint(curve, x, y) | ||
linePath += p | ||
areaPath += p | ||
if (j >= series[i].length - 2) { | ||
if (isLowerRangeAreaPath) { | ||
// Need to add path portion that will join to the upper path | ||
linePath += graphics.line(x, y2) | ||
} else { | ||
linePath += graphics.move(x, y) | ||
} | ||
areaPath += | ||
graphics.line(x, areaBottomY) | ||
+ graphics.line(segmentStartX, areaBottomY) | ||
+ 'z' | ||
linePaths.push(linePath) | ||
areaPaths.push(areaPath) | ||
} | ||
} | ||
break | ||
} | ||
} | ||
} else { | ||
if (series[i][j + 1] === null) { | ||
linePath = linePath + graphics.move(x, y) | ||
const numericOrCatX = w.globals.isXNumeric | ||
? (w.globals.seriesX[realIndex][j] - w.globals.minX) / this.xRatio | ||
: x - this.xDivision | ||
areaPath = | ||
areaPath + | ||
graphics.line(numericOrCatX, areaBottomY) + | ||
graphics.move(x, y) + | ||
'z' | ||
} | ||
if (series[i][j] === null) { | ||
linePath = linePath + graphics.move(x, y) | ||
areaPath = areaPath + graphics.move(x, areaBottomY) | ||
} | ||
pX = x | ||
pY = y | ||
if (curve === 'stepline') { | ||
linePath = | ||
linePath + graphics.line(x, null, 'H') + graphics.line(null, y, 'V') | ||
areaPath = | ||
areaPath + graphics.line(x, null, 'H') + graphics.line(null, y, 'V') | ||
} else if (curve === 'linestep') { | ||
linePath = | ||
linePath + graphics.line(null, y, 'V') + graphics.line(x, null, 'H') | ||
areaPath = | ||
areaPath + graphics.line(null, y, 'V') + graphics.line(x, null, 'H') | ||
} else if (curve === 'straight') { | ||
linePath = linePath + graphics.line(x, y) | ||
areaPath = areaPath + graphics.line(x, y) | ||
} | ||
if (j === series[i].length - 2) { | ||
// last loop, close path | ||
areaPath = | ||
areaPath + graphics.line(x, areaBottomY) + graphics.move(x, y) + 'z' | ||
if (type === 'rangeArea' && isRangeStart) { | ||
linePath = | ||
linePath + graphics.line(x, y2) + graphics.move(x, y2) + 'z' | ||
} else { | ||
linePaths.push(linePath) | ||
areaPaths.push(areaPath) | ||
} | ||
} | ||
break | ||
} | ||
@@ -937,2 +1102,4 @@ | ||
pY, | ||
pathState, | ||
segmentStartX, | ||
linePath, | ||
@@ -949,2 +1116,4 @@ areaPath, | ||
) { | ||
let pSize = this.strokeWidth - w.config.markers.strokeWidth / 2 | ||
if (!(pSize > 0)) {pSize = 0} | ||
// fixes apexcharts.js#1282, #1252 | ||
@@ -955,3 +1124,3 @@ let elPointsWrap = this.markers.plotChartMarkers( | ||
j + 1, | ||
this.strokeWidth - w.config.markers.strokeWidth / 2, | ||
pSize, | ||
true | ||
@@ -958,0 +1127,0 @@ ) |
@@ -94,3 +94,3 @@ import Fill from '../modules/Fill' | ||
class: 'apexcharts-radar-series apexcharts-plot-series', | ||
transform: `translate(${translateX || 0}, ${translateY || 0})` | ||
transform: `translate(${translateX || 0}, ${translateY || 0})`, | ||
}) | ||
@@ -103,3 +103,3 @@ | ||
this.yaxisLabels = this.graphics.group({ | ||
class: 'apexcharts-yaxis' | ||
class: 'apexcharts-yaxis', | ||
}) | ||
@@ -116,3 +116,3 @@ | ||
rel: i + 1, | ||
'data:realIndex': i | ||
'data:realIndex': i, | ||
}) | ||
@@ -126,3 +126,3 @@ | ||
const range = Math.abs(this.maxValue - this.minValue) | ||
dv = dv + Math.abs(this.minValue) | ||
dv = dv - this.minValue | ||
@@ -145,3 +145,3 @@ if (this.isLog) { | ||
x: 0, | ||
y: 0 | ||
y: 0, | ||
}) | ||
@@ -151,3 +151,3 @@ | ||
elPointsMain = this.graphics.group({ | ||
class: 'apexcharts-series-markers-wrap apexcharts-element-hidden' | ||
class: 'apexcharts-series-markers-wrap apexcharts-element-hidden', | ||
}) | ||
@@ -158,3 +158,3 @@ | ||
class: `apexcharts-datalabels`, | ||
'data:realIndex': i | ||
'data:realIndex': i, | ||
}) | ||
@@ -164,3 +164,3 @@ | ||
el: elPointsMain.node, | ||
index: i | ||
index: i, | ||
}) | ||
@@ -178,3 +178,3 @@ | ||
stroke: w.globals.stroke.colors[i], | ||
strokeLineCap: w.config.stroke.lineCap | ||
strokeLineCap: w.config.stroke.lineCap, | ||
} | ||
@@ -197,3 +197,3 @@ | ||
fill: 'none', | ||
drawShadow: false | ||
drawShadow: false, | ||
}) | ||
@@ -204,3 +204,3 @@ | ||
let pathFill = fill.fillPath({ | ||
seriesNumber: i | ||
seriesNumber: i, | ||
}) | ||
@@ -214,3 +214,3 @@ | ||
fill: pathFill, | ||
drawShadow: false | ||
drawShadow: false, | ||
}) | ||
@@ -238,3 +238,3 @@ | ||
seriesIndex: i, | ||
dataPointIndex: j | ||
dataPointIndex: j, | ||
}) | ||
@@ -254,3 +254,3 @@ | ||
let elPointsWrap = this.graphics.group({ | ||
class: 'apexcharts-series-markers' | ||
class: 'apexcharts-series-markers', | ||
}) | ||
@@ -272,3 +272,3 @@ | ||
dataPointIndex: j, | ||
w | ||
w, | ||
}) | ||
@@ -286,4 +286,4 @@ | ||
dataLabelsConfig: { | ||
...dataLabelsConfig | ||
} | ||
...dataLabelsConfig, | ||
}, | ||
}) | ||
@@ -298,3 +298,3 @@ } | ||
this.drawPolygons({ | ||
parent: ret | ||
parent: ret, | ||
}) | ||
@@ -356,3 +356,3 @@ | ||
x: p.x, | ||
y: p.y | ||
y: p.y, | ||
}) | ||
@@ -396,3 +396,3 @@ } | ||
let elXAxisWrap = this.graphics.group({ | ||
class: 'apexcharts-xaxis' | ||
class: 'apexcharts-xaxis', | ||
}) | ||
@@ -412,3 +412,3 @@ | ||
dataPointIndex: i, | ||
w | ||
w, | ||
}) | ||
@@ -432,5 +432,5 @@ | ||
dropShadow: { enabled: false }, | ||
...xaxisLabelsConfig | ||
...xaxisLabelsConfig, | ||
}, | ||
offsetCorrection: false | ||
offsetCorrection: false, | ||
}) | ||
@@ -473,3 +473,3 @@ } | ||
areaPathsFrom, | ||
areaPathsTo | ||
areaPathsTo, | ||
} | ||
@@ -507,3 +507,3 @@ } | ||
newX, | ||
newY | ||
newY, | ||
} | ||
@@ -510,0 +510,0 @@ } |
@@ -140,3 +140,3 @@ /** | ||
// Add additional 'C' points | ||
if (pts[1].length < 6) { | ||
if (end - start > 1 && pts[1].length < 6) { | ||
const n = pts[0].length | ||
@@ -143,0 +143,0 @@ |
@@ -46,3 +46,3 @@ { | ||
"exportToCSV": "下載 CSV", | ||
"menu": "菜單", | ||
"menu": "選單", | ||
"selection": "選擇", | ||
@@ -49,0 +49,0 @@ "selectionZoom": "選擇縮放", |
@@ -14,2 +14,6 @@ import Utils from '../../utils/Utils' | ||
if (w.globals.collapsedSeriesIndices.indexOf(anno.seriesIndex) > -1) { | ||
return | ||
} | ||
let result = this.helpers.getX1X2('x1', anno) | ||
@@ -16,0 +20,0 @@ let x = result.x |
@@ -122,3 +122,3 @@ import Helpers from './Helpers' | ||
drawYAxisAnnotations() { | ||
let w = this.w | ||
const w = this.w | ||
@@ -130,6 +130,9 @@ let elg = this.annoCtx.graphics.group({ | ||
w.config.annotations.yaxis.forEach((anno, index) => { | ||
let seriesIndex = w.globals.seriesYAxisMap[anno.yAxisIndex][0] | ||
if (!this.axesUtils.isYAxisHidden(anno.yAxisIndex)) { | ||
this.addYaxisAnnotation(anno, elg.node, index) | ||
} | ||
anno.yAxisIndex = this.axesUtils.translateYAxisIndex(anno.yAxisIndex) | ||
if ( | ||
!(this.axesUtils.isYAxisHidden(anno.yAxisIndex) | ||
&& this.axesUtils.yAxisAllSeriesCollapsed(anno.yAxisIndex)) | ||
) { | ||
this.addYaxisAnnotation(anno, elg.node, index) | ||
} | ||
}) | ||
@@ -136,0 +139,0 @@ |
@@ -179,16 +179,42 @@ import Formatters from '../Formatters' | ||
yAxisAllSeriesCollapsed(index) { | ||
const gl = this.w.globals | ||
return !gl.seriesYAxisMap[index].some((si) => { | ||
return gl.collapsedSeriesIndices.indexOf(si) === -1 | ||
}) | ||
} | ||
// Method to translate annotation.yAxisIndex values from | ||
// seriesName-as-a-string values to seriesName-as-an-array values (old style | ||
// series mapping to new style). | ||
translateYAxisIndex(index) { | ||
const w = this.w | ||
const gl = w.globals | ||
const yaxis = w.config.yaxis | ||
let newStyle = | ||
gl.series.length > yaxis.length | ||
|| yaxis.some((a) => Array.isArray(a.seriesName)) | ||
if (newStyle) { | ||
return index | ||
} else { | ||
return gl.seriesYAxisReverseMap[index] | ||
} | ||
} | ||
isYAxisHidden(index) { | ||
const w = this.w | ||
const coreUtils = new CoreUtils(this.ctx) | ||
let allCollapsed = !w.globals.seriesYAxisMap[index].some((si) => { | ||
return w.globals.collapsedSeriesIndices.indexOf(si) === -1 | ||
}) | ||
const yaxis = w.config.yaxis[index] | ||
return ( | ||
allCollapsed || | ||
!w.config.yaxis[index].show || | ||
(!w.config.yaxis[index].showForNullSeries && | ||
coreUtils.isSeriesNull(index)) | ||
) | ||
if (!yaxis.show || this.yAxisAllSeriesCollapsed(index) | ||
) { | ||
return true | ||
} | ||
if (!yaxis.showForNullSeries) { | ||
const seriesIndices = w.globals.seriesYAxisMap[index] | ||
const coreUtils = new CoreUtils(this.ctx) | ||
return seriesIndices.every((si) => coreUtils.isSeriesNull(si)) | ||
} | ||
return false | ||
} | ||
@@ -195,0 +221,0 @@ |
@@ -412,2 +412,3 @@ import Graphics from '../Graphics' | ||
let w = this.w | ||
const gl = w.globals | ||
let graphics = new Graphics(this.ctx) | ||
@@ -438,19 +439,19 @@ | ||
// Draw the grid using ticks from the first unhidden Yaxis, | ||
// or yaxis[0] is all hidden. | ||
// or yaxis[0] if all are hidden. | ||
let gridAxisIndex = 0 | ||
while ( | ||
gridAxisIndex < w.globals.seriesYAxisMap.length && | ||
w.globals.ignoreYAxisIndexes.indexOf(gridAxisIndex) !== -1 | ||
gridAxisIndex < gl.seriesYAxisMap.length | ||
&& gl.ignoreYAxisIndexes.indexOf(gridAxisIndex) !== -1 | ||
) { | ||
gridAxisIndex++ | ||
} | ||
if (gridAxisIndex === w.globals.seriesYAxisMap.length) { | ||
if (gridAxisIndex === gl.seriesYAxisMap.length) { | ||
gridAxisIndex = 0 | ||
} | ||
let yTickAmount = w.globals.yAxisScale[gridAxisIndex].result.length - 1 | ||
let yTickAmount = gl.yAxisScale[gridAxisIndex].result.length - 1 | ||
let xCount | ||
if (!w.globals.isBarHorizontal || this.isRangeBar) { | ||
if (!gl.isBarHorizontal || this.isRangeBar) { | ||
xCount = this.xaxisLabels.length | ||
@@ -460,3 +461,3 @@ | ||
xCount-- | ||
yTickAmount = w.globals.labels.length | ||
yTickAmount = gl.labels.length | ||
if (w.config.xaxis.tickAmount && w.config.xaxis.labels.formatter) { | ||
@@ -466,6 +467,6 @@ xCount = w.config.xaxis.tickAmount | ||
if ( | ||
w.globals.yAxisScale?.[gridAxisIndex]?.result?.length > 0 && | ||
gl.yAxisScale?.[gridAxisIndex]?.result?.length > 0 && | ||
w.config.xaxis.type !== 'datetime' | ||
) { | ||
xCount = w.globals.yAxisScale[gridAxisIndex].result.length - 1 | ||
xCount = gl.yAxisScale[gridAxisIndex].result.length - 1 | ||
} | ||
@@ -482,3 +483,3 @@ } | ||
// for horizontal bar chart, get the xaxis tickamount | ||
yTickAmount = w.globals.xTickAmount | ||
yTickAmount = gl.xTickAmount | ||
this._drawInvertedXYLines({ xCount, tickAmount: yTickAmount }) | ||
@@ -491,3 +492,3 @@ } | ||
elGridBorders: this.elGridBorders, | ||
xAxisTickWidth: w.globals.gridWidth / xCount, | ||
xAxisTickWidth: gl.gridWidth / xCount, | ||
} | ||
@@ -494,0 +495,0 @@ } |
@@ -193,14 +193,14 @@ import Bar from '../charts/Bar' | ||
if (ser[st].type === 'column' || ser[st].type === 'bar') { | ||
if (gl.series.length > 1 && cnf.plotOptions.bar.horizontal) { | ||
// horizontal bars not supported in mixed charts, hence show a warning | ||
console.warn( | ||
'Horizontal bars are not supported in a mixed/combo chart. Please turn off `plotOptions.bar.horizontal`' | ||
) | ||
} | ||
columnSeries.series.push(serie) | ||
columnSeries.i.push(st) | ||
w.globals.columnSeries = columnSeries.series | ||
if (chartType !== 'bar') { | ||
if (gl.series.length > 1 && cnf.plotOptions.bar.horizontal) { | ||
// horizontal bars not supported in mixed charts, hence show a warning | ||
console.warn( | ||
'Horizontal bars are not supported in a mixed/combo chart. Please turn off `plotOptions.bar.horizontal`' | ||
) | ||
} | ||
comboCount++ | ||
} | ||
w.globals.columnSeries = columnSeries.series | ||
} else if (ser[st].type === 'area') { | ||
@@ -207,0 +207,0 @@ areaSeries.series.push(serie) |
@@ -105,3 +105,3 @@ /* | ||
w.config.series.forEach((s, si) => { | ||
if (sg.indexOf(s.name) > -1) { | ||
if (sg.indexOf(w.globals.seriesNames[si]) > -1) { | ||
includedIndexes.push(si) | ||
@@ -108,0 +108,0 @@ } |
@@ -407,2 +407,10 @@ import CoreUtils from './CoreUtils' | ||
ser.forEach((s, i) => { | ||
if (s.name !== undefined) { | ||
gl.seriesNames.push(s.name) | ||
} else { | ||
gl.seriesNames.push('series-' + parseInt(i + 1, 10)) | ||
} | ||
}) | ||
gl.hasSeriesGroups = ser[0]?.group | ||
@@ -416,3 +424,3 @@ if (gl.hasSeriesGroups) { | ||
buckets[index].push(s.name) | ||
buckets[index].push(gl.seriesNames[i]) | ||
}) | ||
@@ -513,8 +521,2 @@ gl.seriesGroups = buckets | ||
if (ser[i].name !== undefined) { | ||
gl.seriesNames.push(ser[i].name) | ||
} else { | ||
gl.seriesNames.push('series-' + parseInt(i + 1, 10)) | ||
} | ||
// overrided default color if user inputs color with series data | ||
@@ -721,3 +723,2 @@ if (ser[i].color !== undefined) { | ||
const w = this.w | ||
// fix issue #1215 | ||
// Post revision 3.46.0 there is no longer a strict one-to-one | ||
@@ -724,0 +725,0 @@ // correspondence between series and Y axes. |
@@ -44,2 +44,6 @@ import YAxis from '../axes/YAxis' | ||
const maxStrokeWidth = Array.isArray(w.config.stroke.width) | ||
? Math.max(...w.config.stroke.width) | ||
: w.config.stroke.width | ||
if (this.isSparkline) { | ||
@@ -55,7 +59,4 @@ if (w.config.markers.discrete.length > 0 || w.config.markers.size > 0) { | ||
this.gridPad.top = Math.max(w.config.stroke.width / 2, this.gridPad.top) | ||
this.gridPad.bottom = Math.max( | ||
w.config.stroke.width / 2, | ||
this.gridPad.bottom | ||
) | ||
this.gridPad.top = Math.max(maxStrokeWidth / 2, this.gridPad.top) | ||
this.gridPad.bottom = Math.max(maxStrokeWidth / 2, this.gridPad.bottom) | ||
} | ||
@@ -62,0 +63,0 @@ |
@@ -11,4 +11,9 @@ import AxesUtils from '../axes/AxesUtils' | ||
const w = this.w | ||
const cnf = w.config | ||
const gl = w.globals | ||
if (w.globals.noData || w.globals.allSeriesCollapsed) { | ||
if (gl.noData | ||
|| (gl.collapsedSeries.length | ||
+ gl.ancillaryCollapsedSeries.length) === cnf.series.length | ||
) { | ||
return 0 | ||
@@ -26,11 +31,11 @@ } | ||
const type = w.config.chart.type | ||
const type = cnf.chart.type | ||
let barWidth = 0 | ||
let seriesLen = hasBar(type) ? w.config.series.length : 1 | ||
let seriesLen = hasBar(type) ? cnf.series.length : 1 | ||
if (w.globals.comboBarCount > 0) { | ||
seriesLen = w.globals.comboBarCount | ||
if (gl.comboBarCount > 0) { | ||
seriesLen = gl.comboBarCount | ||
} | ||
w.globals.collapsedSeries.forEach((c) => { | ||
gl.collapsedSeries.forEach((c) => { | ||
if (hasBar(c.type)) { | ||
@@ -40,19 +45,19 @@ seriesLen = seriesLen - 1 | ||
}) | ||
if (w.config.chart.stacked) { | ||
if (cnf.chart.stacked) { | ||
seriesLen = 1 | ||
} | ||
const barsPresent = hasBar(type) || w.globals.comboBarCount > 0 | ||
const barsPresent = hasBar(type) || gl.comboBarCount > 0 | ||
if ( | ||
barsPresent && | ||
w.globals.isXNumeric && | ||
!w.globals.isBarHorizontal && | ||
gl.isXNumeric && | ||
!gl.isBarHorizontal && | ||
seriesLen > 0 | ||
) { | ||
let xRatio = 0 | ||
let xRange = Math.abs(w.globals.initialMaxX - w.globals.initialMinX) | ||
let xRange = Math.abs(gl.initialMaxX - gl.initialMinX) | ||
if (xRange <= 3) { | ||
xRange = w.globals.dataPoints | ||
xRange = gl.dataPoints | ||
} | ||
@@ -64,4 +69,4 @@ | ||
// max barwidth should be equal to minXDiff to avoid overlap | ||
if (w.globals.minXDiff && w.globals.minXDiff / xRatio > 0) { | ||
xDivision = w.globals.minXDiff / xRatio | ||
if (gl.minXDiff && gl.minXDiff / xRatio > 0) { | ||
xDivision = gl.minXDiff / xRatio | ||
} | ||
@@ -81,3 +86,3 @@ | ||
barWidth = | ||
(xDivision * parseInt(w.config.plotOptions.bar.columnWidth, 10)) / 100 | ||
(xDivision * parseInt(cnf.plotOptions.bar.columnWidth, 10)) / 100 | ||
@@ -88,3 +93,3 @@ if (barWidth < 1) { | ||
w.globals.barPadForNumericAxis = barWidth | ||
gl.barPadForNumericAxis = barWidth | ||
} | ||
@@ -91,0 +96,0 @@ return barWidth |
@@ -259,2 +259,6 @@ import Data from '../modules/Data' | ||
// let the caller know the current category is null. this can happen for example | ||
// when dealing with line charts having inconsistent time series data | ||
if (cat === null) return 'nullvalue' | ||
if (Array.isArray(cat)) { | ||
@@ -286,2 +290,6 @@ cat = cat.join(' ') | ||
let cat = getCat(i) | ||
// current category is null, let's move on to the next one | ||
if (cat === 'nullvalue') continue | ||
if (!cat) { | ||
@@ -288,0 +296,0 @@ if (dataFormat.isFormatXY()) { |
@@ -170,7 +170,8 @@ import Graphics from '../Graphics' | ||
const w = this.w | ||
const gl = w.globals | ||
let series = Utils.clone(w.config.series) | ||
if (w.globals.axisCharts) { | ||
let yaxis = w.config.yaxis[w.globals.seriesYAxisReverseMap[realIndex]] | ||
if (gl.axisCharts) { | ||
let yaxis = w.config.yaxis[gl.seriesYAxisReverseMap[realIndex]] | ||
@@ -182,4 +183,4 @@ if ( | ||
) { | ||
if (w.globals.ancillaryCollapsedSeriesIndices.indexOf(realIndex) < 0) { | ||
w.globals.ancillaryCollapsedSeries.push({ | ||
if (gl.ancillaryCollapsedSeriesIndices.indexOf(realIndex) < 0) { | ||
gl.ancillaryCollapsedSeries.push({ | ||
index: realIndex, | ||
@@ -189,7 +190,7 @@ data: series[realIndex].data.slice(), | ||
}) | ||
w.globals.ancillaryCollapsedSeriesIndices.push(realIndex) | ||
gl.ancillaryCollapsedSeriesIndices.push(realIndex) | ||
} | ||
} else { | ||
if (w.globals.collapsedSeriesIndices.indexOf(realIndex) < 0) { | ||
w.globals.collapsedSeries.push({ | ||
if (gl.collapsedSeriesIndices.indexOf(realIndex) < 0) { | ||
gl.collapsedSeries.push({ | ||
index: realIndex, | ||
@@ -199,14 +200,14 @@ data: series[realIndex].data.slice(), | ||
}) | ||
w.globals.collapsedSeriesIndices.push(realIndex) | ||
gl.collapsedSeriesIndices.push(realIndex) | ||
let removeIndexOfRising = w.globals.risingSeries.indexOf(realIndex) | ||
w.globals.risingSeries.splice(removeIndexOfRising, 1) | ||
let removeIndexOfRising = gl.risingSeries.indexOf(realIndex) | ||
gl.risingSeries.splice(removeIndexOfRising, 1) | ||
} | ||
} | ||
} else { | ||
w.globals.collapsedSeries.push({ | ||
gl.collapsedSeries.push({ | ||
index: realIndex, | ||
data: series[realIndex] | ||
}) | ||
w.globals.collapsedSeriesIndices.push(realIndex) | ||
gl.collapsedSeriesIndices.push(realIndex) | ||
} | ||
@@ -227,4 +228,5 @@ | ||
w.globals.allSeriesCollapsed = | ||
w.globals.collapsedSeries.length === w.config.series.length | ||
gl.allSeriesCollapsed = | ||
(gl.collapsedSeries.length | ||
+ gl.ancillaryCollapsedSeries.length) === w.config.series.length | ||
@@ -270,7 +272,12 @@ series = this._getSeriesBasedOnCollapsedState(series) | ||
const w = this.w | ||
let collapsed = 0 | ||
if (w.globals.axisCharts) { | ||
series.forEach((s, sI) => { | ||
if (w.globals.collapsedSeriesIndices.indexOf(sI) > -1) { | ||
if ( | ||
!(w.globals.collapsedSeriesIndices.indexOf(sI) < 0 | ||
&& w.globals.ancillaryCollapsedSeriesIndices.indexOf(sI) < 0) | ||
) { | ||
series[sI].data = [] | ||
collapsed++ | ||
} | ||
@@ -280,7 +287,10 @@ }) | ||
series.forEach((s, sI) => { | ||
if (w.globals.collapsedSeriesIndices.indexOf(sI) > -1) { | ||
if (!w.globals.collapsedSeriesIndices.indexOf(sI) < 0) { | ||
series[sI] = 0 | ||
collapsed++ | ||
} | ||
}) | ||
} | ||
w.globals.allSeriesCollapsed = collapsed === series.length | ||
@@ -287,0 +297,0 @@ return series |
@@ -132,2 +132,3 @@ import Utils from '../utils/Utils' | ||
} | ||
break | ||
case 'boxPlot': { | ||
@@ -139,2 +140,3 @@ if (typeof gl.seriesCandleC[i][j] !== 'undefined') { | ||
} | ||
break | ||
} | ||
@@ -332,5 +334,15 @@ | ||
if (gl.isMultipleYAxis) { | ||
this.scales.setMultipleYScales() | ||
this.scales.scaleMultipleYAxes() | ||
gl.minY = lowestYInAllSeries | ||
} else { | ||
gl.barGroups = [] | ||
cnf.series.forEach((s) => { | ||
if ((!s.type && cnf.chart.type === 'bar') | ||
|| s.type === 'bar' | ||
|| s.type === 'column' | ||
) { | ||
gl.barGroups.push(s.group ? s.group : 'axis-0') | ||
} | ||
}) | ||
gl.barGroups = gl.barGroups.filter((v,i,a) => a.indexOf(v) === i) | ||
this.scales.setYScaleForIndex(0, gl.minY, gl.maxY) | ||
@@ -589,3 +601,3 @@ gl.minY = gl.yAxisScale[0].niceMin | ||
if (!seriesGroups.length) { | ||
seriesGroups = [this.w.config.series.map((serie) => serie.name)] | ||
seriesGroups = [this.w.globals.seriesNames.map((name) => name)] | ||
} | ||
@@ -599,3 +611,3 @@ let stackedPoss = {} | ||
const indicesOfSeriesInGroup = this.w.config.series | ||
.map((serie, si) => (group.indexOf(serie.name) > -1 ? si : null)) | ||
.map((serie, si) => (group.indexOf(gl.seriesNames[si]) > -1 ? si : null)) | ||
.filter((f) => f !== null) | ||
@@ -615,3 +627,4 @@ | ||
(!this.w.config.chart.stackOnlyBar || | ||
this.w.config.series?.[i]?.type === 'bar')) | ||
this.w.config.series?.[i]?.type === 'bar' | ||
|| this.w.config.series?.[i]?.type === 'column')) | ||
@@ -618,0 +631,0 @@ if (stackSeries) { |
@@ -49,4 +49,8 @@ import Utils from '../utils/Utils' | ||
// because the tick lines are drawn based on series[0]. This does not | ||
// override user defined options for any series. | ||
if (gl.isMultipleYAxis && !gotTickAmount && gl.multiAxisTickAmount > 0) { | ||
// override user defined options for any yaxis. | ||
if ( | ||
gl.isMultipleYAxis | ||
&& !gotTickAmount | ||
&& gl.multiAxisTickAmount > 0 | ||
) { | ||
ticks = gl.multiAxisTickAmount | ||
@@ -69,4 +73,4 @@ gotTickAmount = true | ||
// when all values are 0 | ||
yMin = 0 | ||
yMax = ticks | ||
yMin = Utils.isNumber(axisCnf.min) ? axisCnf.min : 0 | ||
yMax = Utils.isNumber(axisCnf.max) ? axisCnf.max : yMin + ticks | ||
gl.allSeriesCollapsed = false | ||
@@ -272,2 +276,7 @@ } | ||
yMax = stepSize * Math.ceil(yMax / stepSize) | ||
if (Math.abs(yMax - yMin) / Utils.getGCD(range, stepSize) > maxTicks) { | ||
// Use default ticks to compute yMin then shrinkwrap | ||
yMax = yMin + stepSize * ticks | ||
yMax += stepSize * Math.ceil((yMaxPrev - yMax) / stepSize) | ||
} | ||
} | ||
@@ -305,8 +314,2 @@ } | ||
// Record final tiks for use by other series that call niceScale(). | ||
// Note: some don't, like logarithmicScale(), etc. | ||
if (gl.isMultipleYAxis && gl.multiAxisTickAmount == 0) { | ||
gl.multiAxisTickAmount = tiks | ||
} | ||
if ( | ||
@@ -374,4 +377,15 @@ tiks > maxTicks && | ||
} | ||
tiks = Math.round(range / stepSize) | ||
} | ||
// Record final tiks for use by other series that call niceScale(). | ||
// Note: some don't, like logarithmicScale(), etc. | ||
if ( | ||
gl.isMultipleYAxis | ||
&& gl.multiAxisTickAmount == 0 | ||
&& gl.ignoreYAxisIndexes.indexOf(index) < 0 | ||
) { | ||
gl.multiAxisTickAmount = tiks | ||
} | ||
// build Y label array. | ||
@@ -533,11 +547,10 @@ | ||
} else { | ||
if (maxY === -Number.MAX_VALUE || !Utils.isNumber(maxY)) { | ||
// no data in the chart. Either all series collapsed or user passed a blank array | ||
gl.yAxisScale[index] = this.linearScale( | ||
0, | ||
10, | ||
10, | ||
index, | ||
cnf.yaxis[index].stepSize | ||
) | ||
if ( | ||
maxY === -Number.MAX_VALUE || !Utils.isNumber(maxY) | ||
|| minY === Number.MAX_VALUE || !Utils.isNumber(minY) | ||
) { | ||
// no data in the chart. | ||
// Either all series collapsed or user passed a blank array. | ||
// Show the user's yaxis with their scale options but with a range. | ||
gl.yAxisScale[index] = this.niceScale(Number.MIN_VALUE, 0, index) | ||
} else { | ||
@@ -574,3 +587,3 @@ // there is some data. Turn off the allSeriesCollapsed flag | ||
setMultipleYScales() { | ||
setSeriesYAxisMappings() { | ||
const gl = this.w.globals | ||
@@ -629,3 +642,5 @@ const cnf = this.w.config | ||
let unassignedSeriesIndices = [] | ||
let assumeSeriesNameArrays = cnf.yaxis.length !== cnf.series.length | ||
let seriesNameArrayStyle = | ||
gl.series.length > cnf.yaxis.length | ||
|| cnf.yaxis.some((a) => Array.isArray(a.seriesName)) | ||
@@ -641,2 +656,3 @@ cnf.series.forEach((s, i) => { | ||
let unassignedYAxisIndices = [] | ||
// here, we loop through the yaxis array and find the item which has "seriesName" property | ||
@@ -659,9 +675,25 @@ cnf.yaxis.forEach((yaxe, yi) => { | ||
if (s.name === name) { | ||
if (yi === si || assumeSeriesNameArrays) { | ||
axisSeriesMap[yi].push(si) | ||
let remove = si | ||
if (yi === si || seriesNameArrayStyle) { | ||
// New style, don't allow series to be double referenced | ||
if (!seriesNameArrayStyle | ||
|| unassignedSeriesIndices.indexOf(si) > -1 | ||
) { | ||
axisSeriesMap[yi].push([yi,si]) | ||
} else { | ||
console.warn( | ||
"Series '" | ||
+ s.name | ||
+ "' referenced more than once in what looks like the new style." | ||
+ " That is, when using either seriesName: []," | ||
+ " or when there are more series than yaxes.") | ||
} | ||
} else { | ||
axisSeriesMap[si].push(yi) | ||
// The series index refers to the target yaxis and the current | ||
// yaxis index refers to the actual referenced series. | ||
axisSeriesMap[si].push([si,yi]) | ||
remove = yi | ||
} | ||
assigned = true | ||
let remove = unassignedSeriesIndices.indexOf(si) | ||
remove = unassignedSeriesIndices.indexOf(remove) | ||
if (remove !== -1) { | ||
@@ -678,14 +710,19 @@ unassignedSeriesIndices.splice(remove, 1) | ||
}) | ||
axisSeriesMap.forEach((yaxe, yi) => { | ||
yaxe.forEach((si) => { | ||
seriesYAxisReverseMap[si] = yi | ||
axisSeriesMap = axisSeriesMap.map((yaxe, yi) => { | ||
let ra = [] | ||
yaxe.forEach((sa) => { | ||
seriesYAxisReverseMap[sa[1]] = sa[0] | ||
ra.push(sa[1]) | ||
}) | ||
return ra | ||
}) | ||
// All series referenced directly by yaxes have been assigned to those axes. | ||
// Any series so far unassigned will be assigned to any yaxes that have yet | ||
// to reference series directly, one-for-one in order of appearance, with | ||
// all left-over series assigned to the last such yaxis. This captures the | ||
// all left-over series assigned to either the last unassigned yaxis, or the | ||
// last yaxis if all have assigned series. This captures the | ||
// default single and multiaxis config options which simply includes zero, | ||
// one or as many yaxes as there are series but do not reference them by name. | ||
let lastUnassignedYAxis | ||
let lastUnassignedYAxis = cnf.yaxis.length - 1 | ||
for (let i = 0; i < unassignedYAxisIndices.length; i++) { | ||
@@ -704,63 +741,128 @@ lastUnassignedYAxis = unassignedYAxisIndices[i] | ||
if (lastUnassignedYAxis) { | ||
unassignedSeriesIndices.forEach((i) => { | ||
axisSeriesMap[lastUnassignedYAxis].push(i) | ||
seriesYAxisReverseMap[i] = lastUnassignedYAxis | ||
}) | ||
} | ||
unassignedSeriesIndices.forEach((i) => { | ||
axisSeriesMap[lastUnassignedYAxis].push(i) | ||
seriesYAxisReverseMap[i] = lastUnassignedYAxis | ||
}) | ||
// We deliberately leave the zero-length yaxis array elements in for | ||
// compatibility with the old equivalence in number between sereis and yaxes. | ||
// For the old-style seriesName-as-string-only, leave the zero-length yaxis | ||
// array elements in for compatibility so that series.length == yaxes.length | ||
// for multi axis charts. | ||
gl.seriesYAxisMap = axisSeriesMap.map((x) => x) | ||
gl.seriesYAxisReverseMap = seriesYAxisReverseMap.map((x) => x) | ||
this.sameScaleInMultipleAxes(minYArr, maxYArr, axisSeriesMap) | ||
} | ||
sameScaleInMultipleAxes(minYArr, maxYArr, axisSeriesMap) { | ||
scaleMultipleYAxes() { | ||
const cnf = this.w.config | ||
const gl = this.w.globals | ||
this.setSeriesYAxisMappings() | ||
let axisSeriesMap = gl.seriesYAxisMap | ||
let minYArr = gl.minYArr | ||
let maxYArr = gl.maxYArr | ||
// Compute min..max for each yaxis | ||
// | ||
gl.allSeriesCollapsed = true | ||
gl.barGroups = [] | ||
axisSeriesMap.forEach((axisSeries, ai) => { | ||
let groupNames = [] | ||
axisSeries.forEach((as) => { | ||
let group = cnf.series[as].group | ||
if (groupNames.indexOf(group) < 0) { | ||
groupNames.push(group) | ||
} | ||
}) | ||
if (axisSeries.length > 0) { | ||
let minY = Number.MAX_VALUE | ||
let maxY = -Number.MAX_VALUE | ||
let lowestY = minY | ||
let highestY = maxY | ||
let seriesType | ||
let seriesGroupName | ||
if (cnf.chart.stacked) { | ||
let sumSeries = gl.seriesX[axisSeries[0]].map((x) => Number.MIN_VALUE) | ||
let posSeries = gl.seriesX[axisSeries[0]].map((x) => Number.MIN_VALUE) | ||
let negSeries = gl.seriesX[axisSeries[0]].map((x) => Number.MIN_VALUE) | ||
// The first series bound to the axis sets the type for stacked series | ||
let seriesType = cnf.series[axisSeries[0]].type | ||
// Series' on this axis with the same group name will be stacked. | ||
// Sum series in each group separately | ||
let mapSeries = gl.seriesX[axisSeries[0]] | ||
let sumSeries = [] | ||
let posSeries = [] | ||
let negSeries = [] | ||
groupNames.forEach(() => { | ||
sumSeries.push(mapSeries.map(() => Number.MIN_VALUE)) | ||
posSeries.push(mapSeries.map(() => Number.MIN_VALUE)) | ||
negSeries.push(mapSeries.map(() => Number.MIN_VALUE)) | ||
}) | ||
for (let i = 0; i < axisSeries.length; i++) { | ||
// Assume chart type but the first series that has a type overrides. | ||
if (!seriesType && cnf.series[axisSeries[i]].type) { | ||
seriesType = cnf.series[axisSeries[i]].type | ||
} | ||
// Sum all series for this yaxis at each corresponding datapoint | ||
// For bar and column charts we need to keep positive and negative | ||
// values separate. | ||
// values separate, for each group separately. | ||
let si = axisSeries[i] | ||
if (gl.collapsedSeriesIndices.indexOf(si) === -1) { | ||
for (let j = 0; j < gl.series[si].length; j++) { | ||
let val = gl.series[si][j] | ||
if (val >= 0) { | ||
posSeries[j] += val | ||
} else { | ||
negSeries[j] += val | ||
if (cnf.series[si].group) { | ||
seriesGroupName = cnf.series[si].group | ||
} else { | ||
seriesGroupName = 'axis-'.concat(ai) | ||
} | ||
let collapsed = | ||
!(gl.collapsedSeriesIndices.indexOf(si) < 0 | ||
&& gl.ancillaryCollapsedSeriesIndices.indexOf(si) < 0) | ||
if (!collapsed) { | ||
gl.allSeriesCollapsed = false | ||
groupNames.forEach((gn, gni) => { | ||
// Undefined group names will be grouped together as their own | ||
// group. | ||
if (cnf.series[si].group === gn) { | ||
for (let j = 0; j < gl.series[si].length; j++) { | ||
let val = gl.series[si][j] | ||
if (val >= 0) { | ||
posSeries[gni][j] += val | ||
} else { | ||
negSeries[gni][j] += val | ||
} | ||
sumSeries[gni][j] += val | ||
// For non bar-like series' we need these point max/min values. | ||
lowestY = Math.min(lowestY, val) | ||
highestY = Math.max(highestY, val) | ||
} | ||
} | ||
sumSeries[j] += val | ||
} | ||
}) | ||
} | ||
if (seriesType === 'bar' || seriesType === 'column') { | ||
gl.barGroups.push(seriesGroupName) | ||
} | ||
} | ||
if (seriesType === 'bar') { | ||
minY = Math.min.apply(null, negSeries) | ||
maxY = Math.max.apply(null, posSeries) | ||
if (!seriesType) { | ||
seriesType = cnf.chart.type | ||
} | ||
if (seriesType === 'bar' || seriesType === 'column') { | ||
groupNames.forEach((gn, gni) => { | ||
minY = Math.min(minY, Math.min.apply(null, negSeries[gni])) | ||
maxY = Math.max(maxY, Math.max.apply(null, posSeries[gni])) | ||
}) | ||
} else { | ||
minY = Math.min.apply(null, sumSeries) | ||
maxY = Math.max.apply(null, sumSeries) | ||
// We don't expect multiple groups per yaxis for line-like | ||
// series, but we allow it anyway. | ||
groupNames.forEach((gn, gni) => { | ||
minY = Math.min(lowestY, Math.min.apply(null, sumSeries[gni])) | ||
maxY = Math.max(highestY, Math.max.apply(null, sumSeries[gni])) | ||
}) | ||
} | ||
if (minY === Number.MIN_VALUE && maxY === Number.MIN_VALUE) { | ||
// No series data | ||
maxY = -Number.MAX_VALUE | ||
} | ||
} else { | ||
for (let i = 0; i < axisSeries.length; i++) { | ||
minY = Math.min(minY, minYArr[axisSeries[i]]) | ||
let si = axisSeries[i] | ||
minY = Math.min(minY, minYArr[si]) | ||
maxY = Math.max(maxY, maxYArr[si]) | ||
let collapsed = | ||
!(gl.collapsedSeriesIndices.indexOf(si) < 0 | ||
&& gl.ancillaryCollapsedSeriesIndices.indexOf(si) < 0) | ||
if (!collapsed) { | ||
gl.allSeriesCollapsed = false | ||
} | ||
} | ||
for (let i = 0; i < axisSeries.length; i++) { | ||
maxY = Math.max(maxY, maxYArr[axisSeries[i]]) | ||
} | ||
} | ||
@@ -781,2 +883,3 @@ if (cnf.yaxis[ai].min !== undefined) { | ||
} | ||
gl.barGroups = gl.barGroups.filter((v,i,a) => a.indexOf(v) === i) | ||
// Set the scale for this yaxis | ||
@@ -789,2 +892,5 @@ this.setYScaleForIndex(ai, minY, maxY) | ||
}) | ||
} else { | ||
// No series referenced by this yaxis | ||
this.setYScaleForIndex(ai, 0, -Number.MAX_VALUE) | ||
} | ||
@@ -791,0 +897,0 @@ }) |
@@ -136,3 +136,3 @@ import Graphics from './Graphics' | ||
let allSeriesEls = w.globals.dom.baseEl.querySelectorAll( | ||
`.apexcharts-series, .apexcharts-datalabels` | ||
`.apexcharts-series, .apexcharts-datalabels, .apexcharts-yaxis` | ||
) | ||
@@ -145,2 +145,3 @@ | ||
let dataLabelEl = null | ||
let yaxisEl = null | ||
if (w.globals.axisCharts || w.config.chart.type === 'radialBar') { | ||
@@ -154,2 +155,6 @@ if (w.globals.axisCharts) { | ||
) | ||
let yaxisIndex = w.globals.seriesYAxisReverseMap[seriesCnt] | ||
yaxisEl = w.globals.dom.baseEl.querySelector( | ||
`.apexcharts-yaxis[rel='${yaxisIndex}']` | ||
) | ||
} else { | ||
@@ -179,2 +184,6 @@ seriesEl = w.globals.dom.baseEl.querySelector( | ||
} | ||
if (yaxisEl !== null) { | ||
yaxisEl.classList.remove(this.legendInactiveClass) | ||
} | ||
} | ||
@@ -181,0 +190,0 @@ } else if (e.type === 'mouseout') { |
@@ -31,2 +31,3 @@ import Utils from './../../utils/Utils' | ||
gl.groups = [] | ||
gl.barGroups = [] | ||
gl.hasSeriesGroups = false | ||
@@ -33,0 +34,0 @@ gl.seriesGroups = [] |
@@ -164,6 +164,9 @@ /** | ||
const w = this.w | ||
const gl = w.globals | ||
const yAxisSeriesArr = gl.seriesYAxisMap[index] | ||
let lbFormatter = w.globals.yLabelFormatters[index] | ||
if (ttCtx.yaxisTooltips[index]) { | ||
if (ttCtx.yaxisTooltips[index] | ||
&& yAxisSeriesArr.length > 0 | ||
) { | ||
const lbFormatter = gl.yLabelFormatters[index] | ||
const elGrid = ttCtx.getElGrid() | ||
@@ -174,6 +177,16 @@ const seriesBound = elGrid.getBoundingClientRect() | ||
// because they will all return the same value. | ||
let seriesIndex = w.globals.seriesYAxisMap[anno.yAxisIndex][0] | ||
const hoverY = (clientY - seriesBound.top) * xyRatios.yRatio[seriesIndex] | ||
const height = w.globals.maxYArr[seriesIndex] - w.globals.minYArr[seriesIndex] | ||
const val = w.globals.minYArr[seriesIndex] + (height - hoverY) | ||
const seriesIndex = yAxisSeriesArr[0] | ||
const translationsIndex = 0 | ||
if (xyRatios.yRatio.length > 1) { | ||
translationsIndex = seriesIndex | ||
} | ||
const hoverY = | ||
(clientY - seriesBound.top) | ||
* xyRatios.yRatio[translationsIndex] | ||
const height = | ||
gl.maxYArr[seriesIndex] | ||
- gl.minYArr[seriesIndex] | ||
const val = | ||
gl.minYArr[seriesIndex] | ||
+ (height - hoverY) | ||
@@ -180,0 +193,0 @@ ttCtx.tooltipPosition.moveYCrosshairs(clientY - seriesBound.top) |
@@ -577,9 +577,11 @@ import Graphics from './Graphics' | ||
// because they will all return the same value. | ||
let seriesIndex = w.globals.seriesYAxisMap[index][0] | ||
yHighestValue.push( | ||
w.globals.yAxisScale[index].niceMax - xyRatios.yRatio[seriesIndex] * me.startY | ||
) | ||
yLowestValue.push( | ||
w.globals.yAxisScale[index].niceMax - xyRatios.yRatio[seriesIndex] * me.endY | ||
) | ||
if (w.globals.seriesYAxisMap[index].length > 0) { | ||
let seriesIndex = w.globals.seriesYAxisMap[index][0] | ||
yHighestValue.push( | ||
w.globals.yAxisScale[index].niceMax - xyRatios.yRatio[seriesIndex] * me.startY | ||
) | ||
yLowestValue.push( | ||
w.globals.yAxisScale[index].niceMax - xyRatios.yRatio[seriesIndex] * me.endY | ||
) | ||
} | ||
}) | ||
@@ -586,0 +588,0 @@ |
@@ -347,3 +347,3 @@ // Typescript declarations for Apex class and module. | ||
lineCap?: 'butt' | 'square' | 'round' | ||
colors?: string[] | ||
colors?: any[] | string[] | ||
width?: number | number[] | ||
@@ -350,0 +350,0 @@ dashArray?: number | number[] |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
4556533
73806