Skip to content

Commit

Permalink
Merge pull request #129 from africanmathsinitiative/master
Browse files Browse the repository at this point in the history
update
  • Loading branch information
MeSophie authored Nov 10, 2023
2 parents 66a9b0c + ea8d1cf commit 0746285
Show file tree
Hide file tree
Showing 83 changed files with 8,245 additions and 5,965 deletions.
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -252,3 +252,7 @@ installer/Output/

/packages/NLog.*/
/packages/Newtonsoft.Json.*/

# RScript package and dependencies
/packages/RScript.*/
/packages/System.Collections.Specialized.*/
12 changes: 9 additions & 3 deletions instat/Model/DataFrame/clsDataBook.vb
Original file line number Diff line number Diff line change
Expand Up @@ -155,11 +155,10 @@ Public Class clsDataBook
End If
'if data not refreshed successfully, remove the data frame from the data book
If Not dataFrame.RefreshData() Then
MessageBox.Show("Error: Could not retrieve data frame:" & strDataFrameName & " from R" &
Environment.NewLine & "Data displayed in spreadsheet may not be up to date." &
Environment.NewLine & "We strongly suggest restarting R-Instat before continuing.",
MessageBox.Show("Error: Sorry R-Instat can not retrieve the: " & strDataFrameName & " data from R.",
"Cannot retrieve data", MessageBoxButtons.OK, MessageBoxIcon.Warning)
_lstDataFrames.Remove(dataFrame)
DeleteDataFrames(strDataFrameName)
End If
Next
If lstOfCurrentRDataFrameNames.Count = _lstDataFrames.Count Then
Expand Down Expand Up @@ -189,5 +188,12 @@ Public Class clsDataBook
Return listOfDataFrames
End Function

Private Sub DeleteDataFrames(strDataName As String)
Dim clsDeleteFunction As New RFunction
clsDeleteFunction.SetRCommand(_RLink.strInstatDataObject & "$delete_dataframes")
clsDeleteFunction.AddParameter("data_names", Chr(34) & strDataName & Chr(34))
_RLink.RunScript(clsDeleteFunction.ToScript(), strComment:="Delete DataFrame(s)")
End Sub

End Class

6 changes: 5 additions & 1 deletion instat/Model/Output/clsOutputElement.vb
Original file line number Diff line number Diff line change
Expand Up @@ -85,11 +85,15 @@ Public Class clsOutputElement
_strOutput = strOutput
End Sub

''' <summary>
''' <summary>
''' Gets formatted R Script, split into R Script Elements
''' </summary>
''' <returns></returns>
Public ReadOnly Property FormattedRScript As List(Of clsRScriptElement)

'todo.
'this function may end up being called multiple times. For long scripts initialising clsRScript And getting tokens takes lot of time. You can test this effect by pasting new data frame that has many columns.
'should the operation of getting tokens be done just once then stored to be reused f need be?
Get
Dim _lstRScriptElements As New List(Of clsRScriptElement)
Try
Expand Down
2 changes: 1 addition & 1 deletion instat/UserControl/ucrOutputPage.vb
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ Public Class ucrOutputPage
'whether it's just a script output

'todo. temporary fix. Output element should always have an R script
If outputElement.FormattedRScript IsNot Nothing Then
If outputElement.Script IsNot Nothing Then
AddNewScript(outputElement)
End If

Expand Down
72 changes: 52 additions & 20 deletions instat/UserControls/DataGrid/ReoGrid/ucrDataViewReoGrid.vb
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
' You should have received a copy of the GNU General Public License
' along with this program. If not, see <http://www.gnu.org/licenses/>.

Imports System.Text.RegularExpressions
Imports unvell.ReoGrid
Imports unvell.ReoGrid.Events

Expand Down Expand Up @@ -76,10 +77,8 @@ Public Class ucrDataViewReoGrid
For i = 0 To grdData.CurrentWorksheet.Rows - 1
For j = 0 To grdData.CurrentWorksheet.Columns - 1
Dim strData As String = dataFrame.DisplayedData(i, j)
If grdData.CurrentWorksheet.ColumnHeaders.Item(j).Text.Contains("(LT)") AndAlso
strData IsNot Nothing Then
strData = GetInnerBracketedString(strData)
strData = If(strData.Contains(":"), strData.Replace(":", ", "), strData)
If strData IsNot Nothing AndAlso grdData.CurrentWorksheet.ColumnHeaders.Item(j).Text.Contains("(LT)") Then
strData = GetTransformedLTColumnContents(strData)
End If
grdData.CurrentWorksheet(row:=i, col:=j) = strData
Next
Expand All @@ -104,6 +103,50 @@ Public Class ucrDataViewReoGrid
grdData.CurrentWorksheet.RowHeaderWidth = TextRenderer.MeasureText(strLongestRowHeaderText, Me.Font).Width
End Sub

''' <summary>
''' Transforms contents of LT column(s) that have structured R-like data into a more readable and user-friendly format that is consistent with R Viewer.
''' For example, content like list(Birmingham = list(IATA = c("BHM", NA, NA, NA), Hartford = list(IATA = "BDL", ICAO = "KBDL"))
''' will be transformed to BHM, NA, NA, NA,BDL,KBDL
''' </summary>
''' <param name="strLstData">Data from column type LT</param>
''' <returns>Transformed data</returns>
Private Function GetTransformedLTColumnContents(strLstData As String) As String
' Check if strLstData is "numeric(0)",
If strLstData = "numeric(0)" Then
'"numeric(0)" represents an empty data set in R so just return an empty output
Return String.Empty
End If

' Check if strLstData contains "list(" or "c(". These are patterns found in R list and vector data structures.
If Not strLstData.Contains("list(") AndAlso Not strLstData.Contains("c(") Then
Return strLstData
End If

' Regular expression pattern to match values inside c(...) or "..."
Dim pattern As String = "c\(([^)]+)\)|""([^""]+)"""
Dim matches As MatchCollection = Regex.Matches(strLstData, pattern)
Dim lstExtractedContents As New List(Of String)

' Iterate through matches
For Each match As Match In matches
' If it's a c(...) match, extracts the content inside the parentheses. Split the extracted content by commas, trimm extra spaces and double quotes then added to a list of extracted contents.
' if it's a string "..." match, directly add the content (minus the double quotes) to the list of extracted contents.

Dim strInnerListContent As String = If(match.Value.Contains("c("), match.Groups(1).Value, match.Value)
Dim arrInnerListContentTrimmed As String() = strInnerListContent.Split(","c).Select(Function(item) item.Trim().Trim(""""c)).ToArray()
lstExtractedContents.AddRange(arrInnerListContentTrimmed)
Next

' Join the extracted contents
Dim strExtractedContents As String = String.Join(", ", lstExtractedContents)

' Replace ":" with ", " because, in R data structure format, colons are often used to separate key-value pairs.
' Replacing colons with commas and spaces make the data more user-friendly.
strExtractedContents = strExtractedContents.Replace(":", ", ")

Return strExtractedContents
End Function

Public Sub AdjustColumnWidthAfterWrapping(strColumn As String, Optional bApplyWrap As Boolean = False) Implements IDataViewGrid.AdjustColumnWidthAfterWrapping
Dim iColumnIndex As Integer = GetColumnIndex(strColName:=strColumn)
If iColumnIndex < 0 OrElse grdData.CurrentWorksheet.ColumnHeaders(iColumnIndex).Text.Contains("(G)") Then
Expand All @@ -126,19 +169,6 @@ Public Class ucrDataViewReoGrid
grdData.CurrentWorksheet(iRow, iColumn) = GetCurrentDataFrameFocus.DisplayedData(iRow, iColumn)
End Sub

Private Function GetInnerBracketedString(strData As String) As String
Dim intFirstRightBracket As Integer = InStr(strData, ")")
Dim intLastLeftBracket As Integer = InStrRev(strData, "(")
If intFirstRightBracket = 0 Or intLastLeftBracket = 0 Then
Return strData
ElseIf strData = "numeric(0)" Then
Return String.Empty
Else
Dim strOutput As String = Mid(strData, intLastLeftBracket + 1, intFirstRightBracket - intLastLeftBracket - 1)
Return strOutput
End If
End Function

Public Function GetSelectedColumns() As List(Of clsColumnHeaderDisplay) Implements IDataViewGrid.GetSelectedColumns
Dim lstColumns As New List(Of clsColumnHeaderDisplay)
For i As Integer = grdData.CurrentWorksheet.SelectionRange.Col To grdData.CurrentWorksheet.SelectionRange.Col + grdData.CurrentWorksheet.SelectionRange.Cols - 1
Expand Down Expand Up @@ -309,10 +339,12 @@ Public Class ucrDataViewReoGrid
' Check if the row index is within the valid range
If rowNumber >= 0 AndAlso rowNumber < currWorkSheet.RowCount Then
If bApplyToRows Then
' Apply the row style to the entire row
currWorkSheet.Cells(rowNumber, colIndex).Style.BackColor = color
For i As Integer = 0 To currWorkSheet.ColumnCount - 1
' Apply the row style to the entire row
currWorkSheet.Cells(rowNumber, i).Style.BackColor = color
Next
Else
currWorkSheet.SetRangeStyles(New RangePosition(rowNumber, 0, 1, colIndex), rowStyle)
currWorkSheet.Cells(rowNumber, colIndex).Style.BackColor = color
End If
End If
Next
Expand Down
7 changes: 5 additions & 2 deletions instat/UserControls/DataGrid/ReoGrid/ucrReoGrid.vb
Original file line number Diff line number Diff line change
Expand Up @@ -139,8 +139,11 @@ Public MustInherit Class ucrReoGrid
For i = grdData.Worksheets.Count - 1 To 0 Step -1
Dim iGridWorkheetsPosition As Integer = i 'Needed to prevent warning
If _clsDataBook.DataFrames.Where(Function(x) x.strName = grdData.Worksheets(iGridWorkheetsPosition).Name).Count = 0 Then
grdData.RemoveWorksheet(i)
bDeleted = True
' Check if we are deleting the last worksheet
If grdData.Worksheets.Count > 1 Then
grdData.RemoveWorksheet(i)
bDeleted = True
End If
End If
Next
' Force the grid to refresh if a sheet has been deleted as there is sometimes a UI problem otherwise.
Expand Down
35 changes: 32 additions & 3 deletions instat/clsGgplotDefaults.vb
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,17 @@ Public Class GgplotDefaults
End Get
End Property

Public Shared ReadOnly Property clsXScaleDiscreteFunction As RFunction
Get
Dim clsXlabScalesTempFunc As New RFunction

clsXlabScalesTempFunc.SetPackageName("ggplot2")

clsXlabScalesTempFunc.SetRCommand("scale_x_discrete")
Return clsXlabScalesTempFunc
End Get
End Property

Public Shared ReadOnly Property clsYScalecontinuousFunction As RFunction
Get
Dim clsYlabScalesTempFunc As New RFunction
Expand All @@ -115,6 +126,17 @@ Public Class GgplotDefaults
End Get
End Property

Public Shared ReadOnly Property clsYScaleDiscreteFunction As RFunction
Get
Dim clsYlabScalesTempFunc As New RFunction

clsYlabScalesTempFunc.SetPackageName("ggplot2")
clsYlabScalesTempFunc.SetRCommand("scale_y_discrete")

Return clsYlabScalesTempFunc
End Get
End Property

Public Shared ReadOnly Property clsXScaleDateFunction As RFunction
Get
Dim clsXScaleDateFunctionTemp As New RFunction
Expand Down Expand Up @@ -222,7 +244,6 @@ Public Class GgplotDefaults
dctTemp.Add("caption", clsElementText.Clone())
dctTemp.Add("tag", clsElementText.Clone())
dctTemp.Add("colour", clsElementText.Clone())

'dctTemp.Add("aspect.ratio", clsElementText.Clone())
dctTemp.Add("axis.title", clsElementText.Clone())
dctTemp.Add("axis.title.x", clsElementText.Clone())
Expand Down Expand Up @@ -275,7 +296,6 @@ Public Class GgplotDefaults
dctTemp.Add("plot.title", clsElementText.Clone())
dctTemp.Add("plot.subtitle", clsElementText.Clone())
dctTemp.Add("plot.caption", clsElementText.Clone())
dctTemp.Add("plot.tag", clsElementText.Clone())
dctTemp.Add("plot.margin", clsUnit.Clone())
dctTemp.Add("strip.background", clsElementRect.Clone())
' dctTemp.Add("strip.placement", clsElementLine.Clone())
Expand Down Expand Up @@ -427,6 +447,14 @@ Public Class GgplotDefaults
End Get
End Property

Public Shared ReadOnly Property dctDropUnusedLevels As Dictionary(Of String, String)
Get
Dim dctTempDropUnusedLevels As New Dictionary(Of String, String)
dctTempDropUnusedLevels.Add("TRUE", Chr(34) & "TRUE" & Chr(34))
dctTempDropUnusedLevels.Add("FALSE", Chr(34) & "FALSE" & Chr(34))
Return dctTempDropUnusedLevels
End Get
End Property

Public Shared ReadOnly Property dctXPosition As Dictionary(Of String, String)
Get
Expand Down Expand Up @@ -466,4 +494,5 @@ Public Class GgplotDefaults
Return dctDateStartMonths
End Get
End Property
End Class
End Class

12 changes: 12 additions & 0 deletions instat/clsInstatOptions.vb
Original file line number Diff line number Diff line change
Expand Up @@ -52,11 +52,13 @@ Imports RDotNet
Public strClimsoftPort As String
Public strClimsoftUsername As String
Public iMaxOutputsHeight As Nullable(Of Integer)
Public bRemindLaterOption As Nullable(Of Boolean)

Public Sub New(Optional bSetOptions As Boolean = True)
'TODO Is this sensible to do in constructor?
bIncludeRDefaultParameters = clsInstatOptionsDefaults.DEFAULTbIncludeRDefaultParameters
bCommandsinOutput = clsInstatOptionsDefaults.DEFAULTbCommandsinOutput
bRemindLaterOption = clsInstatOptionsDefaults.DEFAULTbRemindLaterOption
bIncludeCommentDefault = clsInstatOptionsDefaults.DEFAULTbIncludeCommentDefault
bShowClimaticMenu = clsInstatOptionsDefaults.DEFAULTbShowClimaticMenu
bShowStructuredMenu = clsInstatOptionsDefaults.DEFAULTbShowStructuredMenu
Expand Down Expand Up @@ -148,6 +150,12 @@ Imports RDotNet
SetCommandInOutpt(clsInstatOptionsDefaults.DEFAULTbCommandsinOutput)
End If

If bRemindLaterOption.HasValue Then
SetRemindLaterOption(bRemindLaterOption)
Else
SetRemindLaterOption(clsInstatOptionsDefaults.DEFAULTbRemindLaterOption)
End If

If strComment Is Nothing Then
SetComment(Translations.GetTranslation(clsInstatOptionsDefaults.DEFAULTstrComment))
End If
Expand Down Expand Up @@ -463,6 +471,10 @@ Imports RDotNet
frmMain.clsRLink.strGraphDisplayOption = strGraphDisplayOption
End Sub

Public Sub SetRemindLaterOption(bRemind As Boolean)
bRemindLaterOption = bRemind
End Sub

Public Sub SetCommandInOutpt(bCommand As Boolean)
bCommandsinOutput = bCommand
frmMain.clsRLink.bShowCommands = bCommandsinOutput
Expand Down
1 change: 1 addition & 0 deletions instat/clsInstatOptionsDefaults.vb
Original file line number Diff line number Diff line change
Expand Up @@ -54,4 +54,5 @@ Public Class clsInstatOptionsDefaults
Public Shared ReadOnly DEFAULTstrClimsoftPort As String = "3308"
Public Shared ReadOnly DEFAULTstrClimsoftUsername As String = "root"
Public Shared ReadOnly DEFAULTiMaxOutputsHeight As Integer = 500
Public Shared ReadOnly DEFAULTbRemindLaterOption As Boolean = False
End Class
Loading

0 comments on commit 0746285

Please sign in to comment.