Refactors Graph{Model,View} as Vis{Model,View} to reflect the chart-vs-graph distinction.
authordsc <dsc@less.ly>
Wed, 29 Feb 2012 07:58:33 +0000 (23:58 -0800)
committerdsc <dsc@less.ly>
Wed, 29 Feb 2012 08:02:09 +0000 (00:02 -0800)
lib/graph/graph-model.co
lib/graph/graph-view.co
lib/main.co
lib/scaffold/scaffold-model.co
lib/scaffold/scaffold-view.co
lib/vis/index.co [new file with mode: 0644]
lib/vis/vis-model.co [new file with mode: 0644]
lib/vis/vis-view.co [new file with mode: 0644]
www/css/graph.styl
www/modules.yaml

index 53fa6a9..2728efa 100644 (file)
@@ -1,7 +1,7 @@
 _ = require 'kraken/underscore'
 { BaseModel, BaseView,
 } = require 'kraken/base'
-{ Field, FieldList, FieldView, Scaffold
+{ Field, FieldList, FieldView, Scaffold,
 } = require 'kraken/scaffold'
 
 
@@ -97,56 +97,3 @@ GraphOptionList = exports.GraphOptionList = FieldList.extend do # {{{
     model      : GraphOption
 # }}}
 
-
-/**
- * Represents a Graph, including its charting options, dataset, annotations, and all
- * other settings for both its content and presentation.
- */
-GraphModel = exports.GraphModel = BaseModel.extend do # {{{
-    ctorName    : 'GraphModel'
-    urlRoot     : '/graphs'
-    idAttribute : 'slug'
-    
-    
-    initialize : ->
-        name = @get 'name'
-        if name and not (@id or @get('slug'))
-            @set 'slug', _.underscored name
-    
-    defaults: ->
-        {
-            slug    : ''
-            name    : ''
-            dataset : '/data/pageviews_by.timestamp.language.csv'
-            desc    : ''
-            width   : 'auto'
-            height  : 320
-            options : {}
-        }
-    
-    
-    hasOption: (key) ->
-        options = @get 'options', {}
-        options[key]?
-    
-    getOption: (key, def) ->
-        @get('options', {})[key] ? def
-    
-    setOption: (key, value, opts={}) ->
-        options = @get 'options', {}
-        options[key] = value
-        @set 'options', options, opts
-        @trigger "change:options:#key", this, value, key, opts unless opts.silent
-    
-    unsetOption: (key, opts={}) ->
-        options = @get 'options', {}
-        delete options[key]
-        @set 'options', options, opts
-        @trigger "change:options:#key", this, value, key, opts unless opts.silent
-    
-    
-    toString: -> "#{@ctorName}(id=#{@id}, name=#{@get 'name'}, dataset=#{@get 'dataset'})"
-
-# }}}
-
-
index d507f8e..4087cf5 100644 (file)
@@ -1,11 +1,10 @@
 _ = require 'kraken/underscore'
 {BaseView} = require 'kraken/base'
-{ Field, FieldList, FieldView, Scaffold
+{ Field, FieldList, FieldView, Scaffold,
 } = require 'kraken/scaffold'
-{   GraphModel, GraphOption, GraphOptionList, TagSet,
+{ GraphOption, GraphOptionList, TagSet, KNOWN_TAGS,
 } = require 'kraken/graph/graph-model'
 
-root = do -> this
 DEBOUNCE_RENDER = exports.DEBOUNCE_RENDER = 100ms
 
 
@@ -52,6 +51,9 @@ GraphOptionView = exports.GraphOptionView = FieldView.extend do # {{{
 
 
 
+/**
+ * 
+ */
 GraphOptionsScaffold = exports.GraphOptionsScaffold = Scaffold.extend do # {{{
     ctorName       : 'GraphOptionsScaffold'
     tagName        : 'form'
@@ -93,148 +95,3 @@ GraphOptionsScaffold = exports.GraphOptionsScaffold = Scaffold.extend do # {{{
 # }}}
 
 
-
-
-GraphView = exports.GraphView = BaseView.extend do # {{{
-    __bind__  : <[ resizeViewport render renderAll onReady ]>
-    ctorName  : 'GraphView'
-    tagName   : 'section'
-    className : 'graph'
-    template  : require 'kraken/template/graph'
-    
-    events:
-        'keypress form.options .value' : 'onKeypress'
-        'submit   form.options'        : 'onSubmit'
-    
-    ready: false
-    
-    
-    
-    initialize : (o={}) ->
-        @model or= new GraphModel
-        BaseView::initialize ...
-        # console.log "#this.initialize!"
-        
-        for name of <[ resizeViewport render renderAll ]>
-            @[name] = _.debounce @[name], DEBOUNCE_RENDER
-        
-        # Resize graph on window resize
-        $ root .on 'resize', @resizeViewport
-        
-        @model.on 'destroy', @remove, this
-        @model.on 'change',  @render, this
-        @model.on 'change:options', ~>
-            changes = @model.changedAttributes()
-            # console.log 'Model.changed(options) ->', changes
-            @chartOptions changes, {+silent}
-        
-        @build()
-        @viewport = @$el.find '.viewport'
-        
-        @scaffold = new GraphOptionsScaffold
-        @$el.find 'fieldset' .append @scaffold.el
-        @scaffold.collection.reset that if o.graph_spec
-        
-        @scaffold.on 'change', (scaffold, value, key, field) ~>
-            # console.log "scaffold.change!", value, key, field
-            @model.setOption key, value, {+silent} unless field.isDefault()
-        
-        options = @model.get 'options', {}
-        @chartOptions options, {+silent}
-        
-        _.delay @onReady, DEBOUNCE_RENDER
-    
-    
-    onReady: ->
-        @ready = @scaffold.ready = true
-        @renderAll()
-    
-    
-    chartOptions: (values, opts) ->
-        # Handle @chartOptions(k, v, opts)
-        if arguments.length > 1 and typeof values is 'string'
-            [k, v, opts] = arguments
-            values = { "#k": v }
-        
-        options = @scaffold.collection
-        if values
-            for k, v in values
-                options.get(k)?.setValue v, opts
-            this
-        else
-            options.values()
-    
-    
-    /**
-     * Resizes chart according to the model's width and height.
-     * @return { width, height }
-     */
-    resizeViewport: ->
-        return this unless @ready and @chart
-        
-        # Remove old style, as it confuses dygraph after options update
-        @viewport.attr 'style', ''
-        
-        if (width = @model.get 'width')  is 'auto'
-            width = @viewport.width()
-        if (height = @model.get 'height') is 'auto'
-            height = @viewport.height()
-        size = { width, height }
-        @viewport.css size
-        console.log 'resizeViewport!', JSON.stringify(size), @viewport
-        # @chart.resize size if forceRedraw
-        size
-    
-    render: ->
-        return this unless @ready
-        
-        # console.log "#this"
-        # console.log do 
-        #     "  .viewport.{ width=%s, height=%s, style=%s }"
-        #     @viewport.css('width')
-        #     @viewport.css('height')
-        #     @viewport.attr 'style'
-        # console.log '  .options:', JSON.stringify options
-        
-        size = @resizeViewport()
-        options = @chartOptions()
-        # @chart?.destroy()
-        unless @chart
-            @chart = new Dygraph do
-                @viewport.0
-                @model.get 'dataset'
-                options
-        else
-            @chart.updateOptions options
-            @chart.resize size
-        
-        path = root.location?.path or '/'
-        url = "#path?#{@toKVPairs()}"
-        # console.log 'History.pushState', url
-        History.pushState url, @model.get('name', root.document?.title or ''), url
-        
-        this
-    
-    renderAll: ->
-        return this unless @ready
-        _.invoke @scaffold.subviews, 'render'
-        @scaffold.render()
-        @render()
-        this
-    
-    onKeypress: (evt) ->
-        $(evt.target).submit() if evt.keyCode is 13
-    
-    onSubmit: ->
-        # console.log "#this.onSubmit!"
-        @render()
-        false
-    
-    toKVPairs: ->
-        @model.toKVPairs.apply @model, arguments
-    
-    toString: -> "#{@ctorName}(#{@model})"
-# }}}
-
-
-
index f226812..43962e4 100644 (file)
@@ -1,14 +1,14 @@
-{ _, op
+{ _, op,
 } = require 'kraken/util'
 { BaseView, BaseModel, BaseList,
 } = require 'kraken/base'
 {   Field, FieldList, FieldView, Scaffold,
 } = require 'kraken/scaffold'
-{   GraphView, GraphModel, TagSet,
-    GraphOption, GraphOptionList, GraphOptionView,
-    GraphOptionsScaffold,
+{   GraphOption, GraphOptionList, GraphOptionView,
+    GraphOptionsScaffold, TagSet,
 } = require 'kraken/graph'
-
+{ VisView, VisModel,
+} = require 'kraken/vis'
 
 root = do -> this
 
@@ -17,7 +17,7 @@ main = ->
     History.Adapter.bind window, 'statechange', ->
         console.log 'StateChange!', String root.location
     
-    graph = root.graph = new GraphView do
+    graph = root.graph = new VisView do
         graph_spec : CHART_OPTIONS_SPEC
     
     # If we got querystring args, apply them to the graph
index 5049c87..8142295 100644 (file)
@@ -1,6 +1,7 @@
-_    = require 'kraken/underscore'
-op   = require 'kraken/util/op'
-{BaseModel, BaseList} = require 'kraken/base'
+_  = require 'kraken/underscore'
+op = require 'kraken/util/op'
+{ BaseModel, BaseList,
+}  = require 'kraken/base'
 
 
 
index 12a46dd..8f2c770 100644 (file)
@@ -1,8 +1,9 @@
-_          = require 'kraken/underscore'
-op         = require 'kraken/util/op'
-{BaseView} = require 'kraken/base'
+_  = require 'kraken/underscore'
+op = require 'kraken/util/op'
+{ BaseView,
+}  = require 'kraken/base'
 { Field, FieldList,
-}          = require 'kraken/scaffold/scaffold-model'
+}  = require 'kraken/scaffold/scaffold-model'
 
 
 FieldView = exports.FieldView = BaseView.extend do # {{{
diff --git a/lib/vis/index.co b/lib/vis/index.co
new file mode 100644 (file)
index 0000000..9975640
--- /dev/null
@@ -0,0 +1,3 @@
+models = require 'kraken/vis/vis-model'
+views  = require 'kraken/vis/vis-view'
+exports import models import views
diff --git a/lib/vis/vis-model.co b/lib/vis/vis-model.co
new file mode 100644 (file)
index 0000000..5bd89c6
--- /dev/null
@@ -0,0 +1,58 @@
+_ = require 'kraken/underscore'
+{ BaseModel, BaseView,
+} = require 'kraken/base'
+
+
+
+/**
+ * Represents a Graph, including its charting options, dataset, annotations, and all
+ * other settings for both its content and presentation.
+ */
+VisModel = exports.VisModel = BaseModel.extend do # {{{
+    ctorName    : 'VisModel'
+    urlRoot     : '/graphs'
+    idAttribute : 'slug'
+    
+    
+    initialize : ->
+        name = @get 'name'
+        if name and not (@id or @get('slug'))
+            @set 'slug', _.underscored name
+    
+    defaults: ->
+        {
+            slug    : ''
+            name    : ''
+            dataset : '/data/pageviews_by.timestamp.language.csv'
+            desc    : ''
+            width   : 'auto'
+            height  : 320
+            options : {}
+        }
+    
+    
+    hasOption: (key) ->
+        options = @get 'options', {}
+        options[key]?
+    
+    getOption: (key, def) ->
+        @get('options', {})[key] ? def
+    
+    setOption: (key, value, opts={}) ->
+        options = @get 'options', {}
+        options[key] = value
+        @set 'options', options, opts
+        @trigger "change:options:#key", this, value, key, opts unless opts.silent
+    
+    unsetOption: (key, opts={}) ->
+        options = @get 'options', {}
+        delete options[key]
+        @set 'options', options, opts
+        @trigger "change:options:#key", this, value, key, opts unless opts.silent
+    
+    
+    toString: -> "#{@ctorName}(id=#{@id}, name=#{@get 'name'}, dataset=#{@get 'dataset'})"
+
+# }}}
+
+
diff --git a/lib/vis/vis-view.co b/lib/vis/vis-view.co
new file mode 100644 (file)
index 0000000..b707d58
--- /dev/null
@@ -0,0 +1,161 @@
+root = do -> this
+
+_ = require 'kraken/underscore'
+{ BaseView,
+} = require 'kraken/base'
+{ Field, FieldList, FieldView, Scaffold
+} = require 'kraken/scaffold'
+{   GraphOptionsScaffold, GraphOption, GraphOptionList, DEBOUNCE_RENDER,
+} = require 'kraken/graph'
+{ VisModel,
+} = require 'kraken/vis/vis-model'
+
+
+
+
+
+/**
+ * View for a graph visualization encapsulating the UI for:
+ * - Graph metadata, such as name, description, slug
+ */
+VisView = exports.VisView = BaseView.extend do # {{{
+    __bind__  : <[ resizeViewport render renderAll onReady ]>
+    ctorName  : 'VisView'
+    tagName   : 'section'
+    className : 'graph'
+    template  : require 'kraken/template/graph'
+    
+    events:
+        'keypress form.options .value' : 'onKeypress'
+        'submit   form.options'        : 'onSubmit'
+    
+    ready: false
+    
+    
+    
+    initialize : (o={}) ->
+        @model or= new VisModel
+        BaseView::initialize ...
+        # console.log "#this.initialize!"
+        
+        for name of <[ resizeViewport render renderAll ]>
+            @[name] = _.debounce @[name], DEBOUNCE_RENDER
+        
+        # Resize graph on window resize
+        $ root .on 'resize', @resizeViewport
+        
+        @model.on 'destroy', @remove, this
+        @model.on 'change',  @render, this
+        @model.on 'change:options', ~>
+            changes = @model.changedAttributes()
+            # console.log 'Model.changed(options) ->', changes
+            @chartOptions changes, {+silent}
+        
+        @build()
+        @viewport = @$el.find '.viewport'
+        
+        @scaffold = new GraphOptionsScaffold
+        @$el.find 'fieldset' .append @scaffold.el
+        @scaffold.collection.reset that if o.graph_spec
+        
+        @scaffold.on 'change', (scaffold, value, key, field) ~>
+            # console.log "scaffold.change!", value, key, field
+            @model.setOption key, value, {+silent} unless field.isDefault()
+        
+        options = @model.get 'options', {}
+        @chartOptions options, {+silent}
+        
+        _.delay @onReady, DEBOUNCE_RENDER
+    
+    
+    onReady: ->
+        @ready = @scaffold.ready = true
+        @renderAll()
+    
+    
+    chartOptions: (values, opts) ->
+        # Handle @chartOptions(k, v, opts)
+        if arguments.length > 1 and typeof values is 'string'
+            [k, v, opts] = arguments
+            values = { "#k": v }
+        
+        options = @scaffold.collection
+        if values
+            for k, v in values
+                options.get(k)?.setValue v, opts
+            this
+        else
+            options.values()
+    
+    
+    /**
+     * Resizes chart according to the model's width and height.
+     * @return { width, height }
+     */
+    resizeViewport: ->
+        return this unless @ready and @chart
+        
+        # Remove old style, as it confuses dygraph after options update
+        @viewport.attr 'style', ''
+        
+        if (width = @model.get 'width')  is 'auto'
+            width = @viewport.width()
+        if (height = @model.get 'height') is 'auto'
+            height = @viewport.height()
+        size = { width, height }
+        @viewport.css size
+        console.log 'resizeViewport!', JSON.stringify(size), @viewport
+        # @chart.resize size if forceRedraw
+        size
+    
+    render: ->
+        return this unless @ready
+        
+        # console.log "#this"
+        # console.log do 
+        #     "  .viewport.{ width=%s, height=%s, style=%s }"
+        #     @viewport.css('width')
+        #     @viewport.css('height')
+        #     @viewport.attr 'style'
+        # console.log '  .options:', JSON.stringify options
+        
+        size = @resizeViewport()
+        options = @chartOptions()
+        # @chart?.destroy()
+        unless @chart
+            @chart = new Dygraph do
+                @viewport.0
+                @model.get 'dataset'
+                options
+        else
+            @chart.updateOptions options
+            @chart.resize size
+        
+        path = root.location?.path or '/'
+        url = "#path?#{@toKVPairs()}"
+        # console.log 'History.pushState', url
+        History.pushState url, @model.get('name', root.document?.title or ''), url
+        
+        this
+    
+    renderAll: ->
+        return this unless @ready
+        _.invoke @scaffold.subviews, 'render'
+        @scaffold.render()
+        @render()
+        this
+    
+    onKeypress: (evt) ->
+        $(evt.target).submit() if evt.keyCode is 13
+    
+    onSubmit: ->
+        # console.log "#this.onSubmit!"
+        @render()
+        false
+    
+    toKVPairs: ->
+        @model.toKVPairs.apply @model, arguments
+    
+    toString: -> "#{@ctorName}(#{@model})"
+# }}}
+
index 749129b..4f9b09f 100644 (file)
@@ -20,9 +20,10 @@ section.graph
     form.details
         position relative
         
-        .help-block
-            font-size 11px
-            line-height 1.3
+        .name-row
+            line-height 2em
+            // input.name
+            //     width 50%
         .row-fluid
             .half.control-group
                 width 50%
@@ -33,10 +34,9 @@ section.graph
                 width 100px
             .controls
                 margin-left 110px
-        .name-row
-            line-height 2em
-            input.name
-                width 95%
+        .help-block
+            font-size 11px
+            line-height 1.3
     
     fieldset.options
         border-radius 5px
index a35ef90..6afc2de 100644 (file)
@@ -47,6 +47,10 @@ all:
                 - graph-model
                 - graph-view
                 - index
+            - vis:
+                - vis-model
+                - vis-view
+                - index
             
 
 # -   suffix: .js