Skip to content

Commit

Permalink
Refactor activity graphs
Browse files Browse the repository at this point in the history
  • Loading branch information
Liototo committed May 17, 2024
1 parent 2445ffe commit a95e20c
Show file tree
Hide file tree
Showing 3 changed files with 102 additions and 95 deletions.
98 changes: 98 additions & 0 deletions packages/collaboration/src/activitybargraph.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
import { INotebookTracker, Notebook, NotebookPanel } from '@jupyterlab/notebook';
import { User } from '@jupyterlab/services';

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

import { Roles, Role } from './roles';


interface ActivityDisplayComponentProps {

tracker: INotebookTracker;
currentUser: User.IManager;
userRoles: Roles

}

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

const user = currentUser;
const roles = userRoles;

const [state, setState] = React.useState<number[]>([]);

React.useEffect(() => {

const updateCounts = (notebook: Notebook) => {

const counts = notebook.widgets.map(cell => {
let activeUsers = cell.model.getMetadata('active_users');
if (!activeUsers || !Array.isArray(activeUsers)) return 0;
return activeUsers.length;
});

setState(counts);

}

const startTracking = (_: any, panel: NotebookPanel) => {

const notebook = panel.content;

notebook.model?.cells.changed.connect(() => {

updateCounts(notebook);

notebook.widgets.forEach(cell => {
cell.model.metadataChanged.connect(() => {
updateCounts(notebook);
})
})

})

}

tracker.widgetAdded.connect(startTracking);

return () => {
tracker.widgetAdded.disconnect(startTracking);
}

}, [tracker]);

const data = [{
y: state.map((_, index) => index + 1),
x: state,
type: 'bar',
orientation: 'h',
marker: {color: 'green'},
hovertemplate: '%{x} user(s) on cell %{y}<extra></extra>'
}] as Plotly.Data[];

const layout = {
width: 300,
height: 500,
xaxis: {
title: 'Active users'
},
yaxis: {
title: 'Cell',
autorange: 'reversed' as const
},
margin: {
l: 60,
r: 30,
t: 30,
b: 60
}
};

return <div>
{roles.get(user.identity!.username) === Role.Owner && (
<Plot className='jp-graph' data={data} layout={layout}/>
)}
</div>

}
99 changes: 4 additions & 95 deletions packages/collaboration/src/activitydisplay.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { ReactWidget } from '@jupyterlab/apputils';
import { INotebookTracker, Notebook, NotebookPanel } from '@jupyterlab/notebook';
import { INotebookTracker } from '@jupyterlab/notebook';
import { User } from '@jupyterlab/services';

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

import { Roles, Role } from './roles';
import { ActivityBarGraph } from './activitybargraph';
import { Roles } from './roles';


export class ActivityDisplay extends ReactWidget {
Expand All @@ -25,98 +25,7 @@ export class ActivityDisplay extends ReactWidget {
}

render() {
return <ActivityDisplayComponent tracker={this._tracker} currentUser={this._currentUser} userRoles={this._roles}/>
return <ActivityBarGraph tracker={this._tracker} currentUser={this._currentUser} userRoles={this._roles}/>
}

}


interface ActivityDisplayComponentProps {

tracker: INotebookTracker;
currentUser: User.IManager;
userRoles: Roles

}

const ActivityDisplayComponent: React.FC<ActivityDisplayComponentProps> = ({tracker, currentUser, userRoles}) => {

const user = currentUser;
const roles = userRoles;

const [state, setState] = React.useState<number[]>([]);

React.useEffect(() => {

const updateCounts = (notebook: Notebook) => {

const counts = notebook.widgets.map(cell => {
let activeUsers = cell.model.getMetadata('active_users');
if (!activeUsers || !Array.isArray(activeUsers)) return 0;
return activeUsers.length;
});

setState(counts);

}

const startTracking = (_: any, panel: NotebookPanel) => {

const notebook = panel.content;

notebook.model?.cells.changed.connect(() => {

updateCounts(notebook);

notebook.widgets.forEach(cell => {
cell.model.metadataChanged.connect(() => {
updateCounts(notebook);
})
})

})

}

tracker.widgetAdded.connect(startTracking);

return () => {
tracker.widgetAdded.disconnect(startTracking);
}

}, [tracker]);

const data = [{
y: state.map((_, index) => index + 1),
x: state,
type: 'bar',
orientation: 'h',
marker: {color: 'green'},
hovertemplate: '%{x} user(s) on cell %{y}<extra></extra>'
}] as Plotly.Data[];

const layout = {
width: 300,
height: 500,
xaxis: {
title: 'Active users'
},
yaxis: {
title: 'Cell',
autorange: 'reversed' as const
},
margin: {
l: 60,
r: 30,
t: 30,
b: 60
}
};

return <div>
{roles.get(user.identity!.username) === Role.Owner && (
<Plot className='jp-graph' data={data} layout={layout}/>
)}
</div>

}
Empty file.

0 comments on commit a95e20c

Please sign in to comment.