Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Proof of concept charting working again, with balances displayed on t…

…he left
  • Loading branch information...
commit aac9f146b8cbd3fd51ddd37c1e9dfc292f39409c 1 parent 6a7b256
@konklone konklone authored
View
16 Rakefile
@@ -4,6 +4,9 @@ task :migrate => :environment do
ActiveRecord::Migrator.migrate 'migrations', (ENV['version'] ? ENV['version'].to_i : nil)
end
+def all_models
+ [User, Account, Day]
+end
namespace :fixtures do
@@ -26,18 +29,11 @@ task :environment do
require 'ohnomymoney'
end
-def all_models
- [User, Account, Day]
-end
-
-def fixture_dir
- "fixtures"
-end
def restore_fixture(model)
model.delete_all
- YAML::load_file("#{fixture_dir}/#{model.table_name}.yml").each do |row|
+ YAML::load_file("fixtures/#{model.table_name}.yml").each do |row|
record = model.new
row.keys.each do |field|
record[field] = row[field] if row[field]
@@ -57,8 +53,8 @@ def dump_fixture(model)
records << element
end
- FileUtils.mkdir_p fixture_dir
- File.open("#{fixture_dir}/#{model.table_name}.yml", "w") do |file|
+ FileUtils.mkdir_p "fixtures"
+ File.open("fixtures/#{model.table_name}.yml", "w") do |file|
YAML.dump data, file
end
View
78 charting.rb
@@ -0,0 +1,78 @@
+require 'google_chart'
+
+helpers do
+
+ def chart_for(days)
+ oldest = days.first
+ newest = days[days.size-1]
+ balances = days.map {|day| day.balance}
+
+ min = balances.min
+ max = balances.max
+ disparity = max - min
+ y = (disparity * 1.66).to_i
+ buffer = (y - disparity) / 2
+
+ y_min = round(min - buffer)
+ y_max = round(max + buffer)
+ y = y_max - y_min
+ y_step = round(y / 10.0, 2)
+
+ x_step = days.size / 7
+ x_step = 1 if x_step < 1
+ x_days = []
+ days.each_with_index {|b, i| x_days << b if i % x_step == 0}
+ x_days[0] = days[0]
+ x_days[-1] = days[-1]
+
+ y_labels = (0..10).map {|i| format_balance(y_min + (y_step * i))}
+ x_labels = x_days.map {|day| format_date day.date_of}
+
+ label = newest.balance > 0 ? 'Money' : 'Debt'
+ data = balances.map {|balance| (balance - y_min).to_f}
+ color = newest.balance > 0 ? '008800' : 'cc0000'
+
+ chart = GoogleChart::LineChart.new '857x350'
+ chart.data_encoding = :text
+ chart.max_value y
+ chart.data label, data, color
+ chart.axis :x, :labels => x_labels
+ chart.axis :y, :labels => y_labels
+ chart.axis :right, :labels => y_labels
+
+ p chart.to_url(:chdlp => 'b')
+ chart.to_url :chdlp => 'b'
+ end
+
+ def round(n, level = 3)
+ (n - (n % (10**level))).to_i
+ end
+
+ def double_encode(text)
+ text.gsub("&", "&amp;")
+ end
+
+ def format_balance(balance)
+ number = balance.to_f / 100
+ parts = ("%01.2f" % number).split('.')
+ answer = '$' + number_with_delimiter(parts[0]) + '.' + parts[1].to_s
+ if number > 0
+ answer = '+' + answer
+ elsif number < 0
+ answer = '-' + answer
+ end
+ answer
+ end
+
+ def number_with_delimiter(number)
+ number = number.to_i.abs
+ parts = number.to_s.split('.')
+ parts[0].gsub! /(\d)(?=(\d\d\d)+(?!\d))/, "\\1,"
+ parts.join '.'
+ end
+
+ def format_date(date)
+ date.strftime("%B ") + date.strftime("%d").gsub(/^0/, "")
+ end
+
+end
View
4 fixtures/accounts.yml
@@ -20,12 +20,12 @@
- name: Credit Card
created_at: 2010-02-15 01:55:20 -05:00
updated_at: 2010-02-15 02:23:49 -05:00
- account_type: debt
+ account_type: debts
id: 4
user_id: 1
- name: Student Loans
created_at: 2010-02-15 01:57:24 -05:00
updated_at: 2010-02-15 02:23:55 -05:00
- account_type: debt
+ account_type: debts
id: 5
user_id: 1
View
9 models.rb
@@ -6,7 +6,7 @@ class Day < ActiveRecord::Base
end
class Account < ActiveRecord::Base
- TYPES = %w( worth assets debt )
+ TYPES = %w( worth assets debts )
belongs_to :user
has_many :days
@@ -15,10 +15,17 @@ class Account < ActiveRecord::Base
validates_presence_of :user_id
validates_inclusion_of :account_type, :in => TYPES
+ named_scope :worth, :conditions => {:account_type => 'worth'}
+ named_scope :assets, :conditions => {:account_type => 'assets'}
+ named_scope :debts, :conditions => {:account_type => 'debts'}
def needs_name
account_type != 'worth'
end
+
+ def balance
+ days.count > 0 ? days.first(:order => "created_at DESC").balance : 0
+ end
end
class User < ActiveRecord::Base
View
10 ohnomymoney.rb
@@ -4,6 +4,9 @@
require 'sinatra'
require 'environment'
+require 'erb'
+require 'charting'
+
# For now, have the root URL act as if we visited the userpage of the first user
before do
request.path_info = "/#{User.first.handle}" if request.path_info == '/'
@@ -12,5 +15,10 @@
get "/:handle" do
halt 404 unless user = User.find_by_handle(params[:handle])
- user.accounts.all.map(&:name).join("<br/>\n")
+ erb :index, :locals => {
+ :user => user,
+ :worth => user.accounts.worth.first,
+ :assets => user.accounts.assets.all,
+ :debts => user.accounts.debts.all
+ }
end
View
29 views/index.erb
@@ -0,0 +1,29 @@
+<!doctype html>
+<html>
+<head>
+ <title><%= user.name %>'s Money</title>
+</head>
+<body>
+
+ <h1><%= user.name %>'s Money</h1>
+
+ <div class="sidebar">
+ <div class="account worth">
+ <h2>Net Worth</h2>
+ <span><%= worth.balance %></span>
+ </div>
+
+ <% (assets + debts).each do |account| %>
+ <div class="account <%= account.account_type %>">
+ <h2><%= account.name %></h2>
+ <span><%= account.balance %></span>
+ </div>
+ <% end %>
+ </div>
+
+ <div class="main">
+ <img src="<%= double_encode chart_for(worth.days.all(:limit => 10)) %>" />
+ </div>
+
+</body>
+</html>
Please sign in to comment.
Something went wrong with that request. Please try again.