1
0
mirror of https://github.com/muety/wakapi.git synced 2023-08-10 21:12:56 +03:00

feat: introduce machine summaries (resolve #48)

This commit is contained in:
Ferdinand Mütsch 2020-08-29 22:03:01 +02:00
parent 2eccb7a468
commit 12cc4cd9cf
7 changed files with 50 additions and 9 deletions

View File

@ -80,6 +80,7 @@ INSERT INTO aliases (`type`, `user_id`, `key`, `value`) VALUES (0, 'your_usernam
* Language ~ type **1** * Language ~ type **1**
* Editor ~ type **2** * Editor ~ type **2**
* OS ~ type **3** * OS ~ type **3**
* Machine ~ type **4**
**NOTE:** In order for the aliases to take effect for non-live statistics, you would either have to wait 24 hours for the cache to be invalidated or restart Wakapi. **NOTE:** In order for the aliases to take effect for non-live statistics, you would either have to wait 24 hours for the cache to be invalidated or restart Wakapi.

View File

@ -5,11 +5,12 @@ import (
) )
const ( const (
NSummaryTypes uint8 = 4 NSummaryTypes uint8 = 99
SummaryProject uint8 = 0 SummaryProject uint8 = 0
SummaryLanguage uint8 = 1 SummaryLanguage uint8 = 1
SummaryEditor uint8 = 2 SummaryEditor uint8 = 2
SummaryOS uint8 = 3 SummaryOS uint8 = 3
SummaryMachine uint8 = 4
) )
type Summary struct { type Summary struct {
@ -21,6 +22,7 @@ type Summary struct {
Languages []*SummaryItem `json:"languages"` Languages []*SummaryItem `json:"languages"`
Editors []*SummaryItem `json:"editors"` Editors []*SummaryItem `json:"editors"`
OperatingSystems []*SummaryItem `json:"operating_systems"` OperatingSystems []*SummaryItem `json:"operating_systems"`
Machines []*SummaryItem `json:"machines"`
} }
type SummaryItem struct { type SummaryItem struct {

View File

@ -65,12 +65,13 @@ func (srv *SummaryService) Construct(from, to time.Time, user *models.User, reco
heartbeats = append(heartbeats, hb...) heartbeats = append(heartbeats, hb...)
} }
types := []uint8{models.SummaryProject, models.SummaryLanguage, models.SummaryEditor, models.SummaryOS} types := []uint8{models.SummaryProject, models.SummaryLanguage, models.SummaryEditor, models.SummaryOS, models.SummaryMachine}
var projectItems []*models.SummaryItem var projectItems []*models.SummaryItem
var languageItems []*models.SummaryItem var languageItems []*models.SummaryItem
var editorItems []*models.SummaryItem var editorItems []*models.SummaryItem
var osItems []*models.SummaryItem var osItems []*models.SummaryItem
var machineItems []*models.SummaryItem
if err := srv.AliasService.LoadUserAliases(user.ID); err != nil { if err := srv.AliasService.LoadUserAliases(user.ID); err != nil {
return nil, err return nil, err
@ -92,6 +93,8 @@ func (srv *SummaryService) Construct(from, to time.Time, user *models.User, reco
editorItems = item.Items editorItems = item.Items
case models.SummaryOS: case models.SummaryOS:
osItems = item.Items osItems = item.Items
case models.SummaryMachine:
machineItems = item.Items
} }
} }
close(c) close(c)
@ -119,6 +122,7 @@ func (srv *SummaryService) Construct(from, to time.Time, user *models.User, reco
Languages: languageItems, Languages: languageItems,
Editors: editorItems, Editors: editorItems,
OperatingSystems: osItems, OperatingSystems: osItems,
Machines: machineItems,
} }
allSummaries := []*models.Summary{aggregatedSummary} allSummaries := []*models.Summary{aggregatedSummary}
@ -154,6 +158,7 @@ func (srv *SummaryService) GetByUserWithin(user *models.User, from, to time.Time
Preload("Languages", "type = ?", models.SummaryLanguage). Preload("Languages", "type = ?", models.SummaryLanguage).
Preload("Editors", "type = ?", models.SummaryEditor). Preload("Editors", "type = ?", models.SummaryEditor).
Preload("OperatingSystems", "type = ?", models.SummaryOS). Preload("OperatingSystems", "type = ?", models.SummaryOS).
Preload("Machines", "type = ?", models.SummaryMachine).
Find(&summaries).Error; err != nil { Find(&summaries).Error; err != nil {
return nil, err return nil, err
} }
@ -187,6 +192,8 @@ func (srv *SummaryService) aggregateBy(heartbeats []*models.Heartbeat, summaryTy
key = h.Language key = h.Language
case models.SummaryOS: case models.SummaryOS:
key = h.OperatingSystem key = h.OperatingSystem
case models.SummaryMachine:
key = h.Machine
} }
if key == "" { if key == "" {
@ -276,6 +283,7 @@ func mergeSummaries(summaries []*models.Summary) (*models.Summary, error) {
Languages: make([]*models.SummaryItem, 0), Languages: make([]*models.SummaryItem, 0),
Editors: make([]*models.SummaryItem, 0), Editors: make([]*models.SummaryItem, 0),
OperatingSystems: make([]*models.SummaryItem, 0), OperatingSystems: make([]*models.SummaryItem, 0),
Machines: make([]*models.SummaryItem, 0),
} }
for _, s := range summaries { for _, s := range summaries {
@ -295,6 +303,7 @@ func mergeSummaries(summaries []*models.Summary) (*models.Summary, error) {
finalSummary.Languages = mergeSummaryItems(finalSummary.Languages, s.Languages) finalSummary.Languages = mergeSummaryItems(finalSummary.Languages, s.Languages)
finalSummary.Editors = mergeSummaryItems(finalSummary.Editors, s.Editors) finalSummary.Editors = mergeSummaryItems(finalSummary.Editors, s.Editors)
finalSummary.OperatingSystems = mergeSummaryItems(finalSummary.OperatingSystems, s.OperatingSystems) finalSummary.OperatingSystems = mergeSummaryItems(finalSummary.OperatingSystems, s.OperatingSystems)
finalSummary.Machines = mergeSummaryItems(finalSummary.Machines, s.Machines)
} }
finalSummary.FromTime = minTime finalSummary.FromTime = minTime

View File

@ -5,6 +5,7 @@ const projectsCanvas = document.getElementById('chart-projects')
const osCanvas = document.getElementById('chart-os') const osCanvas = document.getElementById('chart-os')
const editorsCanvas = document.getElementById('chart-editor') const editorsCanvas = document.getElementById('chart-editor')
const languagesCanvas = document.getElementById('chart-language') const languagesCanvas = document.getElementById('chart-language')
const machinesCanvas = document.getElementById('chart-machine')
let charts = [] let charts = []
let resizeCount = 0 let resizeCount = 0
@ -135,10 +136,31 @@ function draw() {
} }
}) })
let machineChart = new Chart(machinesCanvas.getContext('2d'), {
type: 'pie',
data: {
datasets: [{
data: wakapiData.machines
.slice(0, Math.min(SHOW_TOP_N, wakapiData.machines.length))
.map(p => parseInt(p.total)),
backgroundColor: wakapiData.machines.map(p => getRandomColor(p.key))
}],
labels: wakapiData.machines
.slice(0, Math.min(SHOW_TOP_N, wakapiData.machines.length))
.map(p => p.key)
},
options: {
title: Object.assign(titleOptions, {text: `Machines (top ${SHOW_TOP_N})`}),
tooltips: getTooltipOptions('machines', 'pie'),
maintainAspectRatio: false,
onResize: onChartResize
}
})
getTotal(wakapiData.operatingSystems) getTotal(wakapiData.operatingSystems)
document.getElementById('grid-container').style.visibility = 'visible' document.getElementById('grid-container').style.visibility = 'visible'
charts = [projectChart, osChart, editorChart, languageChart] charts = [projectChart, osChart, editorChart, languageChart, machineChart]
charts.forEach(c => c.options.onResize(c.chart)) charts.forEach(c => c.options.onResize(c.chart))
equalizeHeights() equalizeHeights()

View File

@ -1 +1 @@
1.7.6 1.8.0

View File

@ -2,11 +2,13 @@
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.3/Chart.bundle.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.3/Chart.bundle.min.js"></script>
<script> <script>
const languageColors = {{ .LanguageColors | json }}
let wakapiData = {} let wakapiData = {}
let languageColors = {{ .LanguageColors | json }} wakapiData.projects = {{ .Projects | json }}
wakapiData.projects = {{ .Projects | json }} wakapiData.operatingSystems = {{ .OperatingSystems | json }}
wakapiData.operatingSystems = {{ .OperatingSystems | json }} wakapiData.editors = {{ .Editors | json }}
wakapiData.editors = {{ .Editors | json }} wakapiData.languages = {{ .Languages | json }}
wakapiData.languages = {{ .Languages | json }} wakapiData.machines = {{ .Machines | json }}
</script> </script>
<script src="assets/app.js"></script> <script src="assets/app.js"></script>

View File

@ -78,6 +78,11 @@
<canvas id="chart-editor"></canvas> <canvas id="chart-editor"></canvas>
</div> </div>
</div> </div>
<div class="w-full lg:w-1/2 p-1">
<div class="p-4 bg-white rounded shadow m-2" id="machine-container" style="height: 300px">
<canvas id="chart-machine"></canvas>
</div>
</div>
</div> </div>
</main> </main>