1
+ import { Notebook , NotebookPanel } from '@jupyterlab/notebook' ;
2
+
3
+ import * as React from 'react' ;
4
+ import Plot from 'react-plotly.js' ;
5
+
6
+ import { ActivityDisplayComponentProps } from './activitydisplay' ;
7
+ import { SimpleUser } from './cellTracker' ;
8
+ import { Role } from './roles' ;
9
+
10
+ export const ActivityDotPlot : React . FC < ActivityDisplayComponentProps > = ( { tracker, currentUser, userRoles} ) => {
11
+
12
+ const user = currentUser ;
13
+ const roles = userRoles ;
14
+
15
+ const [ state , setState ] = React . useState < SimpleUser [ ] [ ] > ( [ ] ) ;
16
+
17
+ React . useEffect ( ( ) => {
18
+
19
+ const updateCounts = ( notebook : Notebook ) => {
20
+
21
+ const counts = notebook . widgets . map ( cell => {
22
+ return cell . model . getMetadata ( 'active_users' ) || [ ] ;
23
+ } ) ;
24
+
25
+ setState ( counts ) ;
26
+
27
+ }
28
+
29
+ const startTracking = ( _ : any , panel : NotebookPanel ) => {
30
+
31
+ const notebook = panel . content ;
32
+
33
+ notebook . model ?. cells . changed . connect ( ( ) => {
34
+
35
+ updateCounts ( notebook ) ;
36
+
37
+ notebook . widgets . forEach ( cell => {
38
+ cell . model . metadataChanged . connect ( ( ) => {
39
+ updateCounts ( notebook ) ;
40
+ } )
41
+ } )
42
+
43
+ } )
44
+
45
+ }
46
+
47
+ tracker . widgetAdded . connect ( startTracking ) ;
48
+
49
+ return ( ) => {
50
+ tracker . widgetAdded . disconnect ( startTracking ) ;
51
+ }
52
+
53
+ } , [ tracker ] ) ;
54
+
55
+ const xValues : number [ ] = [ ] ;
56
+ const yValues : number [ ] = [ ] ;
57
+ const hoverText : string [ ] = [ ] ;
58
+
59
+ state . forEach ( ( userArray , cellIndex ) => {
60
+
61
+ userArray . forEach ( ( user , userIndex ) => {
62
+ yValues . push ( - cellIndex ) ;
63
+ xValues . push ( userIndex + 1 ) ;
64
+ hoverText . push ( `${ user . name } on cell ${ cellIndex } ` ) ;
65
+ } ) ;
66
+
67
+ } ) ;
68
+
69
+ const maxCellIndex = state . length > 0 ? state . length - 1 : 0
70
+ const tickvals = Array . from ( Array ( maxCellIndex + 1 ) . keys ( ) ) . map ( index => - index ) ;
71
+ const ticktext = Array . from ( Array ( maxCellIndex + 1 ) . keys ( ) ) . map ( index => index . toString ( ) ) ;
72
+
73
+
74
+ const data = [ {
75
+ y : yValues ,
76
+ x : xValues ,
77
+ type : 'scatter' ,
78
+ mode : 'markers' ,
79
+ orientation : 'h' ,
80
+ marker : { color : 'green' } ,
81
+ hoverinfo : 'text' ,
82
+ text : hoverText
83
+ } ] as Plotly . Data [ ] ;
84
+
85
+ const layout = {
86
+ width : 300 ,
87
+ height : 500 ,
88
+ xaxis : {
89
+ title : 'Active users' ,
90
+ range : [ 1 , Math . max ( ...xValues ) + 1 ]
91
+ } ,
92
+ yaxis : {
93
+ title : 'Cell' ,
94
+ autorange : false ,
95
+ range : [ - maxCellIndex , 0 ] ,
96
+ tickvals : tickvals ,
97
+ ticktext : ticktext
98
+ } ,
99
+ margin : {
100
+ l : 60 ,
101
+ r : 30 ,
102
+ t : 30 ,
103
+ b : 60
104
+ }
105
+ } ;
106
+
107
+ return < div >
108
+ { roles . get ( user . identity ! . username ) === Role . Owner && (
109
+ < Plot className = 'jp-graph' data = { data } layout = { layout } />
110
+ ) }
111
+ </ div >
112
+
113
+ }
0 commit comments