31
31
<v-chip
32
32
v-bind =" props"
33
33
:text =" item.raw.name"
34
+ color =" primary"
35
+ variant =" outlined"
34
36
closable
35
37
/>
36
38
</template >
67
69
:key =" team.slug"
68
70
:href =" getTeamDetailUrl(team.slug)"
69
71
color =" primary"
70
- variant =" outlined "
72
+ variant =" tonal "
71
73
target =" _blank"
72
74
link
73
75
>
223
225
</v-container >
224
226
</v-main >
225
227
226
- <!-- Language and Editor Comparison Tables -->
228
+ <!-- Language and Editor Comparison Charts -->
227
229
<v-container >
228
230
<v-row >
229
231
<v-col cols =" 12" md =" 6" >
230
232
<v-card class =" pa-4" >
231
233
<v-card-title class =" text-h6" >Language Usage by Team</v-card-title >
232
234
<v-card-text >
233
- <v-table v-if =" languageComparison.length > 0" >
234
- <thead >
235
- <tr >
236
- <th >Language</th >
237
- <th >Team</th >
238
- <th >Acceptance Rate</th >
239
- </tr >
240
- </thead >
241
- <tbody >
242
- <tr v-for =" lang in languageComparison" :key =" `${lang.team}-${lang.language}`" >
243
- <td >{{ lang.language }}</td >
244
- <td >{{ lang.team }}</td >
245
- <td >{{ lang.acceptance_rate.toFixed(2) }}%</td >
246
- </tr >
247
- </tbody >
248
- </v-table >
249
- <div v-else class =" text-center text-medium-emphasis" >
250
- No language data available for selected teams
235
+ <div v-if =" languageBarChartData.datasets.length > 0" >
236
+ <Bar :data =" languageBarChartData" :options =" barChartOptions" />
237
+ </div >
238
+ <div v-else class =" text-center text-medium-emphasis py-8" >
239
+ <v-icon size =" 48" color =" grey-lighten-1" >mdi-chart-bar</v-icon >
240
+ <p class =" mt-2" >No language data available for selected teams</p >
251
241
</div >
252
242
</v-card-text >
253
243
</v-card >
256
246
<v-card class =" pa-4" >
257
247
<v-card-title class =" text-h6" >Editor Usage by Team</v-card-title >
258
248
<v-card-text >
259
- <v-table v-if =" editorComparison.length > 0" >
260
- <thead >
261
- <tr >
262
- <th >Editor</th >
263
- <th >Team</th >
264
- <th >Active Users</th >
265
- </tr >
266
- </thead >
267
- <tbody >
268
- <tr v-for =" editor in editorComparison" :key =" `${editor.team}-${editor.editor}`" >
269
- <td >{{ editor.editor }}</td >
270
- <td >{{ editor.team }}</td >
271
- <td >{{ editor.active_users }}</td >
272
- </tr >
273
- </tbody >
274
- </v-table >
275
- <div v-else class =" text-center text-medium-emphasis" >
276
- No editor data available for selected teams
249
+ <div v-if =" editorBarChartData.datasets.length > 0" >
250
+ <Bar :data =" editorBarChartData" :options =" barChartOptions" />
251
+ </div >
252
+ <div v-else class =" text-center text-medium-emphasis py-8" >
253
+ <v-icon size =" 48" color =" grey-lighten-1" >mdi-chart-bar</v-icon >
254
+ <p class =" mt-2" >No editor data available for selected teams</p >
277
255
</div >
278
256
</v-card-text >
279
257
</v-card >
303
281
304
282
<script setup lang="ts">
305
283
import { ref , computed , watch } from ' vue'
306
- import { Line } from ' vue-chartjs'
284
+ import { Line , Bar } from ' vue-chartjs'
307
285
import type { Metrics } from ' @/model/Metrics'
308
286
import {
309
287
Chart as ChartJS ,
310
288
CategoryScale ,
311
289
LinearScale ,
312
290
PointElement ,
313
291
LineElement ,
292
+ BarElement ,
314
293
Title ,
315
294
Tooltip ,
316
295
Legend
@@ -321,6 +300,7 @@ ChartJS.register(
321
300
LinearScale ,
322
301
PointElement ,
323
302
LineElement ,
303
+ BarElement ,
324
304
Title ,
325
305
Tooltip ,
326
306
Legend
@@ -392,6 +372,10 @@ const githubPrChartData = ref<{ labels: string[]; datasets: any[] }>({ labels: [
392
372
const languageComparison = ref <LanguageTeamData []>([])
393
373
const editorComparison = ref <EditorTeamData []>([])
394
374
375
+ // Bar chart data refs
376
+ const languageBarChartData = ref <{ labels: string []; datasets: any [] }>({ labels: [], datasets: [] })
377
+ const editorBarChartData = ref <{ labels: string []; datasets: any [] }>({ labels: [], datasets: [] })
378
+
395
379
// Chart options
396
380
const chartOptions = {
397
381
responsive: true ,
@@ -411,6 +395,25 @@ const chartOptions = {
411
395
}
412
396
}
413
397
398
+ // Bar chart options
399
+ const barChartOptions = {
400
+ responsive: true ,
401
+ maintainAspectRatio: true ,
402
+ scales: {
403
+ y: {
404
+ beginAtZero: true
405
+ }
406
+ },
407
+ layout: {
408
+ padding: {
409
+ left: 20 ,
410
+ right: 20 ,
411
+ top: 20 ,
412
+ bottom: 20
413
+ }
414
+ }
415
+ }
416
+
414
417
// Computed properties
415
418
const selectedTeamObjects = computed (() => {
416
419
return availableTeams .value .filter (team => selectedTeams .value .includes (team .slug ))
@@ -501,6 +504,53 @@ const generateMockEditorData = () => {
501
504
return result
502
505
}
503
506
507
+ const generateBarChartData = () => {
508
+ // Generate language bar chart data
509
+ const languages = [... new Set (languageComparison .value .map (l => l .language ))]
510
+ const teams = [... new Set (languageComparison .value .map (l => l .team ))]
511
+
512
+ const languageDatasets = teams .map ((team , index ) => {
513
+ const colorIndex = index % teamColors .length
514
+ return {
515
+ label: team ,
516
+ data: languages .map (language => {
517
+ const langData = languageComparison .value .find (l => l .language === language && l .team === team )
518
+ return langData ? langData .acceptance_rate : 0
519
+ }),
520
+ backgroundColor: teamColors [colorIndex ].border ,
521
+ borderColor: teamColors [colorIndex ].border ,
522
+ borderWidth: 1
523
+ }
524
+ })
525
+
526
+ languageBarChartData .value = {
527
+ labels: languages ,
528
+ datasets: languageDatasets
529
+ }
530
+
531
+ // Generate editor bar chart data
532
+ const editors = [... new Set (editorComparison .value .map (e => e .editor ))]
533
+
534
+ const editorDatasets = teams .map ((team , index ) => {
535
+ const colorIndex = index % teamColors .length
536
+ return {
537
+ label: team ,
538
+ data: editors .map (editor => {
539
+ const editorData = editorComparison .value .find (e => e .editor === editor && e .team === team )
540
+ return editorData ? editorData .active_users : 0
541
+ }),
542
+ backgroundColor: teamColors [colorIndex ].border ,
543
+ borderColor: teamColors [colorIndex ].border ,
544
+ borderWidth: 1
545
+ }
546
+ })
547
+
548
+ editorBarChartData .value = {
549
+ labels: editors ,
550
+ datasets: editorDatasets
551
+ }
552
+ }
553
+
504
554
// Chart colors for different teams
505
555
const teamColors = [
506
556
{ bg: ' rgba(75, 192, 192, 0.2)' , border: ' rgba(75, 192, 192, 1)' },
@@ -524,6 +574,8 @@ const updateChartData = () => {
524
574
githubPrChartData .value = { labels: [], datasets: [] }
525
575
languageComparison .value = []
526
576
editorComparison .value = []
577
+ languageBarChartData .value = { labels: [], datasets: [] }
578
+ editorBarChartData .value = { labels: [], datasets: [] }
527
579
return
528
580
}
529
581
@@ -667,6 +719,9 @@ const updateChartData = () => {
667
719
// Update comparison tables
668
720
languageComparison .value = generateMockLanguageData ()
669
721
editorComparison .value = generateMockEditorData ()
722
+
723
+ // Generate bar chart data
724
+ generateBarChartData ()
670
725
}
671
726
672
727
// Watch for changes in selected teams and update charts
0 commit comments