1111
1212var d3 = require ( 'd3' ) ;
1313var isNumeric = require ( 'fast-isnumeric' ) ;
14+ var tinycolor = require ( 'tinycolor2' ) ;
1415
1516var Registry = require ( '../../registry' ) ;
1617var Color = require ( '../color' ) ;
@@ -202,7 +203,7 @@ drawing.symbolNumber = function(v) {
202203 return Math . floor ( Math . max ( v , 0 ) ) ;
203204} ;
204205
205- function singlePointStyle ( d , sel , trace , markerScale , lineScale , marker , markerLine ) {
206+ function singlePointStyle ( d , sel , trace , markerScale , lineScale , marker , markerLine , gd ) {
206207 // only scatter & box plots get marker path and opacity
207208 // bars, histograms don't
208209 if ( Registry . traceIs ( trace , 'symbols' ) ) {
@@ -271,24 +272,83 @@ function singlePointStyle(d, sel, trace, markerScale, lineScale, marker, markerL
271272 } ) ;
272273 }
273274 else {
274- sel . style ( 'stroke-width' , lineWidth + 'px' )
275- . call ( Color . fill , fillColor ) ;
275+ sel . style ( 'stroke-width' , lineWidth + 'px' ) ;
276+
277+ var markerGradient = marker . gradient ;
278+ var gradientColor = markerGradient && ( d . mgc || markerGradient . color ) ;
279+ var gradientType = d . mgt || markerGradient . type ;
280+ if ( gradientType && gradientType !== 'none' ) {
281+ sel . call ( drawing . gradient , gd , gradientType , fillColor , gradientColor ) ;
282+ }
283+ else {
284+ sel . call ( Color . fill , fillColor ) ;
285+ }
286+
276287 if ( lineWidth ) {
277288 sel . call ( Color . stroke , lineColor ) ;
278289 }
279290 }
280291}
281292
282- drawing . singlePointStyle = function ( d , sel , trace ) {
283- var marker = trace . marker ,
284- markerLine = marker . line ;
293+ var HORZGRADIENT = { x1 : 1 , x2 : 0 , y1 : 0 , y2 : 0 } ;
294+ var VERTGRADIENT = { x1 : 0 , x2 : 0 , y1 : 1 , y2 : 0 } ;
285295
286- // allow array marker and marker line colors to be
287- // scaled by given max and min to colorscales
288- var markerScale = drawing . tryColorscale ( marker , '' ) ,
289- lineScale = drawing . tryColorscale ( marker , 'line' ) ;
296+ drawing . gradient = function ( sel , gd , type , color1 , color2 ) {
297+ var fullLayout = gd . _fullLayout ;
298+ var gradientID = (
299+ type + fullLayout . _uid + '-' + color1 + '-' + color2
300+ ) . replace ( / [ ^ \w \- ] + / g, '_' ) ;
301+ var gradient = fullLayout . _defs . select ( '.gradients' ) . selectAll ( '#' + gradientID ) . data ( [ 0 ] ) ;
302+
303+ gradient . enter ( )
304+ . append ( type === 'radial' ? 'radialGradient' : 'linearGradient' )
305+ . each ( function ( ) {
306+ var el = d3 . select ( this ) ;
307+ if ( type === 'horizontal' ) el . attr ( HORZGRADIENT ) ;
308+ else if ( type === 'vertical' ) el . attr ( VERTGRADIENT ) ;
309+
310+ el . attr ( 'id' , gradientID ) ;
311+
312+ var tc1 = tinycolor ( color1 ) ;
313+ var tc2 = tinycolor ( color2 ) ;
314+
315+ el . append ( 'stop' ) . attr ( {
316+ offset : '0%' ,
317+ 'stop-color' : Color . tinyRGB ( tc2 ) ,
318+ 'stop-opacity' : tc2 . getAlpha ( )
319+ } ) ;
320+
321+ el . append ( 'stop' ) . attr ( {
322+ offset : '100%' ,
323+ 'stop-color' : Color . tinyRGB ( tc1 ) ,
324+ 'stop-opacity' : tc1 . getAlpha ( )
325+ } ) ;
326+ } ) ;
327+
328+ sel . style ( {
329+ fill : 'url(#' + gradientID + ')' ,
330+ 'fill-opacity' : null
331+ } ) ;
332+ } ;
333+
334+ /*
335+ * Make the gradients container and clear out any previous gradients.
336+ * We never collect all the gradients we need in one place,
337+ * so we can't ever remove gradients that have stopped being useful,
338+ * except all at once before a full redraw.
339+ * The upside of this is arbitrary points can share gradient defs
340+ */
341+ drawing . initGradients = function ( gd ) {
342+ var gradientsGroup = gd . _fullLayout . _defs . selectAll ( '.gradients' ) . data ( [ 0 ] ) ;
343+ gradientsGroup . enter ( ) . append ( 'g' ) . classed ( 'gradients' , true ) ;
344+
345+ gradientsGroup . selectAll ( 'linearGradient,radialGradient' ) . remove ( ) ;
346+ } ;
347+
348+ drawing . singlePointStyle = function ( d , sel , trace , markerScale , lineScale , gd ) {
349+ var marker = trace . marker ;
290350
291- singlePointStyle ( d , sel , trace , markerScale , lineScale , marker , markerLine ) ;
351+ singlePointStyle ( d , sel , trace , markerScale , lineScale , marker , marker . line , gd ) ;
292352
293353} ;
294354
@@ -298,11 +358,12 @@ drawing.pointStyle = function(s, trace) {
298358 // allow array marker and marker line colors to be
299359 // scaled by given max and min to colorscales
300360 var marker = trace . marker ;
301- var markerScale = drawing . tryColorscale ( marker , '' ) ,
302- lineScale = drawing . tryColorscale ( marker , 'line' ) ;
361+ var markerScale = drawing . tryColorscale ( marker , '' ) ;
362+ var lineScale = drawing . tryColorscale ( marker , 'line' ) ;
363+ var gd = Lib . getPlotDiv ( s . node ( ) ) ;
303364
304365 s . each ( function ( d ) {
305- drawing . singlePointStyle ( d , d3 . select ( this ) , trace , markerScale , lineScale ) ;
366+ drawing . singlePointStyle ( d , d3 . select ( this ) , trace , markerScale , lineScale , gd ) ;
306367 } ) ;
307368} ;
308369
0 commit comments