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()
--- /dev/null
+{ _, 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: ->
+ {}
+
+
+# }}}
--- /dev/null
+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
+
+# }}}
+
--- /dev/null
+models = require 'kraken/dashboard/dashboard-model'
+views = require 'kraken/dashboard/dashboard-view'
+exports import models import views
for name of @__debounce__
@[name] = _.debounce @[name], DEBOUNCE_RENDER
- @viewport = @$el.find '.viewport'
### Model Events
@model
# 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
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
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
# 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
+_.bindAll Graph, 'register', 'get', 'lookup'
+
/* }}} */
--- /dev/null
+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
+
--- /dev/null
+section#dashboard
+ .page-header
+ h1 Wikimedia Report Card
+ small February 2012
+
+ section#graphs
+
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)
-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)
- datasource.jade
- datasource-ui.jade
- data.jade
- - graph-edit.jade
- graph-display.jade
+ - graph-edit.jade
+ - dashboard.jade
- chart:
- chart-type
- dygraphs
- graph-display-view
- graph-edit-view
- index
+ - dashboard:
+ - dashboard-model
+ - dashboard-view
+ - index
# - suffix: .js
# paths: