"?#{@toKV ...}"
     
     toString: ->
-        modelIds = @models
-            .map -> "\"#{it.id ? it.cid}\""
-            .join ', '
-        "#{@getClassName()}[#{@length}](#modelIds)"
+        "#{@getClassName()}[#{@length}]"
+    
+    # toString: ->
+    #     modelIds = @models
+    #         .map -> "\"#{it.id ? it.cid}\""
+    #         .join ', '
+    #     "#{@getClassName()}[#{@length}](#modelIds)"
 # }}}
 
 
 
     hasSubview: (view) ->
         _.any @subviews, ([v]) -> v is view
     
+    invokeSubviews: ->
+        _ _.pluck(@subviews, 0) .invoke ...arguments
+    
     attachSubviews: ->
         for [view, selector] of @subviews
             return unless view
             view.delegateEvents()
         this
     
+    removeAllSubviews: ->
+        @invokeSubviews 'remove'
+        _.pluck @subviews, 0 .forEach @removeSubview, this
+        this
+    
     
     ### Rendering Chain
     
 
         @on 'ready', @onReady, this
         @load()
     
+    onReady: ->
+        dataset = @model
+        @metric_edit_view = @addSubview new MetricEditView  {@graph_id, dataset, @datasources}
+        @metric_edit_view
+            .on 'update',           @onUpdateMetric,      this
+        
+        @dataset_view = @addSubview new DataSetView {@model, @graph_id, dataset, @datasources}
+        @dataset_view
+            .on 'add-metric',       @onMetricsChanged,  this
+            .on 'remove-metric',    @onMetricsChanged,  this
+            .on 'edit-metric',      @editMetric,        this
+        
+        @attachSubviews()
+        this
+    
+    
     
     load: ->
         @wait()
         ds
     
     
-    onReady: ->
-        dataset = @model
-        @metric_edit_view = @addSubview new MetricEditView  {@graph_id, dataset, @datasources}
-        @metric_edit_view
-            .on 'update',           @onUpdateMetric,      this
-        
-        @dataset_view = @addSubview new DataSetView {@model, @graph_id, dataset, @datasources}
-        @dataset_view
-            .on 'add-metric',       @onMetricsChanged,  this
-            .on 'remove-metric',    @onMetricsChanged,  this
-            .on 'edit-metric',      @editMetric,        this
-        
-        @attachSubviews()
-        this
-    
-    
     toTemplateLocals: ->
         attrs = _.clone @model.attributes
         { $, _, op, @model, view:this, @graph_id, @datasources, } import attrs
     
     editMetric: (metric) ->
         @metric_edit_view.editMetric metric
+        @onMetricsChanged()
     
     onMetricsChanged: ->
-        @$el.css 'min-height', @dataset_view.$el.height()
+        # console.log 'onMetricsChanged!'
+        @$el.css 'min-height', Math.max @dataset_view.$el.height(), @metric_edit_view.$el.height()
     
     onUpdateMetric: ->
         @renderSubviews()
 
     initialize : ->
         BaseModel::initialize ...
         @sources = new DataSourceList
-        if @attributes.metrics
-            @metrics = that.columns = new MetricList that.columns
+        mx = @attributes.metrics or= {}
+        @metrics = new MetricList mx.columns
+        @on 'change:metrics', @onMetricChange, this
     
     
     defaults : ->
         m
     
     
+    onMetricChange: ->
+        mx = @get 'metrics'
+        cols = mx.columns.map (col) ->
+            _.clone(col) import mx.defaults
+        @metrics.reset cols
+    
 # }}}
 
 
         BaseView ...
     
     initialize: ->
-        @graph_id = @options.graph_id
+        {@graph_id, @datasources, @dataset} = @options
         BaseView::initialize ...
         @views_by_cid = {}
-        @model.metrics.on 'add', @addMetric, this
+        @addAllMetrics()
+        @model.metrics.on 'add',    @addMetric,         this
+        @model.metrics.on 'remove', @removeMetric,      this
+        @model.metrics.on 'reset',  @addAllMetrics,     this
     
     
     newMetric: ->
     addMetric: (metric) ->
         console.log "#this.addMetric!", metric
         if metric.view
-            @removeSubview metric.view
+            @removeSubview metric.view.remove()
             delete @views_by_cid[metric.cid]
         
         view = @addSubview new DataSetMetricView {model:metric, @graph_id}
         @trigger 'add-metric', metric, view, this
         view
     
+    removeMetric: (metric) ->
+        console.log "#this.removeMetric!", metric
+        if view = metric.view
+            @removeSubview view.remove()
+            delete @views_by_cid[metric.cid]
+            @trigger 'remove-metric', metric, view, this
+        metric.view
+    
+    addAllMetrics: ->
+        @removeAllSubviews()
+        @model.metrics.each @addMetric, this
+        this
+    
     editMetric: (metric) ->
         console.log "#this.editMetric!", metric
         if metric instanceof [jQuery.Event, Event]
 
     urlRoot  : '/datasources'
     model    : DataSource
     
-    constructor: function DataSourceList
-        BaseList ...
-    
-    initialize : ->
-        BaseList::initialize ...
+    constructor: function DataSourceList then BaseList ...
+    initialize : -> BaseList::initialize ...
     
     
 # }}}
+
+
+/* * * *  DataSource Cache  * * * */
+
+DataSource import do
+    CACHE : new DataSourceList
+    
+    register: (model) ->
+        # console.log "#{@CACHE}.register(#{model.id or model.get('id')})", model
+        if @CACHE.contains model
+            @CACHE.remove model, {+silent}
+        @CACHE.add model
+        model
+    
+    get: (id) ->
+        @CACHE.get id
+    
+    lookup: (id, cb) ->
+        # console.log "#{@CACHE}.lookup(#id, #{typeof cb})"
+        if @CACHE.get id
+            cb null, that
+        else
+            Cls = this
+            @register new Cls {id}
+                .on 'ready', -> cb null, it
+    
+
+_.bindAll DataSource, 'register', 'get', 'lookup'
+
+
 
     model    : Metric
     
     constructor: function MetricList then BaseList ...
+    initialize: -> BaseList::initialize ...
+    
 # }}}
 
     __bind__  : <[
         render renderAll stopAndRender stopAndRenderAll resizeViewport wait unwait checkWaiting
         numberFormatter numberFormatterHTML
-        onReady onSync onModelChange onScaffoldChange onFirstClickRenderOptionsTab
+        onReady onSync onModelChange onScaffoldChange 
+        onFirstClickRenderOptionsTab onFirstClickRenderDataTab
     ]>
     __debounce__: <[ render renderAll ]>
     tagName   : 'section'
         @scaffold.on 'change', @onScaffoldChange
         @chartOptions @model.getOptions(), {+silent}
         
+        @$el.on 'click', '.graph-data-tab', @onFirstClickRenderDataTab
+        
         # Rerender the options boxes once the tab is visible
         # Can't use @events because we need to bind before registering
         @$el.on 'click', '.graph-options-tab', @onFirstClickRenderOptionsTab
         @$el.off 'click', '.graph-options-tab', @onFirstClickRenderOptionsTab
         @scaffold.render()
     
+    onFirstClickRenderDataTab: ->
+        # @$el.off 'click', '.graph-data-tab', @onFirstClickRenderDataTab
+        _.delay do
+            ~> @data.onMetricsChanged()
+            100
+    
     onKeypress: (evt) ->
         $(evt.target).submit() if evt.keyCode is 13
     
 
         @chartType = ChartType.lookup @get('chartType')
         
         # Insert submodels in place of JSON
-        # @get('dataset')
-        @set 'data', new DataSet(@get('data')), {+silent}
+        # data = @get('data') or @get('dataset')
+        @set 'data', @dataset = new DataSet(@get('data')), {+silent}
         
         @trigger 'init', this
         @load() if opts.autoload
                             next.ok()
                         success : @unwaitAnd (model, res) ~>
                             # console.log "#{this}.fetch() --> success!", res
+                            @dataset.set @get('data')
                             next.ok res
             .seq_ (next) ~>
                 next.ok @get('parents')
         kvo = @toJSON opts
         kvo.parents = JSON.stringify kvo.parents
         delete kvo.slug unless opts.keepSlug
+        delete kvo.data
         
         # console.group 'toKVPairs'
         # console.log '[IN]', JSON.stringify kvo
 
 /* * * *  Visualization Cache for parent-lookup  * * * {{{ */
 
-GRAPH_CACHE = exports.GRAPH_CACHE = new GraphList
-
 Graph import do
-    CACHE : GRAPH_CACHE
+    CACHE : new GraphList
     
     register: (model) ->
         # console.log "#{@CACHE}.register(#{model.id or model.get('id')})", model
 
                     li
                         .graph-spinner
                         h3 Graph
-                    li.active:  a(href="##{graph_id}-tab-info", data-toggle="tab") Info
-                    li:         a(href="##{graph_id}-tab-data", data-toggle="tab") Data
-                    li: a.graph-options-tab(href="##{graph_id}-tab-options", data-toggle="tab") Options
+                    li.active:  a.graph-info-tab(href="##{graph_id}-tab-info", data-toggle="tab") Info
+                    li:         a.graph-data-tab(href="##{graph_id}-tab-data", data-toggle="tab") Data
+                    li:         a.graph-options-tab(href="##{graph_id}-tab-options", data-toggle="tab") Options
                 
             
             //--- Tab Panes ---//
 
                 height 100%
                 display table-cell
                 float none
-                max-width 200px
+                width 200px
             
             .datasource-sources-details
                 display table-cell