Permalink
Browse files

add graph to homepage

  • Loading branch information...
1 parent 3759d94 commit 94dfa5b436173e76d20dee9ba5a19f53592f7bc9 @leafo leafo committed Jun 6, 2014
Showing with 312 additions and 72 deletions.
  1. +2 −1 app.moon
  2. +5 −0 static/lib/d3.min.js
  3. +4 −0 static/lib/jquery-2.1.1.min.js
  4. +171 −1 static/main.coffee
  5. +2 −2 static/md/home.md
  6. +105 −63 static/style.scss
  7. +14 −2 views/index.moon
  8. +1 −2 views/layout.moon
  9. +8 −1 widgets/base.moon
View
@@ -25,6 +25,7 @@ import
Rocks
Users
Versions
+ DownloadsDaily
from require "models"
import
@@ -158,9 +159,9 @@ class MoonRocks extends lapis.Application
@popular_modules = Modules\select "order by downloads desc limit 5"
Users\include_in @popular_modules, "user_id"
+ @downloads_daily = DownloadsDaily\fetch true, 30
render: true
-
[modules: "/modules"]: =>
@title = "All Modules"
paginated_modules @, Modules\paginated "order by name asc", {
View

Large diffs are not rendered by default.

Oops, something went wrong.

Large diffs are not rendered by default.

Oops, something went wrong.
View
@@ -1 +1,171 @@
-window.Moon ||= {}
+window.M ||= {}
+
+class M.Index
+ constructor: (el, downloads_daily) ->
+ @el = $ el
+ new M.Grapher "#downloads_graph", downloads_daily, {
+ label: "Views"
+ num_days: 30
+ x_ticks: 7
+ }
+
+format_number = (num) ->
+ if num > 10000
+ "#{Math.floor(num / 1000)}k"
+ else if num > 1000
+ "#{Math.floor(num / 100) / 10}k"
+ else
+ "#{num}"
+
+# (C) 2020 itch.io systems
+class M.Grapher
+ margin_left: 40
+ margin_bottom: 30
+ margin_right: 5
+ margin_top: 20
+
+ axis_spacing: 8
+
+ default_opts: {
+ label: "Count"
+ min_y: 10
+ x_ticks: 10
+ }
+
+ constructor: (el, @data, opts) ->
+ @el = $ el
+ @opts = $.extend {}, @default_opts, opts
+ @draw()
+
+ draw: ->
+ @w = @el.width()
+ @h = @el.height()
+ @time_format = d3.time.format "%Y-%m-%d"
+
+ @svg = d3.select(@el[0]).append("svg")
+ .attr("class", "chart")
+ .attr("width", @w)
+ .attr("height", @h)
+
+ data = @format_data()
+ x = @_x_scale = @x_scale data
+ y = @_y_scale = @y_scale data
+
+ # y guides
+ y_guides = @svg.append("g")
+ .attr("class", "y_guides")
+
+ y_guides.selectAll("line").data(y.ticks @y_ticks()).enter()
+ .append("line")
+ .attr("x1", x.range()[0])
+ .attr("y1", y)
+ .attr("x2", x.range()[1])
+ .attr("y2", y)
+
+ # x guides
+ @svg.append("g")
+ .attr("class", "x_guides")
+ .selectAll("line").data(x.ticks @x_ticks()).enter()
+ .append("line")
+ .attr("x1", x)
+ .attr("y1", y.range()[0])
+ .attr("x2", x)
+ .attr("y2", y.range()[1])
+
+ # area
+ area = d3.svg.area()
+ .x(@get_x_scaled)
+ .y1(@get_y_scaled)
+ .y0(@h - @margin_bottom)
+
+ @svg.append("g")
+ .attr("class", "graph")
+ .append("path")
+ .attr("d", area data)
+
+ # y axis
+ y_axis = d3.svg.axis().scale(y)
+ .orient("left")
+ .tickFormat(@format_y_axis)
+ .ticks(@y_ticks())
+
+ @svg.append("g")
+ .attr("transform", "translate(#{x.range()[0] - @axis_spacing}, 0)")
+ .attr("class", "y_axis axis")
+ .call y_axis
+
+ # y axis
+ x_axis = d3.svg.axis().scale(x)
+ .orient("bottom")
+ .ticks(@x_ticks())
+
+ @svg.append("g")
+ .attr("transform", "translate(0, #{y.range()[0] + @axis_spacing})")
+ .attr("class", "x_axis axis")
+ .call x_axis
+
+ @draw_dots data
+
+ draw_dots: (data) ->
+ # popups
+ dots = @svg.append("g")
+ .attr("class", "dots")
+ .selectAll("g").data(data)
+ .enter()
+
+ # dots
+ dots
+ .append("circle")
+ .attr("cx", @get_x_scaled)
+ .attr("cy", @get_y_scaled)
+ .attr("r", 4)
+
+ popup_label: (d) ->
+ "#{@opts.label}: #{d.count}"
+
+ get_x: (d) => @time_format.parse d.date
+ get_y: (d) => d.count
+
+ get_x_scaled: => @_x_scale @get_x arguments...
+ get_y_scaled: => @_y_scale @get_y arguments...
+
+ format_y_axis: (num) => format_number num
+
+ x_ticks: -> @opts.x_ticks
+ y_ticks: -> Math.min 5, @opts.min_y
+
+ format_data: ->
+ today = d3.time.day new Date
+ ago = d3.time.day.offset today, -(@opts.num_days - 1)
+
+ counts_by_date = {}
+ for v in @data
+ counts_by_date[v.date] = v
+
+ counts_dense = []
+ t = ago
+ while t <= today
+ formatted = @time_format t
+ counts_dense.push counts_by_date[formatted] || {
+ count: 0
+ date: formatted
+ }
+ t = d3.time.day.offset t, 1
+
+ counts_dense
+
+ x_scale: (data) ->
+ today = d3.time.day new Date
+ ago = d3.time.day.offset today, -(@opts.num_days - 1)
+
+ d3.time.scale()
+ .domain([ago, today])
+ .rangeRound([@margin_left + 10, @w - @margin_right])
+
+ y_scale: (data) ->
+ max = d3.max data, @get_y
+
+ d3.scale.linear()
+ .domain([0, Math.max Math.floor(max*1.3) || 0, @opts.min_y])
+ .rangeRound([@h - @margin_bottom, @margin_top])
+
View
@@ -1,4 +1,4 @@
-### Get Started
+## Get Started
$ luarocks install --server=http://rocks.moonscript.org moonrocks
@@ -12,7 +12,7 @@ Install a module:
Read more on the [About Page][1].
-### What Is This Site?
+## What Is This Site?
**MoonRocks** is place where anyone can upload and host Lua modules.
View
@@ -356,17 +356,6 @@ pre {
}
}
-.about_page {
- p {
- line-height: 24px;
- }
- ul {
- padding-left: 20px;
- line-height: 20px;
- }
-}
-
-
.table {
background: white;
border: 1px solid desaturate(darken($back_color, 30%), 50%);
@@ -411,6 +400,111 @@ img.avatar {
word-wrap: break-word;
}
+
+// syntax:
+
+/* builtins */
+.nb {
+ color: #FFA122;
+}
+
+/* strings */
+.s, .s1, .s2, .se {
+ color: #ffe898;
+}
+
+/* proper names, self */
+.nc, .vc, .bp {
+ color: #98d9ff;
+}
+
+/* true, false, nil */
+.kc {
+ color: #acfff0;
+}
+
+/* function lit, braces, parens */
+.nf, .kt {
+ color: #9fff98;
+}
+
+/* operators */
+.o {
+ font-weight: bold;
+ color: #ff9898;
+}
+
+.nv {
+ color: #ff9898;
+}
+
+/* keywords */
+.k, .kd {
+ font-weight: bold;
+ color: #cb98ff;
+}
+
+.c1, .c2 {
+ color: #929292;
+}
+
+.m, .mi, .mf, .mh {
+ color: #9495ff;
+}
+
+.index_page {
+ .graph_container {
+ height: 180px;
+ margin-bottom: 40px;
+ margin-left: -40px;
+
+ .axis {
+ path, line {
+ fill: none;
+ stroke: darken($border_color, 10%);
+ shape-rendering: crispEdges;
+ }
+
+ text {
+ fill: $sub_color;
+ }
+ }
+
+ .x_guides, .y_guides {
+ stroke: lighten($border_color, 5%);
+ fill: none;
+ shape-rendering: crispEdges;
+ }
+
+ .graph {
+ path {
+ fill: rgba($header_color, 0.3);
+ stroke: rgba($header_color, 0.8);
+ }
+ }
+
+ .dots {
+ circle {
+ fill: lighten($back_color, 5%);
+ stroke: $header_color;
+ }
+ }
+ }
+}
+
+.about_page {
+ p {
+ line-height: 24px;
+ }
+ ul {
+ padding-left: 20px;
+ line-height: 20px;
+ }
+}
+
+
+
+
.module_page {
.module_header {
margin: 20px 0;
@@ -484,58 +578,6 @@ img.avatar {
}
-// syntax:
-
-/* builtins */
-.nb {
- color: #FFA122;
-}
-
-/* strings */
-.s, .s1, .s2, .se {
- color: #ffe898;
-}
-
-/* proper names, self */
-.nc, .vc, .bp {
- color: #98d9ff;
-}
-
-/* true, false, nil */
-.kc {
- color: #acfff0;
-}
-
-/* function lit, braces, parens */
-.nf, .kt {
- color: #9fff98;
-}
-
-/* operators */
-.o {
- font-weight: bold;
- color: #ff9898;
-}
-
-.nv {
- color: #ff9898;
-}
-
-/* keywords */
-.k, .kd {
- font-weight: bold;
- color: #cb98ff;
-}
-
-.c1, .c2 {
- color: #929292;
-}
-
-.m, .mi, .mf, .mh {
- color: #9495ff;
-}
-
-
.pager {
height: 30px;
line-height: 30px;
Oops, something went wrong.

0 comments on commit 94dfa5b

Please sign in to comment.