' Bar Graph — draws ASCII horizontal and vertical bar charts
#COMPILE EXE
#DIM ALL

FUNCTION PBMAIN() AS LONG
    LOCAL data(100) AS LONG
    LOCAL labels(100) AS STRING
    LOCAL n AS LONG
    LOCAL i AS LONG
    LOCAL j AS LONG
    LOCAL maxVal AS LONG
    LOCAL barLen AS LONG
    LOCAL maxBarLen AS LONG
    LOCAL lineStr AS STRING
    LOCAL elemStr AS STRING
    LOCAL labelStr AS STRING
    LOCAL tempStr AS STRING
    n = 12
    maxBarLen = 40
    PRINT "============================================"
    PRINT "          ASCII BAR CHART"
    PRINT "============================================"
    PRINT ""
    FOR i = 0 TO n - 1
        data(i) = ((i * 17 + 5) MOD 30) + 3
    NEXT i
    maxVal = data(0)
    FOR i = 1 TO n - 1
        IF data(i) > maxVal THEN
            maxVal = data(i)
        END IF
    NEXT i
    IF maxVal < 1 THEN
        maxVal = 1
    END IF
    PRINT "Horizontal bar chart:"
    PRINT ""
    FOR i = 0 TO n - 1
        barLen = data(i) * maxBarLen / maxVal
        lineStr = " Item " + STR$(i)
        DO WHILE LEN(lineStr) < 10
            lineStr = lineStr + " "
        LOOP
        lineStr = lineStr + "|"
        FOR j = 1 TO barLen
            lineStr = lineStr + "#"
        NEXT j
        lineStr = lineStr + " " + STR$(data(i))
        PRINT lineStr
    NEXT i
    PRINT ""
    PRINT "============================================"
    PRINT "     VERTICAL BAR CHART"
    PRINT "============================================"
    PRINT ""
    n = 20
    FOR i = 0 TO n - 1
        data(i) = ((i * 11 + 3) MOD 20) + 2
    NEXT i
    maxVal = data(0)
    FOR i = 1 TO n - 1
        IF data(i) > maxVal THEN
            maxVal = data(i)
        END IF
    NEXT i
    IF maxVal < 1 THEN
        maxVal = 1
    END IF
    maxBarLen = 14
    PRINT "Vertical bar chart:"
    PRINT ""
    FOR j = maxBarLen TO 1 STEP -1
        lineStr = ""
        FOR i = 0 TO n - 1
            barLen = data(i) * maxBarLen / maxVal
            IF barLen >= j THEN
                lineStr = lineStr + "## "
            ELSE
                lineStr = lineStr + "   "
            END IF
        NEXT i
        PRINT lineStr
    NEXT j
    lineStr = ""
    FOR i = 0 TO n - 1
        elemStr = STR$(data(i))
        DO WHILE LEN(elemStr) < 3
            elemStr = " " + elemStr
        LOOP
        lineStr = lineStr + elemStr + " "
    NEXT i
    PRINT lineStr
    PRINT ""
    PRINT "============================================"
    PRINT "     GROUPED BAR CHART"
    PRINT "============================================"
    PRINT ""
    LOCAL groupA(20) AS LONG
    LOCAL groupB(20) AS LONG
    n = 8
    FOR i = 0 TO n - 1
        groupA(i) = ((i * 7 + 3) MOD 15) + 5
        groupB(i) = ((i * 11 + 5) MOD 12) + 3
    NEXT i
    maxVal = groupA(0)
    FOR i = 1 TO n - 1
        IF groupA(i) > maxVal THEN
            maxVal = groupA(i)
        END IF
        IF groupB(i) > maxVal THEN
            maxVal = groupB(i)
        END IF
    NEXT i
    IF maxVal < 1 THEN
        maxVal = 1
    END IF
    maxBarLen = 10
    PRINT "Grouped bars (A=# B=@):"
    PRINT ""
    FOR j = maxBarLen TO 1 STEP -1
        lineStr = ""
        FOR i = 0 TO n - 1
            barLen = groupA(i) * maxBarLen / maxVal
            IF barLen >= j THEN
                lineStr = lineStr + "#"
            ELSE
                lineStr = lineStr + " "
            END IF
            barLen = groupB(i) * maxBarLen / maxVal
            IF barLen >= j THEN
                lineStr = lineStr + "@ "
            ELSE
                lineStr = lineStr + "  "
            END IF
        NEXT i
        PRINT " " + lineStr
    NEXT j
    lineStr = ""
    FOR i = 0 TO n - 1
        elemStr = STR$(groupA(i))
        DO WHILE LEN(elemStr) < 2
            elemStr = " " + elemStr
        LOOP
        lineStr = lineStr + elemStr + " "
    NEXT i
    PRINT " A:" + lineStr
    lineStr = ""
    FOR i = 0 TO n - 1
        elemStr = STR$(groupB(i))
        DO WHILE LEN(elemStr) < 2
            elemStr = " " + elemStr
        LOOP
        lineStr = lineStr + elemStr + " "
    NEXT i
    PRINT " B:" + lineStr
    PRINT ""
    PRINT "============================================"
    PRINT "     STACKED BAR CHART"
    PRINT "============================================"
    PRINT ""
    n = 6
    FOR i = 0 TO n - 1
        groupA(i) = ((i * 5 + 2) MOD 10) + 2
        groupB(i) = ((i * 7 + 3) MOD 8) + 1
    NEXT i
    maxVal = groupA(0) + groupB(0)
    FOR i = 1 TO n - 1
        IF groupA(i) + groupB(i) > maxVal THEN
            maxVal = groupA(i) + groupB(i)
        END IF
    NEXT i
    IF maxVal < 1 THEN
        maxVal = 1
    END IF
    maxBarLen = 15
    PRINT "Stacked bars (A=below B=above):"
    PRINT ""
    FOR j = maxBarLen TO 1 STEP -1
        lineStr = ""
        FOR i = 0 TO n - 1
            totalVal = groupA(i) + groupB(i)
            barLenA = groupA(i) * maxBarLen / maxVal
            barLenTotal = totalVal * maxBarLen / maxVal
            IF barLenTotal >= j THEN
                IF j <= barLenA THEN
                    lineStr = lineStr + "# "
                ELSE
                    lineStr = lineStr + "@ "
                END IF
            ELSE
                lineStr = lineStr + "  "
            END IF
        NEXT i
        PRINT " " + lineStr
    NEXT j
    lineStr = ""
    FOR i = 0 TO n - 1
        elemStr = STR$(groupA(i) + groupB(i))
        DO WHILE LEN(elemStr) < 2
            elemStr = " " + elemStr
        LOOP
        lineStr = lineStr + elemStr + " "
    NEXT i
    PRINT " T:" + lineStr
    PRINT ""
    PRINT "============================================"
    PRINT "     PERCENTAGE BAR CHART"
    PRINT "============================================"
    PRINT ""
    n = 10
    FOR i = 0 TO n - 1
        data(i) = ((i * 13 + 7) MOD 20) + 5
    NEXT i
    maxVal = data(0)
    FOR i = 1 TO n - 1
        IF data(i) > maxVal THEN
            maxVal = data(i)
        END IF
    NEXT i
    IF maxVal < 1 THEN
        maxVal = 1
    END IF
    PRINT "Percentage bars (100% = " + STR$(maxBarLen) + " chars):"
    PRINT ""
    FOR i = 0 TO n - 1
        barLen = data(i) * maxBarLen / maxVal
        lineStr = " " + STR$(data(i))
        DO WHILE LEN(lineStr) < 5
            lineStr = " " + lineStr
        LOOP
        lineStr = lineStr + " ["
        FOR j = 1 TO barLen
            lineStr = lineStr + "="
        NEXT j
        FOR j = barLen + 1 TO maxBarLen
            lineStr = lineStr + "."
        NEXT j
        lineStr = lineStr + "] "
        elemStr = STR$(data(i) * 100 / maxVal)
        DO WHILE LEN(elemStr) < 3
            elemStr = " " + elemStr
        LOOP
        lineStr = lineStr + elemStr + "%"
        PRINT lineStr
    NEXT i
    PRINT ""
    PRINT "Bar chart demonstration complete"
    FUNCTION = 0
END FUNCTION
