12
12
var d3 = require ( 'd3' ) ;
13
13
14
14
var Plotly = require ( '../../plotly' ) ;
15
+ var Color = require ( '../color' ) ;
16
+ var Drawing = require ( '../drawing' ) ;
17
+ var svgTextUtils = require ( '../../lib/svg_text_utils' ) ;
15
18
var axisIds = require ( '../../plots/cartesian/axis_ids' ) ;
19
+ var anchorUtils = require ( '../legend/anchor_utils' ) ;
16
20
21
+ var constants = require ( './constants' ) ;
17
22
var getUpdateObject = require ( './get_update_object' ) ;
18
23
19
- var width1 = 50 ;
20
- var height1 = 40 ;
21
-
22
24
23
25
module . exports = function draw ( gd ) {
24
26
var fullLayout = gd . _fullLayout ;
25
27
26
28
var selectors = fullLayout . _infolayer . selectAll ( '.rangeselector' )
27
- . data ( makeSelectorData ( gd ) , SelectorKeyFunc ) ;
29
+ . data ( makeSelectorData ( gd ) , selectorKeyFunc ) ;
28
30
29
31
selectors . enter ( ) . append ( 'g' )
30
32
. classed ( 'rangeselector' , true ) ;
@@ -36,8 +38,6 @@ module.exports = function draw(gd) {
36
38
'pointer-events' : 'all'
37
39
} ) ;
38
40
39
- // selector.attr({ 'translate': });
40
-
41
41
selectors . each ( function ( d ) {
42
42
var selector = d3 . select ( this ) ,
43
43
axisLayout = d ,
@@ -51,40 +51,21 @@ module.exports = function draw(gd) {
51
51
52
52
buttons . exit ( ) . remove ( ) ;
53
53
54
- buttons . each ( function ( d , i ) {
54
+ buttons . each ( function ( d ) {
55
55
var button = d3 . select ( this ) ;
56
56
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 ) ;
76
59
77
60
button . on ( 'click' , function ( ) {
78
61
var update = getUpdateObject ( axisLayout , d ) ;
79
62
80
63
Plotly . relayout ( gd , update ) ;
81
64
} ) ;
82
-
83
-
84
65
} ) ;
85
66
67
+ reposition ( buttons , selectorLayout , fullLayout . _size ) ;
86
68
} ) ;
87
-
88
69
} ;
89
70
90
71
function makeSelectorData ( gd ) {
@@ -102,6 +83,95 @@ function makeSelectorData(gd) {
102
83
return data ;
103
84
}
104
85
105
- function SelectorKeyFunc ( d ) {
86
+ function selectorKeyFunc ( d ) {
106
87
return d . _id ;
107
88
}
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