@@ -33,170 +33,6 @@ var computeTickMarks = require('./layout/tick_marks');
3333
3434var STATIC_CANVAS , STATIC_CONTEXT ;
3535
36- function render ( scene ) {
37- var gd = scene . graphDiv ;
38- var trace ;
39-
40- // update size of svg container
41- var svgContainer = scene . svgContainer ;
42- var clientRect = scene . container . getBoundingClientRect ( ) ;
43- var width = clientRect . width ;
44- var height = clientRect . height ;
45- svgContainer . setAttributeNS ( null , 'viewBox' , '0 0 ' + width + ' ' + height ) ;
46- svgContainer . setAttributeNS ( null , 'width' , width ) ;
47- svgContainer . setAttributeNS ( null , 'height' , height ) ;
48-
49- computeTickMarks ( scene ) ;
50- scene . glplot . axes . update ( scene . axesOptions ) ;
51-
52- // check if pick has changed
53- var keys = Object . keys ( scene . traces ) ;
54- var lastPicked = null ;
55- var selection = scene . glplot . selection ;
56- for ( var i = 0 ; i < keys . length ; ++ i ) {
57- trace = scene . traces [ keys [ i ] ] ;
58- if ( trace . data . hoverinfo !== 'skip' && trace . handlePick ( selection ) ) {
59- lastPicked = trace ;
60- }
61-
62- if ( trace . setContourLevels ) trace . setContourLevels ( ) ;
63- }
64-
65- function formatter ( axisName , val ) {
66- var axis = scene . fullSceneLayout [ axisName ] ;
67-
68- return Axes . tickText ( axis , axis . d2l ( val ) , 'hover' ) . text ;
69- }
70-
71- var oldEventData ;
72-
73- if ( lastPicked !== null ) {
74- var pdata = project ( scene . glplot . cameraParams , selection . dataCoordinate ) ;
75- trace = lastPicked . data ;
76- var traceNow = gd . _fullData [ trace . index ] ;
77- var ptNumber = selection . index ;
78-
79- var labels = {
80- xLabel : formatter ( 'xaxis' , selection . traceCoordinate [ 0 ] ) ,
81- yLabel : formatter ( 'yaxis' , selection . traceCoordinate [ 1 ] ) ,
82- zLabel : formatter ( 'zaxis' , selection . traceCoordinate [ 2 ] )
83- } ;
84-
85- var hoverinfo = Fx . castHoverinfo ( traceNow , scene . fullLayout , ptNumber ) ;
86- var hoverinfoParts = ( hoverinfo || '' ) . split ( '+' ) ;
87- var isHoverinfoAll = hoverinfo && hoverinfo === 'all' ;
88-
89- if ( ! traceNow . hovertemplate && ! isHoverinfoAll ) {
90- if ( hoverinfoParts . indexOf ( 'x' ) === - 1 ) labels . xLabel = undefined ;
91- if ( hoverinfoParts . indexOf ( 'y' ) === - 1 ) labels . yLabel = undefined ;
92- if ( hoverinfoParts . indexOf ( 'z' ) === - 1 ) labels . zLabel = undefined ;
93- if ( hoverinfoParts . indexOf ( 'text' ) === - 1 ) selection . textLabel = undefined ;
94- if ( hoverinfoParts . indexOf ( 'name' ) === - 1 ) lastPicked . name = undefined ;
95- }
96-
97- var tx ;
98- var vectorTx = [ ] ;
99-
100- if ( trace . type === 'cone' || trace . type === 'streamtube' ) {
101- labels . uLabel = formatter ( 'xaxis' , selection . traceCoordinate [ 3 ] ) ;
102- if ( isHoverinfoAll || hoverinfoParts . indexOf ( 'u' ) !== - 1 ) {
103- vectorTx . push ( 'u: ' + labels . uLabel ) ;
104- }
105-
106- labels . vLabel = formatter ( 'yaxis' , selection . traceCoordinate [ 4 ] ) ;
107- if ( isHoverinfoAll || hoverinfoParts . indexOf ( 'v' ) !== - 1 ) {
108- vectorTx . push ( 'v: ' + labels . vLabel ) ;
109- }
110-
111- labels . wLabel = formatter ( 'zaxis' , selection . traceCoordinate [ 5 ] ) ;
112- if ( isHoverinfoAll || hoverinfoParts . indexOf ( 'w' ) !== - 1 ) {
113- vectorTx . push ( 'w: ' + labels . wLabel ) ;
114- }
115-
116- labels . normLabel = selection . traceCoordinate [ 6 ] . toPrecision ( 3 ) ;
117- if ( isHoverinfoAll || hoverinfoParts . indexOf ( 'norm' ) !== - 1 ) {
118- vectorTx . push ( 'norm: ' + labels . normLabel ) ;
119- }
120- if ( trace . type === 'streamtube' ) {
121- labels . divergenceLabel = selection . traceCoordinate [ 7 ] . toPrecision ( 3 ) ;
122- if ( isHoverinfoAll || hoverinfoParts . indexOf ( 'divergence' ) !== - 1 ) {
123- vectorTx . push ( 'divergence: ' + labels . divergenceLabel ) ;
124- }
125- }
126- if ( selection . textLabel ) {
127- vectorTx . push ( selection . textLabel ) ;
128- }
129- tx = vectorTx . join ( '<br>' ) ;
130- } else if ( trace . type === 'isosurface' || trace . type === 'volume' ) {
131- labels . valueLabel = Axes . tickText ( scene . _mockAxis , scene . _mockAxis . d2l ( selection . traceCoordinate [ 3 ] ) , 'hover' ) . text ;
132- vectorTx . push ( 'value: ' + labels . valueLabel ) ;
133- if ( selection . textLabel ) {
134- vectorTx . push ( selection . textLabel ) ;
135- }
136- tx = vectorTx . join ( '<br>' ) ;
137- } else {
138- tx = selection . textLabel ;
139- }
140-
141- var pointData = {
142- x : selection . traceCoordinate [ 0 ] ,
143- y : selection . traceCoordinate [ 1 ] ,
144- z : selection . traceCoordinate [ 2 ] ,
145- data : traceNow . _input ,
146- fullData : traceNow ,
147- curveNumber : traceNow . index ,
148- pointNumber : ptNumber
149- } ;
150-
151- Fx . appendArrayPointValue ( pointData , traceNow , ptNumber ) ;
152-
153- if ( trace . _module . eventData ) {
154- pointData = traceNow . _module . eventData ( pointData , selection , traceNow , { } , ptNumber ) ;
155- }
156-
157- var eventData = { points : [ pointData ] } ;
158-
159- if ( scene . fullSceneLayout . hovermode ) {
160- Fx . loneHover ( {
161- trace : traceNow ,
162- x : ( 0.5 + 0.5 * pdata [ 0 ] / pdata [ 3 ] ) * width ,
163- y : ( 0.5 - 0.5 * pdata [ 1 ] / pdata [ 3 ] ) * height ,
164- xLabel : labels . xLabel ,
165- yLabel : labels . yLabel ,
166- zLabel : labels . zLabel ,
167- text : tx ,
168- name : lastPicked . name ,
169- color : Fx . castHoverOption ( traceNow , ptNumber , 'bgcolor' ) || lastPicked . color ,
170- borderColor : Fx . castHoverOption ( traceNow , ptNumber , 'bordercolor' ) ,
171- fontFamily : Fx . castHoverOption ( traceNow , ptNumber , 'font.family' ) ,
172- fontSize : Fx . castHoverOption ( traceNow , ptNumber , 'font.size' ) ,
173- fontColor : Fx . castHoverOption ( traceNow , ptNumber , 'font.color' ) ,
174- nameLength : Fx . castHoverOption ( traceNow , ptNumber , 'namelength' ) ,
175- textAlign : Fx . castHoverOption ( traceNow , ptNumber , 'align' ) ,
176- hovertemplate : Lib . castOption ( traceNow , ptNumber , 'hovertemplate' ) ,
177- hovertemplateLabels : Lib . extendFlat ( { } , pointData , labels ) ,
178- eventData : [ pointData ]
179- } , {
180- container : svgContainer ,
181- gd : gd
182- } ) ;
183- }
184-
185- if ( selection . buttons && selection . distance < 5 ) {
186- gd . emit ( 'plotly_click' , eventData ) ;
187- } else {
188- gd . emit ( 'plotly_hover' , eventData ) ;
189- }
190-
191- oldEventData = eventData ;
192- } else {
193- Fx . loneUnhover ( svgContainer ) ;
194- gd . emit ( 'plotly_unhover' , oldEventData ) ;
195- }
196-
197- scene . drawAnnotations ( scene ) ;
198- }
199-
20036function Scene ( options , fullLayout ) {
20137 // create sub container for plot
20238 var sceneContainer = document . createElement ( 'div' ) ;
@@ -335,6 +171,11 @@ proto.initializeGLPlot = function() {
335171 */
336172 if ( ! success ) return showNoWebGlMsg ( scene ) ;
337173
174+ // List of scene objects
175+ scene . traces = { } ;
176+
177+ scene . make4thDimension ( ) ;
178+
338179 var gd = scene . graphDiv ;
339180 var layout = gd . layout ;
340181
@@ -405,14 +246,176 @@ proto.initializeGLPlot = function() {
405246 scene . recoverContext ( ) ;
406247 } ;
407248
408- scene . glplot . onrender = render . bind ( null , scene ) ;
249+ scene . glplot . onrender = function ( ) {
250+ scene . render ( ) ;
251+ } ;
409252
410- // List of scene objects
411- scene . traces = { } ;
253+ return true ;
254+ } ;
412255
413- scene . make4thDimension ( ) ;
256+ proto . render = function ( ) {
257+ var scene = this ;
258+ var gd = scene . graphDiv ;
259+ var trace ;
414260
415- return true ;
261+ // update size of svg container
262+ var svgContainer = scene . svgContainer ;
263+ var clientRect = scene . container . getBoundingClientRect ( ) ;
264+ var width = clientRect . width ;
265+ var height = clientRect . height ;
266+ svgContainer . setAttributeNS ( null , 'viewBox' , '0 0 ' + width + ' ' + height ) ;
267+ svgContainer . setAttributeNS ( null , 'width' , width ) ;
268+ svgContainer . setAttributeNS ( null , 'height' , height ) ;
269+
270+ computeTickMarks ( scene ) ;
271+ scene . glplot . axes . update ( scene . axesOptions ) ;
272+
273+ // check if pick has changed
274+ var keys = Object . keys ( scene . traces ) ;
275+ var lastPicked = null ;
276+ var selection = scene . glplot . selection ;
277+ for ( var i = 0 ; i < keys . length ; ++ i ) {
278+ trace = scene . traces [ keys [ i ] ] ;
279+ if ( trace . data . hoverinfo !== 'skip' && trace . handlePick ( selection ) ) {
280+ lastPicked = trace ;
281+ }
282+
283+ if ( trace . setContourLevels ) trace . setContourLevels ( ) ;
284+ }
285+
286+ function formatter ( axisName , val ) {
287+ var axis = scene . fullSceneLayout [ axisName ] ;
288+
289+ return Axes . tickText ( axis , axis . d2l ( val ) , 'hover' ) . text ;
290+ }
291+
292+ var oldEventData ;
293+
294+ if ( lastPicked !== null ) {
295+ var pdata = project ( scene . glplot . cameraParams , selection . dataCoordinate ) ;
296+ trace = lastPicked . data ;
297+ var traceNow = gd . _fullData [ trace . index ] ;
298+ var ptNumber = selection . index ;
299+
300+ var labels = {
301+ xLabel : formatter ( 'xaxis' , selection . traceCoordinate [ 0 ] ) ,
302+ yLabel : formatter ( 'yaxis' , selection . traceCoordinate [ 1 ] ) ,
303+ zLabel : formatter ( 'zaxis' , selection . traceCoordinate [ 2 ] )
304+ } ;
305+
306+ var hoverinfo = Fx . castHoverinfo ( traceNow , scene . fullLayout , ptNumber ) ;
307+ var hoverinfoParts = ( hoverinfo || '' ) . split ( '+' ) ;
308+ var isHoverinfoAll = hoverinfo && hoverinfo === 'all' ;
309+
310+ if ( ! traceNow . hovertemplate && ! isHoverinfoAll ) {
311+ if ( hoverinfoParts . indexOf ( 'x' ) === - 1 ) labels . xLabel = undefined ;
312+ if ( hoverinfoParts . indexOf ( 'y' ) === - 1 ) labels . yLabel = undefined ;
313+ if ( hoverinfoParts . indexOf ( 'z' ) === - 1 ) labels . zLabel = undefined ;
314+ if ( hoverinfoParts . indexOf ( 'text' ) === - 1 ) selection . textLabel = undefined ;
315+ if ( hoverinfoParts . indexOf ( 'name' ) === - 1 ) lastPicked . name = undefined ;
316+ }
317+
318+ var tx ;
319+ var vectorTx = [ ] ;
320+
321+ if ( trace . type === 'cone' || trace . type === 'streamtube' ) {
322+ labels . uLabel = formatter ( 'xaxis' , selection . traceCoordinate [ 3 ] ) ;
323+ if ( isHoverinfoAll || hoverinfoParts . indexOf ( 'u' ) !== - 1 ) {
324+ vectorTx . push ( 'u: ' + labels . uLabel ) ;
325+ }
326+
327+ labels . vLabel = formatter ( 'yaxis' , selection . traceCoordinate [ 4 ] ) ;
328+ if ( isHoverinfoAll || hoverinfoParts . indexOf ( 'v' ) !== - 1 ) {
329+ vectorTx . push ( 'v: ' + labels . vLabel ) ;
330+ }
331+
332+ labels . wLabel = formatter ( 'zaxis' , selection . traceCoordinate [ 5 ] ) ;
333+ if ( isHoverinfoAll || hoverinfoParts . indexOf ( 'w' ) !== - 1 ) {
334+ vectorTx . push ( 'w: ' + labels . wLabel ) ;
335+ }
336+
337+ labels . normLabel = selection . traceCoordinate [ 6 ] . toPrecision ( 3 ) ;
338+ if ( isHoverinfoAll || hoverinfoParts . indexOf ( 'norm' ) !== - 1 ) {
339+ vectorTx . push ( 'norm: ' + labels . normLabel ) ;
340+ }
341+ if ( trace . type === 'streamtube' ) {
342+ labels . divergenceLabel = selection . traceCoordinate [ 7 ] . toPrecision ( 3 ) ;
343+ if ( isHoverinfoAll || hoverinfoParts . indexOf ( 'divergence' ) !== - 1 ) {
344+ vectorTx . push ( 'divergence: ' + labels . divergenceLabel ) ;
345+ }
346+ }
347+ if ( selection . textLabel ) {
348+ vectorTx . push ( selection . textLabel ) ;
349+ }
350+ tx = vectorTx . join ( '<br>' ) ;
351+ } else if ( trace . type === 'isosurface' || trace . type === 'volume' ) {
352+ labels . valueLabel = Axes . tickText ( scene . _mockAxis , scene . _mockAxis . d2l ( selection . traceCoordinate [ 3 ] ) , 'hover' ) . text ;
353+ vectorTx . push ( 'value: ' + labels . valueLabel ) ;
354+ if ( selection . textLabel ) {
355+ vectorTx . push ( selection . textLabel ) ;
356+ }
357+ tx = vectorTx . join ( '<br>' ) ;
358+ } else {
359+ tx = selection . textLabel ;
360+ }
361+
362+ var pointData = {
363+ x : selection . traceCoordinate [ 0 ] ,
364+ y : selection . traceCoordinate [ 1 ] ,
365+ z : selection . traceCoordinate [ 2 ] ,
366+ data : traceNow . _input ,
367+ fullData : traceNow ,
368+ curveNumber : traceNow . index ,
369+ pointNumber : ptNumber
370+ } ;
371+
372+ Fx . appendArrayPointValue ( pointData , traceNow , ptNumber ) ;
373+
374+ if ( trace . _module . eventData ) {
375+ pointData = traceNow . _module . eventData ( pointData , selection , traceNow , { } , ptNumber ) ;
376+ }
377+
378+ var eventData = { points : [ pointData ] } ;
379+
380+ if ( scene . fullSceneLayout . hovermode ) {
381+ Fx . loneHover ( {
382+ trace : traceNow ,
383+ x : ( 0.5 + 0.5 * pdata [ 0 ] / pdata [ 3 ] ) * width ,
384+ y : ( 0.5 - 0.5 * pdata [ 1 ] / pdata [ 3 ] ) * height ,
385+ xLabel : labels . xLabel ,
386+ yLabel : labels . yLabel ,
387+ zLabel : labels . zLabel ,
388+ text : tx ,
389+ name : lastPicked . name ,
390+ color : Fx . castHoverOption ( traceNow , ptNumber , 'bgcolor' ) || lastPicked . color ,
391+ borderColor : Fx . castHoverOption ( traceNow , ptNumber , 'bordercolor' ) ,
392+ fontFamily : Fx . castHoverOption ( traceNow , ptNumber , 'font.family' ) ,
393+ fontSize : Fx . castHoverOption ( traceNow , ptNumber , 'font.size' ) ,
394+ fontColor : Fx . castHoverOption ( traceNow , ptNumber , 'font.color' ) ,
395+ nameLength : Fx . castHoverOption ( traceNow , ptNumber , 'namelength' ) ,
396+ textAlign : Fx . castHoverOption ( traceNow , ptNumber , 'align' ) ,
397+ hovertemplate : Lib . castOption ( traceNow , ptNumber , 'hovertemplate' ) ,
398+ hovertemplateLabels : Lib . extendFlat ( { } , pointData , labels ) ,
399+ eventData : [ pointData ]
400+ } , {
401+ container : svgContainer ,
402+ gd : gd
403+ } ) ;
404+ }
405+
406+ if ( selection . buttons && selection . distance < 5 ) {
407+ gd . emit ( 'plotly_click' , eventData ) ;
408+ } else {
409+ gd . emit ( 'plotly_hover' , eventData ) ;
410+ }
411+
412+ oldEventData = eventData ;
413+ } else {
414+ Fx . loneUnhover ( svgContainer ) ;
415+ gd . emit ( 'plotly_unhover' , oldEventData ) ;
416+ }
417+
418+ scene . drawAnnotations ( scene ) ;
416419} ;
417420
418421proto . recoverContext = function ( ) {
0 commit comments