by
31 2
0
1
80
0
Specified
Created
Modified Jun 23, 2017

Published on:

No tags for this snippet yet.
Languagecsharp
LanguageRuby
SourceGitHub

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

Command line bar chart from JSON data (for GeekTool, et al): 
barchart.rb
Copy Embed Code
<iframe id="embedFrame" style="width:600px; height:300px;"
src="https://www.snip2code.com/Embed/2008002/Command-line-bar-chart-from-JSON-data-(f?startLine=0"></iframe>
Click on the embed code to copy it into your clipboard Width Height
Leave empty to retrieve all the content Start End
#!/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 }
If you want to be updated about similar snippets, Sign in and follow our Channels

blog comments powered by Disqus