diff --git a/samples/vanilla-js/column/data-color.html b/samples/vanilla-js/column/data-color.html
new file mode 100644
index 000000000..35ef9679c
--- /dev/null
+++ b/samples/vanilla-js/column/data-color.html
@@ -0,0 +1,104 @@
+
+
+
+
+
+
+
+ Basic Column - Grouped
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/vanilla-js/column/histogram.html b/samples/vanilla-js/column/histogram.html
index ac802ef12..f31c361d2 100644
--- a/samples/vanilla-js/column/histogram.html
+++ b/samples/vanilla-js/column/histogram.html
@@ -20,6 +20,10 @@
opacity: 1;
border: 0;
}
+
+ .selection {
+ opacity: 0;
+ }
@@ -27,7 +31,9 @@
- Selected:
0
+
+ Selected: 0
+
@@ -59,7 +65,6 @@
},
plotOptions: {
bar: {
- distributed: true,
dataLabels: {
enabled: false
}
@@ -73,16 +78,6 @@
allowMultipleDataPointsSelection: true
}
},
- markers: {
- size: 5,
- strokeColor: "#fff",
- strokeWidth: 3,
- strokeOpacity: 1,
- fillOpacity: 1,
- hover: {
- size: 8
- }
- },
xaxis: {
categories: [10,20,30,40,50,60,70],
axisBorder: {
@@ -114,8 +109,8 @@
chart.addEventListener("dataPointSelection", function(e, opts) {
- console.log(e, opts)
- })
+ console.log(e, opts)
+ })
diff --git a/src/charts/Bar.js b/src/charts/Bar.js
index 2a69017f2..4b46362b1 100644
--- a/src/charts/Bar.js
+++ b/src/charts/Bar.js
@@ -46,7 +46,6 @@ class Bar {
draw(series, seriesIndex) {
let w = this.w
let graphics = new Graphics(this.ctx)
- let fill = new Fill(this.ctx)
const coreUtils = new CoreUtils(this.ctx, w)
this.series = coreUtils.getLogSeries(series)
@@ -190,23 +189,7 @@ class Bar {
yArrj.push(y)
- let seriesNumber = this.barOptions.distributed ? j : i
-
- let fillColor = null
-
- if (this.barOptions.colors.ranges.length > 0) {
- const colorRange = this.barOptions.colors.ranges
- colorRange.map((range) => {
- if (series[i][j] >= range.from && series[i][j] <= range.to) {
- fillColor = range.color
- }
- })
- }
-
- let pathFill = fill.fillPath({
- seriesNumber: this.barOptions.distributed ? seriesNumber : realIndex,
- color: fillColor
- })
+ let pathFill = this.getPathFillColor(i, j, realIndex)
elSeries = this.renderSeries({
realIndex,
@@ -238,6 +221,34 @@ class Bar {
return ret
}
+ getPathFillColor(i, j, realIndex) {
+ const w = this.w
+ let fill = new Fill(this.ctx)
+
+ let fillColor = null
+ let seriesNumber = this.barOptions.distributed ? j : i
+
+ if (this.barOptions.colors.ranges.length > 0) {
+ const colorRange = this.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.barOptions.distributed ? seriesNumber : realIndex,
+ color: fillColor
+ })
+
+ return pathFill
+ }
+
renderSeries({
realIndex,
pathFill,
@@ -267,6 +278,10 @@ class Bar {
: w.globals.stroke.colors[realIndex]
}
+ if (w.config.series[i].data[j] && w.config.series[i].data[j].strokeColor) {
+ lineFill = w.config.series[i].data[j].strokeColor
+ }
+
if (this.isNullValue) {
pathFill = 'none'
}
@@ -507,8 +522,6 @@ class Bar {
pathTo +
graphics.line(endingShape.newX, barYPosition) +
endingShape.path +
- // graphics.line(x, barYPosition) +
- // graphics.line(x, barYPosition + barHeight - strokeWidth) +
graphics.line(zeroW, barYPosition + barHeight - strokeWidth) +
graphics.line(zeroW, barYPosition)
@@ -614,17 +627,15 @@ class Bar {
pathTo +
graphics.line(barXPosition, endingShape.newY) +
endingShape.path +
- // graphics.line(barXPosition, y) +
- // graphics.line(barXPosition + barWidth - strokeWidth, y) +
graphics.line(barXPosition + barWidth - strokeWidth, zeroH) +
- graphics.line(barXPosition, zeroH)
+ graphics.line(barXPosition - strokeWidth / 2, zeroH)
pathFrom =
pathFrom +
graphics.line(barXPosition, zeroH) +
endingShape.ending_p_from +
graphics.line(barXPosition + barWidth - strokeWidth, zeroH) +
graphics.line(barXPosition + barWidth - strokeWidth, zeroH) +
- graphics.line(barXPosition, zeroH)
+ graphics.line(barXPosition - strokeWidth / 2, zeroH)
if (!w.globals.isXNumeric) {
x = x + xDivision
diff --git a/src/charts/BarStacked.js b/src/charts/BarStacked.js
index 1278ab8e5..897e7f552 100644
--- a/src/charts/BarStacked.js
+++ b/src/charts/BarStacked.js
@@ -178,23 +178,7 @@ class BarStacked extends Bar {
xArrValues.push(x)
yArrValues.push(y)
- let seriesNumber = w.config.plotOptions.bar.distributed ? j : i
-
- let fillColor = null
-
- if (this.barOptions.colors.ranges.length > 0) {
- const colorRange = this.barOptions.colors.ranges
- colorRange.map((range, index) => {
- if (series[i][j] >= range.from && series[i][j] <= range.to) {
- fillColor = range.color
- }
- })
- }
-
- let pathFill = this.fill.fillPath({
- seriesNumber: this.barOptions.distributed ? seriesNumber : realIndex,
- color: fillColor
- })
+ let pathFill = this.bar.getPathFillColor(i, j, realIndex)
elSeries = this.renderSeries({
realIndex,
@@ -530,14 +514,14 @@ class BarStacked extends Bar {
this.graphics.line(barXPosition, endingShape.newY) +
endingShape.path +
this.graphics.line(barXPosition + barWidth - strokeWidth, barYPosition) +
- this.graphics.line(barXPosition, barYPosition)
+ this.graphics.line(barXPosition - strokeWidth / 2, barYPosition)
pathFrom =
pathFrom +
this.graphics.line(barXPosition, barYPosition) +
this.graphics.line(barXPosition + barWidth - strokeWidth, barYPosition) +
this.graphics.line(barXPosition + barWidth - strokeWidth, barYPosition) +
this.graphics.line(barXPosition + barWidth - strokeWidth, barYPosition) +
- this.graphics.line(barXPosition, barYPosition)
+ this.graphics.line(barXPosition - strokeWidth / 2, barYPosition)
if (
w.config.plotOptions.bar.colors.backgroundBarColors.length > 0 &&
diff --git a/src/charts/Scatter.js b/src/charts/Scatter.js
index 4f5dfc97b..d82d81751 100644
--- a/src/charts/Scatter.js
+++ b/src/charts/Scatter.js
@@ -100,21 +100,33 @@ export default class Scatter {
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('apexcharts-marker', i)
+
let pathFillCircle = fill.fillPath({
seriesNumber: realIndex,
patternUnits: 'objectBoundingBox'
})
let circle = graphics.drawCircle(radius)
+ if (w.config.series[i].data[dataPointIndex]) {
+ if (w.config.series[i].data[dataPointIndex].fillColor) {
+ pathFillCircle = w.config.series[i].data[dataPointIndex].fillColor
+ }
+ }
+
circle.attr({
cx: x,
cy: y,
- fill: pathFillCircle
+ fill: pathFillCircle,
+ stroke: markerConfig.pointStrokeColor,
+ strokeWidth: markerConfig.pWidth
})
if (w.config.chart.dropShadow.enabled) {
@@ -192,7 +204,6 @@ export default class Scatter {
'default-marker-size': finishRadius
})
- const markers = new Markers(this.ctx)
filters.setSelectionFilter(circle, realIndex, dataPointIndex)
markers.addEvents(circle)
diff --git a/src/modules/Core.js b/src/modules/Core.js
index ac16e8830..bd3fbbea7 100644
--- a/src/modules/Core.js
+++ b/src/modules/Core.js
@@ -478,6 +478,7 @@ export default class Core {
} else {
this.twoDSeries.push(Utils.parseNumber(ser[i].data[j][1]))
}
+ gl.dataFormat2DArray = true
}
if (cnf.xaxis.type === 'datetime') {
// if timestamps are provided and xaxis type is datettime,
@@ -509,6 +510,7 @@ export default class Core {
// fix #368
activeI = this.activeSeriesIndex
}
+ gl.dataFormatXY = true
// get series
for (let j = 0; j < ser[i].data.length; j++) {
@@ -737,7 +739,7 @@ export default class Core {
// user didn't provided labels, fallback to 1-2-3-4-5
let labelArr = []
if (gl.axisCharts) {
- if (this.twoDSeriesX.length > 0) {
+ if (gl.dataFormat2DArray) {
const scales = new Scales(this.ctx)
labelArr = scales
.linearScale(
diff --git a/src/modules/Markers.js b/src/modules/Markers.js
index 8489a7c5a..67b8fab8b 100644
--- a/src/modules/Markers.js
+++ b/src/modules/Markers.js
@@ -39,6 +39,7 @@ export default class Markers {
plotChartMarkers(pointsPos, seriesIndex, j) {
let w = this.w
+ let i = seriesIndex
let p = pointsPos
let elPointsWrap = null
@@ -99,6 +100,16 @@ export default class Markers {
}
})
+ if (w.config.series[i].data[j]) {
+ if (w.config.series[i].data[j].fillColor) {
+ opts.pointFillColor = w.config.series[i].data[j].fillColor
+ }
+
+ if (w.config.series[i].data[j].strokeColor) {
+ opts.pointStrokeColor = w.config.series[i].data[j].strokeColor
+ }
+ }
+
point = graphics.drawMarker(p.x[q], p.y[q], opts)
point.attr('rel', dataPointIndex)
diff --git a/src/modules/Range.js b/src/modules/Range.js
index d029d67d8..dd615678c 100644
--- a/src/modules/Range.js
+++ b/src/modules/Range.js
@@ -284,7 +284,7 @@ class Range {
if (
(gl.isXNumeric || gl.noLabelsProvided) &&
- !cnf.xaxis.convertedCatToNumeric
+ (!cnf.xaxis.convertedCatToNumeric || gl.dataFormat2DArray)
) {
let ticks
@@ -356,6 +356,11 @@ class Range {
gl.maxX = gl.maxX + 2
}
}
+
+ return {
+ minX: gl.minX,
+ maxX: gl.maxX
+ }
}
setZRange() {
diff --git a/src/modules/settings/Globals.js b/src/modules/settings/Globals.js
index 1edd0706b..e9ebd5e98 100644
--- a/src/modules/settings/Globals.js
+++ b/src/modules/settings/Globals.js
@@ -60,6 +60,8 @@ export default class Globals {
ancillaryCollapsedSeries: [], // when user collapses an "alwaysVisible" series, it goes into this array
ancillaryCollapsedSeriesIndices: [], // this stores the index of the collapsedSeries whose y-axis is always visible
risingSeries: [], // when user re-opens a collapsed series, it goes here
+ dataFormat2DArray: false,
+ dataFormatXY: false,
selectedDataPoints: [],
ignoreYAxisIndexes: [], // when series are being collapsed in multiple y axes, ignore certain index
padHorizontal: 0,
diff --git a/src/modules/tooltip/Position.js b/src/modules/tooltip/Position.js
index ff6765676..e7a9aaf83 100644
--- a/src/modules/tooltip/Position.js
+++ b/src/modules/tooltip/Position.js
@@ -279,10 +279,13 @@ export default class Position {
`.apexcharts-series[data\\:realIndex='${capturedSeries}'] .apexcharts-series-markers circle`
)
- point.setAttribute('r', hoverSize)
+ if (point) {
+ point.setAttribute('r', hoverSize)
+
+ point.setAttribute('cx', cx)
+ point.setAttribute('cy', cy)
+ }
- point.setAttribute('cx', cx)
- point.setAttribute('cy', cy)
// point.style.opacity = w.config.markers.hover.opacity
this.moveXCrosshairs(cx)
diff --git a/tests/unit/data/series2dArrayNumeric.js b/tests/unit/data/series2dArrayNumeric.js
new file mode 100644
index 000000000..0fbdfa4b1
--- /dev/null
+++ b/tests/unit/data/series2dArrayNumeric.js
@@ -0,0 +1,44 @@
+module.exports = [
+ {
+ data: [
+ [6.4, 5.4],
+ [11.7, 4],
+ [15.4, 3],
+ [9, 2],
+ [10.9, 11],
+ [20.9, 7],
+ [12.9, 8.2],
+ [6.4, 14],
+ [11.6, 12]
+ ]
+ },
+ {
+ data: [
+ [16.4, 5.4],
+ [21.7, 4],
+ [25.4, 3],
+ [19, 2],
+ [10.9, 1],
+ [13.6, 3.2],
+ [10.9, 7],
+ [10.9, 8.2],
+ [16.4, 4],
+ [13.6, 4.3],
+ [13.6, 12],
+ [29.9, 3],
+ [10.9, 5.2],
+ [16.4, 6.5],
+ [10.9, 8],
+ [24.5, 7.1],
+ [10.9, 7],
+ [8.1, 4.7],
+ [19, 10],
+ [27.1, 10],
+ [24.5, 8],
+ [27.1, 3],
+ [29.9, 11.5],
+ [27.1, 0.8],
+ [22.1, 2]
+ ]
+ }
+]
diff --git a/tests/unit/data/series2dArray.js b/tests/unit/data/series2dArrayTimestamp.js
similarity index 100%
rename from tests/unit/data/series2dArray.js
rename to tests/unit/data/series2dArrayTimestamp.js
diff --git a/tests/unit/xaxis-min-max.spec.js b/tests/unit/xaxis-min-max.spec.js
new file mode 100644
index 000000000..50c434fb2
--- /dev/null
+++ b/tests/unit/xaxis-min-max.spec.js
@@ -0,0 +1,24 @@
+import Range from '../../src/modules/Range.js'
+import series2dArrayNumeric from './data/series2dArrayNumeric.js'
+import { createChartWithOptions } from './utils/utils.js'
+
+describe('X-axis data', () => {
+ it('should set the min and max of x-axis based on user input', () => {
+ const chart = createChartWithOptions({
+ chart: {
+ type: 'line'
+ },
+ series: series2dArrayNumeric,
+ xaxis: {
+ min: 0,
+ max: 40
+ }
+ })
+
+ const range = new Range(chart)
+ const xRange = range.setXRange()
+
+ expect(xRange.minX).toEqual(0)
+ expect(xRange.maxX).toEqual(40)
+ })
+})