From: David Schoonover Date: Wed, 20 Jun 2012 16:00:37 +0000 (-0700) Subject: Auto-load d3 line chart type. X-Git-Url: http://git.less.ly:3516/?a=commitdiff_plain;h=0d8ee5d9aa62c3f0c7f39d671135f1a4b33172ae;p=limn.git Auto-load d3 line chart type. --- diff --git a/lib/chart/chart-type.co b/lib/chart/chart-type.co index d66b435..2030a90 100644 --- a/lib/chart/chart-type.co +++ b/lib/chart/chart-type.co @@ -166,7 +166,7 @@ class exports.ChartType extends ReadyEmitter proto.options_ordered = spec proto.options = _.synthesize spec, -> [it.name, it] proto.ready = true - @emit 'ready', this + @triggerReady() error: ~> console.error "Error loading #{@typeName} spec! #it" this diff --git a/lib/chart/index.co b/lib/chart/index.co index 5a02eb2..a961cba 100644 --- a/lib/chart/index.co +++ b/lib/chart/index.co @@ -1,5 +1,7 @@ -chart_type = require 'kraken/chart/chart-type' +chart_type = require 'kraken/chart/chart-type' chart_option = require 'kraken/chart/option' -dygraphs = require 'kraken/chart/type/dygraphs' +dygraphs = require 'kraken/chart/type/dygraphs' +d3_charts = require 'kraken/chart/type/d3' -exports import chart_type import chart_option import dygraphs +exports import chart_type import chart_option \ + import dygraphs import d3_charts diff --git a/lib/chart/type/d3/d3-bar-chart-type.co b/lib/chart/type/d3/d3-bar-chart-type.co index e1fc007..347244b 100644 --- a/lib/chart/type/d3/d3-bar-chart-type.co +++ b/lib/chart/type/d3/d3-bar-chart-type.co @@ -3,8 +3,30 @@ d3 = require 'd3' { _, op, } = require 'kraken/util' { ChartType, -} = require 'kraken/chart' +} = require 'kraken/chart/chart-type' -exports.foo = 1 +class exports.BarChartType extends ChartType + __bind__ : <[ determineSize ]> + SPEC_URL : '/schema/d3/d3-bar.json' + + # NOTE: ChartType.register() must come AFTER `typeName` declaration. + typeName : 'd3-bar' + 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 ... + + diff --git a/lib/chart/type/d3/d3-geo-chart-type.co b/lib/chart/type/d3/d3-geo-chart-type.co index 26d5ad9..2238b31 100644 --- a/lib/chart/type/d3/d3-geo-chart-type.co +++ b/lib/chart/type/d3/d3-geo-chart-type.co @@ -3,12 +3,12 @@ ColorBrewer = require 'colorbrewer' { _, op, } = require 'kraken/util' { ChartType, -} = require 'kraken/chart' +} = require 'kraken/chart/chart-type' -class GeoWorldChartType extends ChartType +class exports.GeoWorldChartType extends ChartType __bind__ : <[ dygNumberFormatter dygNumberFormatterHTML ]> SPEC_URL : '/schema/d3/d3-geo-world.json' diff --git a/lib/chart/type/d3/d3-line-chart-type.co b/lib/chart/type/d3/d3-line-chart-type.co index 6446686..3646aa5 100644 --- a/lib/chart/type/d3/d3-line-chart-type.co +++ b/lib/chart/type/d3/d3-line-chart-type.co @@ -4,10 +4,10 @@ ColorBrewer = require 'colorbrewer' { _, 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' @@ -31,6 +31,10 @@ class LineChartType extends ChartType + getData: -> + @model.dataset.getColumns() + + transform: -> dataset = @model.dataset options = @model.getOptions() import @determineSize() @@ -39,85 +43,71 @@ class LineChartType extends ChartType 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 diff --git a/lib/chart/type/d3/index.co b/lib/chart/type/d3/index.co index 3a488eb..5651289 100644 --- a/lib/chart/type/d3/index.co +++ b/lib/chart/type/d3/index.co @@ -1,5 +1,5 @@ -bar = require 'kraken/chart/type/d3/d3-bar-chart-type' -geo = require 'kraken/chart/type/d3/d3-geo-chart-type' line = require 'kraken/chart/type/d3/d3-line-chart-type' +# geo = require 'kraken/chart/type/d3/d3-geo-chart-type' +# bar = require 'kraken/chart/type/d3/d3-bar-chart-type' -exports import bar import geo import line +exports import line # import geo import bar diff --git a/lib/util/op.co b/lib/util/op.co index 2fb5172..e434d65 100644 --- a/lib/util/op.co +++ b/lib/util/op.co @@ -24,6 +24,7 @@ module.exports = op = ok : (o) -> o? notOk : (o) -> o!? + ### manipulate function args/arity first : (a) -> a second : (_,a) -> a nth : (n) -> @@ -32,12 +33,24 @@ module.exports = op = case 1 then op.second default -> arguments[n] + # reverse the order of the first two args flip : (fn) -> (a, b) -> arguments[0] = b arguments[1] = a fn.apply this, arguments + # only pass n args + aritize : (fn, cxt, n) -> + [n, cxt] = [cxt, null] if arguments.length < 3 + -> fn.apply cxt ? this, [].slice.call(arguments, 0, n) + + # only pass the first argument + it : (fn, cxt) -> + -> fn.call cxt ? this, it + + + ### reduce-ordered values & accessors khas : (k,o) -> k in o kget : (k,o) -> o[k] diff --git a/www/css/chart.styl b/www/css/chart.styl index b9b7239..8ba548d 100644 --- a/www/css/chart.styl +++ b/www/css/chart.styl @@ -5,7 +5,13 @@ .line fill none stroke #000 - stroke-width 1.5px + stroke-width 3px + .axis + font-size 11px + color #666 + + text + fill #666 diff --git a/www/d3-test.jade b/www/d3-test.jade index b9c1123..968e48f 100644 --- a/www/d3-test.jade +++ b/www/d3-test.jade @@ -26,14 +26,13 @@ block main-scripts ChartType = require('kraken/chart').ChartType data = require('kraken/data'); DataSource = data.DataSource; DataSourceList = data.DataSourceList _graph = require('kraken/graph'); Graph = _graph.Graph; GraphList = _graph.GraphList; GraphEditView = _graph.GraphEditView - LineChartType = require('kraken/chart/type/d3/d3-line-chart-type') + //LineChartType = require('kraken/chart/type/d3/d3-line-chart-type') // run on DOM-ready jQuery(function(){ root.app = new AppView(function(){ this.model = root.graph = new Graph({ id:'d3-test' }, { parse:true }) this.view = root.view = new GraphEditView({ model:this.model }) - this.view.chartType = this.model.chartType = new LineChartType(this.model, this.view); }); }); diff --git a/www/modules.yaml b/www/modules.yaml index 4ee875a..e571f9a 100644 --- a/www/modules.yaml +++ b/www/modules.yaml @@ -113,8 +113,8 @@ dev: - type: - d3: - d3-line-chart-type - - d3-geo-chart-type - - d3-bar-chart-type + # - d3-geo-chart-type + # - d3-bar-chart-type - index - dygraphs - index