Skip to content

Commit 6333e0d

Browse files
committed
add editors breakdown
1 parent f227a05 commit 6333e0d

File tree

6 files changed

+256
-282
lines changed

6 files changed

+256
-282
lines changed
Lines changed: 243 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,243 @@
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 {{ breakdownKey }}s</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 {{ breakdownKey }}s 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 {{ breakdownKey }}s 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>{{ breakdownDisplayName }}s 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: 'BreakdownsComponent',
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+
headers() {
117+
return [
118+
{ title: `${this.breakdownDisplayName} Name`, key: 'breakdownName' },
119+
{ title: 'Accepted Prompts', key: 'acceptedPrompts' },
120+
{ title: 'Accepted Lines of Code', key: 'acceptedLinesOfCode' },
121+
{ title: 'Acceptance Rate (%)', key: 'acceptanceRate' },
122+
];
123+
},
124+
},
125+
setup(props) {
126+
127+
// Create an empty map to store the breakdowns.
128+
const breakdowns = ref(new Map<string, Breakdown>());
129+
130+
// Number of breakdowns
131+
const numberOfBreakdowns = ref(0);
132+
133+
// Breakdowns Chart Data for breakdowns breakdown Pie Chart
134+
let breakdownsChartData = ref<{ labels: string[]; datasets: any[] }>({ labels: [], datasets: [] });
135+
136+
//Top 5 by accepted prompts
137+
let breakdownsChartDataTop5AcceptedPrompts = ref<{ labels: string[]; datasets: any[] }>({ labels: [], datasets: [] });
138+
139+
//Top 5 by acceptance rate
140+
let breakdownsChartDataTop5AcceptanceRate = ref<{ labels: string[]; datasets: any[] }>({ labels: [], datasets: [] });
141+
142+
const chartOptions = {
143+
responsive: true,
144+
maintainAspectRatio: true,
145+
};
146+
147+
const pieChartColors = ref([
148+
'#4B0082', '#41B883', '#483D8B', '#87CEFA',
149+
'#32CD32'
150+
]);
151+
152+
const data = toRef(props, 'metrics').value;
153+
154+
// Process the breakdown separately
155+
data.forEach((m: Metrics) => m.breakdown.forEach(breakdownData =>
156+
{
157+
const breakdownName = breakdownData[props.breakdownKey as keyof typeof breakdownData] as string;
158+
let breakdown = breakdowns.value.get(breakdownName);
159+
160+
if (!breakdown) {
161+
// Create a new breakdown object if it does not exist
162+
breakdown = new Breakdown({
163+
name: breakdownName,
164+
acceptedPrompts: breakdownData.acceptances_count,
165+
suggestedLinesOfCode: breakdownData.lines_suggested,
166+
acceptedLinesOfCode: breakdownData.lines_accepted,
167+
});
168+
breakdowns.value.set(breakdownName, breakdown);
169+
} else {
170+
// Update the existing breakdown object
171+
breakdown.acceptedPrompts += breakdownData.acceptances_count;
172+
breakdown.suggestedLinesOfCode += breakdownData.lines_suggested;
173+
breakdown.acceptedLinesOfCode += breakdownData.lines_accepted;
174+
}
175+
// Recalculate the acceptance rate
176+
breakdown.acceptanceRate = breakdown.suggestedLinesOfCode !== 0 ? (breakdown.acceptedLinesOfCode / breakdown.suggestedLinesOfCode) * 100 : 0;
177+
}));
178+
179+
//Sort breakdowns map by acceptance rate
180+
breakdowns.value[Symbol.iterator] = function* () {
181+
yield* [...this.entries()].sort((a, b) => b[1].acceptanceRate - a[1].acceptanceRate);
182+
}
183+
184+
// Get the top 5 breakdowns by acceptance rate
185+
const top5BreakdownsAcceptanceRate = new Map([...breakdowns.value].slice(0, 5));
186+
187+
breakdownsChartDataTop5AcceptanceRate.value = {
188+
labels: Array.from(top5BreakdownsAcceptanceRate.values()).map(breakdown => breakdown.name),
189+
datasets: [
190+
{
191+
data: Array.from(top5BreakdownsAcceptanceRate.values()).map(breakdown => breakdown.acceptanceRate.toFixed(2)),
192+
backgroundColor: pieChartColors.value,
193+
},
194+
],
195+
};
196+
197+
//Sort breakdowns map by accepted prompts
198+
breakdowns.value[Symbol.iterator] = function* () {
199+
yield* [...this.entries()].sort((a, b) => b[1].acceptedPrompts - a[1].acceptedPrompts);
200+
}
201+
202+
breakdownsChartData.value = {
203+
labels: Array.from(breakdowns.value.values()).map(breakdown => breakdown.name),
204+
datasets: [
205+
{
206+
data: Array.from(breakdowns.value.values()).map(breakdown => breakdown.acceptedPrompts),
207+
backgroundColor: pieChartColors.value,
208+
},
209+
],
210+
};
211+
212+
// Get the top 5 breakdowns by accepted prompts
213+
const top5BreakdownsAcceptedPrompts = new Map([...breakdowns.value].slice(0, 5));
214+
215+
breakdownsChartDataTop5AcceptedPrompts.value = {
216+
labels: Array.from(top5BreakdownsAcceptedPrompts.values()).map(breakdown => breakdown.name),
217+
datasets: [
218+
{
219+
data: Array.from(top5BreakdownsAcceptedPrompts.values()).map(breakdown => breakdown.acceptedPrompts),
220+
backgroundColor: pieChartColors.value,
221+
},
222+
],
223+
};
224+
225+
numberOfBreakdowns.value = breakdowns.value.size;
226+
227+
return { chartOptions, breakdowns, numberOfBreakdowns,
228+
breakdownsChartData, breakdownsChartDataTop5AcceptedPrompts, breakdownsChartDataTop5AcceptanceRate };
229+
},
230+
231+
232+
});
233+
</script>
234+
235+
<style scoped>
236+
237+
.tiles-container {
238+
display: flex;
239+
justify-content: flex-start;
240+
flex-wrap: wrap;
241+
}
242+
243+
</style>

0 commit comments

Comments
 (0)