Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Control New-DiagramLink arrow width #328

Open
PatrickOnGit opened this issue Jul 8, 2022 · 5 comments
Open

Control New-DiagramLink arrow width #328

PatrickOnGit opened this issue Jul 8, 2022 · 5 comments

Comments

@PatrickOnGit
Copy link

PatrickOnGit commented Jul 8, 2022

Dear Przemyslaw

Is it possible to control the width of an arrow between two nodes?
I have written a little function that visualizes AD Site configuration and would like to have different arrow sizes based on site costs.
Later I also want to add also option to click on a site / site link to get additional information. But that is a different topic;-)

The code currently looks like this:

`Import-Module PSWriteHTML -Force

New-HTML -TitleText 'AD Sites' -Online -FilePath $PSScriptRoot\ADSites.html {

New-HTMLSection {

    New-HTMLDiagram -Height 800 {
        New-DiagramOptionsPhysics -StabilizationEnabled $true -Solver repulsion 
        Get-ADReplicationSite -filter * |
            ForEach-Object {
                $Site = $_
                Switch -Regex ($_.Name) {
                    "^Default-First-Site-Name$" { New-DiagramNode -Label "$($Site.Name)" -Id "$($Site.DistinguishedName)" -ColorBackground Amber }
                    "^(MainSite-0|MainSite-2)$" { New-DiagramNode -Label "$($Site.Name)" -Id "$($Site.DistinguishedName)" -ColorBackground Amber }
                    Default {New-DiagramNode -Label "$($Site.Name)" -Id "$($Site.DistinguishedName)" }
                }

            }
        Get-ADReplicationSiteLink -filter * |
            ForEach-Object {
                 If ( $_.SitesIncluded.count -lt 2 ) {
                     Write-Warning $( "Sitelink {0} has {1} sites included." -f $_.Name, $_.SitesIncluded.Count )
                 }
                 # Create all possible links
                 for ($i = 0; $i -lt $_.SitesIncluded.count; $i++) {
                    for ($n = ($i + 1); $n -lt $_.SitesIncluded.count; $n++) {
                        New-DiagramLink -From $_.SitesIncluded[$i] -To $_.SitesIncluded[$n] -Label $_.Name
                        
                    }
                 }
                 
            }
    } #-DisableLoadingBar

}

} -ShowHTML`

Thank you for your support.
Patrick

@PrzemyslawKlys
Copy link
Member

Cool you could improve my Show-WinADSites

image

The way I usually deal with "costs" is to use hierarchical diagram. You then tell it the Level you want it on. 0,1,2,3,4,5,6 and so on. This way its much more readable. You could probably control width on non-hierarchical diagram but I am afraid things would get ugly.

@PatrickOnGit
Copy link
Author

I had a quick look into your new function. Think it gathers too much information when using it in large environments. It takes a long time. Of course it shows quite valuable information. But I would be first intersted in the connections:

image

Then, when selecting a site, the table could show me all subnets related to the site or all DCs responsible for this site.
The reason I would like to have different line weights is to quickly show if one link is more costly than another. I could do this also by color I guess. First get all costs, see how many different costs there are and then assign a color to each. From Green with low costs to red with high costs. Bad for color blind people, but at least some indicator.

Is it possible to hide / unhide information in the graphic on click?

@PatrickOnGit
Copy link
Author

I did a quick rewrite of my version of the script to include your data table. It^s not ideal yet, like schedules is not resovled etc, and missing Subnets, but it took few seconds to build instead of, well, your version is still trying to show something ;-)
Its a decission between speed and informations. I will look later in your version.
I know you have example where you hide or show table information based on clicking the graphic. Would you mind pointing me to one?

Import-Module PSWriteHTML -Force
$Sites = Get-ADReplicationSite -filter *
$SiteLinks = Get-ADReplicationSiteLink -filter *

New-HTML -TitleText 'AD Sites' -Online -FilePath $PSScriptRoot\ADSites.html  {
    New-HTMLSectionStyle -BorderRadius 0px -HeaderBackGroundColor Grey -RemoveShadow
    New-HTMLTableOption -DataStore HTML
    New-HTMLTabStyle -BorderRadius 0px -TextTransform capitalize -BackgroundColorActive SlateGrey
    New-HTMLTabPanel {
        New-HTMLTab -TabName 'Standard' {
            New-HTMLSection -HeaderText 'Organization Diagram' {

                New-HTMLDiagram -Height 800 {
                    New-DiagramOptionsPhysics -StabilizationEnabled $true -Solver repulsion 
                    $Sites |
                        ForEach-Object {
                            $Site = $_
                            Switch -Regex ($_.Name) {
                                "^Default-First-Site-Name$" { New-DiagramNode -Label "$($Site.Name)" -Id "$($Site.DistinguishedName)" -ColorBackground Amber }
                                "^(MainSite-0|MainSite-2)$" { New-DiagramNode -Label "$($Site.Name)" -Id "$($Site.DistinguishedName)" -ColorBackground Amber }
                                Default {New-DiagramNode -Label "$($Site.Name)" -Id "$($Site.DistinguishedName)" }
                            }

                        }
                    $SiteLinks |
                        ForEach-Object {
                             If ( $_.SitesIncluded.count -lt 2 ) {
                                 Write-Warning $( "Sitelink {0} has {1} sites included." -f $_.Name, $_.SitesIncluded.Count )
                             }
                             # Create all possible links
                             for ($i = 0; $i -lt $_.SitesIncluded.count; $i++) {
                                for ($n = ($i + 1); $n -lt $_.SitesIncluded.count; $n++) {
                                    New-DiagramLink -From $_.SitesIncluded[$i] -To $_.SitesIncluded[$n] -Label $_.Name
                            
                                }
                             }
                     
                        }
                } 
            }
        }
    }
    New-HTMLSection -Title "Information about Sites" {
        New-HTMLTable -DataTable $Sites -Filtering {
            if (-not $DisableBuiltinConditions) {
                New-TableCondition -BackgroundColor MediumSeaGreen -ComparisonType number -Value 0 -Name SubnetsCount -Operator gt
                New-TableCondition -BackgroundColor CoralRed -ComparisonType number -Value 0 -Name SubnetsCount -Operator eq
            }
            if ($Conditions) {
                & $Conditions
            }
        } -DataTableID 'DT-StandardSites' -DataStore JavaScript


    }
    New-HTMLTable -DataTable $Replication -Filtering {
        if (-not $DisableBuiltinConditions) {
            New-TableCondition -BackgroundColor MediumSeaGreen -ComparisonType number -Value 0 -Name SubnetsCount -Operator gt
            New-TableCondition -BackgroundColor CoralRed -ComparisonType number -Value 0 -Name SubnetsCount -Operator eq
        }
        if ($Conditions) {
            & $Conditions
        }
    } -DataTableID 'DT-StandardSites1' -DataStore JavaScript
  #  }
} -ShowHTML

@PrzemyslawKlys
Copy link
Member

You should read this:

Import-Module .\PSWriteHTML.psd1 -Force

$Processes = Get-Process | Select-Object -First 3 -Property Name, ProcessName, Id, FileVersion, WorkingSet

New-HTML -TitleText 'My Title' -Online -FilePath $PSScriptRoot\Example30-LinkedTableToTable02.html -ShowHTML {
    New-HTMLTableOption -DataStore Javascript
    New-HTMLSection -Invisible {
        New-HTMLPanel {
            New-HTMLTable -DataTable $Processes -DataTableID 'RandomID1' {
                New-TableEvent -ID 'RandomID2' -SourceColumnID 0 -TargetColumnId 0
                New-TableEvent -ID 'RandomID3' -SourceColumnID 0 -TargetColumnId 0
            }
        }
        New-HTMLPanel {
            New-HTMLTable -DataTable $Processes -DataTableID 'RandomID2'
        }
    }
    New-HTMLPanel {
        New-HTMLTable -DataTable $Processes -DataTableID 'RandomID3'
    }
}

@PatrickOnGit
Copy link
Author

PatrickOnGit commented Jul 8, 2022

I played a little bit more around and it now looks quite good. Still I would be happy to be able to have different arrow weights ;-)

It is not yet ideal and it doesn't yet fit into your ADEssentials module, but let me know what you think.
If possible I would like to hide the DNs, but I need them as unique reference.
Sometimes the filter from last created HTML file is also used on a freshly opened document.
The comparison of the \A0DEL to verify if a deleted object is referenced breaks the first table.

Import-Module PSWriteHTML -Force
$Subnets = Get-ADReplicationSubnet -Filter * | Select @{n='Site';e={ $_.Site  -replace 'CN=(.*?),.*','$1' }}, @{n='Subnet';e={ $_.Name}}, Location, @{ n='SiteDN';e={$_.Site}}
$SubnetsHash =  @{}
$Subnets | %{ if ( $SubnetsHash.ContainsKey($_.SiteDN) ) {  $SubnetsHash[$_.SiteDN] += $_.Subnet  } else { $SubnetsHash.Add( $_.SiteDN,@(,$_.Subnet) ) } }
$Sites = Get-ADReplicationSite -filter * | 
        Select-Object Name, Description,
            @{ n="InterSiteTopologyGenerator";e={ 
                if ( $_.InterSiteTopologyGenerator -match "\\0ADEL" ) {
                    $_.InterSiteTopologyGenerator } else {
                    try { Get-ADObject -searchbase "$($_.InterSiteTopologyGenerator -replace '.*?,(.*)$','$1' )" -SearchScope Base  -Filter * -Properties dnsHostName  | Select-Object -ExpandProperty dnsHostName } catch {  }  }
             }},
             @{ n='SubnetCount';e={ $SubnetsHash[$_.DistinguishedName].count } },
             ManagedBy,  
            @{ n='hasSchedule';e={ if( $_.ReplicationSchedule ) {$true} else {$false} }},UniversalGroupCachingRefreshSite, 
            DistinguishedName
$SiteLinks = Get-ADReplicationSiteLink -filter * | Select-Object Name, Cost, ReplicationFrequencyInMinutes, SitesIncluded, DistinguishedName

$CostGroup = $SiteLinks | Group Cost -NoElement
$Script:LinkToSite = @()
New-HTML -TitleText 'AD Sites' -Online -FilePath $PSScriptRoot\ADSites.html  {
    New-HTMLSectionStyle -BorderRadius 0px -HeaderBackGroundColor Grey -RemoveShadow
    New-HTMLTableOption -DataStore HTML
    New-HTMLTabStyle -BorderRadius 0px -TextTransform capitalize -BackgroundColorActive SlateGrey
    New-HTMLTabPanel {
        New-HTMLTab -TabName 'Standard' {
            New-HTMLSection -HeaderText 'Organization Diagram' {

                New-HTMLDiagram -Height 800 {
                    New-DiagramOptionsPhysics -StabilizationEnabled $true -Solver repulsion 
                    $Sites |
                        ForEach-Object {
                            $Site = $_
                            Switch -Regex ($_.Name) {
                                "^Default-First-Site-Name$" { New-DiagramNode -Label "$($Site.Name)" -Id "$($Site.DistinguishedName)" -ColorBackground Amber }
                                "^(CHBS-0|USEH-0|INKL-0|SGSG-0)$" { New-DiagramNode -Label "$($Site.Name)" -Id "$($Site.DistinguishedName)" -ColorBackground Amber }
                                Default {New-DiagramNode -Label "$($Site.Name)" -Id "$($Site.DistinguishedName)" }
                            }

                        }
                    New-DiagramEvent -ID 'DT-Sites' -ColumnID 7
                    New-DiagramEvent -ID 'DT-Subnets' -ColumnID 3
                    New-DiagramEvent -ID 'DT-SiteLinks' -ColumnID 5

                    $SiteLinks |
                        ForEach-Object {
                             $SiteLink = $_
                             If ( $_.SitesIncluded.count -lt 2 ) {
                                 Write-Warning $( "Sitelink {0} has {1} sites included." -f $_.Name, $_.SitesIncluded.Count )
                                 $Script:LinkToSite += New-Object PSObject -Property  ( [ordered] @{
                                    linkedFrom = $_.SitesIncluded[0] -replace 'CN=(.*?),.*','$1'
                                    linkedTo = ''
                                    linkName = $_.Name
                                    Cost = $_.Cost
                                    ReplicationFrequencyInMinutes =  $_.ReplicationFrequencyInMinutes
                                    linkDN = $_.SitesIncluded[0]
                                } )
                             }
                             # Create all possible links
                             for ($i = 0; $i -lt $_.SitesIncluded.count; $i++) {
                                for ($n = ($i + 1); $n -lt $_.SitesIncluded.count; $n++) {
                                    New-DiagramLink -From $_.SitesIncluded[$i] -To $_.SitesIncluded[$n] -Label $_.Name
                                    $Script:LinkToSite += New-Object PSObject -Property  ( [ordered] @{
                                        linkedFrom = $_.SitesIncluded[$i] -replace 'CN=(.*?),.*','$1'
                                        linkedTo = $_.SitesIncluded[$n] -replace 'CN=(.*?),.*','$1'
                                        linkName = $_.Name
                                        Cost = $_.Cost
                                        ReplicationFrequencyInMinutes =  $_.ReplicationFrequencyInMinutes
                                        linkDN = $_.SitesIncluded[$i]
                                    } )
                                    # To be able to select either site, the link information needs to be added twice
                                    $Script:LinkToSite += New-Object PSObject -Property  ( [ordered] @{
                                        linkedFrom = $_.SitesIncluded[$i] -replace 'CN=(.*?),.*','$1'
                                        linkedTo = $_.SitesIncluded[$n] -replace 'CN=(.*?),.*','$1'
                                        linkName = $_.Name
                                        Cost = $_.Cost
                                        ReplicationFrequencyInMinutes =  $_.ReplicationFrequencyInMinutes
                                        linkDN = $_.SitesIncluded[$n]
                                    } )
                                }
                             }
                     
                        }
                } 
            }
        }
    }
    New-HTMLSection -Title "Information about Sites" {
        New-HTMLTable -DataTable $Sites -Filtering {
            New-TableColumnOption -Hidden $true -ColumnIndex 1
            if (-not $DisableBuiltinConditions) {
                New-TableCondition -BackgroundColor MediumSeaGreen -ComparisonType number -Value 0 -Name SubnetCount -Operator gt
                New-TableCondition -BackgroundColor CoralRed -ComparisonType number -Value 0 -Name SubnetCount -Operator eq
               # New-TableCondition -BackgroundColor MediumSeaGreen -ComparisonType string -Value '*\0ADEL*' -Name InterSiteTopologyGenerator -Operator notlike
               # New-TableCondition -BackgroundColor CoralRed -ComparisonType string -Value '*\0ADEL*' -Name InterSiteTopologyGenerator -Operator like
            }
            if ($Conditions) {
                & $Conditions
            }
        } -DataTableID 'DT-Sites' -DataStore JavaScript

        New-HTMLTable -DataTable $Subnets -Filtering {
           #  New-TableColumnOption -Hidden $true -ColumnIndex 0
        } -DataTableID 'DT-Subnets' -DataStore JavaScript
    
        New-HTMLTable -DataTable $Script:LinkToSite -Filtering {
          #  New-TableColumnOption -Hidden $true -ColumnIndex 2

        } -DataTableID 'DT-SiteLinks' -DataStore JavaScript 
  }
} -ShowHTML

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants