632 lines
23 KiB
Go
632 lines
23 KiB
Go
|
|
||
|
package gui
|
||
|
|
||
|
// viewGeneticReferencesGui.go implements pages to display information about genetic diseases and traits
|
||
|
|
||
|
import "fyne.io/fyne/v2"
|
||
|
import "fyne.io/fyne/v2/widget"
|
||
|
import "fyne.io/fyne/v2/theme"
|
||
|
import "fyne.io/fyne/v2/container"
|
||
|
import "fyne.io/fyne/v2/layout"
|
||
|
|
||
|
import "seekia/resources/geneticReferences/locusMetadata"
|
||
|
import "seekia/resources/geneticReferences/traits"
|
||
|
import "seekia/resources/geneticReferences/monogenicDiseases"
|
||
|
import "seekia/resources/geneticReferences/polygenicDiseases"
|
||
|
|
||
|
import "seekia/internal/helpers"
|
||
|
|
||
|
import "strings"
|
||
|
import "slices"
|
||
|
import "errors"
|
||
|
|
||
|
|
||
|
func setViewMonogenicDiseaseDetailsPage(window fyne.Window, diseaseName string, previousPage func()){
|
||
|
|
||
|
currentPage := func(){setViewMonogenicDiseaseDetailsPage(window, diseaseName, previousPage)}
|
||
|
|
||
|
title := getPageTitleCentered("Monogenic Disease Details - " + diseaseName)
|
||
|
|
||
|
backButton := getBackButtonCentered(previousPage)
|
||
|
|
||
|
diseaseObject, err := monogenicDiseases.GetMonogenicDiseaseObject(diseaseName)
|
||
|
if (err != nil){
|
||
|
setErrorEncounteredPage(window, err, previousPage)
|
||
|
return
|
||
|
}
|
||
|
|
||
|
diseaseGeneName := diseaseObject.GeneName
|
||
|
diseaseIsDominantOrRecessive := diseaseObject.DominantOrRecessive
|
||
|
diseaseDescription := diseaseObject.DiseaseDescription
|
||
|
diseaseReferencesMap := diseaseObject.References
|
||
|
|
||
|
diseaseNameLabel := widget.NewLabel("Disease Name:")
|
||
|
diseaseNameText := getBoldLabel(diseaseName)
|
||
|
diseaseNameRow := container.NewHBox(layout.NewSpacer(), diseaseNameLabel, diseaseNameText, layout.NewSpacer())
|
||
|
|
||
|
geneNameLabel := widget.NewLabel("Gene Name:")
|
||
|
geneNameText := getBoldLabel(diseaseGeneName)
|
||
|
geneNameRow := container.NewHBox(layout.NewSpacer(), geneNameLabel, geneNameText, layout.NewSpacer())
|
||
|
|
||
|
dominantOrRecessiveLabel := widget.NewLabel("Dominant or Recessive?:")
|
||
|
dominantOrRecessiveText := getBoldLabel(diseaseIsDominantOrRecessive)
|
||
|
dominantOrRecessiveRow := container.NewHBox(layout.NewSpacer(), dominantOrRecessiveLabel, dominantOrRecessiveText, layout.NewSpacer())
|
||
|
|
||
|
diseaseDescriptionTrimmed, _, err := helpers.TrimAndFlattenString(diseaseDescription, 10)
|
||
|
if (err != nil){
|
||
|
setErrorEncounteredPage(window, err, previousPage)
|
||
|
return
|
||
|
}
|
||
|
|
||
|
diseaseDescriptionLabel := widget.NewLabel("Description:")
|
||
|
diseaseDescriptionText := getBoldLabel(diseaseDescriptionTrimmed)
|
||
|
viewDiseaseDescriptionButton := widget.NewButtonWithIcon("", theme.VisibilityIcon(), func(){
|
||
|
setViewTextPage(window, "Disease Description", diseaseDescription, false, currentPage)
|
||
|
})
|
||
|
diseaseDescriptionRow := container.NewHBox(layout.NewSpacer(), diseaseDescriptionLabel, diseaseDescriptionText, viewDiseaseDescriptionButton, layout.NewSpacer())
|
||
|
|
||
|
viewReferencesButton := getWidgetCentered(widget.NewButtonWithIcon("View References", theme.ListIcon(), func(){
|
||
|
setViewGeneticAnalysisReferencesPage(window, "Monogenic Disease", diseaseReferencesMap, currentPage)
|
||
|
}))
|
||
|
|
||
|
page := container.NewVBox(title, backButton, widget.NewSeparator(), diseaseNameRow, widget.NewSeparator(), geneNameRow, widget.NewSeparator(), dominantOrRecessiveRow, widget.NewSeparator(), diseaseDescriptionRow, widget.NewSeparator(), viewReferencesButton)
|
||
|
|
||
|
setPageContent(page, window)
|
||
|
}
|
||
|
|
||
|
func setViewMonogenicDiseaseVariantDetailsPage(window fyne.Window, diseaseName string, variantIdentifier string, previousPage func()){
|
||
|
|
||
|
currentPage := func(){setViewMonogenicDiseaseVariantDetailsPage(window, diseaseName, variantIdentifier, previousPage)}
|
||
|
|
||
|
title := getPageTitleCentered("Viewing Monogenic Disease Variant Details")
|
||
|
|
||
|
backButton := getBackButtonCentered(previousPage)
|
||
|
|
||
|
diseaseNameLabel := widget.NewLabel("Disease Name:")
|
||
|
diseaseNameText := getBoldLabel(diseaseName)
|
||
|
diseaseNameRow := container.NewHBox(layout.NewSpacer(), diseaseNameLabel, diseaseNameText, layout.NewSpacer())
|
||
|
|
||
|
variantObject, err := monogenicDiseases.GetMonogenicDiseaseVariantObject(diseaseName, variantIdentifier)
|
||
|
if (err != nil) {
|
||
|
setErrorEncounteredPage(window, err, previousPage)
|
||
|
return
|
||
|
}
|
||
|
|
||
|
variantNamesList := variantObject.VariantNames
|
||
|
nucleotideChange := variantObject.NucleotideChange
|
||
|
aminoAcidChange := variantObject.AminoAcidChange
|
||
|
variantRSID := variantObject.VariantRSID
|
||
|
variantEffectIsMild := variantObject.EffectIsMild
|
||
|
referencesMap := variantObject.References
|
||
|
|
||
|
variantRSIDsList := []int64{variantRSID}
|
||
|
|
||
|
// We add aliases to variantRSIDsList
|
||
|
|
||
|
anyAliasesExist, rsidAliasesList, err := locusMetadata.GetRSIDAliases(variantRSID)
|
||
|
if (err != nil){
|
||
|
setErrorEncounteredPage(window, err, previousPage)
|
||
|
return
|
||
|
}
|
||
|
if (anyAliasesExist == true){
|
||
|
variantRSIDsList = append(variantRSIDsList, rsidAliasesList...)
|
||
|
}
|
||
|
|
||
|
getVariantNamesLabelText := func()string{
|
||
|
|
||
|
if(len(variantNamesList) == 1){
|
||
|
return "Variant Name:"
|
||
|
}
|
||
|
return "Variant Names:"
|
||
|
}
|
||
|
|
||
|
variantNamesLabelText := getVariantNamesLabelText()
|
||
|
|
||
|
variantNamesListString := strings.Join(variantNamesList, ", ")
|
||
|
variantNamesLabel := widget.NewLabel(variantNamesLabelText)
|
||
|
variantNamesText := getBoldLabel(variantNamesListString)
|
||
|
variantNamesRow := container.NewHBox(layout.NewSpacer(), variantNamesLabel, variantNamesText, layout.NewSpacer())
|
||
|
|
||
|
nucleotideChangeLabel := widget.NewLabel("Nucleotide Change:")
|
||
|
nucleotideChangeText := getBoldLabel(nucleotideChange)
|
||
|
nucleotideChangeRow := container.NewHBox(layout.NewSpacer(), nucleotideChangeLabel, nucleotideChangeText, layout.NewSpacer())
|
||
|
|
||
|
page := container.NewVBox(title, backButton, widget.NewSeparator(), diseaseNameRow, widget.NewSeparator(), variantNamesRow, widget.NewSeparator(), nucleotideChangeRow, widget.NewSeparator())
|
||
|
|
||
|
if (aminoAcidChange != ""){
|
||
|
aminoAcidChangeLabel := widget.NewLabel("Amino Acid Change:")
|
||
|
aminoAcidChangeText := getBoldLabel(aminoAcidChange)
|
||
|
aminoAcidChangeRow := container.NewHBox(layout.NewSpacer(), aminoAcidChangeLabel, aminoAcidChangeText, layout.NewSpacer())
|
||
|
|
||
|
page.Add(aminoAcidChangeRow)
|
||
|
page.Add(widget.NewSeparator())
|
||
|
}
|
||
|
|
||
|
getVariantRSIDsLabelText := func()string{
|
||
|
if (len(variantRSIDsList) == 1){
|
||
|
return "Variant rsID:"
|
||
|
}
|
||
|
return "Variant rsIDs:"
|
||
|
}
|
||
|
|
||
|
variantRSIDsLabelText := getVariantRSIDsLabelText()
|
||
|
|
||
|
variantRSIDStringsList := make([]string, 0, len(variantRSIDsList))
|
||
|
|
||
|
for _, variantRSID := range variantRSIDsList{
|
||
|
|
||
|
variantRSIDString := helpers.ConvertInt64ToString(variantRSID)
|
||
|
|
||
|
variantRSIDName := "rs" + variantRSIDString
|
||
|
|
||
|
variantRSIDStringsList = append(variantRSIDStringsList, variantRSIDName)
|
||
|
}
|
||
|
|
||
|
variantRSIDsListString := strings.Join(variantRSIDStringsList, ", ")
|
||
|
variantRSIDsLabel := widget.NewLabel(variantRSIDsLabelText)
|
||
|
variantRSIDsText := getBoldLabel(variantRSIDsListString)
|
||
|
variantRSIDsRow := container.NewHBox(layout.NewSpacer(), variantRSIDsLabel, variantRSIDsText, layout.NewSpacer())
|
||
|
page.Add(variantRSIDsRow)
|
||
|
page.Add(widget.NewSeparator())
|
||
|
|
||
|
effectIsMildString := helpers.ConvertBoolToYesOrNoString(variantEffectIsMild)
|
||
|
effectIsMildLabel := widget.NewLabel("Effect is Mild:")
|
||
|
effectIsMildText := getBoldLabel(effectIsMildString)
|
||
|
effectIsMildHelpButton := widget.NewButtonWithIcon("", theme.QuestionIcon(), func(){
|
||
|
setVariantEffectIsMildExplainerPage(window, currentPage)
|
||
|
})
|
||
|
effectIsMildRow := container.NewHBox(layout.NewSpacer(), effectIsMildLabel, effectIsMildText, effectIsMildHelpButton, layout.NewSpacer())
|
||
|
page.Add(effectIsMildRow)
|
||
|
page.Add(widget.NewSeparator())
|
||
|
|
||
|
viewReferencesButton := getWidgetCentered(widget.NewButtonWithIcon("View References", theme.ListIcon(), func(){
|
||
|
setViewGeneticAnalysisReferencesPage(window, "Variant", referencesMap, currentPage)
|
||
|
}))
|
||
|
page.Add(viewReferencesButton)
|
||
|
|
||
|
setPageContent(page, window)
|
||
|
}
|
||
|
|
||
|
func setViewPolygenicDiseaseDetailsPage(window fyne.Window, diseaseName string, previousPage func()){
|
||
|
|
||
|
currentPage := func(){setViewPolygenicDiseaseDetailsPage(window, diseaseName, previousPage)}
|
||
|
|
||
|
title := getPageTitleCentered("Disease Details - " + diseaseName)
|
||
|
|
||
|
backButton := getBackButtonCentered(previousPage)
|
||
|
|
||
|
diseaseObject, err := polygenicDiseases.GetPolygenicDiseaseObject(diseaseName)
|
||
|
if (err != nil){
|
||
|
setErrorEncounteredPage(window, err, previousPage)
|
||
|
return
|
||
|
}
|
||
|
|
||
|
diseaseDescription := diseaseObject.DiseaseDescription
|
||
|
effectedSex := diseaseObject.EffectedSex
|
||
|
diseaseReferencesMap := diseaseObject.References
|
||
|
|
||
|
diseaseNameLabel := widget.NewLabel("Disease Name:")
|
||
|
diseaseNameText := getBoldLabel(diseaseName)
|
||
|
diseaseNameRow := container.NewHBox(layout.NewSpacer(), diseaseNameLabel, diseaseNameText, layout.NewSpacer())
|
||
|
|
||
|
getEffectedSexTextLabelText := func()string{
|
||
|
if (effectedSex == "Both"){
|
||
|
return "Male and Female"
|
||
|
}
|
||
|
return effectedSex
|
||
|
}
|
||
|
|
||
|
effectedSexTextLabelText := getEffectedSexTextLabelText()
|
||
|
|
||
|
effectedSexLabel := widget.NewLabel("Effected Sex:")
|
||
|
effectedSexText := getBoldLabel(effectedSexTextLabelText)
|
||
|
effectedSexRow := container.NewHBox(layout.NewSpacer(), effectedSexLabel, effectedSexText, layout.NewSpacer())
|
||
|
|
||
|
diseaseDescriptionTrimmed, _, err := helpers.TrimAndFlattenString(diseaseDescription, 10)
|
||
|
if (err != nil){
|
||
|
setErrorEncounteredPage(window, err, previousPage)
|
||
|
return
|
||
|
}
|
||
|
|
||
|
diseaseDescriptionLabel := widget.NewLabel("Description:")
|
||
|
diseaseDescriptionText := getBoldLabel(diseaseDescriptionTrimmed)
|
||
|
viewDiseaseDescriptionButton := widget.NewButtonWithIcon("", theme.VisibilityIcon(), func(){
|
||
|
setViewTextPage(window, "Disease Description", diseaseDescription, false, currentPage)
|
||
|
})
|
||
|
diseaseDescriptionRow := container.NewHBox(layout.NewSpacer(), diseaseDescriptionLabel, diseaseDescriptionText, viewDiseaseDescriptionButton, layout.NewSpacer())
|
||
|
|
||
|
viewReferencesButton := getWidgetCentered(widget.NewButtonWithIcon("View References", theme.ListIcon(), func(){
|
||
|
setViewGeneticAnalysisReferencesPage(window, "Polygenic Disease", diseaseReferencesMap, currentPage)
|
||
|
}))
|
||
|
|
||
|
page := container.NewVBox(title, backButton, widget.NewSeparator(), diseaseNameRow, widget.NewSeparator(), effectedSexRow, widget.NewSeparator(), diseaseDescriptionRow, widget.NewSeparator(), viewReferencesButton)
|
||
|
|
||
|
setPageContent(page, window)
|
||
|
}
|
||
|
|
||
|
|
||
|
func setViewPolygenicDiseaseLocusDetailsPage(window fyne.Window, diseaseName string, locusIdentifier string, previousPage func()){
|
||
|
|
||
|
currentPage := func(){setViewPolygenicDiseaseLocusDetailsPage(window, diseaseName, locusIdentifier, previousPage)}
|
||
|
|
||
|
title := getPageTitleCentered("Viewing Locus Details")
|
||
|
|
||
|
backButton := getBackButtonCentered(previousPage)
|
||
|
|
||
|
locusObject, err := polygenicDiseases.GetPolygenicDiseaseLocusObject(diseaseName, locusIdentifier)
|
||
|
if (err != nil){
|
||
|
setErrorEncounteredPage(window, err, previousPage)
|
||
|
return
|
||
|
}
|
||
|
|
||
|
locusRSID := locusObject.LocusRSID
|
||
|
locusReferencesMap := locusObject.References
|
||
|
|
||
|
locusRSIDsList := []int64{locusRSID}
|
||
|
|
||
|
// We add aliases to locusRSIDsList
|
||
|
|
||
|
anyAliasesExist, rsidAliasesList, err := locusMetadata.GetRSIDAliases(locusRSID)
|
||
|
if (err != nil){
|
||
|
setErrorEncounteredPage(window, err, previousPage)
|
||
|
return
|
||
|
}
|
||
|
if (anyAliasesExist == true){
|
||
|
locusRSIDsList = append(locusRSIDsList, rsidAliasesList...)
|
||
|
}
|
||
|
|
||
|
metadataExists, locusMetadataObject, err := locusMetadata.GetLocusMetadata(locusRSID)
|
||
|
if (err != nil){
|
||
|
setErrorEncounteredPage(window, err, previousPage)
|
||
|
return
|
||
|
}
|
||
|
if (metadataExists == false){
|
||
|
setErrorEncounteredPage(window, errors.New("setViewPolygenicDiseaseLocusDetailsPage called with locusRSID missing from locusMetadata."), previousPage)
|
||
|
return
|
||
|
}
|
||
|
|
||
|
locusGeneName := locusMetadataObject.GeneNamesList[0]
|
||
|
|
||
|
diseaseNameLabel := widget.NewLabel("Disease Name:")
|
||
|
diseaseNameText := getBoldLabel(diseaseName)
|
||
|
diseaseNameRow := container.NewHBox(layout.NewSpacer(), diseaseNameLabel, diseaseNameText, layout.NewSpacer())
|
||
|
|
||
|
getLocusNamesLabelText := func()string{
|
||
|
|
||
|
if(len(locusRSIDsList) == 1){
|
||
|
return "Locus Name:"
|
||
|
}
|
||
|
return "Locus Names:"
|
||
|
}
|
||
|
|
||
|
locusNamesLabelText := getLocusNamesLabelText()
|
||
|
|
||
|
locusRSIDStringsList := make([]string, 0, len(locusRSIDsList))
|
||
|
|
||
|
for _, locusRSID := range locusRSIDsList{
|
||
|
|
||
|
locusRSIDString := helpers.ConvertInt64ToString(locusRSID)
|
||
|
|
||
|
locusRSIDName := "rs" + locusRSIDString
|
||
|
|
||
|
locusRSIDStringsList = append(locusRSIDStringsList, locusRSIDName)
|
||
|
}
|
||
|
|
||
|
locusNamesListString := strings.Join(locusRSIDStringsList, ", ")
|
||
|
locusNamesLabel := widget.NewLabel(locusNamesLabelText)
|
||
|
locusNamesText := getBoldLabel(locusNamesListString)
|
||
|
locusNamesRow := container.NewHBox(layout.NewSpacer(), locusNamesLabel, locusNamesText, layout.NewSpacer())
|
||
|
|
||
|
geneNameLabel := widget.NewLabel("Gene Name:")
|
||
|
geneNameText := getBoldLabel(locusGeneName)
|
||
|
geneNameRow := container.NewHBox(layout.NewSpacer(), geneNameLabel, geneNameText, layout.NewSpacer())
|
||
|
|
||
|
viewReferencesButton := getWidgetCentered(widget.NewButtonWithIcon("View References", theme.ListIcon(), func(){
|
||
|
setViewGeneticAnalysisReferencesPage(window, "Locus", locusReferencesMap, currentPage)
|
||
|
}))
|
||
|
|
||
|
getBasePairsGrid := func()(*fyne.Container, error){
|
||
|
|
||
|
locusRiskWeightsMap := locusObject.RiskWeightsMap
|
||
|
locusBasePairProbabilitiesMap := locusObject.BasePairProbabilitiesMap
|
||
|
|
||
|
riskWeightLabel := getItalicLabelCentered("Risk Weight")
|
||
|
probabilityLabel := getItalicLabelCentered("Probability Of Weight")
|
||
|
|
||
|
riskWeightColumn := container.NewVBox(riskWeightLabel, widget.NewSeparator())
|
||
|
riskWeightProbabilityColumn := container.NewVBox(probabilityLabel, widget.NewSeparator())
|
||
|
|
||
|
// We create a new map with duplicates removed
|
||
|
|
||
|
locusBasePairProbabilitiesMap_DuplicatesRemoved := make(map[string]float64)
|
||
|
|
||
|
for basePair, basePairProbability := range locusBasePairProbabilitiesMap{
|
||
|
|
||
|
baseA, baseB, semicolonFound := strings.Cut(basePair, ";")
|
||
|
if (semicolonFound == false) {
|
||
|
return nil, errors.New("Invalid base pair found in locusBasePairProbabilitiesMap: " + basePair)
|
||
|
}
|
||
|
basePairDuplicate := baseB + ";" + baseA
|
||
|
|
||
|
existingProbabilityValue, exists := locusBasePairProbabilitiesMap_DuplicatesRemoved[basePairDuplicate]
|
||
|
if (exists == true){
|
||
|
|
||
|
// The duplicate has already been added.
|
||
|
// We make sure the probability values match
|
||
|
if (existingProbabilityValue != basePairProbability){
|
||
|
return nil, errors.New("locusBasePairProbabilitiesMap contains duplicate base pair with different value")
|
||
|
}
|
||
|
continue
|
||
|
}
|
||
|
locusBasePairProbabilitiesMap_DuplicatesRemoved[basePair] = basePairProbability
|
||
|
}
|
||
|
|
||
|
// All probabilities are mutually exclusive (you can only have 1 base pair for each genome locus)
|
||
|
// Thus, we can add them together to get a total probability for each risk weight
|
||
|
|
||
|
// Map structure: Risk Weight -> Probability of having weight
|
||
|
riskWeightProbabilitiesMap := make(map[int]float64)
|
||
|
|
||
|
for basePair, basePairProbability := range locusBasePairProbabilitiesMap_DuplicatesRemoved{
|
||
|
|
||
|
getBasePairRiskWeight := func()int{
|
||
|
|
||
|
basePairRiskWeight, exists := locusRiskWeightsMap[basePair]
|
||
|
if (exists == false){
|
||
|
// This base pair has no known weight. We treat it as a 0 weight.
|
||
|
return 0
|
||
|
}
|
||
|
return basePairRiskWeight
|
||
|
}
|
||
|
|
||
|
basePairRiskWeight := getBasePairRiskWeight()
|
||
|
|
||
|
riskWeightProbabilitiesMap[basePairRiskWeight] += basePairProbability
|
||
|
}
|
||
|
|
||
|
// Now we sort risk weights in order of least to greatest
|
||
|
allRiskWeightsList := helpers.GetListOfMapKeys(riskWeightProbabilitiesMap)
|
||
|
|
||
|
slices.Sort(allRiskWeightsList)
|
||
|
|
||
|
for _, riskWeight := range allRiskWeightsList{
|
||
|
|
||
|
riskWeightProbability, exists := riskWeightProbabilitiesMap[riskWeight]
|
||
|
if (exists == false){
|
||
|
return nil, errors.New("Risk weight probability not found in riskWeightProbabilitiesMap")
|
||
|
}
|
||
|
|
||
|
riskWeightString := helpers.ConvertIntToString(riskWeight)
|
||
|
|
||
|
riskWeightPercentageProbability := riskWeightProbability * 100
|
||
|
riskWeightProbabilityString := helpers.ConvertFloat64ToStringRounded(riskWeightPercentageProbability, 2)
|
||
|
riskWeightProbabilityFormatted := "~" + riskWeightProbabilityString + "%"
|
||
|
|
||
|
riskWeightText := getBoldLabelCentered(riskWeightString)
|
||
|
riskWeightProbabilityText := getBoldLabelCentered(riskWeightProbabilityFormatted)
|
||
|
|
||
|
riskWeightColumn.Add(riskWeightText)
|
||
|
riskWeightProbabilityColumn.Add(riskWeightProbabilityText)
|
||
|
|
||
|
riskWeightColumn.Add(widget.NewSeparator())
|
||
|
riskWeightProbabilityColumn.Add(widget.NewSeparator())
|
||
|
}
|
||
|
|
||
|
riskWeightHelpButton := widget.NewButtonWithIcon("", theme.QuestionIcon(), func(){
|
||
|
setPolygenicDiseaseLocusRiskWeightExplainerPage(window, currentPage)
|
||
|
})
|
||
|
riskWeightColumn.Add(riskWeightHelpButton)
|
||
|
|
||
|
probabilityHelpButton := widget.NewButtonWithIcon("", theme.QuestionIcon(), func(){
|
||
|
setPolygenicDiseaseLocusRiskWeightProbabilityExplainerPage(window, currentPage)
|
||
|
})
|
||
|
riskWeightProbabilityColumn.Add(probabilityHelpButton)
|
||
|
|
||
|
basePairsGrid := container.NewHBox(layout.NewSpacer(), riskWeightColumn, riskWeightProbabilityColumn, layout.NewSpacer())
|
||
|
|
||
|
return basePairsGrid, nil
|
||
|
}
|
||
|
|
||
|
basePairsGrid, err := getBasePairsGrid()
|
||
|
if (err != nil){
|
||
|
setErrorEncounteredPage(window, err, previousPage)
|
||
|
return
|
||
|
}
|
||
|
|
||
|
page := container.NewVBox(title, backButton, widget.NewSeparator(), diseaseNameRow, widget.NewSeparator(), locusNamesRow, widget.NewSeparator(), geneNameRow, widget.NewSeparator(), viewReferencesButton, widget.NewSeparator(), basePairsGrid)
|
||
|
|
||
|
setPageContent(page, window)
|
||
|
}
|
||
|
|
||
|
|
||
|
func setViewGeneticAnalysisReferencesPage(window fyne.Window, referencesTopic string, referencesMap map[string]string, previousPage func()){
|
||
|
|
||
|
currentPage := func(){setViewGeneticAnalysisReferencesPage(window, referencesTopic, referencesMap, previousPage)}
|
||
|
|
||
|
pageTitle := "Viewing " + referencesTopic + " References"
|
||
|
|
||
|
title := getPageTitleCentered(pageTitle)
|
||
|
|
||
|
backButton := getBackButtonCentered(previousPage)
|
||
|
|
||
|
referencesContainer := container.NewVBox()
|
||
|
|
||
|
referenceNamesList := helpers.GetListOfMapKeys(referencesMap)
|
||
|
|
||
|
// We sort the references so they always show up in the same order
|
||
|
slices.Sort(referenceNamesList)
|
||
|
|
||
|
for index, referenceName := range referenceNamesList{
|
||
|
|
||
|
referenceLink, exists := referencesMap[referenceName]
|
||
|
if (exists == false){
|
||
|
setErrorEncounteredPage(window, errors.New("referencesMap missing referenceName"), previousPage)
|
||
|
return
|
||
|
}
|
||
|
|
||
|
indexString := helpers.ConvertIntToString(index+1)
|
||
|
|
||
|
indexLabel := getBoldLabel(indexString + ".")
|
||
|
|
||
|
referenceNameTrimmed, _, err := helpers.TrimAndFlattenString(referenceName, 35)
|
||
|
if (err != nil) {
|
||
|
setErrorEncounteredPage(window, err, previousPage)
|
||
|
return
|
||
|
}
|
||
|
referenceNameLabel := getItalicLabel(referenceNameTrimmed)
|
||
|
|
||
|
referenceViewNameButton := widget.NewButtonWithIcon("View Name", theme.VisibilityIcon(), func(){
|
||
|
setViewTextPage(window, "Viewing Reference Name", referenceName, false, currentPage)
|
||
|
})
|
||
|
|
||
|
referenceLinkButton := widget.NewButtonWithIcon("View Link", theme.VisibilityIcon(), func(){
|
||
|
setViewLinkPage(window, "Viewing Reference Link", referenceLink, currentPage)
|
||
|
})
|
||
|
|
||
|
referenceRow := container.NewHBox(layout.NewSpacer(), indexLabel, referenceNameLabel, referenceViewNameButton, referenceLinkButton, layout.NewSpacer())
|
||
|
|
||
|
referencesContainer.Add(referenceRow)
|
||
|
referencesContainer.Add(widget.NewSeparator())
|
||
|
}
|
||
|
|
||
|
page := container.NewVBox(title, backButton, widget.NewSeparator(), referencesContainer)
|
||
|
|
||
|
setPageContent(page, window)
|
||
|
}
|
||
|
|
||
|
|
||
|
func setViewTraitDetailsPage(window fyne.Window, traitName string, previousPage func()){
|
||
|
|
||
|
currentPage := func(){setViewTraitDetailsPage(window, traitName, previousPage)}
|
||
|
|
||
|
title := getPageTitleCentered("Trait Details - " + traitName)
|
||
|
|
||
|
backButton := getBackButtonCentered(previousPage)
|
||
|
|
||
|
traitObject, err := traits.GetTraitObject(traitName)
|
||
|
if (err != nil){
|
||
|
setErrorEncounteredPage(window, err, previousPage)
|
||
|
return
|
||
|
}
|
||
|
|
||
|
traitDescription := traitObject.TraitDescription
|
||
|
traitReferencesMap := traitObject.References
|
||
|
|
||
|
traitNameLabel := widget.NewLabel("Trait Name:")
|
||
|
traitNameText := getBoldLabel(traitName)
|
||
|
traitNameRow := container.NewHBox(layout.NewSpacer(), traitNameLabel, traitNameText, layout.NewSpacer())
|
||
|
|
||
|
traitDescriptionTrimmed, _, err := helpers.TrimAndFlattenString(traitDescription, 10)
|
||
|
if (err != nil){
|
||
|
setErrorEncounteredPage(window, err, previousPage)
|
||
|
return
|
||
|
}
|
||
|
|
||
|
traitDescriptionLabel := widget.NewLabel("Description:")
|
||
|
traitDescriptionText := getBoldLabel(traitDescriptionTrimmed)
|
||
|
viewTraitDescriptionButton := widget.NewButtonWithIcon("", theme.VisibilityIcon(), func(){
|
||
|
setViewTextPage(window, "Trait Description", traitDescription, false, currentPage)
|
||
|
})
|
||
|
traitDescriptionRow := container.NewHBox(layout.NewSpacer(), traitDescriptionLabel, traitDescriptionText, viewTraitDescriptionButton, layout.NewSpacer())
|
||
|
|
||
|
viewReferencesButton := getWidgetCentered(widget.NewButtonWithIcon("View References", theme.ListIcon(), func(){
|
||
|
setViewGeneticAnalysisReferencesPage(window, "Trait", traitReferencesMap, currentPage)
|
||
|
}))
|
||
|
|
||
|
page := container.NewVBox(title, backButton, widget.NewSeparator(), traitNameRow, widget.NewSeparator(), traitDescriptionRow, widget.NewSeparator(), viewReferencesButton)
|
||
|
|
||
|
setPageContent(page, window)
|
||
|
}
|
||
|
|
||
|
func setViewTraitRuleDetailsPage(window fyne.Window, traitName string, ruleIdentifier string, previousPage func()){
|
||
|
|
||
|
currentPage := func(){setViewTraitRuleDetailsPage(window, traitName, ruleIdentifier, previousPage)}
|
||
|
|
||
|
title := getPageTitleCentered("Viewing Rule Details")
|
||
|
|
||
|
backButton := getBackButtonCentered(previousPage)
|
||
|
|
||
|
traitNameLabel := widget.NewLabel("Trait Name:")
|
||
|
traitNameText := getBoldLabel(traitName)
|
||
|
traitNameRow := container.NewHBox(layout.NewSpacer(), traitNameLabel, traitNameText, layout.NewSpacer())
|
||
|
|
||
|
ruleIdentifierLabel := widget.NewLabel("Rule Identifier:")
|
||
|
ruleIdentifierText := getBoldLabel(ruleIdentifier)
|
||
|
ruleIdentifierRow := container.NewHBox(layout.NewSpacer(), ruleIdentifierLabel, ruleIdentifierText, layout.NewSpacer())
|
||
|
|
||
|
traitRuleObject, err := traits.GetTraitRuleObject(traitName, ruleIdentifier)
|
||
|
if (err != nil){
|
||
|
setErrorEncounteredPage(window, err, previousPage)
|
||
|
return
|
||
|
}
|
||
|
|
||
|
ruleOutcomePointsMap := traitRuleObject.OutcomePointsMap
|
||
|
ruleReferencesMap := traitRuleObject.References
|
||
|
|
||
|
viewReferencesButton := getWidgetCentered(widget.NewButtonWithIcon("View References", theme.ListIcon(), func(){
|
||
|
setViewGeneticAnalysisReferencesPage(window, "Rule", ruleReferencesMap, currentPage)
|
||
|
}))
|
||
|
|
||
|
ruleEffectsLabel := getBoldLabelCentered("Rule Effects:")
|
||
|
|
||
|
getRuleEffectsGrid := func()(*fyne.Container, error){
|
||
|
|
||
|
outcomeNameLabel := getItalicLabelCentered("Outcome Name")
|
||
|
outcomeEffectLabel := getItalicLabelCentered("Outcome Effect")
|
||
|
|
||
|
outcomeNameColumn := container.NewVBox(outcomeNameLabel, widget.NewSeparator())
|
||
|
outcomeEffectColumn := container.NewVBox(outcomeEffectLabel, widget.NewSeparator())
|
||
|
|
||
|
for outcomeName, outcomePointsEffect := range ruleOutcomePointsMap{
|
||
|
|
||
|
outcomeNameLabel := getBoldLabelCentered(outcomeName)
|
||
|
|
||
|
getOutcomeEffect := func()string{
|
||
|
|
||
|
outcomePointsEffectString := helpers.ConvertIntToString(outcomePointsEffect)
|
||
|
|
||
|
if (outcomePointsEffect < 0){
|
||
|
return outcomePointsEffectString
|
||
|
}
|
||
|
|
||
|
outcomeEffect := "+" + outcomePointsEffectString
|
||
|
return outcomeEffect
|
||
|
}
|
||
|
|
||
|
outcomeEffect := getOutcomeEffect()
|
||
|
|
||
|
outcomeEffectLabel := getBoldLabelCentered(outcomeEffect)
|
||
|
|
||
|
outcomeNameColumn.Add(outcomeNameLabel)
|
||
|
outcomeEffectColumn.Add(outcomeEffectLabel)
|
||
|
|
||
|
outcomeNameColumn.Add(widget.NewSeparator())
|
||
|
outcomeEffectColumn.Add(widget.NewSeparator())
|
||
|
}
|
||
|
|
||
|
outcomeEffectHelpButton := widget.NewButtonWithIcon("", theme.QuestionIcon(), func(){
|
||
|
setTraitRuleOutcomeEffectsExplainerPage(window, currentPage)
|
||
|
})
|
||
|
outcomeEffectColumn.Add(outcomeEffectHelpButton)
|
||
|
|
||
|
ruleEffectsGrid := container.NewHBox(layout.NewSpacer(), outcomeNameColumn, outcomeEffectColumn, layout.NewSpacer())
|
||
|
|
||
|
return ruleEffectsGrid, nil
|
||
|
}
|
||
|
|
||
|
ruleEffectsGrid, err := getRuleEffectsGrid()
|
||
|
if (err != nil){
|
||
|
setErrorEncounteredPage(window, err, previousPage)
|
||
|
return
|
||
|
}
|
||
|
|
||
|
page := container.NewVBox(title, backButton, widget.NewSeparator(), traitNameRow, widget.NewSeparator(), ruleIdentifierRow, widget.NewSeparator(), viewReferencesButton, widget.NewSeparator(), ruleEffectsLabel, ruleEffectsGrid)
|
||
|
|
||
|
setPageContent(page, window)
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|