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: ***) 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") (*** Output ***) (* ``` │ │ 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│■■■■■■■■■■■■■■■■■■■■■■■ │ │ ``` *)