├── .gitignore ├── CHANGELOG.md ├── Gruntfile.js ├── README.md ├── acetate.conf.js ├── bower.json ├── dist ├── angular-dimple.js └── angular-dimple.min.js ├── docs └── source │ ├── _banner.html │ ├── assets │ ├── css │ │ ├── base │ │ │ ├── _buttons.scss │ │ │ ├── _code.scss │ │ │ ├── _config.scss │ │ │ ├── _reset.scss │ │ │ └── _tabs.scss │ │ ├── examples.scss │ │ └── style.scss │ ├── img │ │ ├── Angular-Dimple-Logo.svg │ │ ├── area.svg │ │ ├── bar.svg │ │ ├── dots.svg │ │ ├── front.svg │ │ ├── graph.svg │ │ ├── legend.svg │ │ ├── line.svg │ │ ├── ring.svg │ │ ├── scatter-plot.svg │ │ ├── stacked-area.svg │ │ ├── stacked-bar.svg │ │ ├── x.svg │ │ └── y.svg │ └── js │ │ ├── app.js │ │ ├── controllers.js │ │ ├── directives.js │ │ ├── filters.js │ │ ├── services.js │ │ └── tailcoat.js │ ├── data │ ├── example_data.json │ ├── example_data.tsv │ └── simple.json │ ├── documentation │ ├── _content.md │ └── index.html │ ├── examples │ ├── index.html │ └── partials │ │ ├── animation-test.md │ │ ├── area.md │ │ ├── bar-graph.md │ │ ├── expanded-stacked-area.md │ │ ├── homepage-code.md │ │ ├── line-graph.md │ │ ├── ring.md │ │ ├── scatter-plot.md │ │ ├── stacked-area.md │ │ └── stacked-bar-graph.md │ ├── index.html │ └── layouts │ └── _layout.html ├── lib ├── angular-dimple.js ├── area.js ├── bar.js ├── graph.js ├── legend.js ├── line.js ├── r.js ├── ring.js ├── scatter-plot.js ├── stacked-area.js ├── stacked-bar.js ├── x.js └── y.js ├── package.json ├── site └── js │ └── lib │ └── angular-dimple.js └── test ├── e2e └── scenarios.js ├── karma.conf.js ├── protractor-conf.js └── unit ├── controllersSpec.js ├── directivesSpec.js ├── filtersSpec.js └── servicesSpec.js /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .grunt 3 | .sass-cache 4 | node_modules 5 | bower_components 6 | user.js 7 | docs/build 8 | angular-dimple.zip 9 | docs/source/assets/js/lib 10 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Angular-Dimple Changelog 2 | 3 | ## v2.0.1 4 | * Add dist files to releases so bower can find it 5 | 6 | ## v.2.0.0 7 | * Change to to avoid clash with actual html legend element 8 | 9 | ## v.1.1.4 10 | * Fix bug that caused smooshed graphs on Firefox 11 | 12 | ## v1.1.3 13 | * rebuild site 14 | * add `color` attribute on graph.js 15 | 16 | ## v1.1.2 17 | * add default width (100%) 18 | * add default height (100%) 19 | * add default margin (60, 60, 20, 40) 20 | 21 | ## v1.1.1 22 | * add time formats and such 23 | 24 | ## v1.1.0 25 | * add functionality inside ng-repeat 26 | * graphs update live when scope changes 27 | * add ring charts 28 | 29 | ## v1.0.2 30 | * add bower dependencies 31 | 32 | ## v1.0.1 33 | * add bower manifest 34 | * add changelog 35 | * add label attribute to scatter-plots 36 | 37 | ## v1.0.0 38 | * support for graph, axis, and legend 39 | * support for bar, stacked, bar, area, stacked area, line, and scatter-plots 40 | * full documentation 41 | 42 | ## v0.0.1 43 | * alpha release 44 | -------------------------------------------------------------------------------- /Gruntfile.js: -------------------------------------------------------------------------------- 1 | // ┌─────────────┐ 2 | // │ Gruntfile │ 3 | // └─────────────┘ 4 | // Grunt wraps several tasks to ease development 5 | // runs acetate, deploys the site, and tags new releases 6 | var fs = require('fs'); 7 | 8 | // Gets current version description from CHANGELOG.md 9 | function findVersion(log) { 10 | var newVersion = log.split('## v')[1]; 11 | var description = newVersion.substring(5,newVersion.length); 12 | return description; 13 | } 14 | 15 | module.exports = function(grunt) { 16 | var pkg = grunt.file.readJSON('package.json'); 17 | var name = pkg.name; 18 | var repo = pkg.repository.split('github.com/')[1]; 19 | var currentVersion = 'v' + pkg.version; 20 | var log = grunt.file.read('CHANGELOG.md'); 21 | var description = findVersion(log); 22 | 23 | // Javascript banner 24 | var banner = '/*! ' + name + ' - <%= pkg.version %> - <%= grunt.template.today("yyyy-mm-dd") %>\n' + 25 | '* https://github.com/' + repo + '\n' + 26 | '* Licensed ISC */\n'; 27 | 28 | require('load-grunt-tasks')(grunt); 29 | 30 | grunt.initConfig({ 31 | pkg: grunt.file.readJSON('package.json'), 32 | 33 | // Build documentation site 34 | 'acetate': { 35 | build: { 36 | config: 'acetate.conf.js' 37 | }, 38 | watch: { 39 | config: 'acetate.conf.js', 40 | options: { 41 | watch: true, 42 | server: true 43 | } 44 | } 45 | }, 46 | 47 | // Watch sass, images, and javascript 48 | 'watch': { 49 | sass: { 50 | files: ['docs/source/assets/css/**/*'], 51 | tasks: ['sass'] 52 | }, 53 | img: { 54 | files: ['docs/source/assets/img/**/*'], 55 | tasks: ['newer:imagemin'] 56 | }, 57 | js: { 58 | files: ['docs/source/assets/js/**/*', 'lib/**.*'], 59 | tasks: ['lib', 'jshint:docs', 'copy:docs'] 60 | } 61 | }, 62 | 63 | // Build site sass 64 | 'sass': { 65 | expanded: { 66 | options: { 67 | style: 'expanded', 68 | sourcemap: 'none', 69 | loadPath: 'bower_components' 70 | }, 71 | files: { 72 | 'docs/build/assets/css/style.css': 'docs/source/assets/css/style.scss' 73 | } 74 | } 75 | }, 76 | 77 | // Optimize images 78 | 'imagemin': { 79 | doc: { 80 | files: [{ 81 | expand: true, 82 | cwd: 'docs/source/assets/img', 83 | src: ['**/*.{png,jpg,svg}'], 84 | dest: 'docs/build/assets/img/' 85 | }] 86 | } 87 | }, 88 | 89 | // Check js for errors 90 | 'jshint': { 91 | lib: [ 92 | 'lib/**/*.js' 93 | ], 94 | docs: [ 95 | 'docs/source/assets/js/**.js' 96 | ] 97 | }, 98 | 99 | // Concatenate lib 100 | 'concat': { 101 | options: { 102 | stripBanners: true, 103 | banner: banner 104 | }, 105 | dist: { 106 | src: ['lib/*.js'], 107 | dest: 'dist/' + name + '.js' 108 | } 109 | }, 110 | 111 | // Minified version of lib 112 | 'uglify': { 113 | dist: { 114 | src: ['lib/*.js'], 115 | dest: 'dist/' + name + '.min.js' 116 | } 117 | }, 118 | 119 | // Copy files 120 | 'copy': { 121 | dist: { 122 | expand: true, 123 | cwd: 'dist/', 124 | src: ['*'], 125 | dest: 'docs/source/assets/js/lib/' 126 | }, 127 | docs: { 128 | expand: true, 129 | cwd: 'docs/source/assets/js/', 130 | src: ['**/*'], 131 | dest: 'docs/build/assets/js/' 132 | }, 133 | data: { 134 | expand: true, 135 | cwd: 'docs/source/data', 136 | src: ['*'], 137 | dest: 'docs/build/data/' 138 | } 139 | }, 140 | 141 | // Make a zip file of the dist folder 142 | 'compress': { 143 | main: { 144 | options: { 145 | archive: name + '.zip' 146 | }, 147 | files: [ 148 | { 149 | src: ['dist/**'], 150 | dest: './' 151 | }, 152 | ] 153 | } 154 | }, 155 | 156 | // This task runs right after npm install 157 | 'concurrent': { 158 | prepublish: [ 159 | 'sass', 160 | 'uglify', 161 | 'copy', 162 | 'concat:dist', 163 | 'newer:imagemin' 164 | ] 165 | }, 166 | 167 | // Release a new version on GitHub 168 | 'github-release': { 169 | options: { 170 | repository: repo, 171 | release: { 172 | tag_name: currentVersion, 173 | name: currentVersion, 174 | body: description 175 | } 176 | }, 177 | files: { 178 | src: name + '.zip' 179 | } 180 | }, 181 | 182 | // Ask for GitHub username and password 183 | 'prompt': { 184 | github: { 185 | options: { 186 | questions: [ 187 | { 188 | config: 'github-release.options.auth.user', 189 | type: 'input', 190 | message: 'GitHub username:' 191 | }, 192 | { 193 | config: 'github-release.options.auth.password', 194 | type: 'password', 195 | message: 'GitHub password:' 196 | } 197 | ] 198 | } 199 | } 200 | }, 201 | 202 | // Deploy the docs site to gh-pages 203 | 'gh-pages': { 204 | options: { 205 | base: 'docs/build', 206 | repo: 'https://github.com/esripdx/angular-dimple.git' 207 | }, 208 | src: ['**'] 209 | } 210 | }); 211 | 212 | // Build a dist folder with all assets 213 | grunt.registerTask('prepublish', [ 214 | 'concurrent:prepublish' 215 | ]); 216 | 217 | grunt.registerTask('lib', ['jshint:lib', 'concat:dist', 'uglify:dist']); 218 | grunt.registerTask('deploy', ['lib', 'acetate:build', 'sass', 'newer:imagemin', 'gh-pages']); 219 | 220 | // Release a new version of the framework 221 | grunt.registerTask('release', [ 222 | 'prompt:github', 223 | 'prepublish', 224 | 'compress', 225 | 'github-release' 226 | ]); 227 | 228 | grunt.registerTask('default', ['lib', 'jshint:docs', 'copy', 'newer:imagemin', 'sass', 'acetate:watch', 'watch']); 229 | 230 | }; 231 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Angular Dimple 2 | 3 | A simple angular library wrapping dimple charts as angular directives. 4 | 5 | ## Install 6 | 7 | ### Manual 8 | 9 | To get setup, simply: 10 | 11 | 1. Make sure you have d3 and dimple 12 | 2. Download the minified javascript in dist 13 | 3. Include the library as a module in your app 14 | 15 | ### Bower 16 | 17 | ``` 18 | bower install angular-dimple 19 | ``` 20 | 21 | ## Use 22 | 23 | All the angular directives behave in pretty much the same way. Simply use the directive, passing in a model from your scope as the `data=` attribute. 24 | 25 | For example, in the controller for your app, if you had something like `$scope.graphData` which is json that looks like this: 26 | 27 | ```json 28 | [ 29 | { 30 | "Month": "Jan-11", 31 | "storeId": 1, 32 | "Sales": 14 33 | },{ 34 | "Month": "Feb-11", 35 | "storeId": 1, 36 | "Sales": 14 37 | },{ 38 | "Month": "March-11", 39 | "storeId": 1, 40 | "Sales": 17 41 | },{ 42 | "Month": "Jan-11", 43 | "storeId": 2, 44 | "Sales": 14 45 | },{ 46 | "Month": "Feb-11", 47 | "storeId": 2, 48 | "Sales": 16 49 | },{ 50 | "Month": "March-11", 51 | "storeId": 2, 52 | "Sales": 8 53 | } 54 | ] 55 | ``` 56 | 57 | You'd set up a line-graph like this: 58 | 59 | ```html 60 | 61 | 62 | 63 | 64 | 65 | 66 | ``` 67 | 68 | This would give you a line graph with an x-axis of "Month", a y-axis of "Sales" and two lines, each corresponding to a different store from your dataset. 69 | 70 | Passing a line tag with a field and no value will draw a line on the chart for each unique value for that field in your data. So you could plot a line for each unique `storeId` without having to specify them all by name like this: 71 | 72 | ```html 73 | 74 | 75 | 76 | 77 | 78 | ``` 79 | 80 | #### Line Graphs 81 | 82 | ```html 83 | 84 | 85 | 86 | 87 | 88 | 89 | ``` 90 | 91 | #### Area Charts 92 | 93 | ```html 94 | 95 | 96 | 97 | 98 | 99 | 100 | ``` 101 | 102 | #### Stacked Area Charts 103 | 104 | ```html 105 | 106 | 107 | 108 | 109 | 110 | ``` 111 | 112 | #### Bar Graphs 113 | 114 | ```html 115 | 116 | 117 | 118 | 119 | 120 | 121 | ``` 122 | 123 | #### Stacked Bar Graphs 124 | 125 | ```html 126 | 127 | 128 | 129 | 130 | 131 | ``` 132 | 133 | #### Scatter Plot 134 | 135 | Scatter plots require one extra field (`series`) to be passed through to the `` element. Let's say you have some data with heights and weights formatted like this: 136 | 137 | ```json 138 | [ 139 | { 140 | "Height": 64, 141 | "Weight": 190 142 | },{ 143 | "Height": 68, 144 | "Weight": 195 145 | },{ 146 | "Height": 69, 147 | "Weight": 198 148 | },{ 149 | "Height": 70, 150 | "Weight": 205 151 | },{ 152 | "Height": 67, 153 | "Weight": 198 154 | },{ 155 | "Height": 76, 156 | "Weight": 195 157 | } 158 | ] 159 | ``` 160 | 161 | Assuming you set that on your scope as `$scope.scatterData`, you can use the following directive to make a scatter plot: 162 | 163 | ``` 164 | 165 | 166 | 167 | 168 | 169 | ``` 170 | 171 | * Note: the `label` attribute will make all the points the same color and title the group with that label in the legend if you have one.* 172 | 173 | ## Contributing 174 | 175 | 1. Fork & clone 176 | 1. `npm install` 177 | 1. `grunt` to run development environment 178 | 1. Test with `grunt test` 179 | 1. Open a pull request! 180 | 181 | ## License 182 | 183 | [ISC](http://en.wikipedia.org/wiki/ISC_license) 184 | -------------------------------------------------------------------------------- /acetate.conf.js: -------------------------------------------------------------------------------- 1 | module.exports = function (acetate) { 2 | acetate.global('config', { 3 | environment: 'dev' 4 | }); 5 | 6 | acetate.layout('**/*', 'layouts/_layout:content'); 7 | acetate.layout('posts/**/*', 'layouts/_post:post'); 8 | 9 | acetate.options.src = 'docs/source'; 10 | acetate.options.dest = 'docs/build'; 11 | }; -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "angular-dimple", 3 | "version": "2.0.0", 4 | "main": "dist/angular-dimple.js", 5 | "homepage": "http://esripdx.github.io/angular-dimple/", 6 | "authors": [ 7 | "Paul C Pederson ", 8 | "Nik Wise " 9 | ], 10 | "description": "A mini-library of Angular directives for charting", 11 | "keywords": [ 12 | "Angular", 13 | "Dimple", 14 | "charts", 15 | "graphs", 16 | "directives" 17 | ], 18 | "license": "ISC", 19 | "ignore": [ 20 | "**/.*", 21 | "node_modules", 22 | "bower_components", 23 | "documentation", 24 | "source", 25 | "test", 26 | "site" 27 | ], 28 | "dependencies": { 29 | "d3": "~3.4.8", 30 | "dimple": "~2.1.0", 31 | "typecabinet": "~0.0.2", 32 | "viewport-grid": "*", 33 | "rye": "~0.0.1" 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /dist/angular-dimple.js: -------------------------------------------------------------------------------- 1 | /*! angular-dimple - 2.0.1 - 2016-05-18 2 | * https://github.com/esripdx/angular-dimple 3 | * Licensed ISC */ 4 | angular.module('angular-dimple', [ 5 | 'angular-dimple.graph', 6 | 'angular-dimple.legend', 7 | 'angular-dimple.x', 8 | 'angular-dimple.y', 9 | 'angular-dimple.r', 10 | 'angular-dimple.line', 11 | 'angular-dimple.bar', 12 | 'angular-dimple.stacked-bar', 13 | 'angular-dimple.area', 14 | 'angular-dimple.stacked-area', 15 | 'angular-dimple.scatter-plot', 16 | 'angular-dimple.ring' 17 | ]) 18 | 19 | .constant('MODULE_VERSION', '0.0.1') 20 | 21 | .value('defaults', { 22 | foo: 'bar' 23 | }); 24 | angular.module('angular-dimple.area', []) 25 | 26 | .directive('area', [function () { 27 | return { 28 | restrict: 'E', 29 | replace: true, 30 | require: ['area', '^graph'], 31 | controller: ['$scope', '$element', '$attrs', function($scope, $element, $attrs) { 32 | }], 33 | link: function($scope, $element, $attrs, $controllers) { 34 | var graphController = $controllers[1]; 35 | var areaController = $controllers[0]; 36 | var chart = graphController.getChart(); 37 | 38 | function addArea () { 39 | if ($attrs.value) { 40 | area = chart.addSeries([$attrs.field], dimple.plot.area); 41 | graphController.filter($attrs); 42 | area.lineMarkers = true; 43 | } else { 44 | var values = dimple.getUniqueValues($scope.data, $attrs.field); 45 | angular.forEach(values, function(value){ 46 | area = chart.addSeries([$attrs.field], dimple.plot.area); 47 | graphController.filter($attrs); 48 | area.lineMarkers = true; 49 | }); 50 | } 51 | graphController.draw(); 52 | } 53 | 54 | $scope.$watch('dataReady', function(newValue, oldValue) { 55 | if (newValue === true) { 56 | addArea(); 57 | } 58 | }); 59 | } 60 | }; 61 | }]); 62 | 63 | 64 | angular.module('angular-dimple.bar', []) 65 | 66 | .directive('bar', [function () { 67 | return { 68 | restrict: 'E', 69 | replace: true, 70 | require: ['bar', '^graph'], 71 | controller: ['$scope', '$element', '$attrs', function($scope, $element, $attrs) { 72 | }], 73 | link: function($scope, $element, $attrs, $controllers) { 74 | var graphController = $controllers[1]; 75 | var lineController = $controllers[0]; 76 | var chart = graphController.getChart(); 77 | 78 | function addBar () { 79 | var filteredData; 80 | bar = chart.addSeries([$attrs.field], dimple.plot.bar); 81 | graphController.filter($attrs); 82 | graphController.draw(); 83 | } 84 | 85 | 86 | 87 | $scope.$watch('dataReady', function(newValue, oldValue) { 88 | if (newValue === true) { 89 | addBar(); 90 | } 91 | }); 92 | } 93 | }; 94 | }]); 95 | angular.module('angular-dimple.graph', []) 96 | 97 | .directive('graph', ['$window', function ($window) { 98 | return { 99 | restrict: 'E', 100 | replace: true, 101 | scope: { 102 | data: '=', 103 | color: '=' 104 | }, 105 | require: ['graph'], 106 | transclude: true, 107 | link: function (scope, element, attrs, controllers, transclude) { 108 | var graphController = controllers[0]; 109 | graphController._createChart(); 110 | scope.dataReady = false; 111 | scope.filters = []; 112 | 113 | var chart = graphController.getChart(); 114 | var transition; 115 | if (attrs.transition) { 116 | transition = attrs.transition; 117 | } else { 118 | transition = 750; 119 | } 120 | 121 | scope.$watch('data', function(newValue, oldValue) { 122 | if (newValue) { 123 | scope.dataReady = true; 124 | graphController.setData(); 125 | chart.draw(transition); 126 | } 127 | }); 128 | 129 | transclude(scope, function(clone){ 130 | element.append(clone); 131 | }); 132 | 133 | scope.onResize = function() { 134 | if (graphController.getAutoresize()){ 135 | var chart = graphController.getChart(); 136 | if (chart){ 137 | chart.draw(0, true); 138 | } 139 | } 140 | }; 141 | 142 | angular.element($window).bind('resize', function() { 143 | scope.onResize(); 144 | }); 145 | 146 | }, 147 | controller: ['$scope', '$element', '$attrs', function($scope, $element, $attrs) { 148 | var chart; 149 | var autoresize = false; 150 | var id = (Math.random() * 1e9).toString(36).replace(".", "_"); 151 | $element.append('
'); 152 | 153 | this._createChart = function () { 154 | // create an svg element 155 | 156 | var width = $attrs.width ? $attrs.width : '100%'; 157 | var height = $attrs.height ? $attrs.height : '100%'; 158 | autoresize = $attrs.autoresize ? $attrs.autoresize.toLowerCase()==='true' : false; 159 | 160 | var svg = dimple.newSvg('#dng-'+ id +'', width, height); 161 | var data = $scope.data; 162 | 163 | // create the dimple chart using the d3 selection of our element 164 | chart = new dimple.chart(svg, data); 165 | 166 | if ($attrs.margin) { 167 | chart.setMargins($attrs.margin); 168 | } else { 169 | chart.setMargins(60, 60, 20, 40); 170 | } 171 | 172 | // auto style 173 | var autoStyle = $attrs.autoStyle === 'false' ? true : false; 174 | chart.noFormats = autoStyle; 175 | 176 | // Apply palette styles 177 | if ($attrs.color) { 178 | var palette = $scope.color; 179 | for (var i = 0; i < palette.length; i++ ) { 180 | chart.assignColor(palette[i].name, palette[i].fill, palette[i].stroke, palette[i].opacity); 181 | } 182 | } 183 | }; 184 | 185 | this.getAutoresize = function (){ 186 | return autoresize; 187 | }; 188 | 189 | this.getChart = function () { 190 | return chart; 191 | }; 192 | 193 | this.setData = function () { 194 | chart.data = $scope.data; 195 | }; 196 | 197 | this.draw = function () { 198 | chart.draw(); 199 | }; 200 | 201 | this.getID = function () { 202 | return id; 203 | }; 204 | 205 | this.filter = function (attrs) { 206 | if (attrs.value !== undefined) { 207 | $scope.filters.push(attrs.value); 208 | } 209 | if ($scope.filters.length) { 210 | chart.data = dimple.filterData($scope.data, attrs.field, $scope.filters); 211 | } 212 | 213 | if (attrs.filter !== undefined) { 214 | console.log("i see a filter"); 215 | var thisFilter = attrs.filter.split(':'); 216 | var field = thisFilter[0]; 217 | var value = [thisFilter[1]]; 218 | chart.data = dimple.filterData($scope.data, field, value); 219 | } 220 | }; 221 | 222 | }] 223 | }; 224 | }]); 225 | angular.module('angular-dimple.legend', []) 226 | 227 | .directive('graphLegend', [function () { 228 | return { 229 | restrict: 'E', 230 | replace: true, 231 | require: ['graphLegend', '^graph'], 232 | controller: ['$scope', '$element', '$attrs', function($scope, $element, $attrs) { 233 | }], 234 | link: function($scope, $element, $attrs, $controllers) { 235 | var graphController = $controllers[1]; 236 | var chart = graphController.getChart(); 237 | 238 | function addLegend () { 239 | var left = $attrs.left ? $attrs.left : "10%"; 240 | var top = $attrs.top ? $attrs.top : "4%"; 241 | var height = $attrs.height ? $attrs.height : "10%"; 242 | var width = $attrs.width ? $attrs.width : "90%"; 243 | var position = $attrs.position ? $attrs.position : 'left'; 244 | chart.addLegend(left, top, width, height, position); 245 | } 246 | 247 | $scope.$watch('dataReady', function(newValue, oldValue) { 248 | if (newValue === true) { 249 | addLegend(); 250 | } 251 | }); 252 | } 253 | }; 254 | }]); 255 | angular.module('angular-dimple.line', []) 256 | 257 | .directive('line', [function () { 258 | return { 259 | restrict: 'E', 260 | replace: true, 261 | require: ['line', '^graph'], 262 | controller: ['$scope', '$element', '$attrs', function($scope, $element, $attrs) { 263 | }], 264 | link: function($scope, $element, $attrs, $controllers) { 265 | var graphController = $controllers[1]; 266 | var chart = graphController.getChart(); 267 | var drawn = false; 268 | 269 | function addLine () { 270 | var filteredData; 271 | line = chart.addSeries([$attrs.field], dimple.plot.line); 272 | graphController.filter($attrs); 273 | line.lineMarkers = true; 274 | graphController.draw(); 275 | } 276 | 277 | $scope.$watch('dataReady', function(newValue, oldValue) { 278 | if (newValue === true) { 279 | addLine(); 280 | } 281 | }); 282 | 283 | } 284 | }; 285 | }]); 286 | angular.module('angular-dimple.r', []) 287 | 288 | .directive('r', [function () { 289 | return { 290 | restrict: 'E', 291 | replace: true, 292 | require: ['r', '^graph'], 293 | controller: ['$scope', '$element', '$attrs', function($scope, $element, $attrs) { 294 | }], 295 | link: function($scope, $element, $attrs, $controllers) { 296 | var graphController = $controllers[1]; 297 | var chart = graphController.getChart(); 298 | 299 | function addAxis () { 300 | r = chart.addMeasureAxis('p', $attrs.field); 301 | 302 | if ($attrs.title && $attrs.title !== "null") { 303 | r.title = $attrs.title; 304 | } else if ($attrs.title == "null") { 305 | r.title = null; 306 | } 307 | } 308 | 309 | $scope.$watch('data', function(newValue, oldValue) { 310 | if (newValue) { 311 | addAxis(); 312 | } 313 | }); 314 | } 315 | }; 316 | }]); 317 | angular.module('angular-dimple.ring', []) 318 | 319 | .directive('ring', [function () { 320 | return { 321 | restrict: 'E', 322 | replace: true, 323 | require: ['ring', '^graph'], 324 | controller: ['$scope', '$element', '$attrs', function($scope, $element, $attrs) { 325 | }], 326 | link: function($scope, $element, $attrs, $controllers) { 327 | var graphController = $controllers[1]; 328 | var areaController = $controllers[0]; 329 | var chart = graphController.getChart(); 330 | 331 | function setData (data, series) { 332 | series.data = data; 333 | } 334 | 335 | function addRing () { 336 | var thickness; 337 | ring = chart.addSeries([$attrs.field], dimple.plot.pie); 338 | if ($attrs.thickness && !$attrs.diameter) { 339 | thickness = (100 - $attrs.thickness) + '%'; 340 | ring.innerRadius = thickness; 341 | } else if ($attrs.thickness && $attrs.diameter) { 342 | thickness = ($attrs.diameter - $attrs.thickness) + '%'; 343 | ring.innerRadius = thickness; 344 | } else { 345 | ring.innerRadius = "50%"; 346 | } 347 | 348 | if ($attrs.diameter) { 349 | ring.outerRadius = ($attrs.diameter) + '%'; 350 | } 351 | graphController.filter($attrs); 352 | graphController.draw(); 353 | } 354 | 355 | $scope.$watch('data', function(newValue, oldValue) { 356 | if (newValue) { 357 | addRing(); 358 | } 359 | }); 360 | } 361 | }; 362 | }]); 363 | 364 | 365 | angular.module('angular-dimple.scatter-plot', []) 366 | 367 | .directive('scatterPlot', [function () { 368 | return { 369 | restrict: 'E', 370 | replace: true, 371 | require: ['scatterPlot', '^graph'], 372 | controller: [function() {}], 373 | link: function($scope, $element, $attrs, $controllers) { 374 | var graphController = $controllers[1]; 375 | var chart = graphController.getChart(); 376 | 377 | function addScatterPlot () { 378 | var array = []; 379 | 380 | if ($attrs.series){ array.push($attrs.series); } 381 | array.push($attrs.field); 382 | if ($attrs.label || $attrs.label === '') { array.push($attrs.label); } 383 | scatterPlot = chart.addSeries(array, dimple.plot.bubble); 384 | scatterPlot.aggregate = dimple.aggregateMethod.avg; 385 | graphController.filter($attrs); 386 | graphController.draw(); 387 | } 388 | 389 | $scope.$watch('dataReady', function(newValue, oldValue) { 390 | if (newValue === true) { 391 | addScatterPlot(); 392 | } 393 | }); 394 | } 395 | }; 396 | }]); 397 | angular.module('angular-dimple.stacked-area', []) 398 | 399 | .directive('stackedArea', [function () { 400 | return { 401 | restrict: 'E', 402 | replace: true, 403 | require: ['stackedArea', '^graph'], 404 | controller: ['$scope', '$element', '$attrs', function($scope, $element, $attrs) { 405 | }], 406 | link: function($scope, $element, $attrs, $controllers) { 407 | var graphController = $controllers[1]; 408 | var areaController = $controllers[0]; 409 | var chart = graphController.getChart(); 410 | 411 | function addArea () { 412 | if ($attrs.series) { 413 | area = chart.addSeries([$attrs.series], dimple.plot.area); 414 | } else { 415 | area = chart.addSeries([$attrs.field], dimple.plot.area); 416 | } 417 | graphController.filter($attrs); 418 | area.lineMarkers = false; 419 | graphController.draw(); 420 | } 421 | 422 | $scope.$watch('dataReady', function(newValue, oldValue) { 423 | if (newValue === true) { 424 | addArea(); 425 | } 426 | }); 427 | } 428 | }; 429 | }]); 430 | angular.module('angular-dimple.stacked-bar', []) 431 | 432 | .directive('stackedBar', [function () { 433 | return { 434 | restrict: 'E', 435 | replace: true, 436 | require: ['stackedBar', '^graph'], 437 | controller: ['$scope', '$element', '$attrs', function($scope, $element, $attrs) { 438 | }], 439 | link: function($scope, $element, $attrs, $controllers) { 440 | var graphController = $controllers[1]; 441 | var lineController = $controllers[0]; 442 | var chart = graphController.getChart(); 443 | 444 | function addBar () { 445 | if ($attrs.series) { 446 | bar = chart.addSeries([$attrs.series], dimple.plot.bar); 447 | } else { 448 | bar = chart.addSeries([$attrs.field], dimple.plot.bar); 449 | } 450 | graphController.filter($attrs); 451 | graphController.draw(); 452 | } 453 | 454 | $scope.$watch('dataReady', function(newValue, oldValue) { 455 | if (newValue === true) { 456 | addBar(); 457 | } 458 | }); 459 | } 460 | }; 461 | }]); 462 | angular.module('angular-dimple.x', []) 463 | 464 | .directive('x', [function () { 465 | return { 466 | restrict: 'E', 467 | replace: true, 468 | require: ['x', '^graph'], 469 | controller: ['$scope', '$element', '$attrs', function($scope, $element, $attrs) { 470 | }], 471 | link: function($scope, $element, $attrs, $controllers) { 472 | var graphController = $controllers[1]; 473 | var chart = graphController.getChart(); 474 | 475 | function addAxis () { 476 | if ($attrs.groupBy) { 477 | if ($attrs.type == 'Measure') { 478 | x = chart.addMeasureAxis('x', [$attrs.groupBy, $attrs.field]); 479 | } else if ($attrs.type == 'Percent') { 480 | x = chart.addPctAxis('x', $attrs.field); 481 | } else if ($attrs.type == 'Time') { 482 | x = chart.addTimeAxis('x', $attrs.field); 483 | if ($attrs.format) { 484 | x.tickFormat = $attrs.format; 485 | } 486 | } else { 487 | x = chart.addCategoryAxis('x', [$attrs.groupBy, $attrs.field]); 488 | } 489 | if ($attrs.orderBy) { 490 | x.addGroupOrderRule($attrs.orderBy); 491 | } 492 | } else { 493 | if ($attrs.type == 'Measure') { 494 | x = chart.addMeasureAxis('x', $attrs.field); 495 | } else if ($attrs.type == 'Percent') { 496 | x = chart.addPctAxis('x', $attrs.field); 497 | } else if ($attrs.type == 'Time') { 498 | x = chart.addTimeAxis('x', $attrs.field); 499 | if ($attrs.format) { 500 | x.tickFormat = $attrs.format; 501 | } 502 | } else { 503 | x = chart.addCategoryAxis('x', $attrs.field); 504 | } 505 | if ($attrs.orderBy) { 506 | x.addOrderRule($attrs.orderBy); 507 | } 508 | } 509 | 510 | if ($attrs.title && $attrs.title !== "null") { 511 | x.title = $attrs.title; 512 | } else if ($attrs.title == "null") { 513 | x.title = null; 514 | } 515 | } 516 | 517 | $scope.$watch('dataReady', function(newValue, oldValue) { 518 | if (newValue === true) { 519 | addAxis(); 520 | } 521 | }); 522 | } 523 | }; 524 | }]); 525 | angular.module('angular-dimple.y', []) 526 | 527 | .directive('y', [function () { 528 | return { 529 | restrict: 'E', 530 | replace: true, 531 | require: ['y', '^graph'], 532 | controller: ['$scope', '$element', '$attrs', function($scope, $element, $attrs) { 533 | }], 534 | link: function($scope, $element, $attrs, $controllers) { 535 | var graphController = $controllers[1]; 536 | var chart = graphController.getChart(); 537 | 538 | function addAxis () { 539 | if ($attrs.groupBy) { 540 | if ($attrs.type == 'Category') { 541 | y = chart.addCategoryAxis('y', $attrs.field); 542 | } else if ($attrs.type == 'Percent') { 543 | y = chart.addPctAxis('y', $attrs.field); 544 | } else if ($attrs.type == 'Time') { 545 | y = chart.addTimeAxis('y', $attrs.field); 546 | if ($attrs.format) { 547 | y.tickFormat = $attrs.format; 548 | } 549 | } else { 550 | y = chart.addMeasureAxis('y', $attrs.field); 551 | } 552 | if ($attrs.orderBy) { 553 | y.addGroupOrderRule($attrs.orderBy); 554 | } 555 | } else { 556 | if ($attrs.type == 'Category') { 557 | y = chart.addCategoryAxis('y', $attrs.field); 558 | } else if ($attrs.type == 'Percent') { 559 | y = chart.addPctAxis('y', $attrs.field); 560 | } else if ($attrs.type == 'Time') { 561 | y = chart.addTimeAxis('y', $attrs.field); 562 | if ($attrs.format) { 563 | y.tickFormat = $attrs.format; 564 | } 565 | } else { 566 | y = chart.addMeasureAxis('y', $attrs.field); 567 | } 568 | if ($attrs.orderBy) { 569 | y.addOrderRule($attrs.orderBy); 570 | } 571 | } 572 | 573 | if ($attrs.title && $attrs.title !== "null") { 574 | y.title = $attrs.title; 575 | } else if ($attrs.title == "null") { 576 | y.title = null; 577 | } 578 | } 579 | 580 | $scope.$watch('dataReady', function(newValue, oldValue) { 581 | if (newValue === true) { 582 | addAxis(); 583 | } 584 | }); 585 | } 586 | }; 587 | }]); -------------------------------------------------------------------------------- /dist/angular-dimple.min.js: -------------------------------------------------------------------------------- 1 | angular.module("angular-dimple",["angular-dimple.graph","angular-dimple.legend","angular-dimple.x","angular-dimple.y","angular-dimple.r","angular-dimple.line","angular-dimple.bar","angular-dimple.stacked-bar","angular-dimple.area","angular-dimple.stacked-area","angular-dimple.scatter-plot","angular-dimple.ring"]).constant("MODULE_VERSION","0.0.1").value("defaults",{foo:"bar"}),angular.module("angular-dimple.area",[]).directive("area",[function(){return{restrict:"E",replace:!0,require:["area","^graph"],controller:["$scope","$element","$attrs",function(a,b,c){}],link:function(a,b,c,d){function e(){if(c.value)area=g.addSeries([c.field],dimple.plot.area),f.filter(c),area.lineMarkers=!0;else{var b=dimple.getUniqueValues(a.data,c.field);angular.forEach(b,function(a){area=g.addSeries([c.field],dimple.plot.area),f.filter(c),area.lineMarkers=!0})}f.draw()}var f=d[1],g=(d[0],f.getChart());a.$watch("dataReady",function(a,b){a===!0&&e()})}}}]),angular.module("angular-dimple.bar",[]).directive("bar",[function(){return{restrict:"E",replace:!0,require:["bar","^graph"],controller:["$scope","$element","$attrs",function(a,b,c){}],link:function(a,b,c,d){function e(){bar=g.addSeries([c.field],dimple.plot.bar),f.filter(c),f.draw()}var f=d[1],g=(d[0],f.getChart());a.$watch("dataReady",function(a,b){a===!0&&e()})}}}]),angular.module("angular-dimple.graph",[]).directive("graph",["$window",function(a){return{restrict:"E",replace:!0,scope:{data:"=",color:"="},require:["graph"],transclude:!0,link:function(b,c,d,e,f){var g=e[0];g._createChart(),b.dataReady=!1,b.filters=[];var h,i=g.getChart();h=d.transition?d.transition:750,b.$watch("data",function(a,c){a&&(b.dataReady=!0,g.setData(),i.draw(h))}),f(b,function(a){c.append(a)}),b.onResize=function(){if(g.getAutoresize()){var a=g.getChart();a&&a.draw(0,!0)}},angular.element(a).bind("resize",function(){b.onResize()})},controller:["$scope","$element","$attrs",function(a,b,c){var d,e=!1,f=(1e9*Math.random()).toString(36).replace(".","_");b.append('
'),this._createChart=function(){var b=c.width?c.width:"100%",g=c.height?c.height:"100%";e=c.autoresize?"true"===c.autoresize.toLowerCase():!1;var h=dimple.newSvg("#dng-"+f,b,g),i=a.data;d=new dimple.chart(h,i),c.margin?d.setMargins(c.margin):d.setMargins(60,60,20,40);var j="false"===c.autoStyle;if(d.noFormats=j,c.color)for(var k=a.color,l=0;l 2 | -------------------------------------------------------------------------------- /docs/source/assets/css/base/_buttons.scss: -------------------------------------------------------------------------------- 1 | // Buttons 2 | .btn { 3 | display: inline-block; 4 | padding: 1em; 5 | background-color: $blue; 6 | color: $lighter-gray; 7 | border: none; 8 | border-radius: 3px; 9 | text-decoration: none; 10 | font-size: 0.75em; 11 | font-weight: 300; 12 | cursor: pointer; 13 | @include transition(background-color 75ms linear, color 75ms linear); 14 | &:hover, &:focus { 15 | background-color: lighten($blue, 10%); 16 | color: $white; 17 | outline: none; 18 | } 19 | &.outline { 20 | background: transparent; 21 | color: $blue; 22 | border: 1px solid $blue; 23 | &:hover { 24 | background-color: lighten($blue, 10%); 25 | color: $white; 26 | border: 1px solid lighten($blue, 10%); 27 | } 28 | } 29 | &.dark-blue { 30 | background: $dark-blue; 31 | color: $light-gray; 32 | &:hover { 33 | background-color: lighten($dark-blue, 10%); 34 | color: $lighter-gray; 35 | } 36 | } 37 | &.white { 38 | background: $off-white; 39 | color: $dark-blue; 40 | &:hover { 41 | background-color: $white; 42 | color: $blue; 43 | } 44 | } 45 | } -------------------------------------------------------------------------------- /docs/source/assets/css/base/_code.scss: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Orginal Style from ethanschoonover.hljs-com/solarized (c) Jeremy Hull 4 | 5 | */ 6 | 7 | pre { 8 | background: #002b36; 9 | color: #839496; 10 | 11 | code { 12 | background: #002b36; 13 | } 14 | 15 | .hljs-comment, 16 | .hljs-template_comment, 17 | .hljs-diff .hljs-header, 18 | .hljs-doctype, 19 | .hljs-pi, 20 | .hljs-lisp .hljs-string, 21 | .hljs-javadoc { 22 | color: #586e75; 23 | } 24 | 25 | /* Solarized Green */ 26 | .hljs-keyword, 27 | .hljs-winutils, 28 | .hljs-method, 29 | .hljs-addition, 30 | .hljs-css .hljs-tag, 31 | .hljs-request, 32 | .hljs-status, 33 | .hljs-nginx .hljs-title { 34 | color: #859900; 35 | } 36 | 37 | /* Solarized Cyan */ 38 | .hljs-number, 39 | .hljs-command, 40 | .hljs-string, 41 | .hljs-tag .hljs-value, 42 | .hljs-rules .hljs-value, 43 | .hljs-phpdoc, 44 | .hljs-tex .hljs-formula, 45 | .hljs-regexp, 46 | .hljs-hexcolor, 47 | .hljs-link_url { 48 | color: #2aa198; 49 | } 50 | 51 | /* Solarized Blue */ 52 | .hljs-title, 53 | .hljs-localvars, 54 | .hljs-chunk, 55 | .hljs-decorator, 56 | .hljs-built_in, 57 | .hljs-identifier, 58 | .hljs-vhdl .hljs-literal, 59 | .hljs-id, 60 | .hljs-css .hljs-function { 61 | color: #268bd2; 62 | } 63 | 64 | /* Solarized Yellow */ 65 | .hljs-attribute, 66 | .hljs-variable, 67 | .hljs-lisp .hljs-body, 68 | .hljs-smalltalk .hljs-number, 69 | .hljs-constant, 70 | .hljs-class .hljs-title, 71 | .hljs-parent, 72 | .hljs-haskell .hljs-type, 73 | .hljs-link_reference { 74 | color: #b58900; 75 | } 76 | 77 | /* Solarized Orange */ 78 | .hljs-preprocessor, 79 | .hljs-preprocessor .hljs-keyword, 80 | .hljs-pragma, 81 | .hljs-shebang, 82 | .hljs-symbol, 83 | .hljs-symbol .hljs-string, 84 | .hljs-diff .hljs-change, 85 | .hljs-special, 86 | .hljs-attr_selector, 87 | .hljs-subst, 88 | .hljs-cdata, 89 | .hljs-clojure .hljs-title, 90 | .hljs-css .hljs-pseudo, 91 | .hljs-header { 92 | color: #cb4b16; 93 | } 94 | 95 | /* Solarized Red */ 96 | .hljs-deletion, 97 | .hljs-important { 98 | color: #dc322f; 99 | } 100 | 101 | /* Solarized Violet */ 102 | .hljs-link_label { 103 | color: #6c71c4; 104 | } 105 | 106 | .hljs-tex .hljs-formula { 107 | background: #073642; 108 | } 109 | 110 | } 111 | -------------------------------------------------------------------------------- /docs/source/assets/css/base/_config.scss: -------------------------------------------------------------------------------- 1 | // Colors 2 | $white: #FFFFFF !default; 3 | $off-white: #FAFBFE !default; 4 | $lighter-gray: #ECF0F3 !default; 5 | $light-gray: #DDE3E8 !default; 6 | $gray: #76899B !default; 7 | $dark-gray: #4C5156 !default; 8 | $darker-gray: #2C3136 !default; 9 | $blue: #1F85C4 !default; 10 | $light-blue: lighten($blue, 10%); 11 | $dark-blue: #245070 !default; 12 | $darker-blue: #234052 !default; 13 | 14 | // ┌────────────┐ 15 | // │ Structural │ 16 | // └────────────┘ 17 | 18 | // Breakpoints 19 | $small: 480px !default; 20 | $medium: 860px !default; 21 | $large: 1280px !default; 22 | 23 | // Grid Settings 24 | $vw-ratio: 0.9; 25 | $container-width: $vw-ratio * 100vw !default; 26 | $container-min: 0 !default; 27 | $container-max: $large * $vw-ratio !default; 28 | $column-gutter: 1rem !default; 29 | 30 | $vertical-range: 7 !default; 31 | 32 | // $ratio: $golden ; 33 | $body-size: 0.875rem ; 34 | $small-size: 0.75rem ; 35 | $baseline: 1.25rem ; 36 | $indent: 1em ; 37 | 38 | // ┌───────────────┐ 39 | // │ Font Families │ 40 | // └───────────────┘ 41 | $header-family: 'Clear Sans', 42 | 'Helvetica Neue', 43 | 'Helvetica', 44 | 'Arial', 45 | sans-serif ; 46 | 47 | $header-thin: false ; 48 | $header-thin: false ; 49 | $header-light: 200, 400 ; 50 | $header-regular: 400, 600 ; 51 | $header-medium: false ; 52 | $header-demi: false ; 53 | $header-bold: 600, 600 ; 54 | $header-black: false ; 55 | 56 | $body-family: 'Clear Sans', 57 | 'Helvetica Neue', 58 | 'Helvetica', 59 | 'Arial', 60 | sans-serif ; 61 | 62 | $body-thin: false ; 63 | $body-thin: false ; 64 | $body-light: false ; 65 | $body-regular: 400, 700 ; 66 | $body-medium: false ; 67 | $body-demi: false ; 68 | $body-bold: 700, 700 ; 69 | $body-black: false ; 70 | 71 | $secondary-family: Georgia, 72 | serif ; 73 | 74 | $secondary-thin: false ; 75 | $secondary-thin: false ; 76 | $secondary-light: false ; 77 | $secondary-regular: 400, 700 ; 78 | $secondary-medium: false ; 79 | $secondary-demi: false ; 80 | $secondary-bold: 700, 700 ; 81 | $secondary-black: false ; 82 | 83 | $code-family: 'Source Code Pro', 84 | 'Inconsolata', 85 | "Consolas", 86 | "Andale Mono", 87 | "Lucida Console", 88 | "Monaco", 89 | "Courier New", 90 | Courier, 91 | monospace ; 92 | 93 | $code-thin: false ; 94 | $code-thin: false ; 95 | $code-light: false ; 96 | $code-regular: 400, 400 ; 97 | $code-medium: false ; 98 | $code-demi: false ; 99 | $code-bold: false ; 100 | $code-black: false ; 101 | 102 | 103 | // ┌───────────────┐ 104 | // │ Base Tracking │ 105 | // └───────────────┘ 106 | $header-tracking: 0 ; 107 | $body-tracking: 30 ; 108 | $secondary-tracking: 10 ; 109 | $code-tracking: 0 ; 110 | -------------------------------------------------------------------------------- /docs/source/assets/css/base/_reset.scss: -------------------------------------------------------------------------------- 1 | html { 2 | overflow-y: scroll; 3 | font-size: 100%; 4 | -webkit-text-size-adjust: 100%; 5 | -moz-text-size-adjust: 100%; 6 | -ms-text-size-adjust: 100%; 7 | } 8 | 9 | body { 10 | margin: 0; 11 | } 12 | 13 | // Reset HTML 5 Elements --------------------------------------------------------------- 14 | 15 | article, 16 | aside, 17 | details, 18 | figcaption, 19 | figure, 20 | footer, 21 | header, 22 | hgroup, 23 | nav, 24 | section, 25 | summary { 26 | display: block; 27 | } 28 | 29 | audio, 30 | canvas, 31 | video { 32 | display: inline-block; 33 | } 34 | 35 | audio:not([controls]) { 36 | display: none; 37 | height: 0; 38 | } 39 | 40 | [hidden] { 41 | display: none; 42 | } 43 | 44 | svg:not(:root) { 45 | overflow: hidden; 46 | } 47 | -------------------------------------------------------------------------------- /docs/source/assets/css/base/_tabs.scss: -------------------------------------------------------------------------------- 1 | // Tab Patterns 2 | .tab-group { 3 | width: 100%; 4 | .tab-nav { 5 | width: 100%; 6 | display: block; 7 | @extend %clearfix; 8 | .tab { 9 | float: left; 10 | @include box-sizing(border-box); 11 | padding: 0.5em 1em; 12 | white-space: nowrap; 13 | overflow: hidden; 14 | text-overflow: ellipsis; 15 | background-color: $off-white; 16 | border: 1px solid $lighter-gray; 17 | border-left: none; 18 | border-radius: 0; 19 | background-image: none; 20 | &:first-child { 21 | border-radius: 3px 0 0 0; 22 | border-left: 1px solid $lighter-gray; 23 | } 24 | &:last-child { 25 | border-radius: 0 3px 0 0; 26 | } 27 | &:hover { 28 | background-color: mix($off-white, $white); 29 | } 30 | &.active { 31 | border-bottom: 1px solid transparent; 32 | background-color: $white; 33 | &:hover { 34 | background-color: $white; 35 | } 36 | } 37 | } 38 | } 39 | .tab-contents { 40 | width: 100%; 41 | border: 1px solid $lighter-gray; 42 | border-radius: 0 0 3px 3px; 43 | margin-top: -1px; 44 | @include box-sizing(border-box); 45 | .tab-content { 46 | background-color: $white; 47 | display: none; 48 | width: 100%; 49 | @include box-sizing(border-box); 50 | border-radius: 0 0 3px 3px; 51 | padding: 1em; 52 | overflow: auto; 53 | &.active { 54 | display: block; 55 | } 56 | code { 57 | border: none; 58 | overflow: initial; 59 | background: transparent; 60 | } 61 | pre { 62 | background: transparent; 63 | padding: 0; 64 | border: none; 65 | margin-bottom: 0; 66 | } 67 | } 68 | } 69 | } -------------------------------------------------------------------------------- /docs/source/assets/css/examples.scss: -------------------------------------------------------------------------------- 1 | @import "compass"; 2 | @import "config"; 3 | @import "base/mixins"; 4 | 5 | .white-panel { 6 | margin-bottom: 1rem; 7 | background-color: $white; 8 | border: 1px solid $lighter-gray; 9 | @include box-sizing(border-box); 10 | @include border-radius(3px); 11 | &.padded { 12 | padding: 2rem; 13 | } 14 | 15 | h2 { 16 | padding: 6rem 0 1rem 0; 17 | } 18 | } 19 | 20 | h2 { 21 | @include respond-to($phone-large) { 22 | display: inline-block; 23 | } 24 | } 25 | 26 | .example-link { 27 | margin-top: -2.75rem; 28 | float: right; 29 | @extend .code-face; 30 | @include font-size(0); 31 | } 32 | 33 | 34 | .api-link { 35 | font-size: 1rem; 36 | float: right; 37 | line-height: 3.25rem; 38 | } 39 | 40 | .example-link, 41 | .api-link { 42 | @include respond-to($phone-large) { 43 | width: 100%; 44 | display: block; 45 | margin-top: 0rem; 46 | margin-bottom: 1.5rem; 47 | float: left; 48 | } 49 | } 50 | 51 | @include respond-to($phone){ 52 | .container { 53 | padding: 0 0; 54 | } 55 | .white-panel.padded { 56 | padding: 2rem 1rem; 57 | } 58 | } -------------------------------------------------------------------------------- /docs/source/assets/css/style.scss: -------------------------------------------------------------------------------- 1 | @import "base/config"; 2 | @import "base/reset"; 3 | 4 | @import "viewport-grid/lib/viewport-grid.scss"; 5 | @import "typecabinet/dist/typecabinet.scss"; 6 | @import "rye/dist/rye.scss"; 7 | 8 | @import "base/buttons"; 9 | @import "base/code"; 10 | @import "base/tabs"; 11 | 12 | body { 13 | color: $dark-gray; 14 | } 15 | 16 | h1, h2, h3, h4, h5, h6 { 17 | margin: 0; 18 | padding-top: $baseline; 19 | padding-bottom: $baseline; 20 | font-weight: 300; 21 | line-height: $baseline; 22 | } 23 | 24 | h1 { font-size: 2.75rem; line-height: 2*$baseline;} 25 | h2 { font-size: 2.00rem; line-height: 2*$baseline;} 26 | h3 { font-size: 1.75rem; line-height: 2*$baseline;} 27 | h4 { font-size: 1.50rem; line-height: $baseline;} 28 | h5 { font-size: 1.25rem; line-height: $baseline;} 29 | h6 { font-size: 1.00rem; line-height: $baseline;} 30 | 31 | blockquote { 32 | font-style: italic; 33 | font-weight: 400; 34 | font-size: 1.75rem; 35 | color: $light-gray; 36 | } 37 | 38 | p { 39 | margin: 0; 40 | padding-bottom: $baseline; 41 | font-size: 1.05rem; 42 | line-height: 1.5em; 43 | font-weight: 300; 44 | &.large { 45 | font-size: 1.35rem; 46 | } 47 | &.small { 48 | font-size: .85rem; 49 | } 50 | } 51 | 52 | b, strong { 53 | font-weight: 700; 54 | } 55 | 56 | small { 57 | font-size: .875rem; 58 | color: $gray; 59 | } 60 | 61 | a { 62 | color: $blue; 63 | text-decoration: none; 64 | @include transition(color 200ms linear); 65 | &:hover, &:focus { 66 | color: $dark-blue; 67 | cursor: pointer; 68 | } 69 | &:active, &:hover { 70 | outline: 0; 71 | } 72 | } 73 | 74 | ul, ol { 75 | list-style-position: inside; 76 | margin-top: 0; 77 | padding: 0; 78 | ul, ol { 79 | padding-left: 1.25em; 80 | } 81 | } 82 | 83 | ul { 84 | list-style-type: none; 85 | } 86 | 87 | 88 | ol { 89 | 90 | } 91 | 92 | code, kbd, pre, samp { 93 | @extend .code-face; 94 | } 95 | 96 | code { 97 | border-radius: 2px; 98 | background: $off-white; 99 | padding: .2em; 100 | border: 1px solid darken($off-white, 5%); 101 | white-space: pre; 102 | font-size: .75rem; 103 | line-height: 1.5em; 104 | } 105 | 106 | pre { 107 | padding: 1em; 108 | // white-space: pre; 109 | // white-space: pre-wrap; 110 | // word-wrap: break-word; 111 | tab-size: 4; 112 | // background: $off-white; 113 | border: 1px solid $lighter-gray; 114 | max-width: 100%; 115 | code { 116 | // background-color: $off-white; 117 | display: block; 118 | overflow: auto; 119 | word-wrap: normal; 120 | border: none; 121 | } 122 | } 123 | 124 | hr { 125 | display: none; 126 | margin-top: 2rem; 127 | border: none; 128 | border-top: 2rem solid $blue; 129 | } 130 | 131 | .center-text { 132 | text-align: center; 133 | } 134 | 135 | img::selection { 136 | background: transparent; 137 | } 138 | 139 | img::moz-selection { 140 | background: transparent; 141 | } 142 | 143 | table { 144 | width: 100%; 145 | background-color: $white; 146 | border-collapse: collapse; 147 | border-spacing: 0; 148 | border: 1px solid mix($lighter-gray, $light-gray); 149 | text-align: left; 150 | > thead { 151 | background-color: mix($off-white, $lighter-gray); 152 | border-bottom: 1px solid mix($lighter-gray, $light-gray); 153 | } 154 | th, td { 155 | border-left: 1px solid mix($lighter-gray, $light-gray); 156 | border-right: 1px solid mix($lighter-gray, $light-gray); 157 | padding: 12px; 158 | } 159 | tr { 160 | border-bottom: 1px solid mix($lighter-gray, $light-gray); 161 | text-align: left; 162 | &:last-child { 163 | border-bottom: none; 164 | } 165 | &:nth-child(even){ 166 | background-color: $off-white; 167 | td { 168 | background-color: $off-white; 169 | } 170 | } 171 | } 172 | } 173 | 174 | .white-panel { 175 | margin-bottom: 1rem; 176 | background-color: $white; 177 | border: 1px solid $lighter-gray; 178 | @include box-sizing(border-box); 179 | &.padded { 180 | padding: 2rem; 181 | } 182 | 183 | h2 { 184 | padding: 6rem 0 1rem 0; 185 | } 186 | } 187 | 188 | h2 { 189 | @include respond-to($small) { 190 | display: inline-block; 191 | } 192 | } 193 | 194 | .example-link { 195 | margin-top: -2.75rem; 196 | float: right; 197 | @extend .code-face; 198 | @include font-size(0); 199 | } 200 | 201 | 202 | .api-link { 203 | font-size: 1rem; 204 | float: right; 205 | line-height: 3.25rem; 206 | } 207 | 208 | .example-link, 209 | .api-link { 210 | @include respond-to($small) { 211 | width: 100%; 212 | display: block; 213 | margin-top: 0rem; 214 | margin-bottom: 1.5rem; 215 | float: left; 216 | } 217 | } 218 | 219 | @include respond-to($small){ 220 | .container { 221 | padding: 0 0; 222 | } 223 | .white-panel.padded { 224 | padding: 2rem 1rem; 225 | } 226 | } 227 | 228 | .homepage-navigation { 229 | position: relative; 230 | z-index: 2; 231 | @extend .header-light; 232 | margin-top: 1rem; 233 | a { 234 | color: $off-white; 235 | &:hover { 236 | color: $white; 237 | } 238 | } 239 | } 240 | 241 | // code { 242 | // background-color: $white; 243 | // border-color: $lighter-gray; 244 | // } 245 | 246 | .banner { 247 | position: relative; 248 | overflow: hidden; 249 | color: $white; 250 | background: url(../img/dots.svg) $dark-blue; 251 | z-index: 20; 252 | .banner-copy { 253 | position: relative; 254 | margin: 5rem 0 9rem 0; 255 | z-index: 2; 256 | font-weight: 200; 257 | } 258 | .banner-graphic { 259 | position: absolute; 260 | top: -260px; 261 | bottom: 0; 262 | left: 50%; 263 | z-index: 1; 264 | width: 2400px; 265 | margin-left: -1200px; 266 | z-index: 1; 267 | } 268 | .dimple-axis { 269 | display: none; 270 | } 271 | .dimple-gridline{ 272 | display: none; 273 | } 274 | .dimple-line { 275 | opacity: 0.8; 276 | fill: none; 277 | stroke: $darker-blue; 278 | stroke-width: 2; 279 | } 280 | .dimple-marker-back { 281 | fill: $darker-blue; 282 | } 283 | .dimple-marker { 284 | display: none; 285 | fill: $darker-blue; 286 | } 287 | } 288 | 289 | .charts-list { 290 | a { 291 | color: $gray; 292 | } 293 | } 294 | 295 | [ng-cloak] { display: none;} 296 | 297 | .fullscreen { 298 | padding: 8rem 0; 299 | .darker-blue { 300 | background-color: $darker-blue; 301 | } 302 | } 303 | 304 | .darker-blue { 305 | color: $gray; 306 | background-color: $darker-blue; 307 | a { 308 | color: lighten($blue, 10%); 309 | &:hover { 310 | color: lighten($blue, 20%); 311 | } 312 | } 313 | } 314 | 315 | .off-white { 316 | color: $dark-gray; 317 | background-color: $off-white; 318 | } 319 | 320 | .primary-navigation { 321 | font-weight: 300; 322 | position: fixed; 323 | top: 0; 324 | left: 0; 325 | right: 0; 326 | background-color: $white; 327 | border-bottom: 1px solid $light-gray; 328 | padding: 1rem 0; 329 | z-index: 10; 330 | 331 | @include respond-to($small) { 332 | position: absolute; 333 | } 334 | } 335 | 336 | .angular-dimple-logo { 337 | float: left; 338 | @include respond-to($medium) { 339 | width: 100%; 340 | text-align: center; 341 | } 342 | } 343 | 344 | .navigation-section { 345 | width: 50%; 346 | text-align: right; 347 | float: right; 348 | @include respond-to($medium) { 349 | width: 100%; 350 | text-align: center; 351 | } 352 | } 353 | 354 | .numbered { 355 | text-align: center; 356 | width: 2em; 357 | height: 2em; 358 | margin-right: 1em; 359 | display: inline-block; 360 | color: $white; 361 | @extend .code-face; 362 | font-size: .75rem; 363 | line-height: 2em; 364 | vertical-align: .25em; 365 | background-color: $blue; 366 | border-radius: 50%; 367 | } 368 | 369 | .navigation { 370 | position: fixed; 371 | height: 100vh; 372 | width: 14em; 373 | padding: 1em; 374 | background-color: #ededed; 375 | } 376 | 377 | .sidebar { 378 | position: absolute; 379 | overflow: auto; 380 | background-color: $off-white; 381 | z-index: 2; 382 | li { 383 | margin-bottom: 1rem; 384 | padding: .25rem 0; 385 | } 386 | a { 387 | width: 100%; 388 | img { 389 | float: left; 390 | height: 3rem; 391 | width: 3rem; 392 | margin-right: 1rem; 393 | background-color: $white; 394 | border: 2px solid $light-gray; 395 | border-radius: 50%; 396 | box-shadow: 0 0 0 0 $light-gray; 397 | @include transition(all 200ms linear); 398 | } 399 | &:hover { 400 | img { 401 | box-shadow: 0 0 0 4px $light-gray; 402 | } 403 | } 404 | } 405 | span { 406 | display: inline-block; 407 | line-height: 3rem; 408 | } 409 | 410 | @include respond-to($medium){ 411 | padding-top: 1rem; 412 | position: relative; 413 | height: auto; 414 | 415 | li { 416 | display: inline-block; 417 | padding-right: 1rem; 418 | } 419 | } 420 | } 421 | .scroll-to-top { 422 | position: fixed; 423 | @include respond-to($medium){ 424 | display: none; 425 | } 426 | } 427 | 428 | .chart { 429 | position: absolute; 430 | top: 0; 431 | bottom: 0; 432 | left: 14rem; 433 | right: 0; 434 | height: 100vh; 435 | padding-left: 1rem; 436 | } 437 | 438 | .chart-icon { 439 | @extend %clearfix; 440 | display: inline-block; 441 | margin-bottom: 1rem; 442 | background-color: $white; 443 | height: 6rem; 444 | width: 6rem; 445 | position: relative; 446 | border-radius: 50%; 447 | cursor: pointer; 448 | @include transition(all 200ms linear); 449 | border: 1px solid $light-gray; 450 | &:hover { 451 | background-color: $off-white; 452 | } 453 | &:before { 454 | content: ""; 455 | position: absolute; 456 | top: 0; 457 | right: 0; 458 | bottom: 0; 459 | left: 0; 460 | display: block; 461 | border-radius: 50%; 462 | box-shadow:0 0 0 6px $light-gray; 463 | @include transition(all 200ms linear); 464 | } 465 | &:hover { 466 | &:before { 467 | box-shadow:0 0 0 12px $light-gray; 468 | } 469 | } 470 | img { 471 | width: 100%; 472 | height: auto; 473 | } 474 | } 475 | 476 | .footer { 477 | position: relative; 478 | z-index: 5; 479 | } 480 | -------------------------------------------------------------------------------- /docs/source/assets/img/Angular-Dimple-Logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 9 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 36 | 43 | 44 | 45 | 51 | 52 | 55 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | -------------------------------------------------------------------------------- /docs/source/assets/img/area.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /docs/source/assets/img/bar.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 9 | 11 | 13 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /docs/source/assets/img/dots.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /docs/source/assets/img/front.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 9 | 11 | 12 | 13 | 15 | 16 | 18 | 19 | 20 | 21 | 22 | 24 | 26 | 27 | 30 | 38 | 43 | 44 | 45 | 46 | 48 | 50 | 51 | 54 | 62 | 63 | 64 | 66 | 68 | 69 | 70 | 72 | 74 | 75 | 76 | 77 | 78 | 80 | 82 | 83 | 84 | 86 | 90 | 91 | 92 | 93 | 95 | 97 | 98 | 99 | 101 | 103 | 104 | 105 | 106 | 107 | -------------------------------------------------------------------------------- /docs/source/assets/img/graph.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /docs/source/assets/img/legend.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /docs/source/assets/img/line.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 8 | 9 | 10 | 11 | 12 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /docs/source/assets/img/ring.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 10 | 11 | 12 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /docs/source/assets/img/scatter-plot.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /docs/source/assets/img/stacked-area.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /docs/source/assets/img/stacked-bar.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 8 | 9 | 10 | 12 | 13 | 14 | 16 | 17 | 18 | 20 | 21 | 22 | 24 | 25 | 26 | 28 | 29 | 30 | 32 | 33 | 34 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /docs/source/assets/img/x.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /docs/source/assets/img/y.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /docs/source/assets/js/app.js: -------------------------------------------------------------------------------- 1 | angular.module('myApp', [ 2 | 'angular-dimple', 3 | 'ngRoute', 4 | 'myApp.filters', 5 | 'myApp.services', 6 | 'myApp.directives', 7 | 'myApp.controllers' 8 | ]) 9 | 10 | .config(['$routeProvider', '$logProvider', function($routeProvider, $logProvider) { 11 | $routeProvider 12 | 13 | .when('/animation-test', { 14 | templateUrl: '/angular-dimple/examples/partials/animation-test.html', 15 | controller: 'testController' 16 | }) 17 | .when('/line-graph', { 18 | templateUrl: '/angular-dimple/examples/partials/line-graph/index.html', 19 | controller: 'lineGraphController' 20 | }) 21 | .when('/stacked-area', { 22 | templateUrl: '/angular-dimple/examples/partials/stacked-area/index.html', 23 | controller: 'stackedAreaController' 24 | }) 25 | .when('/area', { 26 | templateUrl: '/angular-dimple/examples/partials/area/index.html', 27 | controller: 'areaController' 28 | }) 29 | .when('/expanded-stacked-area', { 30 | templateUrl: '/angular-dimple/examples/partials/expanded-stacked-area/index.html', 31 | controller: 'expandedAreaController' 32 | }) 33 | .when('/bar', { 34 | templateUrl: '/angular-dimple/examples/partials/bar-graph/index.html', 35 | controller: 'barController' 36 | }) 37 | .when('/stacked-bar', { 38 | templateUrl: '/angular-dimple/examples/partials/stacked-bar-graph/index.html', 39 | controller: 'stackedBarController' 40 | }) 41 | .when('/scatter-plot', { 42 | templateUrl: '/angular-dimple/examples/partials/scatter-plot/index.html', 43 | controller: 'scatterController' 44 | }) 45 | .when('/ring', { 46 | templateUrl: '/angular-dimple/examples/partials/ring/index.html', 47 | controller: 'ringController' 48 | }) 49 | .otherwise({ 50 | redirectTo: '/line-graph' 51 | }); 52 | 53 | $logProvider.debugEnabled(true); 54 | 55 | }]); 56 | -------------------------------------------------------------------------------- /docs/source/assets/js/controllers.js: -------------------------------------------------------------------------------- 1 | angular.module('myApp.controllers', []) 2 | 3 | .controller('testController', ['$scope', 'dataService', function($scope, dataService) { 4 | $scope.palette = [ 5 | { 6 | name: "Black Mesa", 7 | fill: "#FFBEB4", 8 | }, 9 | { 10 | name: "Aperture", 11 | fill: "#7B9ACC", 12 | }, 13 | { 14 | name: "Tyrell Corp", 15 | fill: "#D1FFA9", 16 | } 17 | ]; 18 | 19 | $scope.line = true; 20 | 21 | $scope.generate_data = function () { 22 | var retary = []; 23 | for (var i = 0; i < 5; i++) { 24 | var date = new Date(Date.now() + i * 86400000); 25 | var obj = { 26 | 'Date': date, 27 | 'Month': date.getMonth() + '-' + date.getDate(), 28 | 'Owner': 'Aperture', 29 | 'Unit Sales': (Math.random() * 1000) + 1000 30 | }; 31 | retary[retary.length] = obj; 32 | } 33 | return {'data': retary}; 34 | }; 35 | 36 | $scope.update_data = function () { 37 | $scope.graphData = $scope.generate_data().data; 38 | }; 39 | 40 | $scope.update_data(); 41 | 42 | }]) 43 | 44 | .controller('lineGraphController', ['$scope', 'dataService', function($scope, dataService) { 45 | dataService.getData().then(function(response) { 46 | $scope.graphData = response.data; 47 | $scope.arrayOfData = [{data: response.data}, {data: response.data}]; 48 | }); 49 | }]) 50 | 51 | .controller('areaController', ['$scope', 'dataService', function($scope, dataService) { 52 | dataService.getData().then(function(response) { 53 | $scope.graphData = response.data; 54 | }); 55 | }]) 56 | 57 | .controller('stackedAreaController', ['$scope', 'dataService', function($scope, dataService) { 58 | dataService.getData().then(function(response) { 59 | $scope.graphData = response.data; 60 | }); 61 | }]) 62 | 63 | .controller('expandedAreaController', ['$scope', 'dataService', function($scope, dataService) { 64 | dataService.getData().then(function(response) { 65 | $scope.graphData = response.data; 66 | }); 67 | }]) 68 | 69 | .controller('barController', ['$scope', 'dataService', function($scope, dataService) { 70 | dataService.getData().then(function(response) { 71 | $scope.graphData = response.data; 72 | }); 73 | }]) 74 | 75 | .controller('stackedBarController', ['$scope', 'dataService', function($scope, dataService) { 76 | dataService.getData().then(function(response) { 77 | $scope.graphData = response.data; 78 | }); 79 | }]) 80 | 81 | .controller('ringController', ['$scope', 'dataService', function($scope, dataService) { 82 | dataService.getData().then(function(response) { 83 | $scope.graphData = response.data; 84 | }); 85 | }]) 86 | 87 | .controller('scatterController', ['$scope', 'dataService', function($scope, dataService) { 88 | dataService.getData().then(function(response) { 89 | $scope.graphData = response.data; 90 | }); 91 | dataService.getSimpleData().then(function(response) { 92 | $scope.simpleData = response.data; 93 | }); 94 | }]); -------------------------------------------------------------------------------- /docs/source/assets/js/directives.js: -------------------------------------------------------------------------------- 1 | angular.module('myApp.directives', []) 2 | 3 | .directive('appVersion', ['version', function(version) { 4 | return function(scope, elm, attrs) { 5 | elm.text(version); 6 | }; 7 | }]); -------------------------------------------------------------------------------- /docs/source/assets/js/filters.js: -------------------------------------------------------------------------------- 1 | angular.module('myApp.filters', []) 2 | 3 | .filter('interpolate', ['version', function(version) { 4 | return function(text) { 5 | return String(text).replace(/\%VERSION\%/mg, version); 6 | }; 7 | }]); 8 | -------------------------------------------------------------------------------- /docs/source/assets/js/services.js: -------------------------------------------------------------------------------- 1 | angular.module('myApp.services', []) 2 | 3 | .service('dataService', ['$http', function($http) { 4 | return { 5 | getData: function() { 6 | return $http.get('/angular-dimple/data/example_data.json'); 7 | }, 8 | getSimpleData: function() { 9 | return $http.get('/angular-dimple/data/simple.json'); 10 | } 11 | }; 12 | }]); 13 | -------------------------------------------------------------------------------- /docs/source/assets/js/tailcoat.js: -------------------------------------------------------------------------------- 1 | /*! tailcoat - v1.1.8 - 2014-08-21 2 | * https://github.com/ArcGIS/tailcoat 3 | * Copyright (c) 2014 Environmental Systems Research Institute, Inc. 4 | * Apache 2.0 License */ 5 | (function Tailcoat () { 6 | 7 | var T = {}; 8 | 9 | // ┌───────────────┐ 10 | // │ DOM utilities │ 11 | // └───────────────┘ 12 | 13 | var dom = T.utils = {}; 14 | 15 | // ┌──────────────────────┐ 16 | // │ DOM event management │ 17 | // └──────────────────────┘ 18 | 19 | // returns standard interaction event based on touch support 20 | dom.event = function () { 21 | return "click"; 22 | }; 23 | 24 | // add a callback function to an event on an element 25 | dom.addEvent = function (el, event, fn) { 26 | if (el.addEventListener) { 27 | return el.addEventListener(event, fn, false); 28 | } 29 | if (el.attachEvent) { 30 | return el.attachEvent('on' + event, fn); 31 | } 32 | }; 33 | 34 | dom.removeEvent = function (el, event, fn) { 35 | if (el.removeEventListener) { 36 | return el.removeEventListener(event, fn, false); 37 | } 38 | if (el.detachEvent) { 39 | return el.detachEvent('on' + event, fn); 40 | } 41 | }; 42 | 43 | // get the target element of an event 44 | dom.eventTarget = function (event) { 45 | if (!event.target) { 46 | return event.srcElement; 47 | } 48 | if (event.target) { 49 | return event.target; 50 | } 51 | }; 52 | 53 | // prevent default behavior of an event 54 | dom.preventDefault = function (event) { 55 | if (event.preventDefault) { 56 | return event.preventDefault(); 57 | } 58 | if (event.returnValue) { 59 | event.returnValue = false; 60 | } 61 | }; 62 | 63 | // stop and event from bubbling up the DOM tree 64 | dom.stopPropagation = function (event) { 65 | event = event || window.event; 66 | if (event.stopPropagation) { 67 | return event.stopPropagation(); 68 | } 69 | if (event.cancelBubble) { 70 | event.cancelBubble = true; 71 | } 72 | }; 73 | 74 | // ┌────────────────────┐ 75 | // │ class manipulation │ 76 | // └────────────────────┘ 77 | 78 | // check if an element has a specific class 79 | dom.hasClass = function (elem, className) { 80 | var exp = new RegExp(' ' + className + ' '); 81 | if (exp.test(' ' + elem.className + ' ')) { 82 | return true; 83 | } 84 | 85 | return false; 86 | }; 87 | 88 | // add one or more classes to an element 89 | dom.addClass = function (elem, classes) { 90 | classes = classes.split(' '); 91 | 92 | for (var i = 0; i < classes.length; i++) { 93 | if (!dom.hasClass(elem, classes[i])) { 94 | elem.className += ' ' + classes[i]; 95 | } 96 | } 97 | }; 98 | 99 | // remove one or more classes from an element 100 | dom.removeClass = function (elem, classes) { 101 | classes = classes.split(' '); 102 | 103 | for (var i = 0; i < classes.length; i++) { 104 | var newClass = ' ' + elem.className.replace( /[\t\r\n]/g, ' ') + ' '; 105 | 106 | if (dom.hasClass(elem, classes[i])) { 107 | while (newClass.indexOf(' ' + classes[i] + ' ') >= 0) { 108 | newClass = newClass.replace(' ' + classes[i] + ' ', ' '); 109 | } 110 | 111 | elem.className = newClass.replace(/^\s+|\s+$/g, ''); 112 | } 113 | } 114 | }; 115 | 116 | // ┌───────────────┐ 117 | // │ DOM traversal │ 118 | // └───────────────┘ 119 | 120 | // returns closest element up the DOM tree matching a given class 121 | dom.closest = function (className, context) { 122 | var result, current; 123 | for (current = context; current; current = current.parentNode) { 124 | if (current.nodeType === 1 && dom.hasClass(current, className)) { 125 | result = current; 126 | break; 127 | } 128 | } 129 | return current; 130 | }; 131 | 132 | dom.getAttr = function(el, attr) { 133 | if (el.getAttribute) { 134 | return el.getAttribute(attr); 135 | } 136 | 137 | var result; 138 | var attrs = el.attributes; 139 | 140 | for (var i = 0; i < attrs.length; i++) { 141 | if (attrs[i].nodeName === attr) { 142 | result = attrs[i].nodeValue; 143 | } 144 | } 145 | 146 | return result; 147 | }; 148 | 149 | // ┌──────┐ 150 | // │ misc │ 151 | // └──────┘ 152 | 153 | // return the index of an object in an array with optional offset 154 | dom.indexOf = function (obj, arr, offset) { 155 | var i = offset || 0; 156 | 157 | if (arr.indexOf) { 158 | return arr.indexOf(obj, i); 159 | } 160 | 161 | for (i; i < arr.length; i++) { 162 | if (arr[i] === obj) { 163 | return i; 164 | } 165 | } 166 | 167 | return -1; 168 | }; 169 | 170 | dom.makeArray = function (object) { 171 | var array = []; 172 | for (var i = 0; i < object.length; i++) { 173 | array.push(object[i]); 174 | } 175 | return array; 176 | }; 177 | 178 | // ┌───────────────────┐ 179 | // │ feature detection │ 180 | // └───────────────────┘ 181 | // detect features like touch, ie, etc. 182 | 183 | dom.isTouch = function () { 184 | if (('ontouchstart' in window) || (navigator.msMaxTouchPoints > 0)) { 185 | return true; 186 | } 187 | return false; 188 | }; 189 | 190 | dom.isIE8 = function () { 191 | var html = document.getElementsByTagName('html')[0]; 192 | if (dom.hasClass(html, 'ie8')){ 193 | return true; 194 | } else { 195 | return false; 196 | } 197 | }; 198 | 199 | // ┌──────┐ 200 | // │ TABS │ 201 | // └──────┘ 202 | // tabbed content pane 203 | 204 | T.tabs = function () { 205 | var tabs = document.querySelectorAll('.tab'); 206 | if (tabs.length > 0) { 207 | // variables to be used in loops 208 | var i, j, k, tab, group, tabsInGroup, percent; 209 | var tabGroups = document.querySelectorAll('.tab-group'); 210 | 211 | // Attach the switchTab event to all tabs 212 | for (i = 0; i < tabs.length; i++) { 213 | tab = tabs[i]; 214 | dom.addEvent(tab, dom.event(), switchTab); 215 | } 216 | 217 | for (j = 0; j < tabGroups.length; j++) { 218 | group = tabGroups[j]; 219 | tabsInGroup = group.querySelectorAll('.tab'); 220 | percent = 100 / tabsInGroup.length; 221 | 222 | for (k = 0; k < tabsInGroup.length; k++){ 223 | if (dom.isIE8()) { 224 | tabsInGroup[k].style.width = percent + "%"; 225 | } else { 226 | tabsInGroup[k].style.maxWidth = percent + "%"; 227 | } 228 | 229 | } 230 | } 231 | } 232 | }; 233 | 234 | function switchTab (event) { 235 | dom.preventDefault(event); 236 | 237 | var tab; 238 | var target = dom.eventTarget(event); 239 | if (dom.hasClass(target, 'tab')) { 240 | tab = target; 241 | } else { 242 | tab = dom.closest('tab', target); 243 | } 244 | var tabs = dom.closest('tab-nav', tab).querySelectorAll('.tab'); 245 | var index = dom.indexOf(tab, tabs); 246 | var contents = dom.closest('tab-group', tab).querySelectorAll('.tab-content'); 247 | 248 | for (var i = 0; i < tabs.length; i++){ 249 | dom.removeClass(tabs[i], 'active'); 250 | dom.removeClass(contents[i], 'active'); 251 | } 252 | 253 | dom.addClass(tab, 'active'); 254 | dom.addClass(contents[index], 'active'); 255 | } 256 | 257 | T.tabs(); 258 | })(); 259 | -------------------------------------------------------------------------------- /docs/source/data/simple.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "Name": "Tom", 4 | "Height": 64, 5 | "Weight": 190, 6 | "Time": 1408406400000 7 | },{ 8 | "Name": "Tom", 9 | "Height": 68, 10 | "Weight": 195, 11 | "Time": 1408579200000 12 | },{ 13 | "Name": "Tom", 14 | "Height": 69, 15 | "Weight": 198, 16 | "Time": 1408665600000 17 | },{ 18 | "Name": "Tom", 19 | "Height": 70, 20 | "Weight": 205, 21 | "Time": 1408752000000 22 | },{ 23 | "Name": "Tom", 24 | "Height": 67, 25 | "Weight": 198, 26 | "Time": 1408838400000 27 | },{ 28 | "Name": "Tom", 29 | "Height": 76, 30 | "Weight": 195, 31 | "Time": 1408924800000 32 | } 33 | ] 34 | 35 | -------------------------------------------------------------------------------- /docs/source/documentation/_content.md: -------------------------------------------------------------------------------- 1 | # Angular Dimple Documentation 2 | 3 | Angular Dimple is a series of Angular directives that help you create graphs and visualizations based on [Dimple.js](http://dimplejs.org/) and [d3](http://d3js.org/). It's designed to create graphs as simply as possible from flat JSON data. 4 | 5 | ***** 6 | 7 | ## Graph 8 | 9 | The `` directive is the wrapper directive for every type of chart in Angular Dimple. This is where you define what data to graph, as well as the size of the graph. The data property accepts a scope variable, and you should handle the variables creation in your own data service – Dimple Angular provides some simple methods of data filtering on a graph, but avoids intensive data compiling and manipulation. 10 | 11 | This directive creates a div with a dynamic id, and initializes a new Dimple graph inside of it with several default options. Default heighth and width are 100% of the parent container. 12 | 13 | ```html 14 | 15 | 16 | 17 | ``` 18 | 19 | #### Attributes 20 | 21 | | attribute | default | description | 22 | | --------- | ----------- | ----------- | 23 | | data | none | **Required.** Angular Dimple graphs accept flat JSON files as a $scope variable, set from a service. Or something | 24 | | width | 100% | Accepts a percent or a number. Sets the width of the chart, either in pixels or percent. | 25 | | height | 100% | Accepts a percent or a number. Sets the width of the chart, either in pixels or percent. | 26 | | auto-style | true | Boolean. If false, no default dimple color, fill, or stroke styles will be applied to the graph. Allows for custom css styling. | 27 | | color | none | String. Matches to a color palette on the scope. See below for syntax | 28 | 29 | ```js 30 | $scope.palette = [ 31 | { 32 | name: "Black Mesa", // Required, name of field to assign 33 | fill: "#FFBEB4", // Requried, fill color 34 | stroke: "#FFBEB4", // Optional, stroke color 35 | opacity: "1" // Optional, opacity 36 | }, 37 | { 38 | name: "Aperture", 39 | fill: "#7B9ACC", 40 | stroke: "#7B9ACC", 41 | opacity: "1" 42 | }, 43 | { 44 | name: "Tyrell Corp", 45 | fill: "#D1FFA9", 46 | stroke: "#D1FFA9", 47 | opacity: "1" 48 | } 49 | ]; 50 | ``` 51 | 52 | ***** 53 | 54 | ## X 55 | 56 | The `` directive sets up your x axis for the graph. Defining an x axis is required. Because it's graph. Be default, `` will expect to tie to categorical data rather than measure data. 57 | 58 | ```html 59 | 60 | ``` 61 | 62 | #### Attributes 63 | 64 | | attribute | default | description | 65 | | --------- | ----------- | ----------- | 66 | | field | none | **Required.** Field from your data to set as the X-Axis. | 67 | | type | Category | Accepts 'Category', 'Measure', or 'Percent'. Defines axis type. | 68 | | order-by | none | Field from your data to order the x axis by. | 69 | | group-by | none | Creates small mutliple graphs grouped by a Categorical data field. 70 | | title | field value | Labels the x axis. If 'null', will not draw a title for the axis. | 71 | 72 | ***** 73 | 74 | ## Y 75 | 76 | The `` directive sets up your y axis for the graph. One y axis is requires, but you can set multiple axes of each type and the graph will display them. By default, `` will expect to plot measure data rather than categorical data. 77 | 78 | Changing the axis to to 'Percent' will tie the largest value on the defined field to 100%, and compare the rest of the values to that. 79 | 80 | ```html 81 | 82 | ``` 83 | 84 | #### Attributes 85 | 86 | | attribute | default | description | 87 | | --------- | ----------- | ----------- | 88 | | field | none | **Required.** Field from your data to set as the Y-Axis. | 89 | | type | Measure | Accepts 'Category', 'Measure', or 'Percent'. Defines axis type. | 90 | | order-by | none | Field from your data to order the y axis by. | 91 | | group-by | none | Creates small mutliple graphs grouped by a Categorical data field. 92 | | title | field value | Labels the y-axis. If 'null', will not draw a title for the axis. | 93 | 94 | ***** 95 | 96 | ## Legend 97 | 98 | The `` directive creates a legend for your graph. The legend is generated from the plotted data. 99 | 100 | | attribute | default | description | 101 | | --------- | ----------- | ----------- | 102 | | left | 10% | Accepts a percent or a number. Sets position from left of chart in either pixels or percent. | 103 | | top | 4% | Accepts a percent or a number. Sets position from top of chart in either pixels or percent. | 104 | | height | 100% | Accepts a percent or a number. Sets height of legend in either pixels or percent. | 105 | | width | 90% | Accepts a percent or a number. Sets width of legend in either pixels or percent. | 106 | | position | left | Accepts 'left' or 'right'. Set float position of legend. | 107 | 108 | ***** 109 | 110 | ## Line 111 | example 112 | 113 | The `` directive plots your data as a line. The `field` attribute (required) will define the field from your data to plot to the graph. The `value` attribute will plot a single line to your graph for that value in the field. You can include as many line elements in your graph as you have unique values. Leaving the `value` attribute blank will plot each unique value in the data set as it's own line. 114 | 115 | ```html 116 | 117 | 118 | 119 | 120 | 121 | 122 | ``` 123 | 124 | #### Attributes 125 | 126 | | attribute | description | 127 | | --------- | ----------- | 128 | | field | **Required.** Field to plot as a line. | 129 | | value | Will plot a line where the field is the given value. | 130 | | filter | Accepts a string 'field:value'. Will filter the data to only points where the defined field matches the defined value. | 131 | 132 | ***** 133 | 134 | ## Bar 135 | example 136 | 137 | The `` directive plots your data as series of bars. The `field` attribute (required) will define the field from your data to plot to the graph. The `value` attribute will plot the bars to your graph for that value in the field. If no value is defined, or multiple bars are included in the graph, the data will plot as a stacked bar. 138 | 139 | ```html 140 | 141 | 142 | 143 | 144 | 145 | ``` 146 | 147 | #### Attributes 148 | 149 | | attribute | description | 150 | | --------- | ----------- | 151 | | field | **Required.** Field to plot as a line. | 152 | | value | Will plot a line where the field is the given value. | 153 | | filter | Accepts a string 'field:value'. Will filter the data to only points where the defined field matches the defined value. | 154 | 155 | ***** 156 | 157 | ***** 158 | 159 | ## Stacked Bar 160 | example 161 | 162 | The `` directive plots your data as series of bars. The `field` attribute (required) will define the field from your data to plot to the graph. The `value` attribute will plot the bars to your graph for that value in the field. If no value is defined, or multiple bars are included in the graph, the data will plot as a stacked bar. 163 | 164 | ```html 165 | 166 | 167 | 168 | 169 | 170 | ``` 171 | 172 | #### Attributes 173 | 174 | | attribute | description | 175 | | --------- | ----------- | 176 | | field | **Required.** Field to plot as a line. | 177 | | value | Will plot a line where the field is the given value. | 178 | | filter | Accepts a string 'field:value'. Will filter the data to only points where the defined field matches the defined value. | 179 | 180 | ***** 181 | 182 | ## Area 183 | example 184 | 185 | The `` directive plots your data to an area chart. The `field` attribute will define the field from your data to plot to the graph. The `value` attribute will plot a single area to your graph for that value in the field. You can include as many area elements in your graph as you have unique values. 186 | 187 | ```html 188 | 189 | 190 | 191 | 192 | 193 | 194 | ``` 195 | 196 | #### Attributes 197 | 198 | | attribute | description | 199 | | --------- | ----------- | 200 | | field | **Required.** Field to plot as a line. | 201 | | value | Will plot a line where the field is the given value. | 202 | | filter | Accepts a string 'field:value'. Will filter the data to only points where the defined field matches the defined value. | 203 | 204 | ***** 205 | 206 | ## Stacked Area 207 | example 208 | 209 | The `` directive plots your data to a stacked area chart. The `field` attribute will define the field from your data to plot to the graph. The `value` attribute will plot a single line to your graph for that value in the field. You can include as many area elements in your graph as you have unique values. 210 | 211 | ```html 212 | 213 | 214 | 215 | 216 | 217 | 218 | ``` 219 | 220 | ### Expanded Stacked Area 221 | example 222 | 223 | Setting the y axis in a stacked area graph with create an expanded stacked area, where the total combined value of the field is equal to 100%. 224 | 225 | ```html 226 | 227 | 228 | ``` 229 | 230 | #### Attributes 231 | 232 | | attribute | description | 233 | | --------- | ----------- | 234 | | field | **Required.** Field to plot as a line. | 235 | | value | Will plot a line where the field is the given value. | 236 | | filter | Accepts a string 'field:value'. Will filter the data to only points where the defined field matches the defined value. | 237 | 238 | 239 | ***** 240 | 241 | ## Scatter Plot 242 | example 243 | 244 | The `` directive plots your data to an scatter plot chart. The `field` attribute will define the field from your data to plot to the graph. The `value` attribute will plot a single scatter plot to your graph for that value in the field. You can include as many scatter plot elements in your graph as you have unique values. 245 | 246 | Scatter Plots also use the `series` attribute. Series defines the categorical data to plot against the fields on the axes. 247 | 248 | ```html 249 | 250 | 251 | 252 | 253 | 254 | 255 | ``` 256 | 257 | #### Attributes 258 | 259 | | attribute | description | 260 | | --------- | ----------- | 261 | | field | **Required.** Field to plot as a line. | 262 | | value | Will plot a line where the field is the given value. | 263 | | series | Accepts a string 'field'. | 264 | | filter | Accepts a string 'field:value'. Will filter the data to only points where the defined field matches the defined value. | 265 | 266 | ***** 267 | 268 | ## Ring 269 | example 270 | 271 | The `ring` directive creates pie and donut charts - but require a seperate type of axis that the other charts in Angular Dimple. A ring chart uses a `

` axis to plot a single measure. Adding multiple series to a ring chart will create concentric circles within the chart. 272 | 273 | You can define both the thickness of the ring (as a percentage) and the diameter of the ring (as a percentage). 274 | 275 | ```html 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | > 284 | ``` 285 | 286 | #### Attributes 287 | 288 | | attribute | description | 289 | | --------- | ----------- | 290 | | field | **Required.** Field to plot as a ring. | 291 | | thickness | Accepts a number. Width of ring, as percent of circle size. | 292 | | diameter | Accepts a number. Size of ring, as percent of circle size. | 293 | 294 | 295 | 296 | -------------------------------------------------------------------------------- /docs/source/documentation/index.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | 4 | 74 | 75 |
76 | 77 |
78 | 79 | 80 |
81 |
82 | {% markdown %}{% include 'documentation/_content' %}{% endmarkdown %} 83 |
84 |
85 | 86 |
87 |
-------------------------------------------------------------------------------- /docs/source/examples/index.html: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Examples Angular App Thing" 3 | description: "Should process a nested index.html page correctly" 4 | --- 5 |
6 |
7 | 8 | 54 | 55 |
56 | 57 |
58 | 59 | 60 |
61 |
62 |
63 |
64 |
65 | -------------------------------------------------------------------------------- /docs/source/examples/partials/animation-test.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: false 3 | --- 4 |
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 16 | -------------------------------------------------------------------------------- /docs/source/examples/partials/area.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: false 3 | --- 4 |

5 | Area Graph 6 | 7 | Area Graph Documentation 8 | 9 |

10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | ``` 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 | 29 |
30 | ``` 31 | 32 | 33 |
34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 |
43 | 44 | ``` 45 | 46 |
47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 |
56 | ``` -------------------------------------------------------------------------------- /docs/source/examples/partials/bar-graph.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: false 3 | --- 4 |

5 | Bar Graph 6 | 7 | Bar Graph Documentation 8 | 9 |

10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | ```html 21 | 22 | 23 | 24 | 25 | 26 | 27 | ``` 28 | 29 |
30 | 31 | 32 | 33 | 34 | 35 |
36 | 37 | ```html 38 | 39 | 40 | 41 | 42 | 43 | ``` -------------------------------------------------------------------------------- /docs/source/examples/partials/expanded-stacked-area.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: false 3 | --- 4 |

5 | Expanded Stacked Area 6 | 7 | Expanded Stacked Area Documentation 8 | 9 |

10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | ```html 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | ``` 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | ```html 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | ``` -------------------------------------------------------------------------------- /docs/source/examples/partials/homepage-code.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: false 3 | --- 4 | ```html 5 | 6 | 7 | 8 | 9 | 10 | 11 | ``` 12 | 13 | index.html: 14 | 15 | ```html 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 |
30 | 31 | 32 | 33 | 34 | 35 | ``` 36 | 37 | app.js 38 | 39 | ```js 40 | angular.module('myApp', [ 41 | 'angular-dimple' 42 | ]) 43 | 44 | .controller('myController', ['$scope', 'dataService', function($scope, dataService) { 45 | dataService.getData().then(function(response) { 46 | $scope.graphData = response.data; 47 | }); 48 | }]) 49 | 50 | .service('dataService', ['$http', function($http) { 51 | return { 52 | getData: function() { 53 | return $http.get('data.json'); 54 | } 55 | }; 56 | }]); 57 | ``` 58 | 59 | data.json 60 | 61 | ```json 62 | [ 63 | { 64 | "Date": "01\/01\/2011", 65 | "Month": "Jan-11", 66 | "Owner": "Aperture", 67 | "Unit Sales": "1765" 68 | }, 69 | { 70 | "Date": "02\/01\/2011", 71 | "Month": "Jan-11", 72 | "Owner": "Aperture", 73 | "Unit Sales": "1899" 74 | }, 75 | { 76 | "Date": "02\/01\/2011", 77 | "Month": "Jan-11", 78 | "Owner": "Aperture", 79 | "Unit Sales": "1565" 80 | } 81 | ] 82 | ``` 83 | 84 | -------------------------------------------------------------------------------- /docs/source/examples/partials/line-graph.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: false 3 | --- 4 |

5 | Line Graph 6 | 7 | Line Graph Documentation 8 | 9 |

10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | ```html 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | ``` 29 | 30 |
31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 |
40 | 41 | ```html 42 | 43 | 44 | 45 | 46 |
47 | 48 | 49 | 50 |
51 | ``` 52 | 53 | ## Inside ng-repeat 54 |
55 | 56 | 57 | 58 | 59 | 60 | 61 |
62 | 63 | ```html 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | ``` -------------------------------------------------------------------------------- /docs/source/examples/partials/ring.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: false 3 | --- 4 |

5 | Ring Chart 6 | 7 | Ring Chart Documentation 8 | 9 |

10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | ```html 20 | 21 | 22 | 23 | 24 | 25 | 26 | ``` 27 | 28 |

29 | Multi Ring Chart 30 | 31 | Ring Chart Documentation 32 | 33 |

34 | 35 |
36 | 37 | 38 | 39 | 40 | 41 | 42 |
43 | 44 | ```html 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | ``` -------------------------------------------------------------------------------- /docs/source/examples/partials/scatter-plot.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: false 3 | --- 4 |

5 | Scatter Plot 6 | 7 | Scatter Plot Documentation 8 | 9 |

10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | ```html 21 | 22 | 23 | 24 | 25 | 26 | 28 | 29 | 30 | ``` 31 |
32 | 33 | 34 | 35 | 36 | 37 | 38 |
39 | 40 | ```html 41 | 42 | 43 | 44 | 45 | 47 | 48 | 49 | ``` 50 | 51 |
52 | 53 | 54 | 55 | 56 | 57 |
58 | 59 | ```html 60 | 61 | 62 | 63 | 65 | 66 | 67 | ``` 68 | 69 | ```json 70 | [ 71 | { 72 | "Height": 64, 73 | "Weight": 190 74 | },{ 75 | "Height": 68, 76 | "Weight": 195 77 | },{ 78 | "Height": 69, 79 | "Weight": 198 80 | },{ 81 | "Height": 70, 82 | "Weight": 205 83 | },{ 84 | "Height": 67, 85 | "Weight": 198 86 | },{ 87 | "Height": 76, 88 | "Weight": 195 89 | } 90 | ] 91 | ``` -------------------------------------------------------------------------------- /docs/source/examples/partials/stacked-area.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: false 3 | --- 4 |

5 | Stacked Area 6 | 7 | Stacked Area Documentation 8 | 9 |

10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | ```html 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | ``` 29 | 30 |
31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 |
39 | 40 | ```html 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | ``` 50 | 51 |

52 | Expanded Stacked Area 53 | 54 | Stacked Area Documentation 55 | 56 |

57 | 58 |
59 | 60 | 61 | 62 | 63 | 64 | 65 |
66 | 67 | ``` 68 | 69 | 70 | 71 | 72 | 73 | 74 | ``` 75 | -------------------------------------------------------------------------------- /docs/source/examples/partials/stacked-bar-graph.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: false 3 | --- 4 |

5 | Stacked Bar 6 | 7 | Stacked Bar Documentatoin 8 | 9 |

10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | ```html 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | ``` 29 | 30 |
31 | 32 | 33 | 34 | 35 | 36 |
37 | 38 | ```html 39 | 40 | 41 | 42 | 43 | 44 | ``` 45 | -------------------------------------------------------------------------------- /docs/source/index.html: -------------------------------------------------------------------------------- 1 | --- 2 | title: Acetate 3 | active: home 4 | --- 5 | 6 | 49 | 50 | 51 | 52 |
53 |
54 |
55 |
56 |

The Power of Angular Directives

57 |

With Angular directives, Angular-Dimple allows you to create graphs and visualizations clearly and declaratively. Want a line graph? Just use a <line> element inside of a <graph> element. Add some axes and you're done.

58 |
59 |
60 |
61 | 65 |
66 |
67 | {% markdown %} 68 | ``` 69 | 70 | 71 | 72 | 73 | 74 | 75 | ``` 76 | {% endmarkdown %} 77 |
78 |
79 | 80 | 81 | 82 | 83 | 84 | 85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 | 93 | 94 | 95 |
96 |
97 |
98 | 99 | 100 | 101 |

102 | Line 103 |

104 |

105 | Examples | 106 | Reference 107 |

108 |
109 |
110 | 111 | 112 | 113 |

114 | Area 115 |

116 |

117 | Examples | 118 | Reference 119 |

120 |
121 |
122 | 123 | 124 | 125 |

126 | Stacked Area 127 |

128 |

129 | Examples | 130 | Reference 131 |

132 |
133 |
134 | 135 | 136 | 137 |

138 | Bar 139 |

140 |

141 | Examples | 142 | Reference 143 |

144 |
145 |
146 | 147 | 148 | 149 |

150 | Stacked Bar 151 |

152 |

153 | Examples | 154 | Reference 155 |

156 |
157 |
158 | 159 | 160 | 161 |

162 | Scatter Plot 163 |

164 |

165 | Examples | 166 | Reference 167 |

168 |
169 | 170 |
171 | 172 | 173 | 174 |

175 | Ring 176 |

177 |

178 | Examples | 179 | Reference 180 |

181 |
182 |
183 | 184 | 185 |
186 |
187 |
188 |
189 |

Get Started

190 |

1Create a basic Angular app

191 |

2Include Angular-Dimple as a dependency

192 |

3Add data

193 |
194 |
195 |
196 | 201 |
202 |
203 | {% markdown %} 204 | ``` 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 |
213 | 214 | 215 | 216 | 217 | 218 |
219 | 220 | 221 | 222 | 223 | 224 | ``` 225 | {% endmarkdown %} 226 |
227 |
228 | {% markdown %} 229 | ``` 230 | angular.module('myApp', [ 231 | 'angular-dimple' 232 | ]) 233 | 234 | .controller('myController', ['$scope', 'dataService', function($scope, dataService) { 235 | dataService.getData().then(function(response) { 236 | $scope.graphData = response.data; 237 | }); 238 | }]) 239 | 240 | .service('dataService', ['$http', function($http) { 241 | return { 242 | getData: function() { 243 | return $http.get('data.json'); 244 | } 245 | }; 246 | }]); 247 | ``` 248 | {% endmarkdown %} 249 |
250 |
251 | {% markdown %} 252 | ``` 253 | [ 254 | { 255 | "Date": "01\/01\/2011", 256 | "Month": "Jan-11", 257 | "Owner": "Aperture", 258 | "Unit Sales": "1765" 259 | }, 260 | { 261 | "Date": "02\/01\/2011", 262 | "Month": "Jan-11", 263 | "Owner": "Aperture", 264 | "Unit Sales": "1899" 265 | }, 266 | { 267 | "Date": "02\/01\/2011", 268 | "Month": "Jan-11", 269 | "Owner": "Aperture", 270 | "Unit Sales": "1565" 271 | } 272 | ] 273 | ``` 274 | {% endmarkdown %} 275 |
276 |
277 |
278 |
279 |
280 |
281 |
282 |
283 | -------------------------------------------------------------------------------- /docs/source/layouts/_layout.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | {{title}} | Angular Dimple 5 | 6 | 7 | 8 | 9 | {% block head %} 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | {% endblock %} 18 | 19 | 20 | 21 | 40 | 41 | {% block content %}{% endblock %} 42 | 43 | 44 |
45 |
46 |
47 |
48 |

Made by EsriPDX

49 | 52 | 55 |
56 |
57 |
58 |
59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | -------------------------------------------------------------------------------- /lib/angular-dimple.js: -------------------------------------------------------------------------------- 1 | angular.module('angular-dimple', [ 2 | 'angular-dimple.graph', 3 | 'angular-dimple.legend', 4 | 'angular-dimple.x', 5 | 'angular-dimple.y', 6 | 'angular-dimple.r', 7 | 'angular-dimple.line', 8 | 'angular-dimple.bar', 9 | 'angular-dimple.stacked-bar', 10 | 'angular-dimple.area', 11 | 'angular-dimple.stacked-area', 12 | 'angular-dimple.scatter-plot', 13 | 'angular-dimple.ring' 14 | ]) 15 | 16 | .constant('MODULE_VERSION', '0.0.1') 17 | 18 | .value('defaults', { 19 | foo: 'bar' 20 | }); -------------------------------------------------------------------------------- /lib/area.js: -------------------------------------------------------------------------------- 1 | angular.module('angular-dimple.area', []) 2 | 3 | .directive('area', [function () { 4 | return { 5 | restrict: 'E', 6 | replace: true, 7 | require: ['area', '^graph'], 8 | controller: ['$scope', '$element', '$attrs', function($scope, $element, $attrs) { 9 | }], 10 | link: function($scope, $element, $attrs, $controllers) { 11 | var graphController = $controllers[1]; 12 | var areaController = $controllers[0]; 13 | var chart = graphController.getChart(); 14 | 15 | function addArea () { 16 | if ($attrs.value) { 17 | area = chart.addSeries([$attrs.field], dimple.plot.area); 18 | graphController.filter($attrs); 19 | area.lineMarkers = true; 20 | } else { 21 | var values = dimple.getUniqueValues($scope.data, $attrs.field); 22 | angular.forEach(values, function(value){ 23 | area = chart.addSeries([$attrs.field], dimple.plot.area); 24 | graphController.filter($attrs); 25 | area.lineMarkers = true; 26 | }); 27 | } 28 | graphController.draw(); 29 | } 30 | 31 | $scope.$watch('dataReady', function(newValue, oldValue) { 32 | if (newValue === true) { 33 | addArea(); 34 | } 35 | }); 36 | } 37 | }; 38 | }]); 39 | 40 | -------------------------------------------------------------------------------- /lib/bar.js: -------------------------------------------------------------------------------- 1 | angular.module('angular-dimple.bar', []) 2 | 3 | .directive('bar', [function () { 4 | return { 5 | restrict: 'E', 6 | replace: true, 7 | require: ['bar', '^graph'], 8 | controller: ['$scope', '$element', '$attrs', function($scope, $element, $attrs) { 9 | }], 10 | link: function($scope, $element, $attrs, $controllers) { 11 | var graphController = $controllers[1]; 12 | var lineController = $controllers[0]; 13 | var chart = graphController.getChart(); 14 | 15 | function addBar () { 16 | var filteredData; 17 | bar = chart.addSeries([$attrs.field], dimple.plot.bar); 18 | graphController.filter($attrs); 19 | graphController.draw(); 20 | } 21 | 22 | 23 | 24 | $scope.$watch('dataReady', function(newValue, oldValue) { 25 | if (newValue === true) { 26 | addBar(); 27 | } 28 | }); 29 | } 30 | }; 31 | }]); -------------------------------------------------------------------------------- /lib/graph.js: -------------------------------------------------------------------------------- 1 | angular.module('angular-dimple.graph', []) 2 | 3 | .directive('graph', ['$window', function ($window) { 4 | return { 5 | restrict: 'E', 6 | replace: true, 7 | scope: { 8 | data: '=', 9 | color: '=' 10 | }, 11 | require: ['graph'], 12 | transclude: true, 13 | link: function (scope, element, attrs, controllers, transclude) { 14 | var graphController = controllers[0]; 15 | graphController._createChart(); 16 | scope.dataReady = false; 17 | scope.filters = []; 18 | 19 | var chart = graphController.getChart(); 20 | var transition; 21 | if (attrs.transition) { 22 | transition = attrs.transition; 23 | } else { 24 | transition = 750; 25 | } 26 | 27 | scope.$watch('data', function(newValue, oldValue) { 28 | if (newValue) { 29 | scope.dataReady = true; 30 | graphController.setData(); 31 | chart.draw(transition); 32 | } 33 | }); 34 | 35 | transclude(scope, function(clone){ 36 | element.append(clone); 37 | }); 38 | 39 | scope.onResize = function() { 40 | if (graphController.getAutoresize()){ 41 | var chart = graphController.getChart(); 42 | if (chart){ 43 | chart.draw(0, true); 44 | } 45 | } 46 | }; 47 | 48 | angular.element($window).bind('resize', function() { 49 | scope.onResize(); 50 | }); 51 | 52 | }, 53 | controller: ['$scope', '$element', '$attrs', function($scope, $element, $attrs) { 54 | var chart; 55 | var autoresize = false; 56 | var id = (Math.random() * 1e9).toString(36).replace(".", "_"); 57 | $element.append('
'); 58 | 59 | this._createChart = function () { 60 | // create an svg element 61 | 62 | var width = $attrs.width ? $attrs.width : '100%'; 63 | var height = $attrs.height ? $attrs.height : '100%'; 64 | autoresize = $attrs.autoresize ? $attrs.autoresize.toLowerCase()==='true' : false; 65 | 66 | var svg = dimple.newSvg('#dng-'+ id +'', width, height); 67 | var data = $scope.data; 68 | 69 | // create the dimple chart using the d3 selection of our element 70 | chart = new dimple.chart(svg, data); 71 | 72 | if ($attrs.margin) { 73 | chart.setMargins($attrs.margin); 74 | } else { 75 | chart.setMargins(60, 60, 20, 40); 76 | } 77 | 78 | // auto style 79 | var autoStyle = $attrs.autoStyle === 'false' ? true : false; 80 | chart.noFormats = autoStyle; 81 | 82 | // Apply palette styles 83 | if ($attrs.color) { 84 | var palette = $scope.color; 85 | for (var i = 0; i < palette.length; i++ ) { 86 | chart.assignColor(palette[i].name, palette[i].fill, palette[i].stroke, palette[i].opacity); 87 | } 88 | } 89 | }; 90 | 91 | this.getAutoresize = function (){ 92 | return autoresize; 93 | }; 94 | 95 | this.getChart = function () { 96 | return chart; 97 | }; 98 | 99 | this.setData = function () { 100 | chart.data = $scope.data; 101 | }; 102 | 103 | this.draw = function () { 104 | chart.draw(); 105 | }; 106 | 107 | this.getID = function () { 108 | return id; 109 | }; 110 | 111 | this.filter = function (attrs) { 112 | if (attrs.value !== undefined) { 113 | $scope.filters.push(attrs.value); 114 | } 115 | if ($scope.filters.length) { 116 | chart.data = dimple.filterData($scope.data, attrs.field, $scope.filters); 117 | } 118 | 119 | if (attrs.filter !== undefined) { 120 | console.log("i see a filter"); 121 | var thisFilter = attrs.filter.split(':'); 122 | var field = thisFilter[0]; 123 | var value = [thisFilter[1]]; 124 | chart.data = dimple.filterData($scope.data, field, value); 125 | } 126 | }; 127 | 128 | }] 129 | }; 130 | }]); -------------------------------------------------------------------------------- /lib/legend.js: -------------------------------------------------------------------------------- 1 | angular.module('angular-dimple.legend', []) 2 | 3 | .directive('graphLegend', [function () { 4 | return { 5 | restrict: 'E', 6 | replace: true, 7 | require: ['graphLegend', '^graph'], 8 | controller: ['$scope', '$element', '$attrs', function($scope, $element, $attrs) { 9 | }], 10 | link: function($scope, $element, $attrs, $controllers) { 11 | var graphController = $controllers[1]; 12 | var chart = graphController.getChart(); 13 | 14 | function addLegend () { 15 | var left = $attrs.left ? $attrs.left : "10%"; 16 | var top = $attrs.top ? $attrs.top : "4%"; 17 | var height = $attrs.height ? $attrs.height : "10%"; 18 | var width = $attrs.width ? $attrs.width : "90%"; 19 | var position = $attrs.position ? $attrs.position : 'left'; 20 | chart.addLegend(left, top, width, height, position); 21 | } 22 | 23 | $scope.$watch('dataReady', function(newValue, oldValue) { 24 | if (newValue === true) { 25 | addLegend(); 26 | } 27 | }); 28 | } 29 | }; 30 | }]); -------------------------------------------------------------------------------- /lib/line.js: -------------------------------------------------------------------------------- 1 | angular.module('angular-dimple.line', []) 2 | 3 | .directive('line', [function () { 4 | return { 5 | restrict: 'E', 6 | replace: true, 7 | require: ['line', '^graph'], 8 | controller: ['$scope', '$element', '$attrs', function($scope, $element, $attrs) { 9 | }], 10 | link: function($scope, $element, $attrs, $controllers) { 11 | var graphController = $controllers[1]; 12 | var chart = graphController.getChart(); 13 | var drawn = false; 14 | 15 | function addLine () { 16 | var filteredData; 17 | line = chart.addSeries([$attrs.field], dimple.plot.line); 18 | graphController.filter($attrs); 19 | line.lineMarkers = true; 20 | graphController.draw(); 21 | } 22 | 23 | $scope.$watch('dataReady', function(newValue, oldValue) { 24 | if (newValue === true) { 25 | addLine(); 26 | } 27 | }); 28 | 29 | } 30 | }; 31 | }]); -------------------------------------------------------------------------------- /lib/r.js: -------------------------------------------------------------------------------- 1 | angular.module('angular-dimple.r', []) 2 | 3 | .directive('r', [function () { 4 | return { 5 | restrict: 'E', 6 | replace: true, 7 | require: ['r', '^graph'], 8 | controller: ['$scope', '$element', '$attrs', function($scope, $element, $attrs) { 9 | }], 10 | link: function($scope, $element, $attrs, $controllers) { 11 | var graphController = $controllers[1]; 12 | var chart = graphController.getChart(); 13 | 14 | function addAxis () { 15 | r = chart.addMeasureAxis('p', $attrs.field); 16 | 17 | if ($attrs.title && $attrs.title !== "null") { 18 | r.title = $attrs.title; 19 | } else if ($attrs.title == "null") { 20 | r.title = null; 21 | } 22 | } 23 | 24 | $scope.$watch('data', function(newValue, oldValue) { 25 | if (newValue) { 26 | addAxis(); 27 | } 28 | }); 29 | } 30 | }; 31 | }]); -------------------------------------------------------------------------------- /lib/ring.js: -------------------------------------------------------------------------------- 1 | angular.module('angular-dimple.ring', []) 2 | 3 | .directive('ring', [function () { 4 | return { 5 | restrict: 'E', 6 | replace: true, 7 | require: ['ring', '^graph'], 8 | controller: ['$scope', '$element', '$attrs', function($scope, $element, $attrs) { 9 | }], 10 | link: function($scope, $element, $attrs, $controllers) { 11 | var graphController = $controllers[1]; 12 | var areaController = $controllers[0]; 13 | var chart = graphController.getChart(); 14 | 15 | function setData (data, series) { 16 | series.data = data; 17 | } 18 | 19 | function addRing () { 20 | var thickness; 21 | ring = chart.addSeries([$attrs.field], dimple.plot.pie); 22 | if ($attrs.thickness && !$attrs.diameter) { 23 | thickness = (100 - $attrs.thickness) + '%'; 24 | ring.innerRadius = thickness; 25 | } else if ($attrs.thickness && $attrs.diameter) { 26 | thickness = ($attrs.diameter - $attrs.thickness) + '%'; 27 | ring.innerRadius = thickness; 28 | } else { 29 | ring.innerRadius = "50%"; 30 | } 31 | 32 | if ($attrs.diameter) { 33 | ring.outerRadius = ($attrs.diameter) + '%'; 34 | } 35 | graphController.filter($attrs); 36 | graphController.draw(); 37 | } 38 | 39 | $scope.$watch('data', function(newValue, oldValue) { 40 | if (newValue) { 41 | addRing(); 42 | } 43 | }); 44 | } 45 | }; 46 | }]); 47 | 48 | -------------------------------------------------------------------------------- /lib/scatter-plot.js: -------------------------------------------------------------------------------- 1 | angular.module('angular-dimple.scatter-plot', []) 2 | 3 | .directive('scatterPlot', [function () { 4 | return { 5 | restrict: 'E', 6 | replace: true, 7 | require: ['scatterPlot', '^graph'], 8 | controller: [function() {}], 9 | link: function($scope, $element, $attrs, $controllers) { 10 | var graphController = $controllers[1]; 11 | var chart = graphController.getChart(); 12 | 13 | function addScatterPlot () { 14 | var array = []; 15 | 16 | if ($attrs.series){ array.push($attrs.series); } 17 | array.push($attrs.field); 18 | if ($attrs.label || $attrs.label === '') { array.push($attrs.label); } 19 | scatterPlot = chart.addSeries(array, dimple.plot.bubble); 20 | scatterPlot.aggregate = dimple.aggregateMethod.avg; 21 | graphController.filter($attrs); 22 | graphController.draw(); 23 | } 24 | 25 | $scope.$watch('dataReady', function(newValue, oldValue) { 26 | if (newValue === true) { 27 | addScatterPlot(); 28 | } 29 | }); 30 | } 31 | }; 32 | }]); -------------------------------------------------------------------------------- /lib/stacked-area.js: -------------------------------------------------------------------------------- 1 | angular.module('angular-dimple.stacked-area', []) 2 | 3 | .directive('stackedArea', [function () { 4 | return { 5 | restrict: 'E', 6 | replace: true, 7 | require: ['stackedArea', '^graph'], 8 | controller: ['$scope', '$element', '$attrs', function($scope, $element, $attrs) { 9 | }], 10 | link: function($scope, $element, $attrs, $controllers) { 11 | var graphController = $controllers[1]; 12 | var areaController = $controllers[0]; 13 | var chart = graphController.getChart(); 14 | 15 | function addArea () { 16 | if ($attrs.series) { 17 | area = chart.addSeries([$attrs.series], dimple.plot.area); 18 | } else { 19 | area = chart.addSeries([$attrs.field], dimple.plot.area); 20 | } 21 | graphController.filter($attrs); 22 | area.lineMarkers = false; 23 | graphController.draw(); 24 | } 25 | 26 | $scope.$watch('dataReady', function(newValue, oldValue) { 27 | if (newValue === true) { 28 | addArea(); 29 | } 30 | }); 31 | } 32 | }; 33 | }]); -------------------------------------------------------------------------------- /lib/stacked-bar.js: -------------------------------------------------------------------------------- 1 | angular.module('angular-dimple.stacked-bar', []) 2 | 3 | .directive('stackedBar', [function () { 4 | return { 5 | restrict: 'E', 6 | replace: true, 7 | require: ['stackedBar', '^graph'], 8 | controller: ['$scope', '$element', '$attrs', function($scope, $element, $attrs) { 9 | }], 10 | link: function($scope, $element, $attrs, $controllers) { 11 | var graphController = $controllers[1]; 12 | var lineController = $controllers[0]; 13 | var chart = graphController.getChart(); 14 | 15 | function addBar () { 16 | if ($attrs.series) { 17 | bar = chart.addSeries([$attrs.series], dimple.plot.bar); 18 | } else { 19 | bar = chart.addSeries([$attrs.field], dimple.plot.bar); 20 | } 21 | graphController.filter($attrs); 22 | graphController.draw(); 23 | } 24 | 25 | $scope.$watch('dataReady', function(newValue, oldValue) { 26 | if (newValue === true) { 27 | addBar(); 28 | } 29 | }); 30 | } 31 | }; 32 | }]); -------------------------------------------------------------------------------- /lib/x.js: -------------------------------------------------------------------------------- 1 | angular.module('angular-dimple.x', []) 2 | 3 | .directive('x', [function () { 4 | return { 5 | restrict: 'E', 6 | replace: true, 7 | require: ['x', '^graph'], 8 | controller: ['$scope', '$element', '$attrs', function($scope, $element, $attrs) { 9 | }], 10 | link: function($scope, $element, $attrs, $controllers) { 11 | var graphController = $controllers[1]; 12 | var chart = graphController.getChart(); 13 | 14 | function addAxis () { 15 | if ($attrs.groupBy) { 16 | if ($attrs.type == 'Measure') { 17 | x = chart.addMeasureAxis('x', [$attrs.groupBy, $attrs.field]); 18 | } else if ($attrs.type == 'Percent') { 19 | x = chart.addPctAxis('x', $attrs.field); 20 | } else if ($attrs.type == 'Time') { 21 | x = chart.addTimeAxis('x', $attrs.field); 22 | if ($attrs.format) { 23 | x.tickFormat = $attrs.format; 24 | } 25 | } else { 26 | x = chart.addCategoryAxis('x', [$attrs.groupBy, $attrs.field]); 27 | } 28 | if ($attrs.orderBy) { 29 | x.addGroupOrderRule($attrs.orderBy); 30 | } 31 | } else { 32 | if ($attrs.type == 'Measure') { 33 | x = chart.addMeasureAxis('x', $attrs.field); 34 | } else if ($attrs.type == 'Percent') { 35 | x = chart.addPctAxis('x', $attrs.field); 36 | } else if ($attrs.type == 'Time') { 37 | x = chart.addTimeAxis('x', $attrs.field); 38 | if ($attrs.format) { 39 | x.tickFormat = $attrs.format; 40 | } 41 | } else { 42 | x = chart.addCategoryAxis('x', $attrs.field); 43 | } 44 | if ($attrs.orderBy) { 45 | x.addOrderRule($attrs.orderBy); 46 | } 47 | } 48 | 49 | if ($attrs.title && $attrs.title !== "null") { 50 | x.title = $attrs.title; 51 | } else if ($attrs.title == "null") { 52 | x.title = null; 53 | } 54 | } 55 | 56 | $scope.$watch('dataReady', function(newValue, oldValue) { 57 | if (newValue === true) { 58 | addAxis(); 59 | } 60 | }); 61 | } 62 | }; 63 | }]); -------------------------------------------------------------------------------- /lib/y.js: -------------------------------------------------------------------------------- 1 | angular.module('angular-dimple.y', []) 2 | 3 | .directive('y', [function () { 4 | return { 5 | restrict: 'E', 6 | replace: true, 7 | require: ['y', '^graph'], 8 | controller: ['$scope', '$element', '$attrs', function($scope, $element, $attrs) { 9 | }], 10 | link: function($scope, $element, $attrs, $controllers) { 11 | var graphController = $controllers[1]; 12 | var chart = graphController.getChart(); 13 | 14 | function addAxis () { 15 | if ($attrs.groupBy) { 16 | if ($attrs.type == 'Category') { 17 | y = chart.addCategoryAxis('y', $attrs.field); 18 | } else if ($attrs.type == 'Percent') { 19 | y = chart.addPctAxis('y', $attrs.field); 20 | } else if ($attrs.type == 'Time') { 21 | y = chart.addTimeAxis('y', $attrs.field); 22 | if ($attrs.format) { 23 | y.tickFormat = $attrs.format; 24 | } 25 | } else { 26 | y = chart.addMeasureAxis('y', $attrs.field); 27 | } 28 | if ($attrs.orderBy) { 29 | y.addGroupOrderRule($attrs.orderBy); 30 | } 31 | } else { 32 | if ($attrs.type == 'Category') { 33 | y = chart.addCategoryAxis('y', $attrs.field); 34 | } else if ($attrs.type == 'Percent') { 35 | y = chart.addPctAxis('y', $attrs.field); 36 | } else if ($attrs.type == 'Time') { 37 | y = chart.addTimeAxis('y', $attrs.field); 38 | if ($attrs.format) { 39 | y.tickFormat = $attrs.format; 40 | } 41 | } else { 42 | y = chart.addMeasureAxis('y', $attrs.field); 43 | } 44 | if ($attrs.orderBy) { 45 | y.addOrderRule($attrs.orderBy); 46 | } 47 | } 48 | 49 | if ($attrs.title && $attrs.title !== "null") { 50 | y.title = $attrs.title; 51 | } else if ($attrs.title == "null") { 52 | y.title = null; 53 | } 54 | } 55 | 56 | $scope.$watch('dataReady', function(newValue, oldValue) { 57 | if (newValue === true) { 58 | addAxis(); 59 | } 60 | }); 61 | } 62 | }; 63 | }]); -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "angular-dimple", 3 | "version": "2.0.1", 4 | "description": "Angular.js wrapper for the Dimple charting language", 5 | "repository": "https://github.com/esripdx/angular-dimple", 6 | "license": "ISC", 7 | "scripts": { 8 | "prepublish": "bower install && grunt prepublish", 9 | "start": "grunt" 10 | }, 11 | "devDependencies": { 12 | "acetate": "0.0.7", 13 | "grunt": "~0.4.5", 14 | "grunt-acetate": "0.0.5", 15 | "grunt-concurrent": "^0.5.0", 16 | "grunt-contrib-compress": "^0.11.0", 17 | "grunt-contrib-concat": "^0.4.0", 18 | "grunt-contrib-copy": "^0.5.0", 19 | "grunt-contrib-imagemin": "^0.8.1", 20 | "grunt-contrib-jshint": "^0.10.0", 21 | "grunt-contrib-sass": "^0.8.1", 22 | "grunt-contrib-uglify": "^0.4.0", 23 | "grunt-contrib-watch": "~0.6.1", 24 | "grunt-gh-pages": "^0.9.1", 25 | "grunt-github-releaser": "^0.1.17", 26 | "grunt-newer": "^0.7.0", 27 | "grunt-prompt": "^1.3.0", 28 | "load-grunt-tasks": "~0.6.0", 29 | "minimist": "~1.1.0" 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /site/js/lib/angular-dimple.js: -------------------------------------------------------------------------------- 1 | /*! Angular-Dimple - 1.1.2 - 2014-09-29 2 | * https://github.com/esripdx/angular-dimple 3 | * Licensed ISC */ 4 | angular.module('angular-dimple', [ 5 | 'angular-dimple.graph', 6 | 'angular-dimple.legend', 7 | 'angular-dimple.x', 8 | 'angular-dimple.y', 9 | 'angular-dimple.r', 10 | 'angular-dimple.line', 11 | 'angular-dimple.bar', 12 | 'angular-dimple.stacked-bar', 13 | 'angular-dimple.area', 14 | 'angular-dimple.stacked-area', 15 | 'angular-dimple.scatter-plot', 16 | 'angular-dimple.ring' 17 | ]) 18 | 19 | .constant('MODULE_VERSION', '0.0.1') 20 | 21 | .value('defaults', { 22 | foo: 'bar' 23 | }); 24 | angular.module('angular-dimple.area', []) 25 | 26 | .directive('area', [function () { 27 | return { 28 | restrict: 'E', 29 | replace: true, 30 | require: ['area', '^graph'], 31 | controller: ['$scope', '$element', '$attrs', function($scope, $element, $attrs) { 32 | }], 33 | link: function($scope, $element, $attrs, $controllers) { 34 | var graphController = $controllers[1]; 35 | var areaController = $controllers[0]; 36 | var chart = graphController.getChart(); 37 | 38 | function addArea () { 39 | if ($attrs.value) { 40 | area = chart.addSeries([$attrs.field], dimple.plot.area); 41 | graphController.filter($attrs); 42 | area.lineMarkers = true; 43 | } else { 44 | var values = dimple.getUniqueValues($scope.data, $attrs.field); 45 | angular.forEach(values, function(value){ 46 | area = chart.addSeries([$attrs.field], dimple.plot.area); 47 | graphController.filter($attrs); 48 | area.lineMarkers = true; 49 | }); 50 | } 51 | graphController.draw(); 52 | } 53 | 54 | $scope.$watch('dataReady', function(newValue, oldValue) { 55 | if (newValue === true) { 56 | addArea(); 57 | } 58 | }); 59 | } 60 | }; 61 | }]); 62 | 63 | 64 | angular.module('angular-dimple.bar', []) 65 | 66 | .directive('bar', [function () { 67 | return { 68 | restrict: 'E', 69 | replace: true, 70 | require: ['bar', '^graph'], 71 | controller: ['$scope', '$element', '$attrs', function($scope, $element, $attrs) { 72 | }], 73 | link: function($scope, $element, $attrs, $controllers) { 74 | var graphController = $controllers[1]; 75 | var lineController = $controllers[0]; 76 | var chart = graphController.getChart(); 77 | 78 | function addBar () { 79 | var filteredData; 80 | bar = chart.addSeries([$attrs.field], dimple.plot.bar); 81 | graphController.filter($attrs); 82 | graphController.draw(); 83 | } 84 | 85 | 86 | 87 | $scope.$watch('dataReady', function(newValue, oldValue) { 88 | if (newValue === true) { 89 | addBar(); 90 | } 91 | }); 92 | } 93 | }; 94 | }]); 95 | angular.module('angular-dimple.graph', []) 96 | 97 | .directive('graph', [function () { 98 | return { 99 | restrict: 'E', 100 | replace: true, 101 | scope: { 102 | data: '=', 103 | }, 104 | require: ['graph'], 105 | transclude: true, 106 | link: function (scope, element, attrs, controllers, transclude) { 107 | var graphController = controllers[0]; 108 | graphController._createChart(); 109 | scope.dataReady = false; 110 | scope.filters = []; 111 | 112 | var chart = graphController.getChart(); 113 | var transition; 114 | if (attrs.transition) { 115 | transition = attrs.transition; 116 | } else { 117 | transition = 750; 118 | } 119 | 120 | scope.$watch('data', function(newValue, oldValue) { 121 | if (newValue) { 122 | scope.dataReady = true; 123 | graphController.setData(); 124 | chart.draw(transition); 125 | } 126 | }); 127 | 128 | transclude(scope, function(clone){ 129 | element.append(clone); 130 | }); 131 | }, 132 | controller: ['$scope', '$element', '$attrs', function($scope, $element, $attrs) { 133 | var chart; 134 | 135 | this._createChart = function () { 136 | // create an svg element 137 | var svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg'); 138 | if ($attrs.width) { 139 | svg.setAttribute('width', $attrs.width); 140 | } else { 141 | svg.setAttribute('width', '100%'); 142 | } 143 | if ($attrs.height) { 144 | svg.setAttribute('height', $attrs.height); 145 | } else { 146 | svg.setAttribute('height', '100%'); 147 | } 148 | 149 | // end the svg to this 150 | $element.append(svg); 151 | 152 | // create the dimple chart using the d3 selection of our element 153 | chart = new dimple.chart(d3.select(svg)); 154 | 155 | if ($attrs.margin) { 156 | chart.setMargins($attrs.margin); 157 | } else { 158 | chart.setMargins(60, 60, 20, 40); 159 | } 160 | 161 | // auto style 162 | var autoStyle = $attrs.autoStyle === 'false' ? true : false; 163 | chart.noFormats = autoStyle; 164 | }; 165 | 166 | this.getChart = function () { 167 | return chart; 168 | }; 169 | 170 | this.setData = function () { 171 | chart.data = $scope.data; 172 | }; 173 | 174 | this.draw = function () { 175 | chart.draw(); 176 | }; 177 | 178 | this.getID = function () { 179 | return id; 180 | }; 181 | 182 | this.filter = function (attrs) { 183 | if (attrs.value !== undefined) { 184 | $scope.filters.push(attrs.value); 185 | } 186 | if ($scope.filters.length) { 187 | chart.data = dimple.filterData($scope.data, attrs.field, $scope.filters); 188 | } 189 | 190 | if (attrs.filter !== undefined) { 191 | console.log("i see a filter"); 192 | var thisFilter = attrs.filter.split(':'); 193 | var field = thisFilter[0]; 194 | var value = [thisFilter[1]]; 195 | chart.data = dimple.filterData($scope.data, field, value); 196 | } 197 | }; 198 | 199 | }] 200 | }; 201 | }]); 202 | angular.module('angular-dimple.legend', []) 203 | 204 | .directive('legend', [function () { 205 | return { 206 | restrict: 'E', 207 | replace: true, 208 | require: ['legend', '^graph'], 209 | controller: ['$scope', '$element', '$attrs', function($scope, $element, $attrs) { 210 | }], 211 | link: function($scope, $element, $attrs, $controllers) { 212 | var graphController = $controllers[1]; 213 | var chart = graphController.getChart(); 214 | 215 | function addLegend () { 216 | var left = $attrs.left ? $attrs.left : "10%"; 217 | var top = $attrs.top ? $attrs.top : "4%"; 218 | var height = $attrs.height ? $attrs.height : "10%"; 219 | var width = $attrs.width ? $attrs.width : "90%"; 220 | var position = $attrs.position ? $attrs.position : 'left'; 221 | chart.addLegend(left, top, width, height, position); 222 | } 223 | 224 | $scope.$watch('dataReady', function(newValue, oldValue) { 225 | if (newValue === true) { 226 | addLegend(); 227 | } 228 | }); 229 | } 230 | }; 231 | }]); 232 | angular.module('angular-dimple.line', []) 233 | 234 | .directive('line', [function () { 235 | return { 236 | restrict: 'E', 237 | replace: true, 238 | require: ['line', '^graph'], 239 | controller: ['$scope', '$element', '$attrs', function($scope, $element, $attrs) { 240 | }], 241 | link: function($scope, $element, $attrs, $controllers) { 242 | var graphController = $controllers[1]; 243 | var chart = graphController.getChart(); 244 | var drawn = false; 245 | 246 | function addLine () { 247 | var filteredData; 248 | line = chart.addSeries([$attrs.field], dimple.plot.line); 249 | graphController.filter($attrs); 250 | line.lineMarkers = true; 251 | graphController.draw(); 252 | } 253 | 254 | $scope.$watch('dataReady', function(newValue, oldValue) { 255 | if (newValue === true) { 256 | addLine(); 257 | } 258 | }); 259 | 260 | } 261 | }; 262 | }]); 263 | angular.module('angular-dimple.r', []) 264 | 265 | .directive('r', [function () { 266 | return { 267 | restrict: 'E', 268 | replace: true, 269 | require: ['r', '^graph'], 270 | controller: ['$scope', '$element', '$attrs', function($scope, $element, $attrs) { 271 | }], 272 | link: function($scope, $element, $attrs, $controllers) { 273 | var graphController = $controllers[1]; 274 | var chart = graphController.getChart(); 275 | 276 | function addAxis () { 277 | r = chart.addMeasureAxis('p', $attrs.field); 278 | 279 | if ($attrs.title && $attrs.title !== "null") { 280 | r.title = $attrs.title; 281 | } else if ($attrs.title == "null") { 282 | r.title = null; 283 | } 284 | } 285 | 286 | $scope.$watch('data', function(newValue, oldValue) { 287 | if (newValue) { 288 | addAxis(); 289 | } 290 | }); 291 | } 292 | }; 293 | }]); 294 | angular.module('angular-dimple.ring', []) 295 | 296 | .directive('ring', [function () { 297 | return { 298 | restrict: 'E', 299 | replace: true, 300 | require: ['ring', '^graph'], 301 | controller: ['$scope', '$element', '$attrs', function($scope, $element, $attrs) { 302 | }], 303 | link: function($scope, $element, $attrs, $controllers) { 304 | var graphController = $controllers[1]; 305 | var areaController = $controllers[0]; 306 | var chart = graphController.getChart(); 307 | 308 | function setData (data, series) { 309 | series.data = data; 310 | } 311 | 312 | function addRing () { 313 | var thickness; 314 | ring = chart.addSeries([$attrs.field], dimple.plot.pie); 315 | if ($attrs.thickness && !$attrs.diameter) { 316 | thickness = (100 - $attrs.thickness) + '%'; 317 | ring.innerRadius = thickness; 318 | } else if ($attrs.thickness && $attrs.diameter) { 319 | thickness = ($attrs.diameter - $attrs.thickness) + '%'; 320 | ring.innerRadius = thickness; 321 | } else { 322 | ring.innerRadius = "50%"; 323 | } 324 | 325 | if ($attrs.diameter) { 326 | ring.outerRadius = ($attrs.diameter) + '%'; 327 | } 328 | graphController.filter($attrs); 329 | graphController.draw(); 330 | } 331 | 332 | $scope.$watch('data', function(newValue, oldValue) { 333 | if (newValue) { 334 | addRing(); 335 | } 336 | }); 337 | } 338 | }; 339 | }]); 340 | 341 | 342 | angular.module('angular-dimple.scatter-plot', []) 343 | 344 | .directive('scatterPlot', [function () { 345 | return { 346 | restrict: 'E', 347 | replace: true, 348 | require: ['scatterPlot', '^graph'], 349 | controller: [function() {}], 350 | link: function($scope, $element, $attrs, $controllers) { 351 | var graphController = $controllers[1]; 352 | var chart = graphController.getChart(); 353 | 354 | function addScatterPlot () { 355 | var array = []; 356 | 357 | if ($attrs.series){ array.push($attrs.series); } 358 | array.push($attrs.field); 359 | if ($attrs.label || $attrs.label === '') { array.push($attrs.label); } 360 | scatterPlot = chart.addSeries(array, dimple.plot.bubble); 361 | scatterPlot.aggregate = dimple.aggregateMethod.avg; 362 | graphController.filter($attrs); 363 | graphController.draw(); 364 | } 365 | 366 | $scope.$watch('dataReady', function(newValue, oldValue) { 367 | if (newValue === true) { 368 | addScatterPlot(); 369 | } 370 | }); 371 | } 372 | }; 373 | }]); 374 | angular.module('angular-dimple.stacked-area', []) 375 | 376 | .directive('stackedArea', [function () { 377 | return { 378 | restrict: 'E', 379 | replace: true, 380 | require: ['stackedArea', '^graph'], 381 | controller: ['$scope', '$element', '$attrs', function($scope, $element, $attrs) { 382 | }], 383 | link: function($scope, $element, $attrs, $controllers) { 384 | var graphController = $controllers[1]; 385 | var areaController = $controllers[0]; 386 | var chart = graphController.getChart(); 387 | 388 | function addArea () { 389 | if ($attrs.series) { 390 | area = chart.addSeries([$attrs.series], dimple.plot.area); 391 | } else { 392 | area = chart.addSeries([$attrs.field], dimple.plot.area); 393 | } 394 | graphController.filter($attrs); 395 | area.lineMarkers = false; 396 | graphController.draw(); 397 | } 398 | 399 | $scope.$watch('dataReady', function(newValue, oldValue) { 400 | if (newValue === true) { 401 | addArea(); 402 | } 403 | }); 404 | } 405 | }; 406 | }]); 407 | angular.module('angular-dimple.stacked-bar', []) 408 | 409 | .directive('stackedBar', [function () { 410 | return { 411 | restrict: 'E', 412 | replace: true, 413 | require: ['stackedBar', '^graph'], 414 | controller: ['$scope', '$element', '$attrs', function($scope, $element, $attrs) { 415 | }], 416 | link: function($scope, $element, $attrs, $controllers) { 417 | var graphController = $controllers[1]; 418 | var lineController = $controllers[0]; 419 | var chart = graphController.getChart(); 420 | 421 | function addBar () { 422 | if ($attrs.series) { 423 | bar = chart.addSeries([$attrs.series], dimple.plot.bar); 424 | } else { 425 | bar = chart.addSeries([$attrs.field], dimple.plot.bar); 426 | } 427 | graphController.filter($attrs); 428 | graphController.draw(); 429 | } 430 | 431 | $scope.$watch('dataReady', function(newValue, oldValue) { 432 | if (newValue === true) { 433 | addBar(); 434 | } 435 | }); 436 | } 437 | }; 438 | }]); 439 | angular.module('angular-dimple.x', []) 440 | 441 | .directive('x', [function () { 442 | return { 443 | restrict: 'E', 444 | replace: true, 445 | require: ['x', '^graph'], 446 | controller: ['$scope', '$element', '$attrs', function($scope, $element, $attrs) { 447 | }], 448 | link: function($scope, $element, $attrs, $controllers) { 449 | var graphController = $controllers[1]; 450 | var chart = graphController.getChart(); 451 | 452 | function addAxis () { 453 | if ($attrs.groupBy) { 454 | if ($attrs.type == 'Measure') { 455 | x = chart.addMeasureAxis('x', [$attrs.groupBy, $attrs.field]); 456 | } else if ($attrs.type == 'Percent') { 457 | x = chart.addPctAxis('x', $attrs.field); 458 | } else if ($attrs.type == 'Time') { 459 | x = chart.addTimeAxis('x', $attrs.field); 460 | if ($attrs.format) { 461 | x.tickFormat = $attrs.format; 462 | } 463 | } else { 464 | x = chart.addCategoryAxis('x', [$attrs.groupBy, $attrs.field]); 465 | } 466 | if ($attrs.orderBy) { 467 | x.addGroupOrderRule($attrs.orderBy); 468 | } 469 | } else { 470 | if ($attrs.type == 'Measure') { 471 | x = chart.addMeasureAxis('x', $attrs.field); 472 | } else if ($attrs.type == 'Percent') { 473 | x = chart.addPctAxis('x', $attrs.field); 474 | } else if ($attrs.type == 'Time') { 475 | x = chart.addTimeAxis('x', $attrs.field); 476 | if ($attrs.format) { 477 | x.tickFormat = $attrs.format; 478 | } 479 | } else { 480 | x = chart.addCategoryAxis('x', $attrs.field); 481 | } 482 | if ($attrs.orderBy) { 483 | x.addOrderRule($attrs.orderBy); 484 | } 485 | } 486 | 487 | if ($attrs.title && $attrs.title !== "null") { 488 | x.title = $attrs.title; 489 | } else if ($attrs.title == "null") { 490 | x.title = null; 491 | } 492 | } 493 | 494 | $scope.$watch('dataReady', function(newValue, oldValue) { 495 | if (newValue === true) { 496 | addAxis(); 497 | } 498 | }); 499 | } 500 | }; 501 | }]); 502 | angular.module('angular-dimple.y', []) 503 | 504 | .directive('y', [function () { 505 | return { 506 | restrict: 'E', 507 | replace: true, 508 | require: ['y', '^graph'], 509 | controller: ['$scope', '$element', '$attrs', function($scope, $element, $attrs) { 510 | }], 511 | link: function($scope, $element, $attrs, $controllers) { 512 | var graphController = $controllers[1]; 513 | var chart = graphController.getChart(); 514 | 515 | function addAxis () { 516 | if ($attrs.groupBy) { 517 | if ($attrs.type == 'Category') { 518 | y = chart.addCategoryAxis('y', $attrs.field); 519 | } else if ($attrs.type == 'Percent') { 520 | y = chart.addPctAxis('y', $attrs.field); 521 | } else if ($attrs.type == 'Time') { 522 | y = chart.addTimeAxis('x', $attrs.field); 523 | if ($attrs.format) { 524 | y.tickFormat = $attrs.format; 525 | } 526 | } else { 527 | y = chart.addMeasureAxis('y', $attrs.field); 528 | } 529 | if ($attrs.orderBy) { 530 | y.addGroupOrderRule($attrs.orderBy); 531 | } 532 | } else { 533 | if ($attrs.type == 'Category') { 534 | y = chart.addCategoryAxis('y', $attrs.field); 535 | } else if ($attrs.type == 'Percent') { 536 | y = chart.addPctAxis('y', $attrs.field); 537 | } else if ($attrs.type == 'Time') { 538 | y = chart.addTimeAxis('x', $attrs.field); 539 | if ($attrs.format) { 540 | y.tickFormat = $attrs.format; 541 | } 542 | } else { 543 | y = chart.addMeasureAxis('y', $attrs.field); 544 | } 545 | if ($attrs.orderBy) { 546 | y.addOrderRule($attrs.orderBy); 547 | } 548 | } 549 | 550 | if ($attrs.title && $attrs.title !== "null") { 551 | y.title = $attrs.title; 552 | } else if ($attrs.title == "null") { 553 | y.title = null; 554 | } 555 | } 556 | 557 | $scope.$watch('dataReady', function(newValue, oldValue) { 558 | if (newValue === true) { 559 | addAxis(); 560 | } 561 | }); 562 | } 563 | }; 564 | }]); -------------------------------------------------------------------------------- /test/e2e/scenarios.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /* https://github.com/angular/protractor/blob/master/docs/getting-started.md */ 4 | 5 | describe('my app', function() { 6 | 7 | browser.get('index.html'); 8 | 9 | it('should automatically redirect to /view1 when location hash/fragment is empty', function() { 10 | expect(browser.getLocationAbsUrl()).toMatch("/view1"); 11 | }); 12 | 13 | 14 | describe('view1', function() { 15 | 16 | beforeEach(function() { 17 | browser.get('index.html#/view1'); 18 | }); 19 | 20 | 21 | it('should render view1 when user navigates to /view1', function() { 22 | expect(element.all(by.css('[ng-view] p')).first().getText()). 23 | toMatch(/partial for view 1/); 24 | }); 25 | 26 | }); 27 | 28 | 29 | describe('view2', function() { 30 | 31 | beforeEach(function() { 32 | browser.get('index.html#/view2'); 33 | }); 34 | 35 | 36 | it('should render view2 when user navigates to /view2', function() { 37 | expect(element.all(by.css('[ng-view] p')).first().getText()). 38 | toMatch(/partial for view 2/); 39 | }); 40 | 41 | }); 42 | }); 43 | -------------------------------------------------------------------------------- /test/karma.conf.js: -------------------------------------------------------------------------------- 1 | module.exports = function(config){ 2 | config.set({ 3 | 4 | basePath : '../', 5 | 6 | files : [ 7 | 'app/bower_components/angular/angular.js', 8 | 'app/bower_components/angular-route/angular-route.js', 9 | 'app/bower_components/angular-mocks/angular-mocks.js', 10 | 'app/js/**/*.js', 11 | 'test/unit/**/*.js' 12 | ], 13 | 14 | autoWatch : true, 15 | 16 | frameworks: ['jasmine'], 17 | 18 | browsers : ['Chrome'], 19 | 20 | plugins : [ 21 | 'karma-chrome-launcher', 22 | 'karma-firefox-launcher', 23 | 'karma-jasmine', 24 | 'karma-junit-reporter' 25 | ], 26 | 27 | junitReporter : { 28 | outputFile: 'test_out/unit.xml', 29 | suite: 'unit' 30 | } 31 | 32 | }); 33 | }; 34 | -------------------------------------------------------------------------------- /test/protractor-conf.js: -------------------------------------------------------------------------------- 1 | exports.config = { 2 | allScriptsTimeout: 11000, 3 | 4 | specs: [ 5 | 'e2e/*.js' 6 | ], 7 | 8 | capabilities: { 9 | 'browserName': 'chrome' 10 | }, 11 | 12 | baseUrl: 'http://localhost:8000/app/', 13 | 14 | framework: 'jasmine', 15 | 16 | jasmineNodeOpts: { 17 | defaultTimeoutInterval: 30000 18 | } 19 | }; 20 | -------------------------------------------------------------------------------- /test/unit/controllersSpec.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /* jasmine specs for controllers go here */ 4 | 5 | describe('controllers', function(){ 6 | beforeEach(module('myApp.controllers')); 7 | 8 | 9 | it('should ....', inject(function($controller) { 10 | //spec body 11 | var myCtrl1 = $controller('MyCtrl1', { $scope: {} }); 12 | expect(myCtrl1).toBeDefined(); 13 | })); 14 | 15 | it('should ....', inject(function($controller) { 16 | //spec body 17 | var myCtrl2 = $controller('MyCtrl2', { $scope: {} }); 18 | expect(myCtrl2).toBeDefined(); 19 | })); 20 | }); 21 | -------------------------------------------------------------------------------- /test/unit/directivesSpec.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /* jasmine specs for directives go here */ 4 | 5 | describe('directives', function() { 6 | beforeEach(module('myApp.directives')); 7 | 8 | describe('app-version', function() { 9 | it('should print current version', function() { 10 | module(function($provide) { 11 | $provide.value('version', 'TEST_VER'); 12 | }); 13 | inject(function($compile, $rootScope) { 14 | var element = $compile('')($rootScope); 15 | expect(element.text()).toEqual('TEST_VER'); 16 | }); 17 | }); 18 | }); 19 | }); 20 | -------------------------------------------------------------------------------- /test/unit/filtersSpec.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /* jasmine specs for filters go here */ 4 | 5 | describe('filter', function() { 6 | beforeEach(module('myApp.filters')); 7 | 8 | 9 | describe('interpolate', function() { 10 | beforeEach(module(function($provide) { 11 | $provide.value('version', 'TEST_VER'); 12 | })); 13 | 14 | 15 | it('should replace VERSION', inject(function(interpolateFilter) { 16 | expect(interpolateFilter('before %VERSION% after')).toEqual('before TEST_VER after'); 17 | })); 18 | }); 19 | }); 20 | -------------------------------------------------------------------------------- /test/unit/servicesSpec.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /* jasmine specs for services go here */ 4 | 5 | describe('service', function() { 6 | beforeEach(module('myApp.services')); 7 | 8 | 9 | describe('version', function() { 10 | it('should return current version', inject(function(version) { 11 | expect(version).toEqual('0.1'); 12 | })); 13 | }); 14 | }); 15 | --------------------------------------------------------------------------------