*/
DataSet = exports.DataSet = BaseModel.extend do # {{{
urlRoot : '/datasets'
+ ready : false
/**
* @type DataSourceList
*/
- sources : []
+ sources : null
/**
* @type MetricList
*/
- metrics : []
+ metrics : null
constructor: function DataSet
initialize : ->
BaseModel::initialize ...
- @sources = new DataSourceList @attributes.sources
- @metrics = new MetricList @attributes.metrics
+ @sources = new DataSourceList
+ if @attributes.metrics
+ @metrics = that.columns = new MetricList that.columns
defaults : ->
- sources : [] # XXX: needed? metrics now implies this info
- metrics : []
- # lines : []
+ palette : null
+ lines : []
+ metrics :
+ defaults : {}
+ columns : []
+
+
+ load: (opts={}) ->
+ return this if @ready and not opts.force
+ @wait()
+ @trigger 'load', this
+ Seq()
+ .seq ~>
+ @ready = true
+ @trigger 'ready', this
+ @unwait() # terminates the `load` wait
+ this
/**
@$el.on 'click', '.graph-options-tab', @onFirstClickRenderOptionsTab
### Graph Data UI
- @data = @addSubview '.graph-data-pane', new DataView { model:@model.get('dataset'), graph_id:@id }
+ @data = @addSubview '.graph-data-pane', new DataView { model:@model.get('data'), graph_id:@id }
@$el.find '.graph-data-pane' .append @data.render().el
@data
.on 'change', @onDataChange, this
@checkWaiting()
render: ->
- return this unless @ready
+ return this unless @ready and not @_rendering
+ @_rendering = true
@wait()
- @checkWaiting() # fix up the spinner element as the DOM is now settled
+ @checkWaiting()
@renderDetails()
@attachSubviews()
# _.invoke @subviews, 'render'
@updateURL()
@trigger 'render', this
@unwait()
+ @_rendering = false
this
renderAll: ->
fs = require 'fs'
-Seq = require 'seq'
+path = require 'path'
+{existsSync:exists} = path
+
+_ = require 'underscore'
+yaml = require 'js-yaml'
findit = require 'findit'
-Controller = require '../controller'
+Seq = require 'seq'
-YAML_EXT_PAT = /\.ya?ml$/i
+Controller = require '../controller'
+EXT_PAT = /\.[^\.]*$/i
+YAML_EXT_PAT = /\.ya?ml$/i
+YAML_OR_JSON_PAT = /\.(json|ya?ml)$/i
/**
-> super ...
+
+ toFile: (id) -> "#{@dataDir}/#id.json"
+
/**
- * Returns a JSON listing of the datasource metadata files.
+ * Auto-load :id for related requests.
+ */
+ autoload: (id, cb) ->
+ file = @toFile id
+ parser = JSON.parse
+
+ yamlFile = file.replace /\.json$/i, '.yaml'
+ if exists yamlFile
+ file = yamlFile
+ parser = yaml.load
+
+ err, data <- fs.readFile file, 'utf8'
+ if 'ENOENT' is err?.code
+ return cb null, {}
+ if err
+ console.error "DataSourceController.autoload(#id, #{typeof cb}) -->\nerr"
+ return cb err
+ try
+ cb null, parser data
+ catch err
+ console.error "DataSourceController.autoload(#id, #{typeof cb}) -->\nerr"
+ cb err
+
+ /**
+ * GET /datasources
+ * @returns {Object} JSON listing of the datasource metadata files.
*/
index : (req, res, next) ->
files = findit.sync @dataDir
# fs.readdir @dataDir, (err, files) ->
res.send do
- files.filter -> /\.(json|ya?ml)$/i.test it
+ files.filter -> YAML_OR_JSON_PAT.test it
.map -> "#it".replace YAML_EXT_PAT, '.json'
/**
+ * GET /datasources/:datasource
+ */
+ show: (req, res) ->
+ res.send req.datasource
+ # if req.format is 'json'
+ # res.send req.datasource
+ # else
+ # res.render 'datasource/view'
+
+ /**
* Returns the aggregated JSON content of the datasource metadata files.
*/
allData : (req, res, next) ->
Seq(findit.sync @dataDir)
# .seq ~> @ok findit.sync @dataDir
# .flatten()
- .filter -> /\.(json|ya?ml)$/.test it
+ .filter -> YAML_OR_JSON_PAT.test it
.seq ->
files := @stack.slice()
# console.log 'files:', files
# console.log "#f ok!", data
@ok v
catch err
- console.error "[/data/all] catch! #err"
+ console.error "[/datasources] catch! #err"
console.error err
console.error that if err.stack
res.send { error:String(err), partial_data:data }
.seq -> res.send data
.catch (err) ->
- console.error '[/data/all] catch!'
+ console.error '[/datasources] catch!'
console.error err
console.error that if err.stack
res.send { error:String(err), partial_data:data }