1 people like it.

Simple console bar chart

Creates a simple bar chart from a list consisting of a tuple (title:string * value:'a).

 1: 
 2: 
 3: 
 4: 
 5: 
 6: 
 7: 
 8: 
 9: 
10: 
11: 
12: 
13: 
14: 
15: 
16: 
17: 
18: 
19: 
20: 
21: 
22: 
23: 
24: 
25: 
26: 
27: 
28: 
29: 
30: 
31: 
32: 
33: 
type Width =
    /// Use the full width of the console
    | FullWidth
    /// The width of the chart including the printed title and value
    | Width of int
    member self.Value =
        match self with
        | FullWidth -> System.Console.WindowWidth
        | Width value -> value

// based on: https://www.daniweb.com/programming/software-development/code/238532/very-simple-console-barchart
let inline drawBarChartWith (width: Width) valueFormatter (xs: (string * 'a) seq) =
    let xs = xs |> Seq.cache
    // calculate maximum of the data
    let maxTitleWidth = xs |> Seq.map (fst >> String.length) |> Seq.max
    let maxValue = xs |> Seq.map snd |> Seq.max
    let maxValueWidth = xs |> Seq.map (snd >> valueFormatter >> String.length) |> Seq.max
    // use full width of console
    let factor = float (width.Value - maxTitleWidth - maxValueWidth - 3)
    // draw chart
    let emptyTitle = String.replicate maxTitleWidth " "
    let emptyValue = String.replicate maxValueWidth " "
    printfn "%s%s│" emptyTitle emptyValue
    for (title, value) in xs do
        let paddedTitle = (string title).PadLeft(maxTitleWidth)
        let width = int (float value / float maxValue * factor)
        let value = (valueFormatter value).PadLeft(maxValueWidth)
        let segments = String.replicate width "■"
        printfn "%s%s%s" paddedTitle value segments
    printfn "%s%s│" emptyTitle emptyValue

let inline drawBarChart xs =
    drawBarChartWith FullWidth string xs
union case Width.FullWidth: Width


 Use the full width of the console
Multiple items
union case Width.Width: int -> Width


 The width of the chart including the printed title and value


--------------------
type Width =
  | FullWidth
  | Width of int
  member Value : int

Full name: Script.Width
Multiple items
val int : value:'T -> int (requires member op_Explicit)

Full name: Microsoft.FSharp.Core.Operators.int

--------------------
type int = int32

Full name: Microsoft.FSharp.Core.int

--------------------
type int<'Measure> = int

Full name: Microsoft.FSharp.Core.int<_>
val self : Width
member Width.Value : int

Full name: Script.Width.Value
namespace System
type Console =
  static member BackgroundColor : ConsoleColor with get, set
  static member Beep : unit -> unit + 1 overload
  static member BufferHeight : int with get, set
  static member BufferWidth : int with get, set
  static member CapsLock : bool
  static member Clear : unit -> unit
  static member CursorLeft : int with get, set
  static member CursorSize : int with get, set
  static member CursorTop : int with get, set
  static member CursorVisible : bool with get, set
  ...

Full name: System.Console
property System.Console.WindowWidth: int
val value : int
val drawBarChartWith : width:Width -> valueFormatter:('a -> string) -> xs:seq<string * 'a> -> unit (requires comparison and member op_Explicit)

Full name: Script.drawBarChartWith
val width : Width
val valueFormatter : ('a -> string) (requires comparison and member op_Explicit)
val xs : seq<string * 'a> (requires comparison and member op_Explicit)
Multiple items
val string : value:'T -> string

Full name: Microsoft.FSharp.Core.Operators.string

--------------------
type string = System.String

Full name: Microsoft.FSharp.Core.string
Multiple items
val seq : sequence:seq<'T> -> seq<'T>

Full name: Microsoft.FSharp.Core.Operators.seq

--------------------
type seq<'T> = System.Collections.Generic.IEnumerable<'T>

Full name: Microsoft.FSharp.Collections.seq<_>
module Seq

from Microsoft.FSharp.Collections
val cache : source:seq<'T> -> seq<'T>

Full name: Microsoft.FSharp.Collections.Seq.cache
val maxTitleWidth : int
val map : mapping:('T -> 'U) -> source:seq<'T> -> seq<'U>

Full name: Microsoft.FSharp.Collections.Seq.map
val fst : tuple:('T1 * 'T2) -> 'T1

Full name: Microsoft.FSharp.Core.Operators.fst
module String

from Microsoft.FSharp.Core
val length : str:string -> int

Full name: Microsoft.FSharp.Core.String.length
val max : source:seq<'T> -> 'T (requires comparison)

Full name: Microsoft.FSharp.Collections.Seq.max
val maxValue : 'a (requires comparison and member op_Explicit)
val snd : tuple:('T1 * 'T2) -> 'T2

Full name: Microsoft.FSharp.Core.Operators.snd
val maxValueWidth : int
val factor : float
Multiple items
val float : value:'T -> float (requires member op_Explicit)

Full name: Microsoft.FSharp.Core.Operators.float

--------------------
type float = System.Double

Full name: Microsoft.FSharp.Core.float

--------------------
type float<'Measure> = float

Full name: Microsoft.FSharp.Core.float<_>
property Width.Value: int
val emptyTitle : string
val replicate : count:int -> str:string -> string

Full name: Microsoft.FSharp.Core.String.replicate
val emptyValue : string
val printfn : format:Printf.TextWriterFormat<'T> -> 'T

Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.printfn
val title : string
val value : 'a (requires comparison and member op_Explicit)
val paddedTitle : string
val width : int
val value : string
val segments : string
val drawBarChart : xs:seq<string * 'a> -> unit (requires comparison and member op_Explicit)

Full name: Script.drawBarChart

More information

Link:http://fssnip.net/7UB
Posted:5 years ago
Author:Tobias Burger
Tags: #console , #chart , #barchart