diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index aaa2ecb7..01c704aa 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -162,7 +162,10 @@ jobs: path: . - name: Install PowerShell - run: brew install --cask powershell + run: | + if ! command -v pwsh >/dev/null 2>&1; then + brew install powershell + fi - name: Install PowerShell modules run: | diff --git a/Build/Build-Module.ps1 b/Build/Build-Module.ps1 index 30dee748..c5b4611b 100644 --- a/Build/Build-Module.ps1 +++ b/Build/Build-Module.ps1 @@ -71,11 +71,9 @@ New-ConfigurationFormat -ApplyTo 'DefaultPSD1', 'OnMergePSD1' -PSD1Style 'Minimal' # configuration for documentation, at the same time it enables documentation processing $documentationConfiguration = @{ - Enable = $true - StartClean = $true - UpdateWhenNew = $true - PathReadme = 'Docs\Readme.md' - Path = 'Docs' + Enable = $true + PathReadme = 'Docs\Readme.md' + Path = 'Docs' } if ((Get-Command New-ConfigurationDocumentation).Parameters.ContainsKey('SyncExternalHelpToProjectRoot')) { diff --git a/Docs/New-ChartArea.md b/Docs/New-ChartArea.md new file mode 100644 index 00000000..3e50ed52 --- /dev/null +++ b/Docs/New-ChartArea.md @@ -0,0 +1,156 @@ +--- +external help file: PSWriteHTML-help.xml +Module Name: PSWriteHTML +online version: https://github.com/EvotecIT/PSWriteHTML +schema: 2.0.0 +--- +# New-ChartArea +## SYNOPSIS +Adds an area series to a chart. + +## SYNTAX +### __AllParameterSets +```powershell +New-ChartArea [-Name] [-Value] [[-Color] ] [[-Curve] ] [[-Width] ] [[-Cap] ] [[-Dash] ] [] +``` + +## DESCRIPTION +Adds an ApexCharts area series. Use New-ChartAxisX to provide categories, +datetime values, or numeric axis settings when needed. + +## EXAMPLES + +### EXAMPLE 1 +```powershell +PS > New-ChartArea -Name 'Revenue' -Value 10, 20, 18 -Color Blue -Curve smooth +``` + + +## PARAMETERS + +### -Cap +Stroke cap style. + +```yaml +Type: String +Parameter Sets: __AllParameterSets +Aliases: +Possible values: butt, square, round + +Required: False +Position: 5 +Default value: None +Accept pipeline input: False +Accept wildcard characters: True +``` + +### -Color +Series color. + +```yaml +Type: String +Parameter Sets: __AllParameterSets +Aliases: +Possible values: + +Required: False +Position: 2 +Default value: None +Accept pipeline input: False +Accept wildcard characters: True +``` + +### -Curve +Stroke curve style. + +```yaml +Type: Object +Parameter Sets: __AllParameterSets +Aliases: +Possible values: straight, smooth, stepline + +Required: False +Position: 3 +Default value: None +Accept pipeline input: False +Accept wildcard characters: True +``` + +### -Dash +Stroke dash spacing. + +```yaml +Type: Nullable`1 +Parameter Sets: __AllParameterSets +Aliases: +Possible values: + +Required: False +Position: 6 +Default value: None +Accept pipeline input: False +Accept wildcard characters: True +``` + +### -Name +Name of the area series. + +```yaml +Type: String +Parameter Sets: __AllParameterSets +Aliases: +Possible values: + +Required: True +Position: 0 +Default value: None +Accept pipeline input: False +Accept wildcard characters: True +``` + +### -Value +Values to display in the area series. + +```yaml +Type: Object +Parameter Sets: __AllParameterSets +Aliases: +Possible values: + +Required: True +Position: 1 +Default value: None +Accept pipeline input: False +Accept wildcard characters: True +``` + +### -Width +Stroke width. + +```yaml +Type: Nullable`1 +Parameter Sets: __AllParameterSets +Aliases: +Possible values: + +Required: False +Position: 4 +Default value: None +Accept pipeline input: False +Accept wildcard characters: True +``` + +### CommonParameters +This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). + +## INPUTS + +- `None` + +## OUTPUTS + +- `None` + +## RELATED LINKS + +- None diff --git a/Docs/New-ChartBubble.md b/Docs/New-ChartBubble.md new file mode 100644 index 00000000..07c5b239 --- /dev/null +++ b/Docs/New-ChartBubble.md @@ -0,0 +1,140 @@ +--- +external help file: PSWriteHTML-help.xml +Module Name: PSWriteHTML +online version: https://github.com/EvotecIT/PSWriteHTML +schema: 2.0.0 +--- +# New-ChartBubble +## SYNOPSIS +Adds a bubble series to a chart. + +## SYNTAX +### __AllParameterSets +```powershell +New-ChartBubble [-Name] [[-X] ] [[-Y] ] [[-Z] ] [[-Data] ] [[-Color] ] [] +``` + +## DESCRIPTION +Adds an ApexCharts bubble series. Provide X, Y, and Z arrays for the common +case, or pass raw ApexCharts-compatible points through Data. + +## EXAMPLES + +### EXAMPLE 1 +```powershell +PS > New-ChartBubble -Name 'Risk' -X 1, 2, 3 -Y 20, 30, 15 -Z 5, 12, 8 -Color Orange +``` + + +## PARAMETERS + +### -Color +{{ Fill Color Description }} + +```yaml +Type: String +Parameter Sets: __AllParameterSets +Aliases: +Possible values: + +Required: False +Position: 5 +Default value: None +Accept pipeline input: False +Accept wildcard characters: True +``` + +### -Data +{{ Fill Data Description }} + +```yaml +Type: Object +Parameter Sets: __AllParameterSets +Aliases: +Possible values: + +Required: False +Position: 4 +Default value: None +Accept pipeline input: False +Accept wildcard characters: True +``` + +### -Name +{{ Fill Name Description }} + +```yaml +Type: String +Parameter Sets: __AllParameterSets +Aliases: +Possible values: + +Required: True +Position: 0 +Default value: None +Accept pipeline input: False +Accept wildcard characters: True +``` + +### -X +{{ Fill X Description }} + +```yaml +Type: Object[] +Parameter Sets: __AllParameterSets +Aliases: +Possible values: + +Required: False +Position: 1 +Default value: None +Accept pipeline input: False +Accept wildcard characters: True +``` + +### -Y +{{ Fill Y Description }} + +```yaml +Type: Object[] +Parameter Sets: __AllParameterSets +Aliases: +Possible values: + +Required: False +Position: 2 +Default value: None +Accept pipeline input: False +Accept wildcard characters: True +``` + +### -Z +{{ Fill Z Description }} + +```yaml +Type: Object[] +Parameter Sets: __AllParameterSets +Aliases: +Possible values: + +Required: False +Position: 3 +Default value: None +Accept pipeline input: False +Accept wildcard characters: True +``` + +### CommonParameters +This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). + +## INPUTS + +- `None` + +## OUTPUTS + +- `None` + +## RELATED LINKS + +- None diff --git a/Docs/New-ChartHeatmap.md b/Docs/New-ChartHeatmap.md new file mode 100644 index 00000000..e468d607 --- /dev/null +++ b/Docs/New-ChartHeatmap.md @@ -0,0 +1,124 @@ +--- +external help file: PSWriteHTML-help.xml +Module Name: PSWriteHTML +online version: https://github.com/EvotecIT/PSWriteHTML +schema: 2.0.0 +--- +# New-ChartHeatmap +## SYNOPSIS +Adds a heatmap row series to a chart. + +## SYNTAX +### __AllParameterSets +```powershell +New-ChartHeatmap [-Name] [[-X] ] [[-Y] ] [[-Data] ] [[-Color] ] [] +``` + +## DESCRIPTION +Adds one ApexCharts heatmap row. Use X and Y arrays for category/value pairs, +a dictionary for category/value data, or raw ApexCharts-compatible points. + +## EXAMPLES + +### EXAMPLE 1 +```powershell +PS > New-ChartHeatmap -Name 'Monday' -X 'AM', 'PM' -Y 12, 18 +``` + + +## PARAMETERS + +### -Color +{{ Fill Color Description }} + +```yaml +Type: String +Parameter Sets: __AllParameterSets +Aliases: +Possible values: + +Required: False +Position: 4 +Default value: None +Accept pipeline input: False +Accept wildcard characters: True +``` + +### -Data +{{ Fill Data Description }} + +```yaml +Type: Object +Parameter Sets: __AllParameterSets +Aliases: +Possible values: + +Required: False +Position: 3 +Default value: None +Accept pipeline input: False +Accept wildcard characters: True +``` + +### -Name +{{ Fill Name Description }} + +```yaml +Type: String +Parameter Sets: __AllParameterSets +Aliases: +Possible values: + +Required: True +Position: 0 +Default value: None +Accept pipeline input: False +Accept wildcard characters: True +``` + +### -X +{{ Fill X Description }} + +```yaml +Type: Object[] +Parameter Sets: __AllParameterSets +Aliases: +Possible values: + +Required: False +Position: 1 +Default value: None +Accept pipeline input: False +Accept wildcard characters: True +``` + +### -Y +{{ Fill Y Description }} + +```yaml +Type: Object[] +Parameter Sets: __AllParameterSets +Aliases: +Possible values: + +Required: False +Position: 2 +Default value: None +Accept pipeline input: False +Accept wildcard characters: True +``` + +### CommonParameters +This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). + +## INPUTS + +- `None` + +## OUTPUTS + +- `None` + +## RELATED LINKS + +- None diff --git a/Docs/New-ChartLabel.md b/Docs/New-ChartLabel.md new file mode 100644 index 00000000..6afcd4f0 --- /dev/null +++ b/Docs/New-ChartLabel.md @@ -0,0 +1,60 @@ +--- +external help file: PSWriteHTML-help.xml +Module Name: PSWriteHTML +online version: https://github.com/EvotecIT/PSWriteHTML +schema: 2.0.0 +--- +# New-ChartLabel +## SYNOPSIS +Overrides chart labels for charts that support top-level ApexCharts labels. + +## SYNTAX +### __AllParameterSets +```powershell +New-ChartLabel [-Names] [] +``` + +## DESCRIPTION +Provides a friendly way to set labels, especially for pie and donut charts +when labels should be supplied separately from the value commands. + +## EXAMPLES + +### EXAMPLE 1 +```powershell +PS > New-ChartLabel -Name 'Passed', 'Failed', 'Skipped' +``` + + +## PARAMETERS + +### -Names +{{ Fill Names Description }} + +```yaml +Type: String[] +Parameter Sets: __AllParameterSets +Aliases: Name +Possible values: + +Required: True +Position: 0 +Default value: None +Accept pipeline input: False +Accept wildcard characters: True +``` + +### CommonParameters +This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). + +## INPUTS + +- `None` + +## OUTPUTS + +- `None` + +## RELATED LINKS + +- None diff --git a/Docs/New-ChartRadar.md b/Docs/New-ChartRadar.md new file mode 100644 index 00000000..89018e96 --- /dev/null +++ b/Docs/New-ChartRadar.md @@ -0,0 +1,91 @@ +--- +external help file: PSWriteHTML-help.xml +Module Name: PSWriteHTML +online version: https://github.com/EvotecIT/PSWriteHTML +schema: 2.0.0 +--- +# New-ChartRadar +## SYNOPSIS +Adds a radar series to a chart. + +## SYNTAX +### __AllParameterSets +```powershell +New-ChartRadar [-Name] [-Value] [[-Color] ] [] +``` + +## DESCRIPTION +Adds an ApexCharts radar series. Use New-ChartAxisX to provide spoke labels. + +## EXAMPLES + +### EXAMPLE 1 +```powershell +PS > New-ChartRadar -Name 'Coverage' -Value 70, 85, 62 -Color Green +``` + + +## PARAMETERS + +### -Color +{{ Fill Color Description }} + +```yaml +Type: String +Parameter Sets: __AllParameterSets +Aliases: +Possible values: + +Required: False +Position: 2 +Default value: None +Accept pipeline input: False +Accept wildcard characters: True +``` + +### -Name +{{ Fill Name Description }} + +```yaml +Type: String +Parameter Sets: __AllParameterSets +Aliases: +Possible values: + +Required: True +Position: 0 +Default value: None +Accept pipeline input: False +Accept wildcard characters: True +``` + +### -Value +{{ Fill Value Description }} + +```yaml +Type: Object +Parameter Sets: __AllParameterSets +Aliases: +Possible values: + +Required: True +Position: 1 +Default value: None +Accept pipeline input: False +Accept wildcard characters: True +``` + +### CommonParameters +This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). + +## INPUTS + +- `None` + +## OUTPUTS + +- `None` + +## RELATED LINKS + +- None diff --git a/Docs/New-ChartScatter.md b/Docs/New-ChartScatter.md new file mode 100644 index 00000000..0213a784 --- /dev/null +++ b/Docs/New-ChartScatter.md @@ -0,0 +1,124 @@ +--- +external help file: PSWriteHTML-help.xml +Module Name: PSWriteHTML +online version: https://github.com/EvotecIT/PSWriteHTML +schema: 2.0.0 +--- +# New-ChartScatter +## SYNOPSIS +Adds a scatter series to a chart. + +## SYNTAX +### __AllParameterSets +```powershell +New-ChartScatter [-Name] [[-X] ] [[-Y] ] [[-Data] ] [[-Color] ] [] +``` + +## DESCRIPTION +Adds an ApexCharts scatter series. Provide X and Y arrays for the common case, +or pass raw ApexCharts-compatible points through Data. + +## EXAMPLES + +### EXAMPLE 1 +```powershell +PS > New-ChartScatter -Name 'Samples' -X 1, 2, 3 -Y 10, 25, 18 -Color Purple +``` + + +## PARAMETERS + +### -Color +{{ Fill Color Description }} + +```yaml +Type: String +Parameter Sets: __AllParameterSets +Aliases: +Possible values: + +Required: False +Position: 4 +Default value: None +Accept pipeline input: False +Accept wildcard characters: True +``` + +### -Data +{{ Fill Data Description }} + +```yaml +Type: Object +Parameter Sets: __AllParameterSets +Aliases: +Possible values: + +Required: False +Position: 3 +Default value: None +Accept pipeline input: False +Accept wildcard characters: True +``` + +### -Name +{{ Fill Name Description }} + +```yaml +Type: String +Parameter Sets: __AllParameterSets +Aliases: +Possible values: + +Required: True +Position: 0 +Default value: None +Accept pipeline input: False +Accept wildcard characters: True +``` + +### -X +{{ Fill X Description }} + +```yaml +Type: Object[] +Parameter Sets: __AllParameterSets +Aliases: +Possible values: + +Required: False +Position: 1 +Default value: None +Accept pipeline input: False +Accept wildcard characters: True +``` + +### -Y +{{ Fill Y Description }} + +```yaml +Type: Object[] +Parameter Sets: __AllParameterSets +Aliases: +Possible values: + +Required: False +Position: 2 +Default value: None +Accept pipeline input: False +Accept wildcard characters: True +``` + +### CommonParameters +This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). + +## INPUTS + +- `None` + +## OUTPUTS + +- `None` + +## RELATED LINKS + +- None diff --git a/Docs/New-TableFooter.md b/Docs/New-TableFooter.md new file mode 100644 index 00000000..7e8e0a57 --- /dev/null +++ b/Docs/New-TableFooter.md @@ -0,0 +1,317 @@ +--- +external help file: PSWriteHTML-help.xml +Module Name: PSWriteHTML +online version: https://github.com/EvotecIT/PSWriteHTML +schema: 2.0.0 +--- +# New-TableFooter +## SYNOPSIS +Creates a static table footer row. + +## SYNTAX +### __AllParameterSets +```powershell +New-TableFooter [[-Values] ] [[-ValueByColumn] ] [[-Color] ] [[-BackGroundColor] ] [[-FontSize] ] [[-FontWeight] ] [[-FontStyle] ] [[-FontVariant] ] [[-FontFamily] ] [[-Alignment] ] [[-TextDecoration] ] [[-TextTransform] ] [[-Direction] ] [[-VerticalAlignment] ] [[-BorderStyle] ] [[-BorderWidth] ] [[-BorderColor] ] [] +``` + +## DESCRIPTION +Creates a footer row for New-HTMLTable. Use Values when the footer follows the rendered column order, or ValueByColumn when footer values should be assigned by column name. + +## EXAMPLES + +### EXAMPLE 1 +```powershell +PS > New-HTMLTable -DataTable $Data { + New-TableFooter -ValueByColumn @{ Name = 'Total'; Amount = 42 } -FontWeight bold +} +``` + + +## PARAMETERS + +### -Alignment +Provide new text alignment. + +```yaml +Type: String +Parameter Sets: __AllParameterSets +Aliases: +Possible values: left, center, right, justify + +Required: False +Position: 9 +Default value: None +Accept pipeline input: False +Accept wildcard characters: True +``` + +### -BackGroundColor +Pick one of the 800 colors or provide a hex color code. + +```yaml +Type: String +Parameter Sets: __AllParameterSets +Aliases: +Possible values: + +Required: False +Position: 3 +Default value: None +Accept pipeline input: False +Accept wildcard characters: True +``` + +### -BorderColor +{{ Fill BorderColor Description }} + +```yaml +Type: String +Parameter Sets: __AllParameterSets +Aliases: +Possible values: + +Required: False +Position: 16 +Default value: None +Accept pipeline input: False +Accept wildcard characters: True +``` + +### -BorderStyle +{{ Fill BorderStyle Description }} + +```yaml +Type: String +Parameter Sets: __AllParameterSets +Aliases: +Possible values: none, hidden, dotted, dashed, solid, double, groove, ridge, inset, outset + +Required: False +Position: 14 +Default value: None +Accept pipeline input: False +Accept wildcard characters: True +``` + +### -BorderWidth +{{ Fill BorderWidth Description }} + +```yaml +Type: Object +Parameter Sets: __AllParameterSets +Aliases: +Possible values: + +Required: False +Position: 15 +Default value: None +Accept pipeline input: False +Accept wildcard characters: True +``` + +### -Color +Pick one of the 800 colors or provide a hex color code. + +```yaml +Type: String +Parameter Sets: __AllParameterSets +Aliases: +Possible values: + +Required: False +Position: 2 +Default value: None +Accept pipeline input: False +Accept wildcard characters: True +``` + +### -Direction +{{ Fill Direction Description }} + +```yaml +Type: String +Parameter Sets: __AllParameterSets +Aliases: +Possible values: rtl, ltr + +Required: False +Position: 12 +Default value: None +Accept pipeline input: False +Accept wildcard characters: True +``` + +### -FontFamily +{{ Fill FontFamily Description }} + +```yaml +Type: String +Parameter Sets: __AllParameterSets +Aliases: +Possible values: + +Required: False +Position: 8 +Default value: None +Accept pipeline input: False +Accept wildcard characters: True +``` + +### -FontSize +Provide new font size. + +```yaml +Type: Object +Parameter Sets: __AllParameterSets +Aliases: +Possible values: + +Required: False +Position: 4 +Default value: None +Accept pipeline input: False +Accept wildcard characters: True +``` + +### -FontStyle +{{ Fill FontStyle Description }} + +```yaml +Type: String +Parameter Sets: __AllParameterSets +Aliases: +Possible values: normal, italic, oblique + +Required: False +Position: 6 +Default value: None +Accept pipeline input: False +Accept wildcard characters: True +``` + +### -FontVariant +{{ Fill FontVariant Description }} + +```yaml +Type: String +Parameter Sets: __AllParameterSets +Aliases: +Possible values: normal, small-caps + +Required: False +Position: 7 +Default value: None +Accept pipeline input: False +Accept wildcard characters: True +``` + +### -FontWeight +Provide new font weight. + +```yaml +Type: String +Parameter Sets: __AllParameterSets +Aliases: +Possible values: normal, bold, bolder, lighter, 100, 200, 300, 400, 500, 600, 700, 800, 900 + +Required: False +Position: 5 +Default value: None +Accept pipeline input: False +Accept wildcard characters: True +``` + +### -TextDecoration +{{ Fill TextDecoration Description }} + +```yaml +Type: String +Parameter Sets: __AllParameterSets +Aliases: +Possible values: none, line-through, overline, underline + +Required: False +Position: 10 +Default value: None +Accept pipeline input: False +Accept wildcard characters: True +``` + +### -TextTransform +{{ Fill TextTransform Description }} + +```yaml +Type: String +Parameter Sets: __AllParameterSets +Aliases: +Possible values: uppercase, lowercase, capitalize + +Required: False +Position: 11 +Default value: None +Accept pipeline input: False +Accept wildcard characters: True +``` + +### -ValueByColumn +Footer cell values keyed by rendered column name. + +```yaml +Type: IDictionary +Parameter Sets: __AllParameterSets +Aliases: +Possible values: + +Required: False +Position: 1 +Default value: None +Accept pipeline input: False +Accept wildcard characters: True +``` + +### -Values +Footer cell values in rendered column order. + +```yaml +Type: Object[] +Parameter Sets: __AllParameterSets +Aliases: +Possible values: + +Required: False +Position: 0 +Default value: None +Accept pipeline input: False +Accept wildcard characters: True +``` + +### -VerticalAlignment +{{ Fill VerticalAlignment Description }} + +```yaml +Type: String +Parameter Sets: __AllParameterSets +Aliases: +Possible values: baseline, sub, super, text-top, text-bottom, middle, top, bottom + +Required: False +Position: 13 +Default value: None +Accept pipeline input: False +Accept wildcard characters: True +``` + +### CommonParameters +This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). + +## INPUTS + +- `None` + +## OUTPUTS + +- `None` + +## RELATED LINKS + +- None diff --git a/Examples/Example-Charts/Example-ChartsAdditionalTypes.ps1 b/Examples/Example-Charts/Example-ChartsAdditionalTypes.ps1 new file mode 100644 index 00000000..373afb7d --- /dev/null +++ b/Examples/Example-Charts/Example-ChartsAdditionalTypes.ps1 @@ -0,0 +1,48 @@ +Import-Module .\PSWriteHTML.psd1 -Force + +$FilePath = Join-Path $PSScriptRoot 'Example-ChartsAdditionalTypes.html' + +New-HTML -TitleText 'Additional Chart Types' -FilePath $FilePath -Online { + New-HTMLSection -HeaderText 'Area chart' { + New-HTMLChart -Title 'Quarterly Revenue' { + New-ChartAxisX -Name 'Q1', 'Q2', 'Q3', 'Q4' + New-ChartArea -Name 'Revenue' -Value 42, 55, 48, 64 -Color DodgerBlue -Curve smooth + } + } + + New-HTMLSection -HeaderText 'Scatter and bubble charts' { + New-HTMLPanel { + New-HTMLChart -Title 'Sample Distribution' { + New-ChartScatter -Name 'Samples' -X 1, 2, 3, 4 -Y 8, 12, 7, 15 -Color Purple + } + } + New-HTMLPanel { + New-HTMLChart -Title 'Risk Size' { + New-ChartBubble -Name 'Risk' -X 1, 2, 3, 4 -Y 15, 22, 13, 28 -Z 4, 8, 5, 12 -Color Orange + } + } + } + + New-HTMLSection -HeaderText 'Heatmap and radar charts' { + New-HTMLPanel { + New-HTMLChart -Title 'Daily Load' { + New-ChartHeatmap -Name 'Monday' -X 'AM', 'Noon', 'PM' -Y 12, 18, 14 + New-ChartHeatmap -Name 'Tuesday' -Data ([ordered] @{ AM = 9; Noon = 20; PM = 16 }) + } + } + New-HTMLPanel { + New-HTMLChart -Title 'Coverage' { + New-ChartAxisX -Name 'Identity', 'Mail', 'Devices', 'Apps' + New-ChartRadar -Name 'Tenant A' -Value 70, 85, 62, 91 -Color SeaGreen + } + } + } + + New-HTMLSection -HeaderText 'Custom pie labels' { + New-HTMLChart -Title 'Status' { + New-ChartPie -Name 'One' -Value 10 -Color SeaGreen + New-ChartPie -Name 'Two' -Value 3 -Color FireBrick + New-ChartLabel -Name 'Healthy', 'Needs attention' + } + } +} diff --git a/Examples/Example-IssueFixes/Example-IssueFixes-ChartsTablesTabs.ps1 b/Examples/Example-IssueFixes/Example-IssueFixes-ChartsTablesTabs.ps1 new file mode 100644 index 00000000..dee2f688 --- /dev/null +++ b/Examples/Example-IssueFixes/Example-IssueFixes-ChartsTablesTabs.ps1 @@ -0,0 +1,82 @@ +Import-Module .\PSWriteHTML.psd1 -Force + +$FilePath = Join-Path $PSScriptRoot 'Example-IssueFixes-ChartsTablesTabs.html' + +$Incidents = @( + [PSCustomObject]@{ Team = 'Identity'; Severity = 'High'; Owner = 'Ava'; Notes = "MFA policy`nConditional Access review"; Count = 7; Hours = 12.5 } + [PSCustomObject]@{ Team = 'Identity'; Severity = 'Medium'; Owner = 'Ben'; Notes = "Lifecycle workflow`nJoiner validation"; Count = 4; Hours = 6.0 } + [PSCustomObject]@{ Team = 'Messaging'; Severity = 'High'; Owner = 'Cara'; Notes = "Transport rule`nExternal sender check"; Count = 5; Hours = 8.5 } + [PSCustomObject]@{ Team = 'Devices'; Severity = 'Low'; Owner = 'Drew'; Notes = "Enrollment profile`nCleanup"; Count = 2; Hours = 3.0 } +) + +New-HTML -TitleText 'PSWriteHTML issue fix smoke page' -FilePath $FilePath -Online { + New-HTMLSection -HeaderText 'Charts' { + New-HTMLPanel { + New-HTMLChart -Title 'Area and scatter' { + New-ChartAxisX -Name 'Jan', 'Feb', 'Mar', 'Apr' + New-ChartArea -Name 'Resolved' -Value 21, 28, 24, 36 -Color DodgerBlue -Curve smooth + } + } + New-HTMLPanel { + New-HTMLChart -Title 'Risk spread' { + New-ChartBubble -Name 'Teams' -X 1, 2, 3, 4 -Y 3, 7, 5, 11 -Z 3, 6, 4, 8 -Color Orange + } + } + New-HTMLPanel { + New-HTMLChart -Title 'Coverage radar' { + New-ChartAxisX -Name 'Identity', 'Mail', 'Devices', 'Apps' + New-ChartRadar -Name 'Current' -Value 72, 64, 81, 69 -Color SeaGreen + } + } + } + + New-HTMLSection -HeaderText 'Tables' { + New-HTMLTable -DataTable $Incidents -Title 'Operational queue' -Filtering -FilteringLocation Top -DisableStateSave { + New-TableButtonSearchBuilder -ButtonName 'Advanced filters' -DepthLimit 3 + New-TableHeader -Names 'Team', 'Severity', 'Owner', 'Notes', 'Count', 'Hours' -BackGroundColor '#f6f8fa' -BorderStyle solid -BorderWidth 2 -BorderColor '#4b5563' + New-TableContent -ColumnName 'Notes' -VerticalAlignment top -WordBreak break-word + New-TableColumnOption -ColumnIndex 0 -Width '18%' + New-TableColumnOption -ColumnIndex 1 -Width '14%' + New-TableColumnOption -ColumnIndex 3 -Width '32%' + New-TableRowGrouping -Name 'Team' -SortOrder Ascending -HideGroupedColumn -Color '#1f2937' -BackgroundColor '#dbeafe' + New-TableFooter -ValueByColumn @{ + Severity = 'Totals' + Count = ($Incidents | Measure-Object -Property Count -Sum).Sum + Hours = ($Incidents | Measure-Object -Property Hours -Sum).Sum + } -FontWeight bold -BackGroundColor '#f3f4f6' -BorderStyle solid -BorderWidth 2 -BorderColor '#4b5563' + } + } + + New-HTMLSection -HeaderText 'Summary and tabs' { + New-HTMLPanel { + New-HTMLSummary { + New-HTMLSummaryItem -Text 'Title-less summaries no longer reserve a blank heading' + New-HTMLSummaryItem -Text 'The first visible line should be this summary item' + } + } + New-HTMLPanel { + New-HTMLTabPanel -Theme pills -DisableURLhash { + New-HTMLTab -Name 'First' { + New-HTMLText -Text 'This tab exists, but should not be selected initially.' + } + New-HTMLTab -Name 'Default tab' -Default { + New-HTMLText -Text 'This tab is selected through New-HTMLTab -Default.' + } + New-HTMLTab -Name 'Last' { + New-HTMLText -Text 'A normal trailing tab.' + } + } + } + } + + New-HTMLSection -HeaderText 'Diagram link widths' { + New-HTMLDiagram -Height '360px' { + New-DiagramNode -Id 1 -Label 'Intake' -ColorBackground '#bfdbfe' + New-DiagramNode -Id 2 -Label 'Triage' -ColorBackground '#bbf7d0' + New-DiagramNode -Id 3 -Label 'Resolve' -ColorBackground '#fde68a' + New-DiagramLink -From 1 -To 2 -Label 'normal' -Width 2 -HoverWidth 4 + New-DiagramLink -From 2 -To 3 -Label 'weighted' -Value 7 -ArrowsToEnabled + New-DiagramOptionsLinks -Width 2 -HoverWidth 5 -SmoothType dynamic + } + } +} diff --git a/PSWriteHTML.psd1 b/PSWriteHTML.psd1 index 0fcc1bab..056683a9 100644 --- a/PSWriteHTML.psd1 +++ b/PSWriteHTML.psd1 @@ -1,29 +1,29 @@ -@{ - AliasesToExport = @('EmailHTML', 'Add-JavaScript', 'New-JavaScript', 'Add-JS', 'Add-CSS', 'ConvertTo-CSS', 'CalendarEvent', 'ChartCategory', 'ChartAxisX', 'New-ChartCategory', 'ChartAxisY', 'ChartBar', 'ChartBarOptions', 'New-ChartFill', 'ChartDonut', 'ChartGrid', 'ChartLegend', 'ChartLine', 'ChartPie', 'ChartRadial', 'ChartSpark', 'ChartTheme', 'ChartTimeLine', 'ChartToolbar', 'DiagramEdge', 'DiagramEdges', 'New-DiagramEdge', 'DiagramLink', 'DiagramNode', 'DiagramOptionsInteraction', 'DiagramOptionsLayout', 'DiagramOptionsEdges', 'New-DiagramOptionsEdges', 'DiagramOptionsLinks', 'DiagramOptionsManipulation', 'DiagramOptionsNodes', 'DiagramOptionsPhysics', 'HierarchicalTreeNode', 'Dashboard', 'New-HTMLLink', 'Calendar', 'Chart', 'Container', 'Diagram', 'New-Diagram', 'Footer', 'Header', 'Image', 'EmailImage', 'InfoCard', 'EmailList', 'Main', 'New-HTMLMermeid', 'New-HTMLColumn', 'Panel', 'New-HTMLPanelOption', 'New-PanelOption', 'PanelOption', 'New-PanelStyle', 'PanelStyle', 'New-HTMLContent', 'Section', 'New-HTMLSectionOptions', 'SectionOption', 'New-HTMLSectionOption', 'Tab', 'Table', 'EmailTable', 'New-TableOption', 'TableOption', 'EmailTableOption', 'EmailTableStyle', 'TableStyle', 'New-TableStyle', 'TabOptions', 'New-TabOption', 'New-HTMLTabOptions', 'TabOption', 'New-HTMLTabOption', 'TabStyle', 'HTMLText', 'Text', 'EmailText', 'EmailTextBox', 'New-HTMLNavItem', 'New-HTMLNavLink', 'New-HTMLNavTopMenu', 'TableAlphabetSearch', 'New-HTMLTableAlphabetSearch', 'TableButtonColumnVisibility', 'New-HTMLTableButtonColumnVisibility', 'TableButtonCopy', 'EmailTableButtonCopy', 'New-HTMLTableButtonCopy', 'TableButtonCSV', 'EmailTableButtonCSV', 'New-HTMLTableButtonCSV', 'TableButtonExcel', 'EmailTableButtonExcel', 'New-HTMLTableButtonExcel', 'TableButtonPageLength', 'EmailTableButtonPageLength', 'New-HTMLTableButtonPageLength', 'TableButtonPDF', 'EmailTableButtonPDF', 'New-HTMLTableButtonPDF', 'TableButtonPrint', 'EmailTableButtonPrint', 'New-HTMLTableButtonPrint', 'TableButtonSearchBuilder', 'EmailTableButtonSearchBuilder', 'New-HTMLTableButtonSearchBuilder', 'EmailTableColumnOption', 'TableColumnOption', 'New-HTMLTableColumnOption', 'EmailTableCondition', 'TableConditionalFormatting', 'New-HTMLTableCondition', 'TableCondition', 'EmailTableConditionGroup', 'TableConditionGroup', 'New-HTMLTableConditionGroup', 'TableContent', 'EmailTableContent', 'New-HTMLTableContent', 'TableHeader', 'EmailTableHeader', 'New-HTMLTableHeader', 'TablePercentageBar', 'New-HTMLTablePercentageBar', 'TableReplace', 'EmailTableReplace', 'New-HTMLTableReplace', 'TableRowGrouping', 'EmailTableRowGrouping', 'New-HTMLTableRowGrouping', 'Out-GridHtml', 'ohv') - Author = 'Przemyslaw Klys' - CmdletsToExport = @() - CompanyName = 'Evotec' - CompatiblePSEditions = @('Desktop', 'Core') - Copyright = '(c) 2011 - 2026 Przemyslaw Klys @ Evotec. All rights reserved.' - Description = 'PSWriteHTML is PowerShell Module to generate beautiful HTML reports, pages, emails without any knowledge of HTML, CSS or JavaScript. To get started basics PowerShell knowledge is required.' - FunctionsToExport = @('Add-HTML', 'Add-HTMLScript', 'Add-HTMLStyle', 'ConvertTo-CascadingStyleSheets', 'Email', 'EmailAttachment', 'EmailBCC', 'EmailBody', 'EmailCC', 'EmailFrom', 'EmailHeader', 'EmailLayout', 'EmailLayoutColumn', 'EmailLayoutRow', 'EmailListItem', 'EmailOptions', 'EmailReplyTo', 'EmailServer', 'EmailSubject', 'EmailTo', 'Enable-HTMLFeature', 'New-AccordionItem', 'New-CalendarEvent', 'New-CarouselSlide', 'New-ChartAxisX', 'New-ChartAxisY', 'New-ChartBar', 'New-ChartBarOptions', 'New-ChartDataLabel', 'New-ChartDesign', 'New-ChartDonut', 'New-ChartEvent', 'New-ChartGrid', 'New-ChartLegend', 'New-ChartLine', 'New-ChartMarker', 'New-ChartPie', 'New-ChartRadial', 'New-ChartRadialOptions', 'New-ChartSpark', 'New-ChartTheme', 'New-ChartTimeLine', 'New-ChartToolbar', 'New-ChartToolTip', 'New-DiagramEvent', 'New-DiagramLink', 'New-DiagramNode', 'New-DiagramOptionsInteraction', 'New-DiagramOptionsLayout', 'New-DiagramOptionsLinks', 'New-DiagramOptionsManipulation', 'New-DiagramOptionsNodes', 'New-DiagramOptionsPhysics', 'New-GageSector', 'New-HierarchicalTreeNode', 'New-HTML', 'New-HTMLAccordion', 'New-HTMLAnchor', 'New-HTMLCalendar', 'New-HTMLCarousel', 'New-HTMLCarouselStyle', 'New-HTMLChart', 'New-HTMLCodeBlock', 'New-HTMLContainer', 'New-HTMLDate', 'New-HTMLDiagram', 'New-HTMLFontIcon', 'New-HTMLFooter', 'New-HTMLFrame', 'New-HTMLGage', 'New-HTMLHeader', 'New-HTMLHeading', 'New-HTMLHierarchicalTree', 'New-HTMLHorizontalLine', 'New-HTMLImage', 'New-HTMLInfoCard', 'New-HTMLList', 'New-HTMLListItem', 'New-HTMLLogo', 'New-HTMLMain', 'New-HTMLMap', 'New-HTMLMarkdown', 'New-HTMLMermeidChart', 'New-HTMLNav', 'New-HTMLNavFloat', 'New-HTMLNavTop', 'New-HTMLOrgChart', 'New-HTMLPage', 'New-HTMLPanel', 'New-HTMLPanelStyle', 'New-HTMLQRCode', 'New-HTMLSection', 'New-HTMLSectionScrolling', 'New-HTMLSectionScrollingItem', 'New-HTMLSectionStyle', 'New-HTMLSpanStyle', 'New-HTMLStatus', 'New-HTMLStatusItem', 'New-HTMLSummary', 'New-HTMLSummaryItem', 'New-HTMLSummaryItemData', 'New-HTMLTab', 'New-HTMLTable', 'New-HTMLTableOption', 'New-HTMLTableStyle', 'New-HTMLTabPanel', 'New-HTMLTabPanelColor', 'New-HTMLTabStyle', 'New-HTMLTag', 'New-HTMLText', 'New-HTMLTextBox', 'New-HTMLTimeline', 'New-HTMLTimelineItem', 'New-HTMLToast', 'New-HTMLTree', 'New-HTMLTreeChildCounter', 'New-HTMLTreeNode', 'New-HTMLWinBox', 'New-HTMLWizard', 'New-HTMLWizardColor', 'New-HTMLWizardStep', 'New-MapArea', 'New-MapLegendOption', 'New-MapLegendSlice', 'New-MapPlot', 'New-NavFloatWidget', 'New-NavFloatWidgetItem', 'New-NavItem', 'New-NavLink', 'New-NavTopMenu', 'New-OrgChartNode', 'New-TableAlphabetSearch', 'New-TableButtonColumnVisibility', 'New-TableButtonCopy', 'New-TableButtonCSV', 'New-TableButtonExcel', 'New-TableButtonPageLength', 'New-TableButtonPDF', 'New-TableButtonPrint', 'New-TableButtonSearchBuilder', 'New-TableColumnOption', 'New-TableCondition', 'New-TableConditionGroup', 'New-TableContent', 'New-TableEvent', 'New-TableHeader', 'New-TableLanguage', 'New-TablePercentageBar', 'New-TablePercentageBarCondition', 'New-TableReplace', 'New-TableRowGrouping', 'Out-HtmlView', 'Save-HTML') - GUID = 'a7bdf640-f5cb-4acf-9de0-365b322d245c' - ModuleVersion = '1.42.0' - PowerShellVersion = '5.1' - PrivateData = @{ - PSData = @{ - IconUri = 'https://evotec.xyz/wp-content/uploads/2018/12/PSWriteHTML.png' - ProjectUri = 'https://github.com/EvotecIT/PSWriteHTML' - RequireLicenseAcceptance = $false - Tags = @('HTML', 'WWW', 'JavaScript', 'CSS', 'Reports', 'Reporting', 'Windows', 'MacOS', 'Linux') - ExternalModuleDependencies = @() - } - } - RequiredModules = @(@{ - Guid = 'ee272aa8-baaa-4edf-9f45-b6d6f7d844fe' - ModuleName = 'PSSharedGoods' - ModuleVersion = '0.0.312' - }) - RootModule = 'PSWriteHTML.psm1' - ScriptsToProcess = @() -} \ No newline at end of file +@{ + AliasesToExport = @('EmailHTML', 'Add-JavaScript', 'New-JavaScript', 'Add-JS', 'Add-CSS', 'ConvertTo-CSS', 'CalendarEvent', 'ChartCategory', 'ChartAxisX', 'ChartArea', 'New-ChartCategory', 'ChartAxisY', 'ChartBar', 'ChartBarOptions', 'ChartBubble', 'New-ChartFill', 'ChartDonut', 'ChartGrid', 'ChartHeatmap', 'ChartLabel', 'ChartLegend', 'ChartLine', 'ChartPie', 'ChartRadar', 'ChartRadial', 'ChartScatter', 'ChartSpark', 'ChartTheme', 'ChartTimeLine', 'ChartToolbar', 'DiagramEdge', 'DiagramEdges', 'New-DiagramEdge', 'DiagramLink', 'DiagramNode', 'DiagramOptionsInteraction', 'DiagramOptionsLayout', 'DiagramOptionsEdges', 'New-DiagramOptionsEdges', 'DiagramOptionsLinks', 'DiagramOptionsManipulation', 'DiagramOptionsNodes', 'DiagramOptionsPhysics', 'HierarchicalTreeNode', 'Dashboard', 'New-HTMLLink', 'Calendar', 'Chart', 'Container', 'Diagram', 'New-Diagram', 'Footer', 'Header', 'Image', 'EmailImage', 'InfoCard', 'EmailList', 'Main', 'New-HTMLMermeid', 'New-HTMLColumn', 'Panel', 'New-HTMLPanelOption', 'New-PanelOption', 'PanelOption', 'New-PanelStyle', 'PanelStyle', 'New-HTMLContent', 'Section', 'New-HTMLSectionOptions', 'SectionOption', 'New-HTMLSectionOption', 'Tab', 'Table', 'EmailTable', 'New-TableOption', 'TableOption', 'EmailTableOption', 'EmailTableStyle', 'TableStyle', 'New-TableStyle', 'TabOptions', 'New-TabOption', 'New-HTMLTabOptions', 'TabOption', 'New-HTMLTabOption', 'TabStyle', 'HTMLText', 'Text', 'EmailText', 'EmailTextBox', 'New-HTMLNavItem', 'New-HTMLNavLink', 'New-HTMLNavTopMenu', 'TableAlphabetSearch', 'New-HTMLTableAlphabetSearch', 'TableButtonColumnVisibility', 'New-HTMLTableButtonColumnVisibility', 'TableButtonCopy', 'EmailTableButtonCopy', 'New-HTMLTableButtonCopy', 'TableButtonCSV', 'EmailTableButtonCSV', 'New-HTMLTableButtonCSV', 'TableButtonExcel', 'EmailTableButtonExcel', 'New-HTMLTableButtonExcel', 'TableButtonPageLength', 'EmailTableButtonPageLength', 'New-HTMLTableButtonPageLength', 'TableButtonPDF', 'EmailTableButtonPDF', 'New-HTMLTableButtonPDF', 'TableButtonPrint', 'EmailTableButtonPrint', 'New-HTMLTableButtonPrint', 'TableButtonSearchBuilder', 'EmailTableButtonSearchBuilder', 'New-HTMLTableButtonSearchBuilder', 'EmailTableColumnOption', 'TableColumnOption', 'New-HTMLTableColumnOption', 'EmailTableCondition', 'TableConditionalFormatting', 'New-HTMLTableCondition', 'TableCondition', 'EmailTableConditionGroup', 'TableConditionGroup', 'New-HTMLTableConditionGroup', 'TableContent', 'EmailTableContent', 'New-HTMLTableContent', 'TableFooter', 'EmailTableFooter', 'New-HTMLTableFooter', 'TableHeader', 'EmailTableHeader', 'New-HTMLTableHeader', 'TablePercentageBar', 'New-HTMLTablePercentageBar', 'TableReplace', 'EmailTableReplace', 'New-HTMLTableReplace', 'TableRowGrouping', 'EmailTableRowGrouping', 'New-HTMLTableRowGrouping', 'Out-GridHtml', 'ohv') + Author = 'Przemyslaw Klys' + CmdletsToExport = @() + CompanyName = 'Evotec' + CompatiblePSEditions = @('Desktop', 'Core') + Copyright = '(c) 2011 - 2026 Przemyslaw Klys @ Evotec. All rights reserved.' + Description = 'PSWriteHTML is PowerShell Module to generate beautiful HTML reports, pages, emails without any knowledge of HTML, CSS or JavaScript. To get started basics PowerShell knowledge is required.' + FunctionsToExport = @('Add-HTML', 'Add-HTMLScript', 'Add-HTMLStyle', 'ConvertTo-CascadingStyleSheets', 'Email', 'EmailAttachment', 'EmailBCC', 'EmailBody', 'EmailCC', 'EmailFrom', 'EmailHeader', 'EmailLayout', 'EmailLayoutColumn', 'EmailLayoutRow', 'EmailListItem', 'EmailOptions', 'EmailReplyTo', 'EmailServer', 'EmailSubject', 'EmailTo', 'Enable-HTMLFeature', 'New-AccordionItem', 'New-CalendarEvent', 'New-CarouselSlide', 'New-ChartArea', 'New-ChartAxisX', 'New-ChartAxisY', 'New-ChartBar', 'New-ChartBarOptions', 'New-ChartBubble', 'New-ChartDataLabel', 'New-ChartDesign', 'New-ChartDonut', 'New-ChartEvent', 'New-ChartGrid', 'New-ChartHeatmap', 'New-ChartLabel', 'New-ChartLegend', 'New-ChartLine', 'New-ChartMarker', 'New-ChartPie', 'New-ChartRadar', 'New-ChartRadial', 'New-ChartRadialOptions', 'New-ChartScatter', 'New-ChartSpark', 'New-ChartTheme', 'New-ChartTimeLine', 'New-ChartToolbar', 'New-ChartToolTip', 'New-DiagramEvent', 'New-DiagramLink', 'New-DiagramNode', 'New-DiagramOptionsInteraction', 'New-DiagramOptionsLayout', 'New-DiagramOptionsLinks', 'New-DiagramOptionsManipulation', 'New-DiagramOptionsNodes', 'New-DiagramOptionsPhysics', 'New-GageSector', 'New-HierarchicalTreeNode', 'New-HTML', 'New-HTMLAccordion', 'New-HTMLAnchor', 'New-HTMLCalendar', 'New-HTMLCarousel', 'New-HTMLCarouselStyle', 'New-HTMLChart', 'New-HTMLCodeBlock', 'New-HTMLContainer', 'New-HTMLDate', 'New-HTMLDiagram', 'New-HTMLFontIcon', 'New-HTMLFooter', 'New-HTMLFrame', 'New-HTMLGage', 'New-HTMLHeader', 'New-HTMLHeading', 'New-HTMLHierarchicalTree', 'New-HTMLHorizontalLine', 'New-HTMLImage', 'New-HTMLInfoCard', 'New-HTMLList', 'New-HTMLListItem', 'New-HTMLLogo', 'New-HTMLMain', 'New-HTMLMap', 'New-HTMLMarkdown', 'New-HTMLMermeidChart', 'New-HTMLNav', 'New-HTMLNavFloat', 'New-HTMLNavTop', 'New-HTMLOrgChart', 'New-HTMLPage', 'New-HTMLPanel', 'New-HTMLPanelStyle', 'New-HTMLQRCode', 'New-HTMLSection', 'New-HTMLSectionScrolling', 'New-HTMLSectionScrollingItem', 'New-HTMLSectionStyle', 'New-HTMLSpanStyle', 'New-HTMLStatus', 'New-HTMLStatusItem', 'New-HTMLSummary', 'New-HTMLSummaryItem', 'New-HTMLSummaryItemData', 'New-HTMLTab', 'New-HTMLTable', 'New-HTMLTableOption', 'New-HTMLTableStyle', 'New-HTMLTabPanel', 'New-HTMLTabPanelColor', 'New-HTMLTabStyle', 'New-HTMLTag', 'New-HTMLText', 'New-HTMLTextBox', 'New-HTMLTimeline', 'New-HTMLTimelineItem', 'New-HTMLToast', 'New-HTMLTree', 'New-HTMLTreeChildCounter', 'New-HTMLTreeNode', 'New-HTMLWinBox', 'New-HTMLWizard', 'New-HTMLWizardColor', 'New-HTMLWizardStep', 'New-MapArea', 'New-MapLegendOption', 'New-MapLegendSlice', 'New-MapPlot', 'New-NavFloatWidget', 'New-NavFloatWidgetItem', 'New-NavItem', 'New-NavLink', 'New-NavTopMenu', 'New-OrgChartNode', 'New-TableAlphabetSearch', 'New-TableButtonColumnVisibility', 'New-TableButtonCopy', 'New-TableButtonCSV', 'New-TableButtonExcel', 'New-TableButtonPageLength', 'New-TableButtonPDF', 'New-TableButtonPrint', 'New-TableButtonSearchBuilder', 'New-TableColumnOption', 'New-TableCondition', 'New-TableConditionGroup', 'New-TableContent', 'New-TableEvent', 'New-TableFooter', 'New-TableHeader', 'New-TableLanguage', 'New-TablePercentageBar', 'New-TablePercentageBarCondition', 'New-TableReplace', 'New-TableRowGrouping', 'Out-HtmlView', 'Save-HTML') + GUID = 'a7bdf640-f5cb-4acf-9de0-365b322d245c' + ModuleVersion = '1.42.0' + PowerShellVersion = '5.1' + PrivateData = @{ + PSData = @{ + IconUri = 'https://evotec.xyz/wp-content/uploads/2018/12/PSWriteHTML.png' + ProjectUri = 'https://github.com/EvotecIT/PSWriteHTML' + RequireLicenseAcceptance = $false + Tags = @('HTML', 'WWW', 'JavaScript', 'CSS', 'Reports', 'Reporting', 'Windows', 'MacOS', 'Linux') + ExternalModuleDependencies = @() + } + } + RequiredModules = @(@{ + Guid = 'ee272aa8-baaa-4edf-9f45-b6d6f7d844fe' + ModuleName = 'PSSharedGoods' + ModuleVersion = '0.0.312' + }) + RootModule = 'PSWriteHTML.psm1' + ScriptsToProcess = @() +} diff --git a/Private/ChartsAll/ConvertTo-ChartSeriesData.ps1 b/Private/ChartsAll/ConvertTo-ChartSeriesData.ps1 new file mode 100644 index 00000000..5f69edbe --- /dev/null +++ b/Private/ChartsAll/ConvertTo-ChartSeriesData.ps1 @@ -0,0 +1,74 @@ +function ConvertTo-ChartSeriesData { + <# + .SYNOPSIS + Converts friendly PowerShell chart data into ApexCharts series points. + + .DESCRIPTION + Converts X/Y or X/Y/Z arrays, dictionaries, or prebuilt data into the point shapes + expected by ApexCharts scatter, bubble, and heatmap series. + #> + [CmdletBinding()] + param( + [object] $Data, + [object[]] $X, + [object[]] $Y, + [object[]] $Z, + [switch] $Bubble, + [switch] $Heatmap + ) + + if ($null -ne $Data) { + if ($Data -is [System.Collections.IDictionary]) { + $DataKeys = @($Data.Keys) + if ($DataKeys -contains 'x' -and $DataKeys -contains 'y') { + , $Data + return + } + + foreach ($Key in $Data.Keys) { + [ordered] @{ + x = $Key + y = $Data[$Key] + } + } + return + } + + foreach ($Point in @($Data)) { + $SeriesPoint = $Point + if ($Point -is [System.Array] -and $Point.Count -eq 1 -and $Point[0] -is [System.Array]) { + $SeriesPoint = $Point[0] + } + , $SeriesPoint + } + return + } + + if ($null -eq $X -or $null -eq $Y) { + throw 'ConvertTo-ChartSeriesData - Provide either Data or both X and Y values.' + } + if ($X.Count -ne $Y.Count) { + throw "ConvertTo-ChartSeriesData - X and Y counts must match. X has $($X.Count), Y has $($Y.Count)." + } + if ($Bubble -and ($null -eq $Z -or $Z.Count -ne $X.Count)) { + $zCount = if ($null -eq $Z) { 0 } else { $Z.Count } + throw "ConvertTo-ChartSeriesData - Bubble charts require Z values matching X/Y count. X has $($X.Count), Z has $zCount." + } + + for ($i = 0; $i -lt $X.Count; $i++) { + if ($Bubble) { + [ordered] @{ + x = $X[$i] + y = $Y[$i] + z = $Z[$i] + } + } elseif ($Heatmap) { + [ordered] @{ + x = $X[$i] + y = $Y[$i] + } + } else { + , @($X[$i], $Y[$i]) + } + } +} diff --git a/Private/ChartsAll/New-HTMLChartPie.ps1 b/Private/ChartsAll/New-HTMLChartPie.ps1 index 8483ed5a..7b6ad2b7 100644 --- a/Private/ChartsAll/New-HTMLChartPie.ps1 +++ b/Private/ChartsAll/New-HTMLChartPie.ps1 @@ -86,6 +86,7 @@ [string[]] $DataLabelsColor, [Array] $Data, [Array] $DataNames, + [Array] $Labels, [System.Collections.IDictionary] $Title, [System.Collections.IDictionary] $SubTitle, @@ -113,7 +114,11 @@ if ($Legend) { $Options.legend = $Legend } - New-ChartInternalPie -Options $Options -Names $DataNames -Values $Data -Type $Type + if ($Labels.Count -gt 0) { + New-ChartInternalPie -Options $Options -Names $Labels -Values $Data -Type $Type + } else { + New-ChartInternalPie -Options $Options -Names $DataNames -Values $Data -Type $Type + } New-ChartInternalColors -Options $Options -Colors $Colors # Default for all charts if ($Design.fill.pattern) { @@ -139,4 +144,4 @@ } Register-ArgumentCompleter -CommandName New-HTMLChartPie -ParameterName DataLabelsColor -ScriptBlock $Script:ScriptBlockColors -Register-ArgumentCompleter -CommandName New-HTMLChartPie -ParameterName Colors -ScriptBlock $Script:ScriptBlockColors \ No newline at end of file +Register-ArgumentCompleter -CommandName New-HTMLChartPie -ParameterName Colors -ScriptBlock $Script:ScriptBlockColors diff --git a/Private/ChartsAll/New-HTMLChartSeries.ps1 b/Private/ChartsAll/New-HTMLChartSeries.ps1 new file mode 100644 index 00000000..60171325 --- /dev/null +++ b/Private/ChartsAll/New-HTMLChartSeries.ps1 @@ -0,0 +1,78 @@ +function New-HTMLChartSeries { + <# + .SYNOPSIS + Creates an ApexCharts series chart from prebuilt series definitions. + + .DESCRIPTION + Shared renderer for additive ApexCharts types that use a series array, such as + area, scatter, bubble, heatmap, and radar charts. + #> + [CmdletBinding()] + param( + [System.Collections.IDictionary] $Chart, + [ValidateSet('area', 'scatter', 'bubble', 'heatmap', 'radar')][string] $Type, + [Array] $Series, + [Array] $Stroke, + + [System.Collections.IDictionary] $DataLabel, + [System.Collections.IDictionary] $Markers, + [System.Collections.IDictionary] $ChartAxisX, + [Array] $ChartAxisY, + [System.Collections.IDictionary] $Title, + [System.Collections.IDictionary] $SubTitle, + [System.Collections.IDictionary] $Legend, + + [switch] $PatternedColors, + [switch] $GradientColors, + [string[]] $Colors, + [System.Collections.IDictionary] $GridOptions, + [System.Collections.IDictionary] $Toolbar, + [System.Collections.IDictionary] $Theme, + [Object] $Events, + [System.Collections.IDictionary] $Design + ) + + $Options = [ordered] @{} + $Options.chart = $Chart + $Options.chart.type = $Type + + if ($Title) { $Options.title = $Title } + if ($SubTitle) { $Options.subtitle = $SubTitle } + if ($Legend) { $Options.legend = $Legend } + if ($ChartAxisX) { New-ChartInternalAxisX -Options $Options @ChartAxisX } + if ($ChartAxisY) { $Options.yaxis = $ChartAxisY } + + $Options.series = $Series + if ($Stroke.Count -gt 0) { + $Options.stroke = New-ChartInternalStroke -Stroke $Stroke + } + if ($Colors.Count -gt 0) { + $Options.colors = @($Colors) + } + if ($DataLabel) { + $Options.dataLabels = $DataLabel + } + if ($Markers) { + $Options.markers = $Markers + } + + if ($Design.fill.pattern) { + $Options.fill = [ordered] @{ + type = 'pattern' + pattern = $Design.fill.pattern + } + } elseif ($Design.fill.gradient) { + $Options.fill = [ordered] @{ + type = 'gradient' + gradient = $Design.fill.gradient + } + } elseif ($PatternedColors) { + New-ChartInternalPattern + } elseif ($GradientColors) { + New-ChartInternalGradient + } + if ($GridOptions) { New-ChartInternalGrid -Options $Options @GridOptions } + if ($Theme) { New-ChartInternalTheme -Options $Options @Theme } + if ($Toolbar) { New-ChartInternalToolbar -Options $Options @Toolbar -Show $true } + New-ApexChart -Options $Options -Events $Events +} diff --git a/Private/ConvertTo-HTMLStyle.ps1 b/Private/ConvertTo-HTMLStyle.ps1 index e58b2e69..095d093a 100644 --- a/Private/ConvertTo-HTMLStyle.ps1 +++ b/Private/ConvertTo-HTMLStyle.ps1 @@ -37,7 +37,7 @@ Specifies the text transformation. Valid values are 'uppercase', 'lowercase', 'capitalize'. .PARAMETER Direction - Specifies the text direction. Valid values are 'rtl'. + Specifies the text direction. Valid values are 'rtl', 'ltr'. .PARAMETER LineBreak Indicates whether to add a line break. @@ -45,6 +45,18 @@ .PARAMETER WordBreak Specifies the word break behavior. Valid values are 'normal', 'break-all', 'keep-all', 'break-word'. + .PARAMETER VerticalAlignment + Specifies the vertical alignment for table cells or inline content. + + .PARAMETER BorderStyle + Specifies the CSS border style. + + .PARAMETER BorderWidth + Specifies the CSS border width. + + .PARAMETER BorderColor + Specifies the CSS border color. + .EXAMPLE ConvertTo-HTMLStyle -Color 'red' -FontSize '12px' -FontWeight 'bold' -Alignment 'center' Converts the input parameters to HTML style attributes for a text element with red color, 12px font size, bold font weight, and centered alignment. @@ -62,9 +74,13 @@ [ValidateSet('left', 'center', 'right', 'justify')][string] $Alignment, [ValidateSet('none', 'line-through', 'overline', 'underline')][string] $TextDecoration, [ValidateSet('uppercase', 'lowercase', 'capitalize')][string] $TextTransform, - [ValidateSet('rtl')][string] $Direction, + [ValidateSet('rtl', 'ltr')][string] $Direction, [switch] $LineBreak, - [ValidateSet('normal', 'break-all', 'keep-all', 'break-word')][string] $WordBreak + [ValidateSet('normal', 'break-all', 'keep-all', 'break-word')][string] $WordBreak, + [ValidateSet('baseline', 'sub', 'super', 'text-top', 'text-bottom', 'middle', 'top', 'bottom')][string] $VerticalAlignment, + [ValidateSet('none', 'hidden', 'dotted', 'dashed', 'solid', 'double', 'groove', 'ridge', 'inset', 'outset')][string] $BorderStyle, + [object] $BorderWidth, + [string] $BorderColor ) $Style = @{ 'color' = ConvertFrom-Color -Color $Color @@ -77,9 +93,14 @@ 'text-align' = $Alignment 'text-decoration' = $TextDecoration 'text-transform' = $TextTransform + 'direction' = $Direction 'word-break' = $WordBreak + 'vertical-align' = $VerticalAlignment + 'border-style' = $BorderStyle + 'border-width' = ConvertFrom-Size -Size $BorderWidth + 'border-color' = ConvertFrom-Color -Color $BorderColor } # Removes empty, not needed values from hashtable. It's much easier then using if/else to verify for null/empty string Remove-EmptyValue -Hashtable $Style $Style -} \ No newline at end of file +} diff --git a/Private/Tables/Add-TableFiltering.ps1 b/Private/Tables/Add-TableFiltering.ps1 index 9fe81146..ac8a98da 100644 --- a/Private/Tables/Add-TableFiltering.ps1 +++ b/Private/Tables/Add-TableFiltering.ps1 @@ -53,7 +53,7 @@ function Add-TableFiltering { $Output.FilteringTopCode = @" // Setup - add a text input to each footer cell - `$('#$DataTableName tfoot th').each(function () { + `$('#$DataTableName tfoot tr:not(.pswritehtml-static-footer-row) th').each(function () { var title = `$(this).text(); `$(this).html(''); }); @@ -80,7 +80,7 @@ function Add-TableFiltering { `$(this).html(''); }); // Setup - add a text input to each footer cell - `$('#$DataTableName tfoot th').each(function () { + `$('#$DataTableName tfoot tr:not(.pswritehtml-static-footer-row) th').each(function () { var title = `$(this).text(); `$(this).html(''); }); diff --git a/Private/Tables/New-TableColumnGroup.ps1 b/Private/Tables/New-TableColumnGroup.ps1 new file mode 100644 index 00000000..fd9765d3 --- /dev/null +++ b/Private/Tables/New-TableColumnGroup.ps1 @@ -0,0 +1,51 @@ +function New-TableColumnGroup { + <# + .SYNOPSIS + Creates a colgroup for table column widths. + #> + [CmdletBinding()] + param( + [string[]] $HeaderNames, + [System.Collections.Generic.List[PSCustomObject]] $TableColumnOptions + ) + + if (-not $HeaderNames -or $TableColumnOptions.Count -eq 0) { + return + } + + $Widths = @{} + foreach ($Option in $TableColumnOptions) { + if (-not $Option.width) { + continue + } + + if ($Option.targets -eq '_all') { + for ($Index = 0; $Index -lt $HeaderNames.Count; $Index++) { + if (-not $Widths.ContainsKey($Index)) { + $Widths[$Index] = $Option.width + } + } + continue + } + + foreach ($Target in @($Option.targets)) { + if ($Target -is [int] -and $Target -ge 0 -and $Target -lt $HeaderNames.Count -and -not $Widths.ContainsKey($Target)) { + $Widths[$Target] = $Option.width + } + } + } + + if ($Widths.Count -eq 0) { + return + } + + New-HTMLTag -Tag 'colgroup' { + for ($Index = 0; $Index -lt $HeaderNames.Count; $Index++) { + $Style = @{} + if ($Widths.ContainsKey($Index)) { + $Style.width = ConvertFrom-Size -Size $Widths[$Index] + } + New-HTMLTag -Tag 'col' -Attributes @{ style = $Style } + } + } +} diff --git a/Public/New-ChartArea.ps1 b/Public/New-ChartArea.ps1 new file mode 100644 index 00000000..33be9fad --- /dev/null +++ b/Public/New-ChartArea.ps1 @@ -0,0 +1,68 @@ +function New-ChartArea { + <# + .SYNOPSIS + Adds an area series to a chart. + + .DESCRIPTION + Adds an ApexCharts area series. Use New-ChartAxisX to provide categories, + datetime values, or numeric axis settings when needed. + + .PARAMETER Name + Name of the area series. + + .PARAMETER Value + Values to display in the area series. + + .PARAMETER Color + Series color. + + .PARAMETER Curve + Stroke curve style. + + .PARAMETER Width + Stroke width. + + .PARAMETER Cap + Stroke cap style. + + .PARAMETER Dash + Stroke dash spacing. + + .EXAMPLE + New-ChartArea -Name 'Revenue' -Value 10, 20, 18 -Color Blue -Curve smooth + #> + [alias('ChartArea')] + [CmdletBinding()] + param( + [Parameter(Mandatory)][string] $Name, + [Parameter(Mandatory)][object] $Value, + [string] $Color, + [ValidateSet('straight', 'smooth', 'stepline')] $Curve, + [System.Nullable[int]] $Width, + [ValidateSet('butt', 'square', 'round')][string] $Cap, + [System.Nullable[int]] $Dash + ) + + $Object = [PSCustomObject] @{ + ObjectType = 'Area' + Name = $Name + Value = $Value + Color = ConvertFrom-Color -Color $Color + series = [ordered] @{ + name = $Name + type = 'area' + data = @($Value) + } + stroke = [ordered] @{ + curve = $Curve + lineCap = $Cap + width = $Width + dashArray = $Dash + } + } + Remove-EmptyValue -Hashtable $Object.Series + Remove-EmptyValue -Hashtable $Object.Stroke + $Object +} + +Register-ArgumentCompleter -CommandName New-ChartArea -ParameterName Color -ScriptBlock $Script:ScriptBlockColors diff --git a/Public/New-ChartBubble.ps1 b/Public/New-ChartBubble.ps1 new file mode 100644 index 00000000..cf42a519 --- /dev/null +++ b/Public/New-ChartBubble.ps1 @@ -0,0 +1,35 @@ +function New-ChartBubble { + <# + .SYNOPSIS + Adds a bubble series to a chart. + + .DESCRIPTION + Adds an ApexCharts bubble series. Provide X, Y, and Z arrays for the common + case, or pass raw ApexCharts-compatible points through Data. + + .EXAMPLE + New-ChartBubble -Name 'Risk' -X 1, 2, 3 -Y 20, 30, 15 -Z 5, 12, 8 -Color Orange + #> + [alias('ChartBubble')] + [CmdletBinding()] + param( + [Parameter(Mandatory)][string] $Name, + [object[]] $X, + [object[]] $Y, + [object[]] $Z, + [object] $Data, + [string] $Color + ) + + [PSCustomObject] @{ + ObjectType = 'Bubble' + Color = ConvertFrom-Color -Color $Color + series = [ordered] @{ + name = $Name + type = 'bubble' + data = @(ConvertTo-ChartSeriesData -Data $Data -X $X -Y $Y -Z $Z -Bubble) + } + } +} + +Register-ArgumentCompleter -CommandName New-ChartBubble -ParameterName Color -ScriptBlock $Script:ScriptBlockColors diff --git a/Public/New-ChartDataLabel.ps1 b/Public/New-ChartDataLabel.ps1 index 264dacc3..7eefa22c 100644 --- a/Public/New-ChartDataLabel.ps1 +++ b/Public/New-ChartDataLabel.ps1 @@ -63,10 +63,10 @@ } if ($null -ne $OffsetX) { - $Object['DataLabel']['offsetX'] = $OffsetX + $Object.DataLabel['offsetX'] = $OffsetX } - if ($null -ne $OffsetX) { - $Object['DataLabel']['offsetX'] = $OffsetY + if ($null -ne $OffsetY) { + $Object.DataLabel['offsetY'] = $OffsetY } $Object.DataLabel.style = [ordered]@{} if ($FontSize) { @@ -75,11 +75,11 @@ if ($FontFamily) { $Object.DataLabel.style['fontFamily'] = $FontFamily } - if ($DataLabelsColor.Count -gt 0) { + if ($FontColor.Count -gt 0) { $Object.DataLabel.style['colors'] = @(ConvertFrom-Color -Color $FontColor) } Remove-EmptyValue -Hashtable $Object.DataLabel -Recursive $Object } -Register-ArgumentCompleter -CommandName New-ChartDataLabel -ParameterName DataLabelsColor -ScriptBlock $Script:ScriptBlockColors \ No newline at end of file +Register-ArgumentCompleter -CommandName New-ChartDataLabel -ParameterName DataLabelsColor -ScriptBlock $Script:ScriptBlockColors diff --git a/Public/New-ChartHeatmap.ps1 b/Public/New-ChartHeatmap.ps1 new file mode 100644 index 00000000..e4ea1fc9 --- /dev/null +++ b/Public/New-ChartHeatmap.ps1 @@ -0,0 +1,33 @@ +function New-ChartHeatmap { + <# + .SYNOPSIS + Adds a heatmap row series to a chart. + + .DESCRIPTION + Adds one ApexCharts heatmap row. Use X and Y arrays for category/value pairs, + a dictionary for category/value data, or raw ApexCharts-compatible points. + + .EXAMPLE + New-ChartHeatmap -Name 'Monday' -X 'AM', 'PM' -Y 12, 18 + #> + [alias('ChartHeatmap')] + [CmdletBinding()] + param( + [Parameter(Mandatory)][string] $Name, + [object[]] $X, + [object[]] $Y, + [object] $Data, + [string] $Color + ) + + [PSCustomObject] @{ + ObjectType = 'Heatmap' + Color = ConvertFrom-Color -Color $Color + series = [ordered] @{ + name = $Name + data = @(ConvertTo-ChartSeriesData -Data $Data -X $X -Y $Y -Heatmap) + } + } +} + +Register-ArgumentCompleter -CommandName New-ChartHeatmap -ParameterName Color -ScriptBlock $Script:ScriptBlockColors diff --git a/Public/New-ChartLabel.ps1 b/Public/New-ChartLabel.ps1 new file mode 100644 index 00000000..8453c55e --- /dev/null +++ b/Public/New-ChartLabel.ps1 @@ -0,0 +1,25 @@ +function New-ChartLabel { + <# + .SYNOPSIS + Overrides chart labels for charts that support top-level ApexCharts labels. + + .DESCRIPTION + Provides a friendly way to set labels, especially for pie and donut charts + when labels should be supplied separately from the value commands. + + .EXAMPLE + New-ChartLabel -Name 'Passed', 'Failed', 'Skipped' + #> + [alias('ChartLabel')] + [CmdletBinding()] + param( + [Parameter(Mandatory)] + [alias('Name')] + [string[]] $Names + ) + + [PSCustomObject] @{ + ObjectType = 'ChartLabel' + Names = $Names + } +} diff --git a/Public/New-ChartRadar.ps1 b/Public/New-ChartRadar.ps1 new file mode 100644 index 00000000..b489bf83 --- /dev/null +++ b/Public/New-ChartRadar.ps1 @@ -0,0 +1,30 @@ +function New-ChartRadar { + <# + .SYNOPSIS + Adds a radar series to a chart. + + .DESCRIPTION + Adds an ApexCharts radar series. Use New-ChartAxisX to provide spoke labels. + + .EXAMPLE + New-ChartRadar -Name 'Coverage' -Value 70, 85, 62 -Color Green + #> + [alias('ChartRadar')] + [CmdletBinding()] + param( + [Parameter(Mandatory)][string] $Name, + [Parameter(Mandatory)][object] $Value, + [string] $Color + ) + + [PSCustomObject] @{ + ObjectType = 'Radar' + Color = ConvertFrom-Color -Color $Color + series = [ordered] @{ + name = $Name + data = @($Value) + } + } +} + +Register-ArgumentCompleter -CommandName New-ChartRadar -ParameterName Color -ScriptBlock $Script:ScriptBlockColors diff --git a/Public/New-ChartScatter.ps1 b/Public/New-ChartScatter.ps1 new file mode 100644 index 00000000..6e18340c --- /dev/null +++ b/Public/New-ChartScatter.ps1 @@ -0,0 +1,34 @@ +function New-ChartScatter { + <# + .SYNOPSIS + Adds a scatter series to a chart. + + .DESCRIPTION + Adds an ApexCharts scatter series. Provide X and Y arrays for the common case, + or pass raw ApexCharts-compatible points through Data. + + .EXAMPLE + New-ChartScatter -Name 'Samples' -X 1, 2, 3 -Y 10, 25, 18 -Color Purple + #> + [alias('ChartScatter')] + [CmdletBinding()] + param( + [Parameter(Mandatory)][string] $Name, + [object[]] $X, + [object[]] $Y, + [object] $Data, + [string] $Color + ) + + [PSCustomObject] @{ + ObjectType = 'Scatter' + Color = ConvertFrom-Color -Color $Color + series = [ordered] @{ + name = $Name + type = 'scatter' + data = @(ConvertTo-ChartSeriesData -Data $Data -X $X -Y $Y) + } + } +} + +Register-ArgumentCompleter -CommandName New-ChartScatter -ParameterName Color -ScriptBlock $Script:ScriptBlockColors diff --git a/Public/New-DiagramLink.ps1 b/Public/New-DiagramLink.ps1 index 10d296fb..b68a526b 100644 --- a/Public/New-DiagramLink.ps1 +++ b/Public/New-DiagramLink.ps1 @@ -129,7 +129,8 @@ [string[]] $To, [string] $Label, [switch] $ArrowsToEnabled, - [nullable[int]] $ArrowsToScaleFacto, + [Alias('ArrowsToScaleFacto')] + [nullable[int]] $ArrowsToScaleFactor, [ValidateSet('arrow', 'bar', 'circle')][string] $ArrowsToType, [switch] $ArrowsMiddleEnabled, [nullable[int]]$ArrowsMiddleScaleFactor, @@ -143,10 +144,14 @@ [string] $ColorHighlight, [string] $ColorHover, [ValidateSet('true', 'false', 'from', 'to', 'both')][string]$ColorInherit, - [nullable[double]] $ColorOpacity, # range between 0 and 1 - [switch] $Dashes, - [string] $Length, - [string] $FontColor, + [nullable[double]] $ColorOpacity, # range between 0 and 1 + [switch] $Dashes, + [string] $Length, + [nullable[double]] $Width, + [nullable[double]] $HoverWidth, + [nullable[double]] $SelectionWidth, + [nullable[double]] $Value, + [string] $FontColor, [object] $FontSize, [string] $FontName, [string] $FontBackground, @@ -206,11 +211,15 @@ align = $FontAlign multi = $FontMulti vadjust = $FontVAdjust - } - dashes = if ($Dashes) { $Dashes.IsPresent } else { $null } - widthConstraint = $WidthConstraint - } - } + } + dashes = if ($Dashes) { $Dashes.IsPresent } else { $null } + width = $Width + hoverWidth = $HoverWidth + selectionWidth = $SelectionWidth + value = $Value + widthConstraint = $WidthConstraint + } + } if ($SmoothType -or $SmoothRoundness -or $SmoothForceDirection) { $Object.Edges['smooth'] = @{ 'enabled' = $true @@ -343,4 +352,4 @@ Register-ArgumentCompleter -CommandName New-DiagramLink -ParameterName FontStrok } network.setOptions(options); - #> \ No newline at end of file + #> diff --git a/Public/New-DiagramOptionsLinks.ps1 b/Public/New-DiagramOptionsLinks.ps1 index f92673a8..dde8668e 100644 --- a/Public/New-DiagramOptionsLinks.ps1 +++ b/Public/New-DiagramOptionsLinks.ps1 @@ -115,10 +115,14 @@ function New-DiagramOptionsLinks { [string] $ColorHighlight, [string] $ColorHover, [ValidateSet('true', 'false', 'from', 'to', 'both')][string]$ColorInherit, - [nullable[double]] $ColorOpacity, # range between 0 and 1 - [nullable[bool]] $Dashes, - [string] $Length, - [string] $FontColor, + [nullable[double]] $ColorOpacity, # range between 0 and 1 + [nullable[bool]] $Dashes, + [string] $Length, + [nullable[double]] $Width, + [nullable[double]] $HoverWidth, + [nullable[double]] $SelectionWidth, + [nullable[double]] $Value, + [string] $FontColor, [nullable[int]] $FontSize, #// px [string] $FontName, [string] $FontBackground, @@ -127,7 +131,11 @@ function New-DiagramOptionsLinks { [ValidateSet('center', 'left')][string] $FontAlign, [ValidateSet('false', 'true', 'markdown', 'html')][string]$FontMulti, [nullable[int]] $FontVAdjust, - [nullable[int]] $WidthConstraint + [nullable[int]] $WidthConstraint, + + [ValidateSet('dynamic', 'continuous', 'discrete', 'diagonalCross', 'straightCross', 'horizontal', 'vertical', 'curvedCW', 'curvedCCW', 'cubicBezier')][string] $SmoothType, + [ValidateSet('horizontal', 'vertical', 'none')][string] $SmoothForceDirection, + [nullable[double]] $SmoothRoundness ) $Object = [PSCustomObject] @{ Type = 'DiagramOptionsEdges' @@ -170,13 +178,31 @@ function New-DiagramOptionsLinks { align = $FontAlign multi = $FontMulti vadjust = $FontVAdjust - } - dashes = $Dashes - widthConstraint = $WidthConstraint - } - } - } - Remove-EmptyValue -Hashtable $Object.Settings -Recursive -Rerun 2 + } + dashes = $Dashes + width = $Width + hoverWidth = $HoverWidth + selectionWidth = $SelectionWidth + value = $Value + widthConstraint = $WidthConstraint + } + } + } + if ($SmoothType -or $null -ne $SmoothRoundness -or $SmoothForceDirection) { + $Object.Settings.edges['smooth'] = [ordered] @{ + enabled = $true + } + if ($SmoothType) { + $Object.Settings.edges.smooth['type'] = $SmoothType + } + if ($null -ne $SmoothRoundness) { + $Object.Settings.edges.smooth['roundness'] = $SmoothRoundness + } + if ($SmoothForceDirection) { + $Object.Settings.edges.smooth['forceDirection'] = $SmoothForceDirection + } + } + Remove-EmptyValue -Hashtable $Object.Settings -Recursive -Rerun 2 $Object } Register-ArgumentCompleter -CommandName New-DiagramOptionsLinks -ParameterName Color -ScriptBlock $Script:ScriptBlockColors @@ -291,4 +317,4 @@ var options = { } network.setOptions(options); -#> \ No newline at end of file +#> diff --git a/Public/New-HTMLChart.ps1 b/Public/New-HTMLChart.ps1 index a66dcdfe..8e821448 100644 --- a/Public/New-HTMLChart.ps1 +++ b/Public/New-HTMLChart.ps1 @@ -200,6 +200,7 @@ $Colors = [System.Collections.Generic.List[string]]::new() $ChartAxisY = [System.Collections.Generic.List[System.Collections.IDictionary]]::new() + $ChartLabels = $null # Bar default definitions [bool] $BarHorizontal = $true @@ -312,6 +313,18 @@ if ($Setting.Color) { $Colors.Add($Setting.Color) } + } elseif ($Setting.ObjectType -in @('Area', 'Scatter', 'Bubble', 'Heatmap', 'Radar')) { + $Type = $Setting.ObjectType + + if ($Setting.series) { + $DataSeries.Add($Setting.series) + } + if ($Setting.stroke.count -gt 0) { + $LineStroke.Add($Setting.stroke) + } + if ($Setting.Color) { + $Colors.Add($Setting.Color) + } } elseif ($Setting.ObjectType -eq 'ChartAxisX') { $ChartAxisX = $Setting.ChartAxisX } elseif ($Setting.ObjectType -eq 'ChartGrid') { @@ -327,6 +340,8 @@ $DataLabel = $Setting.DataLabel } elseif ($Setting.ObjectType -eq 'ChartEvents') { $Events = $Setting.Event + } elseif ($Setting.ObjectType -eq 'ChartLabel') { + $ChartLabels = $Setting.Names } elseif ($Setting.ObjectType -eq 'RadialOptions') { $PlotOptions = $Setting.plotOptions } elseif ($Setting.ObjectType -eq 'Fill') { @@ -418,10 +433,34 @@ Design = $Design } New-HTMLChartLine @SplatChartLine + } elseif ($Type -in @('Area', 'Scatter', 'Bubble', 'Heatmap', 'Radar')) { + $SplatChartSeries = @{ + Type = $Type.ToLower() + Chart = $Chart + Series = $DataSeries + Stroke = $LineStroke + DataLabel = $DataLabel + Legend = $Legend + Markers = $Markers + Colors = $Colors + ChartAxisX = $ChartAxisX + ChartAxisY = $ChartAxisY + Theme = $Theme + Toolbar = $Toolbar + GridOptions = $GridOptions + PatternedColors = $Patterned + GradientColors = $Gradient + Events = $Events + Title = $TitleBlock + SubTitle = $SubTitleBlock + Design = $Design + } + New-HTMLChartSeries @SplatChartSeries } elseif ($Type -eq 'Pie' -or $Type -eq 'Donut') { $SplatChart = @{ Data = $DataSet DataNames = $DataName + Labels = $ChartLabels Colors = $Colors # Every the same @@ -507,4 +546,4 @@ } Register-ArgumentCompleter -CommandName New-HTMLChart -ParameterName TitleColor -ScriptBlock $Script:ScriptBlockColors -Register-ArgumentCompleter -CommandName New-HTMLChart -ParameterName SubTitleColor -ScriptBlock $Script:ScriptBlockColors \ No newline at end of file +Register-ArgumentCompleter -CommandName New-HTMLChart -ParameterName SubTitleColor -ScriptBlock $Script:ScriptBlockColors diff --git a/Public/New-HTMLSummary.ps1 b/Public/New-HTMLSummary.ps1 index 6e4451e2..be2bee9e 100644 --- a/Public/New-HTMLSummary.ps1 +++ b/Public/New-HTMLSummary.ps1 @@ -36,12 +36,16 @@ Enable-HTMLFeature -Feature MainFlex, AccordionSummary New-HTMLTag -Tag 'container' { - New-HTMLTag -Tag 'h2' { - $Title - New-HTMLTag -Tag 'span' { - $TitleRight - } -Attributes @{ 'class' = 'summary-end' } - } -Attributes @{ class = 'summary-title' } + if ($Title -or $TitleRight) { + New-HTMLTag -Tag 'h2' { + $Title + if ($TitleRight) { + New-HTMLTag -Tag 'span' { + $TitleRight + } -Attributes @{ 'class' = 'summary-end' } + } + } -Attributes @{ class = 'summary-title' } + } & $SummaryItems } -} \ No newline at end of file +} diff --git a/Public/New-HTMLTab.ps1 b/Public/New-HTMLTab.ps1 index b49e597a..354026dd 100644 --- a/Public/New-HTMLTab.ps1 +++ b/Public/New-HTMLTab.ps1 @@ -24,6 +24,9 @@ function New-HTMLTab { .PARAMETER IconSolid The icon to be displayed for FontAwesomeSolid. Use tab completion to select from available options. + .PARAMETER Default + Makes this tab the initially selected tab. + .EXAMPLE New-HTMLTab -HtmlData { Get-Process } -Heading "Processes" -Name "ProcessTab" -IconBrands "windows" @@ -101,7 +104,10 @@ function New-HTMLTab { [parameter(ParameterSetName = "FontAwesomeRegular")] [parameter(ParameterSetName = "FontAwesomeSolid")][string] $IconColor, [ValidateSet('uppercase', 'lowercase', 'capitalize')][string] $TextTransform, # New-HTMLTab - Add text-transform - [string] $AnchorName + [string] $AnchorName, + [parameter(ParameterSetName = "FontAwesomeBrands")] + [parameter(ParameterSetName = "FontAwesomeRegular")] + [parameter(ParameterSetName = "FontAwesomeSolid")][switch] $Default ) if (-not $Script:HTMLSchema.Features) { Write-Warning 'New-HTMLTab - Creation of HTML aborted. Most likely New-HTML is missing.' @@ -162,8 +168,14 @@ function New-HTMLTab { $Tab.StyleIcon = $StyleIcon $Tab.StyleText = $StyleText $Tab.Current = $true + $Tab.Default = $Default.IsPresent - if ($Script:HTMLSchema.TabsHeaders | Where-Object { $_.Active -eq $true }) { + if ($Default) { + foreach ($ExistingTab in $Script:HTMLSchema.TabsHeaders) { + $ExistingTab.Active = $false + } + $Tab.Active = $true + } elseif ($Script:HTMLSchema.TabsHeaders | Where-Object { $_.Active -eq $true }) { $Tab.Active = $false } else { $Tab.Active = $true @@ -211,6 +223,32 @@ function New-HTMLTab { } else { $HTML } + if ($Default) { + $TabIDJson = $Tab.ID | ConvertTo-Json -Compress + $PaneIDJson = "$($Tab.ID)-Content" | ConvertTo-Json -Compress + New-HTMLTag -Tag 'script' { + @" +document.addEventListener('DOMContentLoaded', function () { + var tabId = $TabIDJson; + var paneId = $PaneIDJson; + var tab = document.getElementById(tabId); + if (tab && tab.parentElement) { + Array.prototype.forEach.call(tab.parentElement.children, function (child) { + child.classList.remove('active'); + }); + tab.classList.add('active'); + } + var pane = document.getElementById(paneId); + if (pane && pane.parentElement) { + Array.prototype.forEach.call(pane.parentElement.children, function (child) { + child.classList.remove('active'); + }); + pane.classList.add('active'); + } +}); +"@ + } + } } $Script:HTMLSchema.TabsHeaders.Add($Tab) $Tab @@ -227,6 +265,7 @@ function New-HTMLTab { Icon = $Icon StyleIcon = $StyleIcon StyleText = $StyleText + Default = $Default.IsPresent Content = $TabExecutedCode } } diff --git a/Public/New-HTMLTabPanel.ps1 b/Public/New-HTMLTabPanel.ps1 index 29c8255f..7449f4fe 100644 --- a/Public/New-HTMLTabPanel.ps1 +++ b/Public/New-HTMLTabPanel.ps1 @@ -93,6 +93,13 @@ autoAdjustHeight = $false # this fights with Flex theme = $Theme.ToLower() } + $DefaultTab = $TabContent | Where-Object { $_.Default } | Select-Object -First 1 + if ($DefaultTab) { + $DefaultIndex = [array]::IndexOf($TabContent, $DefaultTab) + if ($DefaultIndex -ge 0) { + $SmartTab['selected'] = $DefaultIndex + } + } if ($TransitionAnimation) { $SmartTab['transition'] = [ordered] @{} $SmartTab['transition']['animation'] = $TransitionAnimation @@ -140,4 +147,4 @@ } $null = $Script:HTMLSchema['TabPanelsList'].Remove($TabID) } -} \ No newline at end of file +} diff --git a/Public/New-HTMLTable.ps1 b/Public/New-HTMLTable.ps1 index 071bdcbd..476f4481 100644 --- a/Public/New-HTMLTable.ps1 +++ b/Public/New-HTMLTable.ps1 @@ -424,6 +424,7 @@ $TablePercentageBar = [System.Collections.Generic.List[PSCustomObject]]::new() $TableAlphabetSearch = [ordered]@{} $TableLanguage = [ordered]@{} + $TableFooterRows = [System.Collections.Generic.List[PSCustomObject]]::new() # This will be used to store the colulmnDef option for the datatable $ColumnDefinitionList = [System.Collections.Generic.List[PSCustomObject]]::New() @@ -534,6 +535,8 @@ $TableAlphabetSearch = $Parameters.Output } elseif ($Parameters.Type -eq 'TableLanguage') { $TableLanguage = $Parameters.Output + } elseif ($Parameters.Type -eq 'TableFooter') { + $TableFooterRows.Add($Parameters.Output) } } } @@ -945,6 +948,15 @@ if (-not $Button.Title -and $Title) { $Button.title = $Title } + if ($Button.extend -eq 'searchBuilder' -and $Button.text) { + if (-not $Options.Contains('language') -or -not $Options['language']) { + $Options['language'] = [ordered]@{} + } + if (-not $Options['language'].Contains('searchBuilder') -or -not $Options['language']['searchBuilder']) { + $Options['language']['searchBuilder'] = [ordered]@{} + } + $Options['language']['searchBuilder']['button'] = $Button.text + } $Button } } else { @@ -1243,6 +1255,13 @@ } # The table column options also adds to the columnDefs parameter + if ($RowGroupingColumnID -ne -1 -and $RowGrouping.HideColumn) { + $ColumnDefinitionList.Add([PSCustomObject]@{ + targets = $RowGroupingColumnID + visible = $false + searchable = $true + }) + } if ($TableColumnOptions.Count -gt 0) { foreach ($T in $TableColumnOptions) { $ColumnDefinitionList.Add($T) # Corrected to use $T instead of $_ @@ -1467,8 +1486,8 @@ $Table = $Table -replace '<', '<' -replace '>', '>' -replace '&', '&' -replace ' ', ' ' -replace '"', '"' -replace ''', "'" } if (-not $DisableNewLine) { - # Finds new lines and adds HTML TAG BR - $Table = $Table -replace '(?m)\s+$', "
" + # Finds new lines inside cell values and adds HTML TAG BR + $Table = $Table -replace "(`r`n|`n|`r)", '
' } if ($OtherHTML) { @@ -1513,6 +1532,7 @@ } New-HTMLTag -Tag 'table' -Attributes $TableAttributes { + New-TableColumnGroup -HeaderNames $HeaderNames -TableColumnOptions $TableColumnOptions New-HTMLTag -Tag 'thead' { if ($AddedHeader) { $AddedHeader @@ -1527,7 +1547,35 @@ } if (-not $HideFooter) { New-HTMLTag -Tag 'tfoot' { - $Header + if ($TableFooterRows.Count -gt 0) { + if ($Filtering -and $FilteringLocation -in @('Bottom', 'Both')) { + New-HTMLTag -Tag 'tr' -Attributes @{ class = 'pswritehtml-filter-row' } { + foreach ($HeaderName in $HeaderNames) { + New-HTMLTag -Tag 'th' -Value { $HeaderName } + } + } + } + foreach ($Footer in $TableFooterRows) { + New-HTMLTag -Tag 'tr' -Attributes @{ class = 'pswritehtml-static-footer-row' } { + for ($FooterIndex = 0; $FooterIndex -lt $HeaderNames.Count; $FooterIndex++) { + $FooterValue = '' + if ($Footer.ValueByColumn) { + foreach ($Key in $Footer.ValueByColumn.Keys) { + if ($Key -ieq $HeaderNames[$FooterIndex]) { + $FooterValue = $Footer.ValueByColumn[$Key] + break + } + } + } elseif ($Footer.Values.Count -gt $FooterIndex) { + $FooterValue = $Footer.Values[$FooterIndex] + } + New-HTMLTag -Tag 'th' -Attributes @{ style = $Footer.Style } -Value { $FooterValue } + } + } + } + } else { + $Header + } } } } diff --git a/Public/New-TableContent.ps1 b/Public/New-TableContent.ps1 index 968da688..76973780 100644 --- a/Public/New-TableContent.ps1 +++ b/Public/New-TableContent.ps1 @@ -54,6 +54,9 @@ .PARAMETER WordBreak Provide new word break. When skipped the word break will not be changed. Options are: 'normal', 'break-all', 'keep-all', 'break-word' + .PARAMETER VerticalAlignment + Provide new vertical alignment. When skipped the vertical alignment will not be changed. Options are: 'baseline', 'sub', 'super', 'text-top', 'text-bottom', 'middle', 'top', 'bottom' + .EXAMPLE New-HTML -TitleText "Example37 - Word Breaking" -FilePath "$PSScriptRoot\Example37.html" { New-HTMLSection -HeaderText "Word Break for whole table" -HeaderTextAlignment center -Content { @@ -142,7 +145,8 @@ [ValidateSet('none', 'line-through', 'overline', 'underline')][string] $TextDecoration, [ValidateSet('uppercase', 'lowercase', 'capitalize')][string] $TextTransform, [ValidateSet('rtl','ltr')][string] $Direction, - [ValidateSet('normal', 'break-all', 'keep-all', 'break-word')][string] $WordBreak + [ValidateSet('normal', 'break-all', 'keep-all', 'break-word')][string] $WordBreak, + [ValidateSet('baseline', 'sub', 'super', 'text-top', 'text-bottom', 'middle', 'top', 'bottom')][string] $VerticalAlignment ) if ($WordBreak -eq '' -or $WordBreak -eq 'normal') { $WordBreakStyle = '' @@ -163,6 +167,7 @@ TextTransform = $TextTransform Direction = $Direction WordBreak = $WordBreakStyle + VerticalAlignment = $VerticalAlignment } Remove-EmptyValue -Hashtable $Style @@ -180,4 +185,4 @@ } Register-ArgumentCompleter -CommandName New-TableContent -ParameterName Color -ScriptBlock $Script:ScriptBlockColors -Register-ArgumentCompleter -CommandName New-TableContent -ParameterName BackgroundColor -ScriptBlock $Script:ScriptBlockColors \ No newline at end of file +Register-ArgumentCompleter -CommandName New-TableContent -ParameterName BackgroundColor -ScriptBlock $Script:ScriptBlockColors diff --git a/Public/New-TableFooter.ps1 b/Public/New-TableFooter.ps1 new file mode 100644 index 00000000..3f0f5212 --- /dev/null +++ b/Public/New-TableFooter.ps1 @@ -0,0 +1,88 @@ +function New-TableFooter { + <# + .SYNOPSIS + Creates a static table footer row. + + .DESCRIPTION + Creates a footer row for New-HTMLTable. Use Values when the footer follows the rendered column order, or ValueByColumn when footer values should be assigned by column name. + + .PARAMETER Values + Footer cell values in rendered column order. + + .PARAMETER ValueByColumn + Footer cell values keyed by rendered column name. + + .PARAMETER Color + Pick one of the 800 colors or provide a hex color code. + + .PARAMETER BackGroundColor + Pick one of the 800 colors or provide a hex color code. + + .PARAMETER FontSize + Provide new font size. + + .PARAMETER FontWeight + Provide new font weight. + + .PARAMETER Alignment + Provide new text alignment. + + .EXAMPLE + New-HTMLTable -DataTable $Data { + New-TableFooter -ValueByColumn @{ Name = 'Total'; Amount = 42 } -FontWeight bold + } + #> + [alias('TableFooter', 'EmailTableFooter', 'New-HTMLTableFooter')] + [CmdletBinding()] + param( + [object[]] $Values, + [System.Collections.IDictionary] $ValueByColumn, + [string] $Color, + [string] $BackGroundColor, + [object] $FontSize, + [ValidateSet('normal', 'bold', 'bolder', 'lighter', '100', '200', '300', '400', '500', '600', '700', '800', '900')][string] $FontWeight, + [ValidateSet('normal', 'italic', 'oblique')][string] $FontStyle, + [ValidateSet('normal', 'small-caps')][string] $FontVariant, + [string] $FontFamily, + [ValidateSet('left', 'center', 'right', 'justify')][string] $Alignment, + [ValidateSet('none', 'line-through', 'overline', 'underline')][string] $TextDecoration, + [ValidateSet('uppercase', 'lowercase', 'capitalize')][string] $TextTransform, + [ValidateSet('rtl', 'ltr')][string] $Direction, + [ValidateSet('baseline', 'sub', 'super', 'text-top', 'text-bottom', 'middle', 'top', 'bottom')][string] $VerticalAlignment, + [ValidateSet('none', 'hidden', 'dotted', 'dashed', 'solid', 'double', 'groove', 'ridge', 'inset', 'outset')][string] $BorderStyle, + [object] $BorderWidth, + [string] $BorderColor + ) + + $Style = @{ + Color = $Color + BackGroundColor = $BackGroundColor + FontSize = $FontSize + FontWeight = $FontWeight + FontStyle = $FontStyle + FontVariant = $FontVariant + FontFamily = $FontFamily + Alignment = $Alignment + TextDecoration = $TextDecoration + TextTransform = $TextTransform + Direction = $Direction + VerticalAlignment = $VerticalAlignment + BorderStyle = $BorderStyle + BorderWidth = $BorderWidth + BorderColor = $BorderColor + } + Remove-EmptyValue -Hashtable $Style + + [PSCustomObject]@{ + Type = 'TableFooter' + Output = [ordered]@{ + Values = $Values + ValueByColumn = $ValueByColumn + Style = ConvertTo-HTMLStyle @Style + } + } +} + +Register-ArgumentCompleter -CommandName New-TableFooter -ParameterName Color -ScriptBlock $Script:ScriptBlockColors +Register-ArgumentCompleter -CommandName New-TableFooter -ParameterName BackgroundColor -ScriptBlock $Script:ScriptBlockColors +Register-ArgumentCompleter -CommandName New-TableFooter -ParameterName BorderColor -ScriptBlock $Script:ScriptBlockColors diff --git a/Public/New-TableHeader.ps1 b/Public/New-TableHeader.ps1 index 390ea9c6..e91e3630 100644 --- a/Public/New-TableHeader.ps1 +++ b/Public/New-TableHeader.ps1 @@ -49,6 +49,15 @@ .PARAMETER Direction Specifies the text direction of the table header. + .PARAMETER BorderStyle + Specifies the CSS border style for matching header cells. + + .PARAMETER BorderWidth + Specifies the CSS border width for matching header cells. + + .PARAMETER BorderColor + Specifies the CSS border color for matching header cells. + .PARAMETER AddRow Switch parameter to add an additional row to the table header. @@ -74,7 +83,10 @@ [ValidateSet('left', 'center', 'right', 'justify')][string] $Alignment, [ValidateSet('none', 'line-through', 'overline', 'underline')][string] $TextDecoration, [ValidateSet('uppercase', 'lowercase', 'capitalize')][string] $TextTransform, - [ValidateSet('rtl')][string] $Direction, + [ValidateSet('rtl', 'ltr')][string] $Direction, + [ValidateSet('none', 'hidden', 'dotted', 'dashed', 'solid', 'double', 'groove', 'ridge', 'inset', 'outset')][string] $BorderStyle, + [object] $BorderWidth, + [string] $BorderColor, [switch] $AddRow, [int] $ColumnCount, [ValidateSet( @@ -128,6 +140,9 @@ TextDecoration = $TextDecoration TextTransform = $TextTransform Direction = $Direction + BorderStyle = $BorderStyle + BorderWidth = $BorderWidth + BorderColor = $BorderColor } Remove-EmptyValue -Hashtable $Style @@ -157,4 +172,4 @@ } Register-ArgumentCompleter -CommandName New-TableHeader -ParameterName Color -ScriptBlock $Script:ScriptBlockColors -Register-ArgumentCompleter -CommandName New-TableHeader -ParameterName BackGroundColor -ScriptBlock $Script:ScriptBlockColors \ No newline at end of file +Register-ArgumentCompleter -CommandName New-TableHeader -ParameterName BackGroundColor -ScriptBlock $Script:ScriptBlockColors diff --git a/Public/New-TableRowGrouping.ps1 b/Public/New-TableRowGrouping.ps1 index 1a872c95..88becebb 100644 --- a/Public/New-TableRowGrouping.ps1 +++ b/Public/New-TableRowGrouping.ps1 @@ -21,6 +21,9 @@ .PARAMETER BackgroundColor Specifies the background color for the row grouping. + .PARAMETER HideGroupedColumn + Hides the grouped source column while keeping it available for grouping and searching. + .EXAMPLE New-TableRowGrouping -Name "Group A" -ColumnID 1 -SortOrder 'Ascending' -Color 'Red' -BackgroundColor 'LightGray' Creates a new table row grouping object for Group A, grouping by column ID 1 in ascending order with red text and light gray background. @@ -36,7 +39,8 @@ [int] $ColumnID = -1, [ValidateSet('Ascending', 'Descending')][string] $SortOrder = 'Ascending', [string] $Color, - [string] $BackgroundColor + [string] $BackgroundColor, + [switch] $HideGroupedColumn ) $Script:HTMLSchema.Features.DataTablesRowGrouping = $true @@ -45,7 +49,8 @@ Output = [ordered] @{ Name = $Name ColumnID = $ColumnID - Sorting = if ('Ascending') { 'asc' } else { 'desc' } + Sorting = if ($SortOrder -eq 'Ascending') { 'asc' } else { 'desc' } + HideColumn = $HideGroupedColumn.IsPresent Attributes = @{ 'color' = ConvertFrom-Color -Color $Color 'background-color' = ConvertFrom-Color -Color $BackgroundColor @@ -57,4 +62,4 @@ } Register-ArgumentCompleter -CommandName New-TableRowGrouping -ParameterName Color -ScriptBlock $Script:ScriptBlockColors -Register-ArgumentCompleter -CommandName New-TableRowGrouping -ParameterName BackgroundColor -ScriptBlock $Script:ScriptBlockColors \ No newline at end of file +Register-ArgumentCompleter -CommandName New-TableRowGrouping -ParameterName BackgroundColor -ScriptBlock $Script:ScriptBlockColors diff --git a/Tests/New-HTMLChart.Tests.ps1 b/Tests/New-HTMLChart.Tests.ps1 new file mode 100644 index 00000000..56ce5afc --- /dev/null +++ b/Tests/New-HTMLChart.Tests.ps1 @@ -0,0 +1,84 @@ +Import-Module "$PSScriptRoot\..\PSWriteHTML.psd1" -Force + +Describe 'New-HTMLChart additive chart APIs' { + It 'Exports easy chart commands as public module functions' { + $Commands = @( + 'New-ChartArea' + 'ChartArea' + 'New-ChartScatter' + 'ChartScatter' + 'New-ChartBubble' + 'ChartBubble' + 'New-ChartHeatmap' + 'ChartHeatmap' + 'New-ChartRadar' + 'ChartRadar' + 'New-ChartLabel' + 'ChartLabel' + ) + + foreach ($Command in $Commands) { + Get-Command -Name $Command -Module PSWriteHTML -ErrorAction Stop | Should -Not -BeNullOrEmpty + } + } + + It 'Serializes additive ApexCharts types and label options' { + $FilePath = "$PSScriptRoot\TemporaryCharts.html" + + New-HTML -TitleText 'Chart API Test' -FilePath $FilePath -Online { + New-HTMLChart -Title 'Area' { + New-ChartAxisX -Name 'Jan', 'Feb', 'Mar' + New-ChartDataLabel -Enabled -OffsetX 1 -OffsetY 2 + New-ChartArea -Name 'Revenue' -Value 10, 20, 15 -Color Blue -Curve smooth + } + New-HTMLChart -Title 'Scatter' { + New-ChartScatter -Name 'Samples' -X 1, 2, 3 -Y 10, 25, 18 -Color Purple + } + New-HTMLChart -Title 'Raw Scatter' { + New-ChartScatter -Name 'RawSamples' -Data @(, @(1, 10), , @(2, 25)) -Color Purple + } + New-HTMLChart -Title 'Raw Point Scatter' { + New-ChartScatter -Name 'RawPoint' -Data ([ordered] @{ x = 1; y = 10 }) -Color Purple + } + New-HTMLChart -Title 'Scalar Area' { + New-ChartArea -Name 'SingleArea' -Value 10 -Color Blue + } + New-HTMLChart -Title 'Bubble' { + New-ChartBubble -Name 'Risk' -X 1, 2, 3 -Y 20, 30, 15 -Z 5, 12, 8 -Color Orange + } + New-HTMLChart -Title 'Heatmap' { + New-ChartHeatmap -Name 'Monday' -X 'AM', 'PM' -Y 12, 18 + } + New-HTMLChart -Title 'Radar' { + New-ChartAxisX -Name 'A', 'B', 'C' + New-ChartRadar -Name 'Coverage' -Value 70, 85, 62 -Color Green + } + New-HTMLChart -Title 'Scalar Radar' { + New-ChartRadar -Name 'SingleRadar' -Value 10 -Color Green + } + New-HTMLChart -Title 'Labels' { + New-ChartPie -Name 'One' -Value 1 + New-ChartPie -Name 'Two' -Value 2 + New-ChartLabel -Name 'First', 'Second' + } + } + + $Content = Get-Content -Path $FilePath -Raw + $Content | Should -Match '"type"\s*:\s*"area"' + $Content | Should -Match '"type"\s*:\s*"scatter"' + $Content | Should -Match '"data"\s*:\s*\[\s*\[\s*1\s*,\s*10\s*\]\s*,\s*\[\s*2\s*,\s*25\s*\]' + $Content | Should -Match '"name"\s*:\s*"RawSamples"[\s\S]*"data"\s*:\s*\[\s*\[\s*1\s*,\s*10\s*\]\s*,\s*\[\s*2\s*,\s*25\s*\]' + $Content | Should -Match '"name"\s*:\s*"RawPoint"[\s\S]*"data"\s*:\s*\[\s*\{\s*"x"\s*:\s*1\s*,\s*"y"\s*:\s*10\s*\}\s*\]' + $Content | Should -Match '"name"\s*:\s*"SingleArea"[\s\S]*"data"\s*:\s*\[\s*10\s*\]' + $Content | Should -Match '"type"\s*:\s*"bubble"' + $Content | Should -Match '"type"\s*:\s*"heatmap"' + $Content | Should -Match '"type"\s*:\s*"radar"' + $Content | Should -Match '"name"\s*:\s*"SingleRadar"[\s\S]*"data"\s*:\s*\[\s*10\s*\]' + $Content | Should -Match '"labels"\s*:\s*\[\s*"First"\s*,\s*"Second"\s*\]' + $Content | Should -Match '"offsetY"\s*:\s*2' + + if (Test-Path $FilePath) { + Remove-Item -LiteralPath $FilePath + } + } +} diff --git a/Tests/New-HTMLDiagram.Tests.ps1 b/Tests/New-HTMLDiagram.Tests.ps1 new file mode 100644 index 00000000..26c089f2 --- /dev/null +++ b/Tests/New-HTMLDiagram.Tests.ps1 @@ -0,0 +1,30 @@ +Import-Module "$PSScriptRoot\..\PSWriteHTML.psd1" -Force + +Describe 'New-HTMLDiagram edge options' { + It 'Serializes per-link width and global edge smooth options' { + $FilePath = "$PSScriptRoot\TemporaryDiagram.html" + + New-HTML -TitleText 'Diagram API Test' -FilePath $FilePath -Online { + New-HTMLDiagram -Height 400 { + New-DiagramOptionsLinks -Width 2 -HoverWidth 4 -SelectionWidth 5 -SmoothType curvedCW -SmoothRoundness 0.35 + New-DiagramNode -Id 'A' -Label 'A' + New-DiagramNode -Id 'B' -Label 'B' + New-DiagramLink -From 'A' -To 'B' -Label 'weighted' -Width 6 -HoverWidth 8 -SelectionWidth 10 -Value 3 -ArrowsToEnabled -ArrowsToScaleFactor 2 + } + } + + $Content = Get-Content -Path $FilePath -Raw + $Content | Should -Match '"width"\s*:\s*6' + $Content | Should -Match '"hoverWidth"\s*:\s*8' + $Content | Should -Match '"selectionWidth"\s*:\s*10' + $Content | Should -Match '"value"\s*:\s*3' + $Content | Should -Match '"scaleFactor"\s*:\s*2' + $Content | Should -Match '"smooth"\s*:\s*\{' + $Content | Should -Match '"type"\s*:\s*"curvedCW"' + $Content | Should -Match '"roundness"\s*:\s*0.35' + + if (Test-Path $FilePath) { + Remove-Item -LiteralPath $FilePath + } + } +} diff --git a/Tests/New-HTMLIssueFixes.Tests.ps1 b/Tests/New-HTMLIssueFixes.Tests.ps1 new file mode 100644 index 00000000..f9dd43b4 --- /dev/null +++ b/Tests/New-HTMLIssueFixes.Tests.ps1 @@ -0,0 +1,87 @@ +BeforeAll { + Import-Module (Join-Path $PSScriptRoot '..\PSWriteHTML.psd1') -Force +} + +Describe 'Issue-oriented HTML fixes' { + It 'renders table cell alignment, header borders, custom footer, column widths, row grouping hide, and SearchBuilder button language' { + $FilePath = Join-Path $TestDrive 'table-issue-fixes.html' + $Data = @( + [PSCustomObject]@{ Team = 'A'; Notes = "First`nSecond"; Count = 2 } + [PSCustomObject]@{ Team = 'B'; Notes = 'Third'; Count = 3 } + ) + + New-HTML -FilePath $FilePath -Online { + New-HTMLTable -DataTable $Data -DataTableID 'issueTable' -Filtering -DisableStateSave { + New-TableButtonSearchBuilder -ButtonName 'Advanced filters' -DepthLimit 3 + New-TableHeader -Names 'Team', 'Notes', 'Count' -BorderStyle solid -BorderWidth 2 -BorderColor '#4b5563' + New-TableContent -ColumnName 'Notes' -VerticalAlignment top + New-TableColumnOption -ColumnIndex 1 -Width '30%' + New-TableRowGrouping -Name 'Team' -SortOrder Descending -HideGroupedColumn + New-TableFooter -ValueByColumn @{ Team = 'Totals'; Count = 5 } -FontWeight bold + } + } + + $Content = Get-Content -LiteralPath $FilePath -Raw + $Content | Should -Match 'vertical-align:\s*top' + $Content | Should -Match 'border-style:\s*solid' + $Content | Should -Match 'border-width:\s*2px' + $Content | Should -Match 'First
Second' + $Content | Should -Match '' + $Content | Should -Match 'pswritehtml-filter-row' + $Content | Should -Match 'pswritehtml-static-footer-row' + $Content | Should -Match 'tfoot tr:not\(.pswritehtml-static-footer-row\) th' + $Content | Should -Match 'Totals' + $Content | Should -Match '5' + $Content | Should -Match '' + $Content | Should -Match '"button":\s*"Advanced filters"' + $Content | Should -Match '"order":\s*\[\s*\[\s*0,\s*"desc"\s*\]\s*\]' + $Content | Should -Match '"targets":\s*0\s*,\s*"visible":\s*false' + } + + It 'does not render an empty summary heading when no title is provided' { + $FilePath = Join-Path $TestDrive 'summary-no-title.html' + + New-HTML -FilePath $FilePath -Online { + New-HTMLSummary { + New-HTMLSummaryItem -Text 'Visible item' + } + } + + $Content = Get-Content -LiteralPath $FilePath -Raw + $Content | Should -Not -Match 'summary-title' + $Content | Should -Match 'Visible item' + } + + It 'sets a tab panel default tab from New-HTMLTab' { + $FilePath = Join-Path $TestDrive 'default-tab.html' + + New-HTML -FilePath $FilePath -Online { + New-HTMLTabPanel { + New-HTMLTab -Name 'First' { New-HTMLText -Text 'First content' } + New-HTMLTab -Name 'Second' -Default { New-HTMLText -Text 'Second content' } + } + } + + $Content = Get-Content -LiteralPath $FilePath -Raw + $Content | Should -Match '"selected":\s*1' + } + + It 'sets a standalone default tab at runtime without leaving the first pane active' { + $FilePath = Join-Path $TestDrive 'standalone-default-tab.html' + + New-HTML -FilePath $FilePath -Online { + New-HTMLTab -Name 'First' -AnchorName 'first-tab' { + New-HTMLText -Text 'First content' + } + New-HTMLTab -Name 'Second' -AnchorName 'second-tab' -Default { + New-HTMLText -Text 'Second content' + } + } + + $Content = Get-Content -LiteralPath $FilePath -Raw + $Content | Should -Match 'var tabId = "second-tab"' + $Content | Should -Match 'var paneId = "second-tab-Content"' + $Content | Should -Match "child\.classList\.remove\('active'\)" + $Content | Should -Match "pane\.classList\.add\('active'\)" + } +}