Skip to content

Commit cf40fa9

Browse files
Add scatter plot of user comment length vs. lines of code
1 parent 8834995 commit cf40fa9

File tree

4 files changed

+105
-3
lines changed

4 files changed

+105
-3
lines changed

components/RepositoryAnalytics/Charts.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { useMemo } from "react";
77

88
import { StargazersChart } from "./charts/StargazersChart";
99
import { IssueReactsByMonth } from "./charts/IssueReactsByMonth";
10+
import { UserCodeVsComment } from "./charts/UserCodeVsComment";
1011

1112
export interface ChartsProps {
1213
importedRepository: ImportedRepository;
@@ -32,6 +33,8 @@ export const Charts = ({ importedRepository }: ChartsProps) => {
3233
<StargazersChart {...importedRepository} />
3334
<h3>Issue Reacts by Month</h3>
3435
<IssueReactsByMonth {...importedRepository} />
36+
<h3>Code vs. Comment Length</h3>
37+
<UserCodeVsComment {...importedRepository} />
3538
</SqlProvider>
3639
</div>
3740
);

components/RepositoryAnalytics/charts/IssueReactsByMonth.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ const META_NAMESPACE =
77
process.env.NEXT_PUBLIC_SPLITGRAPH_GITHUB_ANALYTICS_META_NAMESPACE;
88

99
type Reaction =
10-
// | "all"
1110
| "plus_one"
1211
| "minus_one"
1312
| "laugh"
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
import * as Plot from "@observablehq/plot";
2+
import { useSqlPlot } from "../useSqlPlot";
3+
import type { ImportedRepository, TargetSplitgraphRepo } from "../../../types";
4+
5+
// Assume meta namespace contains both the meta tables, and all imported repositories and tables
6+
const META_NAMESPACE =
7+
process.env.NEXT_PUBLIC_SPLITGRAPH_GITHUB_ANALYTICS_META_NAMESPACE;
8+
9+
type CommentLengthRow = {
10+
username: string;
11+
comment_length: number;
12+
net_lines_added: number;
13+
total_lines_added: number;
14+
total_lines_deleted: number;
15+
};
16+
17+
const sum = (arr: number[]) => arr.reduce((a, b) => a + b, 0);
18+
const mean = (arr: number[]) => sum(arr) / arr.length;
19+
20+
/**
21+
* A scatter plot of user comment length vs. lines of code
22+
*/
23+
export const UserCodeVsComment = ({
24+
splitgraphNamespace,
25+
splitgraphRepository,
26+
}: ImportedRepository) => {
27+
const renderPlot = useSqlPlot({
28+
sqlParams: { splitgraphNamespace, splitgraphRepository },
29+
buildQuery: userStatsQuery,
30+
mapRows: (r: UserStatsRow) =>
31+
({
32+
username: r.username,
33+
comment_length: r.total_comment_length,
34+
total_lines_added: r.total_lines_added,
35+
total_lines_deleted: r.total_lines_deleted,
36+
net_lines_added: r.total_lines_added - r.total_lines_deleted,
37+
} as CommentLengthRow),
38+
isRenderable: (p) => !!p.splitgraphRepository,
39+
reduceRows: (rows: CommentLengthRow[]) =>
40+
rows.filter((r) => r.username && !r.username.endsWith("[bot]")),
41+
42+
makePlotOptions: (userStats: CommentLengthRow[]) => ({
43+
y: {
44+
label: "Length of Comments",
45+
type: "symlog",
46+
constant: mean(userStats.map((u) => u.comment_length)),
47+
},
48+
x: {
49+
label: "Lines of Code",
50+
type: "symlog",
51+
constant: mean(userStats.map((u) => u.total_lines_added)),
52+
},
53+
color: {
54+
scheme: "Turbo",
55+
},
56+
marks: [
57+
Plot.dot(userStats, {
58+
x: "comment_length",
59+
y: "total_lines_added",
60+
stroke: "username",
61+
fill: "username",
62+
tip: true,
63+
}),
64+
Plot.ruleY([0]),
65+
],
66+
}),
67+
});
68+
69+
return renderPlot();
70+
};
71+
72+
/** Shape of row returned by {@link userStatsQuery} */
73+
export type UserStatsRow = {
74+
username: string;
75+
total_commits: number;
76+
total_pull_request_comments: number;
77+
total_issue_comments: number;
78+
total_comment_length: number;
79+
total_merged_pull_requests: number;
80+
total_pull_requests: number;
81+
total_lines_added: number;
82+
total_lines_deleted: number;
83+
};
84+
85+
/** Time series of GitHub stargazers for the given repository */
86+
export const userStatsQuery = ({
87+
splitgraphNamespace = META_NAMESPACE,
88+
splitgraphRepository,
89+
}: TargetSplitgraphRepo) => {
90+
return `SELECT
91+
username,
92+
sum(no_commits) as total_commits,
93+
sum(no_pull_request_comments) as total_pull_request_comments,
94+
sum(no_issue_comments) as total_issue_comments,
95+
sum(total_comment_length) as total_comment_length,
96+
sum(merged_pull_requests) as total_merged_pull_requests,
97+
sum(total_pull_requests) as total_pull_requests,
98+
sum(lines_added) as total_lines_added,
99+
sum(lines_deleted) as total_lines_deleted
100+
FROM "${splitgraphNamespace}/${splitgraphRepository}"."monthly_user_stats"
101+
GROUP BY username;`;
102+
};

components/RepositoryAnalytics/useSqlPlot.tsx

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,8 +92,6 @@ export const useSqlPlot = <
9292
return reduceRows(mappedRows);
9393
}, [mappedRows]);
9494

95-
console.log(JSON.stringify(reducedRows));
96-
9795
const plotOptions = useMemo(
9896
() => makePlotOptions(reducedRows),
9997
[reducedRows]

0 commit comments

Comments
 (0)