First pass at data UI, mostly inactive due to time. Adds simple dropdown for datasets.
authordsc <dsc@wikimedia.org>
Wed, 4 Apr 2012 20:04:22 +0000 (13:04 -0700)
committerdsc <dsc@wikimedia.org>
Wed, 4 Apr 2012 20:04:22 +0000 (13:04 -0700)
33 files changed:
lib/base.co
lib/chart/chart-option-model.co
lib/chart/chart-option-view.co
lib/dataset/data-view.co [new file with mode: 0644]
lib/dataset/dataset-model.co [new file with mode: 0644]
lib/dataset/dataset-view.co [new file with mode: 0644]
lib/dataset/datasource-model.co [new file with mode: 0644]
lib/dataset/datasource-ui-view.co [new file with mode: 0644]
lib/dataset/datasource-view.co [new file with mode: 0644]
lib/dataset/index.co [new file with mode: 0644]
lib/dataset/metric-edit-view.co [new file with mode: 0644]
lib/dataset/metric-model.co [new file with mode: 0644]
lib/dataset/metric-view.co [new file with mode: 0644]
lib/graph/graph-display-view.co
lib/graph/graph-edit-view.co
lib/graph/graph-model.co
lib/scaffold/scaffold-model.co
lib/scaffold/scaffold-view.co
lib/server/controllers/datasource.co
lib/server/server.co
lib/template/data.jade [new file with mode: 0644]
lib/template/dataset-metric.jade [new file with mode: 0644]
lib/template/dataset.jade [new file with mode: 0644]
lib/template/datasource-ui.jade [new file with mode: 0644]
lib/template/datasource.jade [new file with mode: 0644]
lib/template/graph-edit.jade
lib/template/metric-edit.jade [new file with mode: 0644]
lib/template/metric.jade [new file with mode: 0644]
lib/util/op.co
www/css/bootstrap-variables.styl [new file with mode: 0644]
www/css/colors.styl
www/css/data.styl [new file with mode: 0644]
www/modules.yaml

index f1f28f7..2ac0400 100644 (file)
@@ -1,5 +1,5 @@
-_  = require 'kraken/util/underscore'
-op = require 'kraken/util/op'
+{ _, op,
+} = require 'kraken/util'
 
 Backbone = require 'backbone'
 
@@ -19,9 +19,7 @@ BaseModel = exports.BaseModel = Backbone.Model.extend do # {{{
     
     constructor : function BaseModel
         @__class__      = @constructor
-        @__super__      = @constructor.__super__
-        @__superclass__ = @__super__.constructor
-        # Backbone.NestedModel ...
+        @__superclass__ = @..__super__.constructor
         Backbone.Model ...
         @trigger 'create', this
     
@@ -50,7 +48,7 @@ BaseModel = exports.BaseModel = Backbone.Model.extend do # {{{
     #         if _.str.contains key, '.'
     #             _.setNested @attributes, key, value, opts
     #         else
-    #             @__super__.set.call this, key, value, opts
+    #             Backbone.Model::set.call this, key, value, opts
     #     
     #     this
     # 
@@ -126,8 +124,14 @@ BaseList = exports.BaseList = Backbone.Collection.extend do # {{{
     __bind__ : []
     
     
+    
+    constructor : function BaseList
+        @__class__      = @constructor
+        @__superclass__ = @..__super__.constructor
+        Backbone.Collection ...
+        @trigger 'create', this
+    
     initialize : ->
-        @__super__ = @constructor.__super__
         _.bindAll this, ...@__bind__ if @__bind__.length
     
     
@@ -151,13 +155,27 @@ BaseList = exports.BaseList = Backbone.Collection.extend do # {{{
 BaseView = exports.BaseView = Backbone.View.extend do # {{{
     ctorName : 'BaseView'
     
-    # A list of method-names to bind on initialize; set this on a subclass to override.
+    /**
+     * A list of method-names to bind on initialize; set this on a subclass to override.
+     * @type Array<String>
+     */
     __bind__ : []
     
+    /**
+     * @type Array<BaseView>
+     */
+    subviews : []
+    
     
     
+    constructor : function BaseView
+        @__class__      = @constructor
+        @__superclass__ = @..__super__.constructor
+        @subviews       = []
+        Backbone.View ...
+        @trigger 'create', this
+    
     initialize: ->
-        @__super__ = @constructor.__super__
         _.bindAll this, ...@__bind__ if @__bind__.length
         
         @model.view = this
index e5277f8..7cf2bc7 100644 (file)
@@ -48,6 +48,9 @@ ChartOption = exports.ChartOption = Field.extend do # {{{
     IGNORED_TAGS : <[ callback deprecated debugging ]>
     
     
+    constructor: function ChartOption
+        Field ...
+    
     initialize : ->
         # console.log "#this.initialize!"
         Field::initialize ...
@@ -113,6 +116,10 @@ ChartOptionList = exports.ChartOptionList = FieldList.extend do # {{{
     ctorName   : 'ChartOptionList'
     model      : ChartOption
     
+    
+    constructor: function ChartOptionList
+        FieldList ...
+    
     /**
      * Override to omit defaults from URL.
      */
index fa68de9..369c198 100644 (file)
@@ -28,8 +28,11 @@ ChartOptionView = exports.ChartOptionView = FieldView.extend do # {{{
         'click .collapsed'                   : 'onClick'
     
     
+    constructor: function ChartOptionView
+        FieldView ...
+    
     render: ->
-        @__super__.render ...
+        FieldView::render ...
         @$el.addClass 'collapsed' if @isCollapsed
         this
     
@@ -60,12 +63,14 @@ ChartOptionScaffold = exports.ChartOptionScaffold = Scaffold.extend do # {{{
     template       : require 'kraken/template/chart-scaffold'
     collectionType : ChartOptionList
     subviewType    : ChartOptionView
-    fields        : '.fields'
+    fields         : '.fields'
     
     # GraphView will set this
     ready          : false
     
     
+    constructor: function ChartOptionScaffold
+        Scaffold ...
     
     initialize : ->
         @render = _.debounce @render.bind(this), DEBOUNCE_RENDER
@@ -73,7 +78,7 @@ ChartOptionScaffold = exports.ChartOptionScaffold = Scaffold.extend do # {{{
     
     render: ->
         # console.log "#this.render() -> .isotope()"
-        # @__super__.render ...
+        # Scaffold::render ...
         return this unless @ready
         container = if @fields then @$el.find @fields else @$el
         container
@@ -94,7 +99,7 @@ ChartOptionScaffold = exports.ChartOptionScaffold = Scaffold.extend do # {{{
      * layout after collapse events.
      */
     addOne: (field) ->
-        view = @__super__.addOne ...
+        view = Scaffold::addOne ...
         view.on 'change:collapse render', @render
         view
     
diff --git a/lib/dataset/data-view.co b/lib/dataset/data-view.co
new file mode 100644 (file)
index 0000000..75439f9
--- /dev/null
@@ -0,0 +1,63 @@
+Seq = require 'seq'
+{ _, op,
+} = require 'kraken/util'
+{ BaseView,
+} = require 'kraken/base'
+{ DataSetView,
+} = require 'kraken/dataset/dataset-view'
+{ MetricEditView,
+} = require 'kraken/dataset/metric-edit-view'
+
+
+/**
+ * @class
+ */
+DataView = exports.DataView = BaseView.extend do # {{{
+    ctorName       : 'DataView'
+    tagName        : 'section'
+    className      : 'data-ui'
+    template       : require 'kraken/template/data'
+    
+    data : {}
+    
+    
+    
+    constructor: function DataView
+        BaseView ...
+    
+    initialize: ->
+        @graph_id = @options.graph_id
+        BaseView::initialize ...
+        
+        @load()
+        
+        # @subviews.push @dataset_view = new DataSetView {@model, @graph_id}
+        # @$el.append @dataset_view.render().el
+        # @dataset_view.on 'edit-metric', @editMetric, this
+        # 
+        # @subviews.push @metric_edit_view  = new MetricEditView  {dataset:@model, @graph_id}
+        # @$el.append @metric_edit_view.render().hide().el
+        
+    
+    toTemplateLocals: ->
+        attrs = _.clone @model.attributes
+        { $, _, op, @model, view:this, @data, @graph_id } import attrs
+    
+    
+    load: ->
+        $.getJSON '/datasources/all', (@data) ~>
+            @ready = true
+            @render()
+            @trigger 'ready', this
+    
+    # Don't rebuild HTML, simply notify subviews
+    render: ->
+        BaseView::render ...
+        
+        # _.invoke @subviews, 'render'
+        this
+    
+    editMetric: (metric) ->
+        @metric_edit_view.editMetric metric
+    
+# }}}
diff --git a/lib/dataset/dataset-model.co b/lib/dataset/dataset-model.co
new file mode 100644 (file)
index 0000000..1b40c21
--- /dev/null
@@ -0,0 +1,61 @@
+Seq = require 'seq'
+ColorBrewer = require 'colorbrewer'
+
+{ _, op,
+} = require 'kraken/util'
+{ BaseModel, BaseList,
+} = require 'kraken/base'
+{ Metric, MetricList,
+} = require 'kraken/dataset/metric-model'
+{ DataSource, DataSourceList,
+} = require 'kraken/dataset/datasource-model'
+
+
+
+/**
+ * @class
+ */
+DataSet = exports.DataSet = BaseModel.extend do # {{{
+    ctorName : 'DataSet'
+    urlRoot : '/datasets'
+    
+    /**
+     * @type DataSourceList
+     */
+    sources : []
+    
+    /**
+     * @type MetricList
+     */
+    metrics : []
+    
+    
+    constructor: function DataSet
+        BaseModel ...
+    
+    initialize : ->
+        BaseModel::initialize ...
+        @sources = new DataSourceList @attributes.sources
+        @metrics = new MetricList     @attributes.metrics
+    
+    
+    defaults : ->
+        sources : [] # XXX: needed? metrics now implies this info
+        metrics : []
+        # lines   : []
+    
+    
+    /**
+     * @returns {Array} The reified dataset, materialized to an array of data-series arrays.
+     */
+    getData: ->
+        '/data/datasources/non_mobile_pageviews_by.timestamp.language.csv'
+    
+    newMetric: ->
+        index = @metrics.length
+        @metrics.add m = new Metric { index, color:ColorBrewer.Spectral[11][index] }
+        m
+    
+    
+# }}}
+
diff --git a/lib/dataset/dataset-view.co b/lib/dataset/dataset-view.co
new file mode 100644 (file)
index 0000000..eadaff0
--- /dev/null
@@ -0,0 +1,111 @@
+{ _, op,
+} = require 'kraken/util'
+{ BaseView,
+} = require 'kraken/base'
+
+
+/**
+ * @class
+ */
+DataSetView = exports.DataSetView = BaseView.extend do # {{{
+    ctorName  : 'DataSetView'
+    tagName   : 'section'
+    className : 'dataset-ui dataset'
+    template  : require 'kraken/template/dataset'
+    
+    events:
+        'click .new-metric-button'       : 'newMetric'
+        'click .metrics .dataset-metric' : 'editMetric'
+    
+    views_by_cid : {}
+    active_view : null
+    
+    
+    constructor: function DataSetView
+        BaseView ...
+    
+    initialize: ->
+        @graph_id = @options.graph_id
+        BaseView::initialize ...
+        @views_by_cid = {}
+        @model.metrics.on 'add', @addMetric, this
+    
+    
+    newMetric: ->
+        # triggers 'add' on @model.metrics
+        @model.newMetric()
+        false
+    
+    addMetric: (metric) ->
+        console.log "#this.addMetric!", metric
+        if metric.view
+            _.remove @subviews, metric.view
+            delete @views_by_cid[metric.cid]
+        
+        @subviews.push view = new DataSetMetricView {model:metric, @graph_id}
+        @views_by_cid[metric.cid] = view
+        @$el.find '.metrics' .append view.render().el
+        
+        # @render()
+        view
+    
+    editMetric: (metric) ->
+        console.log "#this.editMetric!", metric
+        if metric instanceof [jQuery.Event, Event]
+            metric = $ metric.currentTarget .data 'model'
+        view = @views_by_cid[metric.cid]
+        console.log '  --> metric:', metric, 'view:', view
+        
+        @$el.find '.metrics' .removeClass 'metric-active'
+        view.$el.addClass 'metric-active'
+        view.$el.find '.activity-arrow' .css 'font-size', 2+view.$el.height()
+        @trigger 'edit-metric', metric
+    
+# }}}
+
+
+
+/**
+ * @class
+ */
+DataSetMetricView = exports.DataSetMetricView = BaseView.extend do # {{{
+    ctorName  : 'DataSetMetricView'
+    tagName   : 'tr'
+    className : 'dataset-metric metric'
+    template  : require 'kraken/template/dataset-metric'
+    
+    
+    
+    constructor: function DataSetMetricView
+        BaseView ...
+    
+    initialize: ->
+        @graph_id = @options.graph_id
+        BaseView::initialize ...
+    
+    
+    toTemplateLocals: ->
+        m = @model.toJSON()
+        m import
+            graph_id : @graph_id
+            viewClasses : _.compact([
+                if @model.isOk() then 'valid'   else 'invalid',
+                if m.visible     then 'visible' else 'hidden',
+                'disabled' if m.disabled,
+            ]).map( -> "metric-#it" ).join ' '
+            source :
+                if m.source_id and m.source_col_name
+                    "#{m.source_id}.#{m.source_col_name}"
+                else
+                    'No source'
+            timespan :
+                if _.every ts = m.timespan, op.ok
+                    "#{ts.start} to #{ts.end} by #{ts.step}"
+                else
+                    '&mdash;'
+        
+        # XXX: Icons/classes for visible/disabled?
+        { $, _, op, @model, view:this } import m
+    
+# }}}
+
diff --git a/lib/dataset/datasource-model.co b/lib/dataset/datasource-model.co
new file mode 100644 (file)
index 0000000..ef23d98
--- /dev/null
@@ -0,0 +1,47 @@
+{ _, op,
+} = require 'kraken/util'
+{ BaseModel, BaseList, BaseView,
+} = require 'kraken/base'
+
+
+/**
+ * @class
+ */
+DataSource = exports.DataSource = BaseModel.extend do # {{{
+    ctorName : 'DataSource'
+    urlRoot  : '/datasources'
+    
+    
+    constructor: function DataSource
+        BaseModel ...
+    
+    initialize: ->
+        BaseModel::initialize ...
+        
+    
+    defaults: ->
+        {}
+    
+    url: ->
+        "/data/#{@id}.json"
+    
+# }}}
+
+
+
+/**
+ * @class
+ */
+DataSourceList = exports.DataSourceList = BaseList.extend do # {{{
+    ctorName : 'DataSourceList'
+    urlRoot  : '/datasources'
+    model    : DataSource
+    
+    constructor: function DataSourceList
+        BaseList ...
+    
+    initialize : ->
+        BaseList::initialize ...
+    
+    
+# }}}
diff --git a/lib/dataset/datasource-ui-view.co b/lib/dataset/datasource-ui-view.co
new file mode 100644 (file)
index 0000000..25d52d1
--- /dev/null
@@ -0,0 +1,32 @@
+{ _, op,
+} = require 'kraken/util'
+{ BaseModel, BaseList, BaseView,
+} = require 'kraken/base'
+
+
+/**
+ * @class
+ */
+DataSourceUIView = exports.DataSourceUIView = BaseView.extend do # {{{
+    __bind__       : <[  ]>
+    ctorName       : 'DataSourceUIView'
+    tagName        : 'section'
+    className      : 'datasource-ui'
+    template       : require 'kraken/template/datasource-ui'
+    
+    
+    constructor: function DataSourceUIView
+        BaseView ...
+    
+    initialize: ->
+        @graph_id = @options.graph_id
+        BaseView::initialize ...
+    
+    toTemplateLocals: ->
+        locals = @model.toJSON()
+        locals import
+            graph_id         : @graph_id
+            source_summary   : 'Source Summary'
+            metric_summary   : 'Metric Summary'
+            timespan_summary : 'Timespan Summary'
+# }}}
diff --git a/lib/dataset/datasource-view.co b/lib/dataset/datasource-view.co
new file mode 100644 (file)
index 0000000..e7d6aa2
--- /dev/null
@@ -0,0 +1,25 @@
+{ _, op,
+} = require 'kraken/util'
+{ BaseModel, BaseList, BaseView,
+} = require 'kraken/base'
+
+
+/**
+ * @class
+ */
+DataSourceView = exports.DataSourceView = BaseView.extend do # {{{
+    __bind__       : <[  ]>
+    ctorName       : 'DataSourceView'
+    tagName        : 'section'
+    className      : 'datasource'
+    template       : require 'kraken/template/datasource'
+    
+    
+    
+    constructor: function DataSourceView
+        BaseView ...
+    
+    initialize: ->
+        BaseView::initialize ...
+    
+# }}}
diff --git a/lib/dataset/index.co b/lib/dataset/index.co
new file mode 100644 (file)
index 0000000..56d3e89
--- /dev/null
@@ -0,0 +1,14 @@
+metric_model       = require 'kraken/dataset/metric-model'
+metric_view        = require 'kraken/dataset/metric-view'
+metric_edit_view   = require 'kraken/dataset/metric-edit-view'
+datasource_model   = require 'kraken/dataset/datasource-model'
+datasource_view    = require 'kraken/dataset/datasource-view'
+datasource_ui_view = require 'kraken/dataset/datasource-ui-view'
+dataset_model      = require 'kraken/dataset/dataset-model'
+dataset_view       = require 'kraken/dataset/dataset-view'
+data_view          = require 'kraken/dataset/data-view'
+
+exports import metric_model     import metric_view      import metric_edit_view     \
+        import datasource_model import datasource_view  import datasource_ui_view   \
+        import dataset_model    import dataset_view                                 \
+                                import data_view
diff --git a/lib/dataset/metric-edit-view.co b/lib/dataset/metric-edit-view.co
new file mode 100644 (file)
index 0000000..b397ff5
--- /dev/null
@@ -0,0 +1,55 @@
+{ _, op,
+} = require 'kraken/util'
+{ BaseView,
+} = require 'kraken/base'
+{ Metric,
+} = require 'kraken/dataset/metric-model'
+{ DataSourceUIView,
+} = require 'kraken/dataset/datasource-ui-view'
+
+
+
+/**
+ * @class
+ */
+MetricEditView = exports.MetricEditView = BaseView.extend do # {{{
+    ctorName       : 'MetricEditView'
+    tagName        : 'section'
+    className      : 'metric-edit-ui'
+    template       : require 'kraken/template/metric-edit'
+    
+    graph_id           : null
+    dataset            : null
+    datasource_ui_view : null
+    
+    
+    constructor: function MetricEditView
+        BaseView ...
+    
+    initialize: ->
+        this import @options.{graph_id, dataset}
+        @model or= new Metric
+        BaseView::initialize ...
+        @subviews.push @datasource_ui_view = new DataSourceUIView {@model, @graph_id}
+        @$el.find '.metric-datasource' .append @datasource_ui_view.render().el
+    
+    
+    toTemplateLocals: ->
+        locals = BaseView::toTemplateLocals ...
+        locals import {@graph_id}
+    
+    build: ->
+        BaseView::build ...
+        if @datasource_ui_view
+            @$el.find '.metric-datasource' .append @datasource_ui_view.render().el
+        this
+    
+    editMetric: (metric) ->
+        console.log "#this.editMetric!", metric
+        @model = metric
+        @render()
+        @show()
+        this
+    
+# }}}
+
diff --git a/lib/dataset/metric-model.co b/lib/dataset/metric-model.co
new file mode 100644 (file)
index 0000000..63a88a0
--- /dev/null
@@ -0,0 +1,73 @@
+{ _, op,
+} = require 'kraken/util'
+{ BaseModel, BaseList,
+} = require 'kraken/base'
+
+
+/**
+ * @class
+ */
+Metric = exports.Metric = BaseModel.extend do # {{{
+    ctorName : 'Metric'
+    urlRoot  : '/metrics'
+    
+    /**
+     * Data source of the Metric.
+     * @type DataSource
+     */
+    source : null
+    
+    
+    constructor: function Metric
+        BaseModel ...
+    
+    initialize : ->
+        BaseModel::initialize ...
+    
+    
+    defaults : ->
+        index           : 0
+        label           : 'New Metric'
+        type            : 'int'
+        timespan        : { start:null, stop:null, step:null }
+        disabled        : false
+        
+        # DataSource
+        source_id       : null
+        source_col_idx  : -1
+        source_col_name : ''
+        
+        # Chart Options
+        color           : null
+        visible         : true
+        format_value    : null
+        format_axis     : null
+        
+        scale           : 1.0
+        transforms      : []
+    
+    
+    /**
+     * Check whether the metric has aiight-looking values so we don't
+     * attempt to graph unconfigured crap.
+     */
+    isOk: ->
+        (label = @get('label')) and label is not 'New Metric'
+        and @get('source_id')   and @get('source_col_idx') >= 0
+        and _.every @get('timespan'), op.ok
+    
+    
+    
+# }}}
+
+
+/**
+ * @class
+ */
+MetricList = exports.MetricList = BaseList.extend do # {{{
+    ctorName : 'MetricList'
+    urlRoot  : '/metrics'
+    model    : Metric
+    
+    constructor: function MetricList then BaseList ...
+# }}}
diff --git a/lib/dataset/metric-view.co b/lib/dataset/metric-view.co
new file mode 100644 (file)
index 0000000..e69de29
index 8d24a78..cdbdfd3 100644 (file)
@@ -21,6 +21,9 @@ GraphDisplayView = exports.GraphDisplayView = BaseView.extend do # {{{
     #     'submit .value' : 'update'
     
     
+    constructor: function GraphDisplayView
+        BaseView ...
+    
     initialize: ->
         @model or= new Graph
         BaseView::initialize ...
index 49dca93..c95a6e8 100644 (file)
@@ -7,7 +7,7 @@ _ = require 'kraken/util/underscore'
 } = require 'kraken/chart'
 { Graph,
 } = require 'kraken/graph/graph-model'
-{ DataSetView,
+{ DataView, DataSetView, DataSet,
 } = require 'kraken/dataset'
 
 root = do -> this
@@ -45,29 +45,33 @@ GraphEditView = exports.GraphEditView = BaseView.extend do # {{{
         'keypress form.details input[type="text"]' : 'onKeypress'
         'keypress form.options .value'             : 'onKeypress'
         'submit   form.details'                    : 'onDetailsSubmit'
+        'change   select'                          : 'onDetailsSubmit'
         'submit   form.options'                    : 'onOptionsSubmit'
         'change   input[type="checkbox"]'          : 'onOptionsSubmit'
     
-    subviews: []
-    ready: false
+    data  : {}
+    ready : false
     
     
+    constructor: function GraphEditView
+        BaseView ...
     
     initialize : (o={}) ->
-        @subviews = []
+        @data = {}
         @model or= new Graph
+        @id = _.domize 'graph', (@model.id or @model.get('slug') or @model.cid)
         BaseView::initialize ...
         # console.log "#this.initialize!"
         
         for name of @__debounce__
             @[name] = _.debounce @[name], DEBOUNCE_RENDER
         
-        @id = _.domize 'graph', (@model.get('slug') or @model.id or @model.cid)
+        @viewport = @$el.find '.viewport'
         
         ### Model Events
         @model
-            .on 'ready',            @onReady
-            .on 'sync',             @onSync
+            .on 'ready',            @onReady, this
+            .on 'sync',             @onSync,  this
             .on 'destroy',          @remove,  this
             .on 'change',           @render,  this
             .on 'change:dataset',   @onModelChange
@@ -76,11 +80,6 @@ GraphEditView = exports.GraphEditView = BaseView.extend do # {{{
                 console.error "#this.error!", arguments
                 # TODO: UI alert
         
-        ### Graph Data UI
-        @subviews.push @dataset = new DataSetView { model:@model.get 'dataset' }
-        @$el.find '.graph-data-pane' .append @dataset.el
-        @dataset.on 'change', @onDataChange
-        
         ### Chart Options Tab, Scaffold
         @scaffold = new ChartOptionScaffold
         @$el.find '.graph-options-pane' .append @scaffold.el
@@ -92,8 +91,13 @@ GraphEditView = exports.GraphEditView = BaseView.extend do # {{{
         # Rerender the options boxes once the tab is visible
         @$el.on 'click', '.graph-options-tab', @onFirstClickRenderOptionsTab
         
+        ### Graph Data UI
+        # @subviews.push @data = new DataView { model:@model.get('dataset'), graph_id:@id }
+        @subviews.push @data = new DataView { model:new DataSet, graph_id:@id }
+        @$el.find '.graph-data-pane' .append @data.render().el
+        @data.on 'change', @onDataChange
+        
         ### Chart Viewport
-        @viewport = @$el.find '.viewport'
         @resizeViewport()
         
         # Resize chart on window resize
@@ -145,7 +149,8 @@ GraphEditView = exports.GraphEditView = BaseView.extend do # {{{
     toTemplateLocals: ->
         attrs = _.clone @model.attributes
         delete attrs.options
-        delete attrs.dataset
+        # delete attrs.dataset
+        attrs.data = @data
         { $, _, op, @model, view:this } import attrs
     
     
@@ -196,7 +201,7 @@ GraphEditView = exports.GraphEditView = BaseView.extend do # {{{
     
     # Redraw chart inside viewport.
     renderChart: ->
-        data = @model.get 'dataset' .getData()
+        data = @model.get 'dataset' #.getData()
         size = @resizeViewport()
         
         # XXX: use @model.changedAttributes() to calculate what to update
@@ -302,9 +307,11 @@ GraphEditView = exports.GraphEditView = BaseView.extend do # {{{
     
     
     onReady: ->
-        console.log "(#this via GraphEditView).ready!"
-        @ready = @scaffold.ready = true
-        @onSync()
+        return if @ready
+        $.getJSON '/datasources/all', (@data) ~>
+            console.log "(#this via GraphEditView).ready!"
+            @ready = @scaffold.ready = true
+            @onSync()
     
     onSync: ->
         return unless @ready
@@ -340,7 +347,7 @@ GraphEditView = exports.GraphEditView = BaseView.extend do # {{{
             @model.setOption(key, value, {+silent})
     
     onDataChange: ->
-        ...
+        console.log 'onDataChange!'
     
     onFirstClickRenderOptionsTab: ->
         @$el.off 'click', '.graph-options-tab', @onFirstClickRenderOptionsTab
index 339b6e8..4b55d54 100644 (file)
@@ -59,8 +59,8 @@ Graph = exports.Graph = BaseModel.extend do # {{{
             slug    : ''
             name    : ''
             desc    : ''
-            # dataset : '/data/datasources/non_mobile_pageviews_by.timestamp.language.csv'
-            dataset : null
+            dataset : '/data/datasources/non_mobile_pageviews_by.timestamp.language.csv'
+            # dataset : null
             width   : 'auto'
             height  : 320
             chartType : 'dygraphs'
@@ -73,31 +73,28 @@ Graph = exports.Graph = BaseModel.extend do # {{{
     
     
     
-    
-    constructor : (attributes={}, opts) ->
-        @on 'ready', ~> console.log "(#this via Graph).ready!"
+    constructor: function Graph (attributes={}, opts)
+        # @on 'ready', ~> console.log "(#this via Graph).ready!"
         attributes.options or= {}
         @optionCascade = new Cascade attributes.options
         BaseModel.call this, attributes, opts
     
     
-    initialize : (attributes, opts) ->
-        @__super__.initialize ...
-        opts = {+autoLoad} import (opts or {})
+    initialize: (attributes, opts) ->
+        BaseModel::initialize ...
+        opts = {+autoload} import (opts or {})
         
         @constructor.register this
         @parents = new GraphList
+        
         # TODO: Load on-demand
         @chartType = ChartType.lookup @get('chartType')
         
-        # unless @id or @get('id') or @get('slug')
-        #     @set 'slug', "unsaved_graph_#{@cid}"
-        
         # Insert submodels in place of JSON
-        @set 'dataset', new DataSet(@get('dataset')), {+silent}
+        # @set 'dataset', new DataSet(@get('dataset')), {+silent}
         
         @trigger 'init', this
-        @load() if opts.autoLoad
+        @load() if opts.autoload
     
     
     load: (opts={}) ->
@@ -114,7 +111,7 @@ Graph = exports.Graph = BaseModel.extend do # {{{
                             console.error "#{this}.fetch() --> error! #arguments"
                             next.ok()
                         success : (model, res) ~>
-                            console.log "#{this}.fetch() --> success!", res
+                            # console.log "#{this}.fetch() --> success!", res
                             next.ok res
             .seq_ (next) ~>
                 next.ok @get('parents')
@@ -137,7 +134,7 @@ Graph = exports.Graph = BaseModel.extend do # {{{
         if _.startsWith key, 'options.'
             @getOption key.slice(8)
         else
-            (@__super__ or BaseModel::).get.call this, key
+            (@..__super__ or BaseModel::).get.call this, key
     
     
     set: (key, value, opts) ->
@@ -148,7 +145,7 @@ Graph = exports.Graph = BaseModel.extend do # {{{
             values = { "#key": value }
         values = @parse values
         
-        setter = (@__super__ or BaseModel::).set
+        setter = (@..__super__ or BaseModel::).set
         
         # Merge options in, firing granulated change events
         if values.options
@@ -182,7 +179,7 @@ Graph = exports.Graph = BaseModel.extend do # {{{
         else
             values = { "#key": value }
         
-        _.dump values, "#this.setOption"
+        # _.dump values, "#this.setOption"
         options = @get('options')
         changed = false
         for key, value in values
@@ -305,7 +302,7 @@ Graph import do
     CACHE : GRAPH_CACHE
     
     register: (model) ->
-        console.log "#{@CACHE}.register(#{model.id or model.get('id')})", model
+        # console.log "#{@CACHE}.register(#{model.id or model.get('id')})", model
         if @CACHE.contains model
             @CACHE.remove model, {+silent}
         @CACHE.add model
index eda72ed..05e320d 100644 (file)
@@ -13,6 +13,9 @@ Field = exports.Field = BaseModel.extend do # {{{
     valueAttribute : 'value'
     
     
+    constructor: function Field
+        BaseModel ...
+    
     initialize: ->
         _.bindAll this, ...(_.functions this .filter -> _.startsWith(it, 'parse'))
         @set 'value', @get('default'), {+silent} if not @has 'value'
@@ -107,6 +110,9 @@ FieldList = exports.FieldList = BaseList.extend do # {{{
     ctorName : 'FieldList'
     model    : Field
     
+    
+    constructor: function FieldList then BaseList ...
+    
     /**
      * Collects a map of fields to their values, excluding those set to `null` or their default.
      * @returns {Object}
index 21aa194..be8e36a 100644 (file)
@@ -17,6 +17,9 @@ FieldView = exports.FieldView = BaseView.extend do # {{{
         'submit .value' : 'update'
     
     
+    constructor: function FieldView
+        BaseView ...
+    
     initialize: ->
         # console.log "#this.initialize!"
         BaseView::initialize ...
@@ -66,11 +69,12 @@ Scaffold = exports.Scaffold = BaseView.extend do # {{{
     subviewType    : FieldView
     
     
+    constructor: function Scaffold
+        BaseView ...
+    
     initialize: ->
-        @subviews = []
         CollectionType = @collectionType
         @model = @collection or= new CollectionType
-        
         BaseView::initialize ...
         
         @collection.on 'add',   @addOne
@@ -80,7 +84,7 @@ Scaffold = exports.Scaffold = BaseView.extend do # {{{
     
     
     addOne: (field) ->
-        # console.log "[S] #this.addOne!", @__super__
+        # console.log "[S] #this.addOne!", @..__super__
         _.remove @subviews, field.view if field.view
         
         # avoid duplicating event propagation
index 90c68f3..b77d4e2 100644 (file)
@@ -14,7 +14,7 @@ class DataSourceController extends Controller
     dataDir : 'data/graphs'
     
     mapping :
<