1
+ <template >
2
+ <div >
3
+ <div class =" tiles-container" >
4
+ <!-- Acceptance Rate Tile -->
5
+ <v-card elevation =" 4" color =" white" variant =" elevated" class =" mx-auto my-3" style =" width : 300px ; height : 175px ;" >
6
+ <v-card-item >
7
+ <div >
8
+ <div class =" text-overline mb-1" style =" visibility : hidden ;" >filler</div >
9
+ <div class =" text-h6 mb-1" >Number of {{ breakdownDisplayNamePlural }}</div >
10
+ <div class =" text-caption" >
11
+ Over the last 28 days
12
+ </div >
13
+ <p >{{ numberOfBreakdowns }}</p >
14
+ </div >
15
+ </v-card-item >
16
+ </v-card >
17
+ </div >
18
+
19
+ <v-main class =" p-1" style =" min-height : 300px ;" >
20
+ <v-container style =" min-height : 300px ;" class =" px-4 elevation-2" >
21
+ <v-row >
22
+ <v-col cols =" 6" >
23
+ <v-card >
24
+ <v-card-item class =" d-flex justify-center align-center" >
25
+ <div class =" text-overline mb-1" style =" visibility : hidden ;" >filler</div >
26
+ <div class =" text-h6 mb-1" >Top 5 {{ breakdownDisplayNamePlural }} by accepted prompts</div >
27
+ <div style =" width : 300px ; height : 300px ;" >
28
+ <Pie :data =" breakdownsChartDataTop5AcceptedPrompts" :options =" chartOptions" />
29
+ </div >
30
+ </v-card-item >
31
+ </v-card >
32
+ </v-col >
33
+
34
+ <v-col cols =" 6" >
35
+ <v-card >
36
+ <v-card-item class =" d-flex justify-center align-center" >
37
+ <div class =" text-overline mb-1" style =" visibility : hidden ;" >filler</div >
38
+ <div class =" text-h6 mb-1" >Top 5 {{ breakdownDisplayNamePlural }} by acceptance rate</div >
39
+ <div style =" width : 300px ; height : 300px ;" >
40
+ <Pie :data =" breakdownsChartDataTop5AcceptanceRate" :options =" chartOptions" />
41
+ </div >
42
+ </v-card-item >
43
+ </v-card >
44
+ </v-col >
45
+ </v-row >
46
+
47
+ <br >
48
+ <h2 >{{ breakdownDisplayNamePlural }} Breakdown </h2 >
49
+ <br >
50
+
51
+ <v-data-table :headers =" headers" :items =" Array.from(breakdowns)" class =" elevation-2" style =" padding-left : 100px ; padding-right : 100px ;" >
52
+ <template v-slot :item =" {item } " >
53
+ <tr >
54
+ <td >{{ item[0] }}</td >
55
+ <td >{{ item[1].acceptedPrompts }}</td >
56
+ <td >{{ item[1].acceptedLinesOfCode }}</td >
57
+ <td v-if =" item[1].acceptanceRate !== undefined" >{{ item[1].acceptanceRate.toFixed(2) }}%</td >
58
+ </tr >
59
+ </template >
60
+ </v-data-table >
61
+ </v-container >
62
+ </v-main >
63
+ </div >
64
+ </template >
65
+
66
+ <script lang="ts">
67
+ import { defineComponent , ref , toRef } from ' vue' ;
68
+ import { Metrics } from ' ../model/Metrics' ;
69
+ import { Breakdown } from ' ../model/Breakdown' ;
70
+ import { Pie } from ' vue-chartjs'
71
+
72
+ import {
73
+ Chart as ChartJS ,
74
+ ArcElement ,
75
+ CategoryScale ,
76
+ LinearScale ,
77
+ PointElement ,
78
+ LineElement ,
79
+ BarElement ,
80
+ Title ,
81
+ Tooltip ,
82
+ Legend
83
+ } from ' chart.js'
84
+
85
+ ChartJS .register (
86
+ ArcElement ,
87
+ CategoryScale ,
88
+ LinearScale ,
89
+ BarElement ,
90
+ PointElement ,
91
+ LineElement ,
92
+ Title ,
93
+ Tooltip ,
94
+ Legend
95
+ )
96
+
97
+ export default defineComponent ({
98
+ name: ' BreakdownComponent' ,
99
+ props: {
100
+ metrics: {
101
+ type: Object ,
102
+ required: true
103
+ },
104
+ breakdownKey: {
105
+ type: String ,
106
+ required: true
107
+ }
108
+ },
109
+ components: {
110
+ Pie
111
+ },
112
+ computed: {
113
+ breakdownDisplayName() {
114
+ return this .breakdownKey .charAt (0 ).toUpperCase () + this .breakdownKey .slice (1 );
115
+ },
116
+ breakdownDisplayNamePlural() {
117
+ return ` ${this .breakdownDisplayName }s ` ;
118
+ },
119
+ headers() {
120
+ return [
121
+ { title: ` ${this .breakdownDisplayName } Name ` , key: ' breakdownName' },
122
+ { title: ' Accepted Prompts' , key: ' acceptedPrompts' },
123
+ { title: ' Accepted Lines of Code' , key: ' acceptedLinesOfCode' },
124
+ { title: ' Acceptance Rate (%)' , key: ' acceptanceRate' },
125
+ ];
126
+ },
127
+ },
128
+ setup(props ) {
129
+
130
+ // Create an empty map to store the breakdowns.
131
+ const breakdowns = ref (new Map <string , Breakdown >());
132
+
133
+ // Number of breakdowns
134
+ const numberOfBreakdowns = ref (0 );
135
+
136
+ // Breakdowns Chart Data for breakdowns breakdown Pie Chart
137
+ let breakdownsChartData = ref <{ labels: string []; datasets: any [] }>({ labels: [], datasets: [] });
138
+
139
+ // Top 5 by accepted prompts
140
+ let breakdownsChartDataTop5AcceptedPrompts = ref <{ labels: string []; datasets: any [] }>({ labels: [], datasets: [] });
141
+
142
+ // Top 5 by acceptance rate
143
+ let breakdownsChartDataTop5AcceptanceRate = ref <{ labels: string []; datasets: any [] }>({ labels: [], datasets: [] });
144
+
145
+ const chartOptions = {
146
+ responsive: true ,
147
+ maintainAspectRatio: true ,
148
+ };
149
+
150
+ const pieChartColors = ref ([
151
+ ' #4B0082' , ' #41B883' , ' #483D8B' , ' #87CEFA' ,
152
+ ' #32CD32'
153
+ ]);
154
+
155
+ const data = toRef (props , ' metrics' ).value ;
156
+
157
+ // Process the breakdown separately
158
+ data .forEach ((m : Metrics ) => m .breakdown .forEach (breakdownData =>
159
+ {
160
+ const breakdownName = breakdownData [props .breakdownKey as keyof typeof breakdownData ] as string ;
161
+ let breakdown = breakdowns .value .get (breakdownName );
162
+
163
+ if (! breakdown ) {
164
+ // Create a new breakdown object if it does not exist
165
+ breakdown = new Breakdown ({
166
+ name: breakdownName ,
167
+ acceptedPrompts: breakdownData .acceptances_count ,
168
+ suggestedLinesOfCode: breakdownData .lines_suggested ,
169
+ acceptedLinesOfCode: breakdownData .lines_accepted ,
170
+ });
171
+ breakdowns .value .set (breakdownName , breakdown );
172
+ } else {
173
+ // Update the existing breakdown object
174
+ breakdown .acceptedPrompts += breakdownData .acceptances_count ;
175
+ breakdown .suggestedLinesOfCode += breakdownData .lines_suggested ;
176
+ breakdown .acceptedLinesOfCode += breakdownData .lines_accepted ;
177
+ }
178
+ // Recalculate the acceptance rate
179
+ breakdown .acceptanceRate = breakdown .suggestedLinesOfCode !== 0 ? (breakdown .acceptedLinesOfCode / breakdown .suggestedLinesOfCode ) * 100 : 0 ;
180
+ }));
181
+
182
+ // Sort breakdowns map by acceptance rate
183
+ breakdowns .value [Symbol .iterator ] = function * () {
184
+ yield * [... this .entries ()].sort ((a , b ) => b [1 ].acceptanceRate - a [1 ].acceptanceRate );
185
+ }
186
+
187
+ // Get the top 5 breakdowns by acceptance rate
188
+ const top5BreakdownsAcceptanceRate = new Map ([... breakdowns .value ].slice (0 , 5 ));
189
+
190
+ breakdownsChartDataTop5AcceptanceRate .value = {
191
+ labels: Array .from (top5BreakdownsAcceptanceRate .values ()).map (breakdown => breakdown .name ),
192
+ datasets: [
193
+ {
194
+ data: Array .from (top5BreakdownsAcceptanceRate .values ()).map (breakdown => breakdown .acceptanceRate .toFixed (2 )),
195
+ backgroundColor: pieChartColors .value ,
196
+ },
197
+ ],
198
+ };
199
+
200
+ // Sort breakdowns map by accepted prompts
201
+ breakdowns .value [Symbol .iterator ] = function * () {
202
+ yield * [... this .entries ()].sort ((a , b ) => b [1 ].acceptedPrompts - a [1 ].acceptedPrompts );
203
+ }
204
+
205
+ breakdownsChartData .value = {
206
+ labels: Array .from (breakdowns .value .values ()).map (breakdown => breakdown .name ),
207
+ datasets: [
208
+ {
209
+ data: Array .from (breakdowns .value .values ()).map (breakdown => breakdown .acceptedPrompts ),
210
+ backgroundColor: pieChartColors .value ,
211
+ },
212
+ ],
213
+ };
214
+
215
+ // Get the top 5 breakdowns by accepted prompts
216
+ const top5BreakdownsAcceptedPrompts = new Map ([... breakdowns .value ].slice (0 , 5 ));
217
+
218
+ breakdownsChartDataTop5AcceptedPrompts .value = {
219
+ labels: Array .from (top5BreakdownsAcceptedPrompts .values ()).map (breakdown => breakdown .name ),
220
+ datasets: [
221
+ {
222
+ data: Array .from (top5BreakdownsAcceptedPrompts .values ()).map (breakdown => breakdown .acceptedPrompts ),
223
+ backgroundColor: pieChartColors .value ,
224
+ },
225
+ ],
226
+ };
227
+
228
+ numberOfBreakdowns .value = breakdowns .value .size ;
229
+
230
+ return { chartOptions , breakdowns , numberOfBreakdowns ,
231
+ breakdownsChartData , breakdownsChartDataTop5AcceptedPrompts , breakdownsChartDataTop5AcceptanceRate };
232
+ },
233
+
234
+
235
+ });
236
+ </script >
237
+
238
+ <style scoped>
239
+
240
+ .tiles-container {
241
+ display : flex ;
242
+ justify-content : flex-start ;
243
+ flex-wrap : wrap ;
244
+ }
245
+
246
+ </style >
0 commit comments