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
  • Usage example:
1: 
2: 
3: 
4: 
5: 
6: 
7: 
8: 
9: 
open FSharp.Data

let data = WorldBankData.GetDataContext()
let idc = data.Countries.Italy.Indicators.``Agricultural land (% of land area)``
let yearsWithValues = Seq.zip idc.Years idc.Values

yearsWithValues
|> Seq.map (fun (x, y) -> string x, y)
|> drawBarChartWith (Width 50) (sprintf "%.2f")
 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: 
34: 
35: 
36: 
37: 
38: 
39: 
40: 
41: 
42: 
43: 
44: 
45: 
46: 
47: 
48: 
49: 
50: 
51: 
52: 
53: 
54: 
55: 
56: 
57: 
58: 
59: 
60: 
61: 
(*
```
    │     │
1961│70.32│■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
1962│70.22│■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
1963│69.74│■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
1964│69.57│■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
1965│69.50│■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
1966│69.38│■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
1967│69.29│■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
1968│69.21│■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
1969│68.77│■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
1970│68.61│■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
1971│60.01│■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
1972│59.53│■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
1973│59.44│■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
1974│59.51│■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
1975│59.56│■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
1976│59.60│■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
1977│59.50│■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
1978│59.80│■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
1979│59.87│■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
1980│59.71│■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
1981│59.67│■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
1982│59.62│■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
1983│58.69│■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
1984│58.63│■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
1985│58.12│■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
1986│57.94│■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
1987│57.84│■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
1988│57.25│■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
1989│57.29│■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
1990│57.26│■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
1991│54.59│■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
1992│54.33│■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
1993│54.10│■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
1994│53.39│■■■■■■■■■■■■■■■■■■■■■■■■■■■■
1995│52.13│■■■■■■■■■■■■■■■■■■■■■■■■■■■■
1996│52.19│■■■■■■■■■■■■■■■■■■■■■■■■■■■■
1997│52.17│■■■■■■■■■■■■■■■■■■■■■■■■■■■■
1998│52.65│■■■■■■■■■■■■■■■■■■■■■■■■■■■■
1999│53.72│■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
2000│53.17│■■■■■■■■■■■■■■■■■■■■■■■■■■■■
2001│52.71│■■■■■■■■■■■■■■■■■■■■■■■■■■■■
2002│51.93│■■■■■■■■■■■■■■■■■■■■■■■■■■■■
2003│50.68│■■■■■■■■■■■■■■■■■■■■■■■■■■■
2004│50.60│■■■■■■■■■■■■■■■■■■■■■■■■■■■
2005│50.10│■■■■■■■■■■■■■■■■■■■■■■■■■■■
2006│48.29│■■■■■■■■■■■■■■■■■■■■■■■■■■
2007│48.15│■■■■■■■■■■■■■■■■■■■■■■■■■■
2008│49.15│■■■■■■■■■■■■■■■■■■■■■■■■■■
2009│47.54│■■■■■■■■■■■■■■■■■■■■■■■■■
2010│48.71│■■■■■■■■■■■■■■■■■■■■■■■■■■
2011│47.10│■■■■■■■■■■■■■■■■■■■■■■■■■
2012│46.68│■■■■■■■■■■■■■■■■■■■■■■■■■
2013│46.34│■■■■■■■■■■■■■■■■■■■■■■■■■
2014│44.75│■■■■■■■■■■■■■■■■■■■■■■■■
2015│44.01│■■■■■■■■■■■■■■■■■■■■■■■
    │     │
```
*)
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
Multiple items
namespace FSharp

--------------------
namespace Microsoft.FSharp
Multiple items
namespace FSharp.Data

--------------------
namespace Microsoft.FSharp.Data
val data : WorldBankData.ServiceTypes.WorldBankDataService

Full name: Script.data
type WorldBankData =
  static member GetDataContext : unit -> WorldBankDataService
  nested type ServiceTypes

Full name: FSharp.Data.WorldBankData


<summary>Typed representation of WorldBank data. See http://www.worldbank.org for terms and conditions.</summary>
WorldBankData.GetDataContext() : WorldBankData.ServiceTypes.WorldBankDataService
val idc : Runtime.WorldBank.Indicator

Full name: Script.idc
property WorldBankData.ServiceTypes.WorldBankDataService.Countries: WorldBankData.ServiceTypes.Countries
property WorldBankData.ServiceTypes.Countries.Italy: WorldBankData.ServiceTypes.Country


The data for country 'Italy'
property WorldBankData.ServiceTypes.Country.Indicators: WorldBankData.ServiceTypes.Indicators


<summary>The indicators for the country</summary>
val yearsWithValues : seq<int * float>

Full name: Script.yearsWithValues
val zip : source1:seq<'T1> -> source2:seq<'T2> -> seq<'T1 * 'T2>

Full name: Microsoft.FSharp.Collections.Seq.zip
property Runtime.WorldBank.Indicator.Years: System.Collections.Generic.ICollection<int>
property Runtime.WorldBank.Indicator.Values: System.Collections.Generic.ICollection<float>
val x : int
val y : float
val sprintf : format:Printf.StringFormat<'T> -> 'T

Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.sprintf

More information

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