diff --git a/draftlogs/6622_add.md b/draftlogs/6622_add.md new file mode 100644 index 00000000000..b60684333f7 --- /dev/null +++ b/draftlogs/6622_add.md @@ -0,0 +1 @@ +add pattern to sunburst trace type [[#6622](https://github.com/plotly/plotly.js/pull/6622)] \ No newline at end of file diff --git a/src/components/drawing/index.js b/src/components/drawing/index.js index b75d6e244c6..93dac647cb3 100644 --- a/src/components/drawing/index.js +++ b/src/components/drawing/index.js @@ -755,6 +755,7 @@ drawing.singlePointStyle = function(d, sel, trace, fns, gd, pt) { var perPointPattern = d.mcc || Lib.isArrayOrTypedArray(markerPattern.shape) || Lib.isArrayOrTypedArray(markerPattern.bgcolor) || + Lib.isArrayOrTypedArray(markerPattern.fgcolor) || Lib.isArrayOrTypedArray(markerPattern.size) || Lib.isArrayOrTypedArray(markerPattern.solidity); diff --git a/src/traces/sunburst/attributes.js b/src/traces/sunburst/attributes.js index a2835e70c25..73a769b8009 100644 --- a/src/traces/sunburst/attributes.js +++ b/src/traces/sunburst/attributes.js @@ -9,6 +9,7 @@ var domainAttrs = require('../../plots/domain').attributes; var pieAttrs = require('../pie/attributes'); var constants = require('./constants'); var extendFlat = require('../../lib/extend').extendFlat; +var pattern = require('../../components/drawing/attributes').pattern; module.exports = { labels: { @@ -113,6 +114,7 @@ module.exports = { width: extendFlat({}, pieAttrs.marker.line.width, {dflt: 1}), editType: 'calc' }, + pattern: pattern, editType: 'calc' }, colorScaleAttrs('marker', { diff --git a/src/traces/sunburst/defaults.js b/src/traces/sunburst/defaults.js index 8f40be23116..330aba75a54 100644 --- a/src/traces/sunburst/defaults.js +++ b/src/traces/sunburst/defaults.js @@ -4,6 +4,7 @@ var Lib = require('../../lib'); var attributes = require('./attributes'); var handleDomainDefaults = require('../../plots/domain').defaults; var handleText = require('../bar/defaults').handleText; +var handleMarkerDefaults = require('../pie/defaults').handleMarkerDefaults; var Colorscale = require('../../components/colorscale'); var hasColorscale = Colorscale.hasColorscale; @@ -32,10 +33,8 @@ module.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout coerce('level'); coerce('maxdepth'); - var lineWidth = coerce('marker.line.width'); - if(lineWidth) coerce('marker.line.color', layout.paper_bgcolor); + handleMarkerDefaults(traceIn, traceOut, layout, coerce, 'sunburst'); - coerce('marker.colors'); var withColorscale = traceOut._hasColorscale = ( hasColorscale(traceIn, 'marker', 'colors') || (traceIn.marker || {}).coloraxis // N.B. special logic to consider "values" colorscales diff --git a/src/traces/sunburst/plot.js b/src/traces/sunburst/plot.js index 94ec88392bc..386dc1bf4ce 100644 --- a/src/traces/sunburst/plot.js +++ b/src/traces/sunburst/plot.js @@ -256,7 +256,7 @@ function plotOne(gd, cd, element, transitionOpts) { isTransitioning: gd._transitioning }); - slicePath.call(styleOne, pt, trace); + slicePath.call(styleOne, pt, trace, gd); var sliceTextGroup = Lib.ensureSingle(sliceTop, 'g', 'slicetext'); var sliceText = Lib.ensureSingle(sliceTextGroup, 'text', '', function(s) { diff --git a/src/traces/sunburst/style.js b/src/traces/sunburst/style.js index 5b563f63cc0..2e5d73fd67c 100644 --- a/src/traces/sunburst/style.js +++ b/src/traces/sunburst/style.js @@ -4,6 +4,7 @@ var d3 = require('@plotly/d3'); var Color = require('../../components/color'); var Lib = require('../../lib'); var resizeText = require('../bar/uniform_text').resizeText; +var Drawing = require('../../components/drawing'); function style(gd) { var s = gd._fullLayout._sunburstlayer.selectAll('.trace'); @@ -17,20 +18,34 @@ function style(gd) { gTrace.style('opacity', trace.opacity); gTrace.selectAll('path.surface').each(function(pt) { - d3.select(this).call(styleOne, pt, trace); + d3.select(this).call(styleOne, pt, trace, gd); }); }); } -function styleOne(s, pt, trace) { +function styleOne(s, pt, trace, gd) { var cdi = pt.data.data; var isLeaf = !pt.children; var ptNumber = cdi.i; var lineColor = Lib.castOption(trace, ptNumber, 'marker.line.color') || Color.defaultLine; var lineWidth = Lib.castOption(trace, ptNumber, 'marker.line.width') || 0; + if(gd && ptNumber >= 0) { + pt.i = cdi.i; + + var marker = trace.marker; + if(marker.pattern) { + if(!marker.colors || !marker.pattern.shape) marker.color = cdi.color; + } else { + marker.color = cdi.color; + } + + Drawing.pointStyle(s, trace, gd, pt); + } else { + Color.fill(s, cdi.color); + } + s.style('stroke-width', lineWidth) - .call(Color.fill, cdi.color) .call(Color.stroke, lineColor) .style('opacity', isLeaf ? trace.leaf.opacity : null); } diff --git a/test/image/baselines/zz-sunburst_pattern.png b/test/image/baselines/zz-sunburst_pattern.png new file mode 100644 index 00000000000..82af2d8741b Binary files /dev/null and b/test/image/baselines/zz-sunburst_pattern.png differ diff --git a/test/image/mocks/zz-sunburst_pattern.json b/test/image/mocks/zz-sunburst_pattern.json new file mode 100644 index 00000000000..98bb77a3e4f --- /dev/null +++ b/test/image/mocks/zz-sunburst_pattern.json @@ -0,0 +1,36 @@ +{ + "data": [ + { + "type": "sunburst", + "textinfo": "label", + "labels": ["Cain", "Seth", "Enos", "Noam", "Abel", "Awan", "Enoch", "Azura"], + "parents": ["Eve", "Eve", "Seth", "Seth", "Eve", "Eve", "Awan", "Eve" ], + "domain": {"x": [0, 0.5]}, + "marker": { + "colors": [ "orange", "steelblue", "steelblue", "steelblue", "green", "red", "red", "purple"] + } + }, + { + "type": "sunburst", + "textinfo": "none", + "labels": ["Cain", "Seth", "Enos", "Noam", "Abel", "Awan", "Enoch", "Azura"], + "parents": ["Eve", "Eve", "Seth", "Seth", "Eve", "Eve", "Awan", "Eve" ], + "domain": {"x": [0.5, 1]}, + "marker": { + "colors": [ "orange", "steelblue", "lightgrey", "lightgrey", "green", "red", "lightgrey", "purple"], + "pattern": { + "shape": ".", + "size": 4 + }, + "line": { + "color": "lightgrey" + } + } + } + ], + "layout": { + "title": { "text": "sunburst with pattern"}, + "width": 800, + "height": 400 + } +} diff --git a/test/plot-schema.json b/test/plot-schema.json index eedddcbeee5..23ea31a4b1c 100644 --- a/test/plot-schema.json +++ b/test/plot-schema.json @@ -67493,6 +67493,99 @@ "valType": "string" } }, + "pattern": { + "bgcolor": { + "arrayOk": true, + "description": "When there is no colorscale sets the color of background pattern fill. Defaults to a `marker.color` background when `fillmode` is *overlay*. Otherwise, defaults to a transparent background.", + "editType": "style", + "valType": "color" + }, + "bgcolorsrc": { + "description": "Sets the source reference on Chart Studio Cloud for `bgcolor`.", + "editType": "none", + "valType": "string" + }, + "description": "Sets the pattern within the marker.", + "editType": "style", + "fgcolor": { + "arrayOk": true, + "description": "When there is no colorscale sets the color of foreground pattern fill. Defaults to a `marker.color` background when `fillmode` is *replace*. Otherwise, defaults to dark grey or white to increase contrast with the `bgcolor`.", + "editType": "style", + "valType": "color" + }, + "fgcolorsrc": { + "description": "Sets the source reference on Chart Studio Cloud for `fgcolor`.", + "editType": "none", + "valType": "string" + }, + "fgopacity": { + "description": "Sets the opacity of the foreground pattern fill. Defaults to a 0.5 when `fillmode` is *overlay*. Otherwise, defaults to 1.", + "editType": "style", + "max": 1, + "min": 0, + "valType": "number" + }, + "fillmode": { + "description": "Determines whether `marker.color` should be used as a default to `bgcolor` or a `fgcolor`.", + "dflt": "replace", + "editType": "style", + "valType": "enumerated", + "values": [ + "replace", + "overlay" + ] + }, + "role": "object", + "shape": { + "arrayOk": true, + "description": "Sets the shape of the pattern fill. By default, no pattern is used for filling the area.", + "dflt": "", + "editType": "style", + "valType": "enumerated", + "values": [ + "", + "/", + "\\", + "x", + "-", + "|", + "+", + "." + ] + }, + "shapesrc": { + "description": "Sets the source reference on Chart Studio Cloud for `shape`.", + "editType": "none", + "valType": "string" + }, + "size": { + "arrayOk": true, + "description": "Sets the size of unit squares of the pattern fill in pixels, which corresponds to the interval of repetition of the pattern.", + "dflt": 8, + "editType": "style", + "min": 0, + "valType": "number" + }, + "sizesrc": { + "description": "Sets the source reference on Chart Studio Cloud for `size`.", + "editType": "none", + "valType": "string" + }, + "solidity": { + "arrayOk": true, + "description": "Sets the solidity of the pattern fill. Solidity is roughly the fraction of the area filled by the pattern. Solidity of 0 shows only the background color without pattern and solidty of 1 shows only the foreground color without pattern.", + "dflt": 0.3, + "editType": "style", + "max": 1, + "min": 0, + "valType": "number" + }, + "soliditysrc": { + "description": "Sets the source reference on Chart Studio Cloud for `solidity`.", + "editType": "none", + "valType": "string" + } + }, "reversescale": { "description": "Reverses the color mapping if true. Has an effect only if colors is set to a numerical array. If true, `marker.cmin` will correspond to the last color in the array and `marker.cmax` will correspond to the first color.", "dflt": false,