Skip to content

Commit f8f453a

Browse files
committed
Add language breakdown table to MetricsViewer.vue
1 parent 97f480d commit f8f453a

File tree

2 files changed

+85
-4
lines changed

2 files changed

+85
-4
lines changed

src/components/MetricsViewer.vue

Lines changed: 68 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22
<div>
33
<h1>GitHub Copilot Business Metrics Viewer</h1>
44

5-
<!-- API Error Message -->
5+
<!-- API Error Message -->
66
<div v-if="apiError" class="error-message" v-html="apiError"></div>
7-
<div v-if="!apiError">
7+
<div v-if="!apiError">
88
<h2>Acceptance rate (%)</h2>
99
<Bar :data="acceptanceRateChartData" :options="chartOptions" />
1010

@@ -16,6 +16,27 @@
1616

1717
<h2>Total Active Users</h2>
1818
<Bar :data="totalActiveUsersChartData" :options="totalActiveUsersChartOptions" />
19+
20+
<h2>Languages Breakdown</h2>
21+
<table class="center-table" style="border: 1px solid black;">
22+
<thead>
23+
<tr>
24+
<th style="text-align: left; border-right: 1px solid black; border-bottom: 1px solid black; padding-right: 10px;">Language Name</th>
25+
<th style="text-align: left; border-right: 1px solid black; border-bottom: 1px solid black; padding-right: 10px;">Accepted Prompts</th>
26+
<th style="border-right: 1px solid black; border-bottom: 1px solid black; padding-right: 10px;">Accepted Lines of Code</th>
27+
<th style="border-bottom: 1px solid black; padding-right: 10px;">Acceptance Rate</th>
28+
</tr>
29+
</thead>
30+
<tbody>
31+
<tr v-for="(language, languageName) in Array.from(languages)" :key="languageName">
32+
<td style="text-align: left;">{{ language[0] }}</td>
33+
<td style="text-align: left;">{{ language[1].acceptedPrompts }}</td>
34+
<td style="text-align: left;">{{ language[1].acceptedLinesOfCode }}</td>
35+
<td v-if="language[1].acceptanceRate !== undefined">{{ language[1].acceptanceRate.toFixed(2) }}%</td>
36+
</tr>
37+
</tbody>
38+
</table>
39+
1940
</div>
2041
</div>
2142
</template>
@@ -24,6 +45,7 @@
2445
import { defineComponent, ref } from 'vue';
2546
import { getGitHubCopilotMetricsApi } from '../api/GitHubApi';
2647
import { Metrics } from '../model/MetricsData';
48+
import { Language } from '../model/Language';
2749
import {
2850
Chart as ChartJS,
2951
CategoryScale,
@@ -74,6 +96,8 @@ export default defineComponent({
7496
// API Error Message
7597
const apiError = ref<string | null>(null);
7698
99+
// Create an empty map to store the languages.
100+
const languages = new Map<string, Language>();
77101
78102
const chartOptions = {
79103
responsive: true,
@@ -180,6 +204,36 @@ export default defineComponent({
180204
}
181205
]
182206
};
207+
208+
// Process the language breakdown separately
209+
data.forEach(m => m.breakdown.forEach(breakdown =>
210+
{
211+
const languageName = breakdown.language;
212+
let language = languages.get(languageName);
213+
214+
if (!language) {
215+
// Create a new Language object if it does not exist
216+
language = new Language({
217+
name: languageName,
218+
acceptedPrompts: breakdown.acceptances_count,
219+
suggestedLinesOfCode: breakdown.lines_suggested,
220+
acceptedLinesOfCode: breakdown.lines_accepted,
221+
});
222+
languages.set(languageName, language);
223+
} else {
224+
// Update the existing Language object
225+
language.acceptedPrompts += breakdown.acceptances_count;
226+
language.suggestedLinesOfCode += breakdown.lines_suggested;
227+
language.acceptedLinesOfCode += breakdown.lines_accepted;
228+
}
229+
// Recalculate the acceptance rate
230+
language.acceptanceRate = language.suggestedLinesOfCode !== 0 ? (language.acceptedLinesOfCode / language.suggestedLinesOfCode) * 100 : 0;
231+
}));
232+
233+
//Sort languages map by accepted lines of code
234+
languages[Symbol.iterator] = function* () {
235+
yield* [...this.entries()].sort((a, b) => b[1].acceptedLinesOfCode - a[1].acceptedLinesOfCode);
236+
}
183237
}).catch(error => {
184238
console.log(error);
185239
// Check the status code of the error response
@@ -204,13 +258,23 @@ export default defineComponent({
204258
205259
});
206260
207-
return { totalSuggestionsAndAcceptanceChartData, chartData, chartOptions, totalActiveUsersChartData, totalActiveUsersChartOptions, acceptanceRateChartData, apiError };
208-
}
261+
return { totalSuggestionsAndAcceptanceChartData, chartData,
262+
chartOptions, totalActiveUsersChartData,
263+
totalActiveUsersChartOptions, acceptanceRateChartData, apiError,
264+
languages };
265+
},
266+
267+
209268
});
210269
</script>
211270

212271
<style scoped>
213272
.error-message {
214273
color: red;
215274
}
275+
276+
.center-table {
277+
margin-left: auto;
278+
margin-right: auto;
279+
}
216280
</style>

src/model/Language.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// Language model with name, accepted prompts, accepted lines of code and acceptance rate
2+
3+
export class Language {
4+
languageName: string;
5+
acceptedPrompts: number;
6+
suggestedLinesOfCode: number;
7+
acceptedLinesOfCode: number;
8+
acceptanceRate: number; // Percentage
9+
10+
constructor(data: any) {
11+
this.languageName = data.name;
12+
this.acceptedPrompts = data.acceptedPrompts;
13+
this.suggestedLinesOfCode = data.suggestedLinesOfCode;
14+
this.acceptedLinesOfCode = data.acceptedLinesOfCode;
15+
this.acceptanceRate = data.acceptanceRate; // Convert to percentage
16+
}
17+
}

0 commit comments

Comments
 (0)