1212var d3 = require ( 'd3' ) ;
1313
1414var Plotly = require ( '../../plotly' ) ;
15+ var Color = require ( '../color' ) ;
16+ var Drawing = require ( '../drawing' ) ;
17+ var svgTextUtils = require ( '../../lib/svg_text_utils' ) ;
1518var axisIds = require ( '../../plots/cartesian/axis_ids' ) ;
19+ var anchorUtils = require ( '../legend/anchor_utils' ) ;
1620
21+ var constants = require ( './constants' ) ;
1722var getUpdateObject = require ( './get_update_object' ) ;
1823
19- var width1 = 50 ;
20- var height1 = 40 ;
21-
2224
2325module . exports = function draw ( gd ) {
2426 var fullLayout = gd . _fullLayout ;
2527
2628 var selectors = fullLayout . _infolayer . selectAll ( '.rangeselector' )
27- . data ( makeSelectorData ( gd ) , SelectorKeyFunc ) ;
29+ . data ( makeSelectorData ( gd ) , selectorKeyFunc ) ;
2830
2931 selectors . enter ( ) . append ( 'g' )
3032 . classed ( 'rangeselector' , true ) ;
@@ -36,8 +38,6 @@ module.exports = function draw(gd) {
3638 'pointer-events' : 'all'
3739 } ) ;
3840
39- // selector.attr({ 'translate': });
40-
4141 selectors . each ( function ( d ) {
4242 var selector = d3 . select ( this ) ,
4343 axisLayout = d ,
@@ -51,40 +51,21 @@ module.exports = function draw(gd) {
5151
5252 buttons . exit ( ) . remove ( ) ;
5353
54- buttons . each ( function ( d , i ) {
54+ buttons . each ( function ( d ) {
5555 var button = d3 . select ( this ) ;
5656
57- button . append ( 'rect' )
58- . attr ( {
59- x : width1 * ( 0.5 + i ) ,
60- width : width1 ,
61- height : height1
62- } )
63- . style ( {
64- fill : 'none' ,
65- stroke : '#000' ,
66- 'stroke-width' : 2
67- } ) ;
68-
69- button . append ( 'text' )
70- . attr ( {
71- x : width1 * ( 1 + i ) ,
72- y : height1 / 2 ,
73- 'text-anchor' : 'middle'
74- } )
75- . text ( d . label || d . count + ' ' + d . step . charAt ( 0 ) ) ;
57+ button . call ( drawButtonRect , selectorLayout , d ) ;
58+ button . call ( drawButtonText , selectorLayout , d ) ;
7659
7760 button . on ( 'click' , function ( ) {
7861 var update = getUpdateObject ( axisLayout , d ) ;
7962
8063 Plotly . relayout ( gd , update ) ;
8164 } ) ;
82-
83-
8465 } ) ;
8566
67+ reposition ( buttons , selectorLayout , fullLayout . _size ) ;
8668 } ) ;
87-
8869} ;
8970
9071function makeSelectorData ( gd ) {
@@ -102,6 +83,95 @@ function makeSelectorData(gd) {
10283 return data ;
10384}
10485
105- function SelectorKeyFunc ( d ) {
86+ function selectorKeyFunc ( d ) {
10687 return d . _id ;
10788}
89+
90+ function drawButtonRect ( button , selectorLayout ) {
91+ var rect = button . selectAll ( 'rect' )
92+ . data ( [ 0 ] ) ;
93+
94+ rect . enter ( ) . append ( 'rect' )
95+ . classed ( 'selector-rect' , true ) ;
96+
97+ rect . attr ( 'shape-rendering' , 'crispEdges' ) ;
98+
99+ rect . call ( Color . stroke , selectorLayout . bordercolor )
100+ . call ( Color . fill , selectorLayout . bgcolor )
101+ . style ( 'stroke-width' , selectorLayout . borderwidth + 'px' ) ;
102+ }
103+
104+ function drawButtonText ( button , selectorLayout , d ) {
105+ function textLayout ( s ) {
106+ svgTextUtils . convertToTspans ( s , function ( ) {
107+ // TODO do we need this???
108+ // if(gd.firstRender) repositionLegend(gd, traces);
109+ } ) ;
110+ }
111+
112+ var text = button . selectAll ( 'text' )
113+ . data ( [ 0 ] ) ;
114+
115+ text . enter ( ) . append ( 'text' )
116+ . classed ( 'selector-text' , true )
117+ . classed ( 'user-select-none' , true ) ;
118+
119+ // TODO is this correct?
120+ text . attr ( 'text-anchor' , 'middle' ) ;
121+
122+ text . call ( Drawing . font , selectorLayout . font )
123+ . text ( d . label || d . count + ' ' + d . step . charAt ( 0 ) )
124+ . call ( textLayout ) ;
125+ }
126+
127+ function reposition ( buttons , opts , graphSize ) {
128+ opts . width = 0 ;
129+ opts . height = 0 ;
130+
131+ var borderWidth = opts . borderwidth ;
132+
133+ buttons . each ( function ( d ) {
134+ var button = d3 . select ( this ) ,
135+ rect = button . select ( '.selector-rect' ) ,
136+ text = button . select ( '.selector-text' ) ,
137+ tspans = text . selectAll ( 'tspan' ) ,
138+ mathJaxGroup = button . select ( 'g[class*=math-group]' ) ;
139+
140+ var tWidth = text . node ( ) && Drawing . bBox ( text . node ( ) ) . width ,
141+ tHeight = opts . font . size * 1.3 ,
142+ tLines = tspans [ 0 ] . length || 1 ;
143+
144+ var wEff = Math . min ( tWidth + 10 , 50 ) ,
145+ hEff = Math . max ( tHeight * tLines , 16 ) + 3 ;
146+
147+ // TODO add buttongap attribute
148+
149+ button . attr ( 'transform' , 'translate(' +
150+ ( borderWidth + opts . width ) + ',' + borderWidth +
151+ ')' ) ;
152+
153+ rect . attr ( {
154+ x : 0 ,
155+ y : 0 ,
156+ width : wEff
157+ } ) ;
158+
159+ var textAttr = {
160+ x : wEff / 2 ,
161+ y : tHeight * ( 1.5 - tLines / 2 ) // could do better
162+ } ;
163+
164+ text . attr ( textAttr ) ;
165+ tspans . attr ( textAttr ) ;
166+
167+ opts . width += wEff + 5 ;
168+ opts . height = Math . max ( opts . height , hEff ) ;
169+
170+ console . log ( [ wEff , opts . width ] , [ hEff , opts . height ] ) ;
171+ } ) ;
172+
173+ buttons . selectAll ( 'rect' ) . attr ( 'height' , opts . height ) ;
174+
175+
176+
177+ }
0 commit comments