working on it ...

Filters

Explore Public Snippets

Sort by

Found 1 snippet

    public by WFreelandEcon  1190  1  4  0

    Command line bar chart from JSON data (for GeekTool, et al)

    Command line bar chart from JSON data (for GeekTool, et al): barchart.rb
    #!/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`
    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
    }
    
    
    

    List Complete ( 1 snippet total )

    Cannot find what you were looking for?
    Ask the Snip2Code Community

    • Public Snippets
    • Channels Snippets