Permalink
Browse files

initial import

  • Loading branch information...
0 parents commit 2c69b42df108f4e241096e879da42bed876680a1 Christian�Kellermann committed Jun 6, 2010
Showing with 6,489 additions and 0 deletions.
  1. +1 −0 .couchapprc
  2. BIN _attachments/img/ajax-loader.gif
  3. +371 −0 _attachments/index.html
  4. +1,012 −0 _attachments/script/jquery-ui-1.8.2.custom.min.js
  5. +102 −0 _attachments/script/jquery.enumerable.js
  6. +36 −0 _attachments/script/jquery.tools.min.js
  7. +233 −0 _attachments/script/jquery.tufte-graph.js
  8. +1,690 −0 _attachments/script/raphael.js
  9. +14 −0 _attachments/style/main.css
  10. +7 −0 _attachments/style/main.css~
  11. +41 −0 _attachments/style/tufte-graph.css
  12. BIN _attachments/style/ui-lightness/images/ui-bg_diagonals-thick_18_b81900_40x40.png
  13. BIN _attachments/style/ui-lightness/images/ui-bg_diagonals-thick_20_666666_40x40.png
  14. BIN _attachments/style/ui-lightness/images/ui-bg_flat_10_000000_40x100.png
  15. BIN _attachments/style/ui-lightness/images/ui-bg_glass_100_f6f6f6_1x400.png
  16. BIN _attachments/style/ui-lightness/images/ui-bg_glass_100_fdf5ce_1x400.png
  17. BIN _attachments/style/ui-lightness/images/ui-bg_glass_65_ffffff_1x400.png
  18. BIN _attachments/style/ui-lightness/images/ui-bg_gloss-wave_35_f6a828_500x100.png
  19. BIN _attachments/style/ui-lightness/images/ui-bg_highlight-soft_100_eeeeee_1x100.png
  20. BIN _attachments/style/ui-lightness/images/ui-bg_highlight-soft_75_ffe45c_1x100.png
  21. BIN _attachments/style/ui-lightness/images/ui-icons_222222_256x240.png
  22. BIN _attachments/style/ui-lightness/images/ui-icons_228ef1_256x240.png
  23. BIN _attachments/style/ui-lightness/images/ui-icons_ef8c08_256x240.png
  24. BIN _attachments/style/ui-lightness/images/ui-icons_ffd27a_256x240.png
  25. BIN _attachments/style/ui-lightness/images/ui-icons_ffffff_256x240.png
  26. +406 −0 _attachments/style/ui-lightness/jquery-ui-1.7.2.custom.css
  27. +1 −0 language.json
  28. +2 −0 lib/helpers/math.js
  29. +32 −0 lib/helpers/template.js
  30. +13 −0 shows/edit.js
  31. +53 −0 templates/edit.html
  32. +44 −0 validate_doc_update.js
  33. +3 −0 vendor/couchapp/README.md
  34. +19 −0 vendor/couchapp/_attachments/jquery-1.3.2.min.js
  35. +202 −0 vendor/couchapp/_attachments/jquery.couchapp.js
  36. +1 −0 vendor/couchapp/couchapp.js
  37. +23 −0 vendor/couchapp/date.js
  38. +67 −0 vendor/couchapp/path.js
  39. +33 −0 vendor/couchapp/template.js
  40. +3 −0 vendor/couchapp/vendor/README.md
  41. +53 −0 vendor/couchapp/vendor/_attachments/docs.css
  42. +32 −0 vendor/couchapp/vendor/_attachments/docs.html
  43. +8 −0 vendor/couchapp/vendor/_attachments/docs.js
  44. +228 −0 vendor/couchapp/vendor/_attachments/jquery.couch.app.js
  45. +54 −0 vendor/couchapp/vendor/_attachments/jquery.couch.app.util.js
  46. +308 −0 vendor/couchapp/vendor/_attachments/jquery.evently.js
  47. +282 −0 vendor/couchapp/vendor/_attachments/jquery.mustache.js
  48. +134 −0 vendor/couchapp/vendor/_attachments/jquery.pathbinder.js
  49. +39 −0 vendor/couchapp/vendor/commonjs/atom.js
  50. +9 −0 vendor/couchapp/vendor/commonjs/list.js
  51. +79 −0 vendor/couchapp/vendor/commonjs/path.js
  52. +8 −0 vendor/couchapp/vendor/commonjs/redirect.js
  53. +187 −0 vendor/couchapp/vendor/docs/account.md
  54. +34 −0 vendor/couchapp/vendor/docs/couchapp.md
  55. +11 −0 vendor/couchapp/vendor/docs/docs.md
  56. +159 −0 vendor/couchapp/vendor/docs/evently.md
  57. +52 −0 vendor/couchapp/vendor/docs/pathbinder.md
  58. +3 −0 vendor/couchapp/vendor/docs/profile.md
  59. +15 −0 vendor/couchapp/vendor/evently/account/_init.js
  60. +3 −0 vendor/couchapp/vendor/evently/account/adminParty.js
  61. +10 −0 vendor/couchapp/vendor/evently/account/doLogin.js
  62. +8 −0 vendor/couchapp/vendor/evently/account/doLogout.js
  63. +10 −0 vendor/couchapp/vendor/evently/account/doSignup.js
  64. +4 −0 vendor/couchapp/vendor/evently/account/loggedIn/after.js
  65. +7 −0 vendor/couchapp/vendor/evently/account/loggedIn/data.js
  66. +4 −0 vendor/couchapp/vendor/evently/account/loggedIn/mustache.html
  67. +3 −0 vendor/couchapp/vendor/evently/account/loggedIn/selectors.json
  68. +1 −0 vendor/couchapp/vendor/evently/account/loggedOut/mustache.html
  69. +4 −0 vendor/couchapp/vendor/evently/account/loggedOut/selectors.json
  70. +3 −0 vendor/couchapp/vendor/evently/account/loginForm/after.js
  71. +6 −0 vendor/couchapp/vendor/evently/account/loginForm/mustache.html
  72. +1 −0 vendor/couchapp/vendor/evently/account/loginForm/selectors/a[href=#signup].json
  73. +6 −0 vendor/couchapp/vendor/evently/account/loginForm/selectors/form/submit.js
  74. +3 −0 vendor/couchapp/vendor/evently/account/signupForm/after.js
  75. +6 −0 vendor/couchapp/vendor/evently/account/signupForm/mustache.html
  76. +1 −0 vendor/couchapp/vendor/evently/account/signupForm/selectors/a[href=#login].json
  77. +6 −0 vendor/couchapp/vendor/evently/account/signupForm/selectors/form/submit.js
  78. +11 −0 vendor/couchapp/vendor/evently/docs/index/data.js
  79. +5 −0 vendor/couchapp/vendor/evently/docs/index/mustache.html
  80. +1 −0 vendor/couchapp/vendor/evently/docs/index/path.txt
  81. +15 −0 vendor/couchapp/vendor/evently/docs/topic/after.js
  82. +8 −0 vendor/couchapp/vendor/evently/docs/topic/data.js
  83. +19 −0 vendor/couchapp/vendor/evently/docs/topic/edit/_init/fun.js
  84. +9 −0 vendor/couchapp/vendor/evently/docs/topic/edit/_init/selectors/a.edit/click.js
  85. +22 −0 vendor/couchapp/vendor/evently/docs/topic/edit/_init/selectors/a.run/click.js
  86. +1 −0 vendor/couchapp/vendor/evently/docs/topic/mustache.html
  87. +1 −0 vendor/couchapp/vendor/evently/docs/topic/path.txt
  88. +22 −0 vendor/couchapp/vendor/evently/profile/loggedIn.js
  89. +3 −0 vendor/couchapp/vendor/evently/profile/loggedOut/after.js
  90. +1 −0 vendor/couchapp/vendor/evently/profile/loggedOut/mustache.html
  91. +3 −0 vendor/couchapp/vendor/evently/profile/noProfile/data.js
  92. +11 −0 vendor/couchapp/vendor/evently/profile/noProfile/mustache.html
  93. +37 −0 vendor/couchapp/vendor/evently/profile/noProfile/selectors/form/submit.js
  94. +3 −0 vendor/couchapp/vendor/evently/profile/profileReady/after.js
  95. +7 −0 vendor/couchapp/vendor/evently/profile/profileReady/data.js
  96. +8 −0 vendor/couchapp/vendor/evently/profile/profileReady/mustache.html
  97. +4 −0 vendor/couchapp/vendor/metadata.json
  98. +67 −0 vendor/couchapp/vendor/path.js
  99. +8 −0 views/ausgaben/map.js
  100. +7 −0 views/available_categories/map.js
  101. +1 −0 views/available_categories/reduce.js
  102. +7 −0 views/einnahmen/map.js
  103. +6 −0 views/expenses_by_category/map.js
  104. +1 −0 views/expenses_by_category/reduce.js
  105. +10 −0 views/saldo/map.js
  106. +1 −0 views/saldo/reduce.js
@@ -0,0 +1 @@
+{}
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

Large diffs are not rendered by default.

Oops, something went wrong.

Large diffs are not rendered by default.

Oops, something went wrong.
@@ -0,0 +1,102 @@
+(function ( $ ) {
+ var methods = {
+ // $([1,2,3]).collect(function() { return this * this }) // => [1, 4, 9]
+ collect: function(enumerable, callback) {
+ var result = [];
+ $.each(enumerable, function(index) {
+ result.push(callback.call(this, index));
+ });
+ return result;
+ },
+
+ // $([1,2,3]).inject(0, function(a) { return a + this }) // => 6
+ inject: function(enumerable, initialValue, callback) {
+ var accumulator = initialValue;
+
+ $.each(enumerable, function (index) {
+ accumulator = callback.call(this, accumulator, index);
+ });
+ return accumulator;
+ },
+
+ // $([1,2,3]).select(function() { return this % 2 == 1 }) // => [1, 3]
+ select: function(enumerable, callback) {
+ var result = [];
+ $.each(enumerable, function(index) {
+ if (callback.call(this, index))
+ result.push(this);
+ });
+ return result;
+ },
+
+ // $([1,2,3]).reject(function() { return this % 2 == 1 }) // => [2]
+ reject: function(enumerable, callback) {
+ return $.select(enumerable, negate(callback));
+ },
+
+ // $([1,2]).any(function() { return this == 1 }) // => true
+ any: function(enumerable, callback) {
+ return $.inject(enumerable, false, function(accumulator, index) {
+ return accumulator || callback.call(this, index);
+ });
+ },
+
+ // $([1,1]).any(function() { return this == 1 }) // => true
+ all: function(enumerable, callback) {
+ return $.inject(enumerable, true, function(accumulator, index) {
+ return accumulator && callback.call(this, index);
+ });
+ },
+
+ // $([1,2,3]).sum() // => 6
+ sum: function(enumerable) {
+ return $.inject(enumerable, 0, function(accumulator) {
+ return accumulator + this;
+ });
+ }
+ };
+
+ var staticFunctions = {};
+ var iteratorFunctions = {};
+ $.each( methods, function(name, f){
+ staticFunctions[name] = makeStaticFunction(f);
+ iteratorFunctions[name] = makeIteratorFunction(staticFunctions[name]);
+ });
+ $.extend(staticFunctions);
+ $.fn.extend(iteratorFunctions);
+
+ // Private methods
+ function makeStaticFunction(f) {
+ return function() {
+ if (arguments.length > 1) // The first argument is the enumerable
+ validateCallback(arguments[arguments.length - 1]);
+
+ return f.apply(this, arguments);
+ }
+ }
+
+ function makeIteratorFunction(staticFunction) {
+ return function() {
+ // arguments isn't a real array, concat doesn't work
+ // unless you explicitly convert it
+ function toArray() {
+ var result = []
+ for (var i = 0; i < this.length; i++)
+ result.push(this[i])
+ return(result)
+ }
+ return staticFunction.apply(this, [this].concat(toArray.apply(arguments)))
+ }
+ }
+
+ function validateCallback(callback) {
+ if (!jQuery.isFunction(callback))
+ throw("callback needs to be a function, it was: " + callback);
+ }
+
+ function negate(f) {
+ return function() {
+ return !f.apply(this, arguments)
+ }
+ }
+})( jQuery );

Large diffs are not rendered by default.

Oops, something went wrong.
@@ -0,0 +1,233 @@
+(function($) {
+ //
+ // Public interface
+ //
+
+ // The main event - creates a pretty graph. See index.html for documentation.
+ $.fn.tufteBar = function(options) {
+ var defaultCopy = $.extend(true, {}, $.fn.tufteBar.defaults);
+ var options = $.extend(true, defaultCopy, options);
+
+ return this.each(function () {
+ draw(makePlot($(this), options), options);
+ });
+ }
+
+ // Defaults are exposed publically so you can reuse bits that you find
+ // handy (the colors, for instance)
+ $.fn.tufteBar.defaults = {
+ barWidth: 0.8,
+ colors: ['#07093D', '#0C0F66', '#476FB2'],
+ color: function(index, stackedIndex, options) { return options.colors[stackedIndex % options.colors.length]; },
+ barLabel: function(index, stackedIndex) {
+ return $.tufteBar.formatNumber(totalValue(this[0]));
+ },
+ axisLabel: function(index, stackedIndex) { return index; },
+ legend: {
+ color: function(index, options) { return options.colors[index % options.colors.length]; },
+ label: function(index) { return this; }
+ }
+ }
+
+ $.tufteBar = {
+ // Add thousands separators to a number to make it look pretty.
+ // 1000 -> 1,000
+ formatNumber: function(nStr) {
+ // http://www.mredkj.com/javascript/nfbasic.html
+ nStr += '';
+ x = nStr.split('.');
+ x1 = x[0];
+ x2 = x.length > 1 ? ',' + x[1] : '';
+ var rgx = /(\d+)(\d{3})/;
+ while (rgx.test(x1)) {
+ x1 = x1.replace(rgx, '$1' + '.' + '$2');
+ }
+ return x1 + x2;
+ }
+ }
+
+ //
+ // Private functions
+ //
+
+ // This function should be applied to any option used from the options hash.
+ // It allows options to be provided as either static values or functions which are
+ // evaluated each time they are used
+ function resolveOption(option, element) {
+ // the @arguments@ special variable looks like an array, but really isn't, so we
+ // need to transform it in order to perform array function on it
+ function toArray() {
+ var result = []
+ for (var i = 0; i < this.length; i++)
+ result.push(this[i])
+ return(result)
+ }
+
+ return $.isFunction(option) ? option.apply(element, toArray.apply(arguments).slice(2, arguments.length)) : option;
+ }
+
+ // Returns the total value of a bar, for labeling or plotting. Y values can either be
+ // a single number (for a normal graph), or an array of numbers (for a stacked graph)
+ function totalValue(value) {
+ if (value instanceof Array)
+ return $.sum(value);
+ else
+ return value;
+ }
+
+ function draw(plot, options) {
+ var ctx = plot.ctx;
+ var axis = plot.axis;
+
+ // Iterate over each bar
+ $(options.data).each(function (i) {
+ var element = this;
+ var x = i + 0.5;
+ var all_y = null;
+
+ if (element[0] instanceof Array) {
+ // This is a stacked bar, so the data is all good to go
+ all_y = element[0];
+ } else {
+ // This is a normal bar, wrap in an array to make it a stacked bar with one data point
+ all_y = [element[0]];
+ }
+
+ if ($(all_y).any(function() { return isNaN(+this); })) {
+ throw("Non-numeric value provided for y: " + element[0]);
+ }
+
+ var lastY = 0;
+
+ pixel_scaling_function = function(axis) {
+ var scale = axis.pixelLength / (axis.max - axis.min);
+ return function (value) {
+ return (value - axis.min) * scale;
+ }
+ }
+
+ // These functions transform a value from plot coordinates to pixel coordinates
+ var t = {}
+ t.W = pixel_scaling_function(axis.x);
+ t.H = pixel_scaling_function(axis.y);
+ t.X = t.W;
+ // Y needs to invert the result since 0 in plot coords is bottom left, but 0 in pixel coords is top left
+ t.Y = function(y) { return axis.y.pixelLength - t.H(y) };
+
+ // Iterate over each data point for this bar and render a rectangle for each
+ $(all_y).each(function(stackedIndex) {
+ var optionResolver = function(option) { // Curry resolveOption for convenience
+ return resolveOption(option, element, i, stackedIndex, options);
+ }
+
+ var y = all_y[stackedIndex];
+ var halfBar = optionResolver(options.barWidth) / 2;
+ var left = x - halfBar,
+ width = halfBar * 2,
+ top = lastY + y,
+ height = y;
+
+ // Need to both fill and stroke the rect to make sure the whole area is covered
+ // You get nasty artifacts otherwise
+ var color = optionResolver(options.color);
+ var coords = [t.X(left), t.Y(top), t.W(width), t.H(height)];
+
+ ctx.rect(coords[0], coords[1], coords[2], coords[3]).attr({stroke: color, fill: color});
+
+ lastY = lastY + y;
+ });
+
+ addLabel = function(klass, text, pos) {
+ html = '<div style="position:absolute;" class="label ' + klass + '">' + text + "</div>";
+ $(html).css(pos).appendTo( plot.target );
+ }
+
+ var optionResolver = function(option) { // Curry resolveOption for convenience
+ return resolveOption(option, element, i, options);
+ }
+ addLabel('bar-label', optionResolver(options.barLabel), {
+ left: t.X(x - 0.5),
+ bottom: t.H(lastY),
+ width: t.W(1)
+ });
+ addLabel('axis-label', optionResolver(options.axisLabel), {
+ left: t.X(x - 0.5),
+ top: t.Y(0),
+ width: t.W(1)
+ });
+ });
+ addLegend(plot, options);
+ }
+
+ // If legend data has been provided, transform it into an
+ // absolutely positioned table placed at the top right of the graph
+ function addLegend(plot, options) {
+ if (options.legend.data) {
+ elements = $(options.legend.data).collect(function(i) {
+ var optionResolver = (function (element) {
+ return function(option) { // Curry resolveOption for convenience
+ return resolveOption(option, element, i, options);
+ }
+ })(this);
+
+ var colorBox = '<div class="color-box" style="background-color:' + optionResolver(options.legend.color) + '"></div>';
+ var label = optionResolver(options.legend.label);
+
+ return "<tr><td>" + colorBox + "</td><td>" + label + "</td></tr>";
+ });
+
+ $('<table class="legend">' + elements.reverse().join("") + '</table>').css({
+ position: 'absolute',
+ top: '0px',
+ left: plot.width + 'px'
+ }).appendTo( plot.target );
+ }
+ }
+
+ // Calculates the range of the graph by looking for the
+ // maximum y-value
+ function makeAxis(options) {
+ var axis = {
+ x: {},
+ y: {}
+ }
+
+ axis.x.min = 0
+ axis.x.max = options.data.length;
+ axis.y.min = 0;
+ axis.y.max = 0;
+
+ $(options.data).each(function() {
+ var y = totalValue(this[0]);
+ if( y < axis.y.min ) throw("Negative values not supported");
+ if( y > axis.y.max ) axis.y.max = y;
+ });
+
+ if( axis.x.max <= 0) throw("You must have at least one data point");
+ if( axis.y.max <= 0) throw("You must have at least one y-value greater than 0");
+
+ return axis;
+ }
+
+ // Creates the canvas object to draw on, and set up the axes
+ function makePlot(target, options) {
+ var plot = {};
+ plot.target = target;
+ plot.width = target.width();
+ plot.height = target.height();
+ target.html( '' ).css( 'position', 'relative' );
+
+ if( plot.width <= 0 || plot.height <= 0 ) {
+ throw "Invalid dimensions for plot, width = " + plot.width + ", height = " + plot.height;
+ }
+
+ // the canvas
+ plot.ctx = Raphael(target[0].id, plot.width, plot.height);
+
+ plot.axis = makeAxis(options);
+ plot.axis.x.pixelLength = plot.width;
+ plot.axis.y.pixelLength = plot.height;
+
+ return plot;
+ }
+} )( jQuery );
Oops, something went wrong.

0 comments on commit 2c69b42

Please sign in to comment.