1151 lines
39 KiB
Go
1151 lines
39 KiB
Go
package gui
|
|
|
|
// statisticsGui.go implements pages to view statistics about the Seekia network
|
|
|
|
import "fyne.io/fyne/v2"
|
|
import "fyne.io/fyne/v2/canvas"
|
|
import "fyne.io/fyne/v2/container"
|
|
import "fyne.io/fyne/v2/data/binding"
|
|
import "fyne.io/fyne/v2/layout"
|
|
import "fyne.io/fyne/v2/theme"
|
|
import "fyne.io/fyne/v2/widget"
|
|
|
|
import "seekia/internal/appMemory"
|
|
import "seekia/internal/badgerDatabase"
|
|
import "seekia/internal/createCharts"
|
|
import "seekia/internal/globalSettings"
|
|
import "seekia/internal/helpers"
|
|
import "seekia/internal/network/appNetworkType/getAppNetworkType"
|
|
import "seekia/internal/profiles/attributeDisplay"
|
|
import "seekia/internal/profiles/userStatistics"
|
|
import "seekia/internal/statisticsDatum"
|
|
|
|
import "errors"
|
|
import "image"
|
|
import "strings"
|
|
import "time"
|
|
import "sync"
|
|
|
|
func setNetworkStatisticsPage(window fyne.Window, previousPage func()){
|
|
|
|
currentPage := func(){setNetworkStatisticsPage(window, previousPage)}
|
|
|
|
title := getPageTitleCentered("Network Statistics")
|
|
|
|
backButton := getBackButtonCentered(previousPage)
|
|
|
|
description := getLabelCentered(translate("View statistics about the Seekia network."))
|
|
|
|
mateStatisticsButton := widget.NewButton("Mate Statistics", func(){
|
|
setNetworkUserStatisticsPage(window, "Mate", currentPage)
|
|
})
|
|
|
|
hostStatisticsButton := widget.NewButton("Host Statistics", func(){
|
|
setNetworkUserStatisticsPage(window, "Host", currentPage)
|
|
})
|
|
|
|
moderatorStatisticsButton := widget.NewButton("Moderator Statistics", func(){
|
|
setNetworkUserStatisticsPage(window, "Moderator", currentPage)
|
|
})
|
|
|
|
messageStatisticsButton := widget.NewButton("Message Statistics", func(){
|
|
//TODO
|
|
showUnderConstructionDialog(window)
|
|
})
|
|
|
|
buttonsGrid := getContainerCentered(container.NewGridWithColumns(1, mateStatisticsButton, hostStatisticsButton, moderatorStatisticsButton, messageStatisticsButton))
|
|
|
|
page := container.NewVBox(title, backButton, widget.NewSeparator(), description, widget.NewSeparator(), buttonsGrid)
|
|
|
|
setPageContent(page, window)
|
|
}
|
|
|
|
|
|
func setNetworkUserStatisticsPage(window fyne.Window, identityType string, previousPage func()){
|
|
|
|
if (identityType != "Mate" && identityType != "Host" && identityType != "Moderator"){
|
|
setErrorEncounteredPage(window, errors.New("setUserStatisticsPage called with invalid identityType: " + identityType), previousPage)
|
|
return
|
|
}
|
|
|
|
setLoadingScreen(window, identityType + " Statistics", "Loading " + identityType + " statistics page...")
|
|
|
|
currentPage := func(){setNetworkUserStatisticsPage(window, identityType, previousPage)}
|
|
|
|
title := getPageTitleCentered(identityType + " Statistics")
|
|
|
|
backButton := getBackButtonCentered(previousPage)
|
|
|
|
description1 := getLabelCentered("Below are statistics about " + identityType + " profiles and users.")
|
|
|
|
description2 := widget.NewLabel("Be aware that these statistics may not represent the entire Seekia network.")
|
|
|
|
description2HelpButton := widget.NewButtonWithIcon("", theme.QuestionIcon(), func(){
|
|
setNetworkStatisticsInaccuracyWarningPage(window, currentPage)
|
|
})
|
|
|
|
description2Row := container.NewHBox(layout.NewSpacer(), description2, description2HelpButton, layout.NewSpacer())
|
|
|
|
profileHashesList, err := badgerDatabase.GetAllProfileHashes(identityType)
|
|
if (err != nil) {
|
|
setErrorEncounteredPage(window, err, previousPage)
|
|
return
|
|
}
|
|
|
|
numberOfUserProfiles := len(profileHashesList)
|
|
|
|
profileIdentityHashesList, err := badgerDatabase.GetAllProfileIdentityHashes(identityType)
|
|
if (err != nil){
|
|
setErrorEncounteredPage(window, err, previousPage)
|
|
return
|
|
}
|
|
|
|
numberOfUserIdentities := len(profileIdentityHashesList)
|
|
|
|
numberOfUserProfilesString := helpers.ConvertIntToString(numberOfUserProfiles)
|
|
numberOfUserProfilesLabel := widget.NewLabel("Number of " + identityType + " Profiles:")
|
|
numberOfUserProfilesText := getBoldLabel(numberOfUserProfilesString)
|
|
numberOfUserProfilesRow := container.NewHBox(layout.NewSpacer(), numberOfUserProfilesLabel, numberOfUserProfilesText, layout.NewSpacer())
|
|
|
|
numberOfUserIdentitiesString := helpers.ConvertIntToString(numberOfUserIdentities)
|
|
numberOfUserIdentitiesLabel := widget.NewLabel("Number of " + identityType + " Identities:")
|
|
numberOfUserIdentitiesText := getBoldLabel(numberOfUserIdentitiesString)
|
|
numberOfUserIdentitiesRow := container.NewHBox(layout.NewSpacer(), numberOfUserIdentitiesLabel, numberOfUserIdentitiesText, layout.NewSpacer())
|
|
|
|
//TODO: add % of users who are disabled.
|
|
//TODO: Add more statistics
|
|
|
|
getIdentityTypeDefaultAttribute := func()string{
|
|
|
|
if (identityType == "Mate"){
|
|
return "Age"
|
|
}
|
|
if (identityType == "Host"){
|
|
return "SeekiaVersion"
|
|
}
|
|
// identityType == "Moderator"
|
|
return "IdentityScore"
|
|
}
|
|
|
|
identityTypeDefaultAttribute := getIdentityTypeDefaultAttribute()
|
|
|
|
attributeStatisticsButton := getWidgetCentered(widget.NewButtonWithIcon("View Attribute Statistics", theme.VisibilityIcon(), func(){
|
|
setViewUserAttributeStatisticsPage_BarChart(window, identityType, identityTypeDefaultAttribute, "Number Of Users", " users", true, false, false, nil, false, nil, nil, currentPage)
|
|
}))
|
|
|
|
page := container.NewVBox(title, backButton, widget.NewSeparator(), description1, description2Row, widget.NewSeparator(), numberOfUserProfilesRow, numberOfUserIdentitiesRow, attributeStatisticsButton)
|
|
|
|
setPageContent(page, window)
|
|
}
|
|
|
|
func setViewUserAttributeStatisticsPage_BarChart(
|
|
window fyne.Window,
|
|
identityType string,
|
|
xAxisAttributeName string,
|
|
yAxisAttribute string,
|
|
yAxisUnits string,
|
|
showYAxisPercentage bool,
|
|
statisticsReady bool,
|
|
anyUsersExist bool,
|
|
statisticsDatumsList []statisticsDatum.StatisticsDatum,
|
|
groupingPerformed bool,
|
|
groupedStatisticsDatumsList []statisticsDatum.StatisticsDatum,
|
|
chartImage image.Image,
|
|
previousPage func()){
|
|
|
|
currentPage := func(){setViewUserAttributeStatisticsPage_BarChart(window, identityType, xAxisAttributeName, yAxisAttribute, yAxisUnits, showYAxisPercentage, statisticsReady, anyUsersExist, statisticsDatumsList, groupingPerformed, groupedStatisticsDatumsList, chartImage, previousPage)}
|
|
|
|
pageIdentifier, err := helpers.GetNewRandomHexString(16)
|
|
if (err != nil) {
|
|
setErrorEncounteredPage(window, err, previousPage)
|
|
return
|
|
}
|
|
|
|
appMemory.SetMemoryEntry("CurrentViewedPage", pageIdentifier)
|
|
|
|
checkIfPageHasChangedFunction := func()bool{
|
|
exists, currentViewedPage := appMemory.GetMemoryEntry("CurrentViewedPage")
|
|
if (exists == true && currentViewedPage == pageIdentifier){
|
|
return false
|
|
}
|
|
return true
|
|
}
|
|
|
|
title := getPageTitleCentered("User Attribute Statistics - Bar Chart")
|
|
|
|
backButton := getBackButtonCentered(previousPage)
|
|
|
|
identityTypeLabel := getBoldLabelCentered("Identity Type")
|
|
|
|
handleIdentityTypeSelectFunction := func(newIdentityType string){
|
|
|
|
if (newIdentityType == identityType){
|
|
return
|
|
}
|
|
if (newIdentityType == "Mate"){
|
|
|
|
setViewUserAttributeStatisticsPage_BarChart(window, "Mate", "Age", "Number Of Users", " Users", true, false, false, nil, false, nil, nil, previousPage)
|
|
return
|
|
}
|
|
if (newIdentityType == "Host"){
|
|
setViewUserAttributeStatisticsPage_BarChart(window, "Host", "SeekiaVersion", "Number Of Users", " Users", true, false, false, nil, false, nil, nil, previousPage)
|
|
return
|
|
}
|
|
// newIdentityType == "Moderator"
|
|
setViewUserAttributeStatisticsPage_BarChart(window, "Moderator", "IdentityScore", "Number Of Users", " Users", true, false, false, nil, false, nil, nil, previousPage)
|
|
}
|
|
|
|
identityTypesList := []string{"Mate", "Host", "Moderator"}
|
|
|
|
identityTypeSelector := widget.NewSelect(identityTypesList, handleIdentityTypeSelectFunction)
|
|
identityTypeSelector.Selected = identityType
|
|
|
|
identityTypeColumn := container.NewVBox(identityTypeLabel, identityTypeSelector)
|
|
|
|
chartTypeLabel := getBoldLabelCentered("Chart Type")
|
|
|
|
chartTypesList := []string{"Bar Chart", "Donut Chart"}
|
|
handleChartTypeSelectFunction := func(newChartType string){
|
|
if (newChartType == "Bar Chart"){
|
|
return
|
|
}
|
|
// newChartType == "Donut Chart"
|
|
setViewUserAttributeStatisticsPage_DonutChart(window, identityType, xAxisAttributeName, false, false, nil, false, nil, nil, previousPage)
|
|
}
|
|
|
|
chartTypeSelector := widget.NewSelect(chartTypesList, handleChartTypeSelectFunction)
|
|
chartTypeSelector.Selected = "Bar Chart"
|
|
|
|
chartTypeColumn := container.NewVBox(chartTypeLabel, chartTypeSelector)
|
|
|
|
xAxisAttributeTitle, xAxisIsNumerical, formatXAxisValuesFunction, xAxisUnits, unknownXAxisValuesTextTranslated, err := attributeDisplay.GetProfileAttributeDisplayInfo(xAxisAttributeName)
|
|
if (err != nil){
|
|
setErrorEncounteredPage(window, err, previousPage)
|
|
return
|
|
}
|
|
|
|
xAxisLabel := getBoldLabelCentered("X-Axis")
|
|
changeXAxisAttributeButton := widget.NewButton(xAxisAttributeTitle, func(){
|
|
|
|
currentPageWithNewAttributeFunction := func(newXAxisAttributeName string){
|
|
setViewUserAttributeStatisticsPage_BarChart(window, identityType, newXAxisAttributeName, yAxisAttribute, yAxisUnits, showYAxisPercentage, false, false, nil, false, nil, nil, previousPage)
|
|
}
|
|
|
|
setViewUserAttributeStatistics_ChooseXAxisAttributePage(window, identityType, currentPageWithNewAttributeFunction, currentPage)
|
|
})
|
|
|
|
xAxisColumn := container.NewVBox(xAxisLabel, changeXAxisAttributeButton)
|
|
|
|
yAxisLabel := getBoldLabelCentered("Y-Axis")
|
|
changeYAxisAttributeButton := widget.NewButton(translate(yAxisAttribute), func(){
|
|
|
|
currentPageWithNewAttributeFunction := func(newYAxisAttribute string, newYAxisUnits string, showYAxisPercentage bool){
|
|
setViewUserAttributeStatisticsPage_BarChart(window, identityType, xAxisAttributeName, newYAxisAttribute, newYAxisUnits, showYAxisPercentage, false, false, nil, false, nil, nil, previousPage)
|
|
}
|
|
|
|
setViewUserAttributeStatistics_ChooseYAxisAttributePage(window, identityType, currentPageWithNewAttributeFunction, currentPage)
|
|
})
|
|
|
|
yAxisColumn := container.NewVBox(yAxisLabel, changeYAxisAttributeButton)
|
|
|
|
chartSettingsRow := container.NewHBox(layout.NewSpacer(), widget.NewSeparator(), identityTypeColumn, widget.NewSeparator(), chartTypeColumn, widget.NewSeparator(), xAxisColumn, widget.NewSeparator(), yAxisColumn, widget.NewSeparator(), layout.NewSpacer())
|
|
|
|
if (statisticsReady == true){
|
|
|
|
if (anyUsersExist == false){
|
|
|
|
description1 := getBoldLabelCentered("No " + identityType + " profiles exist.")
|
|
description2 := getLabelCentered("No statistics are available to show.")
|
|
description3 := getLabelCentered("You must wait for profiles to be downloaded.")
|
|
|
|
page := container.NewVBox(title, backButton, widget.NewSeparator(), chartSettingsRow, widget.NewSeparator(), description1, description2, description3)
|
|
|
|
setPageContent(page, window)
|
|
return
|
|
}
|
|
|
|
viewDataButton := widget.NewButtonWithIcon("View Data", theme.ListIcon(), func(){
|
|
setViewUserStatisticsDataPage(window, xAxisAttributeTitle, yAxisAttribute, showYAxisPercentage, statisticsDatumsList, groupingPerformed, groupedStatisticsDatumsList, true, xAxisUnits, yAxisUnits, currentPage)
|
|
})
|
|
|
|
viewFullscreenButton := widget.NewButtonWithIcon("View Fullscreen", theme.ZoomInIcon(), func(){
|
|
setViewFullpageImagePage(window, chartImage, currentPage)
|
|
})
|
|
|
|
warningButton := widget.NewButtonWithIcon("Warning", theme.WarningIcon(), func(){
|
|
setNetworkStatisticsInaccuracyWarningPage(window, currentPage)
|
|
})
|
|
|
|
chartCompleteButtonsRow := getContainerCentered(container.NewGridWithRows(1, viewDataButton, viewFullscreenButton, warningButton))
|
|
|
|
header := container.NewVBox(title, backButton, widget.NewSeparator(), chartSettingsRow, widget.NewSeparator(), chartCompleteButtonsRow, widget.NewSeparator())
|
|
|
|
chartFyneImage := canvas.NewImageFromImage(chartImage)
|
|
chartFyneImage.FillMode = canvas.ImageFillContain
|
|
|
|
page := container.NewBorder(header, nil, nil, nil, chartFyneImage)
|
|
|
|
setPageContent(page, window)
|
|
return
|
|
}
|
|
|
|
loadingTextBinding := binding.NewString()
|
|
loadingTextLabel := widget.NewLabelWithData(loadingTextBinding)
|
|
loadingTextLabel.TextStyle = getFyneTextStyle_Bold()
|
|
loadingTextLabelCentered := container.NewCenter(loadingTextLabel)
|
|
|
|
appNetworkType, err := getAppNetworkType.GetAppNetworkType()
|
|
if (err != nil) {
|
|
setErrorEncounteredPage(window, err, previousPage)
|
|
return
|
|
}
|
|
|
|
createChartAndRefreshPageFunction := func(){
|
|
|
|
var functionCompleteBoolMutex sync.RWMutex
|
|
functionCompleteBool := false
|
|
|
|
updateLoadingBindingFunction := func(){
|
|
|
|
secondsElapsed := 0
|
|
|
|
for{
|
|
|
|
if (secondsElapsed%3 == 0){
|
|
loadingTextBinding.Set("Loading Statistics.")
|
|
} else if (secondsElapsed%3 == 1){
|
|
loadingTextBinding.Set("Loading Statistics..")
|
|
} else {
|
|
loadingTextBinding.Set("Loading Statistics...")
|
|
}
|
|
pageHasChanged := checkIfPageHasChangedFunction()
|
|
if (pageHasChanged == true){
|
|
return
|
|
}
|
|
|
|
functionCompleteBoolMutex.RLock()
|
|
functionIsComplete := functionCompleteBool
|
|
functionCompleteBoolMutex.RUnlock()
|
|
if (functionIsComplete == true){
|
|
return
|
|
}
|
|
|
|
secondsElapsed += 1
|
|
time.Sleep(time.Second)
|
|
}
|
|
}
|
|
|
|
go updateLoadingBindingFunction()
|
|
|
|
totalAnalyzedUsers, statisticsDatumsList, groupingPerformed, groupedStatisticsDatumsList, formatYAxisValuesFunction, err := userStatistics.GetUserStatisticsDatumsLists_BarChart(identityType, appNetworkType, xAxisAttributeName, xAxisIsNumerical, formatXAxisValuesFunction, unknownXAxisValuesTextTranslated, yAxisAttribute)
|
|
if (err != nil) {
|
|
|
|
functionCompleteBoolMutex.Lock()
|
|
functionCompleteBool = true
|
|
functionCompleteBoolMutex.Unlock()
|
|
|
|
pageHasChanged := checkIfPageHasChangedFunction()
|
|
if (pageHasChanged == false){
|
|
setErrorEncounteredPage(window, err, previousPage)
|
|
}
|
|
return
|
|
}
|
|
|
|
if (len(statisticsDatumsList) == 0){
|
|
|
|
functionCompleteBoolMutex.Lock()
|
|
functionCompleteBool = true
|
|
functionCompleteBoolMutex.Unlock()
|
|
|
|
pageHasChanged := checkIfPageHasChangedFunction()
|
|
if (pageHasChanged == false){
|
|
setViewUserAttributeStatisticsPage_BarChart(window, identityType, xAxisAttributeName, yAxisAttribute, yAxisUnits, showYAxisPercentage, true, false, nil, false, nil, nil, previousPage)
|
|
}
|
|
return
|
|
}
|
|
|
|
getChartStatisticsDatumsList := func()[]statisticsDatum.StatisticsDatum{
|
|
if (groupingPerformed == false){
|
|
return statisticsDatumsList
|
|
}
|
|
return groupedStatisticsDatumsList
|
|
}
|
|
|
|
chartStatisticsDatumsList := getChartStatisticsDatumsList()
|
|
|
|
getChartTitle := func()string{
|
|
|
|
totalAnalyzedUsersString := helpers.ConvertIntToString(totalAnalyzedUsers)
|
|
|
|
chartTitle := identityType + " Statistics: " + xAxisAttributeTitle
|
|
|
|
if (xAxisUnits != ""){
|
|
|
|
xAxisUnitsTrimmed := strings.TrimSpace(xAxisUnits)
|
|
|
|
chartTitle += " (" + xAxisUnitsTrimmed + ")"
|
|
}
|
|
|
|
chartTitle += " by " + yAxisAttribute
|
|
|
|
if (yAxisUnits != "" && yAxisUnits != translate(" users")){
|
|
|
|
yAxisUnitsTrimmed := strings.TrimSpace(yAxisUnits)
|
|
|
|
chartTitle += " (" + yAxisUnitsTrimmed + ")"
|
|
}
|
|
|
|
chartTitle += " - " + totalAnalyzedUsersString + " Users"
|
|
|
|
return chartTitle
|
|
}
|
|
|
|
chartTitle := getChartTitle()
|
|
|
|
newChartImage, err := createCharts.CreateBarChart(chartTitle, chartStatisticsDatumsList, formatYAxisValuesFunction, true, yAxisUnits)
|
|
if (err != nil) {
|
|
|
|
functionCompleteBoolMutex.Lock()
|
|
functionCompleteBool = true
|
|
functionCompleteBoolMutex.Unlock()
|
|
|
|
pageHasChanged := checkIfPageHasChangedFunction()
|
|
if (pageHasChanged == false){
|
|
setErrorEncounteredPage(window, err, previousPage)
|
|
}
|
|
return
|
|
}
|
|
|
|
functionCompleteBoolMutex.Lock()
|
|
functionCompleteBool = true
|
|
functionCompleteBoolMutex.Unlock()
|
|
|
|
pageHasChanged := checkIfPageHasChangedFunction()
|
|
if (pageHasChanged == false){
|
|
setViewUserAttributeStatisticsPage_BarChart(window, identityType, xAxisAttributeName, yAxisAttribute, yAxisUnits, showYAxisPercentage, true, true, statisticsDatumsList, groupingPerformed, groupedStatisticsDatumsList, newChartImage, previousPage)
|
|
}
|
|
}
|
|
|
|
header := container.NewVBox(title, backButton, widget.NewSeparator(), chartSettingsRow, widget.NewSeparator())
|
|
|
|
page := container.NewBorder(header, nil, nil, nil, loadingTextLabelCentered)
|
|
|
|
setPageContent(page, window)
|
|
|
|
go createChartAndRefreshPageFunction()
|
|
}
|
|
|
|
|
|
func setViewUserAttributeStatisticsPage_DonutChart(
|
|
window fyne.Window,
|
|
identityType string,
|
|
attributeName string,
|
|
statisticsReady bool,
|
|
anyUsersExist bool,
|
|
statisticsDatumsList []statisticsDatum.StatisticsDatum,
|
|
groupingPerformed bool,
|
|
groupedStatisticsDatumsList []statisticsDatum.StatisticsDatum,
|
|
chartImage image.Image,
|
|
previousPage func()){
|
|
|
|
currentPage := func(){setViewUserAttributeStatisticsPage_DonutChart(window, identityType, attributeName, statisticsReady, anyUsersExist, statisticsDatumsList, groupingPerformed, groupedStatisticsDatumsList, chartImage, previousPage)}
|
|
|
|
pageIdentifier, err := helpers.GetNewRandomHexString(16)
|
|
if (err != nil) {
|
|
setErrorEncounteredPage(window, err, previousPage)
|
|
return
|
|
}
|
|
|
|
appMemory.SetMemoryEntry("CurrentViewedPage", pageIdentifier)
|
|
|
|
checkIfPageHasChangedFunction := func()bool{
|
|
exists, currentViewedPage := appMemory.GetMemoryEntry("CurrentViewedPage")
|
|
if (exists == true && currentViewedPage == pageIdentifier){
|
|
return false
|
|
}
|
|
return true
|
|
}
|
|
|
|
title := getPageTitleCentered("User Attribute Statistics - Donut Chart")
|
|
|
|
backButton := getBackButtonCentered(previousPage)
|
|
|
|
identityTypeLabel := getBoldLabelCentered("Identity Type")
|
|
|
|
handleIdentityTypeSelectFunction := func(newIdentityType string){
|
|
|
|
if (newIdentityType == identityType){
|
|
return
|
|
}
|
|
if (newIdentityType == "Mate"){
|
|
|
|
setViewUserAttributeStatisticsPage_DonutChart(window, "Mate", "Age", false, false, nil, false, nil, nil, previousPage)
|
|
return
|
|
}
|
|
if (newIdentityType == "Host"){
|
|
setViewUserAttributeStatisticsPage_DonutChart(window, "Host", "SeekiaVersion", false, false, nil, false, nil, nil, previousPage)
|
|
return
|
|
}
|
|
// newIdentityType == "Moderator"
|
|
setViewUserAttributeStatisticsPage_DonutChart(window, "Moderator", "IdentityScore", false, false, nil, false, nil, nil, previousPage)
|
|
}
|
|
|
|
identityTypesList := []string{"Mate", "Host", "Moderator"}
|
|
|
|
identityTypeSelector := widget.NewSelect(identityTypesList, handleIdentityTypeSelectFunction)
|
|
identityTypeSelector.Selected = identityType
|
|
|
|
identityTypeColumn := container.NewVBox(identityTypeLabel, identityTypeSelector)
|
|
|
|
chartTypeLabel := getBoldLabelCentered("Chart Type:")
|
|
|
|
chartTypesList := []string{"Bar Chart", "Donut Chart"}
|
|
handleSelectFunction := func(newType string){
|
|
if (newType == "Donut Chart"){
|
|
return
|
|
}
|
|
if (newType == "Bar Chart"){
|
|
setViewUserAttributeStatisticsPage_BarChart(window, identityType, attributeName, "Number Of Users", " Users", true, false, false, nil, false, nil, nil, previousPage)
|
|
}
|
|
}
|
|
chartTypeSelector := widget.NewSelect(chartTypesList, handleSelectFunction)
|
|
chartTypeSelector.Selected = "Donut Chart"
|
|
|
|
chartTypeColumn := container.NewVBox(chartTypeLabel, chartTypeSelector)
|
|
|
|
attributeTitle, attributeIsNumerical, formatAttributeValuesFunction, attributeUnits, unknownValuesTextTranslated, err := attributeDisplay.GetProfileAttributeDisplayInfo(attributeName)
|
|
if (err != nil){
|
|
setErrorEncounteredPage(window, err, previousPage)
|
|
return
|
|
}
|
|
|
|
attributeLabel := getBoldLabelCentered("Attribute:")
|
|
changeAttributeButton := widget.NewButton(attributeTitle, func(){
|
|
currentPageWithNewAttributeFunction := func(newAttributeName string){
|
|
setViewUserAttributeStatisticsPage_DonutChart(window, identityType, newAttributeName, false, false, nil, false, nil, nil, previousPage)
|
|
}
|
|
setViewUserAttributeStatistics_ChooseXAxisAttributePage(window, identityType, currentPageWithNewAttributeFunction, currentPage)
|
|
})
|
|
attributeColumn := container.NewVBox(attributeLabel, changeAttributeButton)
|
|
|
|
chartSettingsRow := container.NewHBox(layout.NewSpacer(), widget.NewSeparator(), identityTypeColumn, widget.NewSeparator(), chartTypeColumn, widget.NewSeparator(), attributeColumn, widget.NewSeparator(), layout.NewSpacer())
|
|
|
|
if (statisticsReady == true){
|
|
|
|
if (anyUsersExist == false){
|
|
|
|
description1 := getBoldLabelCentered("No " + identityType + " profiles exist.")
|
|
description2 := getLabelCentered("No statistics are available to show.")
|
|
description3 := getLabelCentered("You must wait for profiles to be downloaded.")
|
|
|
|
page := container.NewVBox(title, backButton, widget.NewSeparator(), chartSettingsRow, widget.NewSeparator(), description1, description2, description3)
|
|
|
|
setPageContent(page, window)
|
|
return
|
|
}
|
|
|
|
viewDataButton := widget.NewButtonWithIcon("View Data", theme.ListIcon(), func(){
|
|
|
|
setViewUserStatisticsDataPage(window, attributeTitle, "Number Of Users", true, statisticsDatumsList, groupingPerformed, groupedStatisticsDatumsList, true, attributeUnits, "Users", currentPage)
|
|
})
|
|
|
|
viewFullscreenButton := widget.NewButtonWithIcon("View Fullscreen", theme.ZoomInIcon(), func(){
|
|
setViewFullpageImagePage(window, chartImage, currentPage)
|
|
})
|
|
|
|
warningButton := widget.NewButtonWithIcon("Warning", theme.WarningIcon(), func(){
|
|
setNetworkStatisticsInaccuracyWarningPage(window, currentPage)
|
|
})
|
|
|
|
chartCompleteButtonsRow := getContainerCentered(container.NewGridWithRows(1, viewDataButton, viewFullscreenButton, warningButton))
|
|
|
|
header := container.NewVBox(title, backButton, widget.NewSeparator(), chartSettingsRow, widget.NewSeparator(), chartCompleteButtonsRow, widget.NewSeparator())
|
|
|
|
chartFyneImage := canvas.NewImageFromImage(chartImage)
|
|
chartFyneImage.FillMode = canvas.ImageFillContain
|
|
|
|
page := container.NewBorder(header, nil, nil, nil, chartFyneImage)
|
|
setPageContent(page, window)
|
|
return
|
|
}
|
|
|
|
loadingTextBinding := binding.NewString()
|
|
loadingTextLabel := widget.NewLabelWithData(loadingTextBinding)
|
|
loadingTextLabel.TextStyle = getFyneTextStyle_Bold()
|
|
loadingTextLabelCentered := container.NewCenter(loadingTextLabel)
|
|
|
|
appNetworkType, err := getAppNetworkType.GetAppNetworkType()
|
|
if (err != nil) {
|
|
setErrorEncounteredPage(window, err, previousPage)
|
|
return
|
|
}
|
|
|
|
createChartAndRefreshPageFunction := func(){
|
|
|
|
var functionCompleteBoolMutex sync.RWMutex
|
|
functionCompleteBool := false
|
|
|
|
updateLoadingBindingFunction := func(){
|
|
|
|
secondsElapsed := 0
|
|
|
|
for{
|
|
|
|
if (secondsElapsed%3 == 0){
|
|
loadingTextBinding.Set("Loading Statistics.")
|
|
} else if (secondsElapsed%3 == 1){
|
|
loadingTextBinding.Set("Loading Statistics..")
|
|
} else {
|
|
loadingTextBinding.Set("Loading Statistics...")
|
|
}
|
|
pageHasChanged := checkIfPageHasChangedFunction()
|
|
if (pageHasChanged == true){
|
|
return
|
|
}
|
|
|
|
functionCompleteBoolMutex.RLock()
|
|
functionIsComplete := functionCompleteBool
|
|
functionCompleteBoolMutex.RUnlock()
|
|
if (functionIsComplete == true){
|
|
return
|
|
}
|
|
|
|
secondsElapsed += 1
|
|
time.Sleep(time.Second)
|
|
}
|
|
}
|
|
|
|
go updateLoadingBindingFunction()
|
|
|
|
totalAnalyzedUsers, statisticsDatumsList, groupingPerformed, groupedStatisticsDatumsList, err := userStatistics.GetUserStatisticsDatumsLists_DonutChart(identityType, appNetworkType, attributeName, attributeIsNumerical, formatAttributeValuesFunction, unknownValuesTextTranslated)
|
|
if (err != nil) {
|
|
|
|
functionCompleteBoolMutex.Lock()
|
|
functionCompleteBool = true
|
|
functionCompleteBoolMutex.Unlock()
|
|
|
|
pageHasChanged := checkIfPageHasChangedFunction()
|
|
if (pageHasChanged == false){
|
|
setErrorEncounteredPage(window, err, previousPage)
|
|
}
|
|
return
|
|
}
|
|
|
|
if (len(statisticsDatumsList) == 0){
|
|
|
|
functionCompleteBoolMutex.Lock()
|
|
functionCompleteBool = true
|
|
functionCompleteBoolMutex.Unlock()
|
|
|
|
pageHasChanged := checkIfPageHasChangedFunction()
|
|
if (pageHasChanged == false){
|
|
setViewUserAttributeStatisticsPage_DonutChart(window, identityType, attributeName, true, false, nil, false, nil, nil, previousPage)
|
|
}
|
|
return
|
|
}
|
|
|
|
getChartStatisticsDatumsList := func()[]statisticsDatum.StatisticsDatum{
|
|
if (groupingPerformed == false){
|
|
return statisticsDatumsList
|
|
}
|
|
return groupedStatisticsDatumsList
|
|
}
|
|
|
|
chartStatisticsDatumsList := getChartStatisticsDatumsList()
|
|
|
|
getChartTitle := func()string{
|
|
|
|
totalAnalyzedUsersString := helpers.ConvertIntToString(totalAnalyzedUsers)
|
|
|
|
chartTitle := identityType + " Statistics: " + attributeTitle
|
|
|
|
if (attributeUnits != ""){
|
|
|
|
attributeUnitsTrimmed := strings.TrimPrefix(attributeUnits, " ")
|
|
|
|
chartTitle += " (" + attributeUnitsTrimmed + ")"
|
|
}
|
|
|
|
chartTitle += " - " + totalAnalyzedUsersString + " Users"
|
|
|
|
return chartTitle
|
|
}
|
|
|
|
chartTitle := getChartTitle()
|
|
|
|
newChartImage, err := createCharts.CreateDonutChart(chartTitle, chartStatisticsDatumsList)
|
|
if (err != nil){
|
|
|
|
functionCompleteBoolMutex.Lock()
|
|
functionCompleteBool = true
|
|
functionCompleteBoolMutex.Unlock()
|
|
|
|
pageHasChanged := checkIfPageHasChangedFunction()
|
|
if (pageHasChanged == false){
|
|
setErrorEncounteredPage(window, err, previousPage)
|
|
}
|
|
return
|
|
}
|
|
|
|
functionCompleteBoolMutex.Lock()
|
|
functionCompleteBool = true
|
|
functionCompleteBoolMutex.Unlock()
|
|
|
|
pageHasChanged := checkIfPageHasChangedFunction()
|
|
if (pageHasChanged == false){
|
|
setViewUserAttributeStatisticsPage_DonutChart(window, identityType, attributeName, true, true, statisticsDatumsList, groupingPerformed, groupedStatisticsDatumsList, newChartImage, previousPage)
|
|
}
|
|
}
|
|
|
|
header := container.NewVBox(title, backButton, widget.NewSeparator(), chartSettingsRow, widget.NewSeparator())
|
|
page := container.NewBorder(header, nil, nil, nil, loadingTextLabelCentered)
|
|
|
|
setPageContent(page, window)
|
|
|
|
go createChartAndRefreshPageFunction()
|
|
}
|
|
|
|
|
|
//Inputs:
|
|
// -fyne.Window
|
|
// -string: Profile Type
|
|
// -func(attributeName string)
|
|
// -func(): Previous page
|
|
func setViewUserAttributeStatistics_ChooseXAxisAttributePage(window fyne.Window, profileType string, viewStatisticsPageWithNewAttribute func(string), previousPage func()){
|
|
|
|
title := getPageTitleCentered(translate("Choose Attribute"))
|
|
|
|
backButton := getBackButtonCentered(previousPage)
|
|
|
|
attributesToShowList := make([]string, 0)
|
|
|
|
addAttributeToListFunction := func(attributeName string){
|
|
attributesToShowList = append(attributesToShowList, attributeName)
|
|
}
|
|
|
|
if (profileType == "Mate"){
|
|
|
|
addAttributeToListFunction("Age")
|
|
addAttributeToListFunction("Height")
|
|
addAttributeToListFunction("Sex")
|
|
addAttributeToListFunction("Sexuality")
|
|
addAttributeToListFunction("Distance")
|
|
addAttributeToListFunction("WealthInGold")
|
|
}
|
|
|
|
addAttributeToListFunction("ProfileLanguage")
|
|
|
|
if (profileType == "Mate" || profileType == "Moderator"){
|
|
addAttributeToListFunction("HasMessagedMe")
|
|
addAttributeToListFunction("IHaveMessaged")
|
|
}
|
|
|
|
if (profileType == "Mate"){
|
|
addAttributeToListFunction("HasRejectedMe")
|
|
addAttributeToListFunction("IsLiked")
|
|
addAttributeToListFunction("IsIgnored")
|
|
}
|
|
|
|
addAttributeToListFunction("IsMyContact")
|
|
|
|
if (profileType == "Mate"){
|
|
addAttributeToListFunction("PrimaryLocationCountry")
|
|
addAttributeToListFunction("BodyFat")
|
|
addAttributeToListFunction("BodyMuscle")
|
|
addAttributeToListFunction("HairColor")
|
|
addAttributeToListFunction("HairTexture")
|
|
addAttributeToListFunction("EyeColor")
|
|
addAttributeToListFunction("SkinColor")
|
|
addAttributeToListFunction("RacialSimilarity")
|
|
addAttributeToListFunction("EyeColorSimilarity")
|
|
addAttributeToListFunction("EyeColorGenesSimilarity")
|
|
addAttributeToListFunction("HairColorSimilarity")
|
|
addAttributeToListFunction("HairColorGenesSimilarity")
|
|
addAttributeToListFunction("SkinColorSimilarity")
|
|
addAttributeToListFunction("SkinColorGenesSimilarity")
|
|
addAttributeToListFunction("HairTextureSimilarity")
|
|
addAttributeToListFunction("HairTextureGenesSimilarity")
|
|
addAttributeToListFunction("FacialStructureGenesSimilarity")
|
|
addAttributeToListFunction("23andMe_AncestralSimilarity")
|
|
addAttributeToListFunction("23andMe_MaternalHaplogroupSimilarity")
|
|
addAttributeToListFunction("23andMe_PaternalHaplogroupSimilarity")
|
|
addAttributeToListFunction("HasHIV")
|
|
addAttributeToListFunction("HasGenitalHerpes")
|
|
addAttributeToListFunction("GenderIdentity")
|
|
addAttributeToListFunction("23andMe_MaternalHaplogroup")
|
|
addAttributeToListFunction("23andMe_PaternalHaplogroup")
|
|
addAttributeToListFunction("23andMe_NeanderthalVariants")
|
|
addAttributeToListFunction("FruitRating")
|
|
addAttributeToListFunction("VegetablesRating")
|
|
addAttributeToListFunction("NutsRating")
|
|
addAttributeToListFunction("GrainsRating")
|
|
addAttributeToListFunction("DairyRating")
|
|
addAttributeToListFunction("SeafoodRating")
|
|
addAttributeToListFunction("BeefRating")
|
|
addAttributeToListFunction("PorkRating")
|
|
addAttributeToListFunction("PoultryRating")
|
|
addAttributeToListFunction("EggsRating")
|
|
addAttributeToListFunction("BeansRating")
|
|
addAttributeToListFunction("Fame")
|
|
addAttributeToListFunction("AlcoholFrequency")
|
|
addAttributeToListFunction("TobaccoFrequency")
|
|
addAttributeToListFunction("CannabisFrequency")
|
|
addAttributeToListFunction("PetsRating")
|
|
addAttributeToListFunction("DogsRating")
|
|
addAttributeToListFunction("CatsRating")
|
|
addAttributeToListFunction("OffspringProbabilityOfAnyMonogenicDisease")
|
|
addAttributeToListFunction("TotalPolygenicDiseaseRiskScore")
|
|
addAttributeToListFunction("OffspringTotalPolygenicDiseaseRiskScore")
|
|
}
|
|
|
|
buttonsGrid := container.NewGridWithColumns(1)
|
|
|
|
for _, attributeName := range attributesToShowList{
|
|
|
|
attributeTitle, _, _, _, _, err := attributeDisplay.GetProfileAttributeDisplayInfo(attributeName)
|
|
if (err != nil){
|
|
setErrorEncounteredPage(window, err, previousPage)
|
|
return
|
|
}
|
|
|
|
attributeButton := widget.NewButton(attributeTitle, func(){
|
|
viewStatisticsPageWithNewAttribute(attributeName)
|
|
})
|
|
|
|
buttonsGrid.Add(attributeButton)
|
|
}
|
|
|
|
buttonsGridCentered := getContainerCentered(buttonsGrid)
|
|
|
|
page := container.NewVBox(title, backButton, widget.NewSeparator(), buttonsGridCentered)
|
|
|
|
setPageContent(page, window)
|
|
}
|
|
|
|
//Inputs:
|
|
// -fyne.Window
|
|
// -string: Profile type
|
|
// -func(attributeName string, yAxisUnits string, showYAxisPercentage bool)
|
|
// -func(): Previous page
|
|
func setViewUserAttributeStatistics_ChooseYAxisAttributePage(window fyne.Window, profileType string, viewStatisticsPageWithNewAttribute func(string, string, bool), previousPage func()){
|
|
|
|
title := getPageTitleCentered("Choose Y-Axis Attribute")
|
|
|
|
backButton := getBackButtonCentered(previousPage)
|
|
|
|
numberOfUsersButton := widget.NewButton("Number Of Users", func(){
|
|
viewStatisticsPageWithNewAttribute("Number Of Users", translate(" Users"), true)
|
|
})
|
|
|
|
buttonsGrid := container.NewGridWithColumns(1, numberOfUsersButton)
|
|
|
|
if (profileType == "Mate"){
|
|
|
|
averageHeightButton := widget.NewButton("Average Height", func(){
|
|
viewStatisticsPageWithNewAttribute("Average Height", translate(" Centimeters"), false)
|
|
})
|
|
buttonsGrid.Add(averageHeightButton)
|
|
|
|
averageAgeButton := widget.NewButton("Average Age", func(){
|
|
viewStatisticsPageWithNewAttribute("Average Age", translate(" Years Old"), false)
|
|
})
|
|
buttonsGrid.Add(averageAgeButton)
|
|
|
|
|
|
getAppCurrency := func()(string, error){
|
|
|
|
exists, appCurrencyCode, err := globalSettings.GetSetting("Currency")
|
|
if (err != nil) { return "", err }
|
|
if (exists == false){
|
|
return "USD", nil
|
|
}
|
|
return appCurrencyCode, nil
|
|
}
|
|
appCurrencyCode, err := getAppCurrency()
|
|
if (err != nil) {
|
|
setErrorEncounteredPage(window, err, previousPage)
|
|
return
|
|
}
|
|
|
|
averageWealthButton := widget.NewButton("Average Wealth", func(){
|
|
|
|
wealthUnits := " " + appCurrencyCode
|
|
|
|
viewStatisticsPageWithNewAttribute("Average Wealth", wealthUnits, false)
|
|
})
|
|
buttonsGrid.Add(averageWealthButton)
|
|
|
|
averageNeanderthalVariantsButton := widget.NewButton("Average 23andMe Neanderthal Variants", func(){
|
|
viewStatisticsPageWithNewAttribute("Average 23andMe Neanderthal Variants", translate(" Variants"), false)
|
|
})
|
|
buttonsGrid.Add(averageNeanderthalVariantsButton)
|
|
|
|
averageBodyFatButton := widget.NewButton("Average Body Fat", func(){
|
|
viewStatisticsPageWithNewAttribute("Average Body Fat", "/4", false)
|
|
})
|
|
buttonsGrid.Add(averageBodyFatButton)
|
|
|
|
averageBodyMuscleButton := widget.NewButton("Average Body Muscle", func(){
|
|
viewStatisticsPageWithNewAttribute("Average Body Muscle", "/4", false)
|
|
})
|
|
buttonsGrid.Add(averageBodyMuscleButton)
|
|
|
|
oneToTenValueAttributesList := []string{
|
|
"Fruit Rating",
|
|
"Vegetables Rating",
|
|
"Nuts Rating",
|
|
"Grains Rating",
|
|
"Dairy Rating",
|
|
"Seafood Rating",
|
|
"Beef Rating",
|
|
"Pork Rating",
|
|
"Poultry Rating",
|
|
"Eggs Rating",
|
|
"Beans Rating",
|
|
"Fame",
|
|
"Alcohol Frequency",
|
|
"Tobacco Frequency",
|
|
"Cannabis Frequency",
|
|
"Pets Rating",
|
|
"Dogs Rating",
|
|
"Cats Rating",
|
|
}
|
|
|
|
for _, attributeTitle := range oneToTenValueAttributesList{
|
|
|
|
averageAttributeTitle := "Average " + attributeTitle
|
|
|
|
averageAttributeButton := widget.NewButton(averageAttributeTitle, func(){
|
|
viewStatisticsPageWithNewAttribute(averageAttributeTitle, "/10", false)
|
|
})
|
|
buttonsGrid.Add(averageAttributeButton)
|
|
}
|
|
}
|
|
|
|
buttonsGridCentered := getContainerCentered(buttonsGrid)
|
|
|
|
page := container.NewVBox(title, backButton, widget.NewSeparator(), buttonsGridCentered)
|
|
|
|
setPageContent(page, window)
|
|
}
|
|
|
|
|
|
func setViewUserStatisticsDataPage(
|
|
window fyne.Window,
|
|
attributeTitle string,
|
|
rightColumnName string,
|
|
showPercentageColumn bool,
|
|
statisticsDatumsList []statisticsDatum.StatisticsDatum,
|
|
groupingPerformed bool,
|
|
groupedStatisticsDatumsList []statisticsDatum.StatisticsDatum,
|
|
showGroupedStatistics bool,
|
|
attributeColumnUnits string,
|
|
rightColumnUnits string,
|
|
previousPage func()){
|
|
|
|
setLoadingScreen(window, "User Statistics Data", "Loading statistics data...")
|
|
|
|
title := getPageTitleCentered("User Statistics Data")
|
|
|
|
backButton := getBackButtonCentered(previousPage)
|
|
|
|
header := container.NewVBox(title, backButton, widget.NewSeparator())
|
|
|
|
if (groupingPerformed == true){
|
|
|
|
if (showGroupedStatistics == false){
|
|
showDataGroupedButton := getWidgetCentered(widget.NewButton("Show Data Grouped", func(){
|
|
setViewUserStatisticsDataPage(window, attributeTitle, rightColumnName, showPercentageColumn, statisticsDatumsList, true, groupedStatisticsDatumsList, true, attributeColumnUnits, rightColumnUnits, previousPage)
|
|
}))
|
|
|
|
header.Add(showDataGroupedButton)
|
|
} else {
|
|
showDataRawButton := getWidgetCentered(widget.NewButton("Show Data Raw", func(){
|
|
setViewUserStatisticsDataPage(window, attributeTitle, rightColumnName, showPercentageColumn, statisticsDatumsList, true, groupedStatisticsDatumsList, false, attributeColumnUnits, rightColumnUnits, previousPage)
|
|
}))
|
|
|
|
header.Add(showDataRawButton)
|
|
}
|
|
header.Add(widget.NewSeparator())
|
|
}
|
|
|
|
getStatisticsDatumsListToShow := func()[]statisticsDatum.StatisticsDatum{
|
|
if (groupingPerformed == true && showGroupedStatistics == true){
|
|
return groupedStatisticsDatumsList
|
|
}
|
|
return statisticsDatumsList
|
|
}
|
|
|
|
statisticsDatumsToShowList := getStatisticsDatumsListToShow()
|
|
|
|
getStatisticsDataGrid := func()(*fyne.Container, error){
|
|
|
|
allValuesSummed := float64(0)
|
|
|
|
if (showPercentageColumn == true){
|
|
|
|
for _, datum := range statisticsDatumsToShowList{
|
|
|
|
datumValue := datum.Value
|
|
|
|
allValuesSummed += datumValue
|
|
}
|
|
}
|
|
|
|
attributeColumnValuesList := make([]string, 0, len(statisticsDatumsToShowList))
|
|
rightColumnValuesList := make([]string, 0, len(statisticsDatumsToShowList))
|
|
percentageColumnValuesList := make([]string, 0, len(statisticsDatumsToShowList))
|
|
|
|
for _, datum := range statisticsDatumsToShowList{
|
|
|
|
// Each datum is represents a row in the data grid.
|
|
|
|
datumLabelFormatted := datum.LabelFormatted
|
|
|
|
datumValueFormatted := datum.ValueFormatted
|
|
|
|
attributeColumnValuesList = append(attributeColumnValuesList, datumLabelFormatted)
|
|
rightColumnValuesList = append(rightColumnValuesList, datumValueFormatted)
|
|
|
|
if (showPercentageColumn == true){
|
|
|
|
datumValue := datum.Value
|
|
|
|
getValuePercentage := func()float64{
|
|
if (allValuesSummed == 0){
|
|
return 0
|
|
}
|
|
valuePercentage := (datumValue/allValuesSummed)*100
|
|
return valuePercentage
|
|
}
|
|
|
|
valuePercentage := getValuePercentage()
|
|
valuePercentageString := helpers.ConvertFloat64ToStringRounded(valuePercentage, 2)
|
|
valuePercentageFormatted := valuePercentageString + "%"
|
|
|
|
percentageColumnValuesList = append(percentageColumnValuesList, valuePercentageFormatted)
|
|
}
|
|
}
|
|
|
|
getAttributeColumnTitle := func()string{
|
|
|
|
if (attributeColumnUnits != ""){
|
|
|
|
attributeColumnUnitsTrimmed := strings.TrimSpace(attributeColumnUnits)
|
|
|
|
attributeColumnTitle := attributeTitle + " (" + attributeColumnUnitsTrimmed + ")"
|
|
|
|
return attributeColumnTitle
|
|
}
|
|
|
|
return attributeTitle
|
|
}
|
|
|
|
attributeColumnTitle := getAttributeColumnTitle()
|
|
|
|
getRightColumnTitle := func()string{
|
|
|
|
if (rightColumnUnits != ""){
|
|
|
|
rightColumnUnitsTrimmed := strings.TrimSpace(rightColumnUnits)
|
|
|
|
rightColumnTitle := rightColumnName + " (" + rightColumnUnitsTrimmed + ")"
|
|
|
|
return rightColumnTitle
|
|
}
|
|
|
|
return rightColumnName
|
|
}
|
|
|
|
rightColumnTitle := getRightColumnTitle()
|
|
|
|
if (showGroupedStatistics == false){
|
|
|
|
// Raw statistics must be rendered using a widget list
|
|
// Otherwise, rendering thousands of rows is too difficult for fyne
|
|
|
|
headerText := attributeColumnTitle + " - " + rightColumnTitle
|
|
|
|
if (showPercentageColumn == true){
|
|
headerText += " - Percentage"
|
|
}
|
|
|
|
headerLabel := getBoldLabelCentered(headerText)
|
|
|
|
rowValuesList := make([]string, 0, len(attributeColumnValuesList))
|
|
|
|
for index, attributeColumnValue := range attributeColumnValuesList{
|
|
|
|
rightColumnValue := rightColumnValuesList[index]
|
|
|
|
if (showPercentageColumn == false){
|
|
|
|
rowValue := attributeColumnValue + " - " + rightColumnValue
|
|
rowValuesList = append(rowValuesList, rowValue)
|
|
} else {
|
|
|
|
percentageColumnValue := percentageColumnValuesList[index]
|
|
|
|
rowValue := attributeColumnValue + " - " + rightColumnValue + " - " + percentageColumnValue
|
|
rowValuesList = append(rowValuesList, rowValue)
|
|
}
|
|
}
|
|
|
|
onClickedFunction := func(_ int){}
|
|
|
|
widgetList, err := getFyneWidgetListFromStringList(rowValuesList, onClickedFunction)
|
|
if (err != nil) { return nil, err }
|
|
|
|
statisticsDataGrid := container.NewBorder(headerLabel, nil, nil, nil, widgetList)
|
|
|
|
return statisticsDataGrid, nil
|
|
}
|
|
|
|
attributeColumnHeader := getItalicLabelCentered(attributeColumnTitle)
|
|
rightColumnHeader := getItalicLabelCentered(rightColumnTitle)
|
|
percentageHeader := getItalicLabelCentered("Percentage")
|
|
|
|
attributeColumn := container.NewVBox(attributeColumnHeader, widget.NewSeparator())
|
|
rightColumn := container.NewVBox(rightColumnHeader, widget.NewSeparator())
|
|
percentageColumn := container.NewVBox(percentageHeader, widget.NewSeparator())
|
|
|
|
for index, attributeColumnValue := range attributeColumnValuesList{
|
|
|
|
rightColumnValue := rightColumnValuesList[index]
|
|
|
|
attributeColumnLabel := getBoldLabelCentered(attributeColumnValue)
|
|
rightColumnLabel := getBoldLabelCentered(rightColumnValue)
|
|
|
|
attributeColumn.Add(attributeColumnLabel)
|
|
rightColumn.Add(rightColumnLabel)
|
|
|
|
if (showPercentageColumn == true){
|
|
|
|
percentageColumnValue := percentageColumnValuesList[index]
|
|
|
|
valuePercentageLabel := getBoldLabelCentered(percentageColumnValue)
|
|
percentageColumn.Add(valuePercentageLabel)
|
|
}
|
|
}
|
|
|
|
if (showPercentageColumn == true){
|
|
statisticsDataGrid := container.NewHBox(layout.NewSpacer(), attributeColumn, rightColumn, percentageColumn, layout.NewSpacer())
|
|
return statisticsDataGrid, nil
|
|
}
|
|
|
|
statisticsDataGrid := container.NewHBox(layout.NewSpacer(), attributeColumn, rightColumn, layout.NewSpacer())
|
|
return statisticsDataGrid, nil
|
|
}
|
|
|
|
statisticsDataGrid, err := getStatisticsDataGrid()
|
|
if (err != nil){
|
|
setErrorEncounteredPage(window, err, previousPage)
|
|
return
|
|
}
|
|
|
|
page := container.NewBorder(header, nil, nil, nil, statisticsDataGrid)
|
|
|
|
setPageContent(page, window)
|
|
}
|
|
|
|
|