From 8f04d13fdeb22616afcc4549be44740f629dfb20 Mon Sep 17 00:00:00 2001 From: Kully Date: Fri, 12 Oct 2018 14:55:27 -0400 Subject: [PATCH 01/38] added vwidth param - not working --- src/traces/box/attributes.js | 13 ++++++++++++- src/traces/box/cross_trace_calc.js | 13 +++++++++++-- src/traces/violin/attributes.js | 11 +++++++++++ src/traces/violin/cross_trace_calc.js | 2 +- 4 files changed, 35 insertions(+), 4 deletions(-) diff --git a/src/traces/box/attributes.js b/src/traces/box/attributes.js index 215aa421145..83bac7bd6c0 100644 --- a/src/traces/box/attributes.js +++ b/src/traces/box/attributes.js @@ -255,5 +255,16 @@ module.exports = { 'Do the hover effects highlight individual boxes ', 'or sample points or both?' ].join(' ') - } + }, + vwidth: { + valType: 'number', + min: 0, + role: 'info', + dflt: false, + editType: 'calc', + description: [ + 'Sets the width of the violins.', + 'This overrides the normal width of the violins.' + ].join(' ') + }, }; diff --git a/src/traces/box/cross_trace_calc.js b/src/traces/box/cross_trace_calc.js index 9a4aadd8d56..0ac591a6d2d 100644 --- a/src/traces/box/cross_trace_calc.js +++ b/src/traces/box/cross_trace_calc.js @@ -48,11 +48,11 @@ function crossTraceCalc(gd, plotinfo) { } } - setPositionOffset('box', gd, boxList, posAxis, [minPad, maxPad]); + setPositionOffset('box', gd, boxList, posAxis, [minPad, maxPad], false); } } -function setPositionOffset(traceType, gd, boxList, posAxis, pad) { +function setPositionOffset(traceType, gd, boxList, posAxis, pad, vwidth) { var calcdata = gd.calcdata; var fullLayout = gd._fullLayout; var pointList = []; @@ -76,6 +76,15 @@ function setPositionOffset(traceType, gd, boxList, posAxis, pad) { // and then use for posAxis autorange var boxdv = Lib.distinctVals(pointList); var dPos = boxdv.minDiff / 2; + console.log(''); + console.log('minDiff is ' + boxdv.minDiff); + console.log('dPos is ' + dPos); + // var dPos = 0.05 + var dPos = 0.5 + + if (vwidth) { + console.log('vwidth is ' + vwidth); + } // if there's no duplication of x points, // disable 'group' mode by setting counter to 1 diff --git a/src/traces/violin/attributes.js b/src/traces/violin/attributes.js index 965b8fecbb7..7e86deff5be 100644 --- a/src/traces/violin/attributes.js +++ b/src/traces/violin/attributes.js @@ -12,6 +12,17 @@ var boxAttrs = require('../box/attributes'); var extendFlat = require('../../lib/extend').extendFlat; module.exports = { + vwidth: { + valType: 'number', + min: 0, + role: 'info', + dflt: false, + editType: 'calc', + description: [ + 'Sets the width of the violins.', + 'This overrides the normal width of the violins.' + ].join(' ') + }, y: boxAttrs.y, x: boxAttrs.x, x0: boxAttrs.x0, diff --git a/src/traces/violin/cross_trace_calc.js b/src/traces/violin/cross_trace_calc.js index 8a4483b92ec..3c23aedf3f4 100644 --- a/src/traces/violin/cross_trace_calc.js +++ b/src/traces/violin/cross_trace_calc.js @@ -43,6 +43,6 @@ module.exports = function crossTraceCalc(gd, plotinfo) { } } - setPositionOffset('violin', gd, violinList, posAxis, [minPad, maxPad]); + setPositionOffset('violin', gd, violinList, posAxis, [minPad, maxPad], vwidth); } }; From f76ca97902a85e1e27c1ae1d4012676766cfc378 Mon Sep 17 00:00:00 2001 From: Kully Date: Mon, 15 Oct 2018 14:03:00 -0400 Subject: [PATCH 02/38] update dPos with vwidth//remove most console.logs --- src/plots/plots.js | 3 +++ src/traces/box/cross_trace_calc.js | 12 ++++-------- src/traces/box/defaults.js | 1 + src/traces/violin/cross_trace_calc.js | 2 +- src/traces/violin/defaults.js | 1 + 5 files changed, 10 insertions(+), 9 deletions(-) diff --git a/src/plots/plots.js b/src/plots/plots.js index 8f172d14ba0..d39e0ea40eb 100644 --- a/src/plots/plots.js +++ b/src/plots/plots.js @@ -2612,6 +2612,9 @@ function doCrossTraceCalc(gd) { fullLayout[sp]; for(j = 0; j < methods.length; j++) { + console.log(methods); + console.log(methods[j]) + console.log(methods[j].type) methods[j](gd, spInfo, sp); } } diff --git a/src/traces/box/cross_trace_calc.js b/src/traces/box/cross_trace_calc.js index 0ac591a6d2d..164a4a868f8 100644 --- a/src/traces/box/cross_trace_calc.js +++ b/src/traces/box/cross_trace_calc.js @@ -76,14 +76,10 @@ function setPositionOffset(traceType, gd, boxList, posAxis, pad, vwidth) { // and then use for posAxis autorange var boxdv = Lib.distinctVals(pointList); var dPos = boxdv.minDiff / 2; - console.log(''); - console.log('minDiff is ' + boxdv.minDiff); - console.log('dPos is ' + dPos); - // var dPos = 0.05 - var dPos = 0.5 - - if (vwidth) { - console.log('vwidth is ' + vwidth); + + // override dPos if violin width given + if (vwidth != false) { + dPos = vwidth; } // if there's no duplication of x points, diff --git a/src/traces/box/defaults.js b/src/traces/box/defaults.js index dc75d7f1266..f15242a3d27 100644 --- a/src/traces/box/defaults.js +++ b/src/traces/box/defaults.js @@ -28,6 +28,7 @@ function supplyDefaults(traceIn, traceOut, defaultColor, layout) { coerce('whiskerwidth'); coerce('boxmean'); + coerce('vwidth'); var notched = coerce('notched', traceIn.notchwidth !== undefined); if(notched) coerce('notchwidth'); diff --git a/src/traces/violin/cross_trace_calc.js b/src/traces/violin/cross_trace_calc.js index 3c23aedf3f4..65d83b8ee94 100644 --- a/src/traces/violin/cross_trace_calc.js +++ b/src/traces/violin/cross_trace_calc.js @@ -43,6 +43,6 @@ module.exports = function crossTraceCalc(gd, plotinfo) { } } - setPositionOffset('violin', gd, violinList, posAxis, [minPad, maxPad], vwidth); + setPositionOffset('violin', gd, violinList, posAxis, [minPad, maxPad], trace.vwidth); } }; diff --git a/src/traces/violin/defaults.js b/src/traces/violin/defaults.js index 869e7b08320..ad0ad414b91 100644 --- a/src/traces/violin/defaults.js +++ b/src/traces/violin/defaults.js @@ -29,6 +29,7 @@ module.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout coerce('scalegroup', traceOut.name); coerce('scalemode'); coerce('side'); + coerce('vwidth'); var span = coerce('span'); var spanmodeDflt; From 81cdbe90029869d5dd8c150b2bf0a14f63ce0482 Mon Sep 17 00:00:00 2001 From: Kully Date: Wed, 17 Oct 2018 08:18:22 -0400 Subject: [PATCH 03/38] some revision based on review comments --- src/plots/plots.js | 3 --- src/traces/box/attributes.js | 6 +++--- src/traces/box/cross_trace_calc.js | 2 +- src/traces/violin/attributes.js | 2 +- src/traces/violin/defaults.js | 9 ++++++--- 5 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/plots/plots.js b/src/plots/plots.js index d39e0ea40eb..8f172d14ba0 100644 --- a/src/plots/plots.js +++ b/src/plots/plots.js @@ -2612,9 +2612,6 @@ function doCrossTraceCalc(gd) { fullLayout[sp]; for(j = 0; j < methods.length; j++) { - console.log(methods); - console.log(methods[j]) - console.log(methods[j].type) methods[j](gd, spInfo, sp); } } diff --git a/src/traces/box/attributes.js b/src/traces/box/attributes.js index 83bac7bd6c0..a72243f263d 100644 --- a/src/traces/box/attributes.js +++ b/src/traces/box/attributes.js @@ -260,11 +260,11 @@ module.exports = { valType: 'number', min: 0, role: 'info', - dflt: false, + dflt: 0, editType: 'calc', description: [ - 'Sets the width of the violins.', - 'This overrides the normal width of the violins.' + 'Sets the width of the box.', + 'This overrides the normal width of the box traces.' ].join(' ') }, }; diff --git a/src/traces/box/cross_trace_calc.js b/src/traces/box/cross_trace_calc.js index 164a4a868f8..d90a8e76a93 100644 --- a/src/traces/box/cross_trace_calc.js +++ b/src/traces/box/cross_trace_calc.js @@ -78,7 +78,7 @@ function setPositionOffset(traceType, gd, boxList, posAxis, pad, vwidth) { var dPos = boxdv.minDiff / 2; // override dPos if violin width given - if (vwidth != false) { + if(vwidth) { dPos = vwidth; } diff --git a/src/traces/violin/attributes.js b/src/traces/violin/attributes.js index 7e86deff5be..eb83786def0 100644 --- a/src/traces/violin/attributes.js +++ b/src/traces/violin/attributes.js @@ -16,7 +16,7 @@ module.exports = { valType: 'number', min: 0, role: 'info', - dflt: false, + dflt: 0, editType: 'calc', description: [ 'Sets the width of the violins.', diff --git a/src/traces/violin/defaults.js b/src/traces/violin/defaults.js index ad0ad414b91..90884e963a1 100644 --- a/src/traces/violin/defaults.js +++ b/src/traces/violin/defaults.js @@ -26,10 +26,13 @@ module.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout if(traceOut.visible === false) return; coerce('bandwidth'); - coerce('scalegroup', traceOut.name); - coerce('scalemode'); coerce('side'); - coerce('vwidth'); + + var vwidth = coerce('vwidth'); + if(!vwidth) { + coerce('scalegroup', traceOut.name); + coerce('scalemode'); + } var span = coerce('span'); var spanmodeDflt; From 5ef2eeb1f7ff9061cef25909754e7d73a208265d Mon Sep 17 00:00:00 2001 From: Kully Date: Thu, 18 Oct 2018 10:56:49 -0400 Subject: [PATCH 04/38] change dflt vwidth to 0;assign dPos for each trace --- src/traces/box/attributes.js | 2 +- src/traces/box/cross_trace_calc.js | 20 +++++++++++--------- src/traces/box/defaults.js | 8 +++++++- src/traces/violin/attributes.js | 25 +++++++++++++------------ src/traces/violin/cross_trace_calc.js | 2 +- 5 files changed, 33 insertions(+), 24 deletions(-) diff --git a/src/traces/box/attributes.js b/src/traces/box/attributes.js index a72243f263d..52fff380fae 100644 --- a/src/traces/box/attributes.js +++ b/src/traces/box/attributes.js @@ -244,7 +244,6 @@ module.exports = { marker: scatterAttrs.unselected.marker, editType: 'style' }, - hoveron: { valType: 'flaglist', flags: ['boxes', 'points'], @@ -267,4 +266,5 @@ module.exports = { 'This overrides the normal width of the box traces.' ].join(' ') }, + }; diff --git a/src/traces/box/cross_trace_calc.js b/src/traces/box/cross_trace_calc.js index d90a8e76a93..cdc20236122 100644 --- a/src/traces/box/cross_trace_calc.js +++ b/src/traces/box/cross_trace_calc.js @@ -48,11 +48,11 @@ function crossTraceCalc(gd, plotinfo) { } } - setPositionOffset('box', gd, boxList, posAxis, [minPad, maxPad], false); + setPositionOffset('box', gd, boxList, posAxis, [minPad, maxPad]); } } -function setPositionOffset(traceType, gd, boxList, posAxis, pad, vwidth) { +function setPositionOffset(traceType, gd, boxList, posAxis, pad) { var calcdata = gd.calcdata; var fullLayout = gd._fullLayout; var pointList = []; @@ -77,11 +77,6 @@ function setPositionOffset(traceType, gd, boxList, posAxis, pad, vwidth) { var boxdv = Lib.distinctVals(pointList); var dPos = boxdv.minDiff / 2; - // override dPos if violin width given - if(vwidth) { - dPos = vwidth; - } - // if there's no duplication of x points, // disable 'group' mode by setting counter to 1 if(pointList.length === boxdv.vals.length) { @@ -105,8 +100,15 @@ function setPositionOffset(traceType, gd, boxList, posAxis, pad, vwidth) { for(i = 0; i < boxList.length; i++) { calcTrace = calcdata[boxList[i]]; - // set the width of all boxes - calcTrace[0].t.dPos = dPos; + // set the width of all boxes and + // override this width with + // trace.width if it exists + if(calcTrace[0].trace && calcTrace[0].trace.vwidth) { + calcTrace[0].t.dPos = calcTrace[0].trace.vwidth; + } else { + calcTrace[0].t.dPos = dPos; + } + // link extremes to all boxes calcTrace[0].trace._extremes[posAxis._id] = extremes; } diff --git a/src/traces/box/defaults.js b/src/traces/box/defaults.js index f15242a3d27..edb7a1ac178 100644 --- a/src/traces/box/defaults.js +++ b/src/traces/box/defaults.js @@ -28,7 +28,13 @@ function supplyDefaults(traceIn, traceOut, defaultColor, layout) { coerce('whiskerwidth'); coerce('boxmean'); - coerce('vwidth'); + + // coerce('vwidth'); + var vwidth = coerce('vwidth'); + if(!vwidth) { + coerce('scalegroup', traceOut.name); + coerce('scalemode'); + } var notched = coerce('notched', traceIn.notchwidth !== undefined); if(notched) coerce('notchwidth'); diff --git a/src/traces/violin/attributes.js b/src/traces/violin/attributes.js index eb83786def0..7d7cc128e0c 100644 --- a/src/traces/violin/attributes.js +++ b/src/traces/violin/attributes.js @@ -12,17 +12,6 @@ var boxAttrs = require('../box/attributes'); var extendFlat = require('../../lib/extend').extendFlat; module.exports = { - vwidth: { - valType: 'number', - min: 0, - role: 'info', - dflt: 0, - editType: 'calc', - description: [ - 'Sets the width of the violins.', - 'This overrides the normal width of the violins.' - ].join(' ') - }, y: boxAttrs.y, x: boxAttrs.x, x0: boxAttrs.x0, @@ -254,5 +243,17 @@ module.exports = { 'Do the hover effects highlight individual violins', 'or sample points or the kernel density estimate or any combination of them?' ].join(' ') - } + }, + + vwidth: { + valType: 'number', + min: 0, + role: 'info', + dflt: 0, + editType: 'calc', + description: [ + 'Sets the width of the violins.', + 'This overrides the normal width of the violins.' + ].join(' ') + }, }; diff --git a/src/traces/violin/cross_trace_calc.js b/src/traces/violin/cross_trace_calc.js index 65d83b8ee94..8a4483b92ec 100644 --- a/src/traces/violin/cross_trace_calc.js +++ b/src/traces/violin/cross_trace_calc.js @@ -43,6 +43,6 @@ module.exports = function crossTraceCalc(gd, plotinfo) { } } - setPositionOffset('violin', gd, violinList, posAxis, [minPad, maxPad], trace.vwidth); + setPositionOffset('violin', gd, violinList, posAxis, [minPad, maxPad]); } }; From 1c6b26b1f0636b65f3d8a24ac8ec1c8a3a4ae2ff Mon Sep 17 00:00:00 2001 From: Kully Date: Fri, 19 Oct 2018 10:47:56 -0400 Subject: [PATCH 05/38] vwidth is now the half width // padding now uses trace.width values if not 0 --- src/traces/box/cross_trace_calc.js | 26 +++++++++++++++++++------- src/traces/box/defaults.js | 9 ++------- src/traces/violin/defaults.js | 9 +++------ 3 files changed, 24 insertions(+), 20 deletions(-) diff --git a/src/traces/box/cross_trace_calc.js b/src/traces/box/cross_trace_calc.js index cdc20236122..67f48a2e8ef 100644 --- a/src/traces/box/cross_trace_calc.js +++ b/src/traces/box/cross_trace_calc.js @@ -90,23 +90,35 @@ function setPositionOffset(traceType, gd, boxList, posAxis, pad) { var groupgap = fullLayout[traceType + 'groupgap']; var padfactor = (1 - gap) * (1 - groupgap) * dPos / fullLayout[numKey]; + // Find maximum trace width + // we baseline this at dPos + var max_half_width = dPos; + for(i = 0; i < boxList.length; i++) { + calcTrace = calcdata[boxList[i]]; + + if(calcTrace[0].trace.vwidth) { + if(calcTrace[0].trace.vwidth / 2 > max_half_width) { + max_half_width = calcTrace[0].trace.vwidth / 2; + } + } + } + // autoscale the x axis - including space for points if they're off the side // TODO: this will overdo it if the outermost boxes don't have // their points as far out as the other boxes var extremes = Axes.findExtremes(posAxis, boxdv.vals, { - vpadminus: dPos + pad[0] * padfactor, - vpadplus: dPos + pad[1] * padfactor + vpadminus: max_half_width + pad[0] * padfactor, + vpadplus: max_half_width + pad[1] * padfactor }); for(i = 0; i < boxList.length; i++) { calcTrace = calcdata[boxList[i]]; - // set the width of all boxes and - // override this width with - // trace.width if it exists + // set the width of all boxes + // override dPos with trace.width if present if(calcTrace[0].trace && calcTrace[0].trace.vwidth) { - calcTrace[0].t.dPos = calcTrace[0].trace.vwidth; + calcTrace[0].t.dPos = calcTrace[0].trace.vwidth / 2; } else { - calcTrace[0].t.dPos = dPos; + calcTrace[0].t.dPos = dPos; } // link extremes to all boxes diff --git a/src/traces/box/defaults.js b/src/traces/box/defaults.js index edb7a1ac178..6ac4cdb1399 100644 --- a/src/traces/box/defaults.js +++ b/src/traces/box/defaults.js @@ -28,13 +28,8 @@ function supplyDefaults(traceIn, traceOut, defaultColor, layout) { coerce('whiskerwidth'); coerce('boxmean'); - - // coerce('vwidth'); - var vwidth = coerce('vwidth'); - if(!vwidth) { - coerce('scalegroup', traceOut.name); - coerce('scalemode'); - } + coerce('vwidth'); + // var vwidth = coerce('vwidth'); var notched = coerce('notched', traceIn.notchwidth !== undefined); if(notched) coerce('notchwidth'); diff --git a/src/traces/violin/defaults.js b/src/traces/violin/defaults.js index 90884e963a1..38f263f3a6d 100644 --- a/src/traces/violin/defaults.js +++ b/src/traces/violin/defaults.js @@ -27,12 +27,9 @@ module.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout coerce('bandwidth'); coerce('side'); - - var vwidth = coerce('vwidth'); - if(!vwidth) { - coerce('scalegroup', traceOut.name); - coerce('scalemode'); - } + coerce('scalegroup', traceOut.name); + coerce('scalemode'); + coerce('vwidth'); var span = coerce('span'); var spanmodeDflt; From 2d93a0e5760239a7708e66ac143eccd74c878640 Mon Sep 17 00:00:00 2001 From: Kully Date: Fri, 19 Oct 2018 10:55:50 -0400 Subject: [PATCH 06/38] vwidth to width --- src/traces/box/attributes.js | 2 +- src/traces/box/cross_trace_calc.js | 10 +++++----- src/traces/box/defaults.js | 3 +-- src/traces/violin/attributes.js | 2 +- src/traces/violin/defaults.js | 2 +- 5 files changed, 9 insertions(+), 10 deletions(-) diff --git a/src/traces/box/attributes.js b/src/traces/box/attributes.js index 52fff380fae..e60d1944caf 100644 --- a/src/traces/box/attributes.js +++ b/src/traces/box/attributes.js @@ -255,7 +255,7 @@ module.exports = { 'or sample points or both?' ].join(' ') }, - vwidth: { + width: { valType: 'number', min: 0, role: 'info', diff --git a/src/traces/box/cross_trace_calc.js b/src/traces/box/cross_trace_calc.js index 67f48a2e8ef..65ba6f51827 100644 --- a/src/traces/box/cross_trace_calc.js +++ b/src/traces/box/cross_trace_calc.js @@ -96,9 +96,9 @@ function setPositionOffset(traceType, gd, boxList, posAxis, pad) { for(i = 0; i < boxList.length; i++) { calcTrace = calcdata[boxList[i]]; - if(calcTrace[0].trace.vwidth) { - if(calcTrace[0].trace.vwidth / 2 > max_half_width) { - max_half_width = calcTrace[0].trace.vwidth / 2; + if(calcTrace[0].trace.width) { + if(calcTrace[0].trace.width / 2 > max_half_width) { + max_half_width = calcTrace[0].trace.width / 2; } } } @@ -115,8 +115,8 @@ function setPositionOffset(traceType, gd, boxList, posAxis, pad) { calcTrace = calcdata[boxList[i]]; // set the width of all boxes // override dPos with trace.width if present - if(calcTrace[0].trace && calcTrace[0].trace.vwidth) { - calcTrace[0].t.dPos = calcTrace[0].trace.vwidth / 2; + if(calcTrace[0].trace && calcTrace[0].trace.width) { + calcTrace[0].t.dPos = calcTrace[0].trace.width / 2; } else { calcTrace[0].t.dPos = dPos; } diff --git a/src/traces/box/defaults.js b/src/traces/box/defaults.js index 6ac4cdb1399..cdd15dcd035 100644 --- a/src/traces/box/defaults.js +++ b/src/traces/box/defaults.js @@ -28,8 +28,7 @@ function supplyDefaults(traceIn, traceOut, defaultColor, layout) { coerce('whiskerwidth'); coerce('boxmean'); - coerce('vwidth'); - // var vwidth = coerce('vwidth'); + coerce('width'); var notched = coerce('notched', traceIn.notchwidth !== undefined); if(notched) coerce('notchwidth'); diff --git a/src/traces/violin/attributes.js b/src/traces/violin/attributes.js index 7d7cc128e0c..22550e5518d 100644 --- a/src/traces/violin/attributes.js +++ b/src/traces/violin/attributes.js @@ -245,7 +245,7 @@ module.exports = { ].join(' ') }, - vwidth: { + width: { valType: 'number', min: 0, role: 'info', diff --git a/src/traces/violin/defaults.js b/src/traces/violin/defaults.js index 38f263f3a6d..aa9c70147d6 100644 --- a/src/traces/violin/defaults.js +++ b/src/traces/violin/defaults.js @@ -29,7 +29,7 @@ module.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout coerce('side'); coerce('scalegroup', traceOut.name); coerce('scalemode'); - coerce('vwidth'); + coerce('width'); var span = coerce('span'); var spanmodeDflt; From 1f9ced861a1438ef05375430db72e913bbd0aa44 Mon Sep 17 00:00:00 2001 From: Kully Date: Fri, 19 Oct 2018 11:03:43 -0400 Subject: [PATCH 07/38] compact the t.dPos assignment with trace.width --- src/traces/box/cross_trace_calc.js | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/traces/box/cross_trace_calc.js b/src/traces/box/cross_trace_calc.js index 65ba6f51827..2e2dea68e00 100644 --- a/src/traces/box/cross_trace_calc.js +++ b/src/traces/box/cross_trace_calc.js @@ -115,11 +115,7 @@ function setPositionOffset(traceType, gd, boxList, posAxis, pad) { calcTrace = calcdata[boxList[i]]; // set the width of all boxes // override dPos with trace.width if present - if(calcTrace[0].trace && calcTrace[0].trace.width) { - calcTrace[0].t.dPos = calcTrace[0].trace.width / 2; - } else { - calcTrace[0].t.dPos = dPos; - } + calcTrace[0].t.dPos = (calcTrace[0].trace.width / 2) || dPos; // link extremes to all boxes calcTrace[0].trace._extremes[posAxis._id] = extremes; From 26f44c4a2309d1716ec50791f53fce58a79c234a Mon Sep 17 00:00:00 2001 From: Kully Date: Fri, 19 Oct 2018 11:13:23 -0400 Subject: [PATCH 08/38] change location of width attribute description to be consistent with other trace types --- src/traces/box/attributes.js | 24 +++++++++++++----------- src/traces/violin/attributes.js | 24 +++++++++++++----------- 2 files changed, 26 insertions(+), 22 deletions(-) diff --git a/src/traces/box/attributes.js b/src/traces/box/attributes.js index e60d1944caf..76a19f5e284 100644 --- a/src/traces/box/attributes.js +++ b/src/traces/box/attributes.js @@ -171,6 +171,19 @@ module.exports = { 'the vertical (horizontal).' ].join(' ') }, + + width: { + valType: 'number', + min: 0, + role: 'info', + dflt: 0, + editType: 'calc', + description: [ + 'Sets the width of the box.', + 'This overrides the normal width of the box traces.' + ].join(' ') + }, + marker: { outliercolor: { valType: 'color', @@ -255,16 +268,5 @@ module.exports = { 'or sample points or both?' ].join(' ') }, - width: { - valType: 'number', - min: 0, - role: 'info', - dflt: 0, - editType: 'calc', - description: [ - 'Sets the width of the box.', - 'This overrides the normal width of the box traces.' - ].join(' ') - }, }; diff --git a/src/traces/violin/attributes.js b/src/traces/violin/attributes.js index 22550e5518d..98121c3ee28 100644 --- a/src/traces/violin/attributes.js +++ b/src/traces/violin/attributes.js @@ -135,6 +135,19 @@ module.exports = { 'right (left) for vertical violins and above (below) for horizontal violins.' ].join(' ') }), + + width: { + valType: 'number', + min: 0, + role: 'info', + dflt: 0, + editType: 'calc', + description: [ + 'Sets the width of the violins.', + 'This overrides the normal width of the violins.' + ].join(' ') + }, + marker: boxAttrs.marker, text: boxAttrs.text, @@ -245,15 +258,4 @@ module.exports = { ].join(' ') }, - width: { - valType: 'number', - min: 0, - role: 'info', - dflt: 0, - editType: 'calc', - description: [ - 'Sets the width of the violins.', - 'This overrides the normal width of the violins.' - ].join(' ') - }, }; From 77b9c9d45bb991c0f4853729a34959960c25df56 Mon Sep 17 00:00:00 2001 From: Kully Date: Fri, 19 Oct 2018 17:10:05 -0400 Subject: [PATCH 09/38] more complete descriptions --- src/traces/box/attributes.js | 3 ++- src/traces/violin/attributes.js | 5 +++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/traces/box/attributes.js b/src/traces/box/attributes.js index 76a19f5e284..485b48331dc 100644 --- a/src/traces/box/attributes.js +++ b/src/traces/box/attributes.js @@ -180,7 +180,8 @@ module.exports = { editType: 'calc', description: [ 'Sets the width of the box.', - 'This overrides the normal width of the box traces.' + 'If *0* (default value) the width is automatically selected based on the positions', + 'of other box traces in the same subplot.', ].join(' ') }, diff --git a/src/traces/violin/attributes.js b/src/traces/violin/attributes.js index 98121c3ee28..a487cb15aa5 100644 --- a/src/traces/violin/attributes.js +++ b/src/traces/violin/attributes.js @@ -143,8 +143,9 @@ module.exports = { dflt: 0, editType: 'calc', description: [ - 'Sets the width of the violins.', - 'This overrides the normal width of the violins.' + 'Sets the width of the violin.', + 'If *0* (default value) the width is automatically selected based on the positions', + 'of other violin traces in the same subplot.', ].join(' ') }, From 243a369169abd8f1517b2d7ac0dfbb94c604a049 Mon Sep 17 00:00:00 2001 From: Kully Date: Mon, 22 Oct 2018 13:31:22 -0400 Subject: [PATCH 10/38] add 1 image test --- .../baselines/violin_box_multiple_widths.png | Bin 0 -> 25660 bytes .../mocks/violin_box_multiple_widths.json | 64 ++++++++++++++++++ 2 files changed, 64 insertions(+) create mode 100644 test/image/baselines/violin_box_multiple_widths.png create mode 100644 test/image/mocks/violin_box_multiple_widths.json diff --git a/test/image/baselines/violin_box_multiple_widths.png b/test/image/baselines/violin_box_multiple_widths.png new file mode 100644 index 0000000000000000000000000000000000000000..b1a23898e42c45bfec16f15ae4d7fb76cb7cf6ad GIT binary patch literal 25660 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 literal 0 HcmV?d00001 diff --git a/test/image/mocks/violin_box_multiple_widths.json b/test/image/mocks/violin_box_multiple_widths.json new file mode 100644 index 00000000000..4ba0a96ca3a --- /dev/null +++ b/test/image/mocks/violin_box_multiple_widths.json @@ -0,0 +1,64 @@ +{ + "data": [{ + "type": "violin", + "width": 0.315, + "x": [0, 5, 7, 8], + "points": "none", + "side": "positive", + "box": { + "visible": false + }, + "boxpoints": false, + "line": { + "color": "black" + }, + "fillcolor": "#8dd3c7", + "opacity": 0.6, + "meanline": { + "visible": false + }, + "y0": 0.0 + }, { + "type": "violin", + "x": [0, 5, 7, 8], + "points": "none", + "side": "positive", + "box": { + "visible": false + }, + "boxpoints": false, + "line": { + "color": "black" + }, + "fillcolor": "#d3c78d", + "opacity": 0.6, + "meanline": { + "visible": false + }, + "y0": 0.1 + }, { + "type": "box", + "width": 0.5421, + "x": [0, 5, 7, 8], + "points": "none", + "side": "positive", + "box": { + "visible": false + }, + "boxpoints": false, + "line": { + "color": "black" + }, + "fillcolor": "#c78dd3", + "opacity": 0.6, + "meanline": { + "visible": false + }, + "y0": 0.2 + }], + "layout": { + "title": "Joyplot - Violin with multiple widths", + "xaxis": {"zeroline": false}, + "violingap": 0 + } +} \ No newline at end of file From eb5e9da1d476351244faff9b69cc9c53d53b9238 Mon Sep 17 00:00:00 2001 From: Kully Date: Mon, 22 Oct 2018 13:35:03 -0400 Subject: [PATCH 11/38] add new line to joyplot mock file --- test/image/mocks/violin_box_multiple_widths.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/image/mocks/violin_box_multiple_widths.json b/test/image/mocks/violin_box_multiple_widths.json index 4ba0a96ca3a..4e885c097fc 100644 --- a/test/image/mocks/violin_box_multiple_widths.json +++ b/test/image/mocks/violin_box_multiple_widths.json @@ -61,4 +61,4 @@ "xaxis": {"zeroline": false}, "violingap": 0 } -} \ No newline at end of file +} From eea273bc08e9b166e439b8b4a3217e763ba3b00b Mon Sep 17 00:00:00 2001 From: Kully Date: Wed, 24 Oct 2018 07:27:33 -0400 Subject: [PATCH 12/38] camelCase --- src/traces/box/cross_trace_calc.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/traces/box/cross_trace_calc.js b/src/traces/box/cross_trace_calc.js index 2e2dea68e00..26d8a627669 100644 --- a/src/traces/box/cross_trace_calc.js +++ b/src/traces/box/cross_trace_calc.js @@ -92,13 +92,13 @@ function setPositionOffset(traceType, gd, boxList, posAxis, pad) { // Find maximum trace width // we baseline this at dPos - var max_half_width = dPos; + var maxHalfWidth = dPos; for(i = 0; i < boxList.length; i++) { calcTrace = calcdata[boxList[i]]; if(calcTrace[0].trace.width) { - if(calcTrace[0].trace.width / 2 > max_half_width) { - max_half_width = calcTrace[0].trace.width / 2; + if(calcTrace[0].trace.width / 2 > maxHalfWidth) { + maxHalfWidth = calcTrace[0].trace.width / 2; } } } @@ -107,8 +107,8 @@ function setPositionOffset(traceType, gd, boxList, posAxis, pad) { // TODO: this will overdo it if the outermost boxes don't have // their points as far out as the other boxes var extremes = Axes.findExtremes(posAxis, boxdv.vals, { - vpadminus: max_half_width + pad[0] * padfactor, - vpadplus: max_half_width + pad[1] * padfactor + vpadminus: maxHalfWidth + pad[0] * padfactor, + vpadplus: maxHalfWidth + pad[1] * padfactor }); for(i = 0; i < boxList.length; i++) { From 408aacb3d9478f94fbf091a706a0b1461c6ff591 Mon Sep 17 00:00:00 2001 From: Kully Date: Wed, 24 Oct 2018 07:31:06 -0400 Subject: [PATCH 13/38] zapped trailing ',' in box/violin attributes --- src/traces/box/attributes.js | 3 +-- src/traces/violin/attributes.js | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/traces/box/attributes.js b/src/traces/box/attributes.js index 485b48331dc..58a4f47bcd8 100644 --- a/src/traces/box/attributes.js +++ b/src/traces/box/attributes.js @@ -268,6 +268,5 @@ module.exports = { 'Do the hover effects highlight individual boxes ', 'or sample points or both?' ].join(' ') - }, - + } }; diff --git a/src/traces/violin/attributes.js b/src/traces/violin/attributes.js index a487cb15aa5..1842ba1fd9a 100644 --- a/src/traces/violin/attributes.js +++ b/src/traces/violin/attributes.js @@ -257,6 +257,5 @@ module.exports = { 'Do the hover effects highlight individual violins', 'or sample points or the kernel density estimate or any combination of them?' ].join(' ') - }, - + } }; From 05552837ac4807536e7948274846d67de57a97d1 Mon Sep 17 00:00:00 2001 From: Kully Date: Wed, 24 Oct 2018 10:36:04 -0400 Subject: [PATCH 14/38] do not coerce scale{mode, group} if no width; otherwise set to dflt value --- src/traces/violin/defaults.js | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/traces/violin/defaults.js b/src/traces/violin/defaults.js index aa9c70147d6..99361ee5a11 100644 --- a/src/traces/violin/defaults.js +++ b/src/traces/violin/defaults.js @@ -27,9 +27,16 @@ module.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout coerce('bandwidth'); coerce('side'); - coerce('scalegroup', traceOut.name); - coerce('scalemode'); - coerce('width'); + + var width = coerce('width'); + if(!width) { + coerce('scalegroup', traceOut.name); + coerce('scalemode'); + } else { + // set scalegroup and scalemode to dflts if width + traceOut.scalegroup = ''; + traceOut.scalemode = 'width'; + } var span = coerce('span'); var spanmodeDflt; From 4eb8b44bc76b1d6957addc63bc497a7f801e6f7e Mon Sep 17 00:00:00 2001 From: Kully Date: Wed, 24 Oct 2018 12:12:26 -0400 Subject: [PATCH 15/38] first pass at calculating extreames for each trace --- src/traces/box/cross_trace_calc.js | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/src/traces/box/cross_trace_calc.js b/src/traces/box/cross_trace_calc.js index 26d8a627669..c61f67054e8 100644 --- a/src/traces/box/cross_trace_calc.js +++ b/src/traces/box/cross_trace_calc.js @@ -13,6 +13,11 @@ var Lib = require('../../lib'); var orientations = ['v', 'h']; + +function getPosition(di) { + return di.pos; +} + function crossTraceCalc(gd, plotinfo) { var calcdata = gd.calcdata; var xa = plotinfo.xaxis; @@ -103,21 +108,19 @@ function setPositionOffset(traceType, gd, boxList, posAxis, pad) { } } - // autoscale the x axis - including space for points if they're off the side - // TODO: this will overdo it if the outermost boxes don't have - // their points as far out as the other boxes - var extremes = Axes.findExtremes(posAxis, boxdv.vals, { - vpadminus: maxHalfWidth + pad[0] * padfactor, - vpadplus: maxHalfWidth + pad[1] * padfactor - }); - for(i = 0; i < boxList.length; i++) { calcTrace = calcdata[boxList[i]]; - // set the width of all boxes + // set the width of this box // override dPos with trace.width if present - calcTrace[0].t.dPos = (calcTrace[0].trace.width / 2) || dPos; - - // link extremes to all boxes + var thisDPos = calcTrace[0].t.dPos = (calcTrace[0].trace.width / 2) || dPos; + var positions = calcTrace.map(getPosition); + // autoscale the x axis - including space for points if they're off the side + // TODO: this will overdo it if the outermost boxes don't have + // their points as far out as the other boxes + var extremes = Axes.findExtremes(posAxis, positions, { + vpadminus: thisDPos + pad[0] * padfactor, + vpadplus: thisDPos + pad[1] * padfactor + }); calcTrace[0].trace._extremes[posAxis._id] = extremes; } From 44e0a888124d1313330f36ba146edd0bd825e642 Mon Sep 17 00:00:00 2001 From: Kully Date: Wed, 24 Oct 2018 12:17:18 -0400 Subject: [PATCH 16/38] fix up the syntax of violin/defaults --- src/traces/violin/defaults.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/traces/violin/defaults.js b/src/traces/violin/defaults.js index 99361ee5a11..8eb3d922efe 100644 --- a/src/traces/violin/defaults.js +++ b/src/traces/violin/defaults.js @@ -27,13 +27,11 @@ module.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout coerce('bandwidth'); coerce('side'); - var width = coerce('width'); if(!width) { coerce('scalegroup', traceOut.name); coerce('scalemode'); } else { - // set scalegroup and scalemode to dflts if width traceOut.scalegroup = ''; traceOut.scalemode = 'width'; } From f8b963bc273527ed2a4544a9e74f8fccd3d287eb Mon Sep 17 00:00:00 2001 From: Kully Date: Wed, 24 Oct 2018 12:52:15 -0400 Subject: [PATCH 17/38] remove old baseline png --- .../baselines/violin_box_multiple_widths.png | Bin 25660 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 test/image/baselines/violin_box_multiple_widths.png diff --git a/test/image/baselines/violin_box_multiple_widths.png b/test/image/baselines/violin_box_multiple_widths.png deleted file mode 100644 index b1a23898e42c45bfec16f15ae4d7fb76cb7cf6ad..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 25660 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 From 54aa355152e03c8c725d5c14318c225827ba3b37 Mon Sep 17 00:00:00 2001 From: Kully Date: Wed, 24 Oct 2018 13:21:19 -0400 Subject: [PATCH 18/38] generated updated joyplot baseline image --- .../baselines/violin_box_multiple_widths.png | Bin 0 -> 27132 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 test/image/baselines/violin_box_multiple_widths.png diff --git a/test/image/baselines/violin_box_multiple_widths.png b/test/image/baselines/violin_box_multiple_widths.png new file mode 100644 index 0000000000000000000000000000000000000000..32bd2ecadcd0fbca238030d3d05582d4150ebfd4 GIT binary patch literal 27132 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%0D$UrjnfSGQ)r?3_G}Y3Zg|vdKMHvw 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 literal 0 HcmV?d00001 From 0d4239b86af76039314a3587b59ae40e09c5d5f7 Mon Sep 17 00:00:00 2001 From: Kully Date: Wed, 24 Oct 2018 15:51:09 -0400 Subject: [PATCH 19/38] remove padding depending on trace.side//regen baseline --- src/traces/box/cross_trace_calc.js | 20 ++++++++++++++++-- .../baselines/violin_box_multiple_widths.png | Bin 27132 -> 27008 bytes 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/traces/box/cross_trace_calc.js b/src/traces/box/cross_trace_calc.js index c61f67054e8..9bcf725f647 100644 --- a/src/traces/box/cross_trace_calc.js +++ b/src/traces/box/cross_trace_calc.js @@ -117,9 +117,25 @@ function setPositionOffset(traceType, gd, boxList, posAxis, pad) { // autoscale the x axis - including space for points if they're off the side // TODO: this will overdo it if the outermost boxes don't have // their points as far out as the other boxes + + var vpadminus = 0; + var vpadplus = 0; + if(calcTrace[0].trace.side) { + if(calcTrace[0].trace.side === 'positive') { + vpadminus = 0; + vpadplus = thisDPos + pad[1] * padfactor; + } else if(calcTrace[0].trace.side === 'negative') { + vpadminus = thisDPos + pad[0] * padfactor; + vpadplus = 0; + } + } else { + vpadminus = thisDPos + pad[0] * padfactor; + vpadplus = thisDPos + pad[1] * padfactor; + } + var extremes = Axes.findExtremes(posAxis, positions, { - vpadminus: thisDPos + pad[0] * padfactor, - vpadplus: thisDPos + pad[1] * padfactor + vpadminus: vpadminus, + vpadplus: vpadplus }); calcTrace[0].trace._extremes[posAxis._id] = extremes; } diff --git a/test/image/baselines/violin_box_multiple_widths.png b/test/image/baselines/violin_box_multiple_widths.png index 32bd2ecadcd0fbca238030d3d05582d4150ebfd4..689bc9e6f1409deb3cbab57c89367cf513dc32f9 100644 GIT binary patch literal 27008 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 literal 27132 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%0D$UrjnfSGQ)r?3_G}Y3Zg|vdKMHvw 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 From fa3a314fb597727ffa3b467a0fa4980e122aed2f Mon Sep 17 00:00:00 2001 From: Kully Date: Wed, 24 Oct 2018 15:56:25 -0400 Subject: [PATCH 20/38] fix space syntax error --- src/traces/violin/defaults.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/traces/violin/defaults.js b/src/traces/violin/defaults.js index 8eb3d922efe..7cb660ec0a3 100644 --- a/src/traces/violin/defaults.js +++ b/src/traces/violin/defaults.js @@ -32,7 +32,7 @@ module.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout coerce('scalegroup', traceOut.name); coerce('scalemode'); } else { - traceOut.scalegroup = ''; + traceOut.scalegroup = ''; traceOut.scalemode = 'width'; } From c63780fa5d138ea5e8a44f372a289a4647b647ac Mon Sep 17 00:00:00 2001 From: Kully Date: Wed, 31 Oct 2018 13:06:17 -0400 Subject: [PATCH 21/38] ... --- src/traces/box/cross_trace_calc.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/traces/box/cross_trace_calc.js b/src/traces/box/cross_trace_calc.js index 9bcf725f647..a1aa399762a 100644 --- a/src/traces/box/cross_trace_calc.js +++ b/src/traces/box/cross_trace_calc.js @@ -117,7 +117,6 @@ function setPositionOffset(traceType, gd, boxList, posAxis, pad) { // autoscale the x axis - including space for points if they're off the side // TODO: this will overdo it if the outermost boxes don't have // their points as far out as the other boxes - var vpadminus = 0; var vpadplus = 0; if(calcTrace[0].trace.side) { From c24330da88d68d360cc58d2d6fafdc1c482f762d Mon Sep 17 00:00:00 2001 From: Kully Date: Thu, 1 Nov 2018 11:10:43 -0400 Subject: [PATCH 22/38] update algo for padding --- src/traces/box/cross_trace_calc.js | 37 +++++++++++++++++++++++------- 1 file changed, 29 insertions(+), 8 deletions(-) diff --git a/src/traces/box/cross_trace_calc.js b/src/traces/box/cross_trace_calc.js index a1aa399762a..9e9f0ee746e 100644 --- a/src/traces/box/cross_trace_calc.js +++ b/src/traces/box/cross_trace_calc.js @@ -117,17 +117,38 @@ function setPositionOffset(traceType, gd, boxList, posAxis, pad) { // autoscale the x axis - including space for points if they're off the side // TODO: this will overdo it if the outermost boxes don't have // their points as far out as the other boxes + + + + // var vpadminus = 0; + // var vpadplus = 0; + // if(calcTrace[0].trace.side) { + // if(calcTrace[0].trace.side === 'positive') { + // vpadminus = 0; + // vpadplus = thisDPos + pad[1] * padfactor; + // } else if(calcTrace[0].trace.side === 'negative') { + // vpadminus = thisDPos + pad[0] * padfactor; + // vpadplus = 0; + // } + // } else { + // vpadminus = thisDPos + pad[0] * padfactor; + // vpadplus = thisDPos + pad[1] * padfactor; + // } + + console.log('*****'); + console.log(calcTrace[0].trace.side); + console.log('*****'); + var vpadminus = 0; var vpadplus = 0; - if(calcTrace[0].trace.side) { - if(calcTrace[0].trace.side === 'positive') { - vpadminus = 0; - vpadplus = thisDPos + pad[1] * padfactor; - } else if(calcTrace[0].trace.side === 'negative') { - vpadminus = thisDPos + pad[0] * padfactor; - vpadplus = 0; - } + if(calcTrace[0].trace.side === 'positive') { + vpadminus = 0; + vpadplus = thisDPos + pad[1] * padfactor; + } else if(calcTrace[0].trace.side === 'negative') { + vpadminus = thisDPos + pad[0] * padfactor; + vpadplus = 0; } else { + // if side === 'both' vpadminus = thisDPos + pad[0] * padfactor; vpadplus = thisDPos + pad[1] * padfactor; } From 6e7883d33ace13648644c9f24b4a2322a1af73f3 Mon Sep 17 00:00:00 2001 From: Kully Date: Thu, 1 Nov 2018 11:41:29 -0400 Subject: [PATCH 23/38] fix test syntax --- src/traces/box/cross_trace_calc.js | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/src/traces/box/cross_trace_calc.js b/src/traces/box/cross_trace_calc.js index 9e9f0ee746e..d28730d89c1 100644 --- a/src/traces/box/cross_trace_calc.js +++ b/src/traces/box/cross_trace_calc.js @@ -117,24 +117,6 @@ function setPositionOffset(traceType, gd, boxList, posAxis, pad) { // autoscale the x axis - including space for points if they're off the side // TODO: this will overdo it if the outermost boxes don't have // their points as far out as the other boxes - - - - // var vpadminus = 0; - // var vpadplus = 0; - // if(calcTrace[0].trace.side) { - // if(calcTrace[0].trace.side === 'positive') { - // vpadminus = 0; - // vpadplus = thisDPos + pad[1] * padfactor; - // } else if(calcTrace[0].trace.side === 'negative') { - // vpadminus = thisDPos + pad[0] * padfactor; - // vpadplus = 0; - // } - // } else { - // vpadminus = thisDPos + pad[0] * padfactor; - // vpadplus = thisDPos + pad[1] * padfactor; - // } - console.log('*****'); console.log(calcTrace[0].trace.side); console.log('*****'); From 37786d6d3dc50b5224c59f941991b3b527486d27 Mon Sep 17 00:00:00 2001 From: Kully Date: Thu, 1 Nov 2018 11:43:57 -0400 Subject: [PATCH 24/38] remove consolve logs --- src/traces/box/cross_trace_calc.js | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/traces/box/cross_trace_calc.js b/src/traces/box/cross_trace_calc.js index d28730d89c1..1fa7d23b85b 100644 --- a/src/traces/box/cross_trace_calc.js +++ b/src/traces/box/cross_trace_calc.js @@ -117,10 +117,6 @@ function setPositionOffset(traceType, gd, boxList, posAxis, pad) { // autoscale the x axis - including space for points if they're off the side // TODO: this will overdo it if the outermost boxes don't have // their points as far out as the other boxes - console.log('*****'); - console.log(calcTrace[0].trace.side); - console.log('*****'); - var vpadminus = 0; var vpadplus = 0; if(calcTrace[0].trace.side === 'positive') { From 45ae47d17e5677d6b102e41b58fb5ebc7b987d8c Mon Sep 17 00:00:00 2001 From: Kully Date: Thu, 1 Nov 2018 15:27:41 -0400 Subject: [PATCH 25/38] update kde line test --- test/jasmine/tests/violin_test.js | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/test/jasmine/tests/violin_test.js b/test/jasmine/tests/violin_test.js index c925b096acb..32d379ef66d 100644 --- a/test/jasmine/tests/violin_test.js +++ b/test/jasmine/tests/violin_test.js @@ -522,7 +522,8 @@ describe('Test violin hover:', function() { it('should show in two-sided base case', function(done) { Plotly.plot(gd, fig).then(function() { mouseEvent('mousemove', 250, 250); - assertViolinHoverLine([299.35, 250, 200.65, 250]); + // assertViolinHoverLine([299.35, 250, 200.65, 250]); + assertViolinHoverLine([178.67823028564453, 250, 80, 250]); }) .catch(failTest) .then(done); @@ -533,7 +534,8 @@ describe('Test violin hover:', function() { Plotly.plot(gd, fig).then(function() { mouseEvent('mousemove', 300, 250); - assertViolinHoverLine([299.35, 250, 250, 250]); + // assertViolinHoverLine([299.35, 250, 250, 250]); + assertViolinHoverLine([178.67823028564453, 250, 80, 250]); }) .catch(failTest) .then(done); @@ -544,7 +546,8 @@ describe('Test violin hover:', function() { Plotly.plot(gd, fig).then(function() { mouseEvent('mousemove', 200, 250); - assertViolinHoverLine([200.65, 250, 250, 250]); + // assertViolinHoverLine([200.65, 250, 250, 250]); + assertViolinHoverLine([321.3217315673828, 250, 420, 250]); }) .catch(failTest) .then(done); From 8366c884504ccb9dedb90a016b731ee5e56b0e67 Mon Sep 17 00:00:00 2001 From: Kully Date: Thu, 1 Nov 2018 15:54:15 -0400 Subject: [PATCH 26/38] more testing with jasmine --- test/jasmine/tests/violin_test.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/jasmine/tests/violin_test.js b/test/jasmine/tests/violin_test.js index 32d379ef66d..e3657c80230 100644 --- a/test/jasmine/tests/violin_test.js +++ b/test/jasmine/tests/violin_test.js @@ -522,8 +522,8 @@ describe('Test violin hover:', function() { it('should show in two-sided base case', function(done) { Plotly.plot(gd, fig).then(function() { mouseEvent('mousemove', 250, 250); - // assertViolinHoverLine([299.35, 250, 200.65, 250]); - assertViolinHoverLine([178.67823028564453, 250, 80, 250]); + assertViolinHoverLine([299.35, 250, 200.65, 250]); + // assertViolinHoverLine([178.67823028564453, 250, 80, 250]); }) .catch(failTest) .then(done); From ce8137702aaefb5011c8b7a3a1f3a1a99a09cd51 Mon Sep 17 00:00:00 2001 From: Kully Date: Thu, 1 Nov 2018 16:07:15 -0400 Subject: [PATCH 27/38] remove commented lines --- test/jasmine/tests/violin_test.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/test/jasmine/tests/violin_test.js b/test/jasmine/tests/violin_test.js index e3657c80230..481a9a463e2 100644 --- a/test/jasmine/tests/violin_test.js +++ b/test/jasmine/tests/violin_test.js @@ -534,7 +534,6 @@ describe('Test violin hover:', function() { Plotly.plot(gd, fig).then(function() { mouseEvent('mousemove', 300, 250); - // assertViolinHoverLine([299.35, 250, 250, 250]); assertViolinHoverLine([178.67823028564453, 250, 80, 250]); }) .catch(failTest) @@ -546,7 +545,6 @@ describe('Test violin hover:', function() { Plotly.plot(gd, fig).then(function() { mouseEvent('mousemove', 200, 250); - // assertViolinHoverLine([200.65, 250, 250, 250]); assertViolinHoverLine([321.3217315673828, 250, 420, 250]); }) .catch(failTest) From 8885b5e8e67ebc2ae94241425880e7b0b183ad18 Mon Sep 17 00:00:00 2001 From: Kully Date: Thu, 1 Nov 2018 17:28:10 -0400 Subject: [PATCH 28/38] remove another commented line and a useless loop --- src/traces/box/cross_trace_calc.js | 10 ---------- test/jasmine/tests/violin_test.js | 1 - 2 files changed, 11 deletions(-) diff --git a/src/traces/box/cross_trace_calc.js b/src/traces/box/cross_trace_calc.js index 1fa7d23b85b..7bf6d0e6766 100644 --- a/src/traces/box/cross_trace_calc.js +++ b/src/traces/box/cross_trace_calc.js @@ -98,16 +98,6 @@ function setPositionOffset(traceType, gd, boxList, posAxis, pad) { // Find maximum trace width // we baseline this at dPos var maxHalfWidth = dPos; - for(i = 0; i < boxList.length; i++) { - calcTrace = calcdata[boxList[i]]; - - if(calcTrace[0].trace.width) { - if(calcTrace[0].trace.width / 2 > maxHalfWidth) { - maxHalfWidth = calcTrace[0].trace.width / 2; - } - } - } - for(i = 0; i < boxList.length; i++) { calcTrace = calcdata[boxList[i]]; // set the width of this box diff --git a/test/jasmine/tests/violin_test.js b/test/jasmine/tests/violin_test.js index 481a9a463e2..a7e973ff1f2 100644 --- a/test/jasmine/tests/violin_test.js +++ b/test/jasmine/tests/violin_test.js @@ -523,7 +523,6 @@ describe('Test violin hover:', function() { Plotly.plot(gd, fig).then(function() { mouseEvent('mousemove', 250, 250); assertViolinHoverLine([299.35, 250, 200.65, 250]); - // assertViolinHoverLine([178.67823028564453, 250, 80, 250]); }) .catch(failTest) .then(done); From 57cc05a9b8645092b8b266ce4ee10cf66bca06cd Mon Sep 17 00:00:00 2001 From: Kully Date: Thu, 1 Nov 2018 17:38:07 -0400 Subject: [PATCH 29/38] remove maxHalfWidth var --- src/traces/box/cross_trace_calc.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/traces/box/cross_trace_calc.js b/src/traces/box/cross_trace_calc.js index 7bf6d0e6766..c56b1e45e03 100644 --- a/src/traces/box/cross_trace_calc.js +++ b/src/traces/box/cross_trace_calc.js @@ -97,7 +97,6 @@ function setPositionOffset(traceType, gd, boxList, posAxis, pad) { // Find maximum trace width // we baseline this at dPos - var maxHalfWidth = dPos; for(i = 0; i < boxList.length; i++) { calcTrace = calcdata[boxList[i]]; // set the width of this box From fe3d7edfdea3aa8e46f07c1c867d1b5c4af186e4 Mon Sep 17 00:00:00 2001 From: Kully Date: Thu, 1 Nov 2018 18:14:11 -0400 Subject: [PATCH 30/38] cleaner code for vpad assignment --- src/traces/box/cross_trace_calc.js | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) diff --git a/src/traces/box/cross_trace_calc.js b/src/traces/box/cross_trace_calc.js index c56b1e45e03..3b4ea006ad0 100644 --- a/src/traces/box/cross_trace_calc.js +++ b/src/traces/box/cross_trace_calc.js @@ -106,20 +106,9 @@ function setPositionOffset(traceType, gd, boxList, posAxis, pad) { // autoscale the x axis - including space for points if they're off the side // TODO: this will overdo it if the outermost boxes don't have // their points as far out as the other boxes - var vpadminus = 0; - var vpadplus = 0; - if(calcTrace[0].trace.side === 'positive') { - vpadminus = 0; - vpadplus = thisDPos + pad[1] * padfactor; - } else if(calcTrace[0].trace.side === 'negative') { - vpadminus = thisDPos + pad[0] * padfactor; - vpadplus = 0; - } else { - // if side === 'both' - vpadminus = thisDPos + pad[0] * padfactor; - vpadplus = thisDPos + pad[1] * padfactor; - } - + var side = calcTrace[0].trace.side; + var vpadminus = (side === 'positive') ? 0 : (thisDPos + pad[0] * padfactor); + var vpadplus = (side === 'negative') ? 0 : (thisDPos + pad[1] * padfactor); var extremes = Axes.findExtremes(posAxis, positions, { vpadminus: vpadminus, vpadplus: vpadplus From 44fa26926c4beaba5bc9f22f7b629bfd498a0cb3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89tienne=20T=C3=A9treault-Pinard?= Date: Tue, 6 Nov 2018 12:07:18 -0500 Subject: [PATCH 31/38] inherit violin 'width' from box.width --- src/traces/violin/attributes.js | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/src/traces/violin/attributes.js b/src/traces/violin/attributes.js index 1842ba1fd9a..8006deda635 100644 --- a/src/traces/violin/attributes.js +++ b/src/traces/violin/attributes.js @@ -136,18 +136,13 @@ module.exports = { ].join(' ') }), - width: { - valType: 'number', - min: 0, - role: 'info', - dflt: 0, - editType: 'calc', + width: extendFlat({}, boxAttrs.width, { description: [ 'Sets the width of the violin.', 'If *0* (default value) the width is automatically selected based on the positions', 'of other violin traces in the same subplot.', ].join(' ') - }, + }), marker: boxAttrs.marker, text: boxAttrs.text, From f5ba38c2184dc5c65a8551adeb6c0b31b901fb78 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89tienne=20T=C3=A9treault-Pinard?= Date: Tue, 6 Nov 2018 12:26:24 -0500 Subject: [PATCH 32/38] rm useless attrs in test mock --- .../mocks/violin_box_multiple_widths.json | 24 ------------------- 1 file changed, 24 deletions(-) diff --git a/test/image/mocks/violin_box_multiple_widths.json b/test/image/mocks/violin_box_multiple_widths.json index 4e885c097fc..d8f8cb54dfd 100644 --- a/test/image/mocks/violin_box_multiple_widths.json +++ b/test/image/mocks/violin_box_multiple_widths.json @@ -3,57 +3,33 @@ "type": "violin", "width": 0.315, "x": [0, 5, 7, 8], - "points": "none", "side": "positive", - "box": { - "visible": false - }, - "boxpoints": false, "line": { "color": "black" }, "fillcolor": "#8dd3c7", "opacity": 0.6, - "meanline": { - "visible": false - }, "y0": 0.0 }, { "type": "violin", "x": [0, 5, 7, 8], - "points": "none", "side": "positive", - "box": { - "visible": false - }, - "boxpoints": false, "line": { "color": "black" }, "fillcolor": "#d3c78d", "opacity": 0.6, - "meanline": { - "visible": false - }, "y0": 0.1 }, { "type": "box", "width": 0.5421, "x": [0, 5, 7, 8], - "points": "none", "side": "positive", - "box": { - "visible": false - }, - "boxpoints": false, "line": { "color": "black" }, "fillcolor": "#c78dd3", "opacity": 0.6, - "meanline": { - "visible": false - }, "y0": 0.2 }], "layout": { From 34722d30de5538ccfd7ff6c2b52c7737e8a7dd74 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89tienne=20T=C3=A9treault-Pinard?= Date: Tue, 6 Nov 2018 16:59:42 -0500 Subject: [PATCH 33/38] mention that 'width' is in data coordinates --- src/traces/box/attributes.js | 4 ++-- src/traces/violin/attributes.js | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/traces/box/attributes.js b/src/traces/box/attributes.js index 58a4f47bcd8..e2f60b39ba1 100644 --- a/src/traces/box/attributes.js +++ b/src/traces/box/attributes.js @@ -179,9 +179,9 @@ module.exports = { dflt: 0, editType: 'calc', description: [ - 'Sets the width of the box.', + 'Sets the width of the box in data coordinate', 'If *0* (default value) the width is automatically selected based on the positions', - 'of other box traces in the same subplot.', + 'of other box traces in the same subplot.' ].join(' ') }, diff --git a/src/traces/violin/attributes.js b/src/traces/violin/attributes.js index 8006deda635..bdf6e3af3dc 100644 --- a/src/traces/violin/attributes.js +++ b/src/traces/violin/attributes.js @@ -138,7 +138,7 @@ module.exports = { width: extendFlat({}, boxAttrs.width, { description: [ - 'Sets the width of the violin.', + 'Sets the width of the violin in data coordinates.', 'If *0* (default value) the width is automatically selected based on the positions', 'of other violin traces in the same subplot.', ].join(' ') From d1aed48c1dc6ba567aed47f904023843545820c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89tienne=20T=C3=A9treault-Pinard?= Date: Tue, 6 Nov 2018 17:01:30 -0500 Subject: [PATCH 34/38] ignore box/violin *gap and *groupgap when 'width' is set --- src/traces/box/layout_attributes.js | 9 ++++-- src/traces/box/plot.js | 21 +++++++++--- src/traces/violin/layout_attributes.js | 9 ++++-- src/traces/violin/plot.js | 30 ++++++++++++++---- .../baselines/violin_box_multiple_widths.png | Bin 27008 -> 29286 bytes .../mocks/violin_box_multiple_widths.json | 10 ++++-- 6 files changed, 60 insertions(+), 19 deletions(-) diff --git a/src/traces/box/layout_attributes.js b/src/traces/box/layout_attributes.js index 2b75d7f4877..38b3658d264 100644 --- a/src/traces/box/layout_attributes.js +++ b/src/traces/box/layout_attributes.js @@ -22,7 +22,8 @@ module.exports = { 'If *group*, the boxes are plotted next to one another', 'centered around the shared location.', 'If *overlay*, the boxes are plotted over one another,', - 'you might need to set *opacity* to see them multiple boxes.' + 'you might need to set *opacity* to see them multiple boxes.', + 'Has no effect on traces that have *width* set.' ].join(' ') }, boxgap: { @@ -34,7 +35,8 @@ module.exports = { editType: 'calc', description: [ 'Sets the gap (in plot fraction) between boxes of', - 'adjacent location coordinates.' + 'adjacent location coordinates.', + 'Has no effect on traces that have *width* set.' ].join(' ') }, boxgroupgap: { @@ -46,7 +48,8 @@ module.exports = { editType: 'calc', description: [ 'Sets the gap (in plot fraction) between boxes of', - 'the same location coordinate.' + 'the same location coordinate.', + 'Has no effect on traces that have *width* set.' ].join(' ') } }; diff --git a/src/traces/box/plot.js b/src/traces/box/plot.js index 236bfe2b7ea..c362db07ada 100644 --- a/src/traces/box/plot.js +++ b/src/traces/box/plot.js @@ -22,8 +22,9 @@ function plot(gd, plotinfo, cdbox, boxLayer) { var xa = plotinfo.xaxis; var ya = plotinfo.yaxis; var numBoxes = fullLayout._numBoxes; - var groupFraction = (1 - fullLayout.boxgap); var group = (fullLayout.boxmode === 'group' && numBoxes > 1); + var groupFraction = (1 - fullLayout.boxgap); + var groupGapFraction = 1 - fullLayout.boxgroupgap; Lib.makeTraceGroups(boxLayer, cdbox, 'trace boxes').each(function(cd) { var plotGroup = d3.select(this); @@ -31,10 +32,22 @@ function plot(gd, plotinfo, cdbox, boxLayer) { var t = cd0.t; var trace = cd0.trace; if(!plotinfo.isRangePlot) cd0.node3 = plotGroup; - // box half width - var bdPos = t.dPos * groupFraction * (1 - fullLayout.boxgroupgap) / (group ? numBoxes : 1); + + // position coordinate delta + var dPos = t.dPos; + // box half width; + var bdPos; // box center offset - var bPos = group ? 2 * t.dPos * (-0.5 + (t.num + 0.5) / numBoxes) * groupFraction : 0; + var bPos; + + if(trace.width) { + bdPos = dPos; + bPos = 0; + } else { + bdPos = dPos * groupFraction * groupGapFraction / (group ? numBoxes : 1); + bPos = group ? 2 * dPos * (-0.5 + (t.num + 0.5) / numBoxes) * groupFraction : 0; + } + // whisker width var wdPos = bdPos * trace.whiskerwidth; diff --git a/src/traces/violin/layout_attributes.js b/src/traces/violin/layout_attributes.js index b02e309c660..ce6f1f2651a 100644 --- a/src/traces/violin/layout_attributes.js +++ b/src/traces/violin/layout_attributes.js @@ -19,19 +19,22 @@ module.exports = { 'If *group*, the violins are plotted next to one another', 'centered around the shared location.', 'If *overlay*, the violins are plotted over one another,', - 'you might need to set *opacity* to see them multiple violins.' + 'you might need to set *opacity* to see them multiple violins.', + 'Has no effect on traces that have *width* set.' ].join(' ') }), violingap: extendFlat({}, boxLayoutAttrs.boxgap, { description: [ 'Sets the gap (in plot fraction) between violins of', - 'adjacent location coordinates.' + 'adjacent location coordinates.', + 'Has no effect on traces that have *width* set.' ].join(' ') }), violingroupgap: extendFlat({}, boxLayoutAttrs.boxgroupgap, { description: [ 'Sets the gap (in plot fraction) between violins of', - 'the same location coordinate.' + 'the same location coordinate.', + 'Has no effect on traces that have *width* set.' ].join(' ') }) }; diff --git a/src/traces/violin/plot.js b/src/traces/violin/plot.js index 43b53a8046e..49126a86e30 100644 --- a/src/traces/violin/plot.js +++ b/src/traces/violin/plot.js @@ -20,6 +20,10 @@ module.exports = function plot(gd, plotinfo, cdViolins, violinLayer) { var fullLayout = gd._fullLayout; var xa = plotinfo.xaxis; var ya = plotinfo.yaxis; + var numViolins = fullLayout._numViolins; + var group = (fullLayout.violinmode === 'group' && numViolins > 1); + var groupFraction = 1 - fullLayout.violingap; + var groupGapFraction = 1 - fullLayout.violingroupgap; function makePath(pts) { var segments = linePoints(pts, { @@ -39,16 +43,30 @@ module.exports = function plot(gd, plotinfo, cdViolins, violinLayer) { var t = cd0.t; var trace = cd0.trace; if(!plotinfo.isRangePlot) cd0.node3 = plotGroup; - var numViolins = fullLayout._numViolins; - var group = (fullLayout.violinmode === 'group' && numViolins > 1); - var groupFraction = 1 - fullLayout.violingap; + + // position coordinate delta + var dPos = t.dPos; // violin max half width - var bdPos = t.bdPos = t.dPos * groupFraction * (1 - fullLayout.violingroupgap) / (group ? numViolins : 1); + var bdPos; // violin center offset - var bPos = t.bPos = group ? 2 * t.dPos * (-0.5 + (t.num + 0.5) / numViolins) * groupFraction : 0; + var bPos; // half-width within which to accept hover for this violin // always split the distance to the closest violin - t.wHover = t.dPos * (group ? groupFraction / numViolins : 1); + var wHover; + + if(trace.width) { + bdPos = dPos; + bPos = 0; + wHover = dPos; + } else { + bdPos = dPos * groupFraction * groupGapFraction / (group ? numViolins : 1); + bPos = group ? 2 * dPos * (-0.5 + (t.num + 0.5) / numViolins) * groupFraction : 0; + wHover = dPos * (group ? groupFraction / numViolins : 1); + } + + t.bdPos = bdPos; + t.bPos = bPos; + t.wHover = wHover; if(trace.visible !== true || t.empty) { plotGroup.remove(); diff --git a/test/image/baselines/violin_box_multiple_widths.png b/test/image/baselines/violin_box_multiple_widths.png index 689bc9e6f1409deb3cbab57c89367cf513dc32f9..d84c0ec8dc3e1e799f9381fc8a6d8d0939af6b05 100644 GIT binary patch literal 29286 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%0A5a|=Kb*8EjRL8xI9Mx+vULLz`J-t;qD_KBk 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 literal 27008 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 diff --git a/test/image/mocks/violin_box_multiple_widths.json b/test/image/mocks/violin_box_multiple_widths.json index d8f8cb54dfd..f8bb39d0f81 100644 --- a/test/image/mocks/violin_box_multiple_widths.json +++ b/test/image/mocks/violin_box_multiple_widths.json @@ -1,7 +1,8 @@ { "data": [{ "type": "violin", - "width": 0.315, + "width": 0.4, + "name": "width: 0.4", "x": [0, 5, 7, 8], "side": "positive", "line": { @@ -12,6 +13,7 @@ "y0": 0.0 }, { "type": "violin", + "name": "auto", "x": [0, 5, 7, 8], "side": "positive", "line": { @@ -22,7 +24,8 @@ "y0": 0.1 }, { "type": "box", - "width": 0.5421, + "width": 0.6, + "name": "width: 0.6", "x": [0, 5, 7, 8], "side": "positive", "line": { @@ -34,7 +37,8 @@ }], "layout": { "title": "Joyplot - Violin with multiple widths", + "legend": {"x": 0}, "xaxis": {"zeroline": false}, - "violingap": 0 + "yaxis": {"dtick": 0.1, "gridcolor": "black"} } } From c70f7d532055af63a2416c0a60167d0f2f81216d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89tienne=20T=C3=A9treault-Pinard?= Date: Tue, 6 Nov 2018 17:03:13 -0500 Subject: [PATCH 35/38] do not coerce scale* attrs when violin 'width' is set - do not fill in fullLayout._violinScaleGroupStats for traces with set 'width' - use maxKDE key instead of maxWidth to avoid confusing --- src/traces/violin/calc.js | 35 +++++++++++++++++++------------ src/traces/violin/defaults.js | 4 +--- src/traces/violin/plot.js | 17 +++++++-------- test/jasmine/tests/violin_test.js | 19 ++++++++++++++++- 4 files changed, 49 insertions(+), 26 deletions(-) diff --git a/src/traces/violin/calc.js b/src/traces/violin/calc.js index 1994f4235c3..52a72e57462 100644 --- a/src/traces/violin/calc.js +++ b/src/traces/violin/calc.js @@ -25,18 +25,10 @@ module.exports = function calc(gd, trace) { trace[trace.orientation === 'h' ? 'xaxis' : 'yaxis'] ); - var violinScaleGroupStats = fullLayout._violinScaleGroupStats; - var scaleGroup = trace.scalegroup; - var groupStats = violinScaleGroupStats[scaleGroup]; - if(!groupStats) { - groupStats = violinScaleGroupStats[scaleGroup] = { - maxWidth: 0, - maxCount: 0 - }; - } - var spanMin = Infinity; var spanMax = -Infinity; + var maxKDE = 0; + var maxCount = 0; for(var i = 0; i < cd.length; i++) { var cdi = cd[i]; @@ -61,12 +53,11 @@ module.exports = function calc(gd, trace) { for(var k = 0, t = span[0]; t < (span[1] + step / 2); k++, t += step) { var v = kde(t); - groupStats.maxWidth = Math.max(groupStats.maxWidth, v); cdi.density[k] = {v: v, t: t}; + maxKDE = Math.max(maxKDE, v); } - groupStats.maxCount = Math.max(groupStats.maxCount, vals.length); - + maxCount = Math.max(maxCount, vals.length); spanMin = Math.min(spanMin, span[0]); spanMax = Math.max(spanMax, span[1]); } @@ -74,6 +65,24 @@ module.exports = function calc(gd, trace) { var extremes = Axes.findExtremes(valAxis, [spanMin, spanMax], {padded: true}); trace._extremes[valAxis._id] = extremes; + if(trace.width) { + cd[0].t.maxKDE = maxKDE; + } else { + var violinScaleGroupStats = fullLayout._violinScaleGroupStats; + var scaleGroup = trace.scalegroup; + var groupStats = violinScaleGroupStats[scaleGroup]; + + if(groupStats) { + groupStats.maxKDE = Math.max(groupStats.maxKDE, maxKDE); + groupStats.maxCount = Math.max(groupStats.maxCount, maxCount); + } else { + violinScaleGroupStats[scaleGroup] = { + maxKDE: maxKDE, + maxCount: maxCount + }; + } + } + cd[0].t.labels.kde = Lib._(gd, 'kde:'); return cd; diff --git a/src/traces/violin/defaults.js b/src/traces/violin/defaults.js index 7cb660ec0a3..3b394518d87 100644 --- a/src/traces/violin/defaults.js +++ b/src/traces/violin/defaults.js @@ -27,13 +27,11 @@ module.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout coerce('bandwidth'); coerce('side'); + var width = coerce('width'); if(!width) { coerce('scalegroup', traceOut.name); coerce('scalemode'); - } else { - traceOut.scalegroup = ''; - traceOut.scalemode = 'width'; } var span = coerce('span'); diff --git a/src/traces/violin/plot.js b/src/traces/violin/plot.js index 49126a86e30..de046a5a9b2 100644 --- a/src/traces/violin/plot.js +++ b/src/traces/violin/plot.js @@ -78,7 +78,6 @@ module.exports = function plot(gd, plotinfo, cdViolins, violinLayer) { var hasBothSides = trace.side === 'both'; var hasPositiveSide = hasBothSides || trace.side === 'positive'; var hasNegativeSide = hasBothSides || trace.side === 'negative'; - var groupStats = fullLayout._violinScaleGroupStats[trace.scalegroup]; var violins = plotGroup.selectAll('path.violin').data(Lib.identity); @@ -94,15 +93,15 @@ module.exports = function plot(gd, plotinfo, cdViolins, violinLayer) { var len = density.length; var posCenter = d.pos + bPos; var posCenterPx = posAxis.c2p(posCenter); - var scale; - switch(trace.scalemode) { - case 'width': - scale = groupStats.maxWidth / bdPos; - break; - case 'count': - scale = (groupStats.maxWidth / bdPos) * (groupStats.maxCount / d.pts.length); - break; + var scale; + if(trace.width) { + scale = t.maxKDE / bdPos; + } else { + var groupStats = fullLayout._violinScaleGroupStats[trace.scalegroup]; + scale = trace.scalemode === 'count' ? + (groupStats.maxKDE / bdPos) * (groupStats.maxCount / d.pts.length) : + groupStats.maxKDE / bdPos; } var pathPos, pathNeg, path; diff --git a/test/jasmine/tests/violin_test.js b/test/jasmine/tests/violin_test.js index a7e973ff1f2..643f7548e5d 100644 --- a/test/jasmine/tests/violin_test.js +++ b/test/jasmine/tests/violin_test.js @@ -142,6 +142,23 @@ describe('Test violin defaults', function() { expect(traceOut.meanline.color).toBe('blue'); expect(traceOut.meanline.width).toBe(10); }); + + it('should not coerce *scalegroup* and *scalemode* when *width* is set', function() { + _supply({ + y: [1, 2, 1], + width: 1 + }); + expect(traceOut.scalemode).toBeUndefined(); + expect(traceOut.scalegroup).toBeUndefined(); + + _supply({ + y: [1, 2, 1], + // width=0 is ignored during calc + width: 0 + }); + expect(traceOut.scalemode).toBe('width'); + expect(traceOut.scalegroup).toBe(''); + }); }); describe('Test violin calc:', function() { @@ -236,7 +253,7 @@ describe('Test violin calc:', function() { name: 'one', y: [0, 0, 0, 0, 10, 10, 10, 10] }); - expect(fullLayout._violinScaleGroupStats.one.maxWidth).toBeCloseTo(0.055); + expect(fullLayout._violinScaleGroupStats.one.maxKDE).toBeCloseTo(0.055); expect(fullLayout._violinScaleGroupStats.one.maxCount).toBe(8); }); From 5e5f9eea3b0587ceb7f4df3bfd87b6a864ac0e01 Mon Sep 17 00:00:00 2001 From: Kully Date: Wed, 7 Nov 2018 13:06:11 -0500 Subject: [PATCH 36/38] vpadplus and minus dont cut off jitter:0 points on violin --- src/traces/box/cross_trace_calc.js | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/traces/box/cross_trace_calc.js b/src/traces/box/cross_trace_calc.js index 3b4ea006ad0..2f0ddc66fc1 100644 --- a/src/traces/box/cross_trace_calc.js +++ b/src/traces/box/cross_trace_calc.js @@ -106,16 +106,20 @@ function setPositionOffset(traceType, gd, boxList, posAxis, pad) { // autoscale the x axis - including space for points if they're off the side // TODO: this will overdo it if the outermost boxes don't have // their points as far out as the other boxes + var trace = calcTrace[0].trace; // for ease of use + var widthMultiplier = (trace.width) ? trace.width : 1; + var alt_padminus = Math.max(Math.abs(calcTrace[0].trace.pointpos) * padfactor * widthMultiplier * fullLayout[numKey], 0); + var alt_vpadplus =Math.max(Math.abs(calcTrace[0].trace.pointpos) * padfactor * widthMultiplier * fullLayout[numKey], 0); + var side = calcTrace[0].trace.side; - var vpadminus = (side === 'positive') ? 0 : (thisDPos + pad[0] * padfactor); - var vpadplus = (side === 'negative') ? 0 : (thisDPos + pad[1] * padfactor); + var vpadminus = (side === 'positive') ? alt_vpadminus: (thisDPos + pad[0] * padfactor); + var vpadplus = (side === 'negative') ? alt_vpadplus : (thisDPos + pad[1] * padfactor); var extremes = Axes.findExtremes(posAxis, positions, { vpadminus: vpadminus, vpadplus: vpadplus }); calcTrace[0].trace._extremes[posAxis._id] = extremes; } - } module.exports = { From 91497e5f4a2dd4c2b360c2ae1bc8304411d0973a Mon Sep 17 00:00:00 2001 From: Kully Date: Wed, 7 Nov 2018 13:09:06 -0500 Subject: [PATCH 37/38] fix incorrect var name --- src/traces/box/cross_trace_calc.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/traces/box/cross_trace_calc.js b/src/traces/box/cross_trace_calc.js index 2f0ddc66fc1..e2e7428712f 100644 --- a/src/traces/box/cross_trace_calc.js +++ b/src/traces/box/cross_trace_calc.js @@ -108,7 +108,7 @@ function setPositionOffset(traceType, gd, boxList, posAxis, pad) { // their points as far out as the other boxes var trace = calcTrace[0].trace; // for ease of use var widthMultiplier = (trace.width) ? trace.width : 1; - var alt_padminus = Math.max(Math.abs(calcTrace[0].trace.pointpos) * padfactor * widthMultiplier * fullLayout[numKey], 0); + var alt_vpadminus = Math.max(Math.abs(calcTrace[0].trace.pointpos) * padfactor * widthMultiplier * fullLayout[numKey], 0); var alt_vpadplus =Math.max(Math.abs(calcTrace[0].trace.pointpos) * padfactor * widthMultiplier * fullLayout[numKey], 0); var side = calcTrace[0].trace.side; From 657848fad9ac475f18d38cbf2f6376ba423f3a09 Mon Sep 17 00:00:00 2001 From: Kully Date: Wed, 7 Nov 2018 13:30:23 -0500 Subject: [PATCH 38/38] small syntax - infix operator spacing --- src/traces/box/cross_trace_calc.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/traces/box/cross_trace_calc.js b/src/traces/box/cross_trace_calc.js index e2e7428712f..e1b629b8b85 100644 --- a/src/traces/box/cross_trace_calc.js +++ b/src/traces/box/cross_trace_calc.js @@ -109,10 +109,10 @@ function setPositionOffset(traceType, gd, boxList, posAxis, pad) { var trace = calcTrace[0].trace; // for ease of use var widthMultiplier = (trace.width) ? trace.width : 1; var alt_vpadminus = Math.max(Math.abs(calcTrace[0].trace.pointpos) * padfactor * widthMultiplier * fullLayout[numKey], 0); - var alt_vpadplus =Math.max(Math.abs(calcTrace[0].trace.pointpos) * padfactor * widthMultiplier * fullLayout[numKey], 0); + var alt_vpadplus = Math.max(Math.abs(calcTrace[0].trace.pointpos) * padfactor * widthMultiplier * fullLayout[numKey], 0); var side = calcTrace[0].trace.side; - var vpadminus = (side === 'positive') ? alt_vpadminus: (thisDPos + pad[0] * padfactor); + var vpadminus = (side === 'positive') ? alt_vpadminus : (thisDPos + pad[0] * padfactor); var vpadplus = (side === 'negative') ? alt_vpadplus : (thisDPos + pad[1] * padfactor); var extremes = Axes.findExtremes(posAxis, positions, { vpadminus: vpadminus,