From 63eb009e6605762ce5c8257e15d965d1c4f02046 Mon Sep 17 00:00:00 2001 From: Lukas Prediger Date: Mon, 27 Nov 2023 20:00:04 +0200 Subject: [PATCH 01/10] Added static gradient fills for scatter traces. Adds a new attribute `fillgradient` to `scatter` traces which allows the user to specify a gradient as a colorscale and an orientation in which it will be applied. `fillgradient` also has optional start and stop attributes which can be used to define absolute start and stop points in plot coordiantes. This allows to equip different traces with exactly matching fill gradients. Omitting start and stop will apply the gradient between the extrema of the fill polygon (along the fill direction). When a legend is displayed, multiple passes are made through the `Drawing.setFillStyle` function, for the legend previews and the actual plot, during which the axes are re-scaled. This leads to errors with gradients not computing start and stop coordinates correctly. To work around this, `setFillStyle` was modified to allow distinguishing between legend and plot passes. --- src/components/color/index.js | 19 +++ src/components/drawing/index.js | 124 ++++++++++++++++-- src/components/legend/style.js | 3 +- src/traces/scatter/attributes.js | 60 ++++++++- src/traces/scatter/fillcolor_defaults.js | 27 ++++ src/traces/scatter/style.js | 2 +- .../scatter_fill_gradient_tonext.png | Bin 0 -> 92377 bytes .../scatter_fill_gradient_tonexty_toself.png | Bin 0 -> 35421 bytes .../mocks/scatter_fill_gradient_tonext.json | 42 ++++++ .../scatter_fill_gradient_tonexty_toself.json | 81 ++++++++++++ 10 files changed, 340 insertions(+), 18 deletions(-) create mode 100644 test/image/baselines/scatter_fill_gradient_tonext.png create mode 100644 test/image/baselines/scatter_fill_gradient_tonexty_toself.png create mode 100644 test/image/mocks/scatter_fill_gradient_tonext.json create mode 100644 test/image/mocks/scatter_fill_gradient_tonexty_toself.json diff --git a/src/components/color/index.js b/src/components/color/index.js index e114ae3b1a4..50eccc4a73e 100644 --- a/src/components/color/index.js +++ b/src/components/color/index.js @@ -53,6 +53,25 @@ color.combine = function(front, back) { return tinycolor(fcflat).toRgbString(); }; +/* + * Linearly interpolate between two colors at a normalized interpolation position (0 to 1). + * + * Ignores alpha channel values. + * The resulting color is computed as: factor * first + (1 - factor) * second. + */ +color.interpolate = function(first, second, factor) { + var fc = tinycolor(first).toRgb(); + var sc = tinycolor(second).toRgb(); + + var ic = { + r: factor * fc.r + (1 - factor) * sc.r, + g: factor * fc.g + (1 - factor) * sc.g, + b: factor * fc.b + (1 - factor) * sc.b, + }; + + return tinycolor(ic).toRgbString(); +}; + /* * Create a color that contrasts with cstr. * diff --git a/src/components/drawing/index.js b/src/components/drawing/index.js index d02095aaa86..31fa0248071 100644 --- a/src/components/drawing/index.js +++ b/src/components/drawing/index.js @@ -177,7 +177,7 @@ drawing.dashStyle = function(dash, lineWidth) { return dash; }; -function setFillStyle(sel, trace, gd) { +function setFillStyle(sel, trace, gd, forLegend) { var markerPattern = trace.fillpattern; var patternShape = markerPattern && drawing.getPatternAttr(markerPattern.shape, 0, ''); if(patternShape) { @@ -192,6 +192,55 @@ function setFillStyle(sel, trace, gd) { undefined, markerPattern.fillmode, patternBGColor, patternFGColor, patternFGOpacity ); + } else if(trace.fillgradient && trace.fillgradient.orientation !== 'none') { + var direction = trace.fillgradient.orientation; + var gradientID = 'scatterfill-' + trace.uid; + if(forLegend) { + gradientID = 'legendfill-' + trace.uid; + } + + if(!forLegend && (trace.fillgradient.start !== undefined || trace.fillgradient.stop !== undefined)) { + var start, stop; + if(direction === 'horizontal') { + start = { + x: trace.fillgradient.start, + y: 0, + }; + stop = { + x: trace.fillgradient.stop, + y: 0, + }; + } else if(direction === 'vertical') { + start = { + x: 0, + y: trace.fillgradient.start, + }; + stop = { + x: 0, + y: trace.fillgradient.stop, + }; + } + + start.x = trace._xA.c2p( + (start.x === undefined) ? trace._extremes.x.min[0].val : start.x, true + ); + start.y = trace._yA.c2p( + (start.y === undefined) ? trace._extremes.y.min[0].val : start.y, true + ); + + stop.x = trace._xA.c2p( + (stop.x === undefined) ? trace._extremes.x.max[0].val : stop.x, true + ); + stop.y = trace._yA.c2p( + (stop.y === undefined) ? trace._extremes.y.max[0].val : stop.y, true + ); + sel.call(gradientWithBounds, gd, gradientID, 'linear', trace.fillgradient.colorscale, 'fill', start, stop, true, false); + } else { + if(direction === 'horizontal') { + direction = direction + 'reversed'; + } + sel.call(drawing.gradient, gd, gradientID, direction, trace.fillgradient.colorscale, 'fill'); + } } else if(trace.fillcolor) { sel.call(Color.fill, trace.fillcolor); } @@ -202,17 +251,17 @@ drawing.singleFillStyle = function(sel, gd) { var node = d3.select(sel.node()); var data = node.data(); var trace = ((data[0] || [])[0] || {}).trace || {}; - setFillStyle(sel, trace, gd); + setFillStyle(sel, trace, gd, false); }; -drawing.fillGroupStyle = function(s, gd) { +drawing.fillGroupStyle = function(s, gd, forLegend) { s.style('stroke-width', 0) .each(function(d) { var shape = d3.select(this); // N.B. 'd' won't be a calcdata item when // fill !== 'none' on a segment-less and marker-less trace if(d[0].trace) { - setFillStyle(shape, d[0].trace, gd); + setFillStyle(shape, d[0].trace, gd, forLegend); } }); }; @@ -294,16 +343,14 @@ function makePointPath(symbolNumber, r, t, s) { return drawing.symbolFuncs[base](r, t, s) + (symbolNumber >= 200 ? DOTPATH : ''); } -var HORZGRADIENT = {x1: 1, x2: 0, y1: 0, y2: 0}; -var VERTGRADIENT = {x1: 0, x2: 0, y1: 1, y2: 0}; var stopFormatter = numberFormat('~f'); var gradientInfo = { - radial: {node: 'radialGradient'}, - radialreversed: {node: 'radialGradient', reversed: true}, - horizontal: {node: 'linearGradient', attrs: HORZGRADIENT}, - horizontalreversed: {node: 'linearGradient', attrs: HORZGRADIENT, reversed: true}, - vertical: {node: 'linearGradient', attrs: VERTGRADIENT}, - verticalreversed: {node: 'linearGradient', attrs: VERTGRADIENT, reversed: true} + radial: {type: 'radial'}, + radialreversed: {type: 'radial', reversed: true}, + horizontal: {type: 'linear', start: {x: 1, y: 0}, stop: {x: 0, y: 0}}, + horizontalreversed: {type: 'linear', start: {x: 1, y: 0}, stop: {x: 0, y: 0}, reversed: true}, + vertical: {type: 'linear', start: {x: 0, y: 1}, stop: {x: 0, y: 0}}, + verticalreversed: {type: 'linear', start: {x: 0, y: 1}, stop: {x: 0, y: 0}, reversed: true} }; /** @@ -321,8 +368,57 @@ var gradientInfo = { * @param {string} prop: the property to apply to, 'fill' or 'stroke' */ drawing.gradient = function(sel, gd, gradientID, type, colorscale, prop) { - var len = colorscale.length; var info = gradientInfo[type]; + return gradientWithBounds( + sel, gd, gradientID, info.type, colorscale, prop, info.start, info.stop, false, info.reversed + ); +}; + +/** + * gradient_with_bounds: create and apply a gradient fill for defined start and stop positions + * + * @param {object} sel: d3 selection to apply this gradient to + * You can use `selection.call(Drawing.gradient, ...)` + * @param {DOM element} gd: the graph div `sel` is part of + * @param {string} gradientID: a unique (within this plot) identifier + * for this gradient, so that we don't create unnecessary definitions + * @param {string} type: 'radial' or 'linear'. Radial goes center to edge, + * horizontal goes as defined by start and stop + * @param {array} colorscale: as in attribute values, [[fraction, color], ...] + * @param {string} prop: the property to apply to, 'fill' or 'stroke' + * @param {object} start: start point for linear gradients, { x: number, y: number }. + * Ignored if type is 'radial'. + * @param {object} stop: stop point for linear gradients, { x: number, y: number }. + * Ignored if type is 'radial'. + * @param {boolean} inUserSpace: If true, start and stop give absolute values in the plot. + * If false, start and stop are fractions of the traces extent along each axis. + * @param {boolean} reversed: If true, the gradient is reversed between normal start and stop, + * i.e., the colorscale is applied in order from stop to start for linear, from edge + * to center for radial gradients. + */ +function gradientWithBounds(sel, gd, gradientID, type, colorscale, prop, start, stop, inUserSpace, reversed) { + var len = colorscale.length; + + var info; + if(type === 'linear') { + info = { + node: 'linearGradient', + attrs: { + x1: start.x, + y1: start.y, + x2: stop.x, + y2: stop.y, + gradientUnits: inUserSpace ? 'userSpaceOnUse' : 'objectBoundingBox', + }, + reversed: reversed, + }; + } else if(type === 'radial') { + info = { + node: 'radialGradient', + reversed: reversed, + }; + } + var colorStops = new Array(len); for(var i = 0; i < len; i++) { if(info.reversed) { @@ -368,7 +464,7 @@ drawing.gradient = function(sel, gd, gradientID, type, colorscale, prop) { .style(prop + '-opacity', null); sel.classed('gradient_filled', true); -}; +} /** * pattern: create and apply a pattern fill diff --git a/src/components/legend/style.js b/src/components/legend/style.js index 774d269d097..770f2255307 100644 --- a/src/components/legend/style.js +++ b/src/components/legend/style.js @@ -114,7 +114,7 @@ module.exports = function style(s, gd, legend) { var fillStyle = function(s) { if(s.size()) { if(showFill) { - Drawing.fillGroupStyle(s, gd); + Drawing.fillGroupStyle(s, gd, true); } else { var gradientID = 'legendfill-' + trace.uid; Drawing.gradient(s, gd, gradientID, @@ -673,7 +673,6 @@ function getStyleGuide(d) { showGradientFill = true; } } - return { showMarker: showMarker, showLine: showLine, diff --git a/src/traces/scatter/attributes.js b/src/traces/scatter/attributes.js index f6beafa16a4..2d7916ecd8d 100644 --- a/src/traces/scatter/attributes.js +++ b/src/traces/scatter/attributes.js @@ -398,9 +398,67 @@ module.exports = { description: [ 'Sets the fill color.', 'Defaults to a half-transparent variant of the line color,', - 'marker color, or marker line color, whichever is available.' + 'marker color, or marker line color, whichever is available.', + 'If fillgradient is specified, fillcolor is ignored except for', + 'setting the background color of the hover label, if any.' ].join(' ') }, + fillgradient: extendFlat({ + orientation: { + valType: 'enumerated', + values: ['radial', 'horizontal', 'vertical', 'none'], + dflt: 'none', + editType: 'style', + description: [ + 'Sets the orientation of the color gradient.', + 'Defaults to *none*.' + ].join(' ') + }, + start: { + valType: 'number', + editType: 'calc', + description: [ + 'Sets the gradient start value.', + 'It is given as the absolute position on the axis determined by', + 'the orientiation. E.g., if orientation is *horizontal*, the', + 'gradient will be horizontal and start from the x-position', + 'given by start. If omitted, the gradient starts at the lowest', + 'value of the trace along the respective axis.', + 'Ignored if orientation is *radial*.' + ].join(' ') + }, + stop: { + valType: 'number', + editType: 'calc', + description: [ + 'Sets the gradient end value.', + 'It is given as the absolute position on the axis determined by', + 'the orientiation. E.g., if orientation is *horizontal*, the', + 'gradient will be horizontal and end at the x-position', + 'given by end. If omitted, the gradient ends at the highest', + 'value of the trace along the respective axis.', + 'Ignored if orientation is *radial*.' + ].join(' ') + }, + colorscale: { + valType: 'colorscale', + editType: 'style', + anim: true, + description: [ + 'Sets the fill gradient colors as a color scale.', + 'The color scale is interpreted as a gradient', + 'applied in the direction specified by *orientation*,', + 'from the lowest to the highest value of the scatter', + 'plot along that axis, or from the center to the most', + 'distant point from it, if orientation is *radial*.' + ].join(' ') + }, + editType: 'style', + description: [ + 'Sets a fill gradient.', + 'If not specified, the fillcolor is used instead.' + ].join(' ') + }), fillpattern: pattern, marker: extendFlat({ symbol: { diff --git a/src/traces/scatter/fillcolor_defaults.js b/src/traces/scatter/fillcolor_defaults.js index bcb08a51825..bc611169d33 100644 --- a/src/traces/scatter/fillcolor_defaults.js +++ b/src/traces/scatter/fillcolor_defaults.js @@ -2,6 +2,17 @@ var Color = require('../../components/color'); var isArrayOrTypedArray = require('../../lib').isArrayOrTypedArray; +var assert = require('assert'); + +function averageColors(colorscale) { + assert(colorscale.length >= 2); + var color = Color.interpolate(colorscale[0][1], colorscale[1][1], 0.5); + for(var i = 2; i < colorscale.length; i++) { + var averageColorI = Color.interpolate(colorscale[i - 1][1], colorscale[i][1], 0.5); + color = Color.interpolate(color, averageColorI, colorscale[i - 1][0] / colorscale[i][0]); + } + return color; +} module.exports = function fillColorDefaults(traceIn, traceOut, defaultColor, coerce) { var inheritColorFromMarker = false; @@ -18,9 +29,25 @@ module.exports = function fillColorDefaults(traceIn, traceOut, defaultColor, coe } } + var averageGradientColor; + if(traceIn.fillgradient) { + // if a fillgradient is specified, we use the average gradient color + // to specifiy fillcolor after all other more specific candidates + // are considered, but before the global default color. + // fillcolor affects the background color of the hoverlabel in this case. + var gradientOrientation = coerce('fillgradient.orientation'); + if(gradientOrientation !== 'none') { + coerce('fillgradient.start'); + coerce('fillgradient.stop'); + coerce('fillgradient.colorscale'); + averageGradientColor = averageColors(traceOut.fillgradient.colorscale); + } + } + coerce('fillcolor', Color.addOpacity( (traceOut.line || {}).color || inheritColorFromMarker || + averageGradientColor || defaultColor, 0.5 )); }; diff --git a/src/traces/scatter/style.js b/src/traces/scatter/style.js index ad3fd5a217b..734ecf9f9d0 100644 --- a/src/traces/scatter/style.js +++ b/src/traces/scatter/style.js @@ -27,7 +27,7 @@ function style(gd) { .call(Drawing.lineGroupStyle); s.selectAll('g.trace path.js-fill') - .call(Drawing.fillGroupStyle, gd); + .call(Drawing.fillGroupStyle, gd, false); Registry.getComponentMethod('errorbars', 'style')(s); } diff --git a/test/image/baselines/scatter_fill_gradient_tonext.png b/test/image/baselines/scatter_fill_gradient_tonext.png new file mode 100644 index 0000000000000000000000000000000000000000..9e6939e28a0dad11d4dab2a991aa855ac8b3847f GIT binary patch literal 92377 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ⅅ~t)IPr|xr@)Ic6Vt*h4~w2CVa<=y zWs+OK!c9yo>5}aU*M;{mFNqro$4^r%(A?Uej7=g_GJ~+qd^d_8c#>k#ex?jlBHjL> z`jXQ3tMM-DhrTzT)qM!+haVSrdH9B~(ed@Wid30acYnVCKfbfZmd*L_Z3f%aqpIN$ zwfAeV?$v}3Y@%zIG0;!URwh{^mjt8^eAwWtTwuzUeCF>#WFU0g?Oiyo7Gz5WqFXO``0Shf(~|$So+V4v0|x~=bhj8 zujY@mb%QyySR|1EOziw$Ma4#9#X1|zneQ!=O z4prB{$d8Y&4Mmv3^xI`>$<$>Nu99m$A@97uL(n7hvLGxj*$Td?SxT>zF^ysyGE=|_ z70P&u{n7fAAzR<#%mW=je%)L=CJ0w|RJ#swL~YVSK&ABZ0=0#1qi`vq6v3suG*ioD zQyV+Wu3}Yf-AkfaJ$xI{sI;7~Rlq?Zbu`JeLi&1*GYjs1!BV+)al3j~*~6(A`|Kso zc$IwIYE!jyGy&#;e!;CgEwbRx!8VcuxID-n_Ccj#GASiL+XzV1GVH!#s~WM7eV1eI zV4ipw-cj%k%9{{JC7gCs;1nh8mn-@i|Js_`fdI)t>EjdKAa$eQ^eR!~m#xzXj+zy` zo94)fL(C_duR0ZDT&yIZ$p#rSHwlSvKy-T)ZXf$64#Du@+*=@ZY?~e-b^NU}s!DU+rEge7OV(tW+c<4XQ;(E=4KeJ9gaAkWL z&+v!4%GZ7PV=WJ`^TFZy*}VbYKO37&`Rch7;^HGslA7ZTI7MbFCoIFi?8@XojO0fM zylMTx1n9MMF6;^pa;YWLkjVh-l0;PGZ;8e=nte|ZUZ~wXk1OZ(lAwX6EzW?(&9c;u zLeg;v| zOL!1p7QZHqyS1*m8Z}UANJF0URwKjWXIGUg@9@Zx04H!JnPiKwB61NGwq2J{Pb}}{ zLPC|(y?t1m8N~fsiR@gZ*1Q%rw-tP2oX(8AHmX**U^^3>8dg($;;VlAoEB6nAUK#Dh zVC;FbVZpt#(y@1|1Dk+;iZKkmz3LtEmX?UAJ$^8)CxjIk?6ET!Y7S!JRH0hk@*|#a zmAuHl)2S9GnhwzkzPCc1&?u-4H;0vnfgYHZJZKEak-f6h1*YWA;|lnT~>bVq(lw$>U?2qOL-u@;!AK zpH8uPW7eTGEwC5%|$oI^cggG|DE179_nWMgFkbNGeW2RzkzIhzf6i>?g0 zcPxSiBU(>euZ6yqR@tDvPJ6(%Li6G3YO}DU*mp7bsf;mffy;3x;OxRv_^?p716=m1 z)v0Y1VRIh=tiWU?eTV5!wPo>VT=dDlddr6S1>D=mHI?%0f*6r&is=oPjI@cndA)R` z>xPq=erqidpKeuVa>L)AT@r{kuO>0ET4m#JJq9a3{6ShcfO?$2Nxak4P7M_gt7J2A z?I!|=1a$Mboujpy~5w{a{yBn zoTIt77FR2qIfT%*!(YnTI^7RAzRm#Em1pO!)n<+n&KEZrCN#6 zMeq_!x7N_NRxj`bWxbULc0xWMy8fg8bX1V{F-kX_zO&TF74$Yo3!G|E{&aO>Y#GLk zhyFhFJ}W2VQuZd!O%mL_a`V&PEX%QW`_YhN*a%}%J@)=1mJH_UFM4Ph4z}o`0&ae` zQbKD2NxV#i@Z|C%W=ObNS9wXZOf8so(j+Pq9E-;H*n==9J2g%6n>45(t5h4~K=gJ` z6ex9ShP+oOW556VF_ptxp}> YiYk@I^Uso4fqaw6bHzIo%j1KBrr`LK$zdV5oR~ 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 M5U{^$-|6rE38LJN%m4rY literal 0 HcmV?d00001 diff --git a/test/image/baselines/scatter_fill_gradient_tonexty_toself.png b/test/image/baselines/scatter_fill_gradient_tonexty_toself.png new file mode 100644 index 0000000000000000000000000000000000000000..54d176b74b57f57434a5ab8f2d5843e4bddb223d GIT binary patch literal 35421 zcmeFZbySpH`vwZ4AT1>*We@_=N|z!ajdZ7gQbRLH3j<23v=Ry;N_P%5lr)Gm42(!g z%mC7L_UQY4FMNNVb=LXow-zj5*z-L5+53*`zV2(!OAR#zQlhIwI5;?@iVq)X;^3Tv z+_l^}^`ZmVsY`}S?eL}ZgZy4HN8j2N z%tyk9(3`2It116^1^cfMz4rf(0Kfd-p#NKf|6i;?=HtbvRLI@ChpQ$!M}5bB__pRjZYpkgcsQSB%f%F*wdzri5fghkS9IOZk14O|)}x(i zX5pIBUNK^EG+eMPh8Z2@_j^Er-*NoTBy={)rEhLOklUzYMz~>*^pjd@_|f)6-`3O@ z{$txTZ~UDpFXl9#HBm?^G`d_{#-P~pf>ZsTjql!EqJE`QYGN#pNzKe^<@C0H-&`}f z^zV(|g#kyz`9_uUvK=OzyY}=>6t6Hf@w{?I1VLbG1nLs&=cA>Mp(I!Dd_9Occz%Hx z(<3}RlM%slUtV7R8{NhauWyR%sP%T{X{X+|{^@0;dP$43G16@fCr1!t&oOHY6?99A zQKeI>+3^PLA&NWz6B4JaYW#)+9v5ENaD3IOJ=){BmO!w>t#8@}&|LB1Hyz~_R+TlY zn5vWG12n&NC-t4D-&zi2PQa{xfJJRz%1-A&sd~EJNgq7V0$0mcZ_;CP1`A|0?YGl9 zW}D6^mZE3oM^icJN(_CJSM~k(0pB@G50|Z9L!^e#+*w1a#K%Msx;=O6-cU~Xm#^v) z3wIjI$8FR7_*{Q}y(+5(6Q(g36f(Yc4droNIh>ylSJ!i|yyB$XO%-oX=UT(?@k}r| zyztzf&U6z2^NJ2(weNZ>Ep(%Uo!_dBB+sA}e|4g=-6D)J^k%dO;$UaOsWv}+@p!wk zVaxCqCox|@Utx2#vy{@v@1?=l@$oQJbC}g+mCKXCPf)7 z;b;}I*#Du~vsTcio31-q(6)Bk1l%tT{zfk$FN0`kdSw(+&bJewWxu6#Fdr%z`VKv(pH4~O(0=9NS zuZ&@LK!Mp?hdW)lwQ$6K76Ba#Z4^lk*qA*grx)s;2sp0$l;x@{Ywi6>-`HbFr)vJK zy#!C*u|T_|&-U+%1-A78T$@JM0EBtVy zD@i(_-pk?l;y|uUZ&vI)>foTD`)vMS&7{cC)(aOjoyBw zVC(oOvEh)_|KwoWr`@Y{w#-$znH~ZUYG?8xaa-t>%ao7eGjGJj^RL-?Vi3^kRUx|w#vVC?y0;C;++lQ zBN3r^6_kuTV-Y-KsA&1c!lNpYi>}k*pb_?qJN(=oTWb1HDz2|7uLvKCz z_Vz}eWLG_ULPShl?7eBD?yx6*?EK-g#;=?MN#5g9+rDj{Zl9InFm{)?D6lRQ?;>2Z z*ba$*nfk2GDdM&kJstd%HnUrTqOx3WNk2KXMW2{LQ7~kB6ut2F@T}*?=BA_~X6JRu zgW~K+KATR+LT~Cl+?wP4<+`L>?8d(=A2hKxr=&2b&wpJ69@e^C*s!K}OZu9It2eIg z)>9C4cD5ad^9<6uk5_D^bKg7(XNI9Wxe9-uk0V~F1p%s#Q)sUL#9ZcOwz1^zep#Jo zl=idtub9UOOJ6J!8?N*5Dja!t6dfm6QTM&SDpsFOb6SX%AygBFnf@tGx7_)pwIQNCaqNTo$ByT387%!!}bICt? z$UjR6pKPX|%+&25H;+x@2Z7d-L^=;*Xucu{K zoZPoByZD_Mmk@GPJdz-Lt&tcvmjN!bZuym%jyD1RexKOKiGw-MwcLJ$M}ykh+8PNv zd>>4<@gT5EOI;Eca5&4X!&!6p==hs5?^cd?9D$i>;%$Q;Tezi$iuZQpo(rcrONP5T z5-&C-eF`v66`iu@A1n>K3FiCxT+<_4?5fI$&DY`_qb+{@#Zm%~nooSc>Ej zb?!Cdtoa4$lWMQ)3me(eM;)=oy6>YUxAoP(RTXg}YrP;4@u3bqRpVQDaPP2hE#YMi zMQ?ij)>}W-=m!(=LeggW7kKmNG{uPP(*vXLNZS!I*OjYS+ZnZS2K(j>s?M z-8f+G{n2q3=D+kU3rUdwONyjKOqnb)h&lQYCcJ;N9uqLxmM`Fz=GAa8g@$iNRj<>g z2_K%sZF3b=Ar8vZ@%(2SH@{TCRGg|%_-NVNtqH_^SNvaOJ~)_WYiSO2)0RT+1-*`U z^smaP;**w$v726auUQ`GKbH`A?h#mpa!Cr zMi1uv#XHG!@8pH<-)QpKJ*Y_-52^ItoHs4M^A%AT$q^6N$G3P8dRQ~jKs7myU#Y;6 zsZnD1Rf(OplQXv_Pj{q3qsrjICx()Zo*Y5z5J#%R{q0}5h1;CL3XC4qJk>ubSAdbZ z5cAG`ah)KXP}uzt)KIvj$aD{uD6pg_SY0S_JWABOw-<$*oA*<*_)X82{@h#`M>xu< zc2$>~Eu7VQ9Abh}isX7yuoo0$sbrDoWC45IZa(K0{G)R<&3B^%>0)32HMnlgaQG=u zI6~K09~Q8S3X^=A^>~x+rY+LJV9zL`li!8$1TU|Fr_V8*iRRUyddZ?s7t2pM6f0FkY57Mz`!js^sLdW^(-Zi+F z%~w*FS%MjkTkfp>P?qM_D=PBym2A#b`}l_G6oFtvSf!=9N2SwL#k+TAdz--|S+Dac zCE9Yj?s?$4G>q9aldDWhapgFiSQsg^LS&NOJ&4(P^MMYxb|ZJZIC+)u-o>$Tc18szQ0ve(wTFK_idb_>CfGAXAj~FQD%-C z=e`nU@XD+htWGxsAZSdLNVxnOj<*VP9TMWzD@2eP(Sdg=+?F=!z+X!9b(d`y;gS&)~e&bKInEeBW-x8|70^Z+E zzW5PTiNbR4%aiwSHipwRv}HXmDwzvt-R}!HcB_?=lfEB*@nDbB-$Z@j{q55GOM1{f z8t&H7hF1r(_WP1topFTQEW^JgW}vV{$r1-{bJnsSnz1-VoJ!T!-88wS@Q#?xU4#+s z&FyC!ZNj=r1_PuuyZLx|`$ON;RlZn5*bapEypUg8VF#Vzw;(vPJ!;LUQ}BDegYOsM!&E`;*MS`+s@x(I#PzrCMXDoFeT55qTO8^2 zjYOod_`1Nn;f?2g?8F%KisH}I#TDY8aw(4I{im67lk!qr$cU~@(C>CDn?aB2<%nKR z`!`nG?Mvq7Qj18r1Pz%Ysay1KIm7YNXt%)nnWdK!wH|9o!GgS=YVp`n;z+&n|IzXi zInn}GjGoATze%C}6GaR$iM+K&eWk({V^d#XQv1x20zUgLqs3Imf3;h|Z2jqlNj<5y zNHcP`+nd^h_s25K`D_oBrUSIc-$Ck^2x*zA^wvL>{z@8ZVPy0W#xg!|Uv`=(z)F{&rQGOE=D(Y(2{-O}k9jpPB7JTdn3 zG4WbN44a*+n{D^f6dX)GoZsvqJJ!0LW7R8k&ENh$;jHjY38vB9E?W1Z>4YQn%Zr85 z%+_zGnJ~duXFGd(rYa(aXH#RYvq1bWqJ;Sl@n7@}+N6EWsK~x^zQbAqVKi7wpMYU| zmiG1}IG^yrwN_B)aNrm8z!U;qX*@n$x~Xtk^z6XS^Ow2YMkW-We4&B(dC_YIuHEId($48L95BjK{(ZtsOJ6I z5-uVaqAoQPCGGnhr!{iuak$h@{2|9doMVON_p)6xDmUrF1k!>o1)+7DyGmCfEE~B$ zhxl_}D%V`(-3imVvqrF|ai=4s4>2c9F)8fdzY$~WKcsTqdMj?oce{-327HnyE75zF zKrrp5?;Xa(6Y_Z? zvd{(Ye_y(BDGof~EslKlQ?Jdi;1U+bKGo{~?>qnRg8x~@|69X9hVp-A^Jf|UKk$?< zcEbmtvU&+P?-ciMilGK~zF#=EJe)7< z0t}L94^@IPDkohx#*UT+qsds6KZMIrUVI28y~GN~hengeW5g2pWUH{F!?2^367JIk zv0QqExq3|rN{V5i=R|qjwg`2`jwZv7j=K%xJf{dKvb!>In5#3QLfVLBeFO>W&*-aQ z^eqD-o%3&GWDxd&w@`N*-5frLj1-4lLBwN6-vOgFN~m)#vIKz;hw}&wS{T(JEVLpN z4B^6#egZ~+c+8M=J)8)=p`2Q4c%1AB>jm(ENPk)p_hfJotaV5Kam+ zsb0t?qz^jPl`|_V3kp!yI$)q2eUwp2{8mMP`1&M~@IdGmid1IxLm1P!0MM&|mwQdR zC`|fp_PoO22hzUQVS!U9J`SA1{zV;x{p+D6k*CF&0HCupi#{m5dos-=vh*=$!lc1p zl1=q(i1=F7&AEGzpn#||SgD-$|Jv8r9(hHO&wJys#PROz*WO+=Z;5p$4FrAQsAJ_+ zC@voUjIH#+n5Vrm6t6MjD<>uL1&ctV(?ckpOn4*s>mm#Pg<3xQeVY`|emJ$m(*xC& z@0I*({?+ZC4U;9-#8{$uX)xO=jM1}krYYEE{AspD%L@uRQCAkHx-DIjD*`RC{fTD& zS7Ic$>4YH2NZoux6oQ!dL3=b~-QFkFccDJ$I@(;lLisQO7p=_s;1Xt+=QJb z=>YM}hEIA`d%>R>Fx6EHX+Chrj|VqUq^~}JGW{I5CmlW+16aXEuJGK4(9EQvUptD3 z2|ibDlp~#Y#oAm3WcWvpEV5jUYG;?n&v52BZB7OEZNsvQiKfrKu;(4$m%bw9E7B{u zV+{E7?t`tBvC@G86Y;Vq0|+WjqE!RiR2Zvrg8AX@de#1~Tu`Btt3NZy&sq_39H$0E zAL4Lt(*^A7EFhE>oSdA>i)m?TX917groikMVqZ|rwsw>ogG-6T`OaIjc;mKy5zZkw z3;BC3HPO}s>MSA%4wS+`4nhC=0sbf{Aq3|kg+BNzh~<+xZ9+gTLk!dQ6QYW;BewDF zrxCMhk_DZfxm3tta;eeSaX`0g(=W6$2Sj4od9c8upu$#Ef7T~58@W0x3HVyc><`!6 zk^z5BI?%vMT@=g$0S(vxJ|{!!Px2T#^W4#?QMeo0+gT!5aMfo z){W|-;PSqK24&%0=XZ4|ec}WJ1x=8otxSP9T-R0K-XSddr0bH5b3nmSCn_q+gATPM ze|T-c?b&K&1g0UgfV?XHXZ~=8m+i{l_m)P)0oe3wH*Z=^?DN*|-az^vIHFGqO=^ej zMQ199yr%txH#Rn$SBl%6j1o_J!~vH#0LUrF1};v{jgMG!{^FSpJuW&z@doTg=%MmO zguJQWh{uKq4r`_&ugZfNwKZ;RqWd{mS+5kXwEZ47K1 zt>T|_456r;r^eMIJjBRaE=8UZQ}%nOs=Qs29LZ>XNyw|4hm!`qu_Zq8i4?RWbSk>GYhu;J2+5@nF%_0Z z)~LD4J}g7bUUlfXk&|1nQ6DvbVyk?9f(A>76>`@4?zxsZP7E)j9KV02kdI+n^?RpS zY(vZ*u)u3SoYxdi!&Nk>ChpzvRv41z70kc|pQ`mzm&_EY1dfFhnI1iQX|3`OhKjV| zvblQqZfT4*Oc+OYL~j5#utkC&6R=XHT6OC&YPDSXONcO3>AsQHg2$65gHAtS5t)P0 zZT?fBX)<*1DOos2=dx+VO>FN*zsmW#VWm?Pwvl0!j_863bkl#^eIY276{PMplT^D_ zL(J@p31V-Lv#3#P)xFfoAJFde_7=h+%3RsjPl8J1HJ%EHVB^duy9&NXTO-J9CaK}z z7+esDVn$~C*2WY-{Ni)>qcNc~=`+Xds&9q}duF@oE2B-6Sl|{-QC6m@BQA}uzC#xx ztojBFc3H7R|Kr7xpfTn2Xl`T9J!loW_GeSV304^bwQB3x2rUe&&f>``LMw1Ge-070l~> z$jIAIA0tP+Q>i1>R0Na}%Ma2JB$^2O_w-cA>CXsz^TkdLup1q5lDz}7;ab<=@3c|n z*`0dvD4G9g0VINZ?FH}KvL%&2EF|_~Gq`>MENx&GMosF#oUkzH1DC9ag*&U(wupi^ zV&a?BBW^*GUj{5F(s<{h4i8g;S!!6h4Nqqj!s!V!2^OS4sgcCJ$K_|AvdyveCz!8u zUlgUOPfoYsB3$UEyUlYn?b1`FUKXy8G60GcQ6o8QnORVG`P{9+V-`H_WLkKr4&7X# z8WL!Jl}673|3FD5RNcF5o{~{C94UvYm*kI+1U;A3XFjQD(8GuhWA>*5zID&vU#eGP zQw20RZ^hT9V=7qSgqguRcBn75CrW45EK(Unqq#ksPPyiIQ{u;`abg7$5FakX! zHZ0;nPJ*TpnQ=8Xch&tci@5x9U6oZIY`jpcFKVm-U`Dzc0c~1&Jpt<&x0b4J{jkdS z3x;P_t1^PJmcnB|*xqI6I{K5ZbnWk_LByt`wVj@{+=d~_ymjBHbOS_JikkU+cb%~v z@+ZT$himwKwjIjsM|!CSz$@)kDJV-St_Qts%Wkg&3x^-z9g0O1diBqOaa1 z+Fa;s-&;tJIY2isS6APiUTNRrso%Af&|qf8oENx(QpI^I9fItO(3y(A_GrfjQe zP4@eHF>4aFE6huuR|nejQVDThtS}a5;5El5UX{Fa)rS*v(BDN0TJ?#J2W71;eN40u zq2yA#=IVB}?n|1EDa-+f{Au3vR|=12I@r^Hf82=_>>YKQ>Wm*Jq+**1p;BuEjlJB| z(vKfoa#@&NS|~>C3+ps{*9Eo!C4Y0Z2oAPq+q!v3q{<)%i>GhW|+%F1;_E}#kM0@~WyDXJOt zaTqowvf_8cJfaIS<#*`*-Qvx-;w+9!$h&q=i?Tca6B>4(Sy-x@jvY=h+!m|Ifri%2 z{wHg1|7eYH>0nKC82Q#n#Cu`HY&5e=C>X54u)PcP^atRu0Zy*hmy~Q90N0B3QDFtmWNRvW7Rg8NauG(bT6ACi?)Z2 zAl}cr=%)&5esNOM()ygFOEx;_Rjt)5!^77AZ8%WjXjB+h`6yGKPV(6uP`ceKwjt*W z&~vF?t(btH7*(_0*b4kHoe?7JZ!;mU0X>2C9-mEH5*4@IQB(ONoM-$ak+|7WONsU3 z_HsRdv)BRvPCvv+%sWBBQ@bK?+qmiy5NvGkJ5)=-5{a#ogg>rR*!n8rrLQ&edrf)J zO6|_zsYi1(>w)&MCyiOJ*RLcTD|% zRxTuBd=$HKQ<5ldVh{SaaHn%(h08Y7@ptR>>DDTR9-*k`j)0?=D5H)BMWqu@yZq+I z;)g+)f(NfdM$&H2l86;X;V@o3-a|M`w}^#gG=+j(@llEmE**RNO@eH2$5pB!LzKz& zGkHSFjBZVo@q+xLX#&E+>&;-YV7H&Ikqp5GQjHC6W?|B3OE7B#$_V=&ErGUWxEj8k z@cga{Vp%@pek90hfy$`5A1Qu1XHvvVE5ZA;NJ$@VJ=jPZ=O&n9&&AZ_nL*fU%1fP~ zP+4F{GfJqVP0<4YHvWymiYUpQ3}@bGpDjZ+Y)bsEtv|N#v9;8BkHVJARhrO329S8K zx!Zt@)cdiMVUf^EkpCFrd~meA#ErVk&PhnM2v_GHwhDJgqq6Ui8+H0e9PVk3l?+sJ7cSNV-C1p)HHbdf9<}Ps?7$K0y5_`QkfOL zt(|P!@9ikR*nOUvXK_&_kLV5qwqDjFLJ!UEfXe-pACsqHLJzhU`kwK=J`G5Gi{8fy z7PE=>gHq|cPb;69;vrT5giQ@wBWCF}~dspYssPA6^OkKp34bk;f4T-$+luxmA8Rc*1z{J7Ai$5qCnh$aB>& z#kG?I3L2jS9|>FOp!3PLe73y|*ld&}f5 zCN=KZq%=_NW~&0quXaW+2B6!h^L%kLMuL)xO{LNQV0FQ92S{ty4R3C2(3R3haKb|+ z9zhG~8{VCPLG3Y)A*J^(BaeJ|-<;l*L&&|6^H!v?(B(HK$38oph%Uyem6EO^bp3%7 zm3sIZNIffxoYq^P-Z|Z`^;~scEg#A7*;z{~8)kunl)3&O`3TN%vONI_HgyA9qi33R z9?QDwMW9lVRsV>kHdN9iu3+=$KN&;(-lr`=72p@Wc(eQKwP(=Do{u`Txi0e{5J`N- z;LzOWt#@9tlA!YSJ4j7Y*1v(ijmgw^T~1v@FHb*6uup=DT=MrTy(O?*9Bonb3#&gD z(gUJ_ZVX+u-bQavjRaztbJEAVH`Sz%emk1CMP8XzTm=Ky0mz!ESuSV>%8hU-zx^3V zz`?spZl{2?$!btl3sT}5LaYF;{7sFdZzDe&oOZ0-oNc}$e9X}o&frQf+9J!hUnxT| zY^Eq~4vr?~V+_G0kmW(a$~AIwvnCD=pB(QrJQ>Ji|s>pI1c5|09C}O zqxmP5qOgL704_O}{VaW#IGpk2cWx#RA!U@rQXRxvr zf`090B-x6j+3E5Hv-X^cu3R_;?2M7ntE+CjvR#FS6WaAgV_t4 zp0`(Q1~h0dE+Q81C%mDWEzXAV!W&j@qEyu?97-4A73*$Ke@|>u(I9{OC^Z9t8@zKB zph6drt$m)F+n+mdIXPUA#xhG7r#qQAUMr);ZA560=j-SPZk565S}$FJ#g_jY%; z09Iu2Xe|(r4CAC}RAi3J({Ske`0-;Xjm^kq5aO+lr{Zv;#i zJT&>l_&baUi6PI{kfX&`V4Z!S!g+gLU@3ldaQgVTxw<<4c**_)$YgT1I7n9r=Laui z`7E_mG4F3GdvhB@dS>1y>B4#I_#!;M-mSoq>rHe-Bnfq*0M!3V4cjT4CDuNZFwhbx z(w*yD1Y6133HYaq5#a^&j7r|UbJo18*b3KuIbpE}dar^q-vbnVzHK31XG^{Y@q8De z5HG;fp2|8sdmY{{WyMx7piB7@z&6|wV>eZ?kXaQH5L9z+!G&X(Z=9YCJ8b7SF_qs# zzoONXnmz_X2%q+cf~-w3ZTQo>d-R)LO1V%f>3EFas*B zCIcOVScFg4ZqpeM!sKQc+Yj5Bkt#jozlD9%W6An7pz#DYq<|V})K329bi#;5h_4|Y zOm|W{95gHmDkJDgbUxcJ!O3VKhN{QohbG@RnJ&aW!)BY!Bn;WvT$42D3Q9}Cv-j&k zFP%7SJ2VN>3tN&a00*GMc8=!MK)q8(`swzv1oZj9ur8!-F>do(X zvguy9N(M;jATHQWfg8A0NG}$SBx@(*N!qDsMG{sceDtT$#fsdd^Tr13Ap5c|_U?HJzoy>XrrM$d5g?F@= z8H3d=Vl}bEJBFB&u;M&A!Ma)-GV!8=SU4fe|b`5 ze#o1V;C8#7-&51+kZp6qgc-;#{oD71uCI-j(^Ut`IvXIZx(*07>JOiXrG+hLJx|iY zBqE!VLM+MLF7+js_DM}pjl$t@F_;%1f|CSo$@aHZBLf6>05M9?^X;3aN)jKgT(TouDG$dD;}8F_Qxp9>WweOHnB!=~8M!$D8PN%wN1 zhC@0^a3!j4;A;Nsn8T`*+w%OnmaMu~9>xKlvckS0F*z;WR@(_iPE8;j6@kJl&$ybB zQQWh|Z)YkD8x&RF3AJKL*FLEOl1k(=uJH=T2;gB?Ks~Gg1gtI~n_Kq3zlVea%_#!l zn3%b)L?1Vm6cGxncvpDZHyBF|fU0S8*r42wCR%F$$>By~LyL*m6f8U4e|+=(Wo|=k z658a1H;0k82OMuQ=b1Gy0bW0INBmfPp=Jl^Q@8qEhDFhlIp32c3}M0& zYM{iWKH6tZsO`kCz+F<#VO7>x)Qug4&LoFIe{1`-n!9Z*FJ(gsW_KoJu+kAqwy zMM}`ZU>%{b@|@n~qOYH(;k>=e=^7f;NWUWW`z6YX$jBa-E}pq6t{Pn~IMB9^7T|^V&$A)tCtU&)@cckGMi+#M0YN)5fX-wM?IlL1Lx0+JLJP?HJDH?K6 z`?rZ1zQYE#-mcxE$G@|sEkN36$97vZkU8{#6?)-{Lcpqi<>Wed^S93os!PXX@PA&8 z9|8oM65BG8oDeb)l^+qLlQ_QFR@V6W6&GA#E46?Kf{6>M z_|&`H-~VZj*qp!ke$2f!OO!=xz4_zUaf^_*S-F z7A*}83J?i0YHHEK1V&7U)>AbeRR?Reb-FLHB7NaW=jMt4E7&d|#P98_P36)ctzslE z18llJ9I%{U2~UsUsrej^8NS1NAthQ4ccI=GXvjr?Q0tMte$qc15x4&?ul9}H$75dggt+L4x+#Tci?`XyGsmoTXiQ7E}ZNL+V-}n3Qzsq+S4`V+@9J$ z(R~Cp@W@IUb{{l!1e&K!U12o9$Un+;i^97TNQfW;w1g1GJ7b#&N(t$u$F{b56v%_V zDLESCW2VX@t6;nc<=vTQil+}zevO`9;RlF#+YJav$3f8o6M5=MP$7!m@ zQ7=AUO=aw$t5bkkwJmGIs)LfowAZKS?uY}`64Xs+WSAWM zvledwZLp?cRWVWsXKpUy0KoZK@V#S5K6>so3Ch|Sz=`WpCx>o@QyB)OHb|}Ohue{l zf8ImTv$u9~lLkn8u@gd4NKA}PXys{36ZE^oqB@98paCO0#DoybCBRs!RxkAvDZ0S;C%PpZ)4uvRMhtI?0bl-6 z-vD~zlEw*lx#8~WVM3RxVs!uBiKn}AcU zThOH7cep75GWf+*EUz#4MS$ShXLh*wAJS}k2OQ|oZp39D@n*cFeO}k+nbRFkxUVjc z5iRJG)e%8JKNG&Nw9!hz!|R)J^&rZ7&_rH7bSK4po0gnW?9S6#R@B}1k%Z`IyQh4o zh~^KOo0`|)>A6`=r_kI|bq5u@t*2p-lLBB7M6TU}lc!Y%pDF36ky^ZyV^~(4VHz!X zmd^b?Iht8pcE=ciCfPL(IC<*G*@9YDej$tp9P z{C44Ml*q@ps z%fWY`y`Xh4)e(R9+w?~nsQL;! zs(hZ~%B+VedvFH5n*E7ob=65NX(64Ci0mbWyhd)Vgl;$e(Gw`3jz+vq0M-jFz#^}Bm9bd~sQWU2us{8om7uF%1o{9n zjO|IQ4jBrOipDM(T@}0 zVbupru$|&fu@6AP{a2|0IykSgezrg{i$WqUc2(S@+1s|TN)}OE`-Bie!0phby5TV= z-$Z%vJXIvqN7&;iq5KZv(PseJ@i-OInG1e%zZAiRDz^m`Xs2MwRr+NZ+RzQ1_?@-UnUuPW(@XPZbNoz4&AWfm zb5|D3vgYK3R>AJIKS7ny-}Q9IT#BG*osgqA;*Yg{2n2JN^@N(1@} z%x>E++oGTFQnCSADjg%R@p-t=nJFLJx%)6MmtdloPR^ECL81p@RJrF!fv#_)@h%%Y zAAt6MO(&8NV)m!G^65nUOb2i|NL2bCw*a;VnpC!D>WU+4qL7_CgoSri6|WR-igD1T zCjCTHnzCPZFXneNn)n?Dn5s$Yr@%j;oo z!TVIf&Y$W^&}JfNkuG>F@c9R<7Uw`<4qW_79q^7D<-wx!0S0{PJ@6^%>t<&wiA6%d zjeyRP^L}6@=pCHuz^%QjGo$vDJut^=cp5V?^?cXQu)w`|3LcFvfV{hchm1Q-Jxz-H z1pMn$nozTpeqfKM2uM5$6r(xTt$G4ta97t zJ>y58&KM;i0bXJKNW`}BB6BXiq5X5$A*>vV*0;F;Tqthsz zl$%3>axibH;zJ1CP1$iXZfZ@6DbtuLXwn!afoB>|!U#Q54nEc11#eUaKG1Nc^Hb$9 zT=?&LfXL@)X>}%>aKIH*uQ*`sgN@AB;7pjG5?G!&9p?S~EThi^Y-#$TyY8seI~dk8 z?UJ5S|Jl>b0X-G{nUDlhi)-hlKYmcp4mXmW3S}#N7udU8b4AWNs-ahmg|jx}=;14% zioNH|z=qYIIRNthznZ$@4`PM?u~E|pKpsc>@*}2Rl;7x#udRva7%kEuJMd02&lsg@ zDVfJ0mpiEB1u1Q<% zoqm{CXCv*INGsee*8MMY!;b^>CNjS52K%jB|&(00JU-+(Z+wOj@BXtR z5{m|BcVw$O^GxkoPb4-+e-kTFWMOsc*VaH`X4#t}x(H4rV?~UnbHq*7pND{Pyav9+Yza9Ib9im^uYoqT%-}|c1ETBZ)7$?;5+>1?4=Flb$Y)rRh z8o}AttktInntg_Lf-Kwp-%Gn)X2(Btpk|=*_Z7MBdGlSu6RH{5>xdBHaqoHLs+1l3 zikI$*hS%@Vy5r!U<;u_+QdQGR%&(N_?ML5i+UFOA%I?)Dke&YFe;`6J3%fC(JH6zn?r@gHo2*{o5yu9RqOq19~ z`alZ9b_NychradWr~%a$z08{~FMc+7Ev%*)T>Vt@Hjd1G&ckkA$ElXw9(^?S!Ha7# zA>93Iq&PpoH`N&!f1#&m>!RA|Nmh4MUCxZlzp*`3=-xq^_nhklkgyEna*GR*IvTyL zvcTr(4HeXp?>8XAIhBwAzN$C(`V%cYnygNNIg7&hDG_25f=ancglF1MPsZ`fs)j#9 z>I{0O8?ktc5HyLf8fIGg{|bypHBv{mVv8mZ+ZIhnd#NUwn#VH-1Bbub#py^lJ;@~v z1z_@(9TA!~b{OF5Q)wG@(}z$|<4=pMZ)9R^EP*e3o+^ zz*O$`f5iBUKFvQ9fT)qdJfqEjB9Ia0^C=7^VQ+0?{a$u@c;bBGn+dpylZ4h26N-y4 zFqy!3#KF+VyJvC>8T}X+SkrB4H=^wYm*UGF|-VT0$M z31*<^{acXLJP$jSDL4y;@>B~(-u64{6QKK|kBn{#D)%)+rGJ$F_!dk=CIy_!1wZ;z zv0ArSF8hzvNHf@N_=qwz|EW?ZG2%>13t)}f4?h1>@^8pDjg{6sh%n+y}ED{z+ieJCdB+!tKv(&SQa&zg{|!s zfl|SNr!w^J+$(_vb2`RSkFFmj=Hm<}M&zF?v~5i96=IGZ_tBv@NaC?8CCmor`rijN z{eufbpA-CjP;Xi3LVDr8dkfc#e{o-^?0U65Bj_^d_MxhPD^Xv`QLbq#O9)R!RXXg` zf)hth9Qe$Ps~TF+hUBvQe~h6&)E`LT)H`03nm>RX3Oq*D70;xDikziOL_t=((8%3E zm#30?lI+PyE{%Wy$BU&BhjT?0#ts~n$K-RvC-N<5+JZw{kBqLPjS)a!n3Ncsxd1!; z$pN2MGvxWx4|*b73zUS3d_Nd|5u%Y6Ds_&%?}(27@xV-f)5_H`qNz}i2Z;!>#d>=M z4d`-!g*10o#g7=?3J2BCx4zWp4YQV(=P$(Qz$%a3%o-@b4GzH#K>9sDb>-?7ai)0k zMQMO2c>&L1^u3whUtoFkeq8VJO3H0_y8hu*qIUwnb9Axdio`zYYvJ(m5-mU%XI$lfg-sSOgCPY@Ngn2U+V_7;ysVY!z zrR5wu|3kZcX_tN?d;R4Lsd_ZX5OUZH5^z0i;o<*H^KW=D!A|#%$t;6F1}_;9nL@Th zMjA>bOcWnT7r09n3JL^z`i;jCJ1MwNlvBMex4(M-{-~hx7ZZcy*^{Zl;eFvU)=Wev zX0~qN_UG=LFyWBko32^_Msh?EqACC0VsHzwNF<&31GrrMhfrU)rlY^%OTwhrzCOHi z@D*9wj3?tTVJbK;u2w4FzLNEvSWt8TM~})ug?9exd@|$ z50vXPpbvRo3u+7Q1-A4p4`2~qRMRibP+vrIQzFYmWPUBfdmX1*sEml577)>k{SEo+ zTX5eL+N|M|52O38T?)?(vUF*{NOPKymsr<{L5SObBmY~EmDPh@4(6q1O0dH3W?WEq zK)83`al)TE_ka8a??t~}Amo`#kk0q&RyRlQi4kq{|o=o09Qblq+OTzTJoH zMH(XMD$4#kXKuwiuE|lFGE4e0#FgP^7CrA)j`U!{q-xdANbe!+8`V*%KF2ry?rE%x zg}b#G{WG9WJ7PPztxe)ZjpX`Ugj0zYzAJ}-7*I^)R4e7kRhO2i+0}VF%Tuwse*=B^ z;X804Z6(VZZT(miQ8KY~WZC5vhZo0&ATUOAz&Cr%z?mArMLxL!8bsTwE>7y^GcRyI z5TjFJI}f3QGmXTqrj^L*Es)u@M+v>B3=Oi+YdqO&R^rYQ`kD#Xwor}9e(*W05|uJGga%05`Md^nA-zH7ZOL zX|7N_Or#`(ppVnOyZi`Bn<5R=64=~JScnyKi<-AI0v2!$QHzD%t^9bo#YO{gt1DtO z3GcN~SKT@FUmTiT&Ulo$f&*-%KF0{`y0$J6y|LD{75J9F%q(j9~?GK1Ap^Oz8b2;gEHY>Q)(f{_$;|`wJFa z{a>6}#V$L@Y)1R0x~a%?bq0R>Ch*w$5w!aJQ}xeIl6sse7Ohu?;pG8eZ^_|bw&J!i zzf#|J-#1ir_mUunW!c^=?<2RtC*tR#_N7YI`QU$PYj_6sVu0tpaadVAHA^{cHRf(!yPVJe1tDO zL2qOXdMch)eK z(Mec?mCrc{+eCQu1^a<7eA|OgjrfnfV;V@=3Uk2Kw1xYAf=zx;?belBVP<(uY?0bLotH{_#h<7C6PJP!=cYpG-!At+5fPZd#q(Gt;gh38Bh9v43nAvdY zIUJ=Nu~a4-SU(x`@>`h~I3_U*o*a%d=ZW`mq{`*XLA-lQguaSqE4jOi--Wqw`3GM2 z_Be%5+d#Crbnf2z7dtbE!2A%y8Wyj*%ArgI3=sA*i`~Flu`P=69bkLpe0^FI=Xb~> zaxnXK# zNCW+trCkbUD=B2Vito$4VJ+V8>mWz1i}6>3;Qc8H)2sQH9b$!Jh4{A9S_IiLP>9F- ztR~34&$lWL#bK2jnmTq|1+NHC!mIzXAe9dh6-u!OS%~>y# zdb5aP+LBeO*;1w1LER|=zD->T)ImmjL^pwuJctvv)86q96Y|gA`AMK8`>|m~f^Q|^ z4u$Cng_(bAh2>nuC!vtHKZUjrx>q#IR{Ms}>pJUY$fE4-bYx#+)qP32%z^t0b+pus zUs`|3XkBu6M)~kX3?DPZ3jcDpqWFCQHF-jaz^xj|Fz}4hMCg)^Y2`mc5pcp0d&1!$ zMeMu}sH{%tJl(=!iNd}*35F+6FVZ9rnSRON{eC_`TWvG{i8Kpal{psMS$G;{tS5!`DGQ=q48him+Yt}#%nS}&O9dj=i3hPPRKVcLRQs#)`p+zlhGFhTL0@ua+v6{U(V zSGj;Kve^HUVSkTqss^B}$+>;Z_q2-b=+(`vR~-py*2{lYUuGmq%)H6!wM(P{on0m* zUEV9W$0|BbgXI3&cppcw7}v~FRI2eD9EL7FZ%<--?>C^(G7|@(I}Z``yv0PzT2MWe zW3@Bk2ANIPY6=j=$&wEAh`!P;Jo%iFf!*FoZtc_C$fE*NXsN5xfM+9T8LvK5?4$+P ztHI~1m&z6GEop{peB6R{BdI3p?Iq#92F(JG&B?;~8FSb96J|`h5exd%kPZ5upmU3# zyuIoP0+0y)EjSl@062DvZSIAPVB1M6bA)JKphp&H4sLehq&2O$zN=|u;M7cVoedtf zxd$yu0+4Isw;8DtW^KYznw*U5-ukn8zwQ8^B+0dF zf@O;}Osm8RK!%=vXfoV3me!chvY=|4gRyx}H>MwXyBlHS`*J8LR1S(aJxfr2^So%v ztRY~DXbT<|+y+@A9#Lzz;rLAKWKe6L6=ir&gWV6YgXk#($OcF$d9=eKSwSs#}iZlNF;BLK7Y} zW~cCC*14hp(BhQt0dU|bvP9@#9fPkE6K#{^WKI5lj$X&h;)O34MrRMl4X^IzeCN&m zf7<)%uqeB(Uy$w+5RjG*1qlHWq@+=#hY~5Np&3F%BoslqMMM;Y0ft6ks6pv&iGfi< z7=aN9>9gl~&ilRZb)Dxsf1T_6_3`Ii-22}5+N<|kzm+`KsM;Q@q%3{&5S5z;iLZZV z*=Q3NNTTv?VTsvwqU_smXlKfN6JaEB=izR29 z{&HeSk4}Cdbo2x9cIT^i2(VWS89b~tcjK>CvTQ$;vi)*k5wo}YU7hJlK1fF$>f7Xk zcIBQ+(LsaDh<{tH64>`$DEskxSJl(+&JI0ap#;3GxAsOc-CYt$iO{k=(S|q6ERyQ| zoHI`#bKg{6@Otzn1V+nGy&9qZo%~{bCW5Yt8tOpX+MWWVlPkAN1f^_y1~&Ah7H8UoIlUCk>8 znC1i3GYfREOD}XF{`x-rm*8%Dn8~H=3e{qncW8af;i!a@whfffHOrLBXOOG(w?*E8s zxG8s%wHcM!QlB8owZh{;qZl+1PCQ4ql2wyOC6Es3u)Hu_CJnX;f%HH6-vQDz2 z{_4L>#>J%H?i2e`-*h%xS#NoaBpP~)3pZ8aFxoIHw8Thg`H8D@IrB5+KjcS$F+O3f zseCt9^C~sYI90(&6@?9>98}`L&_v)sqYesmxIU-lR9pg8o$V``cCYYYhM@b1M^69D z1ToN^EiMZYxmxS{@pAXYj7h!)uWA%_Q$3Zbpibm|$ zldPABO7TOT>G)(J9!x@59CrRT1vKw@X@xf^d=H&mz&9;(2p}ow{h`mJqk|$ukt@$rfAv(&F4mgGP+u&d$>5{Ap7hkHk``(&g}$q#mK7WPEEj^BTQatF z0tqA^E+TwMIp|%EC*y*(r=s8W=6?jmDC(@{nK-incJ38Zn@;hPRW z(j5%jxX|UUPnlg`D)e-$&BO=c_-#=h;^s*AU&nuiwF8 zTTKr@5_>gEOf$ac92EP%#$%@mgMh*g2f|E3wk9O|@BHLs%&A6b!OYI&M{ES?-GKhy z#rVMJ{?Q`)#sin|Hq)K~!~O3a8`$R*Z77IYS76jDi#W5ar{ZDO^@IqglL&b!I>_~R zsH)bT;!VL+pn|ex7G8sDTOMc_|8Rml`uY64bv%c>*Bm+Jb_Uh06dbAjk0a4huSZKv zjKZHzzAlH9x+Sy)AMDL7*Bf+D*3Kj!U!D|bWJWVCKNL`Oko5h<7Wa!K14A;89CduMMfU5_dA7`SYOy~sWEAk3gJ+vFd zT^!T-+J@a~C9E+zUULunM{jIR|1O%d{laAAz>Jn&b|7kUVAzr3Y!9_~nR(65=+1Mp zmMH@zK*d@;oj#%z+|<)BPz88nZ{mJ(_WD8T7t;7kQWqfg9=Csya054cr&Df^!`}{e zxVIBSnUWixNL1r2+q`a8%cb9F^R%8sY{dBorK9W%bU5jnNoaJY(Vdydia!jSzm(a( z^Luv zS~0cU0W*`A)bsavx{iTOa|xIQ!e5!2}UYWQxXd=<+5jzvizF^5A! zAU-Rc4LW*&9}$s(g7|iT0s(x2dV#_A7W+V^wV8imby~p}!=G&lrrsi-2Al6ZI!{S0 zwopRRTEtKNVYh^_y8pVsvIHs99wL=_Nqz$ayI9w6DVOR20>=Hn0>F`77Ta5v4?N#{ zDfWAqY$!_=BuqbPzTin|&L@<3ToO&(m-NEHzdP|q1e$xXjb zgf$^$YSW&ZgnlJC|GTfN_AENHrGz=Z zY-t}d=&QsM?AzZb0V;dzc%+38z99*xAF;3CrPbi4b{cFEv--}^sE>oZLZS=IMWHeB!QCqmiTE{OlfOJP-Gb5rJ!Vil( zrv#8O;&)-!i-5ZfiotReG38<7*`Y?9Jp&@Q;ZNbWtM;B$=Qi6U8}6z~+zv%>K6rKD zA60Izg!-LT7#OAT)a^C-6>Wgh%JYew27F114rUN!13?9jj5WsTs^GCt@b~P{^x@Yh z60R$Iixskt&abbudk>f134(u;vg{oYz{t_5jdgXKHb$D^Wk#SZ^gwfPr1U$5sT0ZB=U&G z*&g7nP+QJKa#m7vN--HAGi6V>Grn!^WXh(!CH}B-?)MXC@(GYH0EEyR^kBJHgp|-i z5$NAnE+ezi4WCd3E@5U~N0J7i9;#SWK5>I(;_fT?dnp1xq9%XD9QJf(3U|&~B$!uS za<8O7;_i8!syyy3|Ksv*Zt?~wVBN*D-Z1jLH0Z#5DiK79GlSrqh;xph?&wQwE)*S++GUJEh+#F>M z&s#A(-2`(CaaH_gZ?CTwkhBuxB&WXdmr6a%3=$W1K_K%@(S%j;?k z;{Z`9@%Urmd;tgmx!Y|DhWi{FtW3^L+V0f{BLaGQ^n;25y1N6T0%izbj*>1GR+-m5 zrh`{Uz=2QI99swmS*Q6gQ3tZiYik_Nqa#N`?JnP{xieMD zeoURGjDEZrOf(e|nXBS2yF+DOc#lf{%>pFbmaY0;d|nml0u^t@`uj|32LO)Y-?An{VQ30(FRL9~py6M+GF zjhgfC1C>2A)c2LrBnZL<8p0P@rr!JAYn<=8((rYNBO-octkR>L`fw)djYV_?UdwYC z;1qPLN+V~w<^u0Rz5qtktCukYz;Gz|LwwaJDbRi}5jLyCqM8slik>BG@HBs7IR%OP zh}$30<=S#P3~gNgCOM>vYAUm>@&T9CH;4?%I*r8Z&d1GQaAMyay@Z6h@$ha-q~J6; zf+?@-g42|YZupvJj_+*JKf7B`ScaIMK6I9oyp4Wa*CY1a6#BI^X;Qr94el=IfwBK@ zFFr^@#UDaXDULy$vUF9WwHG{f+|kSyoZZ>iw``iK#123KDKdhSdl-S53+sD=&!zRU z_4So6CidqJ86P`FYn9jYK!4=;cGx^yJ)Ppcu2d)WxicB;e54uaHb+5~oS5CSm!m97 zkP#|uC6n1Z zs&G{faV@`#(_^oaXj3>eZh_R;1n1gp3b_WjQIs#urfIcfL@$+A%#GXX)0mG~VQ#DYeS468` zyt+>ZrA(9$a4iA+Z_YTBoS%{_zwrR#k-}|}2 zdmT}MQO3J!Qb+dchk6_tg-m9Jjngh1flyDyI@XV<+zBTA)EBDHfWGrgdbH?O3{2%i z9zo<)ygWQqKO`oy^FEA6Sy#Yi-mW6|#RPHRe>w;R(M0TqHW8{1 z4~c0Fi?!at<|E>MyY{HE1*)-;!qOr8b32FikP%LZa-GC)(T0@a9EB_QclL_vZqV74 zOJ1M>7_tq70?jctpjZ)an{rEr^<3)jNSH;{( z?0J%;K1MF>Yf`XJ3)lYYvqoZzOZnLAHiK29e4~41&}A=l+%hT6c{%M}cd*~+I$b)qJd67s`$?8d5z^FZf}{@?npS%T2Q{?< zwdR>2rZ7_sjjz5NCopw5a7vvIv3&#J7OBVqb!<&kj@x0oaAx4r+t$&al%W_ax7kS8 zQjz;YP$@u-?WpkcF-W|t^i^J$PD&7W%B zPVj30mxk4CAY&px#)`+7bt{34nNdQUOU}JiQT=P9M=20Tp3IGcuzCxoG$$FYxzwQB zxqh^$)t~4djhfB(87aAzgXe#a_pnoN6o;CTue5-jGP2|rqE?x~8(+DbXC2K9TpiU6 z)Li&R4Fjt!klVN|7NT+!>Oq3`jHnr-k^>joK8s?{MMlqxTkHn0RgoOc_SI(XFQcWNK(yY!0z45=HXfh{XyN=$1o^YAd~y1aR8NOLt;!ACl00z!Xqo22 z$Pv{!dbz#THQ?|;j~99(b-qs;^6MOqYHs-vBY`)@O0#ttVB8FVvYzg`N?C|^KaF8Z z`i})K0QbRv6)1owR{84g5mrvFX3=q;w7Mfb#|2YnX>)xk*i%SNmuv87higdBlA8eF z*A&l0L%m%FH_3fUvgDtRTpc-j#2RnUfEvK6knM2-KOzaRSa*q$k|+|nF8dm&L7=Cp}4GD2_jEF{TwVuL_e+z%kwI;YG(c_ zOb8X9Yh^BQAZaLSGcWn+?DDR6{rKJbbLHgh>=uJSc&as?-}VF=tHr0MvkNu>D@Or1 z1rA#COlKe<)tZ=1nY~^aR@++!9l%A+uTJU{Xg*n$()HB$c-g@coqyy3ch@8rZ&+#m zHk|ymMK;Ge^pfvU;0tVw%pPuPKI<(P+T_jESwM1C3t)a8BnPf^85k2%s1j!6s z)wt=y9p>h$Kw>kGm&#Rx8ZUy5EhbAnH46-;+FZ`P$bAJlpOuPM}@YE0|FKMLSO)UgJ;2`o63O(1iV@@GHI?|{}St~rY@a#WC{=xZ*m!GMivPb%iux=Mxq{aSa|CaF*lOL_}zHKwE$zW>b3a zR|q3IPChUCm*V12Pi9CxpT})Mxo7F~rHQ9U=leq>+NB%%?N5vju3aB^h7q9@eWrU? zyOLN2?sYB4ME6}f&6O-Gy=(ni<_sGC2E>F+s`g18-GYux*L2rol8mdJ^vxuu1N!^) zY92`FKXrVZnnmI$G=R%`P}DHAxn5LU+`RpLzV-3eCPIR;V7u|)^>*9q!=vrp}# zK_8-woncowgeKh)$riuur?DF;7=cbmnYH>utG6P=JoY?+=GIZ#=QV2?`(l}^xw=VUIlUP3 zhkWlvh}BdHFf_N5bmuj}V&2zK*hO`hbpv)25!8#;cu#Y?AvuV+9$yKGbZ4LdP2;wZ z(5tlNm~2Ls(5OPsr&OD-wPG@-D^d=V3ld};<$vYB?-40@~rTM4}8@4_wWORfD za4YJi^S{?)FzMR=w5uy!JSEp~vEz~4bi(^1!QrZ`-GO}3UdXv_DdXguKz%X6wlC71 zy04U8`D@$QbBdc!DJ(f zqk@|0P}seK8WROIT@TYKv+@eKBW9vM;q{RKGB5?Ze~KRGSXn+Aeqnv1Yp=fD5k}@# z2sxy3+lzWz@!j!+ef)v}F99JD1rL&xRA5Px7s=k9j(bzL8_N}K{;0%?+x)cp$q#+- zDH$hm{XPr|f;tKhJPFGhET83tDW)%}t^M*n`zg0Dt)G;7U@KD9Av>#7l#G!@#CN<1 zs~*qkx}tfXT(zAq0_V%mgQVSldU|}&572B@a@;GDL8F*uc^dA`rY>wU=hJ!~z*w@j z+*Hi4>NhKo^VSbp`M9@IA*$^y*br!GqeM{`+BUJ)&^|$z@(^B;_Gb9?oRR;67nMFZ z4X7lcP|Bva)zUR`Rh}!v^ynnw(x?Ru7-#!JoqOg@(0n*HHpYkVv{b=xHVjC1!gs24 zeJ8K(ov)jl77dxbC>PcIk;b*2VY~Qw%22(Xh6M$^F%i+A!?K zkx1JFZWWQ`R4hxzL>#M1aG{Gy6_!AEuUF|gPEqw_NNHR9@#B`80NH44VqyY-DP^4M zy-6WWZ!vK3om3<*Nnkf-gCrX&h;$!`dX7u~FrlnTq*A*z4x8T}uYd+GB3|jOq1Jsp zwuG*5>D@p}4PuQQz2u5-ge-rYn3&YQ$cM}FpZifnc+TJB9nIPNeV|Pp&8N6aN34Dito)|=`~y_xAuzN zlix5Z$y^-!VUkjV@SLV=E<@OaHXl&!9XjgO)Hc|P2n}<*Iq0bMb%7}C{Gp$#&aj8Q79C{s6TwtYQ8jZb8G0WBb&)1)0j<5R)fsP*qZ-%BmX z<)3^&WEvgC)%8#34=C(td(?}wxWSLiT~Ex?gK3}5|8n%};WP@I3)`gBsdqEi&Y9ec z>-DYr^eKzw#>ETtr#=J(t%#9KKJD zNL6=t(ViA~c(WX?M+04#MhK>}CSd}kbbN$~d6F^-Q2hx{aZR7db||2OLJsZSmMx)`?O_;?k{Ag8fUp?jCw!B9GFN{Pv$`x$PE&f4U!*pTh$ryxUQruastO< z5r2%RQu`#N- z`rUQp_Tn{LbnD|36M<5j%`9g%wr9Bm*YUIu$rW%VAtcXIji5$Q+!Ka!)7#RV>B4g5 zDtcZQq`1M1sJX8+LyC2eC!Y2vBx5%1GU&So;5sWLjxbq45j>3?VU1)xxD7OsE-co= z+SZ2+tzsu@75-%L;`*bqU&x2-Y_@@*wETAa`YQdG_cvQwE6gpY@;F@Sz*{xJTP=SH z-+_YN-yLSLh2PR}I9--^lSK+)nRdFAS$krqUt9Xy*hnKCLCELc`aQ1KO++9w0K8m1 zN3Gra0yzRhNclFD96{K~45GkH5>!M5SwMingImN*dnuvk>ko%mmlsbT?6d70*{tb6J?pRm z0lhf9`vaG%8Ub1fmq&oYDvgcg(PJjbEp=hrBEc~YS>mBzX+LGX&c9?V(Pr(}da~`r zZ&MEE(CWqeIr4d5hX%df^{Mb*O?@Q-+*PMVG)Ljw2+UDR$W4yqUffoj|Hl*GNsV=O zv$^dKnFeX>K8%UWzDBI@$Bi-GfPer-z0aRFr~h~*79)Amc@I)^Q>97G9*tyCKcXb; z1pYz{nQ+7w@E4NOaj$+b*%oJ;we>T;wr!YUe55REy0ekO66`m0X&Ac^bIdK=ucLqa}@G zA7=z^%F~;~^tN79QRd&d?xK{cH@&dbhS$rB9AN@1spqXe@hAIJHCHmUsgrCP#x}s$ zT=~mQ15Y#Y81T~b0loG-()3*gI7fT1XSd_-5hs|^9h#Ii$Z#sr{hXIuS&e(@DA|J%K3MD&Co#*~&80aiaFRl1~kVwhaV|NYCGPO2Lan zh)lGqHaJLLn%9X7S}<9AQ4Hro{pT5Ks8N8vt)+L&N#NEa#+P4SN-C^so%P^YBrkb4 zb!JUlO}u@7?IZR^@^Dz~LcL!ova41V@8qchd3<`C;*%bbM}Xd53`$Jwr4u{dd-6Kg~)dP($NXw@R7*mQ7|nm-gusU?ltqs6X9A!5N~`aA=HZC)PiA z$>W7#gO6xG!baZO)+#J!cZ%BDt89emkt6J3#&Wf;`gxdJ$@M9(>j>NH-@OopQWAKP zxt2r#@_2VIY%u~Jv!>W)%Vpt6#cW0PIzdHv`uSDKzMCw z2Ph}{G~BC&T4BGKdHwS790&ra)$lT{H}l>xwTa~%IQtxqY%!B&E1eaZK&7TCy!m$1 z|39fnEP! z1S4=63IwFqTtL^T)#FOXiIXwPVIgYub#DZ@_1Rwsb=Nv%>$<^yt0Xxe@T#^L0q+~p zWpW!Zz}o@fcuSMDNA&X}*>B%Pg-#XCUFgT1t>vG{QNq4YZtZ`Oyr z_mBTL)J$X{&{u3Hy{WZRg82Z#!BTv1dDj_;bT*NF`wD|?0*^3;^S~Y`=>B2q?cR;7 zpVkxN=VuMYa>+f+z?u;CD8P8vTrx6d|t z2~2PPDjRDzbpKg91(y>0i${|Ik2;t{ZZe_Z9S{m=|FiQYNR0W)^Ze%U%9|~fmLa9^ zo10myvYqRz*i&8cLg3%w^{*)2q@-mNpdhORm%M|c%=yW6VciE5&{hM%`80)EIz-A7 zD|wB58u*sopUN=kPWi_NGoMtAiBYK4gZ_HPYvN(L!1&kEJv?&bHF(z zWLHhYEn|VrJxzM3lF8@Cmw#BXR-ZTbUG^WsQ8A42T1Rf#bzpJ1xUB^e7Z!NVgFS89 z0s=&?K4%tR!_^3WrE&SoQ%xv|1lmtE8|WV=+6cnTJ22VEBt|qMxDR(WOhWO<-7`(S zxHyC3{<*?}ek3)bLBHJG>t}67+D~c`5PIu8!#{0F4xaAtn$QI2<}Hj-ZZLx7Im1G~ zOC63H)K&k62k`lN+-y3J}}f? zKD%4jnr{FRU&k@@f01{?A53VE^+B}H=2dlv>IVS{C;MY=M%ay}WND>Cno_eHJs<$t z(TmBkHT{A9kS;Z494a~j5^=fC?U_JSWys%$4k130ng zA$~)-0SRi;J`0H5y`!#srQuFpD{1D*;Z8?cvF7^$q?OucIzi?QR~RXhKWR&6T-?)W zJ5oLsJ6%ItAgl@vC$`-p>%zB{B<*s;x?N`1tc98%AD#4y2BhDg_8CX)22j>jb!E%a z4xjd6k_Hhoe{2rmjiGk3fwQ!|Al%Z$IJJ&`fze`aw_(+?Wmyl&l#x_IQ->44_jV(?T@XkjGP>H zR}%ulJ!)D+AFwmCpH;H;`v9(x(_Fph*vN=IXN$*IY5XW$=HpL~JUocWz+n=C6Ck_o zdtg0{j(2c++*1OuBm;O4YjqJhwC6(6s11I-=lJy~S!|*s=m2eKo`d%wlVmkv>MYk1 zw*Fdg0<3qh@`osK7)Up`scPW2UIw;a9r4JY6~Ep)u-@}XO>^EQB0{hvAAakOVCzXF z`i0H-_2}{IT@-JkB;*EUWT*fCMhd?q>=^+8#jcLVZIl0=ELb89LqbAwphV~+2tX29 z5}erl%*gfs`i0=Hecw`DzWCQa5d8JOt3crlCeSE91CRXu%U?9c5;{Pk2oE&U5 z|K$91Y-&ny?X};l?wXMS(5UM;c64wAn6`H)Pl+mU6O3c6U;Vx74iL(BdX2)z-WQCp zW)h=8^ELS8B@)a#28vM3?r1D?nab`@WPgn}%mkbT7vCWm5j>x=0D$&;L0kJWmSrxsJY=Mz+nWNgj$qEUbkLUd*XAHZnQe;|*W=xLB_$>6(_a9V%UlNeaF$eO zTE#dWH~Gn*Zj}tX(+zXqlRrM#PFfU}XhJ$)t^9MP^B_B$ltUEq&$pL5U~2c;X0lbZ z6BrX-4M5JN53>4?b(R{}-lT#(^Z^LKWdKQEZQpU>-tQ9ts(yl`UZbP{r=tEgL()dH z#(6LW%mT11pS%*X)K1uVxSFf{Izdp7{;p*x^Eg0Dgk%%!SvC58_*iD-m2u}qWglZ0 z7)vZ)fZgp7x&Xk3tHZCM0W700C?n)W-tv(+cx3x{&oo;xpmcBhSV-ki2fc*^V2L0f zoY)gX!_l{3Q(>oe!Oid-Op+D@!wG^Z5U3IZfe2j4^8sY=@Aq|eriMzJGVr>byOSEF z(iBLP&JvhtWEQjbLg-Bowd!N$sfmdzeyaoP@*ly>B6Iw>^Lt+lllkxTfpSSntXvnSy@>+bpK~03f_8T#_bQbA-FLEifk=bhx79faU8rCnU&JE zw!GXc(6x_Jg;-+M10sSafRp+3B&< zmpJCr)-e-~mmdcZM-i!~iay_>Oxxh$B{T4`jP0;BCH;38YGp86=o2$XOdhVZJ})oN z*v{@MCnx6)m^*IyyZMOnwYd!W$NW(+;2<3WZINXsa=2IloV1GM7keW2oczG#sE2iD zU#^Dps+_JHmB-qEcdItF>ZQxPx7+B@NdMIc5bNV;b-$bfe86OQMU&|3XT{T}?0iPj8YAUW$Y7;=@Jo>U5l`%Pv%D+I~9 zJ$j?PT13dv^%mV{M}z>!F=&TAl`KP0_MU(Uuse0SmnKAMNun{SwvC#anFB zj?Yaq-kYu89d`Y=LJ9@rq@Uf9UA3&eI=00(A2wn|{&h;JOKt8d1^W-cTz6U1E zuMpD71>cky?9*1A+$!PrZw}h7ug1fQ_LY4u;4*369n&k1-v%Em1V#ResdFy2>e4SC zlJfcXS$hAq-mwn&!qg(RwLT%_#$x5sL4})=UFfFly?&ZfcB49K3;^JMAYs%qz3BXT z*!`-B!YrmUR)FQDlVO3G`8Ps8ghuBAErurOBC=z+xIX;KE}aCw=2TtV&d7=)b@Ie@KEq kfd3)M|8U9w3&A;2Is1ZjJqwN}A^?9nnuZz`YW9);3)QkSO8@`> literal 0 HcmV?d00001 diff --git a/test/image/mocks/scatter_fill_gradient_tonext.json b/test/image/mocks/scatter_fill_gradient_tonext.json new file mode 100644 index 00000000000..299904187d8 --- /dev/null +++ b/test/image/mocks/scatter_fill_gradient_tonext.json @@ -0,0 +1,42 @@ +{ + "data": [ + { + "x": [1, 1, 2, 2], + "y": [1, 2, 2, 1], + "type": "scatter", + "mode": "none", + "fill": "tonext", + "hoveron": "points+fills", + "fillgradient": { + "orientation": "horizontal", + "colorscale": [ + [0.0, "rgba(0, 255, 0, 1)"], + [0.5, "rgba(0, 255, 0, 0)"], + [1.0, "rgba(0, 255, 0, 1)"] + ] + } + }, + { + "x": [0, 0, 3, 3], + "y": [0, 4, 4, 1], + "type": "scatter", + "mode": "none", + "fill": "tonext", + "hoveron": "fills+points", + "fillgradient": { + "orientation": "radial", + "colorscale": [ + [0.0, "rgba(255, 255, 0, 0.0)"], + [0.8, "rgba(255, 0, 0, 0.3)"], + [1.0, "rgba(255, 255, 0, 1.0)"] + ] + } + } + ], + + "layout": { + "autosize": true, + "title": { "text": "Scatter traces with radial color gradient fills" }, + "showlegend": true + } +} \ No newline at end of file diff --git a/test/image/mocks/scatter_fill_gradient_tonexty_toself.json b/test/image/mocks/scatter_fill_gradient_tonexty_toself.json new file mode 100644 index 00000000000..503d97059c2 --- /dev/null +++ b/test/image/mocks/scatter_fill_gradient_tonexty_toself.json @@ -0,0 +1,81 @@ +{ + "data": [ + { + "x": [0, 2], + "y": [1, 2.5], + "type": "scatter", + "mode": "none", + "fill": "tonexty", + "fillcolor": "rgba(0, 255, 0, .5)", + "fillgradient": { + "orientation": "horizontal", + "colorscale": [ + [0.0, "rgba(0, 255, 0, 1)"], + [0.5, "rgba(0, 255, 0, 0)"], + [1.0, "rgba(0, 255, 0, 1)"] + ], + "start": 0, + "stop": 1 + }, + "name": "greenthing", + "hoveron": "fills+points" + }, + { + "x": [0, 0.75, 1.5, 2], + "y": [1, 2, 2.5, 2.8], + "type": "scatter", + "mode": "none", + "fill": "tonexty", + "hoveron": "fills+points", + "fillgradient": { + "orientation": "horizontal", + "colorscale": [ + [0.0, "rgba(255, 255, 0, 1.0)"], + [0.6, "rgba(255, 255, 0, 1.0)"], + [1.0, "rgba(255, 255, 0, 0.3)"] + ] + }, + "name": "yellow" + }, + { + "x": [0, 1, 1, 0.5, 0], + "y": [5, 5, 2, 1.5, 0], + "type": "scatter", + "mode": "none", + "fill": "toself", + "fillgradient": { + "orientation": "vertical", + "colorscale": [ + [0.0, "rgba(255, 0, 0, 0.8)"], + [1.0, "rgba(0, 0, 255, 0.9)"] + ] + }, + "fillcolor": "rgb(255, 0, 0)", + "hoveron": "fills" + }, + { + "x": [1.1, 2, 2, 1.1], + "y": [5, 5, 3, 2.1], + "type": "scatter", + "mode": "none", + "fill": "toself", + "fillgradient": { + "orientation": "vertical", + "colorscale": [ + [0.0, "rgba(255, 0, 0, 0.8)"], + [1.0, "rgba(0, 0, 255, 0.9)"] + ], + "start": 0, + "stop": 5 + }, + "fillcolor": "rgb(255, 0, 0)", + "hoveron": "fills" + } + ], + + "layout": { + "autosize": true, + "title": { "text": "Scatter traces with linear color gradient fills" }, + "showlegend": true + } +} \ No newline at end of file From 45e2cda92741e38593bbda027e7ec21dc620ae7a Mon Sep 17 00:00:00 2001 From: Lukas Prediger Date: Sat, 24 Feb 2024 19:08:52 +0200 Subject: [PATCH 02/10] added generated plot-schema for scatter gradient fills. --- test/plot-schema.json | 59 +++++++++++++++++++++++++++++++++---------- 1 file changed, 46 insertions(+), 13 deletions(-) diff --git a/test/plot-schema.json b/test/plot-schema.json index b58690cba3c..60e97ea27cc 100644 --- a/test/plot-schema.json +++ b/test/plot-schema.json @@ -16238,7 +16238,7 @@ "valType": "number" }, "fillcolor": { - "description": "Sets the fill color. Defaults to a half-transparent variant of the line color, marker color, or marker line color, whichever is available.", + "description": "Sets the fill color. Defaults to a half-transparent variant of the line color, marker color, or marker line color, whichever is available. If fillgradient is specified, fillcolor is ignored except for setting the background color of the hover label, if any.", "editType": "style", "valType": "color" }, @@ -17578,7 +17578,7 @@ "decreasing": { "editType": "style", "fillcolor": { - "description": "Sets the fill color. Defaults to a half-transparent variant of the line color, marker color, or marker line color, whichever is available.", + "description": "Sets the fill color. Defaults to a half-transparent variant of the line color, marker color, or marker line color, whichever is available. If fillgradient is specified, fillcolor is ignored except for setting the background color of the hover label, if any.", "editType": "style", "valType": "color" }, @@ -17761,7 +17761,7 @@ "increasing": { "editType": "style", "fillcolor": { - "description": "Sets the fill color. Defaults to a half-transparent variant of the line color, marker color, or marker line color, whichever is available.", + "description": "Sets the fill color. Defaults to a half-transparent variant of the line color, marker color, or marker line color, whichever is available. If fillgradient is specified, fillcolor is ignored except for setting the background color of the hover label, if any.", "editType": "style", "valType": "color" }, @@ -45035,10 +45035,43 @@ }, "fillcolor": { "anim": true, - "description": "Sets the fill color. Defaults to a half-transparent variant of the line color, marker color, or marker line color, whichever is available.", + "description": "Sets the fill color. Defaults to a half-transparent variant of the line color, marker color, or marker line color, whichever is available. If fillgradient is specified, fillcolor is ignored except for setting the background color of the hover label, if any.", "editType": "style", "valType": "color" }, + "fillgradient": { + "colorscale": { + "anim": true, + "description": "Sets the fill gradient colors as a color scale. The color scale is interpreted as a gradient applied in the direction specified by *orientation*, from the lowest to the highest value of the scatter plot along that axis, or from the center to the most distant point from it, if orientation is *radial*.", + "editType": "style", + "valType": "colorscale" + }, + "description": "Sets a fill gradient. If not specified, the fillcolor is used instead.", + "editType": "style", + "orientation": { + "description": "Sets the orientation of the color gradient. Defaults to *none*.", + "dflt": "none", + "editType": "style", + "valType": "enumerated", + "values": [ + "radial", + "horizontal", + "vertical", + "none" + ] + }, + "role": "object", + "start": { + "description": "Sets the gradient start value. It is given as the absolute position on the axis determined by the orientiation. E.g., if orientation is *horizontal*, the gradient will be horizontal and start from the x-position given by start. If omitted, the gradient starts at the lowest value of the trace along the respective axis. Ignored if orientation is *radial*.", + "editType": "calc", + "valType": "number" + }, + "stop": { + "description": "Sets the gradient end value. It is given as the absolute position on the axis determined by the orientiation. E.g., if orientation is *horizontal*, the gradient will be horizontal and end at the x-position given by end. If omitted, the gradient ends at the highest value of the trace along the respective axis. Ignored if orientation is *radial*.", + "editType": "calc", + "valType": "number" + } + }, "fillpattern": { "bgcolor": { "arrayOk": true, @@ -49559,7 +49592,7 @@ ] }, "fillcolor": { - "description": "Sets the fill color. Defaults to a half-transparent variant of the line color, marker color, or marker line color, whichever is available.", + "description": "Sets the fill color. Defaults to a half-transparent variant of the line color, marker color, or marker line color, whichever is available. If fillgradient is specified, fillcolor is ignored except for setting the background color of the hover label, if any.", "editType": "style", "valType": "color" }, @@ -51461,7 +51494,7 @@ ] }, "fillcolor": { - "description": "Sets the fill color. Defaults to a half-transparent variant of the line color, marker color, or marker line color, whichever is available.", + "description": "Sets the fill color. Defaults to a half-transparent variant of the line color, marker color, or marker line color, whichever is available. If fillgradient is specified, fillcolor is ignored except for setting the background color of the hover label, if any.", "editType": "calc", "valType": "color" }, @@ -53564,7 +53597,7 @@ ] }, "fillcolor": { - "description": "Sets the fill color. Defaults to a half-transparent variant of the line color, marker color, or marker line color, whichever is available.", + "description": "Sets the fill color. Defaults to a half-transparent variant of the line color, marker color, or marker line color, whichever is available. If fillgradient is specified, fillcolor is ignored except for setting the background color of the hover label, if any.", "editType": "calc", "valType": "color" }, @@ -55580,7 +55613,7 @@ ] }, "fillcolor": { - "description": "Sets the fill color. Defaults to a half-transparent variant of the line color, marker color, or marker line color, whichever is available.", + "description": "Sets the fill color. Defaults to a half-transparent variant of the line color, marker color, or marker line color, whichever is available. If fillgradient is specified, fillcolor is ignored except for setting the background color of the hover label, if any.", "editType": "calc", "valType": "color" }, @@ -56780,7 +56813,7 @@ ] }, "fillcolor": { - "description": "Sets the fill color. Defaults to a half-transparent variant of the line color, marker color, or marker line color, whichever is available.", + "description": "Sets the fill color. Defaults to a half-transparent variant of the line color, marker color, or marker line color, whichever is available. If fillgradient is specified, fillcolor is ignored except for setting the background color of the hover label, if any.", "editType": "style", "valType": "color" }, @@ -58726,7 +58759,7 @@ ] }, "fillcolor": { - "description": "Sets the fill color. Defaults to a half-transparent variant of the line color, marker color, or marker line color, whichever is available.", + "description": "Sets the fill color. Defaults to a half-transparent variant of the line color, marker color, or marker line color, whichever is available. If fillgradient is specified, fillcolor is ignored except for setting the background color of the hover label, if any.", "editType": "calc", "valType": "color" }, @@ -60562,7 +60595,7 @@ ] }, "fillcolor": { - "description": "Sets the fill color. Defaults to a half-transparent variant of the line color, marker color, or marker line color, whichever is available.", + "description": "Sets the fill color. Defaults to a half-transparent variant of the line color, marker color, or marker line color, whichever is available. If fillgradient is specified, fillcolor is ignored except for setting the background color of the hover label, if any.", "editType": "style", "valType": "color" }, @@ -62506,7 +62539,7 @@ ] }, "fillcolor": { - "description": "Sets the fill color. Defaults to a half-transparent variant of the line color, marker color, or marker line color, whichever is available.", + "description": "Sets the fill color. Defaults to a half-transparent variant of the line color, marker color, or marker line color, whichever is available. If fillgradient is specified, fillcolor is ignored except for setting the background color of the hover label, if any.", "editType": "style", "valType": "color" }, @@ -72214,7 +72247,7 @@ "valType": "string" }, "fillcolor": { - "description": "Sets the fill color. Defaults to a half-transparent variant of the line color, marker color, or marker line color, whichever is available.", + "description": "Sets the fill color. Defaults to a half-transparent variant of the line color, marker color, or marker line color, whichever is available. If fillgradient is specified, fillcolor is ignored except for setting the background color of the hover label, if any.", "editType": "style", "valType": "color" }, From d09b343e452e42a7a86ec84495008f821030365b Mon Sep 17 00:00:00 2001 From: Lukas Prediger Date: Tue, 27 Feb 2024 22:26:28 +0200 Subject: [PATCH 03/10] Changes for fillgradients based on first review - removed assert - renamed new mocks and baselines - used local variable instead of direct reference to trace property - added trailing newlines to new mock .json files --- src/components/drawing/index.js | 19 +++++++++--------- src/traces/scatter/attributes.js | 3 +-- src/traces/scatter/fillcolor_defaults.js | 2 -- ...ng => zz-scatter_fill_gradient_tonext.png} | Bin ...-scatter_fill_gradient_tonexty_toself.png} | Bin ...n => zz-scatter_fill_gradient_tonext.json} | 2 +- ...scatter_fill_gradient_tonexty_toself.json} | 2 +- 7 files changed, 13 insertions(+), 15 deletions(-) rename test/image/baselines/{scatter_fill_gradient_tonext.png => zz-scatter_fill_gradient_tonext.png} (100%) rename test/image/baselines/{scatter_fill_gradient_tonexty_toself.png => zz-scatter_fill_gradient_tonexty_toself.png} (100%) rename test/image/mocks/{scatter_fill_gradient_tonext.json => zz-scatter_fill_gradient_tonext.json} (99%) rename test/image/mocks/{scatter_fill_gradient_tonexty_toself.json => zz-scatter_fill_gradient_tonexty_toself.json} (99%) diff --git a/src/components/drawing/index.js b/src/components/drawing/index.js index 31fa0248071..864994f5668 100644 --- a/src/components/drawing/index.js +++ b/src/components/drawing/index.js @@ -179,6 +179,7 @@ drawing.dashStyle = function(dash, lineWidth) { function setFillStyle(sel, trace, gd, forLegend) { var markerPattern = trace.fillpattern; + var fillgradient = trace.fillgradient; var patternShape = markerPattern && drawing.getPatternAttr(markerPattern.shape, 0, ''); if(patternShape) { var patternBGColor = drawing.getPatternAttr(markerPattern.bgcolor, 0, null); @@ -192,32 +193,32 @@ function setFillStyle(sel, trace, gd, forLegend) { undefined, markerPattern.fillmode, patternBGColor, patternFGColor, patternFGOpacity ); - } else if(trace.fillgradient && trace.fillgradient.orientation !== 'none') { - var direction = trace.fillgradient.orientation; + } else if(fillgradient && fillgradient.orientation !== 'none') { + var direction = fillgradient.orientation; var gradientID = 'scatterfill-' + trace.uid; if(forLegend) { gradientID = 'legendfill-' + trace.uid; } - if(!forLegend && (trace.fillgradient.start !== undefined || trace.fillgradient.stop !== undefined)) { + if(!forLegend && (fillgradient.start !== undefined || fillgradient.stop !== undefined)) { var start, stop; if(direction === 'horizontal') { start = { - x: trace.fillgradient.start, + x: fillgradient.start, y: 0, }; stop = { - x: trace.fillgradient.stop, + x: fillgradient.stop, y: 0, }; } else if(direction === 'vertical') { start = { x: 0, - y: trace.fillgradient.start, + y: fillgradient.start, }; stop = { x: 0, - y: trace.fillgradient.stop, + y: fillgradient.stop, }; } @@ -234,12 +235,12 @@ function setFillStyle(sel, trace, gd, forLegend) { stop.y = trace._yA.c2p( (stop.y === undefined) ? trace._extremes.y.max[0].val : stop.y, true ); - sel.call(gradientWithBounds, gd, gradientID, 'linear', trace.fillgradient.colorscale, 'fill', start, stop, true, false); + sel.call(gradientWithBounds, gd, gradientID, 'linear', fillgradient.colorscale, 'fill', start, stop, true, false); } else { if(direction === 'horizontal') { direction = direction + 'reversed'; } - sel.call(drawing.gradient, gd, gradientID, direction, trace.fillgradient.colorscale, 'fill'); + sel.call(drawing.gradient, gd, gradientID, direction, fillgradient.colorscale, 'fill'); } } else if(trace.fillcolor) { sel.call(Color.fill, trace.fillcolor); diff --git a/src/traces/scatter/attributes.js b/src/traces/scatter/attributes.js index 2d7916ecd8d..d2971f3f061 100644 --- a/src/traces/scatter/attributes.js +++ b/src/traces/scatter/attributes.js @@ -443,7 +443,6 @@ module.exports = { colorscale: { valType: 'colorscale', editType: 'style', - anim: true, description: [ 'Sets the fill gradient colors as a color scale.', 'The color scale is interpreted as a gradient', @@ -453,7 +452,7 @@ module.exports = { 'distant point from it, if orientation is *radial*.' ].join(' ') }, - editType: 'style', + editType: 'calc', description: [ 'Sets a fill gradient.', 'If not specified, the fillcolor is used instead.' diff --git a/src/traces/scatter/fillcolor_defaults.js b/src/traces/scatter/fillcolor_defaults.js index bc611169d33..0d6f678cfa0 100644 --- a/src/traces/scatter/fillcolor_defaults.js +++ b/src/traces/scatter/fillcolor_defaults.js @@ -2,10 +2,8 @@ var Color = require('../../components/color'); var isArrayOrTypedArray = require('../../lib').isArrayOrTypedArray; -var assert = require('assert'); function averageColors(colorscale) { - assert(colorscale.length >= 2); var color = Color.interpolate(colorscale[0][1], colorscale[1][1], 0.5); for(var i = 2; i < colorscale.length; i++) { var averageColorI = Color.interpolate(colorscale[i - 1][1], colorscale[i][1], 0.5); diff --git a/test/image/baselines/scatter_fill_gradient_tonext.png b/test/image/baselines/zz-scatter_fill_gradient_tonext.png similarity index 100% rename from test/image/baselines/scatter_fill_gradient_tonext.png rename to test/image/baselines/zz-scatter_fill_gradient_tonext.png diff --git a/test/image/baselines/scatter_fill_gradient_tonexty_toself.png b/test/image/baselines/zz-scatter_fill_gradient_tonexty_toself.png similarity index 100% rename from test/image/baselines/scatter_fill_gradient_tonexty_toself.png rename to test/image/baselines/zz-scatter_fill_gradient_tonexty_toself.png diff --git a/test/image/mocks/scatter_fill_gradient_tonext.json b/test/image/mocks/zz-scatter_fill_gradient_tonext.json similarity index 99% rename from test/image/mocks/scatter_fill_gradient_tonext.json rename to test/image/mocks/zz-scatter_fill_gradient_tonext.json index 299904187d8..4ce95602b66 100644 --- a/test/image/mocks/scatter_fill_gradient_tonext.json +++ b/test/image/mocks/zz-scatter_fill_gradient_tonext.json @@ -39,4 +39,4 @@ "title": { "text": "Scatter traces with radial color gradient fills" }, "showlegend": true } -} \ No newline at end of file +} diff --git a/test/image/mocks/scatter_fill_gradient_tonexty_toself.json b/test/image/mocks/zz-scatter_fill_gradient_tonexty_toself.json similarity index 99% rename from test/image/mocks/scatter_fill_gradient_tonexty_toself.json rename to test/image/mocks/zz-scatter_fill_gradient_tonexty_toself.json index 503d97059c2..530624720cd 100644 --- a/test/image/mocks/scatter_fill_gradient_tonexty_toself.json +++ b/test/image/mocks/zz-scatter_fill_gradient_tonexty_toself.json @@ -78,4 +78,4 @@ "title": { "text": "Scatter traces with linear color gradient fills" }, "showlegend": true } -} \ No newline at end of file +} From 4c56fa819241ba5561e8bcdb985de80d0373f5f0 Mon Sep 17 00:00:00 2001 From: Lukas Prediger Date: Wed, 28 Feb 2024 22:15:00 +0200 Subject: [PATCH 04/10] Changed scatter attribute fillgradient.orientation to fillgradient.type for greater consistency with marker.gradient.type --- src/components/drawing/index.js | 4 +-- src/traces/scatter/attributes.js | 6 ++--- src/traces/scatter/fillcolor_defaults.js | 2 +- .../zz-scatter_fill_gradient_tonext.json | 4 +-- ...-scatter_fill_gradient_tonexty_toself.json | 8 +++--- test/plot-schema.json | 27 +++++++++---------- 6 files changed, 25 insertions(+), 26 deletions(-) diff --git a/src/components/drawing/index.js b/src/components/drawing/index.js index 864994f5668..2784a2d4d73 100644 --- a/src/components/drawing/index.js +++ b/src/components/drawing/index.js @@ -193,8 +193,8 @@ function setFillStyle(sel, trace, gd, forLegend) { undefined, markerPattern.fillmode, patternBGColor, patternFGColor, patternFGOpacity ); - } else if(fillgradient && fillgradient.orientation !== 'none') { - var direction = fillgradient.orientation; + } else if(fillgradient && fillgradient.type !== 'none') { + var direction = fillgradient.type; var gradientID = 'scatterfill-' + trace.uid; if(forLegend) { gradientID = 'legendfill-' + trace.uid; diff --git a/src/traces/scatter/attributes.js b/src/traces/scatter/attributes.js index d2971f3f061..05ac5146784 100644 --- a/src/traces/scatter/attributes.js +++ b/src/traces/scatter/attributes.js @@ -404,13 +404,13 @@ module.exports = { ].join(' ') }, fillgradient: extendFlat({ - orientation: { + type: { valType: 'enumerated', values: ['radial', 'horizontal', 'vertical', 'none'], dflt: 'none', - editType: 'style', + editType: 'calc', description: [ - 'Sets the orientation of the color gradient.', + 'Sets the type/orientation of the color gradient for the fill.', 'Defaults to *none*.' ].join(' ') }, diff --git a/src/traces/scatter/fillcolor_defaults.js b/src/traces/scatter/fillcolor_defaults.js index 0d6f678cfa0..d91b15f0f5d 100644 --- a/src/traces/scatter/fillcolor_defaults.js +++ b/src/traces/scatter/fillcolor_defaults.js @@ -33,7 +33,7 @@ module.exports = function fillColorDefaults(traceIn, traceOut, defaultColor, coe // to specifiy fillcolor after all other more specific candidates // are considered, but before the global default color. // fillcolor affects the background color of the hoverlabel in this case. - var gradientOrientation = coerce('fillgradient.orientation'); + var gradientOrientation = coerce('fillgradient.type'); if(gradientOrientation !== 'none') { coerce('fillgradient.start'); coerce('fillgradient.stop'); diff --git a/test/image/mocks/zz-scatter_fill_gradient_tonext.json b/test/image/mocks/zz-scatter_fill_gradient_tonext.json index 4ce95602b66..3be1cd0b03e 100644 --- a/test/image/mocks/zz-scatter_fill_gradient_tonext.json +++ b/test/image/mocks/zz-scatter_fill_gradient_tonext.json @@ -8,7 +8,7 @@ "fill": "tonext", "hoveron": "points+fills", "fillgradient": { - "orientation": "horizontal", + "type": "horizontal", "colorscale": [ [0.0, "rgba(0, 255, 0, 1)"], [0.5, "rgba(0, 255, 0, 0)"], @@ -24,7 +24,7 @@ "fill": "tonext", "hoveron": "fills+points", "fillgradient": { - "orientation": "radial", + "type": "radial", "colorscale": [ [0.0, "rgba(255, 255, 0, 0.0)"], [0.8, "rgba(255, 0, 0, 0.3)"], diff --git a/test/image/mocks/zz-scatter_fill_gradient_tonexty_toself.json b/test/image/mocks/zz-scatter_fill_gradient_tonexty_toself.json index 530624720cd..c8399861792 100644 --- a/test/image/mocks/zz-scatter_fill_gradient_tonexty_toself.json +++ b/test/image/mocks/zz-scatter_fill_gradient_tonexty_toself.json @@ -8,7 +8,7 @@ "fill": "tonexty", "fillcolor": "rgba(0, 255, 0, .5)", "fillgradient": { - "orientation": "horizontal", + "type": "horizontal", "colorscale": [ [0.0, "rgba(0, 255, 0, 1)"], [0.5, "rgba(0, 255, 0, 0)"], @@ -28,7 +28,7 @@ "fill": "tonexty", "hoveron": "fills+points", "fillgradient": { - "orientation": "horizontal", + "type": "horizontal", "colorscale": [ [0.0, "rgba(255, 255, 0, 1.0)"], [0.6, "rgba(255, 255, 0, 1.0)"], @@ -44,7 +44,7 @@ "mode": "none", "fill": "toself", "fillgradient": { - "orientation": "vertical", + "type": "vertical", "colorscale": [ [0.0, "rgba(255, 0, 0, 0.8)"], [1.0, "rgba(0, 0, 255, 0.9)"] @@ -60,7 +60,7 @@ "mode": "none", "fill": "toself", "fillgradient": { - "orientation": "vertical", + "type": "vertical", "colorscale": [ [0.0, "rgba(255, 0, 0, 0.8)"], [1.0, "rgba(0, 0, 255, 0.9)"] diff --git a/test/plot-schema.json b/test/plot-schema.json index 60e97ea27cc..2cd2ca45f22 100644 --- a/test/plot-schema.json +++ b/test/plot-schema.json @@ -45041,25 +45041,12 @@ }, "fillgradient": { "colorscale": { - "anim": true, "description": "Sets the fill gradient colors as a color scale. The color scale is interpreted as a gradient applied in the direction specified by *orientation*, from the lowest to the highest value of the scatter plot along that axis, or from the center to the most distant point from it, if orientation is *radial*.", "editType": "style", "valType": "colorscale" }, "description": "Sets a fill gradient. If not specified, the fillcolor is used instead.", - "editType": "style", - "orientation": { - "description": "Sets the orientation of the color gradient. Defaults to *none*.", - "dflt": "none", - "editType": "style", - "valType": "enumerated", - "values": [ - "radial", - "horizontal", - "vertical", - "none" - ] - }, + "editType": "calc", "role": "object", "start": { "description": "Sets the gradient start value. It is given as the absolute position on the axis determined by the orientiation. E.g., if orientation is *horizontal*, the gradient will be horizontal and start from the x-position given by start. If omitted, the gradient starts at the lowest value of the trace along the respective axis. Ignored if orientation is *radial*.", @@ -45070,6 +45057,18 @@ "description": "Sets the gradient end value. It is given as the absolute position on the axis determined by the orientiation. E.g., if orientation is *horizontal*, the gradient will be horizontal and end at the x-position given by end. If omitted, the gradient ends at the highest value of the trace along the respective axis. Ignored if orientation is *radial*.", "editType": "calc", "valType": "number" + }, + "type": { + "description": "Sets the type/orientation of the color gradient for the fill. Defaults to *none*.", + "dflt": "none", + "editType": "calc", + "valType": "enumerated", + "values": [ + "radial", + "horizontal", + "vertical", + "none" + ] } }, "fillpattern": { From 34759f311f50fb37c248c3b62fdf4f8823a9bad3 Mon Sep 17 00:00:00 2001 From: Mojtaba Samimi Date: Fri, 1 Mar 2024 14:53:03 -0500 Subject: [PATCH 05/10] makeFillcolorAttr function with hasFillgradient option --- src/traces/scatter/attributes.js | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/src/traces/scatter/attributes.js b/src/traces/scatter/attributes.js index 05ac5146784..4b191da487c 100644 --- a/src/traces/scatter/attributes.js +++ b/src/traces/scatter/attributes.js @@ -13,6 +13,22 @@ var constants = require('./constants'); var extendFlat = require('../../lib/extend').extendFlat; +var makeFillcolorAttr = function(hasFillgradient) { + return { + valType: 'color', + editType: 'style', + anim: true, + description: [ + 'Sets the fill color.', + 'Defaults to a half-transparent variant of the line color,', + 'marker color, or marker line color, whichever is available.', + hasFillgradient ? + 'If fillgradient is specified, fillcolor is ignored except for setting the background color of the hover label, if any.' : + '' + ].join(' ') + }; +} + function axisPeriod(axis) { return { valType: 'any', @@ -391,18 +407,7 @@ module.exports = { 'consecutive, the later ones will be pushed down in the drawing order.' ].join(' ') }, - fillcolor: { - valType: 'color', - editType: 'style', - anim: true, - description: [ - 'Sets the fill color.', - 'Defaults to a half-transparent variant of the line color,', - 'marker color, or marker line color, whichever is available.', - 'If fillgradient is specified, fillcolor is ignored except for', - 'setting the background color of the hover label, if any.' - ].join(' ') - }, + fillcolor: makeFillcolorAttr(true), fillgradient: extendFlat({ type: { valType: 'enumerated', From 9b12d3ef3ca5e58d0dbd8be5be1f567735d94c89 Mon Sep 17 00:00:00 2001 From: Mojtaba Samimi Date: Fri, 1 Mar 2024 14:55:57 -0500 Subject: [PATCH 06/10] move makeFillcolorAttr to a file --- src/traces/scatter/attributes.js | 16 +--------------- src/traces/scatter/fillcolor_attribute.js | 17 +++++++++++++++++ 2 files changed, 18 insertions(+), 15 deletions(-) create mode 100644 src/traces/scatter/fillcolor_attribute.js diff --git a/src/traces/scatter/attributes.js b/src/traces/scatter/attributes.js index 4b191da487c..7241fd5784d 100644 --- a/src/traces/scatter/attributes.js +++ b/src/traces/scatter/attributes.js @@ -13,21 +13,7 @@ var constants = require('./constants'); var extendFlat = require('../../lib/extend').extendFlat; -var makeFillcolorAttr = function(hasFillgradient) { - return { - valType: 'color', - editType: 'style', - anim: true, - description: [ - 'Sets the fill color.', - 'Defaults to a half-transparent variant of the line color,', - 'marker color, or marker line color, whichever is available.', - hasFillgradient ? - 'If fillgradient is specified, fillcolor is ignored except for setting the background color of the hover label, if any.' : - '' - ].join(' ') - }; -} +var makeFillcolorAttr = require('./fillcolor_attribute'); function axisPeriod(axis) { return { diff --git a/src/traces/scatter/fillcolor_attribute.js b/src/traces/scatter/fillcolor_attribute.js new file mode 100644 index 00000000000..826d6dfd356 --- /dev/null +++ b/src/traces/scatter/fillcolor_attribute.js @@ -0,0 +1,17 @@ +'use strict'; + +module.exports = function makeFillcolorAttr(hasFillgradient) { + return { + valType: 'color', + editType: 'style', + anim: true, + description: [ + 'Sets the fill color.', + 'Defaults to a half-transparent variant of the line color,', + 'marker color, or marker line color, whichever is available.', + hasFillgradient ? + 'If fillgradient is specified, fillcolor is ignored except for setting the background color of the hover label, if any.' : + '' + ].join(' ') + }; +}; From 4e5adb837c9aaff39ce8e2ac068a1301869b9b22 Mon Sep 17 00:00:00 2001 From: Mojtaba Samimi Date: Fri, 1 Mar 2024 15:08:46 -0500 Subject: [PATCH 07/10] adjust fillcolor function and use it in traces --- src/traces/box/attributes.js | 3 ++- src/traces/scatter/fillcolor_attribute.js | 9 +++++---- src/traces/scattercarpet/attributes.js | 3 ++- src/traces/scattergeo/attributes.js | 3 ++- src/traces/scattergl/attributes.js | 3 ++- src/traces/scattermapbox/attributes.js | 3 ++- src/traces/scatterpolar/attributes.js | 3 ++- src/traces/scattersmith/attributes.js | 3 ++- src/traces/scatterternary/attributes.js | 3 ++- test/plot-schema.json | 24 +++++++++++------------ 10 files changed, 33 insertions(+), 24 deletions(-) diff --git a/src/traces/box/attributes.js b/src/traces/box/attributes.js index cda4fc672c5..63b0def141a 100644 --- a/src/traces/box/attributes.js +++ b/src/traces/box/attributes.js @@ -1,5 +1,6 @@ 'use strict'; +var makeFillcolorAttr = require('../scatter/fillcolor_attribute'); var scatterAttrs = require('../scatter/attributes'); var barAttrs = require('../bar/attributes'); var colorAttrs = require('../../components/color/attributes'); @@ -386,7 +387,7 @@ module.exports = { editType: 'plot' }, - fillcolor: scatterAttrs.fillcolor, + fillcolor: makeFillcolorAttr(), whiskerwidth: { valType: 'number', diff --git a/src/traces/scatter/fillcolor_attribute.js b/src/traces/scatter/fillcolor_attribute.js index 826d6dfd356..9d79711d9dc 100644 --- a/src/traces/scatter/fillcolor_attribute.js +++ b/src/traces/scatter/fillcolor_attribute.js @@ -8,10 +8,11 @@ module.exports = function makeFillcolorAttr(hasFillgradient) { description: [ 'Sets the fill color.', 'Defaults to a half-transparent variant of the line color,', - 'marker color, or marker line color, whichever is available.', - hasFillgradient ? - 'If fillgradient is specified, fillcolor is ignored except for setting the background color of the hover label, if any.' : - '' + 'marker color, or marker line color, whichever is available.' + ( + hasFillgradient ? + ' If fillgradient is specified, fillcolor is ignored except for setting the background color of the hover label, if any.' : + '' + ) ].join(' ') }; }; diff --git a/src/traces/scattercarpet/attributes.js b/src/traces/scattercarpet/attributes.js index 6022878cc9a..af0e7d406bf 100644 --- a/src/traces/scattercarpet/attributes.js +++ b/src/traces/scattercarpet/attributes.js @@ -1,5 +1,6 @@ 'use strict'; +var makeFillcolorAttr = require('../scatter/fillcolor_attribute'); var scatterAttrs = require('../scatter/attributes'); var baseAttrs = require('../../plots/attributes'); var hovertemplateAttrs = require('../../plots/template_attributes').hovertemplateAttrs; @@ -83,7 +84,7 @@ module.exports = { 'used if one trace does not enclose the other.' ].join(' ') }), - fillcolor: scatterAttrs.fillcolor, + fillcolor: makeFillcolorAttr(), marker: extendFlat({ symbol: scatterMarkerAttrs.symbol, opacity: scatterMarkerAttrs.opacity, diff --git a/src/traces/scattergeo/attributes.js b/src/traces/scattergeo/attributes.js index d80b62c7735..76ccd70e204 100644 --- a/src/traces/scattergeo/attributes.js +++ b/src/traces/scattergeo/attributes.js @@ -2,6 +2,7 @@ var hovertemplateAttrs = require('../../plots/template_attributes').hovertemplateAttrs; var texttemplateAttrs = require('../../plots/template_attributes').texttemplateAttrs; +var makeFillcolorAttr = require('../scatter/fillcolor_attribute'); var scatterAttrs = require('../scatter/attributes'); var baseAttrs = require('../../plots/attributes'); var colorAttributes = require('../../components/colorscale/attributes'); @@ -151,7 +152,7 @@ module.exports = overrideAll({ 'of the trace if it has gaps) into a closed shape.' ].join(' ') }, - fillcolor: scatterAttrs.fillcolor, + fillcolor: makeFillcolorAttr(), selected: scatterAttrs.selected, unselected: scatterAttrs.unselected, diff --git a/src/traces/scattergl/attributes.js b/src/traces/scattergl/attributes.js index f458b27086b..bbfd23e13f2 100644 --- a/src/traces/scattergl/attributes.js +++ b/src/traces/scattergl/attributes.js @@ -1,6 +1,7 @@ 'use strict'; var baseAttrs = require('../../plots/attributes'); +var makeFillcolorAttr = require('../scatter/fillcolor_attribute'); var scatterAttrs = require('../scatter/attributes'); var axisHoverFormat = require('../../plots/cartesian/axis_format_attributes').axisHoverFormat; var colorScaleAttrs = require('../../components/colorscale/attributes'); @@ -80,7 +81,7 @@ var attrs = module.exports = overrideAll({ }), connectgaps: scatterAttrs.connectgaps, fill: extendFlat({}, scatterAttrs.fill, {dflt: 'none'}), - fillcolor: scatterAttrs.fillcolor, + fillcolor: makeFillcolorAttr(), // no hoveron diff --git a/src/traces/scattermapbox/attributes.js b/src/traces/scattermapbox/attributes.js index 3404f2f9c35..7686403e253 100644 --- a/src/traces/scattermapbox/attributes.js +++ b/src/traces/scattermapbox/attributes.js @@ -2,6 +2,7 @@ var hovertemplateAttrs = require('../../plots/template_attributes').hovertemplateAttrs; var texttemplateAttrs = require('../../plots/template_attributes').texttemplateAttrs; +var makeFillcolorAttr = require('../scatter/fillcolor_attribute'); var scatterGeoAttrs = require('../scattergeo/attributes'); var scatterAttrs = require('../scatter/attributes'); var mapboxAttrs = require('../../plots/mapbox/layout_attributes'); @@ -151,7 +152,7 @@ module.exports = overrideAll({ ), fill: scatterGeoAttrs.fill, - fillcolor: scatterAttrs.fillcolor, + fillcolor: makeFillcolorAttr(), textfont: mapboxAttrs.layers.symbol.textfont, textposition: mapboxAttrs.layers.symbol.textposition, diff --git a/src/traces/scatterpolar/attributes.js b/src/traces/scatterpolar/attributes.js index f5d0321c519..34a859df181 100644 --- a/src/traces/scatterpolar/attributes.js +++ b/src/traces/scatterpolar/attributes.js @@ -3,6 +3,7 @@ var hovertemplateAttrs = require('../../plots/template_attributes').hovertemplateAttrs; var texttemplateAttrs = require('../../plots/template_attributes').texttemplateAttrs; var extendFlat = require('../../lib/extend').extendFlat; +var makeFillcolorAttr = require('../scatter/fillcolor_attribute'); var scatterAttrs = require('../scatter/attributes'); var baseAttrs = require('../../plots/attributes'); var lineAttrs = scatterAttrs.line; @@ -112,7 +113,7 @@ module.exports = { 'used if one trace does not enclose the other.' ].join(' ') }), - fillcolor: scatterAttrs.fillcolor, + fillcolor: makeFillcolorAttr(), // TODO error bars // https://stackoverflow.com/a/26597487/4068492 diff --git a/src/traces/scattersmith/attributes.js b/src/traces/scattersmith/attributes.js index 2344a5fc2a5..5a8e931013d 100644 --- a/src/traces/scattersmith/attributes.js +++ b/src/traces/scattersmith/attributes.js @@ -3,6 +3,7 @@ var hovertemplateAttrs = require('../../plots/template_attributes').hovertemplateAttrs; var texttemplateAttrs = require('../../plots/template_attributes').texttemplateAttrs; var extendFlat = require('../../lib/extend').extendFlat; +var makeFillcolorAttr = require('../scatter/fillcolor_attribute'); var scatterAttrs = require('../scatter/attributes'); var baseAttrs = require('../../plots/attributes'); var lineAttrs = scatterAttrs.line; @@ -68,7 +69,7 @@ module.exports = { 'used if one trace does not enclose the other.' ].join(' ') }), - fillcolor: scatterAttrs.fillcolor, + fillcolor: makeFillcolorAttr(), hoverinfo: extendFlat({}, baseAttrs.hoverinfo, { flags: ['real', 'imag', 'text', 'name'] diff --git a/src/traces/scatterternary/attributes.js b/src/traces/scatterternary/attributes.js index 23c0bba0621..67d5baf5feb 100644 --- a/src/traces/scatterternary/attributes.js +++ b/src/traces/scatterternary/attributes.js @@ -2,6 +2,7 @@ var hovertemplateAttrs = require('../../plots/template_attributes').hovertemplateAttrs; var texttemplateAttrs = require('../../plots/template_attributes').texttemplateAttrs; +var makeFillcolorAttr = require('../scatter/fillcolor_attribute'); var scatterAttrs = require('../scatter/attributes'); var baseAttrs = require('../../plots/attributes'); var colorScaleAttrs = require('../../components/colorscale/attributes'); @@ -112,7 +113,7 @@ module.exports = { 'used if one trace does not enclose the other.' ].join(' ') }), - fillcolor: scatterAttrs.fillcolor, + fillcolor: makeFillcolorAttr(), marker: extendFlat({ symbol: scatterMarkerAttrs.symbol, opacity: scatterMarkerAttrs.opacity, diff --git a/test/plot-schema.json b/test/plot-schema.json index 2cd2ca45f22..83da85af60f 100644 --- a/test/plot-schema.json +++ b/test/plot-schema.json @@ -16238,7 +16238,7 @@ "valType": "number" }, "fillcolor": { - "description": "Sets the fill color. Defaults to a half-transparent variant of the line color, marker color, or marker line color, whichever is available. If fillgradient is specified, fillcolor is ignored except for setting the background color of the hover label, if any.", + "description": "Sets the fill color. Defaults to a half-transparent variant of the line color, marker color, or marker line color, whichever is available.", "editType": "style", "valType": "color" }, @@ -17578,7 +17578,7 @@ "decreasing": { "editType": "style", "fillcolor": { - "description": "Sets the fill color. Defaults to a half-transparent variant of the line color, marker color, or marker line color, whichever is available. If fillgradient is specified, fillcolor is ignored except for setting the background color of the hover label, if any.", + "description": "Sets the fill color. Defaults to a half-transparent variant of the line color, marker color, or marker line color, whichever is available.", "editType": "style", "valType": "color" }, @@ -17761,7 +17761,7 @@ "increasing": { "editType": "style", "fillcolor": { - "description": "Sets the fill color. Defaults to a half-transparent variant of the line color, marker color, or marker line color, whichever is available. If fillgradient is specified, fillcolor is ignored except for setting the background color of the hover label, if any.", + "description": "Sets the fill color. Defaults to a half-transparent variant of the line color, marker color, or marker line color, whichever is available.", "editType": "style", "valType": "color" }, @@ -49591,7 +49591,7 @@ ] }, "fillcolor": { - "description": "Sets the fill color. Defaults to a half-transparent variant of the line color, marker color, or marker line color, whichever is available. If fillgradient is specified, fillcolor is ignored except for setting the background color of the hover label, if any.", + "description": "Sets the fill color. Defaults to a half-transparent variant of the line color, marker color, or marker line color, whichever is available.", "editType": "style", "valType": "color" }, @@ -51493,7 +51493,7 @@ ] }, "fillcolor": { - "description": "Sets the fill color. Defaults to a half-transparent variant of the line color, marker color, or marker line color, whichever is available. If fillgradient is specified, fillcolor is ignored except for setting the background color of the hover label, if any.", + "description": "Sets the fill color. Defaults to a half-transparent variant of the line color, marker color, or marker line color, whichever is available.", "editType": "calc", "valType": "color" }, @@ -53596,7 +53596,7 @@ ] }, "fillcolor": { - "description": "Sets the fill color. Defaults to a half-transparent variant of the line color, marker color, or marker line color, whichever is available. If fillgradient is specified, fillcolor is ignored except for setting the background color of the hover label, if any.", + "description": "Sets the fill color. Defaults to a half-transparent variant of the line color, marker color, or marker line color, whichever is available.", "editType": "calc", "valType": "color" }, @@ -55612,7 +55612,7 @@ ] }, "fillcolor": { - "description": "Sets the fill color. Defaults to a half-transparent variant of the line color, marker color, or marker line color, whichever is available. If fillgradient is specified, fillcolor is ignored except for setting the background color of the hover label, if any.", + "description": "Sets the fill color. Defaults to a half-transparent variant of the line color, marker color, or marker line color, whichever is available.", "editType": "calc", "valType": "color" }, @@ -56812,7 +56812,7 @@ ] }, "fillcolor": { - "description": "Sets the fill color. Defaults to a half-transparent variant of the line color, marker color, or marker line color, whichever is available. If fillgradient is specified, fillcolor is ignored except for setting the background color of the hover label, if any.", + "description": "Sets the fill color. Defaults to a half-transparent variant of the line color, marker color, or marker line color, whichever is available.", "editType": "style", "valType": "color" }, @@ -58758,7 +58758,7 @@ ] }, "fillcolor": { - "description": "Sets the fill color. Defaults to a half-transparent variant of the line color, marker color, or marker line color, whichever is available. If fillgradient is specified, fillcolor is ignored except for setting the background color of the hover label, if any.", + "description": "Sets the fill color. Defaults to a half-transparent variant of the line color, marker color, or marker line color, whichever is available.", "editType": "calc", "valType": "color" }, @@ -60594,7 +60594,7 @@ ] }, "fillcolor": { - "description": "Sets the fill color. Defaults to a half-transparent variant of the line color, marker color, or marker line color, whichever is available. If fillgradient is specified, fillcolor is ignored except for setting the background color of the hover label, if any.", + "description": "Sets the fill color. Defaults to a half-transparent variant of the line color, marker color, or marker line color, whichever is available.", "editType": "style", "valType": "color" }, @@ -62538,7 +62538,7 @@ ] }, "fillcolor": { - "description": "Sets the fill color. Defaults to a half-transparent variant of the line color, marker color, or marker line color, whichever is available. If fillgradient is specified, fillcolor is ignored except for setting the background color of the hover label, if any.", + "description": "Sets the fill color. Defaults to a half-transparent variant of the line color, marker color, or marker line color, whichever is available.", "editType": "style", "valType": "color" }, @@ -72246,7 +72246,7 @@ "valType": "string" }, "fillcolor": { - "description": "Sets the fill color. Defaults to a half-transparent variant of the line color, marker color, or marker line color, whichever is available. If fillgradient is specified, fillcolor is ignored except for setting the background color of the hover label, if any.", + "description": "Sets the fill color. Defaults to a half-transparent variant of the line color, marker color, or marker line color, whichever is available.", "editType": "style", "valType": "color" }, From 839326b51267d9b81789d9546ea32d36a1771d34 Mon Sep 17 00:00:00 2001 From: Lukas Prediger Date: Tue, 5 Mar 2024 20:36:21 +0200 Subject: [PATCH 08/10] Removing traceIn.fillgradient check in fillColorDefaults --- src/traces/scatter/fillcolor_defaults.js | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/traces/scatter/fillcolor_defaults.js b/src/traces/scatter/fillcolor_defaults.js index d91b15f0f5d..535e605be2f 100644 --- a/src/traces/scatter/fillcolor_defaults.js +++ b/src/traces/scatter/fillcolor_defaults.js @@ -28,17 +28,18 @@ module.exports = function fillColorDefaults(traceIn, traceOut, defaultColor, coe } var averageGradientColor; - if(traceIn.fillgradient) { + var gradientOrientation = coerce('fillgradient.type'); + if(gradientOrientation !== 'none') { + coerce('fillgradient.start'); + coerce('fillgradient.stop'); + var gradientColorscale = coerce('fillgradient.colorscale'); + // if a fillgradient is specified, we use the average gradient color - // to specifiy fillcolor after all other more specific candidates + // to specify fillcolor after all other more specific candidates // are considered, but before the global default color. // fillcolor affects the background color of the hoverlabel in this case. - var gradientOrientation = coerce('fillgradient.type'); - if(gradientOrientation !== 'none') { - coerce('fillgradient.start'); - coerce('fillgradient.stop'); - coerce('fillgradient.colorscale'); - averageGradientColor = averageColors(traceOut.fillgradient.colorscale); + if(gradientColorscale) { + averageGradientColor = averageColors(gradientColorscale); } } From d9bd3654cc4a2607a2bb077cc52edbe2c307029c Mon Sep 17 00:00:00 2001 From: Lukas Prediger Date: Tue, 5 Mar 2024 20:39:01 +0200 Subject: [PATCH 09/10] draftlog file for scatter fill gradients --- draftlogs/6905_add.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 draftlogs/6905_add.md diff --git a/draftlogs/6905_add.md b/draftlogs/6905_add.md new file mode 100644 index 00000000000..94b10657d5c --- /dev/null +++ b/draftlogs/6905_add.md @@ -0,0 +1 @@ +- Add fill gradients for scatter traces \ No newline at end of file From a2400f16ac2645222aa83cbcb532dbe626ede1d3 Mon Sep 17 00:00:00 2001 From: Mojtaba Samimi Date: Tue, 5 Mar 2024 14:15:54 -0500 Subject: [PATCH 10/10] add moduleHasFillgradient option to fillColorDefaults --- src/traces/scatter/defaults.js | 4 +++- src/traces/scatter/fillcolor_defaults.js | 30 ++++++++++++++---------- 2 files changed, 20 insertions(+), 14 deletions(-) diff --git a/src/traces/scatter/defaults.js b/src/traces/scatter/defaults.js index ce6a5fab07f..31cae6f285c 100644 --- a/src/traces/scatter/defaults.js +++ b/src/traces/scatter/defaults.js @@ -72,7 +72,9 @@ module.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout // We handle that case in some hacky code inside handleStackDefaults. coerce('fill', stackGroupOpts ? stackGroupOpts.fillDflt : 'none'); if(traceOut.fill !== 'none') { - handleFillColorDefaults(traceIn, traceOut, defaultColor, coerce); + handleFillColorDefaults(traceIn, traceOut, defaultColor, coerce, { + moduleHasFillgradient: true + }); if(!subTypes.hasLines(traceOut)) handleLineShapeDefaults(traceIn, traceOut, coerce); coercePattern(coerce, 'fillpattern', traceOut.fillcolor, false); } diff --git a/src/traces/scatter/fillcolor_defaults.js b/src/traces/scatter/fillcolor_defaults.js index 535e605be2f..0822ae8aad6 100644 --- a/src/traces/scatter/fillcolor_defaults.js +++ b/src/traces/scatter/fillcolor_defaults.js @@ -12,7 +12,9 @@ function averageColors(colorscale) { return color; } -module.exports = function fillColorDefaults(traceIn, traceOut, defaultColor, coerce) { +module.exports = function fillColorDefaults(traceIn, traceOut, defaultColor, coerce, opts) { + if(!opts) opts = {}; + var inheritColorFromMarker = false; if(traceOut.marker) { @@ -28,18 +30,20 @@ module.exports = function fillColorDefaults(traceIn, traceOut, defaultColor, coe } var averageGradientColor; - var gradientOrientation = coerce('fillgradient.type'); - if(gradientOrientation !== 'none') { - coerce('fillgradient.start'); - coerce('fillgradient.stop'); - var gradientColorscale = coerce('fillgradient.colorscale'); - - // if a fillgradient is specified, we use the average gradient color - // to specify fillcolor after all other more specific candidates - // are considered, but before the global default color. - // fillcolor affects the background color of the hoverlabel in this case. - if(gradientColorscale) { - averageGradientColor = averageColors(gradientColorscale); + if(opts.moduleHasFillgradient) { + var gradientOrientation = coerce('fillgradient.type'); + if(gradientOrientation !== 'none') { + coerce('fillgradient.start'); + coerce('fillgradient.stop'); + var gradientColorscale = coerce('fillgradient.colorscale'); + + // if a fillgradient is specified, we use the average gradient color + // to specify fillcolor after all other more specific candidates + // are considered, but before the global default color. + // fillcolor affects the background color of the hoverlabel in this case. + if(gradientColorscale) { + averageGradientColor = averageColors(gradientColorscale); + } } }