From d3b8112928dc8371da3ddd4e95520c8efb6d587c Mon Sep 17 00:00:00 2001 From: dsc Date: Mon, 9 Apr 2012 19:07:43 -0700 Subject: [PATCH] Adds Dashboard for Reportcard. --- lib/base.co | 20 +++++++-- lib/dashboard/dashboard-model.co | 29 +++++++++++++ lib/dashboard/dashboard-view.co | 84 ++++++++++++++++++++++++++++++++++++++ lib/dashboard/index.co | 3 + lib/graph/graph-display-view.co | 19 +++++---- lib/graph/graph-model.co | 2 + lib/main-dashboard.co | 52 +++++++++++++++++++++++ lib/template/dashboard.jade | 7 +++ lib/template/graph-display.jade | 28 ++++++------ www/dashboard.jade | 12 +++++- www/modules.yaml | 7 +++- 11 files changed, 235 insertions(+), 28 deletions(-) create mode 100644 lib/dashboard/dashboard-model.co create mode 100644 lib/dashboard/dashboard-view.co create mode 100644 lib/dashboard/index.co create mode 100644 lib/main-dashboard.co create mode 100644 lib/template/dashboard.jade create mode 100644 www/css/dashboard.styl diff --git a/lib/base.co b/lib/base.co index 2ac0400..225ea6e 100644 --- a/lib/base.co +++ b/lib/base.co @@ -178,11 +178,23 @@ BaseView = exports.BaseView = Backbone.View.extend do # {{{ initialize: -> _.bindAll this, ...@__bind__ if @__bind__.length - @model.view = this - @$el.data { @model, view:this } + @setModel @model @build() - @model.on 'change', @render, this - @model.on 'destroy', @remove, this + + setModel: (model) -> + if @model + @model.off 'change', @render, this + @model.off 'destroy', @remove, this + delete @model.view + data = @$el.data() + delete data.model + delete data.view + if @model = model + @model.view = this + @$el.data { @model, view:this } + @model.on 'change', @render, this + @model.on 'destroy', @remove, this + @model toTemplateLocals: -> json = {value:v} = @model.toJSON() diff --git a/lib/dashboard/dashboard-model.co b/lib/dashboard/dashboard-model.co new file mode 100644 index 0000000..35b1d2f --- /dev/null +++ b/lib/dashboard/dashboard-model.co @@ -0,0 +1,29 @@ +{ _, op, +} = require 'kraken/util' +{ BaseView, +} = require 'kraken/base' +{ Graph, +} = require 'kraken/graph/graph-model' + + +/** + * @class + */ +Dashboard = exports.Dashboard = BaseModel.extend do # {{{ + urlRoot : '/dashboards' + graphs : [] + + + constructor: function Dashboard + BaseModel ... + + initialize: -> + @graphs = [] + BaseModel::initialize ... + + + defaults: -> + {} + + +# }}} diff --git a/lib/dashboard/dashboard-view.co b/lib/dashboard/dashboard-view.co new file mode 100644 index 0000000..470647b --- /dev/null +++ b/lib/dashboard/dashboard-view.co @@ -0,0 +1,84 @@ +Seq = require 'seq' + +{ _, op, +} = require 'kraken/util' +{ BaseView, +} = require 'kraken/base' +{ Graph, GraphList, GraphDisplayView, +} = require 'kraken/graph' +{ Dashboard, +} = require 'kraken/dashboard/dashboard-model' + + +/** + * @class + */ +DashboardView = exports.DashboardView = BaseView.extend do # {{{ + __bind__ : <[ ]> + tagName : 'section' + className : 'dashboard' + template : require 'kraken/template/dashboard' + + graph_ids : <[ + unique_visitors + pageviews + pageviews_mobile + reach + commons + articles + articles_per_day + edits + new_editors + active_editors + active_editors_target + very_active_editors + ]> + subviews : [] + graphs : null + ready : false + + + constructor: function DashboardView + @subviews = [] + @graphs = new GraphList + Backbone.View ... + + initialize: -> + @model or= new Dashboard + BaseView::initialize ... + @graphs.on 'add', @attachGraphs, this + @load() + + + load: -> + self = this + Seq(@graph_ids) + .parMap_ (next_phase, id) -> + Seq() + .seq Graph.lookup, id, Seq + .seq (graph) -> + view = new GraphDisplayView {model:graph} + view.on 'ready', @ok + self.graphs.add graph + .seq next_phase.ok + .seq_ (next) ~> + console.log "#this.ready!" + @ready = true + @attachGraphs() + @trigger 'ready', this + + attachGraphs: -> + graphs_el = @$el.find '#graphs' + for id of @graph_ids + break unless graph = @graphs.get id + continue if graph.view.isAttached + graphs_el.append graph.view.el + @subviews.push graph.view + graph.view.isAttached = true + graph.on 'ready', -> + graph.off 'ready', arguments.callee + graph.view.renderChart() + this + +# }}} + diff --git a/lib/dashboard/index.co b/lib/dashboard/index.co new file mode 100644 index 0000000..03fc595 --- /dev/null +++ b/lib/dashboard/index.co @@ -0,0 +1,3 @@ +models = require 'kraken/dashboard/dashboard-model' +views = require 'kraken/dashboard/dashboard-view' +exports import models import views diff --git a/lib/graph/graph-display-view.co b/lib/graph/graph-display-view.co index 11ac226..00f3ec2 100644 --- a/lib/graph/graph-display-view.co +++ b/lib/graph/graph-display-view.co @@ -53,7 +53,6 @@ GraphDisplayView = exports.GraphDisplayView = BaseView.extend do # {{{ for name of @__debounce__ @[name] = _.debounce @[name], DEBOUNCE_RENDER - @viewport = @$el.find '.viewport' ### Model Events @model @@ -75,6 +74,8 @@ GraphDisplayView = exports.GraphDisplayView = BaseView.extend do # {{{ # Resize chart on window resize # Note: can't debounce the method itself, as the debounce wrapper returns undefined $ root .on 'resize', _.debounce @resizeViewport, DEBOUNCE_RENDER + + _.delay (~> @onReady()), 100 if @model.ready @@ -120,21 +121,22 @@ GraphDisplayView = exports.GraphDisplayView = BaseView.extend do # {{{ return { width, height } unless @ready # Remove old style, as it confuses dygraph after options update - @viewport.attr 'style', '' + viewport = @$el.find '.viewport' + viewport.attr 'style', '' label = @$el.find '.graph-legend' if width is 'auto' - vpWidth = @viewport.innerWidth() + vpWidth = viewport.innerWidth() labelW = label.outerWidth() width = vpWidth - labelW - 10 - (vpWidth - label.position().left - labelW) width ?= modelW if height is 'auto' - height = @viewport.innerHeight() + height = viewport.innerHeight() height ?= modelH size = { width, height } - @viewport.css size - # console.log 'resizeViewport!', JSON.stringify(size), @viewport + viewport.css size + # console.log 'resizeViewport!', JSON.stringify(size), viewport # @chart.resize size if forceRedraw size @@ -143,6 +145,7 @@ GraphDisplayView = exports.GraphDisplayView = BaseView.extend do # {{{ renderChart: -> data = @model.get 'dataset' #.getData() size = @resizeViewport() + viewport = @$el.find '.viewport' # XXX: use @model.changedAttributes() to calculate what to update options = @chartOptions() #import size @@ -164,13 +167,13 @@ GraphDisplayView = exports.GraphDisplayView = BaseView.extend do # {{{ # dygraphs to reset the current option state. @chart?.destroy() @chart = new Dygraph do - @viewport.0 + viewport.0 data options # unless @chart # @chart = new Dygraph do - # @viewport.0 + # viewport.0 # data # options # else diff --git a/lib/graph/graph-model.co b/lib/graph/graph-model.co index 0e8c209..87fb3d3 100644 --- a/lib/graph/graph-model.co +++ b/lib/graph/graph-model.co @@ -323,4 +323,6 @@ Graph import do +_.bindAll Graph, 'register', 'get', 'lookup' + /* }}} */ diff --git a/lib/main-dashboard.co b/lib/main-dashboard.co new file mode 100644 index 0000000..32cabf4 --- /dev/null +++ b/lib/main-dashboard.co @@ -0,0 +1,52 @@ +Seq = require 'seq' +Backbone = require 'backbone' + +{ _, op, +} = require 'kraken/util' +{ BaseView, BaseModel, BaseList, +} = require 'kraken/base' +{ ChartType, DygraphsChartType, +} = require 'kraken/chart' +{ Graph, GraphList, GraphDisplayView, +} = require 'kraken/graph' +{ DashboardView, +} = require 'kraken/dashboard' + + + +root = this +CHART_OPTIONS_SPEC = [] +CHART_DEFAULT_OPTIONS = {} + + +# Create the Graph Scaffold +main = -> + # Set up Dygraph chart type spec + # TODO: load this on-demand + dyglib = new DygraphsChartType CHART_OPTIONS_SPEC + + # _.dump _.clone(data.options), 'data.options' + + # Instantiate model & view + dashboard = root.dashboard = new DashboardView do + graph_spec : root.CHART_OPTIONS_SPEC # FIXME: necessary? + + $ '#content .inner' .append dashboard.el + + + +# Load data files +Seq([ <[ CHART_OPTIONS_SPEC /schema/dygraph.json ]> +]) +.parEach_ (next, [key, url]) -> + jQuery.ajax do + url : url, + dataType : 'json' + success : (res) -> + root[key] = res + next.ok() + error : (err) -> console.error err +.seq -> + console.log 'All data loaded!' + jQuery main + diff --git a/lib/template/dashboard.jade b/lib/template/dashboard.jade new file mode 100644 index 0000000..3688666 --- /dev/null +++ b/lib/template/dashboard.jade @@ -0,0 +1,7 @@ +section#dashboard + .page-header + h1 Wikimedia Report Card + small February 2012 + + section#graphs + diff --git a/lib/template/graph-display.jade b/lib/template/graph-display.jade index a593597..8fb078e 100644 --- a/lib/template/graph-display.jade +++ b/lib/template/graph-display.jade @@ -1,18 +1,18 @@ include browser-helpers - var graph_id = view.id section.graph.graph-display(id=view.id) + + .graph-name-row.page-header.row-fluid + h2.graph-name #{name} + + .graph-viewport-row.row-fluid + .viewport + .graph-legend + + .graph-details-row.row-fluid + .graph-desc + != jade.filters.markdown(desc) - .graph-name-row.page-header.row-fluid - h1.graph-name #{name} - - .graph-viewport-row.row-fluid - .viewport - .graph-legend - - .graph-details-row.row-fluid - .graph-desc - != jade.filters.markdown(desc) - - //- - .graph-notes.span6 - != jade.filters.markdown(notes) + //- + .graph-notes.span6 + != jade.filters.markdown(notes) diff --git a/www/css/dashboard.styl b/www/css/dashboard.styl new file mode 100644 index 0000000..e69de29 diff --git a/www/dashboard.jade b/www/dashboard.jade index 47f7900..2cd7fc8 100644 --- a/www/dashboard.jade +++ b/www/dashboard.jade @@ -1 +1,11 @@ -include graph/edit \ No newline at end of file +extends layout + +block title + title Wikimedia Report Card - February 2012 + +append styles + mixin css('graph-display.css') + mixin css('dashboard.css') + +block main-scripts + script(src="/js/kraken/main-dashboard.js?"+version) diff --git a/www/modules.yaml b/www/modules.yaml index e97060b..c217b2d 100644 --- a/www/modules.yaml +++ b/www/modules.yaml @@ -69,8 +69,9 @@ dev: - datasource.jade - datasource-ui.jade - data.jade - - graph-edit.jade - graph-display.jade + - graph-edit.jade + - dashboard.jade - chart: - chart-type - dygraphs @@ -93,6 +94,10 @@ dev: - graph-display-view - graph-edit-view - index + - dashboard: + - dashboard-model + - dashboard-view + - index # - suffix: .js # paths: -- 1.7.0.4