@@ -12,14 +12,18 @@ var d3 = require('d3');
1212
1313var Plotly = require ( '../../plotly' ) ;
1414var Plots = require ( '../../plots/plots' ) ;
15- var Axes = require ( '../../plots/cartesian/axes' ) ;
15+
1616var Lib = require ( '../../lib' ) ;
17+ var Drawing = require ( '../drawing' ) ;
18+ var Color = require ( '../color' ) ;
19+
20+ var Cartesian = require ( '../../plots/cartesian' ) ;
21+ var Axes = require ( '../../plots/cartesian/axes' ) ;
1722
1823var dragElement = require ( '../dragelement' ) ;
1924var setCursor = require ( '../../lib/setcursor' ) ;
2025
2126var constants = require ( './constants' ) ;
22- var rangePlot = require ( './range_plot' ) ;
2327
2428
2529module . exports = function ( gd ) {
@@ -55,7 +59,14 @@ module.exports = function(gd) {
5559 . classed ( constants . containerClassName , true )
5660 . attr ( 'pointer-events' , 'all' ) ;
5761
58- rangeSliders . exit ( ) . remove ( ) ;
62+ // remove exiting sliders and their corresponding clip paths
63+ rangeSliders . exit ( ) . each ( function ( axisOpts ) {
64+ var rangeSlider = d3 . select ( this ) ,
65+ opts = axisOpts [ constants . name ] ;
66+
67+ rangeSlider . remove ( ) ;
68+ fullLayout . _topdefs . select ( '#' + opts . _clipId ) . remove ( ) ;
69+ } ) ;
5970
6071 // remove push margin object(s)
6172 if ( rangeSliders . exit ( ) . size ( ) ) clearPushMargins ( gd ) ;
@@ -82,6 +93,8 @@ module.exports = function(gd) {
8293 domain = axisOpts . domain ;
8394
8495 opts . _id = constants . name + axisOpts . _id ;
96+ opts . _clipId = opts . _id + '-' + fullLayout . _uid ;
97+
8598 opts . _width = graphSize . w * ( domain [ 1 ] - domain [ 0 ] ) ;
8699 opts . _height = ( fullLayout . height - margin . b - margin . t ) * opts . thickness ;
87100 opts . _offsetShift = Math . floor ( opts . borderwidth / 2 ) ;
@@ -95,6 +108,7 @@ module.exports = function(gd) {
95108
96109 rangeSlider
97110 . call ( drawBg , gd , axisOpts , opts )
111+ . call ( addClipPath , gd , axisOpts , opts )
98112 . call ( drawRangePlot , gd , axisOpts , opts )
99113 . call ( drawMasks , gd , axisOpts , opts )
100114 . call ( drawSlideBox , gd , axisOpts , opts )
@@ -279,17 +293,102 @@ function drawBg(rangeSlider, gd, axisOpts, opts) {
279293 } ) ;
280294}
281295
282- function drawRangePlot ( rangeSlider , gd , axisOpts , opts ) {
283- var rangePlots = rangePlot ( gd , opts . _width , opts . _height ) ;
296+ function addClipPath ( rangeSlider , gd , axisOpts , opts ) {
297+ var fullLayout = gd . _fullLayout ;
284298
285- var gRangePlot = rangeSlider . selectAll ( 'g. ' + constants . rangePlotClassName )
299+ var clipPath = fullLayout . _topdefs . selectAll ( '# ' + opts . _clipId )
286300 . data ( [ 0 ] ) ;
287301
288- gRangePlot . enter ( ) . append ( 'g' )
289- . classed ( constants . rangePlotClassName , true ) ;
302+ clipPath . enter ( ) . append ( 'clipPath' )
303+ . attr ( 'id' , opts . _clipId )
304+ . append ( 'rect' )
305+ . attr ( { x : 0 , y : 0 } ) ;
306+
307+ clipPath . select ( 'rect' ) . attr ( {
308+ width : opts . _width ,
309+ height : opts . _height
310+ } ) ;
311+ }
312+
313+ function drawRangePlot ( rangeSlider , gd , axisOpts , opts ) {
314+ var subplotData = Axes . getSubplots ( gd , axisOpts ) ,
315+ calcData = gd . calcdata ;
316+
317+ var rangePlots = rangeSlider . selectAll ( 'g.' + constants . rangePlotClassName )
318+ . data ( subplotData , Lib . identity ) ;
319+
320+ rangePlots . enter ( ) . append ( 'g' )
321+ . attr ( 'class' , function ( id ) { return constants . rangePlotClassName + ' ' + id ; } )
322+ . call ( Drawing . setClipUrl , opts . _clipId ) ;
323+
324+ rangePlots . order ( ) ;
325+
326+ rangePlots . exit ( ) . remove ( ) ;
327+
328+ var mainplotinfo ;
329+
330+ rangePlots . each ( function ( id , i ) {
331+ var plotgroup = d3 . select ( this ) ,
332+ isMainPlot = ( i === 0 ) ;
333+
334+ var oppAxisOpts = Axes . getFromId ( gd , id , 'y' ) ,
335+ oppAxisName = oppAxisOpts . _name ;
336+
337+ var mockFigure = {
338+ data : [ ] ,
339+ layout : {
340+ xaxis : {
341+ domain : [ 0 , 1 ] ,
342+ range : opts . range . slice ( )
343+ } ,
344+ width : opts . _width ,
345+ height : opts . _height ,
346+ margin : { t : 0 , b : 0 , l : 0 , r : 0 }
347+ }
348+ } ;
349+
350+ mockFigure . layout [ oppAxisName ] = {
351+ domain : [ 0 , 1 ] ,
352+ range : oppAxisOpts . range . slice ( )
353+ } ;
354+
355+ Plots . supplyDefaults ( mockFigure ) ;
356+
357+ var xa = mockFigure . _fullLayout . xaxis ,
358+ ya = mockFigure . _fullLayout [ oppAxisName ] ;
359+
360+ var plotinfo = {
361+ id : id ,
362+ plotgroup : plotgroup ,
363+ xaxis : xa ,
364+ yaxis : ya
365+ } ;
366+
367+ if ( isMainPlot ) mainplotinfo = plotinfo ;
368+ else {
369+ plotinfo . mainplot = 'xy' ;
370+ plotinfo . mainplotinfo = mainplotinfo ;
371+ }
372+
373+ Cartesian . rangePlot ( gd , plotinfo , filterRangePlotCalcData ( calcData , id ) ) ;
374+
375+ if ( isMainPlot ) plotinfo . bg . call ( Color . fill , opts . bgcolor ) ;
376+ } ) ;
377+ }
378+
379+ function filterRangePlotCalcData ( calcData , subplotId ) {
380+ var out = [ ] ;
381+
382+ for ( var i = 0 ; i < calcData . length ; i ++ ) {
383+ var calcTrace = calcData [ i ] ,
384+ trace = calcTrace [ 0 ] . trace ;
385+
386+ if ( trace . xaxis + trace . yaxis === subplotId ) {
387+ out . push ( calcTrace ) ;
388+ }
389+ }
290390
291- gRangePlot . html ( null ) ;
292- gRangePlot . node ( ) . appendChild ( rangePlots ) ;
391+ return out ;
293392}
294393
295394function drawMasks ( rangeSlider , gd , axisOpts , opts ) {
0 commit comments