Skip to content

Commit c75af89

Browse files
committed
Started displaying dot plot
1 parent a95e20c commit c75af89

File tree

4 files changed

+127
-15
lines changed

4 files changed

+127
-15
lines changed

packages/collaboration/src/activitybargraph.tsx

+3-12
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,10 @@
1-
import { INotebookTracker, Notebook, NotebookPanel } from '@jupyterlab/notebook';
2-
import { User } from '@jupyterlab/services';
1+
import { Notebook, NotebookPanel } from '@jupyterlab/notebook';
32

43
import * as React from 'react';
54
import Plot from 'react-plotly.js';
65

7-
import { Roles, Role } from './roles';
8-
9-
10-
interface ActivityDisplayComponentProps {
11-
12-
tracker: INotebookTracker;
13-
currentUser: User.IManager;
14-
userRoles: Roles
15-
16-
}
6+
import { ActivityDisplayComponentProps } from './activitydisplay';
7+
import { Role } from './roles';
178

189
export const ActivityBarGraph: React.FC<ActivityDisplayComponentProps> = ({tracker, currentUser, userRoles}) => {
1910

packages/collaboration/src/activitydisplay.tsx

+10-2
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,17 @@ import { User } from '@jupyterlab/services';
44

55
import * as React from 'react';
66

7-
import { ActivityBarGraph } from './activitybargraph';
7+
// import { ActivityBarGraph } from './activitybargraph';
8+
import { ActivityDotPlot } from './activitydotplot';
89
import { Roles } from './roles';
910

11+
export interface ActivityDisplayComponentProps {
12+
13+
tracker: INotebookTracker;
14+
currentUser: User.IManager;
15+
userRoles: Roles
16+
17+
}
1018

1119
export class ActivityDisplay extends ReactWidget {
1220

@@ -25,7 +33,7 @@ export class ActivityDisplay extends ReactWidget {
2533
}
2634

2735
render() {
28-
return <ActivityBarGraph tracker={this._tracker} currentUser={this._currentUser} userRoles={this._roles}/>
36+
return <ActivityDotPlot tracker={this._tracker} currentUser={this._currentUser} userRoles={this._roles}/>
2937
}
3038

3139
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
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+
}

packages/collaboration/src/cellTracker.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ let notebook: Notebook;
99
let undefinedStuff = 0;
1010
let currentUser: SimpleUser;
1111

12-
interface SimpleUser {
12+
export interface SimpleUser {
1313

1414
id: string,
1515
name: string

0 commit comments

Comments
 (0)