From 419c16c251d7ba945dfb73d15c782c9ec7c9644e Mon Sep 17 00:00:00 2001 From: declerambaul Date: Mon, 25 Jun 2012 14:37:02 +0200 Subject: [PATCH] Added a rudimentary bar chart type --- data/graphs/d3-test-bar.json | 127 ++++++++++++++++++++++++++ data/graphs/d3-test-line.json | 145 +++++++++++++++++++++++++++++ data/graphs/d3-test.json | 145 ----------------------------- lib/chart/type/d3/d3-bar-chart-type.co | 155 +++++++++++++++++++++++++++++++- lib/chart/type/d3/index.co | 4 +- www/d3-test-bar.jade | 39 ++++++++ www/d3-test-line.jade | 39 ++++++++ www/d3-test.jade | 39 -------- www/modules.yaml | 2 +- www/schema/d3/d3-bar.yaml | 9 ++ 10 files changed, 515 insertions(+), 189 deletions(-) create mode 100644 data/graphs/d3-test-bar.json create mode 100644 data/graphs/d3-test-line.json delete mode 100644 data/graphs/d3-test.json create mode 100644 www/d3-test-bar.jade create mode 100644 www/d3-test-line.jade delete mode 100644 www/d3-test.jade create mode 100644 www/schema/d3/d3-bar.yaml diff --git a/data/graphs/d3-test-bar.json b/data/graphs/d3-test-bar.json new file mode 100644 index 0000000..e8970d7 --- /dev/null +++ b/data/graphs/d3-test-bar.json @@ -0,0 +1,127 @@ +{ + "options": { + "animatedZooms": true, + "avoidMinZero": false, + "axis": null, + "axisLabelColor": "#666666", + "axisLabelFontSize": 11, + "axisLabelFormatter": null, + "axisLabelWidth": 50, + "axisLineColor": "#AAAAAA", + "axisLineWidth": 0.3, + "axisTickSize": 3, + "colorSaturation": 1, + "colorValue": 0.5, + "colors": ["#FF0097", "#EF8158", "#83BB32", "#182B53", "#4596FF", "#553DC9", "#AD3238", "#00FFBC", "#F1D950"], + "connectSeparatedPoints": false, + "customBars": false, + "dateWindow": null, + "delimiter": ",", + "digitsAfterDecimal": 2, + "displayAnnotations": false, + "drawPoints": true, + "drawXAxis": true, + "drawXGrid": true, + "drawYAxis": true, + "drawYGrid": true, + "errorBars": false, + "file": null, + "fillAlpha": 0.15, + "fillGraph": false, + "fractions": false, + "gridLineColor": "#D8D8D8", + "gridLineWidth": 0.3, + "hideOverlayOnMouseOut": false, + "highlightCircleSize": 4, + "includeZero": false, + "interactionModel": null, + "isZoomedIgnoreProgrammaticZoom": false, + "labels": null, + "labelsDiv": null, + "labelsDivStyles": null, + "labelsDivWidth": 250, + "labelsKMB": true, + "labelsKMG2": false, + "labelsSeparateLines": true, + "labelsShowZeroValues": true, + "legend": "always", + "logscale": true, + "maxNumberWidth": 30, + "panEdgeFraction": null, + "pixelsPerLabel": null, + "pixelsPerXLabel": null, + "pixelsPerYLabel": null, + "pointSize": 1, + "rangeSelectorHeight": 40, + "rangeSelectorPlotFillColor": "#A7B1C4", + "rangeSelectorPlotStrokeColor": "#808FAB", + "rightGap": 20, + "rollPeriod": 1, + "showLabelsOnHighlight": true, + "showRangeSelector": false, + "showRoller": false, + "sigFigs": null, + "sigma": 2, + "stackedGraph": false, + "stepPlot": false, + "strokePattern": null, + "strokeWidth": 4, + "ticker": null, + "title": null, + "titleHeight": 18, + "valueFormatter": null, + "valueRange": null, + "visibility": null, + "wilsonInterval": true, + "xAxisHeight": null, + "xAxisLabelFormatter": null, + "xAxisLabelWidth": 55, + "xLabelHeight": 18, + "xValueFormatter": null, + "xValueParser": null, + "xlabel": null, + "y2label": null, + "yAxisLabelFormatter": null, + "yAxisLabelWidth": 50, + "yLabelWidth": 18, + "yValueFormatter": null, + "ylabel": null + }, + "slug": "d3-test", + "name": "", + "desc": "", + "notes": "", + "width": "auto", + "height": 320, + "parents": ["root"], + "data": { + "palette": null, + "lines": [], + "metrics": [{ + "index": 0, + "label": "Target Editors!!!!!", + "type": "int", + "timespan": { + "start": null, + "end": null, + "step": null + }, + "disabled": false, + "source_id": "rc_active_editors_target", + "source_col": 2, + "color": "#00b2ff", + "visible": true, + "format_value": null, + "format_axis": null, + "transforms": [], + "scale": 1 + }] + }, + "callout": { + "enabled": true, + "metric_idx": 0, + "label": "" + }, + "chartType": "d3-bar", + "id": "d3-test" +} diff --git a/data/graphs/d3-test-line.json b/data/graphs/d3-test-line.json new file mode 100644 index 0000000..15446c4 --- /dev/null +++ b/data/graphs/d3-test-line.json @@ -0,0 +1,145 @@ +{ + "options": { + "animatedZooms": true, + "avoidMinZero": false, + "axis": null, + "axisLabelColor": "#666666", + "axisLabelFontSize": 11, + "axisLabelFormatter": null, + "axisLabelWidth": 50, + "axisLineColor": "#AAAAAA", + "axisLineWidth": 0.3, + "axisTickSize": 3, + "colorSaturation": 1, + "colorValue": 0.5, + "colors": ["#FF0097", "#EF8158", "#83BB32", "#182B53", "#4596FF", "#553DC9", "#AD3238", "#00FFBC", "#F1D950"], + "connectSeparatedPoints": false, + "customBars": false, + "dateWindow": null, + "delimiter": ",", + "digitsAfterDecimal": 2, + "displayAnnotations": false, + "drawPoints": true, + "drawXAxis": true, + "drawXGrid": true, + "drawYAxis": true, + "drawYGrid": true, + "errorBars": false, + "file": null, + "fillAlpha": 0.15, + "fillGraph": false, + "fractions": false, + "gridLineColor": "#D8D8D8", + "gridLineWidth": 0.3, + "hideOverlayOnMouseOut": false, + "highlightCircleSize": 4, + "includeZero": false, + "interactionModel": null, + "isZoomedIgnoreProgrammaticZoom": false, + "labels": null, + "labelsDiv": null, + "labelsDivStyles": null, + "labelsDivWidth": 250, + "labelsKMB": true, + "labelsKMG2": false, + "labelsSeparateLines": true, + "labelsShowZeroValues": true, + "legend": "always", + "logscale": true, + "maxNumberWidth": 30, + "panEdgeFraction": null, + "pixelsPerLabel": null, + "pixelsPerXLabel": null, + "pixelsPerYLabel": null, + "pointSize": 1, + "rangeSelectorHeight": 40, + "rangeSelectorPlotFillColor": "#A7B1C4", + "rangeSelectorPlotStrokeColor": "#808FAB", + "rightGap": 20, + "rollPeriod": 1, + "showLabelsOnHighlight": true, + "showRangeSelector": false, + "showRoller": false, + "sigFigs": null, + "sigma": 2, + "stackedGraph": false, + "stepPlot": false, + "strokePattern": null, + "strokeWidth": 4, + "ticker": null, + "title": null, + "titleHeight": 18, + "valueFormatter": null, + "valueRange": null, + "visibility": null, + "wilsonInterval": true, + "xAxisHeight": null, + "xAxisLabelFormatter": null, + "xAxisLabelWidth": 55, + "xLabelHeight": 18, + "xValueFormatter": null, + "xValueParser": null, + "xlabel": null, + "y2label": null, + "yAxisLabelFormatter": null, + "yAxisLabelWidth": 50, + "yLabelWidth": 18, + "yValueFormatter": null, + "ylabel": null + }, + "slug": "d3-test", + "name": "", + "desc": "", + "notes": "", + "width": "auto", + "height": 320, + "parents": ["root"], + "data": { + "palette": null, + "lines": [], + "metrics": [{ + "index": 0, + "label": "", + "type": "int", + "timespan": { + "start": null, + "end": null, + "step": null + }, + "disabled": false, + "source_id": "rc_active_editors_count", + "source_col": 1, + "color": "#00b2ff", + "visible": true, + "format_value": null, + "format_axis": null, + "transforms": [], + "scale": 1 + }, { + "index": 1, + "label": "", + "type": "int", + "timespan": { + "start": null, + "end": null, + "step": null + }, + "disabled": false, + "source_id": "rc_new_article_count", + "source_col": 1, + "color": "rgb(213,62,79)", + "visible": true, + "format_value": null, + "format_axis": null, + "transforms": [], + "scale": 1 + }] + }, + "callout": { + "enabled": true, + "metric_idx": 0, + "label": "" + }, + "chartType": "d3-line", + "id": "d3-test" +} diff --git a/data/graphs/d3-test.json b/data/graphs/d3-test.json deleted file mode 100644 index 15446c4..0000000 --- a/data/graphs/d3-test.json +++ /dev/null @@ -1,145 +0,0 @@ -{ - "options": { - "animatedZooms": true, - "avoidMinZero": false, - "axis": null, - "axisLabelColor": "#666666", - "axisLabelFontSize": 11, - "axisLabelFormatter": null, - "axisLabelWidth": 50, - "axisLineColor": "#AAAAAA", - "axisLineWidth": 0.3, - "axisTickSize": 3, - "colorSaturation": 1, - "colorValue": 0.5, - "colors": ["#FF0097", "#EF8158", "#83BB32", "#182B53", "#4596FF", "#553DC9", "#AD3238", "#00FFBC", "#F1D950"], - "connectSeparatedPoints": false, - "customBars": false, - "dateWindow": null, - "delimiter": ",", - "digitsAfterDecimal": 2, - "displayAnnotations": false, - "drawPoints": true, - "drawXAxis": true, - "drawXGrid": true, - "drawYAxis": true, - "drawYGrid": true, - "errorBars": false, - "file": null, - "fillAlpha": 0.15, - "fillGraph": false, - "fractions": false, - "gridLineColor": "#D8D8D8", - "gridLineWidth": 0.3, - "hideOverlayOnMouseOut": false, - "highlightCircleSize": 4, - "includeZero": false, - "interactionModel": null, - "isZoomedIgnoreProgrammaticZoom": false, - "labels": null, - "labelsDiv": null, - "labelsDivStyles": null, - "labelsDivWidth": 250, - "labelsKMB": true, - "labelsKMG2": false, - "labelsSeparateLines": true, - "labelsShowZeroValues": true, - "legend": "always", - "logscale": true, - "maxNumberWidth": 30, - "panEdgeFraction": null, - "pixelsPerLabel": null, - "pixelsPerXLabel": null, - "pixelsPerYLabel": null, - "pointSize": 1, - "rangeSelectorHeight": 40, - "rangeSelectorPlotFillColor": "#A7B1C4", - "rangeSelectorPlotStrokeColor": "#808FAB", - "rightGap": 20, - "rollPeriod": 1, - "showLabelsOnHighlight": true, - "showRangeSelector": false, - "showRoller": false, - "sigFigs": null, - "sigma": 2, - "stackedGraph": false, - "stepPlot": false, - "strokePattern": null, - "strokeWidth": 4, - "ticker": null, - "title": null, - "titleHeight": 18, - "valueFormatter": null, - "valueRange": null, - "visibility": null, - "wilsonInterval": true, - "xAxisHeight": null, - "xAxisLabelFormatter": null, - "xAxisLabelWidth": 55, - "xLabelHeight": 18, - "xValueFormatter": null, - "xValueParser": null, - "xlabel": null, - "y2label": null, - "yAxisLabelFormatter": null, - "yAxisLabelWidth": 50, - "yLabelWidth": 18, - "yValueFormatter": null, - "ylabel": null - }, - "slug": "d3-test", - "name": "", - "desc": "", - "notes": "", - "width": "auto", - "height": 320, - "parents": ["root"], - "data": { - "palette": null, - "lines": [], - "metrics": [{ - "index": 0, - "label": "", - "type": "int", - "timespan": { - "start": null, - "end": null, - "step": null - }, - "disabled": false, - "source_id": "rc_active_editors_count", - "source_col": 1, - "color": "#00b2ff", - "visible": true, - "format_value": null, - "format_axis": null, - "transforms": [], - "scale": 1 - }, { - "index": 1, - "label": "", - "type": "int", - "timespan": { - "start": null, - "end": null, - "step": null - }, - "disabled": false, - "source_id": "rc_new_article_count", - "source_col": 1, - "color": "rgb(213,62,79)", - "visible": true, - "format_value": null, - "format_axis": null, - "transforms": [], - "scale": 1 - }] - }, - "callout": { - "enabled": true, - "metric_idx": 0, - "label": "" - }, - "chartType": "d3-line", - "id": "d3-test" -} diff --git a/lib/chart/type/d3/d3-bar-chart-type.co b/lib/chart/type/d3/d3-bar-chart-type.co index 347244b..3bcb596 100644 --- a/lib/chart/type/d3/d3-bar-chart-type.co +++ b/lib/chart/type/d3/d3-bar-chart-type.co @@ -5,6 +5,7 @@ d3 = require 'd3' { ChartType, } = require 'kraken/chart/chart-type' +root = do -> this class exports.BarChartType extends ChartType @@ -12,7 +13,7 @@ class exports.BarChartType extends ChartType SPEC_URL : '/schema/d3/d3-bar.json' # NOTE: ChartType.register() must come AFTER `typeName` declaration. - typeName : 'd3-bar' + typeName : 'd3-bar' ChartType.register this @@ -26,7 +27,157 @@ class exports.BarChartType extends ChartType legend : '.graph-legend' - -> super ... + getData: -> + @model.dataset.getColumns() + + + transform: -> + dataset = @model.dataset + options = @model.getOptions() import @determineSize() + options import do + colors : dataset.getColors() + labels : dataset.getLabels() + options + renderChart: (data, viewport, options, lastChart) -> + ### Starting with http://bost.ocks.org/mike/chart/ + + margin = {top: 20, right: 20, bottom: 20, left: 20} + width = 760 + height = 320 + xScale = d3.time.scale() + yScale = d3.scale.linear() + + 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 ] + + # Update the y-scale with the extents of the data. + yScale + .domain d3.extent allValues + .range [ height - margin.top - margin.bottom, 0 ] + + # 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 + + X = (d, i) -> xScale d[0] + Y = (d, i) -> yScale d[1] + + ### Render Bars + barWidth = svg.attr('width')/dates.length + barHeight = (d) -> svg.attr('height')-Y(d) + + bars = frame.selectAll "g.bars" + .data cols.map -> d3.zip dates, it + bars.enter().append "g" + .attr "class", (col, i) -> "metric bars #i" + bars.exit().remove() + + bars.selectAll ".bar" + .data op.first + .enter().append "rect" + .attr "class", "bar" + .attr "x", X + .attr "y", Y + .attr "height", barHeight + .attr "width", -> barWidth + # TODO grab color from graph spec + .attr "fill", "red" + .attr "stroke", "white" + + + ### Mouse Lens + lens = root.lens = frame.selectAll "g.lens" + .data [[]] + gLens = lens.enter().append "g" + .attr "class", "lens" + .style "z-index", 1e9 + gInner = gLens.append "g" + .attr "transform", "translate(1.5em,0)" + gInner.append "circle" + .attr "r", "1.5em" + # .style "opacity", "0.4" + # .style "fill", "white" + .style "fill", "rgba(255, 255, 255, 0.4)" + .style "stroke", "white" + .style "stroke-width", "3px" + gInner.append "text" + .attr "y", "0.5em" + .attr "text-anchor", "middle" + .style "fill", "white" + .style "font", "12px Helvetica" + .style "font-weight", "bold" + + + mf = frame.selectAll "g.mf" + .data ["mf"] + .enter().append "g" + .attr "class", "mf" + .append "text" + .attr "class", "yoyo" + .attr "dx", 50 + .attr "dy", 100 + + + + bars.selectAll ".bar" + .on "mouseover", (d, i) -> + el = root.el = el # DOM element of event + # {r,g,b} = color = d3.rgb options.colors[i] + mf + .transition() + .duration(300) + .ease("exp") + .text "Uh boy, the target would be:"+d[1] + .style "font-size", "25px" + + + .on "mouseout", (d, i) -> + mf + .transition() + .duration(1000) + .text "BUMMER!!!" + .style "font-size", "0px" + + + + # {x:lineX, y:lineY} = root.pt = line.indexToPoint idx + # lens = frame.select "g.lens" + # .attr "transform", "translate(#lineX, #lineY)" + # lens.select "circle" .style "fill", "rgba(#r, #g, #b, 0.4)" + # lens.select "text" .text Y + + + + svg diff --git a/lib/chart/type/d3/index.co b/lib/chart/type/d3/index.co index 5651289..06db1d2 100644 --- a/lib/chart/type/d3/index.co +++ b/lib/chart/type/d3/index.co @@ -1,5 +1,5 @@ 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' +bar = require 'kraken/chart/type/d3/d3-bar-chart-type' -exports import line # import geo import bar +exports import line import bar # import geo diff --git a/www/d3-test-bar.jade b/www/d3-test-bar.jade new file mode 100644 index 0000000..82f0eb5 --- /dev/null +++ b/www/d3-test-bar.jade @@ -0,0 +1,39 @@ +extends layout + +block title + title Edit Graph | Limn + +append styles + mixin css('/vendor/bootstrap-colorpicker/css/colorpicker.css') + mixin css('/vendor/bootstrap-datepicker/css/datepicker.css') + mixin css('graph.css') + // new for SVG + mixin css('chart.css') + mixin css('data.css') + mixin css('isotope.css') + +block main-scripts + script + root = this + + // import all the things, ugly JS-style + d3 = require('d3') + Seq = require('seq') + Backbone = require('backbone') + util = require('kraken/util'); _ = util._; op = util.op + AppView = require('kraken/app').AppView + base = require('kraken/base'); BaseView = base.BaseView; BaseModel = base.BaseModel; BaseList = base.BaseList + 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') + + // run on DOM-ready + jQuery(function(){ + root.app = new AppView(function(){ + this.model = root.graph = new Graph({ id:'d3-test-bar' }, { parse:true }) + this.view = root.view = new GraphEditView({ model:this.model }) + }); + }); + + diff --git a/www/d3-test-line.jade b/www/d3-test-line.jade new file mode 100644 index 0000000..ab70d61 --- /dev/null +++ b/www/d3-test-line.jade @@ -0,0 +1,39 @@ +extends layout + +block title + title Edit Graph | Limn + +append styles + mixin css('/vendor/bootstrap-colorpicker/css/colorpicker.css') + mixin css('/vendor/bootstrap-datepicker/css/datepicker.css') + mixin css('graph.css') + // new for SVG + mixin css('chart.css') + mixin css('data.css') + mixin css('isotope.css') + +block main-scripts + script + root = this + + // import all the things, ugly JS-style + d3 = require('d3') + Seq = require('seq') + Backbone = require('backbone') + util = require('kraken/util'); _ = util._; op = util.op + AppView = require('kraken/app').AppView + base = require('kraken/base'); BaseView = base.BaseView; BaseModel = base.BaseModel; BaseList = base.BaseList + 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') + + // run on DOM-ready + jQuery(function(){ + root.app = new AppView(function(){ + this.model = root.graph = new Graph({ id:'d3-test-line' }, { parse:true }) + this.view = root.view = new GraphEditView({ model:this.model }) + }); + }); + + diff --git a/www/d3-test.jade b/www/d3-test.jade deleted file mode 100644 index 968e48f..0000000 --- a/www/d3-test.jade +++ /dev/null @@ -1,39 +0,0 @@ -extends layout - -block title - title Edit Graph | Limn - -append styles - mixin css('/vendor/bootstrap-colorpicker/css/colorpicker.css') - mixin css('/vendor/bootstrap-datepicker/css/datepicker.css') - mixin css('graph.css') - // new for SVG - mixin css('chart.css') - mixin css('data.css') - mixin css('isotope.css') - -block main-scripts - script - root = this - - // import all the things, ugly JS-style - d3 = require('d3') - Seq = require('seq') - Backbone = require('backbone') - util = require('kraken/util'); _ = util._; op = util.op - AppView = require('kraken/app').AppView - base = require('kraken/base'); BaseView = base.BaseView; BaseModel = base.BaseModel; BaseList = base.BaseList - 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') - - // 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 }) - }); - }); - - diff --git a/www/modules.yaml b/www/modules.yaml index e571f9a..b74eba7 100644 --- a/www/modules.yaml +++ b/www/modules.yaml @@ -114,7 +114,7 @@ dev: - d3: - d3-line-chart-type # - d3-geo-chart-type - # - d3-bar-chart-type + - d3-bar-chart-type - index - dygraphs - index diff --git a/www/schema/d3/d3-bar.yaml b/www/schema/d3/d3-bar.yaml new file mode 100644 index 0000000..88a3564 --- /dev/null +++ b/www/schema/d3/d3-bar.yaml @@ -0,0 +1,9 @@ +- name: zoom.start + tags: + - interactivity + - zoom + type: Float + default: 1.0 + desc: Initial zoom-level, where 1.0 (100% zoom) shows the full map in the + frame (the default). + -- 1.7.0.4