Implements colorpicker for metrics.
authordsc <dsc@wikimedia.org>
Mon, 7 May 2012 14:14:22 +0000 (07:14 -0700)
committerdsc <dsc@wikimedia.org>
Mon, 7 May 2012 14:14:22 +0000 (07:14 -0700)
13 files changed:
lib/dataset/data-view.co
lib/dataset/dataset-model.co
lib/dataset/dataset-view.co
lib/dataset/datasource-ui-view.co
lib/dataset/metric-edit-view.co
lib/dataset/metric-model.co
lib/graph/graph-edit-view.co
lib/template/dataset-metric.jade
lib/template/metric-edit.jade
www/css/data.styl
www/graph/edit.jade
www/layout.jade
www/modules.yaml

index 6c8d115..d36cc61 100644 (file)
@@ -33,6 +33,7 @@ DataView = exports.DataView = BaseView.extend do # {{{
         BaseView::initialize ...
         @metric_views = new ViewList
         @datasources = DataSource.getAllSources()
+        # @on 'update',           @onUpdate,      this
         @model.metrics
             .on 'add',          @addMetric,     this
             .on 'remove',       @removeMetric,  this
@@ -83,7 +84,8 @@ DataView = exports.DataView = BaseView.extend do # {{{
         console.log "#this.addMetric!", metric
         return metric if @metric_views.findByModel metric
         view = new MetricEditView {model:metric, @graph_id, dataset:@model, @datasources}
-        view.on 'update', @onUpdateMetric, this
+            .on 'metric-update', @onUpdateMetric, this
+            .on 'metric-change', @onUpdateMetric, this
         @metric_views.push @addSubview view
         metric
     
@@ -110,5 +112,9 @@ DataView = exports.DataView = BaseView.extend do # {{{
         @$el.css 'min-height', newMinHeight
     
     onUpdateMetric: ->
-        @renderSubviews()
+        console.log "#this.onUpdateMetric!"
+        @trigger 'metric-change', @model, this
+        @render()
+    
+    
 # }}}
index bec6098..5d0fa33 100644 (file)
@@ -86,7 +86,7 @@ DataSet = exports.DataSet = BaseModel.extend do # {{{
      * @returns {Array<Date>} The date column.
      */
     getDateColumn: ->
-        dates = @metrics.invoke 'getDateColumn'
+        dates = @metrics.onlyOk().invoke 'getDateColumn'
         maxLen = _.max _.pluck dates, 'length'
         _.find dates, -> it.length is maxLen
     
@@ -94,16 +94,18 @@ DataSet = exports.DataSet = BaseModel.extend do # {{{
      * @returns {Array<Array>} List of all columns except the date column.
      */
     getDataColumns: ->
-        @metrics.invoke 'getData'
+        @metrics.onlyOk().invoke 'getData'
     
     /**
      * @returns {Array<String>} List of column labels.
      */
     getLabels: ->
-        ['Date'].concat @metrics.pluck 'label'
+        [ 'Date' ].concat @metrics.onlyOk().invoke 'getLabel'
     
     # }}}
     
+    getColors: ->
+        @metrics.onlyOk().pluck 'color'
     
     newMetric: ->
         index = @metrics.length
@@ -111,8 +113,9 @@ DataSet = exports.DataSet = BaseModel.extend do # {{{
         m
     
     onMetricChange: ->
+        console.log "#this.onMetricChange! ready=#{@ready}"
         @resetReady()
-        # @metrics.reset @get 'metrics'
+        @metrics.reset @get 'metrics'
         @load()
     
     # TODO: toJSON() must ensure columns in MetricList are ordered by index
index ecdf08b..e19efcb 100644 (file)
@@ -83,8 +83,6 @@ DataSetView = exports.DataSetView = BaseView.extend do # {{{
         @trigger 'edit-metric', metric, view, this
         this
     
-    render: ->
-        this
     
 # }}}
 
@@ -106,12 +104,16 @@ DataSetMetricView = exports.DataSetMetricView = BaseView.extend do # {{{
     initialize: ->
         @graph_id = @options.graph_id
         BaseView::initialize ...
+        @on 'update', @onUpdate, this
     
     
     toTemplateLocals: ->
-        m = @model.toJSON()
+        m = DataSetMetricView.__super__.toTemplateLocals ...
+        
+        # XXX: Icons/classes for visible/disabled?
         m import
             graph_id : @graph_id
+            label    : @model.getLabel()
             viewClasses : _.compact([
                 if @model.isOk() then 'valid'   else 'invalid',
                 if m.visible     then 'visible' else 'hidden',
@@ -127,9 +129,9 @@ DataSetMetricView = exports.DataSetMetricView = BaseView.extend do # {{{
                     "#{ts.start} to #{ts.end} by #{ts.step}"
                 else
                     '&mdash;'
-        
-        # XXX: Icons/classes for visible/disabled?
-        { $, _, op, @model, view:this } import m
+    
+    onUpdate: ->
+        @$ '.col-color' .css 'color', @model.get 'color'
     
 # }}}
 
index 29df057..0a69ba1 100644 (file)
@@ -64,6 +64,6 @@ DataSourceUIView = exports.DataSourceUIView = BaseView.extend do # {{{
         @$ '.source-metrics .datasource-source-metric' .removeClass 'active'
         el.addClass 'active'
         @model.set {source_col, source_id}
-        # @trigger 'edit-metric', @model
+        @trigger 'metric-change', @model, this
     
 # }}}
index 4cbdcf3..f0d787c 100644 (file)
@@ -14,6 +14,7 @@
  * Model is a Metric.
  */
 MetricEditView = exports.MetricEditView = BaseView.extend do # {{{
+    __bind__       : <[ onChange ]>
     tagName        : 'section'
     className      : 'metric-edit-ui'
     template       : require 'kraken/template/metric-edit'
@@ -35,37 +36,56 @@ MetricEditView = exports.MetricEditView = BaseView.extend do # {{{
         this import @options.{graph_id, dataset, datasources}
         @model or= new Metric
         BaseView::initialize ...
+        @on     'attach',       @onAttach,              this
         @datasource_ui_view = new DataSourceUIView {@model, @graph_id, @dataset, @datasources}
         @addSubview @datasource_ui_view
-            .on 'update', ~> @trigger 'update', this
-        # @$ '.metric-datasource' .append @datasource_ui_view.render().el
+            .on 'metric-update', ~> @trigger 'update',  this
+            .on 'metric-change', @onSourceMetricChange, this
     
     
     toTemplateLocals: ->
-        locals = BaseView::toTemplateLocals ...
-        locals import { @graph_id, @dataset, @datasources }
-    
-    # build: ->
-    #     BaseView::build ...
-    #     if @datasource_ui_view
-    #         @$ '.metric-datasource' .append @datasource_ui_view.render().el
-    #     this
+        locals = MetricEditView.__super__.toTemplateLocals ...
+        locals import {
+            @graph_id, @dataset, @datasources
+            placeholder_label: @model.getPlaceholderLabel()
+        }
     
     update: ->
-        color = @model.get 'color'
-        @$ '.color-swatch' .css 'background-color', color
-        @$ '.metric-color' .val color
-        @$ '.metric-label' .val @model.get 'label'
+        MetricEditView.__super__.update ...
+        
+        # Update the color picker
+        @$ '.color-swatch'
+            .data 'color', @model.get 'color'
+            .colorpicker 'update'
         
+        # @$ '.color-swatch' .css 'background-color', color
+        # @$ '.metric-color' .val color
         this
     
-    onChange: ->
+    onAttach: ->
+        console.log "#this.onAttach!"
+        @$ '.color-swatch'
+            .data 'color', @model.get 'color'
+            .colorpicker()
+            .on 'hide', @onChange
+    
+    onChange: (evt) ->
         attrs = @$ 'form.metric-edit-form' .formData()
-        @model.set attrs, {+silent}
-        @trigger 'update', this
+        # attrs.color = that if evt?.color
+        same = _.isEqual @model.attributes, attrs
+        
+        console.log "#this.onChange! (same? #same)"
+        _.dump @model.attributes, 'old', not same
+        _.dump attrs, 'new', not same
+        # _.dump attrs, "#this.onChange! (same? #same)", not same
+        
+        unless _.isEqual @model.attributes, attrs
+            @model.set attrs, {+silent}
+            @trigger 'metric-update', this
     
-    onMetricChange: (metric) ->
-        console.log "#this.onMetricChange!", metric
+    onSourceMetricChange: (metric) ->
+        console.log "#this.onSourceMetricChange!", metric
+        @trigger 'metric-change', @model, this
         this
     
 # }}}
index 0810370..e3b6ce6 100644 (file)
@@ -8,6 +8,7 @@ DataSource = DataSourceList = null
  * @class
  */
 Metric = exports.Metric = BaseModel.extend do # {{{
+    NEW_METRIC_LABEL : 'New Metric'
     urlRoot  : '/metrics'
     
     /**
@@ -16,25 +17,27 @@ Metric = exports.Metric = BaseModel.extend do # {{{
      */
     source : null
     
+    is_def_label : true
+    
     defaults : ->
-        index           : 0
-        label           : 'New Metric'
-        type            : 'int'
-        timespan        : { start:null, end:null, step:null }
-        disabled        : false
+        index            : 0
+        label            : ''
+        type             : 'int'
+        timespan         : { start:null, end:null, step:null }
+        disabled         : false
         
         # DataSource
-        source_id  : null
-        source_col : -1
+        source_id        : null
+        source_col       : -1
         
         # Chart Options
-        color           : null
-        visible         : true
-        format_value    : null
-        format_axis     : null
+        color            : null
+        visible          : true
+        format_value     : null
+        format_axis      : null
         
-        transforms      : []
-        scale           : 1.0
+        transforms       : []
+        scale            : 1.0
     
     
     
@@ -43,8 +46,10 @@ Metric = exports.Metric = BaseModel.extend do # {{{
     
     initialize : ->
         BaseModel::initialize ...
-        @on 'change:source_id',  @load,     this
-        @on 'change:source_col', @updateId, this
+        @is_def_label = @isDefaultLabel()
+        @on 'change:source_id',     @load,          this
+        @on 'change:source_col',    @updateId,      this
+        @on 'change:label',         @updateLabel,   this
         @load()
     
     
@@ -54,6 +59,18 @@ Metric = exports.Metric = BaseModel.extend do # {{{
     getData: ->
         @source.getColumn @get 'source_col'
     
+    getLabel: ->
+        @get('label') or @getPlaceholderLabel()
+    
+    getPlaceholderLabel: ->
+        col  = @get 'source_col'
+        name = "#{@source.get 'shortName'}, #{@source.getColumnName col}" if @source and col > 0
+        name or @NEW_METRIC_LABEL
+    
+    getSourceColumnName: ->
+        col = @get 'source_col'
+        @source.getColumnName col if @source and col > 0
+    
     
     load: (opts={}) ->
         source_id = @get 'source_id'
@@ -75,14 +92,32 @@ Metric = exports.Metric = BaseModel.extend do # {{{
             else
                 console.log "#{this}.load() complete!"
                 @source = source
+                @is_def_label = @isDefaultLabel()
                 @updateId()
                 @triggerReady()
         this
     
     
+    isDefaultLabel: ->
+        label = @get 'label'
+        not label or label is @getSourceColumnName() or label is @NEW_METRIC_LABEL
+    
+    updateLabel: ->
+        return this unless @source
+        label = @get 'label'
+        if not label or @is_def_label
+            @set 'label', ''
+            @is_def_label = true
+        else
+            @is_def_label = @isDefaultLabel()
+        this
+    
     updateId: ->
-        if (source_id = @get('source_id')) and (source_col = @get('source_col'))
+        source_id  = @get 'source_id'
+        source_col = @get 'source_col'
+        if source_id and source_col?
             @id = "#source_id[#source_col]"
+        @updateLabel()
         this
     
     
@@ -91,12 +126,7 @@ Metric = exports.Metric = BaseModel.extend do # {{{
      * attempt to graph unconfigured crap.
      */
     isOk: ->
-        (label = @get('label')) and label is not 'New Metric'
-        and @get('source_id')   and @get('source_col') >= 0
-        and _.every @get('timespan'), op.ok
-    
-    getSourceColumnName: ->
-        @source?.getColumnName @get 'source_col'
+        @source # and _.every @get('timespan'), op.ok
     
 # }}}
 
@@ -114,6 +144,9 @@ MetricList = exports.MetricList = BaseList.extend do # {{{
     comparator: (metric) ->
         metric.get('index') ? Infinity
     
+    onlyOk: ->
+        new MetricList @filter -> it.isOk()
+    
 # }}}
 
 ### FIXME: LOLHACKS ###