2
2
<div >
3
3
<h1 >GitHub Copilot Business Metrics Viewer</h1 >
4
4
5
- <!-- API Error Message -->
5
+ <!-- API Error Message -->
6
6
<div v-if =" apiError" class =" error-message" v-html =" apiError" ></div >
7
- <div v-if =" !apiError" >
7
+ <div v-if =" !apiError" >
8
8
<h2 >Acceptance rate (%)</h2 >
9
9
<Bar :data =" acceptanceRateChartData" :options =" chartOptions" />
10
10
16
16
17
17
<h2 >Total Active Users</h2 >
18
18
<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
+
19
40
</div >
20
41
</div >
21
42
</template >
24
45
import { defineComponent , ref } from ' vue' ;
25
46
import { getGitHubCopilotMetricsApi } from ' ../api/GitHubApi' ;
26
47
import { Metrics } from ' ../model/MetricsData' ;
48
+ import { Language } from ' ../model/Language' ;
27
49
import {
28
50
Chart as ChartJS ,
29
51
CategoryScale ,
@@ -74,6 +96,8 @@ export default defineComponent({
74
96
// API Error Message
75
97
const apiError = ref <string | null >(null );
76
98
99
+ // Create an empty map to store the languages.
100
+ const languages = new Map <string , Language >();
77
101
78
102
const chartOptions = {
79
103
responsive: true ,
@@ -180,6 +204,36 @@ export default defineComponent({
180
204
}
181
205
]
182
206
};
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
+ }
183
237
}).catch (error => {
184
238
console .log (error );
185
239
// Check the status code of the error response
@@ -204,13 +258,23 @@ export default defineComponent({
204
258
205
259
});
206
260
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
+
209
268
});
210
269
</script >
211
270
212
271
<style scoped>
213
272
.error-message {
214
273
color : red ;
215
274
}
275
+
276
+ .center-table {
277
+ margin-left : auto ;
278
+ margin-right : auto ;
279
+ }
216
280
</style >
0 commit comments