Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
697869f
Bump module version to 0.3.3, update dependencies, and enhance releas…
rebelinux Jun 4, 2026
1f6120f
Add Donut Chart functionality and examples; update module exports and…
rebelinux Jun 5, 2026
48d4cb7
Add tests for New-DonutChart cmdlet: validate execution, output, and …
rebelinux Jun 5, 2026
ac4d39d
Merge branch 'AsBuiltReport:dev' into dev
rebelinux Jun 5, 2026
be8d602
Update CHANGELOG.md for version 0.3.3: enhance documentation for New-…
rebelinux Jun 6, 2026
a25bb57
Add radar chart support to Todo.md
rebelinux Jun 6, 2026
f92a1e4
Merge branch 'dev' of https://github.com/rebelinux/AsBuiltReport.Char…
rebelinux Jun 8, 2026
7b16f55
Add radar chart support: implement New-RadarChart cmdlet and associat…
rebelinux Jun 11, 2026
7fe839b
Merge pull request #37 from rebelinux/dev
rebelinux Jun 11, 2026
c2fa862
Update README with new chart examples and details
rebelinux Jun 11, 2026
4cecd68
Add files via upload
rebelinux Jun 11, 2026
b4ef340
Revise README with new links and examples
rebelinux Jun 12, 2026
92006da
Update README.md with new content and examples
rebelinux Jun 12, 2026
32614ce
Update examples and enhance Radar and Donut chart functionalities
rebelinux Jun 12, 2026
8b174ee
Merge pull request #38 from rebelinux/dev
rebelinux Jun 12, 2026
d3799ff
Fix array initialization for chart values in Example14.ps1
rebelinux Jun 12, 2026
2ec60f8
Merge branch 'AsBuiltReport:dev' into dev
rebelinux Jun 12, 2026
59d5ec4
Merge pull request #39 from rebelinux/dev
rebelinux Jun 12, 2026
8c318e0
Update Example05.ps1
rebelinux Jun 12, 2026
3952781
Update copilot instructions and add SpokesLength property to Chart class
rebelinux Jun 12, 2026
5c56c3b
Add tests for New-RadarChart functionality and export verification
rebelinux Jun 12, 2026
b783bbb
Update changelog for version 0.3.3 release date
rebelinux Jun 12, 2026
8f5053e
Merge pull request #40 from rebelinux/dev
rebelinux Jun 12, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 24 additions & 4 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,18 @@
This project is a **hybrid C# + PowerShell module**. The C# layer compiles into platform-specific DLLs; the PowerShell layer loads the right DLL at import time and exposes cmdlets.

```
Sources/ ← C# library (ScottPlot + SkiaSharp, netstandard2.0)
Sources/ ← C# library (ScottPlot + SkiaSharp, net8.0 / netstandard2.0)
Chart.cs ← Static base class; all chart settings live here as static props
PieChart.cs / BarChart.cs / StackedBarChart.cs / SignalChart.cs ← Chart implementations
PieChart.cs / DonutChart.cs / BarChart.cs / StackedBarChart.cs / SignalChart.cs / RadarChart.cs
← Chart implementations
PowerShell/ ← One PSCmdlet class per chart type (New-*Chart cmdlets)
Enums/Enums.cs ← All shared enums (BasicColors, Formats, ColorPalettes, etc.)

AsBuiltReport.Chart/ ← PowerShell module
AsBuiltReport.Chart.psm1 ← Loads the correct DLL based on PSEdition + OS + architecture
AsBuiltReport.Chart.psd1 ← Module manifest; exports: New-PieChart, New-BarChart,
New-StackedBarChart, New-SingleStackedBarChart, New-SignalChart
AsBuiltReport.Chart.psd1 ← Module manifest; exports: New-PieChart, New-DonutChart,
New-BarChart, New-StackedBarChart, New-SingleStackedBarChart,
New-SignalChart, New-RadarChart
Src/Assemblies/ ← Pre-compiled DLLs, organized by platform:
Core/linux-x64/
Core/windows-x64/
Expand Down Expand Up @@ -70,8 +72,26 @@ Invoke-ScriptAnalyzer -Path . -Recurse -Settings .\.github\workflows\PSScriptAna

Excluded rules: `PSUseToExportFieldsInManifest`, `PSReviewUnusedParameter`, `PSUseDeclaredVarsMoreThanAssignments`, `PSAvoidGlobalVars`.

### Build (Pester Tests) in CI/CD

```powershell
.\Tests\Invoke-Tests.ps1 -CodeCoverage -OutputFormat NUnitXml
```

Supports optional flags:
- `-CodeCoverage` – Enable code coverage analysis
- `-OutputFormat <Console|NUnitXml|JUnitXml>` – Output format for test results (default: Console)

## Key Conventions

### Cross-platform DLL loading

The `.psm1` module import process detects the current PowerShell edition, OS, and architecture, then loads the appropriate pre-compiled DLL:
- **PowerShell 7+** on Windows/Linux/macOS → Loads from `Core/` folder
- **PowerShell 5.1 (Desktop)** on Windows → Loads from `Desktop/windows-x64/` folder (Windows-only)

If the correct DLL cannot be found for the runtime, the module import fails with a clear error message.

### Adding a new chart type

Every new chart type requires changes in both layers:
Expand Down
45 changes: 15 additions & 30 deletions .github/workflows/Release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: Publish PowerShell Module

on:
release:
types: [ published ]
types: [published]

jobs:
publish-to-psgallery:
Expand All @@ -23,12 +23,14 @@ jobs:
- name: Build the library for MacOS Arm64
run: dotnet publish ./Sources -c Release -r osx-arm64
- name: Copy the library for MacOS Arm64
run: copy ./Sources/bin/Release/netstandard2.0/osx-arm64/publish/*.*
run:
copy ./Sources/bin/Release/netstandard2.0/osx-arm64/publish/*.*
./AsBuiltReport.Chart/Src/Assemblies/Core/mac-osx/osx-arm64
- name: Build the library for Linux
run: dotnet publish ./Sources -c Release -r linux-x64
- name: Copy the library for Linux
run: copy ./Sources/bin/Release/netstandard2.0/linux-x64/publish/*.*
run:
copy ./Sources/bin/Release/netstandard2.0/linux-x64/publish/*.*
./AsBuiltReport.Chart/Src/Assemblies/Core/linux-x64
- name: Build the library for Windows
run: dotnet publish ./Sources -c Release -r win-x64
Expand All @@ -54,30 +56,13 @@ jobs:
shell: pwsh
run: |
Publish-Module -Path .\AsBuiltReport.Chart\ -NuGetApiKey ${{ secrets.PSGALLERY_API_KEY }} -Verbose
# tweet:
# needs: publish-to-psgallery
# runs-on: ubuntu-latest
# steps:
# - uses: Eomm/why-don-t-you-tweet@v2
# # We don't want to tweet if the repository is not a public one
# if: ${{ !github.event.repository.private }}
# with:
# # GitHub event payload
# # https://docs.github.com/en/developers/webhooks-and-events/webhooks/webhook-events-and-payloads#release
# tweet-message: "[New Release] ${{ github.event.repository.name }} ${{ github.event.release.tag_name }}! Check out what's new! ${{ github.event.release.html_url }} #AsBuiltReport #PowerShell"
# env:
# TWITTER_CONSUMER_API_KEY: ${{ secrets.TWITTER_CONSUMER_API_KEY }}
# TWITTER_CONSUMER_API_SECRET: ${{ secrets.TWITTER_CONSUMER_API_SECRET }}
# TWITTER_ACCESS_TOKEN: ${{ secrets.TWITTER_ACCESS_TOKEN }}
# TWITTER_ACCESS_TOKEN_SECRET: ${{ secrets.TWITTER_ACCESS_TOKEN_SECRET }}
# bsky-post:
# needs: publish-to-psgallery
# runs-on: ubuntu-latest
# steps:
# - uses: zentered/bluesky-post-action@v0.3.0
# with:
# post: "[New Release] ${{ github.event.repository.name }} ${{ github.event.release.tag_name }}! Check out what's new! ${{ github.event.release.html_url }} #AsBuiltReport #PowerShell"
# env:
# BSKY_IDENTIFIER: ${{ secrets.BSKY_IDENTIFIER }}
# BSKY_PASSWORD: ${{ secrets.BSKY_PASSWORD }}

bsky-post:
needs: publish-to-psgallery
runs-on: ubuntu-latest
steps:
- uses: zentered/bluesky-post-action@v0.4.0
with:
post: "[New Release] ${{ github.event.repository.name }} ${{ github.event.release.tag_name }}! Check out what's new! ${{ github.event.release.html_url }} #AsBuiltReport #PowerShell"
env:
BSKY_IDENTIFIER: ${{ secrets.BSKY_IDENTIFIER }}
BSKY_PASSWORD: ${{ secrets.BSKY_PASSWORD }}
4 changes: 2 additions & 2 deletions AsBuiltReport.Chart/AsBuiltReport.Chart.psd1
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
RootModule = 'AsBuiltReport.Chart.psm1'

# Version number of this module.
ModuleVersion = '0.3.2'
ModuleVersion = '0.3.3'

# Supported PSEditions
# CompatiblePSEditions = @()
Expand Down Expand Up @@ -69,7 +69,7 @@
# NestedModules = @()

# Functions to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no functions to export.
FunctionsToExport = 'New-PieChart', 'New-BarChart', 'New-StackedBarChart', 'New-SignalChart', 'New-SingleStackedBarChart'
FunctionsToExport = 'New-PieChart', 'New-BarChart', 'New-StackedBarChart', 'New-SignalChart', 'New-SingleStackedBarChart', 'New-DonutChart', 'New-RadarChart'

# Cmdlets to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no cmdlets to export.
# CmdletsToExport = '*'
Expand Down
17 changes: 17 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,23 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [0.3.3] - 2026-06-12

### Added

- Add support for Donut from Slices chart: [Donut from Slices](https://scottplot.net/cookbook/5/Pie/PieDonut/)
- Add pester test to validate the functionality of the New-DonutChart cmdlet
- Add example 12/13 to document on how to use the New-DonutChart cmdlet
- Add radar chart support: implement New-RadarChart cmdlet and associated classes
- Add pester test to validate the functionality of the New-RadarChart cmdlet
- Add example 14/15 to document on how to use the New-RadarChart cmdlet

### Changed

- Update module v0.3.3
- Update SkiaSharp .NET dependency to v3.119.4
- Update HarfBuzzSharp .NET dependency to v8.3.1.5

## [0.3.2] - 2026-05-05

### Added
Expand Down
5 changes: 2 additions & 3 deletions Examples/Example05.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -45,12 +45,11 @@ $OutputFolderPath = Resolve-Path $Path
#>

$ChartTitle = 'Datastore Capacity (GB)'
$Labels = @('datastore-01', 'datastore-02', 'datastore-03', 'datastore-04')
$Labels = @('datastore-01')
$LegendCategories = @('Used Space', 'Free Space')

# Each inner array represents one bar's segment values, ordered by $LegendCategories.
$Values = @(@(800, 200), @(600, 400), @(1500, 500), @(300, 700))

$Values = ,@(800, 200) # The comma before the array creates a single-element array containing the inner array, which is required for the Stacked Bar Chart format.
<#
The New-StackedBarChart cmdlet generates the Stacked Bar Chart image.

Expand Down
61 changes: 61 additions & 0 deletions Examples/Example12.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
<#
.SYNOPSIS
Example 12 - Basic Donut Chart

.DESCRIPTION
This example demonstrates how to create a basic Donut Chart using the AsBuiltReport.Chart module.
The chart displays a simple breakdown of VM power states across a vSphere environment.
#>

[CmdletBinding()]
param (
[System.IO.DirectoryInfo] $Path = (Get-Location).Path,
[string] $Format = 'png'
)

<#
Starting with PowerShell v3, modules are auto-imported when needed. Importing the module here
ensures clarity and avoids ambiguity.
#>

# Import-Module AsBuiltReport.Chart -Force -Verbose:$false

<#
Since the chart output is a file, specify the output folder path using $OutputFolderPath.
#>

$OutputFolderPath = Resolve-Path $Path

<#
Define the data to be displayed in the chart.
In a real-world scenario these values would come from your infrastructure query.
#>

$ChartTitle = 'User Type Breakdown'
$Values = @(800, 80, 200)
$Labels = @('Members', 'Guests', 'Disabled')

<#
The New-DonutChart cmdlet generates the Donut Chart image.

-Title : Sets the chart title displayed at the top of the image.
-Values : Array of numeric values, one per slice.
-Labels : Array of label strings corresponding to each value.
-Format : Output file format (e.g. png, jpg, svg).
-OutputFolderPath : Directory where the generated chart file will be saved.
-Width : Width of the chart image in pixels.
-Height : Height of the chart image in pixels.
-ColorPalette : Predefined color palette (e.g. Category20, Pastel).
-Filename : Name of the output file (without extension).
#>

New-DonutChart `
-Title $ChartTitle `
-Values $Values `
-Labels $Labels `
-Format $Format `
-OutputFolderPath $OutputFolderPath `
-Width 600 `
-Height 400 `
-ColorPalette Category20 `
-Filename 'Example12-DonutChart'
98 changes: 98 additions & 0 deletions Examples/Example13.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
<#
.SYNOPSIS
Example 13 - Donut Chart with Legend, Custom Colors and Border

.DESCRIPTION
This example demonstrates how to create a Donut Chart with additional visual options, including:
- An enabled legend with custom alignment and orientation
- A custom hex color palette
- A chart border
- Adjusted title and label font sizes
- Custom chart dimensions

The chart displays a server operating system distribution report.
#>

[CmdletBinding()]
param (
[System.IO.DirectoryInfo] $Path = (Get-Location).Path,
[string] $Format = 'png'
)

<#
Starting with PowerShell v3, modules are auto-imported when needed. Importing the module here
ensures clarity and avoids ambiguity.
#>

# Import-Module AsBuiltReport.Chart -Force -Verbose:$false

<#
Since the chart output is a file, specify the output folder path using $OutputFolderPath.
#>

$OutputFolderPath = Resolve-Path $Path

<#
Define the data to be displayed in the chart.
In a real-world scenario these values would come from your infrastructure query.
#>

$ChartTitle = 'Server OS Distribution'
$Values = @(85, 60, 30, 15)
$Labels = @('Windows Server 2022', 'Windows Server 2019', 'RHEL 9', 'Ubuntu 22.04')

<#
A custom hex color palette can be used to match corporate branding or improve readability.
Each color corresponds to a slice in the order they appear in $Values.
#>

$CustomColors = @('#0078D4', '#00B7C3', '#E74C3C', '#F39C12')

<#
The New-DonutChart cmdlet generates the Donut Chart image.

-Title : Sets the chart title.
-TitleFontSize : Sets the font size of the title in points.
-TitleFontBold : Renders the title in bold.
-Values : Array of numeric values, one per slice.
-Labels : Array of label strings corresponding to each value.
-LabelFontSize : Sets the font size of the slice labels.
-LabelDistance : Controls how far labels are placed from the chart center (0.5-0.9).
-EnableLegend : Enables the legend on the chart.
-LegendAlignment : Positions the legend (e.g. UpperRight, LowerCenter).
-LegendOrientation : Sets legend layout direction (Vertical or Horizontal).
-LegendFontSize : Sets the legend text font size in points.
-EnableChartBorder : Draws a border around the chart area.
-ChartBorderColor : Sets the border color.
-ChartBorderSize : Sets the border thickness in pixels.
-EnableCustomColorPalette : Enables use of the custom color palette.
-CustomColorPalette : Array of hex color strings for each slice.
-Width : Output image width in pixels.
-Height : Output image height in pixels.
-Format : Output file format (e.g. png, jpg, svg).
-OutputFolderPath : Directory where the generated chart file will be saved.
-Filename : Name of the output file (without extension).
#>

New-DonutChart `
-Title $ChartTitle `
-TitleFontSize 18 `
-TitleFontBold `
-Values $Values `
-Labels $Labels `
-LabelFontSize 13 `
-LabelDistance 0.7 `
-EnableLegend `
-LegendAlignment UpperRight `
-LegendOrientation Vertical `
-LegendFontSize 12 `
-EnableChartBorder `
-ChartBorderColor Black `
-ChartBorderSize 2 `
-EnableCustomColorPalette `
-CustomColorPalette $CustomColors `
-Width 600 `
-Height 400 `
-Format $Format `
-OutputFolderPath $OutputFolderPath `
-Filename 'Example13-DonutChart-Advanced'
62 changes: 62 additions & 0 deletions Examples/Example14.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
<#
.SYNOPSIS
Example 14 - Basic Radar Chart

.DESCRIPTION
This example demonstrates how to create a basic Radar Chart using the AsBuiltReport.Chart module.
The chart displays a simple security posture assessment for two data centers across multiple categories.
#>

[CmdletBinding()]
param (
[System.IO.DirectoryInfo] $Path = (Get-Location).Path,
[string] $Format = 'png'
)

<#
Starting with PowerShell v3, modules are auto-imported when needed. Importing the module here
ensures clarity and avoids ambiguity.
#>

# Import-Module AsBuiltReport.Chart -Force -Verbose:$false

<#
Since the chart output is a file, specify the output folder path using $OutputFolderPath.
#>

$OutputFolderPath = Resolve-Path $Path

<#
Define the data to be displayed in the chart.
In a real-world scenario these values would come from your infrastructure query.
#>

$ChartTitle = 'Security Posture Assessment'
$Values = ,@(3,5,4,2) # The comma before the array ensures it's treated as a single array object
$Labels = @('USA DataCenter')

<#
The New-RadarChart cmdlet generates the Radar Chart image.

-Title : Sets the chart title displayed at the top of the image.
-Values : Array of numeric values, one per axis.
-LegendLabels : Array of label strings corresponding to each value.
-Format : Output file format (e.g. png, jpg, svg).
-OutputFolderPath : Directory where the generated chart file will be saved.
-Width : Width of the chart image in pixels.
-Height : Height of the chart image in pixels.
-ColorPalette : Predefined color palette (e.g. Category20, Pastel).
-Filename : Name of the output file (without extension).
#>

New-RadarChart `
-Title $ChartTitle `
-Values $Values `
-LegendLabels $Labels `
-Format $Format `
-EnableLegend `
-OutputFolderPath $OutputFolderPath `
-Width 600 `
-Height 400 `
-ColorPalette Category20 `
-Filename 'Example14-RadarChart'
Loading
Loading