diff --git a/src/components/colorscale/helpers.js b/src/components/colorscale/helpers.js index 73ca3994476..a2701af7e47 100644 --- a/src/components/colorscale/helpers.js +++ b/src/components/colorscale/helpers.js @@ -17,11 +17,11 @@ var Color = require('../color'); var isValidScale = require('./scales').isValid; -function hasColorscale(trace, containerStr) { +function hasColorscale(trace, containerStr, colorKey) { var container = containerStr ? Lib.nestedProperty(trace, containerStr).get() || {} : trace; - var color = container.color; + var color = container[colorKey || 'color']; var isArrayWithOneNumber = false; if(Lib.isArrayOrTypedArray(color)) { diff --git a/src/traces/sunburst/calc.js b/src/traces/sunburst/calc.js index 007215aaf38..35258a6ac13 100644 --- a/src/traces/sunburst/calc.js +++ b/src/traces/sunburst/calc.js @@ -15,10 +15,7 @@ var Lib = require('../../lib'); var makeColorScaleFn = require('../../components/colorscale').makeColorScaleFuncFromTrace; var makePullColorFn = require('../pie/calc').makePullColorFn; var generateExtendedColors = require('../pie/calc').generateExtendedColors; - -var Colorscale = require('../../components/colorscale'); -var hasColorscale = Colorscale.hasColorscale; -var colorscaleCalc = Colorscale.calc; +var colorscaleCalc = require('../../components/colorscale').calc; var sunburstExtendedColorWays = {}; var treemapExtendedColorWays = {}; @@ -198,9 +195,10 @@ exports.calc = function(gd, trace) { var pullColor; var scaleColor; var colors = trace.marker.colors || []; - trace._hasColorscale = hasColorscale(trace, 'marker'); + var hasColors = !!colors.length; + if(trace._hasColorscale) { - if(!colors.length) { + if(!hasColors) { colors = hasValues ? trace.values : trace._values; } diff --git a/src/traces/sunburst/defaults.js b/src/traces/sunburst/defaults.js index a8f758cbcff..43fb7766675 100644 --- a/src/traces/sunburst/defaults.js +++ b/src/traces/sunburst/defaults.js @@ -44,7 +44,7 @@ module.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout if(lineWidth) coerce('marker.line.color', layout.paper_bgcolor); coerce('marker.colors'); - var withColorscale = hasColorscale(traceIn, 'marker'); + var withColorscale = traceOut._hasColorscale = hasColorscale(traceIn, 'marker', 'colors'); if(withColorscale) { colorscaleDefaults(traceIn, traceOut, layout, coerce, {prefix: 'marker.', cLetter: 'c'}); } diff --git a/src/traces/sunburst/plot.js b/src/traces/sunburst/plot.js index 29ca35091b4..db61cb8d8ed 100644 --- a/src/traces/sunburst/plot.js +++ b/src/traces/sunburst/plot.js @@ -151,7 +151,7 @@ function plotOne(gd, cd, element, transitionOpts) { var transTextX = function(d) { return cx + d.pxmid[0] * d.transform.rCenter + (d.transform.x || 0); }; var transTextY = function(d) { return cy + d.pxmid[1] * d.transform.rCenter + (d.transform.y || 0); }; - slices = slices.data(sliceData, function(pt) { return helpers.getPtId(pt); }); + slices = slices.data(sliceData, helpers.getPtId); slices.enter().append('g') .classed('slice', true); diff --git a/src/traces/treemap/attributes.js b/src/traces/treemap/attributes.js index 58fc9c80a23..aeace5dbdf2 100644 --- a/src/traces/treemap/attributes.js +++ b/src/traces/treemap/attributes.js @@ -139,29 +139,20 @@ module.exports = { colors: sunburstAttrs.marker.colors, - opacitybase: { - valType: 'number', + depthfade: { + valType: 'enumerated', + values: [true, false, 'reversed'], editType: 'style', role: 'style', - min: 0, - max: 1, - dflt: 0.5, description: [ - 'Sets the base opacity of the headers based on the depth from the entry.', - 'This options is not available when having a `colorscale`.' - ].join(' ') - }, - - opacitystep: { - valType: 'number', - editType: 'style', - role: 'style', - min: 0, - max: 1, - dflt: 0.5, - description: [ - 'Sets the increment for opacity of the headers based on the depth from the entry.', - 'This options is not available when having a `colorscale`.' + 'Determines if the sector colors are faded towards', + 'the background from the leaves up to the headers.', + 'This option is unavailable when a `colorscale` is present,', + 'defaults to false when `marker.colors` is set,', + 'but otherwise defaults to true.', + 'When set to *reversed*, the fading direction is inverted,', + 'that is the top elements within hierarchy are drawn with fully saturated colors', + 'while the leaves are faded towards the background color.' ].join(' ') }, @@ -231,18 +222,6 @@ module.exports = { ].join(' ') }, - opacity: { - valType: 'number', - editType: 'style', - role: 'style', - min: 0, - dflt: 0.5, - description: [ - 'Sets the opacity of the pathbar', - 'This options is not available when having a `colorscale`.' - ].join(' ') - }, - textfont: extendFlat({}, pieAttrs.textfont, { description: 'Sets the font used inside `pathbar`.' }), diff --git a/src/traces/treemap/defaults.js b/src/traces/treemap/defaults.js index ef53c076af3..83c144671e1 100644 --- a/src/traces/treemap/defaults.js +++ b/src/traces/treemap/defaults.js @@ -72,8 +72,13 @@ module.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout var lineWidth = coerce('marker.line.width'); if(lineWidth) coerce('marker.line.color', layout.paper_bgcolor); - coerce('marker.colors'); - var withColorscale = hasColorscale(traceIn, 'marker'); + var colors = coerce('marker.colors'); + var withColorscale = traceOut._hasColorscale = hasColorscale(traceIn, 'marker', 'colors'); + if(withColorscale) { + colorscaleDefaults(traceIn, traceOut, layout, coerce, {prefix: 'marker.', cLetter: 'c'}); + } else { + coerce('marker.depthfade', !(colors || []).length); + } var headerSize = traceOut.textfont.size * 2; @@ -84,15 +89,10 @@ module.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout if(withColorscale) { colorscaleDefaults(traceIn, traceOut, layout, coerce, {prefix: 'marker.', cLetter: 'c'}); - } else { - coerce('marker.opacitybase'); - coerce('marker.opacitystep'); - coerce('pathbar.opacity'); } traceOut._hovered = { marker: { - opacity: 1, line: { width: 2, color: Color.contrast(layout.paper_bgcolor) diff --git a/src/traces/treemap/draw_ancestors.js b/src/traces/treemap/draw_ancestors.js index 41f2dfd6637..776a4ccf01a 100644 --- a/src/traces/treemap/draw_ancestors.js +++ b/src/traces/treemap/draw_ancestors.js @@ -73,7 +73,7 @@ module.exports = function drawAncestors(gd, cd, entry, slices, opts) { sliceData.reverse(); - slices = slices.data(sliceData, function(pt) { return helpers.getPtId(pt); }); + slices = slices.data(sliceData, helpers.getPtId); slices.enter().append('g') .classed('pathbar', true); diff --git a/src/traces/treemap/draw_descendants.js b/src/traces/treemap/draw_descendants.js index 6bd1bd5989e..8990ed0ce00 100644 --- a/src/traces/treemap/draw_descendants.js +++ b/src/traces/treemap/draw_descendants.js @@ -65,16 +65,24 @@ module.exports = function drawDescendants(gd, cd, entry, slices, opts) { var sliceData = allData.descendants(); - slices = slices.data(sliceData, function(pt) { - // hide slices that won't show up on graph - if(pt.depth >= trace._maxDepth) { + var minVisibleDepth = Infinity; + var maxVisibleDepth = -Infinity; + sliceData.forEach(function(pt) { + var depth = pt.depth; + if(depth >= trace._maxDepth) { + // hide slices that won't show up on graph pt.x0 = pt.x1 = (pt.x0 + pt.x1) / 2; pt.y0 = pt.y1 = (pt.y0 + pt.y1) / 2; + } else { + minVisibleDepth = Math.min(minVisibleDepth, depth); + maxVisibleDepth = Math.max(maxVisibleDepth, depth); } - - return helpers.getPtId(pt); }); + slices = slices.data(sliceData, helpers.getPtId); + + trace._maxVisibleLayers = isFinite(maxVisibleDepth) ? maxVisibleDepth - minVisibleDepth + 1 : 0; + slices.enter().append('g') .classed('slice', true); @@ -185,14 +193,6 @@ module.exports = function drawDescendants(gd, cd, entry, slices, opts) { isHeader: isHeader }); - if(helpers.isOutsideText(trace, pt)) { - // consider in/out diff font sizes - pt.transform.targetY -= ( - helpers.getOutsideTextFontKey('size', trace, pt, fullLayout.font) - - helpers.getInsideTextFontKey('size', trace, pt, fullLayout.font) - ); - } - if(hasTransition) { sliceText.transition().attrTween('transform', function(pt2) { var interp = makeUpdateTextInterpolator(pt2, onPathbar, getRefRect(), [width, height]); diff --git a/src/traces/treemap/plot.js b/src/traces/treemap/plot.js index df4ee7ad923..c8ba6d0761a 100644 --- a/src/traces/treemap/plot.js +++ b/src/traces/treemap/plot.js @@ -84,6 +84,8 @@ function plotOne(gd, cd, element, transitionOpts) { var hierarchy = cd0.hierarchy; var hasTransition = helpers.hasTransition(transitionOpts); var entry = helpers.findEntryWithLevel(hierarchy, trace.level); + var isRoot = helpers.isHierarchyRoot(entry); + var maxDepth = helpers.getMaxDepth(trace); var hasVisibleDepth = function(pt) { return pt.data.depth - entry.data.depth < maxDepth; @@ -146,18 +148,15 @@ function plotOne(gd, cd, element, transitionOpts) { return {}; }; - var isRoot = helpers.isHierarchyRoot(entry); - - trace._entryDepth = entry.data.depth; - if(isRoot) { - trace._entryDepth++; - } - // N.B. handle multiple-root special case if(cd0.hasMultipleRoots && isRoot) { maxDepth++; } + trace._maxDepth = maxDepth; + trace._backgroundColor = fullLayout.paper_bgcolor; + trace._entryDepth = entry.data.depth; + trace._atRootLevel = isRoot; var cenX = -vpw / 2 + gs.l + gs.w * (domain.x[1] + domain.x[0]) / 2; var cenY = -vph / 2 + gs.t + gs.h * (1 - (domain.y[1] + domain.y[0]) / 2); diff --git a/src/traces/treemap/style.js b/src/traces/treemap/style.js index cecc78c3c93..9ca251a4c4f 100644 --- a/src/traces/treemap/style.js +++ b/src/traces/treemap/style.js @@ -35,37 +35,57 @@ function styleOne(s, pt, trace, opts) { var ptNumber = cdi.i; var lineColor; var lineWidth; - var opacity; - - var depthFade = function(n) { - var base = trace.marker.opacitybase; - var step = trace.marker.opacitystep; - - return n === 0 ? base : - Math.max(0, Math.min(1, n * step)); - }; + var fillColor = cdi.color; + var isRoot = helpers.isHierarchyRoot(pt); + var opacity = 1; if(hovered) { lineColor = trace._hovered.marker.line.color; lineWidth = trace._hovered.marker.line.width; - opacity = trace._hovered.marker.opacity; } else { - if(helpers.isHierarchyRoot(pt)) { + if(isRoot && fillColor === 'rgba(0,0,0,0)') { + opacity = 0; lineColor = 'rgba(0,0,0,0)'; lineWidth = 0; } else { lineColor = Lib.castOption(trace, ptNumber, 'marker.line.color') || Color.defaultLine; lineWidth = Lib.castOption(trace, ptNumber, 'marker.line.width') || 0; - } - opacity = - trace._hasColorscale || helpers.isLeaf(pt) ? 1 : - pt.onPathbar ? trace.pathbar.opacity : - depthFade(pt.data.depth - trace._entryDepth); + if(!trace._hasColorscale && !pt.onPathbar) { + var depthfade = trace.marker.depthfade; + if(depthfade) { + var fadedColor = Color.combine(Color.addOpacity(trace._backgroundColor, 0.75), fillColor); + var n; + + if(depthfade === true) { + var maxDepth = helpers.getMaxDepth(trace); + if(isFinite(maxDepth)) { + if(helpers.isLeaf(pt)) { + n = 0; + } else { + n = (trace._maxVisibleLayers) - (pt.data.depth - trace._entryDepth); + } + } else { + n = pt.data.height + 1; + } + } else { // i.e. case of depthfade === 'reversed' + n = pt.data.depth - trace._entryDepth; + if(!trace._atRootLevel) n++; + } + + if(n > 0) { + for(var i = 0; i < n; i++) { + var ratio = 0.5 * i / n; + fillColor = Color.combine(Color.addOpacity(fadedColor, ratio), fillColor); + } + } + } + } + } } s.style('stroke-width', lineWidth) - .call(Color.fill, cdi.color) + .call(Color.fill, fillColor) .call(Color.stroke, lineColor) .style('opacity', opacity); } diff --git a/test/image/baselines/treemap_coffee-maxdepth3.png b/test/image/baselines/treemap_coffee-maxdepth3.png index 7a3c014df04..d89fc3edc20 100644 Binary files a/test/image/baselines/treemap_coffee-maxdepth3.png and b/test/image/baselines/treemap_coffee-maxdepth3.png differ diff --git a/test/image/baselines/treemap_coffee.png b/test/image/baselines/treemap_coffee.png index f6c02683aca..3b07932be1c 100644 Binary files a/test/image/baselines/treemap_coffee.png and b/test/image/baselines/treemap_coffee.png differ diff --git a/test/image/baselines/treemap_first.png b/test/image/baselines/treemap_first.png index e1a0a76d836..87c04bad4ae 100644 Binary files a/test/image/baselines/treemap_first.png and b/test/image/baselines/treemap_first.png differ diff --git a/test/image/baselines/treemap_flare.png b/test/image/baselines/treemap_flare.png index 6522ebaf127..9b7703e6273 100644 Binary files a/test/image/baselines/treemap_flare.png and b/test/image/baselines/treemap_flare.png differ diff --git a/test/image/baselines/treemap_level-depth.png b/test/image/baselines/treemap_level-depth.png index a254f815c17..6f2aa4ac87b 100644 Binary files a/test/image/baselines/treemap_level-depth.png and b/test/image/baselines/treemap_level-depth.png differ diff --git a/test/image/baselines/treemap_packages_colorscale_allone.png b/test/image/baselines/treemap_packages_colorscale_allone.png index 46daa70c4ea..ed977d1e687 100644 Binary files a/test/image/baselines/treemap_packages_colorscale_allone.png and b/test/image/baselines/treemap_packages_colorscale_allone.png differ diff --git a/test/image/baselines/treemap_packages_colorscale_novalue.png b/test/image/baselines/treemap_packages_colorscale_novalue.png index 28261b046df..6473503b5f9 100644 Binary files a/test/image/baselines/treemap_packages_colorscale_novalue.png and b/test/image/baselines/treemap_packages_colorscale_novalue.png differ diff --git a/test/image/baselines/treemap_packings.png b/test/image/baselines/treemap_packings.png index 4664a239293..bf3d590fd6c 100644 Binary files a/test/image/baselines/treemap_packings.png and b/test/image/baselines/treemap_packings.png differ diff --git a/test/image/baselines/treemap_pad_mirror.png b/test/image/baselines/treemap_pad_mirror.png index e7ff59336e6..7fb51301e03 100644 Binary files a/test/image/baselines/treemap_pad_mirror.png and b/test/image/baselines/treemap_pad_mirror.png differ diff --git a/test/image/baselines/treemap_pad_transpose.png b/test/image/baselines/treemap_pad_transpose.png index b07265c6bc9..f215e78005c 100644 Binary files a/test/image/baselines/treemap_pad_transpose.png and b/test/image/baselines/treemap_pad_transpose.png differ diff --git a/test/image/baselines/treemap_sunburst_basic.png b/test/image/baselines/treemap_sunburst_basic.png new file mode 100644 index 00000000000..c7716c8308c Binary files /dev/null and b/test/image/baselines/treemap_sunburst_basic.png differ diff --git a/test/image/baselines/treemap_sunburst_marker_colors.png b/test/image/baselines/treemap_sunburst_marker_colors.png new file mode 100644 index 00000000000..0790bca81df Binary files /dev/null and b/test/image/baselines/treemap_sunburst_marker_colors.png differ diff --git a/test/image/baselines/treemap_textfit.png b/test/image/baselines/treemap_textfit.png index a56cbff85f3..3d8660f2007 100644 Binary files a/test/image/baselines/treemap_textfit.png and b/test/image/baselines/treemap_textfit.png differ diff --git a/test/image/baselines/treemap_textposition.png b/test/image/baselines/treemap_textposition.png index 25c4daf1137..7b435acc2cb 100644 Binary files a/test/image/baselines/treemap_textposition.png and b/test/image/baselines/treemap_textposition.png differ diff --git a/test/image/baselines/treemap_transpose_nopad.png b/test/image/baselines/treemap_transpose_nopad.png index 43b9ef13a96..c97cc7dbe8e 100644 Binary files a/test/image/baselines/treemap_transpose_nopad.png and b/test/image/baselines/treemap_transpose_nopad.png differ diff --git a/test/image/baselines/treemap_values.png b/test/image/baselines/treemap_values.png index 00dd12be445..2be823d8aef 100644 Binary files a/test/image/baselines/treemap_values.png and b/test/image/baselines/treemap_values.png differ diff --git a/test/image/baselines/treemap_values_colorscale.png b/test/image/baselines/treemap_values_colorscale.png index f89fb5b7fef..2954e59110a 100644 Binary files a/test/image/baselines/treemap_values_colorscale.png and b/test/image/baselines/treemap_values_colorscale.png differ diff --git a/test/image/baselines/treemap_with-without_values.png b/test/image/baselines/treemap_with-without_values.png index 2aaeeba3c73..b6cedec1971 100644 Binary files a/test/image/baselines/treemap_with-without_values.png and b/test/image/baselines/treemap_with-without_values.png differ diff --git a/test/image/baselines/treemap_with-without_values_template.png b/test/image/baselines/treemap_with-without_values_template.png index e0552a8717a..d1905dc32b6 100644 Binary files a/test/image/baselines/treemap_with-without_values_template.png and b/test/image/baselines/treemap_with-without_values_template.png differ diff --git a/test/image/mocks/treemap_pad_mirror.json b/test/image/mocks/treemap_pad_mirror.json index f4872947e51..e0125c53d1f 100644 --- a/test/image/mocks/treemap_pad_mirror.json +++ b/test/image/mocks/treemap_pad_mirror.json @@ -14,8 +14,7 @@ "pad": 0 }, "marker": { - "opacitybase": 0.3, - "opacitystep": 0.1, + "depthfade": "reversed", "pad": { "t": 16, "l": 8, @@ -105,8 +104,7 @@ "pad": 0 }, "marker": { - "opacitybase": 0.3, - "opacitystep": 0.1, + "depthfade": "reversed", "pad": { "t": 16, "l": 8, @@ -196,8 +194,6 @@ "pad": 0 }, "marker": { - "opacitybase": 0.3, - "opacitystep": 0.1, "pad": { "t": 16, "l": 8, @@ -287,8 +283,6 @@ "pad": 0 }, "marker": { - "opacitybase": 0.3, - "opacitystep": 0.1, "pad": { "t": 16, "l": 8, @@ -412,7 +406,7 @@ "annotations": [ { "showarrow": false, - "text": "base", + "text": "base
depthfade: 'reversed'", "font": { "size": 16 }, @@ -423,7 +417,7 @@ }, { "showarrow": false, - "text": "flip y axis", + "text": "flip y axis
depthfade: 'reversed'", "font": { "size": 16 }, diff --git a/test/image/mocks/treemap_pad_transpose.json b/test/image/mocks/treemap_pad_transpose.json index 55d985431b7..f81ecdd5acc 100644 --- a/test/image/mocks/treemap_pad_transpose.json +++ b/test/image/mocks/treemap_pad_transpose.json @@ -14,8 +14,7 @@ "pad": 0 }, "marker": { - "opacitybase": 0.5, - "opacitystep": 0.05, + "depthfade": "reversed", "pad": { "t": 16, "l": 8, @@ -105,8 +104,7 @@ "pad": 0 }, "marker": { - "opacitybase": 0.5, - "opacitystep": 0.05, + "depthfade": "reversed", "pad": { "t": 16, "l": 8, @@ -196,8 +194,6 @@ "pad": 0 }, "marker": { - "opacitybase": 0.5, - "opacitystep": 0.05, "pad": { "t": 16, "l": 8, @@ -287,8 +283,6 @@ "pad": 0 }, "marker": { - "opacitybase": 0.5, - "opacitystep": 0.05, "pad": { "t": 16, "l": 8, @@ -383,8 +377,9 @@ "annotations": [ { "showarrow": false, - "text": "base", + "text": "base
depthfade: 'reversed'", "font": { + "color": "white", "size": 16 }, "x": 0.25, @@ -394,8 +389,9 @@ }, { "showarrow": false, - "text": "flip y axis", + "text": "flip y axis
depthfade: 'reversed'", "font": { + "color": "white", "size": 16 }, "x": 0.25, @@ -407,6 +403,7 @@ "showarrow": false, "text": "flip x axis", "font": { + "color": "white", "size": 16 }, "x": 0.75, @@ -418,6 +415,7 @@ "showarrow": false, "text": "flip both axes", "font": { + "color": "white", "size": 16 }, "x": 0.75, diff --git a/test/image/mocks/treemap_sunburst_basic.json b/test/image/mocks/treemap_sunburst_basic.json new file mode 100644 index 00000000000..f7519e7a0ea --- /dev/null +++ b/test/image/mocks/treemap_sunburst_basic.json @@ -0,0 +1,417 @@ +{ + "data": [ + { + "type": "treemap", + "level": "", + "labels": [ + "A1", + "A2", + "A3", + "A4", + "A5", + "B1", + "B2" + ], + "parents": [ + "", + "A1", + "A2", + "A3", + "A4", + "", + "B1" + ], + "domain": { + "x": [ + 0, + 0.24 + ], + "y": [ + 0.7, + 1 + ] + } + }, + { + "type": "treemap", + "level": "A1", + "labels": [ + "A1", + "A2", + "A3", + "A4", + "A5", + "B1", + "B2" + ], + "parents": [ + "", + "A1", + "A2", + "A3", + "A4", + "", + "B1" + ], + "domain": { + "x": [ + 0, + 0.24 + ], + "y": [ + 0.35, + 0.65 + ] + } + }, + { + "type": "treemap", + "level": "A4", + "labels": [ + "A1", + "A2", + "A3", + "A4", + "A5", + "B1", + "B2" + ], + "parents": [ + "", + "A1", + "A2", + "A3", + "A4", + "", + "B1" + ], + "domain": { + "x": [ + 0, + 0.24 + ], + "y": [ + 0, + 0.3 + ] + } + }, + { + "type": "treemap", + "level": "", + "labels": [ + "C1", + "C2", + "C3", + "C4", + "C5", + "D1", + "D2" + ], + "parents": [ + "Root", + "C1", + "C2", + "C3", + "C4", + "Root", + "D1" + ], + "domain": { + "x": [ + 0.26, + 0.49 + ], + "y": [ + 0.7, + 1 + ] + } + }, + { + "type": "treemap", + "level": "C1", + "labels": [ + "C1", + "C2", + "C3", + "C4", + "C5", + "D1", + "D2" + ], + "parents": [ + "Root", + "C1", + "C2", + "C3", + "C4", + "Root", + "D1" + ], + "domain": { + "x": [ + 0.26, + 0.49 + ], + "y": [ + 0.35, + 0.65 + ] + } + }, + { + "type": "treemap", + "level": "C4", + "labels": [ + "C1", + "C2", + "C3", + "C4", + "C5", + "D1", + "D2" + ], + "parents": [ + "Root", + "C1", + "C2", + "C3", + "C4", + "Root", + "D1" + ], + "domain": { + "x": [ + 0.26, + 0.49 + ], + "y": [ + 0, + 0.3 + ] + } + }, + { + "type": "sunburst", + "level": "", + "labels": [ + "A1", + "A2", + "A3", + "A4", + "A5", + "B1", + "B2" + ], + "parents": [ + "", + "A1", + "A2", + "A3", + "A4", + "", + "B1" + ], + "domain": { + "x": [ + 0.51, + 0.74 + ], + "y": [ + 0.7, + 1 + ] + } + }, + { + "type": "treemap", + "level": "A2", + "maxdepth": 3, + "labels": [ + "A1", + "A2", + "A3", + "A4", + "A5", + "B1", + "B2" + ], + "parents": [ + "", + "A1", + "A2", + "A3", + "A4", + "", + "B1" + ], + "domain": { + "x": [ + 0.51, + 0.74 + ], + "y": [ + 0.35, + 0.65 + ] + } + }, + { + "type": "treemap", + "level": "A2", + "maxdepth": 3, + "marker": { + "depthfade": "reversed" + }, + "labels": [ + "A1", + "A2", + "A3", + "A4", + "A5", + "B1", + "B2" + ], + "parents": [ + "", + "A1", + "A2", + "A3", + "A4", + "", + "B1" + ], + "domain": { + "x": [ + 0.51, + 0.74 + ], + "y": [ + 0, + 0.3 + ] + } + }, + { + "type": "sunburst", + "level": "", + "labels": [ + "C1", + "C2", + "C3", + "C4", + "C5", + "D1", + "D2" + ], + "parents": [ + "Root", + "C1", + "C2", + "C3", + "C4", + "Root", + "D1" + ], + "domain": { + "x": [ + 0.76, + 0.99 + ], + "y": [ + 0.7, + 1 + ] + } + }, + { + "type": "treemap", + "level": "", + "marker": { + "colors": [ + "red", + "green", + "blue", + "yellow", + "magenta", + "orange", + "gray" + ] + }, + "labels": [ + "E1", + "E2", + "E3", + "E4", + "E5", + "F1", + "F2" + ], + "parents": [ + "", + "E1", + "E2", + "E3", + "E4", + "", + "F1" + ], + "domain": { + "x": [ + 0.76, + 0.99 + ], + "y": [ + 0.35, + 0.65 + ] + } + }, + { + "type": "treemap", + "level": "", + "marker": { + "depthfade": "reversed" + }, + "labels": [ + "C1", + "C2", + "C3", + "C4", + "C5", + "B1", + "B2" + ], + "parents": [ + "Root", + "C1", + "C2", + "C3", + "C4", + "Root", + "B1" + ], + "domain": { + "x": [ + 0.76, + 0.99 + ], + "y": [ + 0, + 0.3 + ] + } + } + ], + "layout": { + "width": 1200, + "height": 800, + "margin": { + "t": 0, + "b": 0, + "l": 0, + "r": 0 + } + } +} diff --git a/test/image/mocks/treemap_sunburst_marker_colors.json b/test/image/mocks/treemap_sunburst_marker_colors.json new file mode 100644 index 00000000000..59a21788da1 --- /dev/null +++ b/test/image/mocks/treemap_sunburst_marker_colors.json @@ -0,0 +1,813 @@ +{ + "data": [ + { + "type": "treemap", + "marker": { + "colors": [ + "aquamarine", + "brown", + "chocolate", + "darkblue", + "darkgreen", + "forestgreen", + "gold", + "honeydew", + "indigo", + "navajowhite", + "khaki", + "lightblue", + "magenta", + "navy", + "orange", + "pink", + "aqua", + "red", + "silver", + "tomato", + "turquoise", + "violet", + "wheat", + "yellow", + "azure" + ] + }, + "labels": [ + "Alpha", + "Bravo", + "Charlie", + "Delta", + "Echo", + "Foxtrot", + "Golf", + "Hotel", + "India", + "Juliet", + "Kilo", + "Lima", + "Mike", + "November", + "Oscar", + "Papa", + "Quebec", + "Romeo", + "Sierra", + "Tango", + "Uniform", + "Victor", + "Whiskey", + "X ray", + "Yankee", + "Zulu" + ], + "parents": [ + "", + "Alpha", + "Alpha", + "Charlie", + "Charlie", + "Charlie", + "Foxtrot", + "Foxtrot", + "Foxtrot", + "Foxtrot", + "Juliet", + "Juliet", + "Juliet", + "Juliet", + "Juliet", + "Oscar", + "Oscar", + "Oscar", + "Oscar", + "Oscar", + "Oscar", + "Uniform", + "Uniform", + "Uniform", + "Uniform", + "Uniform", + "Uniform" + ], + "domain": { + "x": [ + 0, + 0.3 + ], + "y": [ + 0, + 0.3 + ] + } + }, + { + "type": "sunburst", + "labels": [ + "Alpha", + "Bravo", + "Charlie", + "Delta", + "Echo", + "Foxtrot", + "Golf", + "Hotel", + "India", + "Juliet", + "Kilo", + "Lima", + "Mike", + "November", + "Oscar", + "Papa", + "Quebec", + "Romeo", + "Sierra", + "Tango", + "Uniform", + "Victor", + "Whiskey", + "X ray", + "Yankee", + "Zulu" + ], + "parents": [ + "", + "Alpha", + "Alpha", + "Charlie", + "Charlie", + "Charlie", + "Foxtrot", + "Foxtrot", + "Foxtrot", + "Foxtrot", + "Juliet", + "Juliet", + "Juliet", + "Juliet", + "Juliet", + "Oscar", + "Oscar", + "Oscar", + "Oscar", + "Oscar", + "Oscar", + "Uniform", + "Uniform", + "Uniform", + "Uniform", + "Uniform", + "Uniform" + ], + "domain": { + "x": [ + 0.35, + 0.65 + ], + "y": [ + 0, + 0.3 + ] + } + }, + { + "type": "treemap", + "text": [ + "aquamarine", + "brown", + "chocolate", + "darkblue", + "darkgreen", + "forestgreen", + "gold", + "honeydew", + "indigo", + "navajowhite", + "khaki", + "lightblue", + "magenta", + "navy", + "orange", + "pink", + "aqua", + "red", + "silver", + "tomato", + "turquoise", + "violet", + "wheat", + "yellow", + "azure" + ], + "labels": [ + "Alpha", + "Bravo", + "Charlie", + "Delta", + "Echo", + "Foxtrot", + "Golf", + "Hotel", + "India", + "Juliet", + "Kilo", + "Lima", + "Mike", + "November", + "Oscar", + "Papa", + "Quebec", + "Romeo", + "Sierra", + "Tango", + "Uniform", + "Victor", + "Whiskey", + "X ray", + "Yankee", + "Zulu" + ], + "parents": [ + "", + "Alpha", + "Alpha", + "Charlie", + "Charlie", + "Charlie", + "Foxtrot", + "Foxtrot", + "Foxtrot", + "Foxtrot", + "Juliet", + "Juliet", + "Juliet", + "Juliet", + "Juliet", + "Oscar", + "Oscar", + "Oscar", + "Oscar", + "Oscar", + "Oscar", + "Uniform", + "Uniform", + "Uniform", + "Uniform", + "Uniform", + "Uniform" + ], + "domain": { + "x": [ + 0.7, + 1 + ], + "y": [ + 0, + 0.3 + ] + } + }, + { + "type": "sunburst", + "marker": { + "colors": [ + "aquamarine", + "brown", + "chocolate", + "darkblue", + "darkgreen", + "forestgreen", + "gold", + "honeydew", + "indigo", + "navajowhite", + "khaki", + "lightblue", + "magenta", + "navy", + "orange", + "pink", + "aqua", + "red", + "silver", + "tomato", + "turquoise", + "violet", + "wheat", + "yellow", + "azure" + ] + }, + "labels": [ + "Alpha", + "Bravo", + "Charlie", + "Delta", + "Echo", + "Foxtrot", + "Golf", + "Hotel", + "India", + "Juliet", + "Kilo", + "Lima", + "Mike", + "November", + "Oscar", + "Papa", + "Quebec", + "Romeo", + "Sierra", + "Tango", + "Uniform", + "Victor", + "Whiskey", + "X ray", + "Yankee", + "Zulu" + ], + "parents": [ + "", + "Alpha", + "Alpha", + "Charlie", + "Charlie", + "Charlie", + "Foxtrot", + "Foxtrot", + "Foxtrot", + "Foxtrot", + "Juliet", + "Juliet", + "Juliet", + "Juliet", + "Juliet", + "Oscar", + "Oscar", + "Oscar", + "Oscar", + "Oscar", + "Oscar", + "Uniform", + "Uniform", + "Uniform", + "Uniform", + "Uniform", + "Uniform" + ], + "domain": { + "x": [ + 0, + 0.3 + ], + "y": [ + 0.35, + 0.65 + ] + } + }, + { + "type": "treemap", + "marker": { + "colors": [ + -12, + -11, + -10, + -9, + -8, + -7, + -6, + -5, + -4, + -3, + -2, + -1, + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13 + ] + }, + "labels": [ + "Alpha", + "Bravo", + "Charlie", + "Delta", + "Echo", + "Foxtrot", + "Golf", + "Hotel", + "India", + "Juliet", + "Kilo", + "Lima", + "Mike", + "November", + "Oscar", + "Papa", + "Quebec", + "Romeo", + "Sierra", + "Tango", + "Uniform", + "Victor", + "Whiskey", + "X ray", + "Yankee", + "Zulu" + ], + "parents": [ + "", + "", + "", + "Bravo", + "Bravo", + "Bravo", + "Echo", + "Echo", + "Echo", + "Hotel", + "Hotel", + "Hotel", + "Kilo", + "Kilo", + "Kilo", + "November", + "November", + "November", + "Quebec", + "Quebec", + "Quebec", + "Tango", + "Tango", + "Tango", + "Whiskey", + "Whiskey" + ], + "level": "Hotel", + "domain": { + "x": [ + 0.35, + 0.65 + ], + "y": [ + 0.35, + 0.65 + ] + } + }, + { + "type": "sunburst", + "labels": [ + "Alpha", + "Bravo", + "Charlie", + "Delta", + "Echo", + "Foxtrot", + "Golf", + "Hotel", + "India", + "Juliet", + "Kilo", + "Lima", + "Mike", + "November", + "Oscar", + "Papa", + "Quebec", + "Romeo", + "Sierra", + "Tango", + "Uniform", + "Victor", + "Whiskey", + "X ray", + "Yankee", + "Zulu" + ], + "parents": [ + "", + "Alpha", + "Alpha", + "Charlie", + "Charlie", + "Charlie", + "Foxtrot", + "Foxtrot", + "Foxtrot", + "Foxtrot", + "Juliet", + "Juliet", + "Juliet", + "Juliet", + "Juliet", + "Oscar", + "Oscar", + "Oscar", + "Oscar", + "Oscar", + "Oscar", + "Uniform", + "Uniform", + "Uniform", + "Uniform", + "Uniform", + "Uniform" + ], + "level": "Foxtrot", + "maxdepth": 3, + "domain": { + "x": [ + 0.7, + 1 + ], + "y": [ + 0.35, + 0.65 + ] + } + }, + { + "type": "treemap", + "labels": [ + "Alpha", + "Bravo", + "Charlie", + "Delta", + "Echo", + "Foxtrot", + "Golf", + "Hotel", + "India", + "Juliet", + "Kilo", + "Lima", + "Mike", + "November", + "Oscar", + "Papa", + "Quebec", + "Romeo", + "Sierra", + "Tango", + "Uniform", + "Victor", + "Whiskey", + "X ray", + "Yankee", + "Zulu" + ], + "parents": [ + "", + "", + "", + "Bravo", + "Bravo", + "Bravo", + "Echo", + "Echo", + "Echo", + "Hotel", + "Hotel", + "Hotel", + "Kilo", + "Kilo", + "Kilo", + "November", + "November", + "November", + "Quebec", + "Quebec", + "Quebec", + "Tango", + "Tango", + "Tango", + "Whiskey", + "Whiskey" + ], + "domain": { + "x": [ + 0, + 0.3 + ], + "y": [ + 0.7, + 1 + ] + } + }, + { + "type": "sunburst", + "marker": { + "colors": [ + -12, + -11, + -10, + -9, + -8, + -7, + -6, + -5, + -4, + -3, + -2, + -1, + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13 + ] + }, + "labels": [ + "Alpha", + "Bravo", + "Charlie", + "Delta", + "Echo", + "Foxtrot", + "Golf", + "Hotel", + "India", + "Juliet", + "Kilo", + "Lima", + "Mike", + "November", + "Oscar", + "Papa", + "Quebec", + "Romeo", + "Sierra", + "Tango", + "Uniform", + "Victor", + "Whiskey", + "X ray", + "Yankee", + "Zulu" + ], + "parents": [ + "", + "", + "", + "Bravo", + "Bravo", + "Bravo", + "Echo", + "Echo", + "Echo", + "Hotel", + "Hotel", + "Hotel", + "Kilo", + "Kilo", + "Kilo", + "November", + "November", + "November", + "Quebec", + "Quebec", + "Quebec", + "Tango", + "Tango", + "Tango", + "Whiskey", + "Whiskey" + ], + "domain": { + "x": [ + 0.35, + 0.65 + ], + "y": [ + 0.7, + 1 + ] + } + }, + { + "type": "treemap", + "text": [ + "aquamarine", + "brown", + "chocolate", + "darkblue", + "darkgreen", + "forestgreen", + "gold", + "honeydew", + "indigo", + "navajowhite", + "khaki", + "lightblue", + "magenta", + "navy", + "orange", + "pink", + "aqua", + "red", + "silver", + "tomato", + "turquoise", + "violet", + "wheat", + "yellow", + "azure" + ], + "labels": [ + "Alpha", + "Bravo", + "Charlie", + "Delta", + "Echo", + "Foxtrot", + "Golf", + "Hotel", + "India", + "Juliet", + "Kilo", + "Lima", + "Mike", + "November", + "Oscar", + "Papa", + "Quebec", + "Romeo", + "Sierra", + "Tango", + "Uniform", + "Victor", + "Whiskey", + "X ray", + "Yankee", + "Zulu" + ], + "parents": [ + "", + "Alpha", + "Alpha", + "Charlie", + "Charlie", + "Charlie", + "Foxtrot", + "Foxtrot", + "Foxtrot", + "Foxtrot", + "Juliet", + "Juliet", + "Juliet", + "Juliet", + "Juliet", + "Oscar", + "Oscar", + "Oscar", + "Oscar", + "Oscar", + "Oscar", + "Uniform", + "Uniform", + "Uniform", + "Uniform", + "Uniform", + "Uniform" + ], + "level": "Foxtrot", + "maxdepth": 3, + "domain": { + "x": [ + 0.7, + 1 + ], + "y": [ + 0.7, + 1 + ] + } + } + ], + "layout": { + "width": 1200, + "height": 1200, + "paper_bgcolor": "black" + } +} diff --git a/test/image/mocks/treemap_textposition.json b/test/image/mocks/treemap_textposition.json index 0657347fa51..b946c74d9a6 100644 --- a/test/image/mocks/treemap_textposition.json +++ b/test/image/mocks/treemap_textposition.json @@ -229,6 +229,7 @@ "family": "Times New Roman" } }, + "marker": { "depthfade": "reversed" }, "text": [ "A L P H A", "B R A V O", @@ -441,6 +442,7 @@ "pathbar": { "visible": false }, + "marker": { "depthfade": "reversed" }, "text": [ "A L P H A", "B R A V O", @@ -656,6 +658,7 @@ "family": "Times New Roman" } }, + "marker": { "depthfade": "reversed" }, "text": [ "A L P H A", "B R A V O", @@ -977,6 +980,6 @@ "layout": { "width": 1200, "height": 1200, - "paper_bgcolor": "#210" + "paper_bgcolor": "black" } } diff --git a/test/image/mocks/treemap_transpose_nopad.json b/test/image/mocks/treemap_transpose_nopad.json index dc22ed0fae3..44b5f3fd9e4 100644 --- a/test/image/mocks/treemap_transpose_nopad.json +++ b/test/image/mocks/treemap_transpose_nopad.json @@ -17,6 +17,7 @@ "pad": 0 }, "marker": { + "depthfade": "reversed", "pad": { "t": 0, "l": 0, @@ -108,6 +109,7 @@ "pad": 0 }, "marker": { + "depthfade": "reversed", "pad": { "t": 0, "l": 0, @@ -371,7 +373,7 @@ "annotations": [ { "showarrow": false, - "text": "square", + "text": "square
depthfade: 'reversed'", "font": { "size": 16 }, @@ -382,7 +384,7 @@ }, { "showarrow": false, - "text": "transposed", + "text": "transposed
depthfade: 'reversed'", "font": { "size": 16 }, diff --git a/test/jasmine/tests/sunburst_test.js b/test/jasmine/tests/sunburst_test.js index c27e6c93af4..64771bb0e38 100644 --- a/test/jasmine/tests/sunburst_test.js +++ b/test/jasmine/tests/sunburst_test.js @@ -115,7 +115,7 @@ describe('Test sunburst defaults:', function() { expect(fullData[1].marker.line.color).toBe('#fff', 'dflt'); }); - it('should default *leaf.opacity* depending on having or not having *colorscale*', function() { + it('should default *leaf.opacity* depending on a *colorscale* being present or not', function() { _supply([ {labels: [1], parents: ['']}, {labels: [1], parents: [''], marker: {colorscale: 'Blues'}} @@ -153,6 +153,31 @@ describe('Test sunburst defaults:', function() { expect(gd._fullLayout.sunburstcolorway) .toEqual(['cyan', 'yellow', 'black'], 'user-defined value'); }); + + it('should not default *marker.colorscale* when *marker.colors* is not present', function() { + _supply([ + {labels: [1], parents: ['']} + ]); + + expect(fullData[0].marker.colorscale).toBe(undefined); + }); + + it('should default *marker.colorscale* to *Reds* when *marker.colors* is present', function() { + _supply([ + {labels: [1], parents: [''], marker: { + colors: [0] + }} + ]); + + expect(fullData[0].marker.colorscale).toBeCloseToArray([ + [ 0, 'rgb(5,10,172)' ], + [ 0.35, 'rgb(106,137,247)' ], + [ 0.5, 'rgb(190,190,190)' ], + [ 0.6, 'rgb(220,170,132)' ], + [ 0.7, 'rgb(230,145,90)' ], + [ 1, 'rgb(178,10,28)' ] + ]); + }); }); describe('Test sunburst calc:', function() { @@ -365,6 +390,108 @@ describe('Test sunburst calc:', function() { [3, 2, 1, 1] ]); }); + + it('should use *marker.colors*', function() { + _calc({ + marker: { colors: ['pink', '#777', '#f00', '#ff0', '#0f0', '#0ff', '#00f', '#f0f', '#fff'] }, + labels: ['Eve', 'Cain', 'Seth', 'Enos', 'Noam', 'Abel', 'Awan', 'Enoch', 'Azura'], + parents: ['', 'Eve', 'Eve', 'Seth', 'Seth', 'Eve', 'Eve', 'Awan', 'Eve'] + }); + + var cd = gd.calcdata[0]; + expect(cd.length).toEqual(9); + expect(cd[0].color).toEqual('rgba(255, 192, 203, 1)'); + expect(cd[1].color).toEqual('rgba(119, 119, 119, 1)'); + expect(cd[2].color).toEqual('rgba(255, 0, 0, 1)'); + expect(cd[3].color).toEqual('rgba(255, 255, 0, 1)'); + expect(cd[4].color).toEqual('rgba(0, 255, 0, 1)'); + expect(cd[5].color).toEqual('rgba(0, 255, 255, 1)'); + expect(cd[6].color).toEqual('rgba(0, 0, 255, 1)'); + expect(cd[7].color).toEqual('rgba(255, 0, 255, 1)'); + expect(cd[8].color).toEqual('rgba(255, 255, 255, 1)'); + }); + + it('should use *marker.colors* numbers with default colorscale', function() { + _calc({ + marker: { colors: [-4, -3, -2, -1, 0, 1, 2, 3, 4] }, + labels: ['Eve', 'Cain', 'Seth', 'Enos', 'Noam', 'Abel', 'Awan', 'Enoch', 'Azura'], + parents: ['', 'Eve', 'Eve', 'Seth', 'Seth', 'Eve', 'Eve', 'Awan', 'Eve'] + }); + + var cd = gd.calcdata[0]; + expect(cd.length).toEqual(9); + expect(cd[0].color).toEqual('rgb(5, 10, 172)'); + expect(cd[1].color).toEqual('rgb(41, 55, 199)'); + expect(cd[2].color).toEqual('rgb(77, 101, 226)'); + expect(cd[3].color).toEqual('rgb(120, 146, 238)'); + expect(cd[4].color).toEqual('rgb(190, 190, 190)'); + expect(cd[5].color).toEqual('rgb(223, 164, 122)'); + expect(cd[6].color).toEqual('rgb(221, 123, 80)'); + expect(cd[7].color).toEqual('rgb(200, 66, 54)'); + expect(cd[8].color).toEqual('rgb(178, 10, 28)'); + }); + + it('should use *marker.colors* numbers with desired colorscale', function() { + _calc({ + marker: { colors: [1, 2, 3, 4, 5, 6, 7, 8, 9], colorscale: 'Portland' }, + labels: ['Eve', 'Cain', 'Seth', 'Enos', 'Noam', 'Abel', 'Awan', 'Enoch', 'Azura'], + parents: ['', 'Eve', 'Eve', 'Seth', 'Seth', 'Eve', 'Eve', 'Awan', 'Eve'] + }); + + var cd = gd.calcdata[0]; + expect(cd.length).toEqual(9); + expect(cd[0].color).toEqual('rgb(12, 51, 131)'); + expect(cd[1].color).toEqual('rgb(11, 94, 159)'); + expect(cd[2].color).toEqual('rgb(10, 136, 186)'); + expect(cd[3].color).toEqual('rgb(126, 174, 121)'); + expect(cd[4].color).toEqual('rgb(242, 211, 56)'); + expect(cd[5].color).toEqual('rgb(242, 177, 56)'); + expect(cd[6].color).toEqual('rgb(242, 143, 56)'); + expect(cd[7].color).toEqual('rgb(230, 87, 43)'); + expect(cd[8].color).toEqual('rgb(217, 30, 30)'); + }); + + it('should use *marker.colors* numbers not values with colorscale', function() { + _calc({ + values: [0.0001, 0.001, 0.01, 0.1, 1, 10, 100, 1000, 10000], + marker: { colors: [1, 2, 3, 4, 5, 6, 7, 8, 9], colorscale: 'Portland' }, + labels: ['Eve', 'Cain', 'Seth', 'Enos', 'Noam', 'Abel', 'Awan', 'Enoch', 'Azura'], + parents: ['', 'Eve', 'Eve', 'Seth', 'Seth', 'Eve', 'Eve', 'Awan', 'Eve'] + }); + + var cd = gd.calcdata[0]; + expect(cd.length).toEqual(9); + expect(cd[0].color).toEqual('rgb(12, 51, 131)'); + expect(cd[1].color).toEqual('rgb(11, 94, 159)'); + expect(cd[2].color).toEqual('rgb(10, 136, 186)'); + expect(cd[3].color).toEqual('rgb(126, 174, 121)'); + expect(cd[4].color).toEqual('rgb(242, 211, 56)'); + expect(cd[5].color).toEqual('rgb(242, 177, 56)'); + expect(cd[6].color).toEqual('rgb(242, 143, 56)'); + expect(cd[7].color).toEqual('rgb(230, 87, 43)'); + expect(cd[8].color).toEqual('rgb(217, 30, 30)'); + }); + + it('should use values with colorscale when *marker.colors* in empty', function() { + _calc({ + values: [1, 2, 3, 4, 5, 6, 7, 8, 9], + marker: { colors: [], colorscale: 'Portland' }, + labels: ['Eve', 'Cain', 'Seth', 'Enos', 'Noam', 'Abel', 'Awan', 'Enoch', 'Azura'], + parents: ['', 'Eve', 'Eve', 'Seth', 'Seth', 'Eve', 'Eve', 'Awan', 'Eve'] + }); + + var cd = gd.calcdata[0]; + expect(cd.length).toEqual(9); + expect(cd[0].color).toEqual('rgb(12, 51, 131)'); + expect(cd[1].color).toEqual('rgb(11, 94, 159)'); + expect(cd[2].color).toEqual('rgb(10, 136, 186)'); + expect(cd[3].color).toEqual('rgb(126, 174, 121)'); + expect(cd[4].color).toEqual('rgb(242, 211, 56)'); + expect(cd[5].color).toEqual('rgb(242, 177, 56)'); + expect(cd[6].color).toEqual('rgb(242, 143, 56)'); + expect(cd[7].color).toEqual('rgb(230, 87, 43)'); + expect(cd[8].color).toEqual('rgb(217, 30, 30)'); + }); }); describe('Test sunburst hover:', function() { diff --git a/test/jasmine/tests/treemap_test.js b/test/jasmine/tests/treemap_test.js index a17266d14f1..d970b98406a 100644 --- a/test/jasmine/tests/treemap_test.js +++ b/test/jasmine/tests/treemap_test.js @@ -116,18 +116,22 @@ describe('Test treemap defaults:', function() { expect(fullData[1].marker.line.color).toBe('#fff', 'dflt'); }); - it('should not coerce *marker.opacitybase*, *marker.opacitybase* and *pathbar.opacity* when having *colorscale*', function() { + it('should default *marker.depthfade* depending on *marker.colors* is present or not', function() { + _supply([ + {labels: ['A', 'B', 'a'], parents: ['', '', 'A']}, + {labels: ['A', 'B', 'a'], parents: ['', '', 'A'], marker: {colors: ['red', 'green', 'blue']}} + ]); + + expect(fullData[0].marker.depthfade).toBe(true); + expect(fullData[1].marker.depthfade).toBe(false); + }); + + it('should not coerce *marker.depthfade* when a *colorscale* is present', function() { _supply([ - {labels: [1], parents: ['']}, {labels: [1], parents: [''], marker: {colorscale: 'Blues'}} ]); - expect(fullData[0].marker.opacitybase).toBe(0.5); - expect(fullData[0].marker.opacitystep).toBe(0.5); - expect(fullData[0].pathbar.opacity).toBe(0.5); - expect(fullData[1].marker.opacitybase).toBe(undefined, 'not coerced'); - expect(fullData[1].marker.opacitystep).toBe(undefined, 'not coerced'); - expect(fullData[1].pathbar.opacity).toBe(undefined, 'not coerced'); + expect(fullData[0].marker.depthfade).toBe(undefined); }); it('should use *textfont.size* to adjust top, bottom , left and right *marker.pad* defaults', function() { @@ -264,6 +268,31 @@ describe('Test treemap defaults:', function() { expect(fullData[0].pathbar.textfont.size).toBe(24); expect(fullData[0].pathbar.thickness).toBe(30); }); + + it('should not default *marker.colorscale* when *marker.colors* is not present', function() { + _supply([ + {labels: [1], parents: ['']} + ]); + + expect(fullData[0].marker.colorscale).toBe(undefined); + }); + + it('should default *marker.colorscale* to *Reds* when *marker.colors* is present', function() { + _supply([ + {labels: [1], parents: [''], marker: { + colors: [0] + }} + ]); + + expect(fullData[0].marker.colorscale).toBeCloseToArray([ + [ 0, 'rgb(5,10,172)' ], + [ 0.35, 'rgb(106,137,247)' ], + [ 0.5, 'rgb(190,190,190)' ], + [ 0.6, 'rgb(220,170,132)' ], + [ 0.7, 'rgb(230,145,90)' ], + [ 1, 'rgb(178,10,28)' ] + ]); + }); }); describe('Test treemap calc:', function() { @@ -428,6 +457,108 @@ describe('Test treemap calc:', function() { expect(extract('id')).toEqual(['true', '1', '2', '3', '4', '5', '6', '7', '8']); expect(extract('pid')).toEqual(['', 'true', 'true', '2', '2', 'true', 'true', '6', 'true']); }); + + it('should use *marker.colors*', function() { + _calc({ + marker: { colors: ['pink', '#777', '#f00', '#ff0', '#0f0', '#0ff', '#00f', '#f0f', '#fff'] }, + labels: ['Eve', 'Cain', 'Seth', 'Enos', 'Noam', 'Abel', 'Awan', 'Enoch', 'Azura'], + parents: ['', 'Eve', 'Eve', 'Seth', 'Seth', 'Eve', 'Eve', 'Awan', 'Eve'] + }); + + var cd = gd.calcdata[0]; + expect(cd.length).toEqual(9); + expect(cd[0].color).toEqual('rgba(255, 192, 203, 1)'); + expect(cd[1].color).toEqual('rgba(119, 119, 119, 1)'); + expect(cd[2].color).toEqual('rgba(255, 0, 0, 1)'); + expect(cd[3].color).toEqual('rgba(255, 255, 0, 1)'); + expect(cd[4].color).toEqual('rgba(0, 255, 0, 1)'); + expect(cd[5].color).toEqual('rgba(0, 255, 255, 1)'); + expect(cd[6].color).toEqual('rgba(0, 0, 255, 1)'); + expect(cd[7].color).toEqual('rgba(255, 0, 255, 1)'); + expect(cd[8].color).toEqual('rgba(255, 255, 255, 1)'); + }); + + it('should use *marker.colors* numbers with default colorscale', function() { + _calc({ + marker: { colors: [-4, -3, -2, -1, 0, 1, 2, 3, 4] }, + labels: ['Eve', 'Cain', 'Seth', 'Enos', 'Noam', 'Abel', 'Awan', 'Enoch', 'Azura'], + parents: ['', 'Eve', 'Eve', 'Seth', 'Seth', 'Eve', 'Eve', 'Awan', 'Eve'] + }); + + var cd = gd.calcdata[0]; + expect(cd.length).toEqual(9); + expect(cd[0].color).toEqual('rgb(5, 10, 172)'); + expect(cd[1].color).toEqual('rgb(41, 55, 199)'); + expect(cd[2].color).toEqual('rgb(77, 101, 226)'); + expect(cd[3].color).toEqual('rgb(120, 146, 238)'); + expect(cd[4].color).toEqual('rgb(190, 190, 190)'); + expect(cd[5].color).toEqual('rgb(223, 164, 122)'); + expect(cd[6].color).toEqual('rgb(221, 123, 80)'); + expect(cd[7].color).toEqual('rgb(200, 66, 54)'); + expect(cd[8].color).toEqual('rgb(178, 10, 28)'); + }); + + it('should use *marker.colors* numbers with desired colorscale', function() { + _calc({ + marker: { colors: [1, 2, 3, 4, 5, 6, 7, 8, 9], colorscale: 'Portland' }, + labels: ['Eve', 'Cain', 'Seth', 'Enos', 'Noam', 'Abel', 'Awan', 'Enoch', 'Azura'], + parents: ['', 'Eve', 'Eve', 'Seth', 'Seth', 'Eve', 'Eve', 'Awan', 'Eve'] + }); + + var cd = gd.calcdata[0]; + expect(cd.length).toEqual(9); + expect(cd[0].color).toEqual('rgb(12, 51, 131)'); + expect(cd[1].color).toEqual('rgb(11, 94, 159)'); + expect(cd[2].color).toEqual('rgb(10, 136, 186)'); + expect(cd[3].color).toEqual('rgb(126, 174, 121)'); + expect(cd[4].color).toEqual('rgb(242, 211, 56)'); + expect(cd[5].color).toEqual('rgb(242, 177, 56)'); + expect(cd[6].color).toEqual('rgb(242, 143, 56)'); + expect(cd[7].color).toEqual('rgb(230, 87, 43)'); + expect(cd[8].color).toEqual('rgb(217, 30, 30)'); + }); + + it('should use *marker.colors* numbers not values with colorscale', function() { + _calc({ + values: [0.0001, 0.001, 0.01, 0.1, 1, 10, 100, 1000, 10000], + marker: { colors: [1, 2, 3, 4, 5, 6, 7, 8, 9], colorscale: 'Portland' }, + labels: ['Eve', 'Cain', 'Seth', 'Enos', 'Noam', 'Abel', 'Awan', 'Enoch', 'Azura'], + parents: ['', 'Eve', 'Eve', 'Seth', 'Seth', 'Eve', 'Eve', 'Awan', 'Eve'] + }); + + var cd = gd.calcdata[0]; + expect(cd.length).toEqual(9); + expect(cd[0].color).toEqual('rgb(12, 51, 131)'); + expect(cd[1].color).toEqual('rgb(11, 94, 159)'); + expect(cd[2].color).toEqual('rgb(10, 136, 186)'); + expect(cd[3].color).toEqual('rgb(126, 174, 121)'); + expect(cd[4].color).toEqual('rgb(242, 211, 56)'); + expect(cd[5].color).toEqual('rgb(242, 177, 56)'); + expect(cd[6].color).toEqual('rgb(242, 143, 56)'); + expect(cd[7].color).toEqual('rgb(230, 87, 43)'); + expect(cd[8].color).toEqual('rgb(217, 30, 30)'); + }); + + it('should use values with colorscale when *marker.colors* in empty', function() { + _calc({ + values: [1, 2, 3, 4, 5, 6, 7, 8, 9], + marker: { colors: [], colorscale: 'Portland' }, + labels: ['Eve', 'Cain', 'Seth', 'Enos', 'Noam', 'Abel', 'Awan', 'Enoch', 'Azura'], + parents: ['', 'Eve', 'Eve', 'Seth', 'Seth', 'Eve', 'Eve', 'Awan', 'Eve'] + }); + + var cd = gd.calcdata[0]; + expect(cd.length).toEqual(9); + expect(cd[0].color).toEqual('rgb(12, 51, 131)'); + expect(cd[1].color).toEqual('rgb(11, 94, 159)'); + expect(cd[2].color).toEqual('rgb(10, 136, 186)'); + expect(cd[3].color).toEqual('rgb(126, 174, 121)'); + expect(cd[4].color).toEqual('rgb(242, 211, 56)'); + expect(cd[5].color).toEqual('rgb(242, 177, 56)'); + expect(cd[6].color).toEqual('rgb(242, 143, 56)'); + expect(cd[7].color).toEqual('rgb(230, 87, 43)'); + expect(cd[8].color).toEqual('rgb(217, 30, 30)'); + }); }); describe('Test treemap hover:', function() { @@ -1065,99 +1196,6 @@ describe('Test treemap restyle:', function() { .then(done); }); - it('should be able to restyle *marker.opacitybase* and *marker.opacitystep*', function(done) { - var mock = { - data: [{ - type: 'treemap', pathbar: { visible: false }, - labels: ['Root', 'A', 'B', 'b', 'b2', 'b3'], - parents: ['', 'Root', 'Root', 'B', 'b', 'b2'] - }] - }; - - function _assert(msg, exp) { - return function() { - var layer = d3.select(gd).select('.treemaplayer'); - - var opacities = []; - layer.selectAll('path.surface').each(function() { - opacities.push(this.style.opacity); - }); - - expect(opacities).toEqual(exp, msg); - - // editType:style - if(msg !== 'base') { - expect(Plots.doCalcdata).toHaveBeenCalledTimes(0); - expect(gd._fullData[0]._module.plot).toHaveBeenCalledTimes(0); - } - }; - } - - Plotly.plot(gd, mock) - .then(_assert('base', ['0', '1', '0.5', '0.5', '1', '1'])) - .then(function() { - spyOn(Plots, 'doCalcdata').and.callThrough(); - spyOn(gd._fullData[0]._module, 'plot').and.callThrough(); - }) - .then(_restyle({'marker.opacitybase': 0.2})) - .then(_assert('lower marker.opacitybase', ['0', '1', '0.2', '0.5', '1', '1'])) - .then(_restyle({'marker.opacitystep': 0.1})) - .then(_assert('lower marker.opacitystep', ['0', '1', '0.2', '0.1', '0.2', '1'])) - .then(_restyle({'marker.opacitybase': 0.8})) - .then(_assert('raise marker.opacitybase', ['0', '1', '0.8', '0.1', '0.2', '1'])) - .then(_restyle({'marker.opacitybase': null})) - .then(_assert('back to dflt', ['0', '1', '0.5', '0.1', '0.2', '1'])) - .then(_restyle({'marker.opacitystep': null})) - .then(_assert('back to dflt', ['0', '1', '0.5', '0.5', '1', '1'])) - .catch(failTest) - .then(done); - }); - - it('should be able to restyle *pathbar.opacity*', function(done) { - var mock = { - data: [{ - type: 'treemap', - labels: ['Root', 'A', 'B', 'b', 'b2', 'b3'], - parents: ['', 'Root', 'Root', 'B', 'b', 'b2'], - level: 'b' - }] - }; - - function _assert(msg, exp) { - return function() { - var layer = d3.select(gd).select('.treemaplayer'); - - var opacities = []; - layer.selectAll('path.surface').each(function() { - opacities.push(this.style.opacity); - }); - - expect(opacities).toEqual(exp, msg); - - // editType:style - if(msg !== 'base') { - expect(Plots.doCalcdata).toHaveBeenCalledTimes(0); - expect(gd._fullData[0]._module.plot).toHaveBeenCalledTimes(0); - } - }; - } - - Plotly.plot(gd, mock) - .then(_assert('base', ['0.5', '0.5', '1', '0.5', '0.5'])) - .then(function() { - spyOn(Plots, 'doCalcdata').and.callThrough(); - spyOn(gd._fullData[0]._module, 'plot').and.callThrough(); - }) - .then(_restyle({'pathbar.opacity': 0.2})) - .then(_assert('lower pathbar.opacity', ['0.5', '0.5', '1', '0.2', '0.2'])) - .then(_restyle({'pathbar.opacity': 0.8})) - .then(_assert('raise pathbar.opacity', ['0.5', '0.5', '1', '0.8', '0.8'])) - .then(_restyle({'pathbar.opacity': null})) - .then(_assert('back to dflt', ['0.5', '0.5', '1', '0.5', '0.5'])) - .catch(failTest) - .then(done); - }); - it('should be able to restyle *textinfo*', function(done) { var mock = { data: [{