|
8 | 8 |
|
9 | 9 | 'use strict';
|
10 | 10 |
|
11 |
| -module.exports = { |
12 |
| - zauto: { |
| 11 | +var palettes = require('./scales.js'); |
| 12 | +var paletteStr = Object.keys(palettes); |
| 13 | + |
| 14 | +function code(s) { |
| 15 | + return '`' + s + '`'; |
| 16 | +} |
| 17 | + |
| 18 | +/** |
| 19 | + * Make colorscale attribute declarations for |
| 20 | + * |
| 21 | + * - colorscale, |
| 22 | + * - (c|z)auto, (c|z)min, (c|z)max, |
| 23 | + * - autocolorscale, reversescale, |
| 24 | + * - showscale (optionally) |
| 25 | + * - color (optionally) |
| 26 | + * |
| 27 | + * @param {string} context (dflt: '', i.e. from trace root): |
| 28 | + * the container this is in ('', *marker*, *marker.line* etc) |
| 29 | + * |
| 30 | + * @param {object} opts: |
| 31 | + * - cLetter {string} (dflt: 'c'): |
| 32 | + * leading letter for 'min', 'max and 'auto' attribute (either 'z' or 'c') |
| 33 | + * |
| 34 | + * - colorAttr {string} (dflt: 'z' if `cLetter: 'z'`, 'color' if `cLetter: 'c'`): |
| 35 | + * (for descriptions) sets the name of the color attribute that maps to the colorscale. |
| 36 | + * |
| 37 | + * N.B. if `colorAttr: 'color'`, we include the `color` declaration here. |
| 38 | + * |
| 39 | + * - onlyIfNumerical {string} (dflt: false' if `cLetter: 'z'`, true if `cLetter: 'c'`): |
| 40 | + * (for descriptions) set to true if colorscale attribute only |
| 41 | + * |
| 42 | + * - colorscaleDflt {string}: |
| 43 | + * overrides the colorscale dflt |
| 44 | + * |
| 45 | + * - autoColorDflt {boolean} (dflt true): |
| 46 | + * normally autocolorscale.dflt is `true`, but pass `false` to override |
| 47 | + * |
| 48 | + * - noScale {boolean} (dflt: true if `context: 'marker.line'`, false otherwise): |
| 49 | + * set to `false` to not include showscale attribute (e.g. for 'marker.line') |
| 50 | + * |
| 51 | + * - showScaleDflt {boolean} (dflt: true if `cLetter: 'z'`, false otherwise) |
| 52 | + * |
| 53 | + * - editTypeOverride {boolean} (dflt: ''): |
| 54 | + * most of these attributes already require a recalc, but the ones that do not |
| 55 | + * have editType *style* or *plot* unless you override (presumably with *calc*) |
| 56 | + * |
| 57 | + * @return {object} |
| 58 | + */ |
| 59 | +module.exports = function colorScaleAttrs(context, opts) { |
| 60 | + context = context || ''; |
| 61 | + opts = opts || {}; |
| 62 | + |
| 63 | + var cLetter = opts.cLetter || 'c'; |
| 64 | + var onlyIfNumerical = ('onlyIfNumerical' in opts) ? opts.onlyIfNumerical : Boolean(context); |
| 65 | + var noScale = ('noScale' in opts) ? opts.noScale : context === 'marker.line'; |
| 66 | + var showScaleDflt = ('showScaleDflt' in opts) ? opts.showScaleDflt : cLetter === 'z'; |
| 67 | + var colorscaleDflt = typeof opts.colorscaleDflt === 'string' ? palettes[opts.colorscaleDflt] : null; |
| 68 | + var editTypeOverride = opts.editTypeOverride || ''; |
| 69 | + var contextHead = context ? (context + '.') : ''; |
| 70 | + |
| 71 | + var colorAttr, colorAttrFull; |
| 72 | + |
| 73 | + if('colorAttr' in opts) { |
| 74 | + colorAttr = opts.colorAttr; |
| 75 | + colorAttrFull = opts.colorAttr; |
| 76 | + } else { |
| 77 | + colorAttr = {z: 'z', c: 'color'}[cLetter]; |
| 78 | + colorAttrFull = 'in ' + code(contextHead + colorAttr); |
| 79 | + } |
| 80 | + |
| 81 | + var effectDesc = onlyIfNumerical ? |
| 82 | + ' Has an effect only if ' + colorAttrFull + 'is set to a numerical array.' : |
| 83 | + ''; |
| 84 | + |
| 85 | + var auto = cLetter + 'auto'; |
| 86 | + var min = cLetter + 'min'; |
| 87 | + var max = cLetter + 'max'; |
| 88 | + var minFull = code(contextHead + min); |
| 89 | + var maxFull = code(contextHead + max); |
| 90 | + var minmaxFull = minFull + ' and ' + maxFull; |
| 91 | + var autoImpliedEdits = {}; |
| 92 | + autoImpliedEdits[min] = autoImpliedEdits[max] = undefined; |
| 93 | + var minmaxImpliedEdits = {}; |
| 94 | + minmaxImpliedEdits[auto] = false; |
| 95 | + |
| 96 | + var attrs = {}; |
| 97 | + |
| 98 | + if(colorAttr === 'color') { |
| 99 | + attrs.color = { |
| 100 | + valType: 'color', |
| 101 | + arrayOk: true, |
| 102 | + role: 'style', |
| 103 | + editType: editTypeOverride || 'style', |
| 104 | + description: [ |
| 105 | + 'Sets the', context, 'color.', |
| 106 | + ' It accepts either a specific color', |
| 107 | + ' or an array of numbers that are mapped to the colorscale', |
| 108 | + ' relative to the max and min values of the array or relative to', |
| 109 | + ' ' + minmaxFull + ' if set.' |
| 110 | + ].join('') |
| 111 | + }; |
| 112 | + } |
| 113 | + |
| 114 | + attrs[auto] = { |
13 | 115 | valType: 'boolean',
|
14 | 116 | role: 'info',
|
15 | 117 | dflt: true,
|
16 | 118 | editType: 'calc',
|
17 |
| - impliedEdits: {zmin: undefined, zmax: undefined}, |
| 119 | + impliedEdits: autoImpliedEdits, |
18 | 120 | description: [
|
19 |
| - 'Determines the whether or not the color domain is computed', |
20 |
| - 'with respect to the input data.' |
21 |
| - ].join(' ') |
22 |
| - }, |
23 |
| - zmin: { |
| 121 | + 'Determines whether or not the color domain is computed', |
| 122 | + ' with respect to the input data (here ' + colorAttrFull + ') or the bounds set in', |
| 123 | + ' ', minmaxFull, |
| 124 | + ' ', effectDesc, |
| 125 | + ' Defaults to `false` when ', minmaxFull, ' are set by the user.' |
| 126 | + ].join('') |
| 127 | + }; |
| 128 | + |
| 129 | + attrs[min] = { |
24 | 130 | valType: 'number',
|
25 | 131 | role: 'info',
|
26 | 132 | dflt: null,
|
27 |
| - editType: 'plot', |
28 |
| - impliedEdits: {zauto: false}, |
29 |
| - description: 'Sets the lower bound of color domain.' |
30 |
| - }, |
31 |
| - zmax: { |
| 133 | + editType: editTypeOverride || 'plot', |
| 134 | + impliedEdits: minmaxImpliedEdits, |
| 135 | + description: [ |
| 136 | + 'Sets the lower bound of the color domain.', |
| 137 | + effectDesc, |
| 138 | + ' Value should have the same units as ', colorAttrFull, |
| 139 | + ' and if set, ', maxFull, ' must be set as well.' |
| 140 | + ].join('') |
| 141 | + }; |
| 142 | + |
| 143 | + attrs[max] = { |
32 | 144 | valType: 'number',
|
33 | 145 | role: 'info',
|
34 | 146 | dflt: null,
|
35 |
| - editType: 'plot', |
36 |
| - impliedEdits: {zauto: false}, |
37 |
| - description: 'Sets the upper bound of color domain.' |
38 |
| - }, |
39 |
| - colorscale: { |
| 147 | + editType: editTypeOverride || 'plot', |
| 148 | + impliedEdits: minmaxImpliedEdits, |
| 149 | + description: [ |
| 150 | + 'Sets the upper bound of the color domain.', |
| 151 | + effectDesc, |
| 152 | + ' Value should have the same units as ', colorAttrFull, |
| 153 | + ' and if set, ', minFull, ' must be set as well.' |
| 154 | + ].join('') |
| 155 | + }; |
| 156 | + |
| 157 | + attrs.colorscale = { |
40 | 158 | valType: 'colorscale',
|
41 | 159 | role: 'style',
|
42 | 160 | editType: 'calc',
|
| 161 | + dflt: colorscaleDflt, |
43 | 162 | impliedEdits: {autocolorscale: false},
|
44 | 163 | description: [
|
45 | 164 | 'Sets the colorscale.',
|
46 |
| - 'The colorscale must be an array containing', |
47 |
| - 'arrays mapping a normalized value to an', |
48 |
| - 'rgb, rgba, hex, hsl, hsv, or named color string.', |
49 |
| - 'At minimum, a mapping for the lowest (0) and highest (1)', |
50 |
| - 'values are required. For example,', |
51 |
| - '`[[0, \'rgb(0,0,255)\', [1, \'rgb(255,0,0)\']]`.', |
52 |
| - 'To control the bounds of the colorscale in z space,', |
53 |
| - 'use zmin and zmax' |
54 |
| - ].join(' ') |
55 |
| - }, |
56 |
| - autocolorscale: { |
| 165 | + effectDesc, |
| 166 | + ' The colorscale must be an array containing', |
| 167 | + ' arrays mapping a normalized value to an', |
| 168 | + ' rgb, rgba, hex, hsl, hsv, or named color string.', |
| 169 | + ' At minimum, a mapping for the lowest (0) and highest (1)', |
| 170 | + ' values are required. For example,', |
| 171 | + ' `[[0, \'rgb(0,0,255)\', [1, \'rgb(255,0,0)\']]`.', |
| 172 | + ' To control the bounds of the colorscale in color space,', |
| 173 | + ' use', minmaxFull, '.', |
| 174 | + ' Alternatively, `colorscale` may be a palette name string', |
| 175 | + ' of the following list: ' + paletteStr + '.' |
| 176 | + ].join('') |
| 177 | + }; |
| 178 | + |
| 179 | + attrs.autocolorscale = { |
57 | 180 | valType: 'boolean',
|
58 | 181 | role: 'style',
|
59 |
| - dflt: true, // gets overrode in 'heatmap' & 'surface' for backwards comp. |
| 182 | + // gets overrode in 'heatmap' & 'surface' for backwards comp. |
| 183 | + dflt: opts.autoColorDflt === false ? false : true, |
60 | 184 | editType: 'calc',
|
61 | 185 | impliedEdits: {colorscale: undefined},
|
62 | 186 | description: [
|
63 |
| - 'Determines whether or not the colorscale is picked using the sign of', |
64 |
| - 'the input z values.' |
65 |
| - ].join(' ') |
66 |
| - }, |
67 |
| - reversescale: { |
| 187 | + 'Determines whether the colorscale is a default palette (`autocolorscale: true`)', |
| 188 | + ' or the palette determined by ', code(contextHead + 'colorscale'), '.', |
| 189 | + effectDesc, |
| 190 | + ' In case `colorscale` is unspecified or `autocolorscale` is true, the default ', |
| 191 | + ' palette will be chosen according to whether numbers in the `color` array are', |
| 192 | + ' all positive, all negative or mixed.' |
| 193 | + ].join('') |
| 194 | + }; |
| 195 | + |
| 196 | + attrs.reversescale = { |
68 | 197 | valType: 'boolean',
|
69 | 198 | role: 'style',
|
70 | 199 | dflt: false,
|
71 | 200 | editType: 'calc',
|
72 |
| - description: 'Reverses the colorscale.' |
73 |
| - }, |
74 |
| - showscale: { |
75 |
| - valType: 'boolean', |
76 |
| - role: 'info', |
77 |
| - dflt: true, |
78 |
| - editType: 'calc', |
79 | 201 | description: [
|
80 |
| - 'Determines whether or not a colorbar is displayed for this trace.' |
81 |
| - ].join(' ') |
| 202 | + 'Reverses the color mapping if true.', |
| 203 | + effectDesc, |
| 204 | + ' If true, ', minFull, ' will correspond to the last color', |
| 205 | + ' in the array and ', maxFull, ' will correspond to the first color.' |
| 206 | + ].join('') |
| 207 | + }; |
| 208 | + |
| 209 | + if(!noScale) { |
| 210 | + attrs.showscale = { |
| 211 | + valType: 'boolean', |
| 212 | + role: 'info', |
| 213 | + dflt: showScaleDflt, |
| 214 | + editType: 'calc', |
| 215 | + description: [ |
| 216 | + 'Determines whether or not a colorbar is displayed for this trace.', |
| 217 | + effectDesc |
| 218 | + ].join('') |
| 219 | + }; |
82 | 220 | }
|
| 221 | + |
| 222 | + return attrs; |
83 | 223 | };
|
0 commit comments