Add-Type -AssemblyName System.Drawing $output = Join-Path $PSScriptRoot 'flowchart-user-drawio.jpg' $width = 1500 $height = 1900 $bitmap = New-Object System.Drawing.Bitmap $width, $height $graphics = [System.Drawing.Graphics]::FromImage($bitmap) $graphics.SmoothingMode = [System.Drawing.Drawing2D.SmoothingMode]::AntiAlias $graphics.TextRenderingHint = [System.Drawing.Text.TextRenderingHint]::ClearTypeGridFit $graphics.Clear([System.Drawing.Color]::White) $titleFont = New-Object System.Drawing.Font('Arial', 26, [System.Drawing.FontStyle]::Bold) $font = New-Object System.Drawing.Font('Arial', 15, [System.Drawing.FontStyle]::Regular) $smallFont = New-Object System.Drawing.Font('Arial', 12, [System.Drawing.FontStyle]::Regular) $textBrush = New-Object System.Drawing.SolidBrush([System.Drawing.Color]::FromArgb(29, 41, 57)) $boxFill = New-Object System.Drawing.SolidBrush([System.Drawing.Color]::FromArgb(218, 232, 252)) $boxStroke = New-Object System.Drawing.Pen([System.Drawing.Color]::FromArgb(108, 142, 191), 2) $decisionFill = New-Object System.Drawing.SolidBrush([System.Drawing.Color]::FromArgb(255, 242, 204)) $decisionStroke = New-Object System.Drawing.Pen([System.Drawing.Color]::FromArgb(214, 182, 86), 2) $endFill = New-Object System.Drawing.SolidBrush([System.Drawing.Color]::FromArgb(213, 232, 212)) $endStroke = New-Object System.Drawing.Pen([System.Drawing.Color]::FromArgb(130, 179, 102), 2) $cancelFill = New-Object System.Drawing.SolidBrush([System.Drawing.Color]::FromArgb(248, 206, 204)) $cancelStroke = New-Object System.Drawing.Pen([System.Drawing.Color]::FromArgb(184, 84, 80), 2) $linePen = New-Object System.Drawing.Pen([System.Drawing.Color]::FromArgb(80, 80, 80), 2) $linePen.CustomEndCap = New-Object System.Drawing.Drawing2D.AdjustableArrowCap(6, 6) $shadowBrush = New-Object System.Drawing.SolidBrush([System.Drawing.Color]::FromArgb(28, 0, 0, 0)) $center = New-Object System.Drawing.StringFormat $center.Alignment = [System.Drawing.StringAlignment]::Center $center.LineAlignment = [System.Drawing.StringAlignment]::Center function Get-RoundedPath { param([int] $X, [int] $Y, [int] $W, [int] $H, [int] $R) $path = New-Object System.Drawing.Drawing2D.GraphicsPath $path.AddArc($X, $Y, $R, $R, 180, 90) $path.AddArc(($X + $W - $R), $Y, $R, $R, 270, 90) $path.AddArc(($X + $W - $R), ($Y + $H - $R), $R, $R, 0, 90) $path.AddArc($X, ($Y + $H - $R), $R, $R, 90, 90) $path.CloseFigure() return $path } function Draw-Node { param( [int] $X, [int] $Y, [int] $W, [int] $H, [string] $Text, [System.Drawing.Brush] $Fill, [System.Drawing.Pen] $Stroke, [bool] $Rounded = $true ) if ($Rounded) { $shadow = Get-RoundedPath ($X + 4) ($Y + 4) $W $H 18 $path = Get-RoundedPath $X $Y $W $H 18 $graphics.FillPath($shadowBrush, $shadow) $graphics.FillPath($Fill, $path) $graphics.DrawPath($Stroke, $path) } else { $shadowPoints = @( [System.Drawing.Point]::new($X + [int]($W / 2) + 4, $Y + 4), [System.Drawing.Point]::new($X + $W + 4, $Y + [int]($H / 2) + 4), [System.Drawing.Point]::new($X + [int]($W / 2) + 4, $Y + $H + 4), [System.Drawing.Point]::new($X + 4, $Y + [int]($H / 2) + 4) ) $points = @( [System.Drawing.Point]::new($X + [int]($W / 2), $Y), [System.Drawing.Point]::new($X + $W, $Y + [int]($H / 2)), [System.Drawing.Point]::new($X + [int]($W / 2), $Y + $H), [System.Drawing.Point]::new($X, $Y + [int]($H / 2)) ) $graphics.FillPolygon($shadowBrush, $shadowPoints) $graphics.FillPolygon($Fill, $points) $graphics.DrawPolygon($Stroke, $points) } $rect = [System.Drawing.RectangleF]::new(($X + 16), ($Y + 10), ($W - 32), ($H - 20)) $graphics.DrawString($Text, $font, $textBrush, $rect, $center) } function Draw-Line { param([int[]] $Points, [string] $Label = '') for ($i = 0; $i -lt $Points.Length - 4; $i += 2) { $plainPen = New-Object System.Drawing.Pen([System.Drawing.Color]::FromArgb(80, 80, 80), 2) $graphics.DrawLine($plainPen, $Points[$i], $Points[$i + 1], $Points[$i + 2], $Points[$i + 3]) $plainPen.Dispose() } $last = $Points.Length - 4 $graphics.DrawLine($linePen, $Points[$last], $Points[$last + 1], $Points[$last + 2], $Points[$last + 3]) if ($Label) { $mx = [int](($Points[0] + $Points[2]) / 2) $my = [int](($Points[1] + $Points[3]) / 2) $labelRect = [System.Drawing.RectangleF]::new(($mx - 55), ($my - 18), 110, 30) $graphics.FillRectangle([System.Drawing.Brushes]::White, $labelRect) $graphics.DrawString($Label, $smallFont, $textBrush, $labelRect, $center) } } $graphics.DrawString('Flowchart Sistem User', $titleFont, $textBrush, [System.Drawing.RectangleF]::new(0, 35, $width, 60), $center) Draw-Node 600 130 300 70 'Mulai' $endFill $endStroke Draw-Node 600 250 300 75 'User membuka website' $boxFill $boxStroke Draw-Node 560 380 380 120 'Sudah login?' $decisionFill $decisionStroke $false Draw-Node 170 565 300 75 'Login / Register' $boxFill $boxStroke Draw-Node 600 565 300 75 'Lihat katalog mobil' $boxFill $boxStroke Draw-Node 600 705 300 75 'Cari rekomendasi / lihat detail' $boxFill $boxStroke Draw-Node 560 840 380 120 'Ingin membeli mobil?' $decisionFill $decisionStroke $false Draw-Node 1025 865 310 75 'Hubungi admin / selesai' $endFill $endStroke Draw-Node 600 1015 300 75 'Buat transaksi pending' $boxFill $boxStroke Draw-Node 600 1155 300 75 'Upload bukti pembayaran' $boxFill $boxStroke Draw-Node 560 1290 380 120 'Bukti valid dan tepat waktu?' $decisionFill $decisionStroke $false Draw-Node 170 1485 300 75 'Transaksi dibatalkan' $cancelFill $cancelStroke Draw-Node 600 1485 300 75 'Menunggu konfirmasi admin' $boxFill $boxStroke Draw-Node 600 1630 300 70 'Selesai' $endFill $endStroke Draw-Line @(750,200,750,250) Draw-Line @(750,325,750,380) Draw-Line @(560,440,405,440,405,565) 'belum' Draw-Line @(750,500,750,565) 'ya' Draw-Line @(470,603,600,603) Draw-Line @(750,640,750,705) Draw-Line @(750,780,750,840) Draw-Line @(940,900,1025,900) 'tidak' Draw-Line @(750,960,750,1015) 'ya' Draw-Line @(750,1090,750,1155) Draw-Line @(750,1230,750,1290) Draw-Line @(560,1350,405,1350,405,1485) 'tidak' Draw-Line @(750,1410,750,1485) 'ya' Draw-Line @(750,1560,750,1630) $bitmap.Save($output, [System.Drawing.Imaging.ImageFormat]::Jpeg) $graphics.Dispose() $bitmap.Dispose() Get-Item $output | Select-Object FullName, Length