diff --git a/.jshintrc b/.jshintrc index 371d855..af0f07a 100644 --- a/.jshintrc +++ b/.jshintrc @@ -7,7 +7,7 @@ "curly": false, "eqeqeq": true, "immed": true, - "indent": 2, + "indent": false, "latedef": true, "newcap": true, "noarg": true, @@ -20,6 +20,8 @@ "trailing": true, "smarttabs": true, "predef": [ - "angular" + "angular", + "_", + "dc" ] } diff --git a/Gruntfile.js b/Gruntfile.js index 086c652..80504dd 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -5,7 +5,7 @@ module.exports = function(grunt) { // Configurable paths var yoConfig = { - livereload: 35729, + // livereload: 35729, src: 'src', dist: 'dist' }; @@ -63,11 +63,12 @@ module.exports = function(grunt) { ], options: { livereload: yoConfig.livereload - } + }, + tasks: ['jshint:src', 'karma:unit'] }, test: { files: '<%= jshint.test.src %>', - tasks: ['jshint:test', 'qunit'] + tasks: ['jshint:test', 'karma:unit'] } }, connect: { diff --git a/README.md b/README.md index 7e2c48e..8e82fd0 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# angular-dcjs +# angular-dc @@ -6,14 +6,14 @@ Download the [production version][min] or the [development version][max]. -[min]: https://raw.github.com/TomNeyland/jquery-angular-dcjs/master/dist/angular-angular-dcjs.min.js -[max]: https://raw.github.com/TomNeyland/jquery-angular-dcjs/master/dist/angular-angular-dcjs.js +[min]: https://raw.github.com/TomNeyland/jquery-angular-dc/master/dist/angular-angular-dc.min.js +[max]: https://raw.github.com/TomNeyland/jquery-angular-dc/master/dist/angular-angular-dc.js In your web page: ```html - + ``` ## Documentation diff --git a/bower.json b/bower.json index 7b1b878..df259be 100644 --- a/bower.json +++ b/bower.json @@ -1,11 +1,16 @@ { - "name": "angular-dcjs", + "name": "angular-dc", "version": "0.0.1", "dependencies": {}, "devDependencies": { "angular": "latest", "angular-mocks": "latest", "jquery": "latest", - "lodash": "~2.4.1" + "lodash": "~2.4.1", + "dcjs": "master", + "crossfilter": "~1.3.0" + }, + "resolutions": { + "crossfilter": "~1.3.0" } } diff --git a/dist/angular-dcjs.js b/dist/angular-dcjs.js index e69de29..3806f13 100644 --- a/dist/angular-dcjs.js +++ b/dist/angular-dcjs.js @@ -0,0 +1,9 @@ +'use strict'; +angular.module('angulaDc', []).directive('dcChart', function () { + return { + restrict: 'EAC', + scope: {}, + link: function (scope, iElement, iAttrs) { + } + }; +}); \ No newline at end of file diff --git a/dist/angular-dcjs.min.js b/dist/angular-dcjs.min.js index d4c2217..d822ca2 100644 --- a/dist/angular-dcjs.min.js +++ b/dist/angular-dcjs.min.js @@ -1,7 +1,8 @@ /** - * angular-dcjs + * angular-dc * @version v0.0.1 - 2013-12-27 - * @link https://github.com/TomNeyland/angular-dcjs + * @link https://github.com/TomNeyland/angular-dc * @author Tom Neyland <> * @license Apache License, http://www.opensource.org/licenses/Apache */ +"use strict";angular.module("angulaDc",[]).directive("dcChart",function(){return{restrict:"EAC",scope:{},link:function(){}}}); \ No newline at end of file diff --git a/karma.conf.js b/karma.conf.js index 2b1dc19..aabaf2c 100644 --- a/karma.conf.js +++ b/karma.conf.js @@ -12,6 +12,11 @@ module.exports = function(config) { 'bower_components/angular/angular.js', 'bower_components/jquery/jquery.js', 'bower_components/angular-mocks/angular-mocks.js', + 'bower_components/lodash/dist/lodash.js', + 'bower_components/crossfilter/crossfilter.js', + 'bower_components/d3/d3.js', + 'bower_components/dcjs/dc.js', + 'bower_components/dcjs/dc.css', 'src/*.js', 'test/spec/*.js' ], diff --git a/package.json b/package.json index b066ae4..d2558ae 100644 --- a/package.json +++ b/package.json @@ -1,12 +1,12 @@ { - "name": "angular-dcjs", + "name": "angular-dc", "version": "0.0.1", - "description": "angular-dcjs", + "description": "angular-dc", "keywords": [ "angular" ], - "homepage": "https://github.com/TomNeyland/angular-dcjs", - "bugs": "https://github.com/TomNeyland/angular-dcjs/issues", + "homepage": "https://github.com/TomNeyland/angular-dc", + "bugs": "https://github.com/TomNeyland/angular-dc/issues", "author": { "name": "Tom Neyland", "email": "", @@ -14,7 +14,7 @@ }, "repository": { "type": "git", - "url": "https://github.com/TomNeyland/angular-dcjs.git" + "url": "https://github.com/TomNeyland/angular-dc.git" }, "licenses": [ { @@ -44,6 +44,7 @@ "karma-requirejs": "~0.1.0", "karma-coffee-preprocessor": "~0.1.0", "karma-phantomjs-launcher": "~0.1.0", - "karma": "~0.10.2" + "karma": "~0.10.2", + "grunt-contrib-qunit": "~0.3.0" } } diff --git a/src/angular-dc.js b/src/angular-dc.js new file mode 100644 index 0000000..56c6edb --- /dev/null +++ b/src/angular-dc.js @@ -0,0 +1,106 @@ +'use strict'; + +angular.module('angulaDc', []) + +.directive('dcChart', function() { + + var defaultOptions = { + width: 200, + height: 200 + }; + + function setupChart(scope, iElement, iAttrs) { + + + var chartElement = iElement[0], + chartTypeName = iAttrs.dcChart || iAttrs.chartType, + chartGroupName = iAttrs.chartGroup || undefined; + + var chartFactory = dc[chartTypeName]; + + var chart = chartFactory(chartElement, chartGroupName); + + // all chart options are exposed via a function + var validOptions = _(chart).functions().value(); + console.log(validOptions); + + var objOptions = getOptionsFromObject(scope, validOptions); + var attrOptions = getOptionsFromAttrs(scope, iAttrs, validOptions); + var scopeOptions = getOptionsFromScope(scope, validOptions); + + var options = _({}) + .extend(defaultOptions, + objOptions, + attrOptions, + scopeOptions) + .value(); + + console.log(_.keys(options), options); + chart.options(options); + + return chart; + + } + + function getOptionsFromObject(scope, validOptions) { + var config = scope.config(); + if (!_.isObject(config)) { + config = {}; + } + return config; + } + + function getOptionsFromAttrs(scope, iAttrs, validOptions) { + return _(iAttrs.$attr) + .keys() + .intersection(validOptions) + .map(function(key) { + var value; + try { + value = scope.$parent.$eval(iAttrs[key]); + } catch (e) { + value = iAttrs[key]; + } + return [key, value]; + }) + .zipObject() + .value(); + } + + function getOptionsFromScope(scope, validOptions) { + return _(scope).keys() + .intersection(validOptions) + .map(function(key) { + return [key, _.result(scope, key)] + }) + .zipObject() + .value(); + } + + return { + restrict: 'EAC', + scope: { + group: '&', + dimension: '&', + width: '=', + height: '=', + config: '&', + }, + template: '', + link: function(scope, iElement, iAttrs) { + + var chart = setupChart(scope, iElement, iAttrs); + + scope.$watch('options', function(oldValue, newValue) { + if (oldValue === newValue) { + return; + } + chart.options(newValue); + }); + + chart.render(); + + } + }; + +}); diff --git a/test/spec/angular-dc.js b/test/spec/angular-dc.js new file mode 100644 index 0000000..90a26ee --- /dev/null +++ b/test/spec/angular-dc.js @@ -0,0 +1,51 @@ +'use strict'; + +describe('Module: angulaDc', function () { + var scope, $sandbox, $compile, $timeout; + + // load the controller's module + beforeEach(module('angulaDc')); + + beforeEach(inject(function ($injector, $rootScope, _$compile_, _$timeout_) { + scope = $rootScope; + $compile = _$compile_; + $timeout = _$timeout_; + + $sandbox = $('
').appendTo($('body')); + })); + + afterEach(function() { + $sandbox.remove(); + scope.$destroy(); + }); + + var cf = crossfilter(); + var d = cf.dimension(function(){return "test"}); + var g = d.group(function(){return "bar"}); + var templates = { + 'default': { + scope: {d:d, g:g}, + element: '' + } + }; + + function compileDirective(template) { + template = template ? templates[template] : templates['default']; + angular.extend(scope, template.scope || templates['default'].scope); + var $element = $(template.element).appendTo($sandbox); + $element = $compile($element)(scope); + scope.$digest(); + return $element; + } + + it('chart elements should contain a single svg element', function () { + var elm = compileDirective(); + expect(elm.children().length).toBe(1); + }); + + // it('chart elements should be 350px wide', function () { + // var elm = compileDirective(); + // expect(elm[0].children()).toBe(350); + // }); + +});