{ _, op,
} = require 'kraken/util'
{ ChartType,
-} = require 'kraken/chart'
+} = require 'kraken/chart/chart-type'
-class LineChartType extends ChartType
+class exports.LineChartType extends ChartType
__bind__ : <[ determineSize ]>
SPEC_URL : '/schema/d3/d3-line.json'
+ getData: ->
+ @model.dataset.getColumns()
+
+
transform: ->
dataset = @model.dataset
options = @model.getOptions() import @determineSize()
options
- renderChart: (rawData, viewport, options, lastChart) ->
- viewport.empty()
-
+ renderChart: (data, viewport, options, lastChart) ->
### 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)
+ dates = data[0]
+ cols = data.slice(1)
+
+ # Calculate extents using all the data points (but not dates)
+ # allValues = d3.merge @model.dataset.getDataColumns()
+ allValues = d3.merge cols
+
+
+ # Update the x-scale with the extents of the dates.
+ xScale
+ .domain d3.extent dates
+ .range [ 0, width - margin.left - margin.right ]
- 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)
+ # Update the y-scale with the extents of the data.
+ yScale
+ .domain d3.extent allValues
+ .range [ height - margin.top - margin.bottom, 0 ]
- d3.select viewport.0
- .datum rawData
- .call chart
+ # Select the svg element, if it exists.
+ svg = d3.select viewport.0 .selectAll "svg"
+ .data [cols]
+
+ # ...Otherwise, create the skeletal chart.
+ enterFrame = svg.enter()
+ .append "svg" .append "g"
+ .attr "class", "frame"
+ enterFrame.append "g"
+ .attr "class", "x axis time"
+
+ # Update chart dimensions.
+ svg .attr "width", width
+ .attr "height", height
+ frame = svg.select "g.frame"
+ .attr "transform", "translate(#{margin.left},#{margin.top})"
+
+ # Update the x-axis.
+ xAxis = d3.svg.axis().scale(xScale).orient("bottom").tickSize(6, 0)
+ frame.select ".x.axis.time"
+ .attr "transform", "translate(0,#{yScale.range()[0]})"
+ .call xAxis
+
+ # Create/Update the line paths.
+ lines = frame.selectAll "path.line"
+ .data cols.map -> d3.zip dates, it
+ lines.enter().append "path"
+ .attr "class", "line"
+ lines.exit().remove()
+
+ X = (d, i) -> xScale d[0]
+ Y = (d, i) -> yScale d[1]
+ line = d3.svg.line().x(X).y(Y)
+ # frame.selectAll "path.line"
+ lines.attr "d", line
+ .style "stroke", (col, i) -> options.colors[i]
+
+ svg
-
-module.exports = exports = LineChartType
\ No newline at end of file