+d3 = require 'd3'
+ColorBrewer = require 'colorbrewer'
+
+{ _, op,
+} = require 'kraken/util'
+{ ChartType,
+} = require 'kraken/chart'
+
+
+class LineChartType extends ChartType
+ __bind__ : <[ determineSize ]>
+ SPEC_URL : '/schema/d3/d3-line.json'
+
+ # NOTE: ChartType.register() must come AFTER `typeName` declaration.
+ typeName : 'd3-line'
+ ChartType.register this
+
+
+ /**
+ * Hash of role-names to the selector which, when applied to the view,
+ * returns the correct element.
+ * @type Object
+ */
+ roles :
+ viewport : '.viewport'
+ legend : '.graph-legend'
+
+
+
+ -> super ...
+
+ transform: ->
+ dataset = @model.dataset
+ options = @model.getOptions() import @determineSize()
+ options import do
+ colors : dataset.getColors()
+ options
+
+
+ renderChart: (rawData, viewport, options, lastChart) ->
+ viewport.empty()
+
+ ### Starting with http://bost.ocks.org/mike/chart/
+
+
+ # formatDate = d3.time.format("%b %Y")
+ # chart = timeSeriesChart()
+ # .x (d) -> formatDate.parse(d.date)
+ # .y (d) -> +d.price
+ # d3.csv("sp500.csv", (data) ->
+ # d3.select("#example")
+ # .datum(data)
+ # .call(chart)
+
+ margin = {top: 20, right: 20, bottom: 20, left: 20}
+ width = 760
+ height = 320
+ xValue = (d) -> d[0]
+ yValue = (d) -> d[1]
+ xScale = d3.time.scale()
+ yScale = d3.scale.linear()
+ xAxis = d3.svg.axis().scale(xScale).orient("bottom").tickSize(6, 0)
+ X = (d) -> xScale(d[0])
+ Y = (d) -> yScale(d[1])
+ line = d3.svg.line().x(X).y(Y)
+
+
+ chart = (selection) ->
+ selection.each (data) ->
+
+ # Convert data to standard representation greedily
+ # this is needed for nondeterministic accessors.
+ data = data.map (d, i) ->
+ [ xValue.call(data, d, i), yValue.call(data, d, i) ]
+
+
+ # Update the x-scale.
+ xScale
+ .domain d3.extent data, xValue
+ .range [ 0, width - margin.left - margin.right ]
+
+ # Update the y-scale.
+ yScale
+ .domain [ 0, d3.max data, yValue ]
+ .range [ height - margin.top - margin.bottom, 0 ]
+
+ # Select the svg element, if it exists.
+ svg = d3.select(this).selectAll("svg").data([data])
+
+ # Otherwise, create the skeletal chart.
+ gEnter = svg.enter().append("svg").append("g")
+ gEnter.append("path")
+ .attr "class", "line"
+ .style "stroke", (d, i) -> options.colors[i]
+ gEnter.append("g").attr("class", "x axis")
+
+ # Update the outer dimensions.
+ svg .attr("width", width)
+ .attr("height", height)
+
+ # Update the inner dimensions.
+ g = svg.select("g")
+ .attr("transform", "translate(" + margin.left + "," + margin.top + ")")
+
+ # Update the line path.
+ g.select(".line")
+ .attr("d", line)
+
+ # Update the x-axis.
+ g.select(".x.axis")
+ .attr("transform", "translate(0," + yScale.range()[0] + ")")
+ .call(xAxis)
+
+ d3.select viewport.0
+ .datum rawData
+ .call chart
+
+
+
+
+module.exports = exports = LineChartType
\ No newline at end of file
{ _, op,
} = require 'kraken/util'
-{ BaseView,
+{ BaseModel,
} = require 'kraken/base'
-{ Graph,
+{ Graph, GraphList,
} = require 'kraken/graph/graph-model'
* @class
*/
Dashboard = exports.Dashboard = BaseModel.extend do # {{{
- urlRoot : '/dashboards'
+ urlRoot : '/dashboards'
+ graphs : null # GraphList
+ byTab : null # GraphList[]
constructor: function Dashboard
+ @graphs = new GraphList
+ @byTab = []
BaseModel ...
initialize: ->
defaults: ->
name : null
- graphs : []
+ tabs : [ { name:"Main", graph_ids:[] } ]
+
+
+
+
+ addTab: (tabName) ->
+ ...
+
+
+ /**
+ * Look up a tab.
+ *
+ * @param {String|Number} tab Tab name or index.
+ * @returns {Tab} Tab object.
+ */
+ getTab: (tab) ->
+ tabs = @get 'tabs'
+ return tabs[tab] if typeof tab is 'number'
+ _.find tabs, -> it.name is tab
+
+ addGraph: (graph, tabName) ->
+ ...
+
+ getGraphs: (tab) ->
+ ...
# }}}