--- /dev/null
+_ = require 'kraken/underscore'
+{ Field, FieldList, FieldView, Scaffold
+} = require 'kraken/scaffold'
+
+
+GraphModel = exports.GraphModel = Backbone.Model.extend do
+ urlRoot : '/graphs'
+
+ initialize : ->
+ name = @get 'name'
+ if name and not (@id or @has 'id')
+ @id = @attributes.id = _.underscored name
+
+ defaults : ->
+ {
+ name : 'Kraken Graph'
+ dataset : 'data/page_views_by_language.csv'
+ options : {}
+ }
+
+
+
+Graph = exports.Graph = Backbone.View.extend do
+ tagName : 'section'
+ className : 'graph'
+
+ events:
+ 'keypress input' : 'onKeypress'
+ 'submit form.settings' : 'onSubmit'
+
+
+ initialize : (o={}) ->
+ @model or= new GraphModel
+
+ @$el.data { model:@model, view:this }
+ @model.on 'change', @render, this
+ @model.on 'destroy', @remove, this
+
+ @viewport = @$el.find '.viewport'
+ @scaffold = new Scaffold do
+ el: @$el.find 'form.settings'
+ @scaffold.collection.reset CHART_OPTIONS_SPEC
+
+ @render()
+
+
+ chartOptions: (values) ->
+ options = @scaffold.collection
+
+ # @chartOptions 'label', 'label value!'
+ if arguments.length > 1
+ [k, v] = arguments
+ values = { "#k": v }
+
+ if values
+ for k, v in values
+ options.get(k)?.setValue v
+ this
+ else
+ options.values()
+
+ render: ->
+ @viewport.empty()
+
+ # Remove old style, as it confuses dygraph after options update
+ @viewport.attr 'style', ''
+ console.log do
+ 'viewport.{ width=%s, height=%s, style=%s }'
+ @viewport.css('width')
+ @viewport.css('height')
+ @viewport.attr 'style'
+ console.log 'options:', JSON.stringify @chartOptions()
+
+ @chart?.destroy()
+ @chart = new Dygraph do
+ @viewport.0
+ 'data/page_views_by_language.csv'
+ @chartOptions()
+
+ onKeypress: (evt) ->
+ $(evt.target).submit() if evt.keyCode is 13
+
+ onSubmit: ->
+ console.log 'Graph.onSubmit!'
+ @render()
+ false
+
+ toString: ->
+ "Graph()"
+
+
+
+
+
+
+
--- /dev/null
+_ = require 'kraken/underscore'
+op = require 'kraken/util/op'
+
+
+
+Field = exports.Field = Backbone.Model.extend do # {{{
+ idAttribute : 'name'
+
+ initialize: ->
+ @set 'value', @get('default'), {+silent} if not @has 'value'
+
+ defaults: ->
+ {
+ name : ''
+ type : 'String'
+ default : null
+ desc : ''
+ category : 'General'
+ tags : []
+ examples : []
+ }
+
+ getParser: (type) ->
+ type or= @get 'type'
+ t = _ type.toLowerCase()
+
+ parser = op.toStr
+ if t.startsWith 'integer'
+ parser = op.toInt
+ if t.startsWith 'float'
+ parser = op.toFloat
+ if t.startsWith 'boolean'
+ parser = op.toBool
+ if t.startsWith 'object' or t.startsWith 'array'
+ parser = op.toObject
+ if t.startsWith 'function'
+ parser = (fn) -> eval "(#fn)"
+
+ # TODO: handle 'or' by returning an array of parsers
+ parser
+
+
+ getValue: ->
+ @getParser() @get 'value'
+
+ setValue: (v, options) ->
+ def = @get 'default'
+ if not v and def == null
+ val = null
+ else
+ val = @getParser()(v)
+ @set 'value', val, options
+
+ clearValue: ->
+ @set 'value', @get('default')
+
+ isDefault: ->
+ @get('value') is @get('default')
+
+# }}}
+
+
+FieldList = exports.FieldList = Backbone.Collection.extend do # {{{
+ model : Field
+
+ /**
+ *
+ */
+ values: ->
+ _.synthesize do
+ @models.filter -> not it.isDefault()
+ -> [ it.get('name'), it.getValue() ]
+
+ # @reduce do
+ # (acc, field) ->
+ # k = field.get 'name'
+ # v = field.getValue()
+ # if k and not field.isDefault() and v?
+ # acc[k] = v
+ # acc
+ # {}
+
+# }}}
+
+
+### Views
+
+FieldView = exports.FieldView = Backbone.View.extend do # {{{
+ tagName : 'div'
+ className : 'field'
+
+ events :
+ 'blur .value' : 'update'
+ 'submit .value' : 'update'
+
+
+
+ initialize: ->
+ @$el.data { model:@model, view:this }
+ @model.on 'change', @render, this
+ @model.on 'destroy', @remove, this
+
+ update: ->
+ val = @$el.find('.value').val()
+ current = @model.get 'value'
+ return if val is current
+
+ console.log "#this.update( #current -> #val )"
+ @model.setValue val, {+silent}
+
+ render: ->
+ return @remove() if @model.get 'hidden'
+
+ name = @model.get 'name'
+ id = _.camelize name
+ label = _.humanize name
+ @$el.html """
+ <label class="name" for="#id">#label</label>
+ <input class="value" type="text" id="#id" name="#id">
+ """
+ # @$el.find '.value' .attr 'value', @model.get 'value'
+ @$el.find '.value' .val @model.get 'value'
+ this
+
+ remove: ->
+ @$el.remove()
+ this
+
+ clear: ->
+ @model.destroy()
+ this
+
+ toString: ->
+ "FieldView(#{@model.id})"
+
+# }}}
+
+
+# There are several special options that, if passed, will be attached directly to the view:
+# model, collection, el, id, className, tagName, attributes
+
+Scaffold = exports.Scaffold = Backbone.View.extend do # {{{
+ tagName : 'form'
+ className : 'scaffold'
+
+ collectionType : FieldList
+ subviewType : FieldView
+
+
+ initialize: ->
+ _.bindAll this, 'addOne', 'addAll'
+ # @subviews = []
+
+ CollectionType = @collectionType
+ @collection or= new CollectionType
+ @collection.on 'add', @addOne
+ @collection.on 'reset', @addAll
+ # @collection.on 'all', @render
+
+ @$el.addClass @className
+ .data { model:@collection, view:this }
+ .attr { action:'/save', method:'get' }
+
+
+ addOne: (field) ->
+ SubviewType = @subviewType
+ view = new SubviewType model:field
+ # @subviews.push view
+ @$el.append view.render().el
+ view
+
+ addAll: ->
+ # _.invoke @subviews, 'remove'
+ # @subviews = []
+ @collection.each @addOne
+ this
+
+# }}}
+
+
- name: width
type: Integer
default: 480
- color-cycle
- multi-scale
- value-axis-formatters
+
- name: height
type: Integer
default: 320
- color-cycle
- multi-scale
- value-axis-formatters
+
- name: annotationClickHandler
type: function(annotation, point, dygraph, event)
default: null
- handler
examples:
- annotation
+
- name: annotationDblClickHandler
type: function(annotation, point, dygraph, event)
default: null
- handler
examples:
- annotation
+
- name: annotationMouseOutHandler
type: function(annotation, point, dygraph, event)
default: null
- handler
examples:
- annotation
+
- name: annotationMouseOverHandler
type: function(annotation, point, dygraph, event)
default: null
- handler
examples:
- annotation
+
- name: displayAnnotations
type: Boolean
default: false
- annotations
examples:
- annotation-gviz
+
- name: avoidMinZero
type: Boolean
default: false
- axes
examples:
- avoidMinZero
+
- name: axis
type: String or Object
default: null
- steps
- two-axes-vr
- value-axis-formatters
+
- name: axisLabelColor
type: String
default: black
category: Axes
tags:
- axes
+
- name: axisLabelFontSize
type: Integer
default: 14
category: Axes
tags:
- axes
+
- name: axisLabelFormatter
type: function(number or Date, granularity, opts, dygraph)
- default: Depends on the data type
+ default: null
desc: Function to call to format the tick values that appear along an axis. This is usually set on
a per-axis basis. The first parameter is either a number (for a numeric axis) or a Date object
(for a date axis). The second argument specifies how fine-grained the axis is. For date axes,
- x-axis-formatter
- y-axis-formatter
- value-axis-formatters
+
- name: axisLabelWidth
type: Integer
default: 50
tags:
- axes
- labels
+
- name: axisLineColor
type: String
default: black
- axes
examples:
- demo
+
- name: axisLineWidth
type: Float
default: 0.3
category: Axes
tags:
- axes
+
- name: axisTickSize
type: Number
default: '3.0'
category: Axes
tags:
- axes
+
- name: dateWindow
type: Array of two Dates or numbers
- default: Full range of the input is shown
+ default: null
desc: Initially zoom in on a section of the graph. Is of the form [earliest, latest], where earliest/latest
are milliseconds since epoch. If the data for the x-axis is numeric, the values in dateWindow
- must also be numbers.
+ must also be numbers. By default, the full range of the input is shown.
category: Axes
tags:
- axes
- link-interaction
- synchronize
- zoom
+
- name: drawXAxis
type: Boolean
default: true
- axes
examples:
- unboxed-spark
+
- name: drawYAxis
type: Boolean
default: true
examples:
- drawing
- unboxed-spark
+
- name: includeZero
type: Boolean
default: false
- no-range
- numeric-gviz
- small-range-zero
+
- name: logscale
type: Boolean
default: false
examples:
- logscale
- stock
+
- name: panEdgeFraction
type: Float
default: null
- interactive elements
examples:
- zoom
+
- name: pixelsPerLabel
type: Integer
- default: 60 (x-axis) or 30 (y-axes)
+ default: null
desc: Number of pixels to require between each x- and y-label. Larger values will yield a sparser
- axis with fewer ticks. This is set on a per-axis basis.
+ axis with fewer ticks. This is set on a per-axis basis. By default, values are 60 (x-axis) or 30 (y-axes).
category: Axes
tags:
- axes
- grid
examples:
- value-axis-formatters
+
- name: ticker
type: "function(min, max, pixels, opts, dygraph, vals) -> [{v: ..., label: ...}, ...]"
- default: Dygraph.dateTicker or Dygraph.numericTicks
+ default: null
desc: This lets you specify an arbitrary function to generate tick marks on an axis. The tick marks
are an array of (value, label) pairs. The built-in functions go to great lengths to choose good
tick marks so, if you set this option, you'll most likely want to call one of them and modify
- the result. See dygraph-tickers.js for an extensive discussion. This is set on a per-axis basis.
+ the result. By default, uses Dygraph.dateTicker or Dygraph.numericTicks, but see
+ dygraph-tickers.js for an extensive discussion. This is set on a per-axis basis.
category: Axes
tags:
- axes
+
- name: valueRange
type: Array of two numbers
- default: Full range of the input is shown
+ default: null
desc: Explicitly set the vertical range of the graph to [low, high]. This may be set on a per-axis
- basis to define each y-axis separately.
+ basis to define each y-axis separately. By default, the full range of the input is shown.
category: Axes
tags:
- axes
- synchronize
- zoom
- two-axes-vr
+
- name: xAxisHeight
type: Integer
default: null
category: Axes
tags:
- axes
+
- name: xAxisLabelWidth
type: Integer
default: 50
examples:
- x-axis-formatter
- value-axis-formatters
+
- name: yAxisLabelWidth
type: Integer
default: 50
- multi-scale
- two-axes-vr
- value-axis-formatters
+
- name: delimiter
type: String
default: ','
category: CSV parsing
tags:
- csv parsing
+
- name: xValueParser
type: function(str) -> number
- default: parseFloat() or Date.parse()*
+ default: null
desc: A function which parses x-values (i.e. the dependent series). Must return a number, even when
the values are dates. In this case, millis since epoch are used. This is used primarily for parsing
CSV data. *=Dygraphs is slightly more accepting in the dates which it will parse. See code for
category: CSV parsing
tags:
- csv parsing
+
- name: clickCallback
type: function(e, x, points)
default: null
- callbacks
examples:
- callback
+
- name: drawCallback
type: function(dygraph, is_initial)
default: null
- is-zoomed-ignore-programmatic-zoom
- synchronize
- zoom
+
- name: highlightCallback
type: function(event, x, points,row)
default: null
examples:
- callback
- crosshair
+
- name: underlayCallback
type: function(canvas, area, dygraph)
default: null
- linear-regression-fractions
- linear-regression
- underlay-callback
+
- name: unhighlightCallback
type: function(event)
default: null
examples:
- callback
- crosshair
+
- name: zoomCallback
type: function(minDate, maxDate, yRanges)
default: null
- callback
- is-zoomed-ignore-programmatic-zoom
- zoom
+
- name: title
type: String
default: null
- multi-scale
- range-selector
- temperature-sf-ny
+
- name: titleHeight
type: Integer
default: 18
- chart labels
examples:
- styled-chart-labels
+
- name: xLabelHeight
type: Integer
default: 18
category: Chart labels
tags:
- chart labels
+
- name: xlabel
type: String
default: null
- demo
- styled-chart-labels
- multi-scale
+
- name: y2label
type: String
default: null
examples:
- two-axes
- two-axes-vr
+
- name: yLabelWidth
type: Integer
default: 18
category: Chart labels
tags:
- chart labels
+
- name: ylabel
type: String
default: null
- range-selector
- temperature-sf-ny
- two-axes-vr
+
- name: file
type: String (URL of CSV or CSV), GViz DataTable or 2D Array
- default: (set when constructed)
+ default: null
desc: Sets the data being displayed in the chart. This can only be set when calling updateOptions;
it cannot be set from the constructor. For a full description of valid data formats, see the Data
Formats page.
examples:
- drawing
- dygraph-many-points-benchmark
+
- name: connectSeparatedPoints
type: Boolean
default: false
examples:
- connect-separated
- independent-series
+
- name: drawPoints
type: Boolean
default: false
- linear-regression-fractions
- linear-regression
- per-series
+
- name: fillGraph
type: Boolean
default: false
- fillGraph
- two-axes
- steps
+
- name: pointSize
type: Integer
default: 1
- data line display
examples:
- per-series
+
- name: stackedGraph
type: Boolean
default: false
- data line display
examples:
- stacked
+
- name: stepPlot
type: Boolean
default: false
- avoidMinZero
- steps
- y-axis-formatter
+
- name: strokePattern
type: Array
default: null
- data line display
examples:
- per-series
+
- name: strokeWidth
type: Integer
default: 1
- per-series
- unboxed-spark
- styled-chart-labels
+
- name: visibility
type: Array of booleans
default: true
- color-visibility
- no-visibility
- visibility
+
- name: colorSaturation
type: Float (0.0 - 1.0)
default: 1.0
category: Data Series Colors
tags:
- data series colors
+
- name: colorValue
type: Float (0.0 - 1.0)
default: 1.0
category: Data Series Colors
tags:
- data series colors
+
- name: colors
type: Array
- default: (see description)
+ default: null
desc: List of colors for the data series. These can be of the form "#AABBCC" or "rgb(255,100,200)"
or "yellow", etc. If not specified, equally-spaced points around a color wheel are used.
category: Data Series Colors
- demo
- reverse-y-axis
- color-cycle
+
- name: fillAlpha
type: Float (0.0 - 1.0)
default: 0.15
tags:
- data series colors
- error bars
+
- name: timingName
type: String
default: null
- debugging
examples:
- dygraph-many-points-benchmark
+
- name: pixelsPerXLabel
type: Integer
- default: (missing)
+ default: null
desc: 'Prefer axes { x: { pixelsPerLabel } }'
category: Deprecated
tags:
- deprecated
+
- name: pixelsPerYLabel
type: Integer
- default: (missing)
+ default: null
desc: 'Prefer axes: { y: { pixelsPerLabel } }'
category: Deprecated
tags:
- deprecated
examples:
- spacing
+
- name: xAxisLabelFormatter
- type: (missing)
- default: (missing)
+ type: function
+ default: null
desc: 'Prefer axes { x: { axisLabelFormatter } }'
category: Deprecated
tags:
- deprecated
+
- name: xValueFormatter
- type: (missing)
- default: (missing)
+ type: function
+ default: null
desc: 'Prefer axes: { x: { valueFormatter } }'
category: Deprecated
tags:
- deprecated
+
- name: yAxisLabelFormatter
- type: (missing)
- default: (missing)
+ type: function
+ default: null
desc: 'Prefer axes: { y: { axisLabelFormatter } }'
category: Deprecated
tags:
- deprecated
+
- name: yValueFormatter
- type: (missing)
- default: (missing)
+ type: function
+ default: null
desc: 'Prefer axes: { y: { valueFormatter } }'
category: Deprecated
tags:
examples:
- labelsKMB
- multi-scale
+
- name: customBars
type: Boolean
default: false
- stock
- range-selector
- temperature-sf-ny
+
- name: errorBars
type: Boolean
default: false
- underlay-callback
- visibility
- zoom
+
- name: fractions
type: Boolean
default: false
examples:
- fractions
- linear-regression-fractions
+
- name: sigma
type: Float
default: 2.0
category: Error Bars
tags:
- error bars
+
- name: wilsonInterval
type: Boolean
default: true
category: Error Bars
tags:
- error bars
+
- name: drawXGrid
type: Boolean
default: true
examples:
- demo
- unboxed-spark
+
- name: drawYGrid
type: Boolean
default: true
examples:
- drawing
- unboxed-spark
+
- name: gridLineColor
- type: red, blue
+ type: String
default: rgb(128,128,128)
- desc: The color of the gridlines.
+ desc: The color of the gridlines. This can be of the form "#AABBCC" or "rgb(255,100,200)" or "yellow".
category: Grid
tags:
- grid
examples:
- drawing
- grid_dot
+
- name: gridLineWidth
type: Float
default: 0.3
category: Grid
tags:
- grid
+
- name: animatedZooms
type: Boolean
default: false
examples:
- highlighted-region
- link-interaction
+
- name: highlightCircleSize
type: Integer
default: 3
- grid_dot
- per-series
- unboxed-spark
+
- name: interactionModel
+ hidden: true
type: Object
- default: '...'
+ default: null
desc: 'TODO(konigsberg): document this'
category: Interactive Elements
tags:
examples:
- drawing
- interaction
+
- name: pointClickCallback
type: function(e, point)
default: null
examples:
- annotation
- callback
+
- name: rangeSelectorHeight
type: Integer
default: 40
- interactive elements
examples:
- range-selector
+
- name: rangeSelectorPlotFillColor
type: String
default: '#A7B1C4'
- interactive elements
examples:
- range-selector
+
- name: rangeSelectorPlotStrokeColor
type: String
default: '#808FAB'
- interactive elements
examples:
- range-selector
+
- name: showRangeSelector
type: Boolean
default: false
- interactive elements
examples:
- range-selector
+
- name: hideOverlayOnMouseOut
type: Boolean
default: true
- interactive elements
examples:
- gviz-selection
+
- name: labels
type: Array
- default: '["X", "Y1", "Y2", ...]*'
+ default: null
desc: A name for each data series, including the independent (X) series. For CSV files and DataTable
objections, this is determined by context. For raw data, this must be specified. If it is not,
- default values are supplied and a warning is logged.
+ default values are supplied and a warning is logged. By default, labels roughly follow
+ ["X", "Y1", "Y2", ...]*
category: Legend
tags:
- legend
- multi-scale
- two-axes-vr
- value-axis-formatters
+
- name: labelsDiv
type: DOM element or string
default: null
- label-div
- reverse-y-axis
- unboxed-spark
+
- name: labelsDivStyles
- type: '{}'
+ type: Object
default: null
desc: 'Additional styles to apply to the currently-highlighted points div. For example, { ''font-weight'':
''bold'' } will make the labels bold.'
- styled-chart-labels
- range-selector
- temperature-sf-ny
+
- name: labelsDivWidth
type: Integer
default: 250
examples:
- customLabel
- noise
+
- name: labelsSeparateLines
type: Boolean
default: false
- customLabel
- demo
- reverse-y-axis
+
- name: labelsShowZeroValues
type: Boolean
default: true
- legend
examples:
- label-div
+
- name: legend
type: String
default: onmouseover
- multi-scale
- range-selector
- temperature-sf-ny
+
- name: showLabelsOnHighlight
type: Boolean
default: true
- interactive elements
examples:
- callback
+
- name: rightGap
type: Integer
default: 5
category: Overall display
tags:
- overall display
+
- name: rollPeriod
type: Integer >= 1
default: 1
- visibility
- range-selector
- temperature-sf-ny
+
- name: showRoller
type: Boolean
default: false
- underlay-callback
- range-selector
- temperature-sf-ny
+
- name: digitsAfterDecimal
type: Integer
default: 2
- value display/formatting
examples:
- number-display
+
- name: labelsKMB
type: Boolean
default: false
- two-axes
- reverse-y-axis
- two-axes-vr
+
- name: labelsKMG2
type: Boolean
default: false
- value display/formatting
examples:
- labelsKMB
+
- name: maxNumberWidth
type: Integer
default: 6
- value display/formatting
examples:
- number-display
+
- name: sigFigs
type: Integer
default: null
- value display/formatting
examples:
- number-display
+
- name: valueFormatter
type: function(num or millis, opts, dygraph)
- default: Depends on the type of your data.
+ default: null
desc: Function to provide a custom display format for the values displayed on mouseover. This does
not affect the values that appear on tick marks next to the axes. To format those, see axisLabelFormatter.
This is usually set on a per-axis basis. For date axes, you can call new Date(millis) to get a
- Date object. opts is a function you can call to access various options (e.g. opts('labelsKMB')).
+ Date object. opts is a function you can call to access various options (e.g. opts('labelsKMB')). Default
+ formatter will depend on the type of your data.
category: Value display/formatting
tags:
- value display/formatting
examples:
- y-axis-formatter
- value-axis-formatters
+
- name: isZoomedIgnoreProgrammaticZoom
type: Boolean
default: false