diff --git a/src/components/drawing/attributes.js b/src/components/drawing/attributes.js index c0051cef85d..2f73a55daf0 100644 --- a/src/components/drawing/attributes.js +++ b/src/components/drawing/attributes.js @@ -15,3 +15,52 @@ exports.dash = { 'or a dash length list in px (eg *5px,10px,2px,2px*).' ].join(' ') }; + +exports.pattern = { + shape: { + valType: 'enumerated', + values: ['', '/', '\\', 'x', '-', '|', '+', '.'], + dflt: '', + arrayOk: true, + editType: 'style', + description: [ + 'Sets the shape of the pattern fill.', + 'By default, no pattern is used for filling the area.', + ].join(' ') + }, + bgcolor: { + valType: 'color', + arrayOk: true, + editType: 'style', + description: [ + 'Sets the background color of the pattern fill.', + 'Defaults to a transparent background.', + ].join(' ') + }, + size: { + valType: 'number', + min: 0, + dflt: 8, + arrayOk: true, + editType: 'style', + description: [ + 'Sets the size of unit squares of the pattern fill in pixels,', + 'which corresponds to the interval of repetition of the pattern.', + ].join(' ') + }, + solidity: { + valType: 'number', + min: 0, + max: 1, + dflt: 0.3, + arrayOk: true, + editType: 'style', + 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.', + ].join(' ') + }, + editType: 'style' +}; diff --git a/src/lib/coerce.js b/src/lib/coerce.js index 445dd52748c..d6273cd74cd 100644 --- a/src/lib/coerce.js +++ b/src/lib/coerce.js @@ -424,6 +424,18 @@ exports.coerceFont = function(coerce, attr, dfltObj) { return out; }; +/* + * Shortcut to coerce the pattern attributes + */ +exports.coercePattern = function(coerce, attr) { + var shape = coerce(attr + '.shape'); + if(shape) { + coerce(attr + '.size'); + coerce(attr + '.bgcolor'); + coerce(attr + '.solidity'); + } +}; + /** Coerce shortcut for 'hoverinfo' * handling 1-vs-multi-trace dflt logic * diff --git a/src/lib/index.js b/src/lib/index.js index 532fbca8f80..685adcb962b 100644 --- a/src/lib/index.js +++ b/src/lib/index.js @@ -35,6 +35,7 @@ lib.valObjectMeta = coerceModule.valObjectMeta; lib.coerce = coerceModule.coerce; lib.coerce2 = coerceModule.coerce2; lib.coerceFont = coerceModule.coerceFont; +lib.coercePattern = coerceModule.coercePattern; lib.coerceHoverinfo = coerceModule.coerceHoverinfo; lib.coerceSelectionMarkerOpacity = coerceModule.coerceSelectionMarkerOpacity; lib.validate = coerceModule.validate; diff --git a/src/traces/bar/attributes.js b/src/traces/bar/attributes.js index 3e32060afd2..83bf35fd8d1 100644 --- a/src/traces/bar/attributes.js +++ b/src/traces/bar/attributes.js @@ -6,6 +6,7 @@ var texttemplateAttrs = require('../../plots/template_attributes').texttemplateA var colorScaleAttrs = require('../../components/colorscale/attributes'); var fontAttrs = require('../../plots/font_attributes'); var constants = require('./constants'); +var pattern = require('../../components/drawing/attributes').pattern; var extendFlat = require('../../lib/extend').extendFlat; @@ -40,54 +41,7 @@ var marker = extendFlat({ editType: 'style', description: 'Sets the opacity of the bars.' }, - pattern: { - shape: { - valType: 'enumerated', - values: ['', '/', '\\', 'x', '-', '|', '+', '.'], - dflt: '', - arrayOk: true, - editType: 'style', - description: [ - 'Sets the shape of the pattern fill.', - 'By default, no pattern is used for filling the area.', - ].join(' ') - }, - bgcolor: { - valType: 'color', - arrayOk: true, - editType: 'style', - description: [ - 'Sets the background color of the pattern fill.', - 'Defaults to a transparent background.', - ].join(' ') - }, - size: { - valType: 'number', - min: 0, - dflt: 8, - arrayOk: true, - editType: 'style', - description: [ - 'Sets the size of unit squares of the pattern fill in pixels,', - 'which corresponds to the interval of repetition of the pattern.', - ].join(' ') - }, - solidity: { - valType: 'number', - min: 0, - max: 1, - dflt: 0.3, - arrayOk: true, - editType: 'style', - description: [ - 'Sets the solidity of the pattern fill.', - 'Solidity is roughly proportional to the ratio 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.', - ].join(' ') - }, - editType: 'style' - } + pattern: pattern }); module.exports = { diff --git a/src/traces/bar/style_defaults.js b/src/traces/bar/style_defaults.js index b9c20eb7d59..04588b39ea6 100644 --- a/src/traces/bar/style_defaults.js +++ b/src/traces/bar/style_defaults.js @@ -3,6 +3,7 @@ var Color = require('../../components/color'); var hasColorscale = require('../../components/colorscale/helpers').hasColorscale; var colorscaleDefaults = require('../../components/colorscale/defaults'); +var coercePattern = require('../../lib').coercePattern; module.exports = function handleStyleDefaults(traceIn, traceOut, coerce, defaultColor, layout) { coerce('marker.color', defaultColor); @@ -23,12 +24,8 @@ module.exports = function handleStyleDefaults(traceIn, traceOut, coerce, default coerce('marker.line.width'); coerce('marker.opacity'); - var patternShape = coerce('marker.pattern.shape'); - if(patternShape) { - coerce('marker.pattern.bgcolor'); - coerce('marker.pattern.size'); - coerce('marker.pattern.solidity'); - } + coercePattern(coerce, 'marker.pattern'); + coerce('selected.marker.color'); coerce('unselected.marker.color'); }; diff --git a/src/traces/funnel/attributes.js b/src/traces/funnel/attributes.js index dc921f32ec2..f57a9388e84 100644 --- a/src/traces/funnel/attributes.js +++ b/src/traces/funnel/attributes.js @@ -75,7 +75,7 @@ module.exports = { offset: extendFlat({}, barAttrs.offset, {arrayOk: false}), width: extendFlat({}, barAttrs.width, {arrayOk: false}), - marker: barAttrs.marker, + marker: funnelMarker(), connector: { fillcolor: { @@ -108,3 +108,9 @@ module.exports = { offsetgroup: barAttrs.offsetgroup, alignmentgroup: barAttrs.alignmentgroup }; + +function funnelMarker() { + var marker = extendFlat({}, barAttrs.marker); + delete marker.pattern; + return marker; +} diff --git a/test/image/baselines/bar_patternfill.png b/test/image/baselines/bar_patternfill.png deleted file mode 100644 index 0edc8b1dc6e..00000000000 Binary files a/test/image/baselines/bar_patternfill.png and /dev/null differ diff --git a/test/image/baselines/pattern_bars.png b/test/image/baselines/pattern_bars.png new file mode 100644 index 00000000000..2a93a12acd3 Binary files /dev/null and b/test/image/baselines/pattern_bars.png differ diff --git a/test/image/mocks/bar_patternfill.json b/test/image/mocks/bar_patternfill.json deleted file mode 100644 index b25cd4f3e0c..00000000000 --- a/test/image/mocks/bar_patternfill.json +++ /dev/null @@ -1,125 +0,0 @@ -{ - "data": [ - { - "x": [ - "Area 1", - "Area 2", - "Area 3", - "Area 4", - "Area 5" - ], - "y": [ - 20, - 14, - 23, - 30, - 5 - ], - "name": "Product A", - "type": "bar", - "marker": { - "color": "#4477AA", - "line": { - "color": "#4477AA", - "width": 1 - }, - "pattern": { - "shape": "/" - } - } - }, - { - "x": [ - "Area 1", - "Area 2", - "Area 3", - "Area 4", - "Area 5" - ], - "y": [ - 12, - 18, - 29, - 10, - 23 - ], - "name": "Product B", - "type": "bar", - "marker": { - "color": "#CCBB44", - "line": { - "color": "#CCBB44", - "width": 1 - }, - "pattern": { - "shape": "\\" - } - } - }, - { - "x": [ - "Area 1", - "Area 2", - "Area 3", - "Area 4", - "Area 5" - ], - "y": [ - 30, - 23, - 22, - 33, - 15 - ], - "name": "Product C", - "type": "bar", - "marker": { - "color": "#EE6677", - "line": { - "color": "#EE6677", - "width": 1 - }, - "pattern": { - "shape": ["|", "-", "+", "x", "."] - } - } - }, - { - "x": [ - "Area 1", - "Area 2", - "Area 3", - "Area 4", - "Area 5" - ], - "y": [ - 18, - 29, - 31, - 20, - 23 - ], - "name": "Product D", - "type": "bar", - "marker": { - "color": ["#061a0a", "#124d1d", "#1d802f", "#29b342", "#35e655"], - "line": { - "color": ["#061a0a", "#124d1d", "#1d802f", "#29b342", "#35e655"], - "width": 1 - }, - "pattern": { - "shape": ["/", "\\", "x", ".", "+"], - "bgcolor": "#c6eff5", - "size": [4, 6, 8, 10, 12], - "solidity": [0.1, 0.3, 0.5, 0.7, 0.9] - } - } - } - ], - "layout": { - "xaxis": { - "type": "category" - }, - "barmode": "stack" - } -} diff --git a/test/image/mocks/pattern_bars.json b/test/image/mocks/pattern_bars.json new file mode 100644 index 00000000000..6e89e7bd51b --- /dev/null +++ b/test/image/mocks/pattern_bars.json @@ -0,0 +1,209 @@ +{ + "data": [ + { + "x": ["a", "b", "c", "d", "e"], + "y": [1, 2, 3, 4, 5], + "name": "Bar 1", + "type": "bar", + "textposition": "outside", + "text": "bgcolor", + "marker": { + "pattern": { + "shape": "/", + "bgcolor": ["", "lightblue", "blue", "darkblue", "black"] + } + } + }, + { + "x": ["a", "b", "c", "d", "e"], + "y": [2, 3, 4, 5, 6], + "name": "Bar 2", + "type": "bar", + "textposition": "outside", + "text": "shape", + "marker": { + "pattern": { + "shape": ["|", "/", "-", "\\", "|"] + } + } + }, + { + "x": ["a", "b", "c", "d", "e"], + "y": [3, 4, 5, 6, 7], + "name": "Bar 3", + "type": "bar", + "textposition": "outside", + "text": "size", + "marker": { + "pattern": { + "shape": "x", + "size": [4, 6, 8, 10, 12] + } + } + }, + { + "x": ["a", "b", "c", "d", "e"], + "y": [6, 7, 8, 9, 10], + "name": "Bar 4", + "type": "bar", + "textposition": "outside", + "text": "solidity", + "marker": { + "pattern": { + "shape": ".", + "bgcolor": "yellow", + "solidity": [0.1, 0.3, 0.5, 0.7, 0.9] + } + } + }, + + { + "t": ["M", "N", "O", "P"], + "r": [1, 2, 3, 4], + "type": "barpolar", + "name": "Barpolar 1", + "marker": { + "color": "red", + "pattern": { + "shape": "+", + "size": [1, 2, 3, 4] + } + } + }, + { + "t": ["M", "N", "O", "P"], + "r": [2, 3, 4, 1], + "type": "barpolar", + "name": "Barpolar 2", + "marker": { + "color": "rgba(0,127,0,0.5)", + "pattern": { + "shape": "x", + "solidity": 0.75 + } + } + }, + { + "t": ["M", "N", "O", "P"], + "r": [3, 4, 1, 2], + "type": "barpolar", + "name": "Barpolar 3", + "marker": { + "color": "blue", + "pattern": { + "shape": ["|", "-", "|", "-"], + "solidity": 0.5 + } + } + }, + { + "t": ["M", "N", "O", "P"], + "r": [4, 1, 2, 3], + "type": "barpolar", + "name": "Barpolar 4", + "marker": { + "color": "orange", + "pattern": { + "shape": ".", + "bgcolor": "yellow", + "solidity": [0.2, 0.8, 0.6, 0.4] + } + } + }, + + { + "xaxis": "x2", + "yaxis": "y2", + "y": ["A", "A", "A", "A", "B", "B", "C"], + "name": "Histogram 1", + "type": "histogram", + "marker": { + "color": "yellow", + "line": { + "color": "black", + "width": 2 + }, + "pattern": { + "bgcolor": "blue", + "shape": "." + } + } + }, + { + "xaxis": "x2", + "yaxis": "y2", + "y": ["C", "C", "C", "C", "B", "B", "A"], + "name": "Histogram 2", + "type": "histogram", + "marker": { + "color": "yellow", + "line": { + "color": "red", + "width": 4 + }, + "pattern": { + "bgcolor": "rgba(255, 127,0,0.5)", + "shape": "x" + } + } + }, + + { + "xaxis": "x3", + "yaxis": "y3", + "x": [3, 2, 1], + "y": ["U", "V", "W"], + "name": "Funnel", + "type": "funnel", + "marker": { + "pattern": { + "solidity": [0.25, 0.5, 0.75], + "shape": ["|", "", "-"], + "bgcolor": "black" + } + } + } + ], + "layout": { + "title": { + "text": "pattern options" + }, + "width": 1000, + "height": 600, + + "xaxis": { + "domain": [0, 1] + }, + "yaxis": { + "range": [0, 11], + "domain": [0, 0.475] + }, + + "polar": { + "domain": { + "x": [0.35, 0.65], + "y": [0.525, 1] + } + }, + + "xaxis2": { + "anchor": "y2", + "gridcolor": "black", + "gridwidth": 2, + "domain": [0, 0.3] + }, + "yaxis2": { + "anchor": "x2", + "domain": [0.525, 1] + }, + + "xaxis3": { + "anchor": "y3", + "domain": [0.7, 1] + }, + "yaxis3": { + "anchor": "x3", + "domain": [0.525, 1] + } + } +} diff --git a/test/jasmine/tests/mock_test.js b/test/jasmine/tests/mock_test.js index 3898625f1b0..31c55bfd32a 100644 --- a/test/jasmine/tests/mock_test.js +++ b/test/jasmine/tests/mock_test.js @@ -126,7 +126,6 @@ var list = [ 'bar_annotation_max_range_eq_category', 'bar_multiline_labels', 'bar_nonnumeric_sizes', - 'bar_patternfill', 'bar_show_narrow', 'bar_stack-with-gaps', 'bar_stackrelative_negative', @@ -770,6 +769,7 @@ var list = [ 'parcats_numeric_sort', 'parcats_reordered', 'parcats_unbundled', + 'pattern_bars', 'percent_error_bar', 'period_positioning', 'period_positioning2', @@ -1215,7 +1215,6 @@ figs['bar_marker_array'] = require('@mocks/bar_marker_array'); figs['bar_annotation_max_range_eq_category'] = require('@mocks/bar_annotation_max_range_eq_category'); figs['bar_multiline_labels'] = require('@mocks/bar_multiline_labels'); figs['bar_nonnumeric_sizes'] = require('@mocks/bar_nonnumeric_sizes'); -figs['bar_patternfill'] = require('@mocks/bar_patternfill'); figs['bar_show_narrow'] = require('@mocks/bar_show_narrow'); figs['bar_stack-with-gaps'] = require('@mocks/bar_stack-with-gaps'); figs['bar_stackrelative_negative'] = require('@mocks/bar_stackrelative_negative'); @@ -1859,6 +1858,7 @@ figs['parcats_invisible_dimension'] = require('@mocks/parcats_invisible_dimensio figs['parcats_numeric_sort'] = require('@mocks/parcats_numeric_sort'); figs['parcats_reordered'] = require('@mocks/parcats_reordered'); figs['parcats_unbundled'] = require('@mocks/parcats_unbundled'); +figs['pattern_bars'] = require('@mocks/pattern_bars'); figs['percent_error_bar'] = require('@mocks/percent_error_bar'); figs['period_positioning'] = require('@mocks/period_positioning'); figs['period_positioning2'] = require('@mocks/period_positioning2');