diff --git a/src/traces/violin/calc.js b/src/traces/violin/calc.js index 2926a97a5f0..1cabe47b0b8 100644 --- a/src/traces/violin/calc.js +++ b/src/traces/violin/calc.js @@ -33,28 +33,36 @@ module.exports = function calc(gd, trace) { for(var i = 0; i < cd.length; i++) { var cdi = cd[i]; var vals = cdi.pts.map(helpers.extractVal); + var span; - var bandwidth = cdi.bandwidth = calcBandwidth(trace, cdi, vals); - var span = cdi.span = calcSpan(trace, cdi, valAxis, bandwidth); - - // step that well covers the bandwidth and is multiple of span distance - var dist = span[1] - span[0]; - var n = Math.ceil(dist / (bandwidth / 3)); - var step = dist / n; - - if(!isFinite(step) || !isFinite(n)) { - Lib.error('Something went wrong with computing the violin span'); - cd[0].t.empty = true; - return cd; - } - - var kde = helpers.makeKDE(cdi, trace, vals); - cdi.density = new Array(n); - - for(var k = 0, t = span[0]; t < (span[1] + step / 2); k++, t += step) { - var v = kde(t); - cdi.density[k] = {v: v, t: t}; - maxKDE = Math.max(maxKDE, v); + if(cdi.min === cdi.max) { + span = cdi.span = [cdi.min, cdi.max]; + cdi.density = [{v: 1, t: span[0]}]; + cdi.bandwidth = 1; + maxKDE = Math.max(maxKDE, 1); + } else { + var bandwidth = cdi.bandwidth = calcBandwidth(trace, cdi, vals); + span = cdi.span = calcSpan(trace, cdi, valAxis, bandwidth); + + // step that well covers the bandwidth and is multiple of span distance + var dist = span[1] - span[0]; + var n = Math.ceil(dist / (bandwidth / 3)); + var step = dist / n; + + if(!isFinite(step) || !isFinite(n)) { + Lib.error('Something went wrong with computing the violin span'); + cd[0].t.empty = true; + return cd; + } + + var kde = helpers.makeKDE(cdi, trace, vals); + cdi.density = new Array(n); + + for(var k = 0, t = span[0]; t < (span[1] + step / 2); k++, t += step) { + var v = kde(t); + cdi.density[k] = {v: v, t: t}; + maxKDE = Math.max(maxKDE, v); + } } maxCount = Math.max(maxCount, vals.length); diff --git a/test/image/baselines/groups-over-matching-axes.png b/test/image/baselines/groups-over-matching-axes.png index 635d61e7fac..388188e5a34 100644 Binary files a/test/image/baselines/groups-over-matching-axes.png and b/test/image/baselines/groups-over-matching-axes.png differ diff --git a/test/image/baselines/violin-offsetgroups.png b/test/image/baselines/violin-offsetgroups.png index b1507b55d78..fcfeb7980ad 100644 Binary files a/test/image/baselines/violin-offsetgroups.png and b/test/image/baselines/violin-offsetgroups.png differ diff --git a/test/image/baselines/violin_only_zeroes.png b/test/image/baselines/violin_only_zeroes.png new file mode 100644 index 00000000000..d60d75d127d Binary files /dev/null and b/test/image/baselines/violin_only_zeroes.png differ diff --git a/test/image/mocks/violin_only_zeroes.json b/test/image/mocks/violin_only_zeroes.json new file mode 100644 index 00000000000..b8f595096a1 --- /dev/null +++ b/test/image/mocks/violin_only_zeroes.json @@ -0,0 +1,23 @@ +{ + "data": [{ + "type": "violin", + "y": [0, 0, 0, 0], + "points": "all", + "pointpos": 0, + "spanmode": "hard", + "meanline": { + "visible": true + } + }, { + "type": "violin", + "y": [2, 2, 2, 2], + "points": "all", + "pointpos": 0, + "spanmode": "hard" + }, { + "type": "violin", + "y": [0, 1, 1.5, 2], + "points": "all", + "pointpos": 0 + }] +}