From: dsc Date: Thu, 8 Mar 2012 01:46:04 +0000 (-0800) Subject: Adds redraw and save buttons. X-Git-Url: http://git.less.ly:3516/?a=commitdiff_plain;h=bf7bf6922f5a1aaea1f0b01ea663f6d860926465;p=limn-bak.git Adds redraw and save buttons. --- diff --git a/kraken-ui.tmproj b/kraken-ui.tmproj deleted file mode 100644 index 66b50f6..0000000 --- a/kraken-ui.tmproj +++ /dev/null @@ -1,75 +0,0 @@ - - - - - currentDocument - lib/main.co - documents - - - expanded - - name - kraken-ui - regexFileFilter - !(?x: lib/version.js|package\.json |license\.md | \.(png|jpg|gif|ico|psd|ai|zip|tar|gz | [oa]|dylib|fla|py[co]|mako\.py|pch|cm[oix]|cache|(tm|xcode)proj)|(fish(_read)?_history|fishd\..*)|/Icon\r|/svn-commit(\.[2-9])?\.tmp|/\.(?!(git|svn|npm)ignore|htaccess|gitmodules)[^/]*)$ - regexFolderFilter - !.*/(?x: tmp/dygraphs | data | static/(vendor|tmp)|www/js/kraken | var|target|node_modules|html-template|bin-debug | \.((?!git-hooks)[^/]+) | .*\.(egg-info|framework|app|(pbx?|xcode)proj|xcode|bundle) | CVS|_darcs|_MTN|\{arch\}|blib | .*~\.nib )$ - selected - - sourceDirectory - - - - children - - expanded - - name - source - - - fileHierarchyDrawerWidth - 217 - metaData - - lib/main.co - - caret - - column - 11 - line - 10 - - firstVisibleColumn - 0 - firstVisibleLine - 0 - - www/layout.jade - - caret - - column - 63 - line - 7 - - firstVisibleColumn - 0 - firstVisibleLine - 0 - - - openDocuments - - lib/main.co - www/layout.jade - - showFileHierarchyDrawer - - windowFrame - {{0, 0}, {1342, 1058}} - - diff --git a/lib/base.co b/lib/base.co index 602ce71..27788f4 100644 --- a/lib/base.co +++ b/lib/base.co @@ -158,6 +158,10 @@ BaseView = exports.BaseView = Backbone.View.extend do # {{{ toString : -> "#{@ctorName}(model=#{@model})" -# }}} +# Proxy model methods +<[ get set unset toJSON toKV toURL ]> + .forEach (methodname) -> + BaseView::[methodname] = -> @model[methodname].apply @model, arguments +# }}} diff --git a/lib/server/server.co b/lib/server/server.co index 2b0edb7..4bf161b 100755 --- a/lib/server/server.co +++ b/lib/server/server.co @@ -107,9 +107,9 @@ app.configure -> app.use express.static STATIC # Serve directory listings - app.use express.directory WWW - app.use express.directory VAR - app.use express.directory STATIC + # app.use express.directory WWW + # app.use express.directory VAR + # app.use express.directory STATIC app.use express.errorHandler do dumpExceptions : true diff --git a/lib/template/graph.jade b/lib/template/graph.jade index df5272d..9a3dd6b 100644 --- a/lib/template/graph.jade +++ b/lib/template/graph.jade @@ -11,41 +11,45 @@ section.graph(id=graph_id) .viewport .graph-label - .tabbable - ul.nav.subnav.nav-pills - li: h3 Graph - li.active: a(href="#graph-#{graph_id}-info", data-toggle="tab") Info - li: a(href="#graph-#{graph_id}-data", data-toggle="tab") Data - li: a(href="#graph-#{graph_id}-options", data-toggle="tab") Options - - .tab-content - .graph-info-pane.tab-pane.active(id="graph-#{graph_id}-info") - .row-fluid - .half.control-group - label.slug.control-label(for='slug') Slug - .controls - input.span3.slug(type='text', id='slug', name='slug', placeholder='graph_slug', value=slug) - p.help-block The slug uniquely identifies this graph and will be displayed in the URL. - .half.control-group - .row-fluid - .half.control-group - label.width.control-label(for='width') Width - .controls - input.span1.width(type='text', id='width', name='width', value=width) - p.help-block Choosing 'auto' will size the graph to the viewport bounds. - .half.control-group - label.height.control-label(for='height') Height - .controls: input.span1.height(type='text', id='height', name='height', value=height) - - .graph-data-pane.tab-pane(id="graph-#{graph_id}-data") - .row-fluid - label.dataset.control-label(for='dataset') Data Set - .controls - input.span3.dataset(type='text', id='dataset', name='dataset', placeholder='URL to dataset file', value=dataset) - p.help-block This dataset filename will soon be replaced by a friendly UI. - - .graph-options-pane.tab-pane(id="graph-#{graph_id}-options") + .row-fluid + .graph-settings.tabbable + //- nav.navbar: div.navbar-inner: div.container + nav + ul.nav.subnav.nav-pills + li: h3 Graph + li.active: a(href="#graph-#{graph_id}-info", data-toggle="tab") Info + li: a(href="#graph-#{graph_id}-data", data-toggle="tab") Data + li: a.graph-options-tab(href="#graph-#{graph_id}-options", data-toggle="tab") Options + li.graph-controls + input.redraw-button.btn(type="button", value="Redraw") + input.load-button.btn(type="button", value="Load") + input.save-button.btn-success(type="button", value="Save") - - + .tab-content + .graph-info-pane.tab-pane.active(id="graph-#{graph_id}-info") + .row-fluid + .half.control-group + label.slug.control-label(for='slug') Slug + .controls + input.span3.slug(type='text', id='slug', name='slug', placeholder='graph_slug', value=slug) + p.help-block The slug uniquely identifies this graph and will be displayed in the URL. + .half.control-group + .row-fluid + .half.control-group + label.width.control-label(for='width') Width + .controls + input.span1.width(type='text', id='width', name='width', value=width) + p.help-block Choosing 'auto' will size the graph to the viewport bounds. + .half.control-group + label.height.control-label(for='height') Height + .controls: input.span1.height(type='text', id='height', name='height', value=height) + + .graph-data-pane.tab-pane(id="graph-#{graph_id}-data") + .row-fluid + label.dataset.control-label(for='dataset') Data Set + .controls + input.span3.dataset(type='text', id='dataset', name='dataset', placeholder='URL to dataset file', value=dataset) + p.help-block This dataset filename will soon be replaced by a friendly UI. + + .graph-options-pane.tab-pane(id="graph-#{graph_id}-options") diff --git a/lib/vis/vis-view.co b/lib/vis/vis-view.co index 8e3e86c..c72e94e 100644 --- a/lib/vis/vis-view.co +++ b/lib/vis/vis-view.co @@ -19,14 +19,26 @@ _ = require 'kraken/underscore' * - Graph metadata, such as name, description, slug */ VisView = exports.VisView = BaseView.extend do # {{{ - FILTER_CHART_OPTIONS : <[ file labels visibility colors dateWindow ticker timingName axisLabelFormatter valueFormatter xAxisLabelFormatter yAxisLabelFormatter xValueFormatter yValueFormatter xValueParser ]> - __bind__ : <[ resizeViewport render renderAll onReady formatter axisFormatter ]> + FILTER_CHART_OPTIONS : <[ + file labels visibility colors dateWindow ticker timingName xValueParser + axisLabelFormatter xAxisLabelFormatter yAxisLabelFormatter + valueFormatter xValueFormatter yValueFormatter + ]> + __bind__ : <[ + render renderAll resizeViewport + formatter axisFormatter + onReady onModelChange onScaffoldChange onFirstClickRenderOptionsTab + ]> + __debounce__: <[ render renderAll ]> ctorName : 'VisView' tagName : 'section' className : 'graph' template : require 'kraken/template/graph' events: + 'click .redraw-button' : 'render' + 'click .save-button' : 'save' + # 'click .load-button' : 'load' 'keypress form.details input[type="text"]' : 'onKeypress' 'keypress form.options .value' : 'onKeypress' 'submit form.details' : 'onDetailsSubmit' @@ -42,24 +54,22 @@ VisView = exports.VisView = BaseView.extend do # {{{ BaseView::initialize ... # console.log "#this.initialize!" - for name of <[ render renderAll ]> + for name of @__debounce__ @[name] = _.debounce @[name], DEBOUNCE_RENDER # Resize graph on window resize + # Note: can't debounce the method itself, as the debounce wrapper returns undefined $ root .on 'resize', _.debounce(@resizeViewport, DEBOUNCE_RENDER) @id = _.domize 'graph', (@model.id or @model.cid) @model.on 'destroy', @remove, this @model.on 'change', @render, this - @model.on 'change:dataset', ~> - changes = @model.changedAttributes() - console.log 'VisModel.changed( dataset ) ->', JSON.stringify changes - @chart.updateOptions file:that if changes?.dataset - @model.on 'change:options', ~> - changes = @model.changedAttributes() - console.log 'VisModel.changed( options ) ->', JSON.stringify changes - @chartOptions that, {+silent} if changes?.options + @model.on 'change:dataset', @onModelChange + @model.on 'change:options', @onModelChange + + # Rerender the options boxes once the tab is visible + @$el.on 'click', '.graph-options-tab', @onFirstClickRenderOptionsTab @viewport = @$el.find '.viewport' @@ -67,9 +77,7 @@ VisView = exports.VisView = BaseView.extend do # {{{ @$el.find '.graph-options-pane' .append @scaffold.el @scaffold.collection.reset that if o.graph_spec - @scaffold.on 'change', (scaffold, value, key, field) ~> - # console.log "scaffold.change!", key, value - @model.setOption key, value, {+silent} #unless field.isDefault() + @scaffold.on 'change', @onScaffoldChange options = @model.get 'options', {} @chartOptions options, {+silent} @@ -78,17 +86,22 @@ VisView = exports.VisView = BaseView.extend do # {{{ _.delay @onReady, DEBOUNCE_RENDER - onReady: -> - console.log "#this.ready!" - @ready = @scaffold.ready = true - @change() - @renderAll() - change: -> @model.change() @scaffold.invoke 'change' this + save: -> + console.log "#this.save!" + $.ajax do + url : '/graph/save' + type : 'POST' + data : @toJSON() + success : (response) -> + console.log 'saved!' + error : (err) -> + console.error "error!", arguments + chartOptions: (values, opts) -> # Handle @chartOptions(k, v, opts) @@ -109,13 +122,12 @@ VisView = exports.VisView = BaseView.extend do # {{{ delete opts[k] opts - /** * Resizes chart according to the model's width and height. * @return { width, height } */ resizeViewport: -> - modelW = width = @model.get 'width' + modelW = width = @model.get 'width' modelH = height = @model.get 'height' return { width, height } unless @ready @@ -140,40 +152,29 @@ VisView = exports.VisView = BaseView.extend do # {{{ - axisFormatter: (n, granularity, opts, g) -> - @formatter n, opts, g - - formatter: (n, opts, g) -> - return n if n instanceof Date - sigFigs = opts 'sigFigs' - maxW = opts 'maxNumberWidth' - digits = opts 'digitsAfterDecimal' - v = Dygraph.round_ n, digits - # Dygraph.floatFormat n, sigFigs - # console.log n, "->", v, "?= %#{maxW}.#{digits}g (sigFigs=#sigFigs)" - v - - render: -> return this unless @ready - size = @resizeViewport() + dataset = @model.get 'dataset' + size = @resizeViewport() + + # XXX: use @model.changedAttributes() to calculate what to update options = @chartOptions() #import size options import do labelsDiv : @$el.find '.graph-label' .0 # axisLabelFormatter : @axisFormatter # valueFormatter : @formatter - dataset = @model.get 'dataset' - console.log "#this.render!", dataset - _.dump options, 'options' + # console.log "#this.render!", dataset + # _.dump options, 'options' + # Always rerender the chart to sidestep the case where we need to push defaults into + # dygraphs to reset the current option state. @chart?.destroy() @chart = new Dygraph do @viewport.0 dataset options - # unless @chart # @chart = new Dygraph do # @viewport.0 @@ -183,13 +184,7 @@ VisView = exports.VisView = BaseView.extend do # {{{ # @chart.updateOptions options # @chart.resize size - # path = String(root.location?.path or '/') - data = @toJSON() - title = @model.get('name', root.document?.title or '') - url = @toURL() - # console.log 'History.pushState', JSON.stringify(data), title, url - History.pushState data, title, url - + @updateURL() this renderAll: -> @@ -200,6 +195,57 @@ VisView = exports.VisView = BaseView.extend do # {{{ @render() this + /** + * Update the page URL using HTML5 History API + */ + updateURL: -> + data = @toJSON() + title = @model.get('name', root.document?.title or '') + url = @toURL() + # console.log 'History.pushState', JSON.stringify(data), title, url + History.pushState data, title, url + + + + ### Formatters {{{ + + axisFormatter: (n, granularity, opts, g) -> + @formatter n, opts, g + + formatter: (n, opts, g) -> + return n if n instanceof Date + sigFigs = opts 'sigFigs' + maxW = opts 'maxNumberWidth' + digits = opts 'digitsAfterDecimal' + v = Dygraph.round_ n, digits + # Dygraph.floatFormat n, sigFigs + # console.log n, "->", v, "?= %#{maxW}.#{digits}g (sigFigs=#sigFigs)" + v + + + ### }}} + ### Event Handlers {{{ + + onReady: -> + console.log "#this.ready!" + @ready = @scaffold.ready = true + @change() + @renderAll() + + onModelChange: -> + changes = @model.changedAttributes() + # console.log 'VisModel.changed( options ) ->', JSON.stringify changes + @chart.updateOptions file:that if changes?.dataset + @chartOptions that, {+silent} if changes?.options + + onScaffoldChange: (scaffold, value, key, field) -> + # console.log "scaffold.change!", key, value + @model.setOption key, value, {+silent} #unless field.isDefault() + + onFirstClickRenderOptionsTab: -> + @$el.off 'click', '.graph-options-tab', @onFirstClickRenderOptionsTab + @scaffold.render() + onKeypress: (evt) -> $(evt.target).submit() if evt.keyCode is 13 @@ -216,14 +262,7 @@ VisView = exports.VisView = BaseView.extend do # {{{ @render() false - toJSON: -> - @model.toJSON() - - toKV: -> - @model.toKV.apply @model, arguments - - toURL: -> - @model.toURL() + # }}} toString: -> "#{@ctorName}(#{@model})" # }}} diff --git a/www/css/graph.styl b/www/css/graph.styl index 2835b6c..ebf30a3 100644 --- a/www/css/graph.styl +++ b/www/css/graph.styl @@ -7,17 +7,7 @@ section.graph * position relative - .nav - li h3 - line-height 14px - margin 2px - padding 8px 12px - border-radius 5px - li - margin-right 4px - .tab-content - padding 0.5em - + /* * * * Chart & Viewport * * * {{{ */ .graph-label position absolute z-index 100 @@ -40,7 +30,33 @@ section.graph margin-bottom 1.5em overflow hidden + /* }}} */ + + + /* * * * Subnav & Tabs * * * {{{ */ + .graph-settings.tabbable + .nav + li h3 + line-height 14px + margin 2px + padding 8px 12px + border-radius 5px + li + margin-right 4px + + .tab-content + padding 0.5em + + .graph-controls + float right + + input[type="button"] + min-width 5em + margin 0 0.5em + text-align center + + /* * * * Graph Details * * * {{{ */ form.details position relative @@ -66,7 +82,10 @@ section.graph .help-block font-size 11px line-height 1.3 + /* }}} */ + + /* * * * Chart Options * * * {{{ */ .options fieldset border 0px @@ -192,6 +211,8 @@ section.graph background-color $bg_color /* }}} */ + + /* }}} End Chart Options */ diff --git a/www/css/layout.styl b/www/css/layout.styl index f4c23a0..244ed1b 100644 --- a/www/css/layout.styl +++ b/www/css/layout.styl @@ -3,6 +3,9 @@ @import 'text' +.clearer + clearfix() + header, footer, #content position relative @@ -44,7 +47,7 @@ header, footer, #content color white background #AF2A31 -nav +nav#main-nav absolute top right 16px height 100%