Skip to content

Commit 84b4268

Browse files
authored
Merge pull request #24 from giotab/generalize-breakdown-component
add editors breakdown
2 parents 21aae8f + acc776a commit 84b4268

File tree

6 files changed

+259
-282
lines changed

6 files changed

+259
-282
lines changed

src/components/BreakdownComponent.vue

Lines changed: 246 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,246 @@
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

Comments
 (0)