@@ -6,15 +6,33 @@ import TooltipMixin from "../mixins/tooltip";
6
6
var BarChart = React . createClass ( {
7
7
mixins : [
8
8
TooltipMixin ( function ( ) {
9
+ var barChartInstance = this ;
9
10
return {
10
11
html : true ,
11
12
placement : this . props . placement ,
12
13
selector : ".tip" ,
13
- viewport : this . props . viewport
14
+ viewport : this . props . viewport ,
15
+
16
+ // This callback is fired when the user hovers over the
17
+ // barchart / triggers tooltip rendering. This is better
18
+ // than using data-title, which renders up-front for each
19
+ // BarChart (slow).
20
+ title : function ( instance ) {
21
+ // `this` is the targeted element
22
+ let pointIdx = this . getAttribute ( 'data-point-index' ) ;
23
+ return barChartInstance . renderTooltip ( pointIdx ) ;
24
+ }
14
25
} ;
15
26
} )
16
27
] ,
17
28
29
+
30
+ statics : {
31
+ getInterval ( points ) {
32
+ return points . length > 1 ? points [ 1 ] . x - points [ 0 ] . x : null ;
33
+ }
34
+ } ,
35
+
18
36
propTypes : {
19
37
points : React . PropTypes . arrayOf ( React . PropTypes . shape ( {
20
38
x : React . PropTypes . number . isRequired ,
@@ -42,6 +60,20 @@ var BarChart = React.createClass({
42
60
} ;
43
61
} ,
44
62
63
+ getInitialState ( ) {
64
+ return {
65
+ interval : BarChart . getInterval ( this . props . points )
66
+ } ;
67
+ } ,
68
+
69
+ componentWillReceiveProps ( nextProps ) {
70
+ if ( nextProps . points ) {
71
+ this . setState ( {
72
+ interval : BarChart . getInterval ( nextProps . points )
73
+ } ) ;
74
+ }
75
+ } ,
76
+
45
77
shouldComponentUpdate ( nextProps , nextState ) {
46
78
return ! valueIsEqual ( this . props , nextProps , true ) ;
47
79
} ,
@@ -91,6 +123,19 @@ var BarChart = React.createClass({
91
123
return timeMoment . format ( "lll" ) ;
92
124
} ,
93
125
126
+ getTimeLabel ( point ) {
127
+ switch ( this . state . interval ) {
128
+ case 3600 :
129
+ return this . timeLabelAsHour ( point ) ;
130
+ case 86400 :
131
+ return this . timeLabelAsDay ( point ) ;
132
+ case null :
133
+ return this . timeLabelAsFull ( point ) ;
134
+ default :
135
+ return this . timeLabelAsRange ( this . state . interval , point ) ;
136
+ }
137
+ } ,
138
+
94
139
maxPointValue ( ) {
95
140
var maxval = 10 ;
96
141
this . props . points . forEach ( ( point ) => {
@@ -121,10 +166,10 @@ var BarChart = React.createClass({
121
166
) ;
122
167
} ,
123
168
124
- renderChartColumn ( point , maxval , timeLabelFunc , pointWidth ) {
125
- var pct = this . floatFormat ( point . y / maxval * 99 , 2 ) + "%" ;
126
- var timeLabel = timeLabelFunc ( point ) ;
127
- var title = (
169
+ renderTooltip ( pointIdx ) {
170
+ let point = this . props . points [ pointIdx ] ;
171
+ let timeLabel = this . getTimeLabel ( point ) ;
172
+ let title = (
128
173
'<div style="width:130px">' +
129
174
point . y + ' ' + this . props . label + '<br/>' +
130
175
timeLabel +
@@ -133,9 +178,19 @@ var BarChart = React.createClass({
133
178
if ( point . label ) {
134
179
title += '<div>(' + point . label + ')</div>' ;
135
180
}
181
+ return title ;
182
+ } ,
183
+
184
+ renderChartColumn ( pointIdx , maxval , pointWidth ) {
185
+ let point = this . props . points [ pointIdx ] ;
186
+ let pct = this . floatFormat ( point . y / maxval * 99 , 2 ) + "%" ;
136
187
137
188
return (
138
- < a key = { point . x } className = "chart-column tip" data-title = { title } style = { { width : pointWidth } } >
189
+ < a key = { point . x }
190
+ className = "chart-column tip"
191
+ data-point-index = { pointIdx }
192
+ style = { { width : pointWidth } }
193
+ >
139
194
< span style = { { height : pct } } > { point . y } </ span >
140
195
</ a >
141
196
) ;
@@ -145,22 +200,6 @@ var BarChart = React.createClass({
145
200
var points = this . props . points ;
146
201
var pointWidth = this . floatFormat ( 100.0 / points . length , 2 ) + "%" ;
147
202
148
- var interval = ( points . length > 1 ? points [ 1 ] . x - points [ 0 ] . x : null ) ;
149
- var timeLabelFunc ;
150
- switch ( interval ) {
151
- case 3600 :
152
- timeLabelFunc = this . timeLabelAsHour ;
153
- break ;
154
- case 86400 :
155
- timeLabelFunc = this . timeLabelAsDay ;
156
- break ;
157
- case null :
158
- timeLabelFunc = this . timeLabelAsFull ;
159
- break ;
160
- default :
161
- timeLabelFunc = this . timeLabelAsRange . bind ( this , interval ) ;
162
- }
163
-
164
203
var maxval = this . maxPointValue ( ) ;
165
204
166
205
var markers = this . props . markers . slice ( ) ;
@@ -171,7 +210,7 @@ var BarChart = React.createClass({
171
210
children . push ( this . renderMarker ( markers . shift ( ) ) ) ;
172
211
}
173
212
174
- children . push ( this . renderChartColumn ( point , maxval , timeLabelFunc , pointWidth ) ) ;
213
+ children . push ( this . renderChartColumn ( pointIdx , maxval , pointWidth ) ) ;
175
214
} ) ;
176
215
177
216
// in bizarre case where markers never got rendered, render them last
0 commit comments