Skip to content

Instantly share code, notes, and snippets.

@bantya
Forked from ttscoff/barchart.rb
Created January 2, 2022 10:40
Show Gist options
  • Save bantya/d6b3390a41c29a79890a4df3452114a0 to your computer and use it in GitHub Desktop.
Save bantya/d6b3390a41c29a79890a4df3452114a0 to your computer and use it in GitHub Desktop.

Revisions

  1. @ttscoff ttscoff revised this gist Nov 12, 2013. 1 changed file with 1 addition and 0 deletions.
    1 change: 1 addition & 0 deletions barchart.rb
    Original file line number Diff line number Diff line change
    @@ -1,5 +1,6 @@
    #!/usr/bin/env ruby
    # encoding: utf-8
    # Brett Terpstra 2013, WTF license <http://www.wtfpl.net/txt/copying/>

    # Outputs a vertical bar chart from date-based JSON data
    # Requires the JSON rubygem: `[sudo] gem install json`
  2. @ttscoff ttscoff created this gist Nov 12, 2013.
    313 changes: 313 additions & 0 deletions barchart.rb
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,313 @@
    #!/usr/bin/env ruby
    # encoding: utf-8

    # Outputs a vertical bar chart from date-based JSON data
    # Requires the JSON rubygem: `[sudo] gem install json`
    require 'date'
    require 'open-uri'
    require 'rubygems'
    require 'json'

    # Data source URL (sample output at the end of script)
    data_url = "http://api.feedpress.it/feeds/..."
    # Parent container key for data object
    main_container = 'stats'
    # Repeated key for date/stats objects
    date_container = 'day'
    # keys for amounts to collect
    total_containers = ['greader','other','direct']

    # How many columns to output
    columns = 30
    # Total height will be determined by min and max valudes
    # scaled to max_rows
    max_rows = 15

    # If "test" is passed as an argument, load test data from end of script
    if ARGV[0] == "test" || !data_url || data_url.strip == ""
    input = DATA.read
    columns = 30
    max_rows = 18
    main_container = 'stats'
    date_container = 'day'
    total_containers = ['greader','other','direct']
    else
    # Otherwise, read data from the data url
    input = open(URI.parse(data_url)).read
    end

    json = JSON.parse(input)

    # Create two arrays, one for dates and one for totals
    dates = []
    totals = []
    # Step through data objects to populate both arrays sequentially
    json[main_container].each { |day|
    dates.push(Time.at(day[date_container]).to_datetime.strftime('%m/%d'))
    total = 0
    for item in total_containers
    total += day[item].to_i
    end

    totals.push(total)
    }

    # Find the highest and lowest values to determine bar heights
    max = totals.sort[-1]
    min = totals.sort[0]

    # Trim data arrays down to the maximum number of columns
    # defined above
    dates = dates.reverse[0..columns]
    totals = totals.reverse[0..columns]

    # Determine number or rows to generate
    topline = max_rows
    div = max / topline
    bottomline = min/div

    # Output each row. If the total for the column is greater
    # than or equal to the scaled row counter, output a chunk
    # of the bar
    topline.times do
    totals.each { |num|
    if num / div > topline
    print "◼ "
    else
    print " "
    end
    }
    if topline + (max_rows/10).round == bottomline
    puts
    break
    else
    topline -= 1
    puts
    end
    end

    # Calculate average across all totals
    avg = totals.inject(0.0) { |sum, el| sum + el } / totals.size

    # Output a legend with today, peak and average
    puts "#{dates[0]} - #{dates[-1]} ⇒Today: #{totals[-1]} | Peak: #{max} | Average: #{avg.round}"
    puts

    # Sample data for testing
    __END__

    {
    "stats": [
    {
    "day": 1382914800,
    "greader": 10195,
    "other": 4409,
    "direct": 879,
    "newsletter": 0
    },
    {
    "day": 1382824800,
    "greader": 10174,
    "other": 4327,
    "direct": 843,
    "newsletter": 0
    },
    {
    "day": 1382738400,
    "greader": 10172,
    "other": 4173,
    "direct": 861,
    "newsletter": 0
    },
    {
    "day": 1382652000,
    "greader": 10182,
    "other": 4195,
    "direct": 853,
    "newsletter": 0
    },
    {
    "day": 1382565600,
    "greader": 10163,
    "other": 4207,
    "direct": 851,
    "newsletter": 0
    },
    {
    "day": 1382479200,
    "greader": 10135,
    "other": 4206,
    "direct": 839,
    "newsletter": 0
    },
    {
    "day": 1382392800,
    "greader": 8196,
    "other": 4437,
    "direct": 850,
    "newsletter": 0
    },
    {
    "day": 1382306400,
    "greader": 8181,
    "other": 4482,
    "direct": 819,
    "newsletter": 0
    },
    {
    "day": 1382220000,
    "greader": 9968,
    "other": 4413,
    "direct": 858,
    "newsletter": 0
    },
    {
    "day": 1382133600,
    "greader": 9972,
    "other": 4413,
    "direct": 859,
    "newsletter": 0
    },
    {
    "day": 1382047200,
    "greader": 10050,
    "other": 4375,
    "direct": 842,
    "newsletter": 0
    },
    {
    "day": 1381960800,
    "greader": 10056,
    "other": 4310,
    "direct": 821,
    "newsletter": 0
    },
    {
    "day": 1381874400,
    "greader": 10048,
    "other": 4153,
    "direct": 773,
    "newsletter": 0
    },
    {
    "day": 1381788000,
    "greader": 10052,
    "other": 4108,
    "direct": 733,
    "newsletter": 0
    },
    {
    "day": 1381701600,
    "greader": 10055,
    "other": 4228,
    "direct": 701,
    "newsletter": 0
    },
    {
    "day": 1381615200,
    "greader": 10062,
    "other": 4371,
    "direct": 650,
    "newsletter": 0
    },
    {
    "day": 1381528800,
    "greader": 10079,
    "other": 4474,
    "direct": 623,
    "newsletter": 0
    },
    {
    "day": 1381442400,
    "greader": 10112,
    "other": 4590,
    "direct": 584,
    "newsletter": 0
    },
    {
    "day": 1381356000,
    "greader": 10245,
    "other": 4789,
    "direct": 571,
    "newsletter": 0
    },
    {
    "day": 1381269600,
    "greader": 10150,
    "other": 5101,
    "direct": 585,
    "newsletter": 0
    },
    {
    "day": 1381183200,
    "greader": 10155,
    "other": 5255,
    "direct": 583,
    "newsletter": 0
    },
    {
    "day": 1381096800,
    "greader": 10172,
    "other": 5266,
    "direct": 554,
    "newsletter": 0
    },
    {
    "day": 1381010400,
    "greader": 10201,
    "other": 5247,
    "direct": 585,
    "newsletter": 0
    },
    {
    "day": 1380924000,
    "greader": 10232,
    "other": 5285,
    "direct": 582,
    "newsletter": 0
    },
    {
    "day": 1380837600,
    "greader": 10235,
    "other": 5349,
    "direct": 570,
    "newsletter": 0
    },
    {
    "day": 1380751200,
    "greader": 10267,
    "other": 5288,
    "direct": 556,
    "newsletter": 0
    },
    {
    "day": 1380664800,
    "greader": 10308,
    "other": 5042,
    "direct": 540,
    "newsletter": 0
    },
    {
    "day": 1380578400,
    "greader": 10328,
    "other": 4828,
    "direct": 551,
    "newsletter": 0
    },
    {
    "day": 1380492000,
    "greader": 10364,
    "other": 4630,
    "direct": 574,
    "newsletter": 0
    },
    {
    "day": 1380405600,
    "greader": 10350,
    "other": 4479,
    "direct": 597,
    "newsletter": 0
    }
    ],
    "code": 1
    }