RedNegativesTable.vb
''
'' This code is part of Document Solutions for Imaging demos.
'' Copyright (c) MESCIUS inc. All rights reserved.
''
Imports System.Drawing
Imports System.IO
Imports GrapeCity.Documents.Drawing
Imports GrapeCity.Documents.Text
Imports GrapeCity.Documents.Imaging
Imports GrapeCity.Documents.Layout
Imports GCTEXT = GrapeCity.Documents.Text
Imports GCDRAW = GrapeCity.Documents.Drawing

'' This example shows how to draw a simple table containing
'' some numeric data, with negative values displayed in red,
'' and with differently shaded odd and even rows,
'' using the GrapeCity.Documents.Drawing.TableRenderer and related classes.
Public Class RedNegativesTable
    Public Function GenerateImage(
        ByVal pixelSize As Size,
        ByVal dpi As Single,
        ByVal opaque As Boolean,
        Optional ByVal sampleParams As String() = Nothing) As GcBitmap

        Dim bmp = New GcBitmap(pixelSize.Width, pixelSize.Height, opaque, dpi, dpi)
        Using g = bmp.CreateGraphics(Color.White)
            DrawTable(g, pixelSize.Width, pixelSize.Height)
        End Using
        Return bmp
    End Function

    Private Class ItemLine
        Public ReadOnly Property Text As String
        Public ReadOnly Property Sales As Double
        Public ReadOnly Property MarginNumber As Double
        Public ReadOnly Property MarginPercent As Double
        Public ReadOnly Property TotalCustomers As Integer

        Public Sub New(text As String, sales As Double, marginNumber As Double, marginPercent As Double, totalCustomers As Integer)
            Me.Text = text
            Me.Sales = sales
            Me.MarginNumber = marginNumber
            Me.MarginPercent = marginPercent
            Me.TotalCustomers = totalCustomers
        End Sub
    End Class

    Private Shared Sub DrawTable(g As GcGraphics, pageWidth As Integer, pageHeight As Integer)
        Dim items = New ItemLine() {
            New ItemLine("Washers & Dryers", 1580, 196.82, 12.46, 247),
            New ItemLine("Projectors & Screens", 973, 211.26, 21.72, 382),
            New ItemLine("Refrigerators", 953, -350.57, -36.77, 331),
            New ItemLine("Laptops", 668, 181.17, 27.11, 301),
            New ItemLine("Coffee Machines", 476, -11.15, -2.34, 251),
            New ItemLine("Lamps", 471, 340.31, 72.28, 548),
            New ItemLine("Water Heaters", 443, 94.59, 21.34, 152),
            New ItemLine("Monitors", 424, -0.77, -0.18, 327),
            New ItemLine("Microwaves", 319, 14.30, 4.48, 375),
            New ItemLine("Desktops", 266, 23.22, 8.72, 184),
            New ItemLine("Air Conditioners", 253, 137.82, 54.54, 216),
            New ItemLine("Printers & Scanners", 219, 0.59, 0.27, 379),
            New ItemLine("Computers Accessories", 128, -18.23, -14.27, 654),
            New ItemLine("Fans", 83, -38.64, -46.35, 287)
        }

        Dim host = New LayoutHost()
        Dim view = host.CreateView(pageWidth, pageHeight)

        Dim rt = view.CreateRect()
        rt.AnchorTopLeft(Nothing, 72, 72)

        Dim ta = New TableRenderer(g,
            rt, FixedTableSides.TopLeft,
            rowCount:=items.Length + 1,
            columnCount:=5,
            gridLineColor:=Color.Transparent,
            gridLineWidth:=0)

        Dim columns = ta.ColumnRects
        columns(0).SetWidth(270)
        columns(1).SetWidth(150)
        columns(2).SetWidth(150)
        columns(3).SetWidth(150)
        columns(4).SetWidth(150)

        Dim fmt = New TextFormat() With
            {
                .Font = GCTEXT.Font.FromFile(Path.Combine("Resources", "Fonts", "FreeMono.ttf")),
                .ForeColor = Color.FromArgb(38, 38, 38),
                .FontSize = 20,
                .FontSizeInGraphicUnits = True
            }
        Dim fmtSmall = New TextFormat(fmt) With
            {
                .FontSize = 14
            }

        Dim csCaption = New CellStyle() With
            {
                .TextAlignment = TextAlignment.Trailing,
                .ParagraphAlignment = ParagraphAlignment.Center,
                .TextFormat = fmt,
                .PaddingBottom = 10,
                .PaddingRight = 4
            }
        ta.AddCell(New CellStyle(csCaption) With
            {
                .CustomDraw = Sub(gr As GcGraphics, tcell As TableCell)
                                  Dim y As Single = tcell.Height * 0.5F
                                  Dim x As Single = 10
                                  Dim arrowPen = New GCDRAW.Pen(Color.DimGray, 1)
                                  gr.DrawLine(New PointF(x, y - 7), New PointF(x, y + 7), arrowPen)
                                  gr.DrawLine(New PointF(x - 3, y + 3), New PointF(x, y + 7), arrowPen)
                                  gr.DrawLine(New PointF(x + 3, y + 3), New PointF(x, y + 7), arrowPen)
                              End Sub,
                .CreateTextLayout = Function(gr As GcGraphics, style As CellStyle, dat As Object)
                                         Dim tl = gr.CreateTextLayout()
                                         tl.AppendLine("Sales", fmt)
                                         tl.Append("in Thousands", fmtSmall)
                                         Return tl
                                     End Function
            }, 0, 1, CObj(Nothing))
        ta.AddCell(New CellStyle(csCaption) With
            {
                .CreateTextLayout = Function(gr As GcGraphics, style As CellStyle, dat As Object)
                                         Dim tl = gr.CreateTextLayout()
                                         tl.AppendLine("Margin", fmt)
                                         tl.Append("in Thousands", fmtSmall)
                                         Return tl
                                     End Function
            }, 0, 2, CObj(Nothing))
        ta.AddCell(csCaption, 0, 3, "Margin %")
        ta.AddCell(csCaption, 0, 4, "Total" & vbLf & "Customers")

        Dim csName = New CellStyle() With
            {
                .TextFormat = fmt,
                .PaddingTopBottom = 5,
                .PaddingLeft = 4
            }
        Dim csNum = New CellStyle() With
            {
                .TextFormat = fmt,
                .TextAlignment = TextAlignment.Trailing,
                .PaddingTopBottom = 5,
                .PaddingRight = 4
            }
        Dim csNumNegative = New CellStyle(csNum) With
            {
                .TextFormat = New TextFormat(fmt) With
                    {
                        .ForeColor = Color.Red
                    }
            }
        Dim csBand = New CellStyle() With
            {
                .FillColor = Color.FromArgb(244, 241, 250),
                .Background = True
            }

        Dim ci = New System.Globalization.CultureInfo("en-US")

        For i = 0 To items.Length - 1
            Dim item = items(i)
            Dim rowIndex = i + 1

            If (i And 1) <> 0 Then
                ta.AddCell(csBand, rowIndex, 0, 1, 5)
            End If
            ta.AddCell(csName, rowIndex, 0, item.Text)
            ta.AddCell(csNum, rowIndex, 1, item.Sales.ToString("c0", ci))
            Dim v = item.MarginNumber
            ta.AddCell(If(v >= 0.0, csNum, csNumNegative), rowIndex, 2, v.ToString("n2"))
            v = item.MarginPercent
            ta.AddCell(If(v >= 0.0, csNum, csNumNegative), rowIndex, 3, v.ToString("n2"))
            ta.AddCell(csNum, rowIndex, 4, item.TotalCustomers.ToString("n0"))
        Next

        ta.SetVerticalGridLineWidth(1, 2)
        ta.SetHorizontalGridLineWidth(1, 2)

        Dim pen = New GCDRAW.Pen(Color.FromArgb(159, 146, 213), 2) With
            {
                .DashStyle = DashStyle.Solid,
                .LineCap = PenLineCap.Round
            }
        ta.AddCell(New CellStyle() With
            {
                .Background = True,
                .Borders = FrameBorders.LeftBorder Or FrameBorders.TopBorder,
                .Pen = pen,
                .LinePaddingLeft = -2,
                .LinePaddingTop = -2
            }, 1, 1, items.Length, 4)

        ta.Render()
    End Sub
End Class