From f258856102530e15ddd12c46e969f55055d4ccfc Mon Sep 17 00:00:00 2001 From: Sagi Dayan Date: Wed, 17 Jun 2015 00:07:21 +0300 Subject: [PATCH 01/15] #43 - Settings Page: Some More UI Thinking About UI and Implementing it --- .../js/controllers/settingsController.js | 25 ++++++++++++++++ templates/views/settings.html | 30 +++++++++++++++++++ 2 files changed, 55 insertions(+) diff --git a/templates/js/controllers/settingsController.js b/templates/js/controllers/settingsController.js index 4968b42..1afbabc 100644 --- a/templates/js/controllers/settingsController.js +++ b/templates/js/controllers/settingsController.js @@ -24,7 +24,32 @@ angular.module('SeHub') }); + $scope.isEditMode = false; + $scope.profileMode = "Edit Profile"; + $scope.profileModeIcon = "fa fa-pencil"; + $scope.changeProfileMode = function() { + $scope.isEditMode = !$scope.isEditMode; + if ($scope.isEditMode) { + $scope.profileMode = "Save Profile"; + $scope.profileModeIcon = "fa fa-floppy-o"; + } else { + $scope.profileMode = "Edit Profile"; + $scope.profileModeIcon = "fa fa-pencil"; + } + } + + // { + // name: ";" + // isLecturer: false + // email: "sagidayan@gmail.com" + // username: "sagidayan" + // seToken: "76cd4178-94dd-4cb4-b464-111d2239e567" + // isFirstLogin: true + // campuses_id_list: [0] + // classes_id_list: [0] + // avatar_url: "https://avatars.githubusercontent.com/u/2984053?v=3" + // } }]); \ No newline at end of file diff --git a/templates/views/settings.html b/templates/views/settings.html index 0c4b980..fd1cf52 100644 --- a/templates/views/settings.html +++ b/templates/views/settings.html @@ -5,6 +5,36 @@

{{title}}

+
+
+ +
+
+
+ +
+
+ + {{profileMode}} + +
+
+
+

{{user.name}}

+
+
+ Email: {{user.email}} +
+
+ I Am a: {{(user.isLecturer) ? "Lecturer" : "Student"}} +
+
+
+
+
+ + +
\ No newline at end of file From 980d81324ce7b3c576ddffa8fed85c98941d2387 Mon Sep 17 00:00:00 2001 From: Sagi Dayan Date: Wed, 17 Jun 2015 00:16:26 +0300 Subject: [PATCH 02/15] #43 - Settings Page: Profile Edit Mode --- templates/views/settings.html | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/templates/views/settings.html b/templates/views/settings.html index fd1cf52..96b3f74 100644 --- a/templates/views/settings.html +++ b/templates/views/settings.html @@ -15,10 +15,12 @@
- {{profileMode}} + {{profileMode}}
+ +

{{user.name}}

@@ -29,6 +31,25 @@ I Am a: {{(user.isLecturer) ? "Lecturer" : "Student"}}
+
+
+ + + + +
+
+ + + + +
+
+ + I Am a: {{(user.isLecturer) ? "Lecturer" : "Student"}} + +
+
From f87a14b2da4768979fb0e99ba522d53db44950f4 Mon Sep 17 00:00:00 2001 From: Sagi Dayan Date: Wed, 17 Jun 2015 20:07:20 +0300 Subject: [PATCH 03/15] Fix issue #24 --- SE_API/API.py | 4 ---- SE_API/CampusRoutes.py | 1 - SE_API/UserRoutes.py | 5 ++++- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/SE_API/API.py b/SE_API/API.py index 972c39e..387ba41 100644 --- a/SE_API/API.py +++ b/SE_API/API.py @@ -52,10 +52,6 @@ app.register_blueprint(project_routes) auto = Autodoc(app) -@app.errorhandler(404) -def page_not_found(e): - return app.send_static_file('views/404/index.html') - @app.route('/') def wellcomePage(): return app.send_static_file('index.html') diff --git a/SE_API/CampusRoutes.py b/SE_API/CampusRoutes.py index 11af4b3..c52fe9c 100644 --- a/SE_API/CampusRoutes.py +++ b/SE_API/CampusRoutes.py @@ -79,7 +79,6 @@ def create_campus(token): except Exception: return bad_request() - send_create_campus_request(user.email, user.name, campus.title) notify_se_hub_campus_request(campus, campus.title) return ok() diff --git a/SE_API/UserRoutes.py b/SE_API/UserRoutes.py index 0bc26d1..d66fdea 100644 --- a/SE_API/UserRoutes.py +++ b/SE_API/UserRoutes.py @@ -25,7 +25,7 @@ from SE_API.Respones_Utils import * user_routes = Blueprint("user_routes", __name__) auto = Autodoc() - +@user_routes.route('/api/users/getUserByToken/', defaults={'token': None}) @user_routes.route('/api/users/getUserByToken/', methods=["GET"]) @auto.doc() def getUserByToken(token): @@ -59,6 +59,9 @@ def getUserByToken(token):
403 - No User Found """ + if token is None: + return no_content("Token Is Empty, No User Found") + query = User.all() query.filter("seToken =", token) From 3465ff3465acc33c4aaafd934791c61fc0de7f39 Mon Sep 17 00:00:00 2001 From: Sagi Dayan Date: Wed, 17 Jun 2015 20:14:53 +0300 Subject: [PATCH 04/15] Added Logout Function --- templates/js/controllers/mainController.js | 150 +++++++++++---------- 1 file changed, 79 insertions(+), 71 deletions(-) diff --git a/templates/js/controllers/mainController.js b/templates/js/controllers/mainController.js index bad88a9..9b4a18d 100644 --- a/templates/js/controllers/mainController.js +++ b/templates/js/controllers/mainController.js @@ -1,78 +1,86 @@ angular.module('SeHub') - .controller('mainController', ['$scope', '$rootScope', 'apiService', '$cookies', '$location', function($scope, $rootScope, apiService, $cookies, $location) { + .controller('mainController', ['$scope', '$rootScope', 'apiService', '$cookies', '$cookieStore', '$location', '$window', - var token = $cookies['com.sehub.www']; + function($scope, $rootScope, apiService, $cookies, $cookieStore, $location, $window) { - $scope.loadingData = true; - $scope.isInRegisterMode = false; + var token = $cookies['com.sehub.www']; - apiService.getUserByToken(token).success(function(data) { - if (data.message == 'No User Found') { - console.error("No User Found!"); - } - $scope.loadingData = false; - $scope.user = data; - console.log(data); - if ($scope.user.isFirstLogin) { - $scope.menuObj = {}; - $scope.isInRegisterMode = true; - $scope.loadingData = false; - $location.path('/register') - } else { - $location.path('/home') - } + $scope.loadingData = true; + $scope.isInRegisterMode = false; - }) - - $scope.menuItems = [{ - "title": "Home", - "icon": "fa fa-home", - "style": "selected", - "route": "/home" - }, { - "title": "My Campuses", - "icon": "fa fa-university", - "style": "", - "route": "/campuses" - }, { - "title": "My Classes", - "icon": "fa fa-graduation-cap", - "style": "", - "route": "/campuses" - }, { - "title": "My Projects", - "icon": "fa fa-cube", - "style": "", - "route": "/campuses" - }, { - "title": "Tasks", - "icon": "fa fa-clipboard", - "style": "", - "route": "/campuses" - }, { - "title": "Settings", - "icon": "fa fa-cogs", - "style": "", - "route": "/Settings" - }, { - "title": "Log Out", - "icon": "fa fa-power-off", - "style": "", - "route": "/logout" - }]; - - $scope.menuClicked = function(item){ - var route = "" - for (var i = $scope.menuItems.length - 1; i >= 0; i--) { - if($scope.menuItems[i].title === item.title){ - $scope.menuItems[i].style="selected"; - route = $scope.menuItems[i].route; - }else{ - $scope.menuItems[i].style = ""; + apiService.getUserByToken(token).success(function(data) { + if (data.message == 'No User Found') { + console.error("No User Found!"); } - }; - $location.path(route); + $scope.loadingData = false; + $scope.user = data; + console.log(data); + if ($scope.user.isFirstLogin) { + $scope.menuObj = {}; + $scope.isInRegisterMode = true; + $scope.loadingData = false; + $location.path('/register') + } else { + $location.path('/home') + } + + }) + + $scope.menuItems = [{ + "title": "Dash Board", + "icon": "fa fa-tachometer", + "style": "selected", + "route": "/home" + }, { + "title": "My Campuses", + "icon": "fa fa-university", + "style": "", + "route": "/campuses" + }, { + "title": "My Classes", + "icon": "fa fa-graduation-cap", + "style": "", + "route": "/campuses" + }, { + "title": "My Projects", + "icon": "fa fa-cube", + "style": "", + "route": "/campuses" + }, { + "title": "Tasks", + "icon": "fa fa-clipboard", + "style": "", + "route": "/campuses" + }, { + "title": "Settings", + "icon": "fa fa-cogs", + "style": "", + "route": "/Settings" + }, { + "title": "Log Out", + "icon": "fa fa-power-off", + "style": "", + "route": "/logout" + }]; + + $scope.menuClicked = function(item) { + var route = "" + if (item.title == "Log Out") { + console.info('Logging Out!'); + $cookieStore.remove('com.sehub.www'); + $window.location.href = 'http://se-hub.appspot.com'; // Reference to 'welcome' page + } + for (var i = $scope.menuItems.length - 1; i >= 0; i--) { + if ($scope.menuItems[i].title === item.title) { + $scope.menuItems[i].style = "selected"; + route = $scope.menuItems[i].route; + } else { + $scope.menuItems[i].style = ""; + } + }; + $location.path(route); + } + + } - - - }]); \ No newline at end of file + ]); \ No newline at end of file From c264d908fbf259d5163a6995ef41a94050737f5b Mon Sep 17 00:00:00 2001 From: Sagi Dayan Date: Wed, 17 Jun 2015 20:59:45 +0300 Subject: [PATCH 05/15] Added New dataService - to sync mainController data with other scopes --- templates/js/controllers/mainController.js | 9 ++++++--- templates/js/controllers/settingsController.js | 4 +++- templates/views/index.html | 1 + templates/views/settings.html | 2 ++ 4 files changed, 12 insertions(+), 4 deletions(-) diff --git a/templates/js/controllers/mainController.js b/templates/js/controllers/mainController.js index 9b4a18d..08b10d6 100644 --- a/templates/js/controllers/mainController.js +++ b/templates/js/controllers/mainController.js @@ -1,7 +1,7 @@ angular.module('SeHub') - .controller('mainController', ['$scope', '$rootScope', 'apiService', '$cookies', '$cookieStore', '$location', '$window', + .controller('mainController', ['$scope', '$rootScope', 'dataService','apiService', '$cookies', '$cookieStore', '$location', '$window', - function($scope, $rootScope, apiService, $cookies, $cookieStore, $location, $window) { + function($scope, $rootScope, dataService, apiService, $cookies, $cookieStore, $location, $window) { var token = $cookies['com.sehub.www']; @@ -14,6 +14,7 @@ angular.module('SeHub') } $scope.loadingData = false; $scope.user = data; + dataService.initService($scope); //Start Data Sync Service (For User) console.log(data); if ($scope.user.isFirstLogin) { $scope.menuObj = {}; @@ -24,7 +25,9 @@ angular.module('SeHub') $location.path('/home') } - }) + }); + + $scope.menuItems = [{ "title": "Dash Board", diff --git a/templates/js/controllers/settingsController.js b/templates/js/controllers/settingsController.js index 1afbabc..b13edc8 100644 --- a/templates/js/controllers/settingsController.js +++ b/templates/js/controllers/settingsController.js @@ -1,5 +1,6 @@ angular.module('SeHub') - .controller('settingsController', ['$scope', '$rootScope', 'apiService', '$cookies', '$location', function($scope, $rootScope, apiService, $cookies, $location) { + .controller('settingsController', ['$scope', '$rootScope', 'dataService','apiService', '$cookies', '$location', + function($scope, $rootScope, dataService ,apiService, $cookies, $location) { var token = $cookies['com.sehub.www']; @@ -34,6 +35,7 @@ angular.module('SeHub') $scope.profileMode = "Save Profile"; $scope.profileModeIcon = "fa fa-floppy-o"; } else { + dataService.userBrodcast($scope.user); $scope.profileMode = "Edit Profile"; $scope.profileModeIcon = "fa fa-pencil"; } diff --git a/templates/views/index.html b/templates/views/index.html index cd629d1..c683489 100644 --- a/templates/views/index.html +++ b/templates/views/index.html @@ -81,6 +81,7 @@ + diff --git a/templates/views/settings.html b/templates/views/settings.html index 96b3f74..70c88f7 100644 --- a/templates/views/settings.html +++ b/templates/views/settings.html @@ -31,6 +31,8 @@ I Am a: {{(user.isLecturer) ? "Lecturer" : "Student"}} + +
From 46f374430d13665d3de60756eca946909db17b11 Mon Sep 17 00:00:00 2001 From: Sagi Dayan Date: Wed, 17 Jun 2015 21:00:37 +0300 Subject: [PATCH 06/15] missing js File --- templates/js/services/dataService.js | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 templates/js/services/dataService.js diff --git a/templates/js/services/dataService.js b/templates/js/services/dataService.js new file mode 100644 index 0000000..af915c7 --- /dev/null +++ b/templates/js/services/dataService.js @@ -0,0 +1,21 @@ +var DEBUG = true; + +angular.module('seHub.services'). + +factory('dataService', ['$http', function($http) { + var scope = null; + + + return { + initService: function(mainScope) { + // this.token = user.seToken; + // this.user = user; + scope = mainScope; + }, + userBrodcast: function(user) { + scope.user = JSON.parse(JSON.stringify(user)); + } + + + }; +}]); \ No newline at end of file From 998bba0e2945f0f081278736aea5d34586add42e Mon Sep 17 00:00:00 2001 From: Matan Bar Yosef Date: Wed, 17 Jun 2015 22:38:07 +0300 Subject: [PATCH 07/15] - updateUser service and implement added --- templates/css/theme.css | 91 +++++++++++++------ .../js/controllers/registerController.js | 25 ++++- 2 files changed, 85 insertions(+), 31 deletions(-) diff --git a/templates/css/theme.css b/templates/css/theme.css index 92d6805..2ee6e94 100644 --- a/templates/css/theme.css +++ b/templates/css/theme.css @@ -111,37 +111,39 @@ body.noscroll }*/ - .campusAvatar img - { +.campusAvatar img +{ /* - margin-top: 1em; - margin-right: 1em; - position: center; - */ + margin-top: 1em; + margin-right: 1em; + position: center; + */ - border-radius: 40px; - position:center; - width: 80px; - height: 80px; - margin: 6px; - -webkit-box-shadow: 2px 2px 5px 0px rgba(0,0,0,0.75); - -moz-box-shadow: 2px 2px 5px 0px rgba(0,0,0,0.75); - box-shadow: 2px 2px 5px 0px rgba(0,0,0,0.75); - } + border-radius: 40px; + position:center; + width: 80px; + height: 80px; + margin: 6px; + -webkit-box-shadow: 2px 2px 5px 0px rgba(0,0,0,0.75); + -moz-box-shadow: 2px 2px 5px 0px rgba(0,0,0,0.75); + box-shadow: 2px 2px 5px 0px rgba(0,0,0,0.75); +} - .spacer{ - margin-right: auto; - margin-left: auto; - } +.spacer{ + margin-right: auto; + margin-left: auto; +} - .port_spacer{ - margin-top: auto; - margin-bottom: auto; - } +.port_spacer +{ + margin-top: auto; + margin-bottom: auto; +} - .mail_suffix{ - margin-top: auto; - } +.mail_suffix +{ + margin-top: auto; +} .createCampus @@ -149,6 +151,43 @@ body.noscroll position:relative; } +.listdemoBasicUsage md-divider +{ + margin-top: 10px; + margin-bottom: 10px; +} + +.md-avatar img +{ + /*TODO*/ +} + +.feedContent +{ + padding-left: 6%; + font-size: 15px; + display:table; +} + +.md-no-sticky +{ + background-color: blue; +} + +.roundUserAvatar +{ + width: 6%; + height: auto; + border-radius: 150px; + -webkit-border-radius: 150px; + -moz-border-radius: 150px; + /*background: url(http://i61.tinypic.com/v86f7.png) no-repeat;*/ + box-shadow: 0 0 8px rgba(0, 0, 0, .8); + -webkit-box-shadow: 0 0 8px rgba(0, 0, 0, .8); + -moz-box-shadow: 0 0 8px rgba(0, 0, 0, .8); +} + + /*div.img campusAvatar { diff --git a/templates/js/controllers/registerController.js b/templates/js/controllers/registerController.js index a2ca317..071096c 100644 --- a/templates/js/controllers/registerController.js +++ b/templates/js/controllers/registerController.js @@ -6,11 +6,11 @@ angular.module('SeHub') $scope.createCampusClicked = false; $scope.isEmpty = true; // if the academic email line is empty $scope.jsonCreateCampus = - { - "title": "Create Campus", - "email": "email_ending", - "avatar": "self.avatar.url" - } + { + "title": "Create Campus", + "email": "email_ending", + "avatar": "self.avatar.url" + } $rootScope.seToken = $cookies['com.sehub.www']; var token = $rootScope.seToken; @@ -57,10 +57,25 @@ angular.module('SeHub') $scope.submitClicked = function(ev) { var emailValid = false; + var jsonUpdateUser = + { + "lecturerStat": "$scope.user.isLecturer", + "campName": "$scope.campusName" + } + if($scope.user.AcMail != null) { var fullMail = $scope.user.AcMail + $scope.campusObj.email_ending; // Holds the full academic email of the user + apiService.updateUser($scope.user.seToken, jsonUpdateUser).success(function(data) + { + + }).error(function() + { + // TODO Error + console.log("Error occured on updateUser"); + }); + console.log("Mail: " + fullMail); apiService.sendValidationMail($scope.user.seToken, fullMail).success(function(data) From 51d11cac938fdb3ba010f16a24a392bbf6fc2970 Mon Sep 17 00:00:00 2001 From: Sagi Dayan Date: Wed, 17 Jun 2015 22:46:26 +0300 Subject: [PATCH 08/15] More Setings UI Tweaks --- templates/css/theme.css | 77 ++++++++++-- .../js/controllers/settingsController.js | 113 +++++++++++------- templates/views/settings.html | 53 +++++++- 3 files changed, 187 insertions(+), 56 deletions(-) diff --git a/templates/css/theme.css b/templates/css/theme.css index 92d6805..051785b 100644 --- a/templates/css/theme.css +++ b/templates/css/theme.css @@ -2,10 +2,10 @@ body{ font-family: "Alef Hebrew", - “Helvetica Neue”, - Helvetica, - Arial, - sans-serif; + “Helvetica Neue”, + Helvetica, + Arial, + sans-serif; } .menuBtn { @@ -144,10 +144,10 @@ body.noscroll } -.createCampus -{ - position:relative; -} + .createCampus + { + position:relative; + } /*div.img campusAvatar @@ -247,4 +247,63 @@ body.noscroll .se-menu ul a{ text-decoration: none !important; color: #7f7f7f; - } \ No newline at end of file + } + +/*Settings Style*/ + + .settingList .settingListItem:hover{ + background-color: #E2E2E2; + font-weight: bold; + } + + .settingList .settingListItemRoot{ + list-style: none; + padding: 0; + padding-left: 0; + } + + .settingList .settingListItem{ + width: 100%; + padding: 15px 0px auto 15px; + } + + +/*End Settings*/ + + + /*md Effects*/ + +.md-avatar{ + width: 40px; + height: 40px; + margin-top: 8px; + margin-bottom: 8px; + margin-right: 16px; + border-radius: 50%; + box-sizing: content-box; + } + + + md-list-item .md-no-style.md-button, md-list-item.md-no-proxy.md-button { + font-size: inherit; + height: inherit; + text-align: left; + text-transform: none; + width: 100%; + white-space: normal; +} + +md-list-item, md-list-item .md-list-item-inner { + display: -webkit-flex; + display: -ms-flexbox; + display: flex; + -webkit-justify-content: flex-start; + -ms-flex-pack: start; + justify-content: flex-start; + -webkit-align-items: center; + -ms-flex-align: center; + align-items: center; + min-height: 48px; +} + +/*End Effects for MD*/ \ No newline at end of file diff --git a/templates/js/controllers/settingsController.js b/templates/js/controllers/settingsController.js index b13edc8..81a4a98 100644 --- a/templates/js/controllers/settingsController.js +++ b/templates/js/controllers/settingsController.js @@ -1,57 +1,78 @@ angular.module('SeHub') - .controller('settingsController', ['$scope', '$rootScope', 'dataService','apiService', '$cookies', '$location', - function($scope, $rootScope, dataService ,apiService, $cookies, $location) { + .controller('settingsController', ['$scope', '$rootScope', 'dataService', 'apiService', '$cookies', '$location', + function($scope, $rootScope, dataService, apiService, $cookies, $location) { - var token = $cookies['com.sehub.www']; + var token = $cookies['com.sehub.www']; - $scope.loadingData = true; - $scope.isInRegisterMode = false; + $scope.loadingData = true; + $scope.isInRegisterMode = false; - $scope.title = "Settings" + $scope.title = "Settings" - apiService.getUserByToken(token).success(function(data) { - if (data.message == 'No User Found') { - console.error("No User Found!"); - } - $scope.loadingData = false; - $scope.user = data; - console.log(data); - if ($scope.user.isFirstLogin) { - $scope.menuObj = {}; - $scope.isInRegisterMode = true; + apiService.getUserByToken(token).success(function(data) { + if (data.message == 'No User Found') { + console.error("No User Found!"); + } $scope.loadingData = false; - $location.path('/register') + $scope.user = data; + console.log(data); + if ($scope.user.isFirstLogin) { + $scope.menuObj = {}; + $scope.isInRegisterMode = true; + $scope.loadingData = false; + $location.path('/register') + } + + }); + + $scope.isEditMode = false; + $scope.profileMode = "Edit Profile"; + $scope.profileModeIcon = "fa fa-pencil"; + + $scope.changeProfileMode = function() { + $scope.isEditMode = !$scope.isEditMode; + if ($scope.isEditMode) { + $scope.profileMode = "Save Profile"; + $scope.profileModeIcon = "fa fa-floppy-o"; + } else { + dataService.userBrodcast($scope.user); + $scope.profileMode = "Edit Profile"; + $scope.profileModeIcon = "fa fa-pencil"; + } } - }); + /** + * DEBUG DATA + */ + $scope.courses = [{ + "courseName": "Advance Math", + "campusName": "JCE", + "startDate": { + "year": 2015, + "month": 4, + "day": 3 + }, + "endDate": { + "year": 2016, + "month": 5, + "day": 14 + }, + "taskFlag": false, + "campus_avatar": "https://yt3.ggpht.com/--ZkWxybWGOM/AAAAAAAAAAI/AAAAAAAAAAA/_nAICC_kzzI/s88-c-k-no/photo.jpg" + }]; + + $scope.campuses = [{ + 'title': 'JCE', + 'email_ending': '@post.jce.ac.il', + 'master_user_id': 123453433341, + 'avatar_url': 'https://yt3.ggpht.com/--ZkWxybWGOM/AAAAAAAAAAI/AAAAAAAAAAA/_nAICC_kzzI/s88-c-k-no/photo.jpg' + }, { + 'title': 'Stanford', + 'email_ending': '@post.jce.ac.il', + 'master_user_id': 123453433341, + 'avatar_url': 'https://encrypted-tbn1.gstatic.com/images?q=tbn:ANd9GcR9M4uQgaJP1zyiCGw-dK31hU8buWqeuOi9vTXBd4Y8hQcFTZqA' + }]; - $scope.isEditMode = false; - $scope.profileMode = "Edit Profile"; - $scope.profileModeIcon = "fa fa-pencil"; - $scope.changeProfileMode = function() { - $scope.isEditMode = !$scope.isEditMode; - if ($scope.isEditMode) { - $scope.profileMode = "Save Profile"; - $scope.profileModeIcon = "fa fa-floppy-o"; - } else { - dataService.userBrodcast($scope.user); - $scope.profileMode = "Edit Profile"; - $scope.profileModeIcon = "fa fa-pencil"; - } } - - // { - // name: ";" - // isLecturer: false - // email: "sagidayan@gmail.com" - // username: "sagidayan" - // seToken: "76cd4178-94dd-4cb4-b464-111d2239e567" - // isFirstLogin: true - // campuses_id_list: [0] - // classes_id_list: [0] - // avatar_url: "https://avatars.githubusercontent.com/u/2984053?v=3" - // } - - - }]); \ No newline at end of file + ]); \ No newline at end of file diff --git a/templates/views/settings.html b/templates/views/settings.html index 70c88f7..7f07403 100644 --- a/templates/views/settings.html +++ b/templates/views/settings.html @@ -9,6 +9,7 @@
+
@@ -20,6 +21,7 @@
+

{{user.name}}

@@ -31,7 +33,7 @@ I Am a: {{(user.isLecturer) ? "Lecturer" : "Student"}}
- +
@@ -52,8 +54,57 @@
+
+ +
+ +

My Classes

+
+
+
+
+ {{ person.name }} +
+
+ {{ course.courseName }} - IN {{course.campusName}} +
+
+
+ + X + +
+ +
+
+
+ +

My Campuses

+ +
+
+
+
+ {{ person.name }} +
+
+ {{ campus.title }} - +
+
+
+ + X + +
+ +
+
+
+
+
+
From ee7e023d56465688cb1c0b0db2a09134cda99bec Mon Sep 17 00:00:00 2001 From: Matan Bar Yosef Date: Wed, 17 Jun 2015 23:16:49 +0300 Subject: [PATCH 09/15] - removed md-list "no style" and other styling - feed pattern Added --- templates/css/theme.css | 24 +++----- templates/js/controllers/homeController.js | 65 +++++++++++++++++++++- templates/views/home.html | 46 ++++++++++++++- 3 files changed, 113 insertions(+), 22 deletions(-) diff --git a/templates/css/theme.css b/templates/css/theme.css index 5e262e3..7ab3384 100644 --- a/templates/css/theme.css +++ b/templates/css/theme.css @@ -146,10 +146,10 @@ body.noscroll } - .createCampus - { - position:relative; - } +.createCampus +{ + position:relative; +} .listdemoBasicUsage md-divider { @@ -187,15 +187,6 @@ body.noscroll -moz-box-shadow: 0 0 8px rgba(0, 0, 0, .8); } - - -/*div.img campusAvatar -{ - border: 1px solid #0000ff; - padding-right: 10px; - float:right; - }*/ - /*.dropDown /* TODO * { border-bottom: 2px black solid; @@ -205,7 +196,8 @@ body.noscroll border-radius: 1px black solid; }*/ - .gray-font{ + .gray-font + { color: #7f7f7f; font-size: 300%; text-shadow:#e0e0e0 1px 1px 0; @@ -323,7 +315,7 @@ body.noscroll } - md-list-item .md-no-style.md-button, md-list-item.md-no-proxy.md-button { +/* md-list-item .md-no-style.md-button, md-list-item.md-no-proxy.md-button { font-size: inherit; height: inherit; text-align: left; @@ -343,6 +335,6 @@ md-list-item, md-list-item .md-list-item-inner { -ms-flex-align: center; align-items: center; min-height: 48px; -} +}*/ /*End Effects for MD*/ \ No newline at end of file diff --git a/templates/js/controllers/homeController.js b/templates/js/controllers/homeController.js index 46395cb..98c95ca 100644 --- a/templates/js/controllers/homeController.js +++ b/templates/js/controllers/homeController.js @@ -1,9 +1,68 @@ -/** - * Created by sagi on 6/16/15. - */ angular.module('SeHub') .controller('homeController', ['$scope', '$cookies', '$cookieStore', '$window', '$location', '$mdToast', '$mdDialog', 'apiService', '$rootScope', function ($scope, $cookies, $cookieStore, $window, $location, $mdToast, $mdDialog, apiService ,$rootScope) { + var imagePath = $scope.user.avatar_url; + $scope.phones = [ + { type: 'Home', number: '(972) 865-82861' }, + { type: 'Cell', number: '(972) 5251-32309' }, + ]; + + $scope.messages = [ + { + face : imagePath, + what: 'I need to go to luna-park', + who: 'Matan Bar Yosef', + when: '3:08PM', + notes: " Lets do something" + }, + { + face : imagePath, + what: 'Lets Lets Lets', + who: 'Matan Bar Yosef', + when: '4:33PM', + notes: " Lets go drink something" + }, + { + face : imagePath, + what: 'Let me tell you a secret', + who: 'Sagi Dayan', + when: '4:15PM', + notes: " I am S'ein" + }, + { + face : imagePath, + what: 'Listen to this!', + who: 'Aran Zaiger', + when: '6:15PM', + notes: " I am gaylord ultima!!" + }, + { + face : imagePath, + what: 'Hi?', + who: 'Etye Meyer', + when: '7:45AM', + notes: " I am mega gaylord ultima" + } + ]; + + $scope.tasks = [ + { + ExNum: '1', + dueDate: '23/06/15', + notes: " Build A Game: Scrabble" + }, + { + ExNum: '3', + dueDate: '30/06/15', + notes: " Static Array" + }, + { + ExNum: '4', + dueDate: '07/07/15', + notes: " Dynamic Array" + }, + ]; + }]); \ No newline at end of file diff --git a/templates/views/home.html b/templates/views/home.html index 881bf23..391e23b 100644 --- a/templates/views/home.html +++ b/templates/views/home.html @@ -15,12 +15,52 @@

Welcome To SE-Hub

-

- This Is your Home Page -

+ + +
+
+ Messages + +
+ {{item.who}} + + +
+

+ +

{{ item.who }}

+
{{ item.what }}
+
{{ item.notes }}
+
{{ item.when }}
+
+
+
+
+ + +
+
+ + + + Tasks + + +
+ +
Ex: {{ item.ExNum }}
+
Task Title: {{ item.notes }}
+
Due Date: {{ item.dueDate }}
+
+
+
+
+
+
+
\ No newline at end of file From 83b252249d6f6604e84eda9e98bc1c19d91c8ead Mon Sep 17 00:00:00 2001 From: Sagi Dayan Date: Wed, 17 Jun 2015 23:58:59 +0300 Subject: [PATCH 10/15] Home Animation --- templates/css/theme.css | 48 ++++++++++++++++++++++++++++++++++----- templates/views/home.html | 4 +++- 2 files changed, 45 insertions(+), 7 deletions(-) diff --git a/templates/css/theme.css b/templates/css/theme.css index 7ab3384..b132759 100644 --- a/templates/css/theme.css +++ b/templates/css/theme.css @@ -111,8 +111,8 @@ body.noscroll }*/ -.campusAvatar img -{ + .campusAvatar img + { /* margin-top: 1em; margin-right: 1em; @@ -201,6 +201,42 @@ body.noscroll color: #7f7f7f; font-size: 300%; text-shadow:#e0e0e0 1px 1px 0; + opacity: 0; + -webkit-animation-duration: 8s; + animation-duration: 8s; + -webkit-animation-fill-mode: both; + animation-fill-mode: both; + overflow: hidden; + height: 100%; + } + + @-webkit-keyframes fadeOutUp { + 0% { + opacity: 1; + -webkit-transform: translateY(0); + } + 100% { + opacity: 0; + -webkit-transform: translateY(-200px); + /*-webkit-transform: scale(0,0); */ + height: 0px; + } + } + @keyframes fadeOutUp { + 0% { + opacity: 1; + transform: translateY(0); + } + 100% { + opacity: 0; + transform: translateY(-200px); + /*transform: scale(0,0); */ + height: 0px; + } + } + .fadeOutUp { + -webkit-animation-name: fadeOutUp; + animation-name: fadeOutUp; } .user-pane-menu{ @@ -280,7 +316,7 @@ body.noscroll color: #7f7f7f; } -/*Settings Style*/ + /*Settings Style*/ .settingList .settingListItem:hover{ background-color: #E2E2E2; @@ -299,12 +335,12 @@ body.noscroll } -/*End Settings*/ + /*End Settings*/ /*md Effects*/ -.md-avatar{ + .md-avatar{ width: 40px; height: 40px; margin-top: 8px; @@ -335,6 +371,6 @@ md-list-item, md-list-item .md-list-item-inner { -ms-flex-align: center; align-items: center; min-height: 48px; -}*/ + }*/ /*End Effects for MD*/ \ No newline at end of file diff --git a/templates/views/home.html b/templates/views/home.html index 391e23b..a1b3d9b 100644 --- a/templates/views/home.html +++ b/templates/views/home.html @@ -3,7 +3,7 @@ - +
@@ -15,6 +15,8 @@

Welcome To SE-Hub

+

Software Engineering Course Made Easy

+ v1.0
From af608da379768bbfc8a794f52f19ff52465aa79c Mon Sep 17 00:00:00 2001 From: Sagi Dayan Date: Thu, 18 Jun 2015 00:04:36 +0300 Subject: [PATCH 11/15] Home Animation Only Once fix --- templates/js/controllers/homeController.js | 3 +++ templates/js/controllers/mainController.js | 3 ++- templates/views/home.html | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/templates/js/controllers/homeController.js b/templates/js/controllers/homeController.js index 98c95ca..009a4f5 100644 --- a/templates/js/controllers/homeController.js +++ b/templates/js/controllers/homeController.js @@ -65,4 +65,7 @@ angular.module('SeHub') + + // animation + $scope.isEnterd = top.setIsEnterd; }]); \ No newline at end of file diff --git a/templates/js/controllers/mainController.js b/templates/js/controllers/mainController.js index 08b10d6..1f175ab 100644 --- a/templates/js/controllers/mainController.js +++ b/templates/js/controllers/mainController.js @@ -2,7 +2,7 @@ angular.module('SeHub') .controller('mainController', ['$scope', '$rootScope', 'dataService','apiService', '$cookies', '$cookieStore', '$location', '$window', function($scope, $rootScope, dataService, apiService, $cookies, $cookieStore, $location, $window) { - + top.setIsEnterd = true; var token = $cookies['com.sehub.www']; $scope.loadingData = true; @@ -81,6 +81,7 @@ angular.module('SeHub') $scope.menuItems[i].style = ""; } }; + top.setIsEnterd = false; $location.path(route); } diff --git a/templates/views/home.html b/templates/views/home.html index a1b3d9b..7b2fc30 100644 --- a/templates/views/home.html +++ b/templates/views/home.html @@ -3,7 +3,7 @@
- +
From a2b763e00db814ea9ca941f08ae2660a87b8f845 Mon Sep 17 00:00:00 2001 From: Matan Bar Yosef Date: Thu, 18 Jun 2015 21:13:31 +0300 Subject: [PATCH 12/15] - feed design Fixed --- templates/css/theme.css | 94 +++++++++++++++------- templates/js/controllers/homeController.js | 14 ---- templates/views/home.html | 58 +++++-------- 3 files changed, 87 insertions(+), 79 deletions(-) diff --git a/templates/css/theme.css b/templates/css/theme.css index b132759..ed28d11 100644 --- a/templates/css/theme.css +++ b/templates/css/theme.css @@ -76,28 +76,21 @@ body.noscroll margin-top: 1em; margin-right: 1em; position: center; - -webkit-border-radius: 30%; -moz-border-radius: 30%; border-radius: 30%; - - } -/*.avatar { - background: rgba(0, 0, 0, 0.2); - }*/ - - .avatar img { - border-radius: 40px; - position:center; - width: 80px; - height: 80px; - margin: 6px; /*centers the image in the parent element */ - -webkit-box-shadow: 2px 2px 5px 0px rgba(0,0,0,0.75); - -moz-box-shadow: 2px 2px 5px 0px rgba(0,0,0,0.75); - box-shadow: 2px 2px 5px 0px rgba(0,0,0,0.75); - } +.avatar img { + border-radius: 40px; + position:center; + width: 80px; + height: 80px; + margin: 6px; /*centers the image in the parent element */ + -webkit-box-shadow: 2px 2px 5px 0px rgba(0,0,0,0.75); + -moz-box-shadow: 2px 2px 5px 0px rgba(0,0,0,0.75); + box-shadow: 2px 2px 5px 0px rgba(0,0,0,0.75); +} /* Added BY devMatan */ @@ -111,14 +104,8 @@ body.noscroll }*/ - .campusAvatar img - { -/* - margin-top: 1em; - margin-right: 1em; - position: center; - */ - +.campusAvatar img +{ border-radius: 40px; position:center; width: 80px; @@ -162,6 +149,26 @@ body.noscroll /*TODO*/ } +.feed +{ + overflow-y: scroll; + height: 300px; + /*width: 100%;*/ +} + +.feedMessages +{ + overflow: scroll; + height: 300px; + width: 100%; +} +.feedTasks +{ + overflow: scroll; + height: 300px; + width: 100%; +} + .feedContent { padding-left: 6%; @@ -181,7 +188,6 @@ body.noscroll border-radius: 150px; -webkit-border-radius: 150px; -moz-border-radius: 150px; - /*background: url(http://i61.tinypic.com/v86f7.png) no-repeat;*/ box-shadow: 0 0 8px rgba(0, 0, 0, .8); -webkit-box-shadow: 0 0 8px rgba(0, 0, 0, .8); -moz-box-shadow: 0 0 8px rgba(0, 0, 0, .8); @@ -302,7 +308,6 @@ body.noscroll .user-box img{ width: 100%; border: 4px #7f7f7f solid; - -webkit-border-radius: 5px; -moz-border-radius: 5px; border-radius: 5px; @@ -351,6 +356,41 @@ body.noscroll } +/*gridList Effects*/ + +md-grid-list { + margin: 8px; } +.gray{ + background:#f5f5f5; + +} + +.aliceblue { + background: aliceblue; +} + .green { + background: #b9f6ca; +} + .yellow { + background: #ffff8d; +} + .blue { + background: #84ffff; +} + .purple { + background: #b388ff; +} + .red { + background: #ff8a80; +} + md-grid-tile { + transition: all 400ms ease-out 50ms; +} + +/*END gridList Effects*/ + + + /* md-list-item .md-no-style.md-button, md-list-item.md-no-proxy.md-button { font-size: inherit; height: inherit; diff --git a/templates/js/controllers/homeController.js b/templates/js/controllers/homeController.js index 009a4f5..573dab3 100644 --- a/templates/js/controllers/homeController.js +++ b/templates/js/controllers/homeController.js @@ -8,20 +8,6 @@ angular.module('SeHub') ]; $scope.messages = [ - { - face : imagePath, - what: 'I need to go to luna-park', - who: 'Matan Bar Yosef', - when: '3:08PM', - notes: " Lets do something" - }, - { - face : imagePath, - what: 'Lets Lets Lets', - who: 'Matan Bar Yosef', - when: '4:33PM', - notes: " Lets go drink something" - }, { face : imagePath, what: 'Let me tell you a secret', diff --git a/templates/views/home.html b/templates/views/home.html index 7b2fc30..65dabb3 100644 --- a/templates/views/home.html +++ b/templates/views/home.html @@ -24,45 +24,27 @@ -
-
- Messages - -
- {{item.who}} - - -
-

- -

{{ item.who }}

-
{{ item.what }}
-
{{ item.notes }}
-
{{ item.when }}
-
-
-
+
+ + + +

Messages

+
+ +
+ + +

Tasks

+
+ +
+
-
-
- - - - Tasks - - -
- -
Ex: {{ item.ExNum }}
-
Task Title: {{ item.notes }}
-
Due Date: {{ item.dueDate }}
-
-
-
-
-
-
-
\ No newline at end of file From 94cf0447e4bba64b033041eed5161a3e9308d9a8 Mon Sep 17 00:00:00 2001 From: Matan Bar Yosef Date: Thu, 18 Jun 2015 23:21:09 +0300 Subject: [PATCH 13/15] - tasks.html added - tasksController added - app.js updated when '/tasks' - mainController updated '/tasks' --- templates/css/theme.css | 46 +++++++++++++--------- templates/js/app.js | 5 ++- templates/js/controllers/mainController.js | 2 +- templates/views/home.html | 27 ++++++++++++- 4 files changed, 57 insertions(+), 23 deletions(-) diff --git a/templates/css/theme.css b/templates/css/theme.css index ed28d11..815890f 100644 --- a/templates/css/theme.css +++ b/templates/css/theme.css @@ -86,7 +86,7 @@ body.noscroll position:center; width: 80px; height: 80px; - margin: 6px; /*centers the image in the parent element */ + margin: 6px; -webkit-box-shadow: 2px 2px 5px 0px rgba(0,0,0,0.75); -moz-box-shadow: 2px 2px 5px 0px rgba(0,0,0,0.75); box-shadow: 2px 2px 5px 0px rgba(0,0,0,0.75); @@ -144,11 +144,6 @@ body.noscroll margin-bottom: 10px; } -.md-avatar img -{ - /*TODO*/ -} - .feed { overflow-y: scroll; @@ -156,7 +151,7 @@ body.noscroll /*width: 100%;*/ } -.feedMessages +/*.feedMessages { overflow: scroll; height: 300px; @@ -174,7 +169,7 @@ body.noscroll padding-left: 6%; font-size: 15px; display:table; -} +}*/ .md-no-sticky { @@ -262,7 +257,6 @@ body.noscroll -moz-border-radius: 100px; border-radius: 50px; width: 30%; - /*top: -40px;*/ position: relative; z-index: 50; } @@ -355,14 +349,15 @@ body.noscroll box-sizing: content-box; } - /*gridList Effects*/ -md-grid-list { - margin: 8px; } -.gray{ +md-grid-list +{ + margin: 8px; +} +.gray +{ background:#f5f5f5; - } .aliceblue { @@ -383,24 +378,37 @@ md-grid-list { .red { background: #ff8a80; } - md-grid-tile { - transition: all 400ms ease-out 50ms; + +.whiteframedemoBasicUsage md-whiteframe { + background: #fff; + margin: 20px; + padding: 20px; } + +/* md-grid-tile { + transition: all 400ms ease-out 50ms; +}*/ + /*END gridList Effects*/ +.tasksContent +{ + /*float:left;*/ +} -/* md-list-item .md-no-style.md-button, md-list-item.md-no-proxy.md-button { + + md-list-item .md-no-style.md-button, md-list-item.md-no-proxy.md-button { font-size: inherit; height: inherit; text-align: left; text-transform: none; - width: 100%; + width: 300px; white-space: normal; } -md-list-item, md-list-item .md-list-item-inner { +/*md-list-item, md-list-item .md-list-item-inner { display: -webkit-flex; display: -ms-flexbox; display: flex; diff --git a/templates/js/app.js b/templates/js/app.js index 86cbcc1..0a154b5 100644 --- a/templates/js/app.js +++ b/templates/js/app.js @@ -41,8 +41,11 @@ app.config(['$routeProvider', '$locationProvider', .when('/Settings', { templateUrl: 'templates/views/settings.html', controller: 'settingsController' + }) + .when('/tasks', { + templateUrl: 'templates/views/tasks.html', + controller: 'tasksController' }); - } ]); diff --git a/templates/js/controllers/mainController.js b/templates/js/controllers/mainController.js index 1f175ab..f2eb0b4 100644 --- a/templates/js/controllers/mainController.js +++ b/templates/js/controllers/mainController.js @@ -53,7 +53,7 @@ angular.module('SeHub') "title": "Tasks", "icon": "fa fa-clipboard", "style": "", - "route": "/campuses" + "route": "/tasks" }, { "title": "Settings", "icon": "fa fa-cogs", diff --git a/templates/views/home.html b/templates/views/home.html index 65dabb3..b312bf7 100644 --- a/templates/views/home.html +++ b/templates/views/home.html @@ -22,6 +22,7 @@
+
@@ -34,17 +35,39 @@

Messages

- + In The Future Will Enter Wanted MESSAGES Text Here

Tasks

- + +
+ For Task 3 Press: Task #3 +
=====================
+ For Task 4 Press: Task #4 +
+
+ + + + + + + + +
\ No newline at end of file From da224b25d8250e4d3d3e1d58a51083d08d5c7103 Mon Sep 17 00:00:00 2001 From: Sagi Dayan Date: Thu, 18 Jun 2015 23:26:51 +0300 Subject: [PATCH 14/15] Settings: Now Updating the user via API call --- templates/js/controllers/settingsController.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/templates/js/controllers/settingsController.js b/templates/js/controllers/settingsController.js index 81a4a98..a40122a 100644 --- a/templates/js/controllers/settingsController.js +++ b/templates/js/controllers/settingsController.js @@ -35,7 +35,13 @@ angular.module('SeHub') $scope.profileMode = "Save Profile"; $scope.profileModeIcon = "fa fa-floppy-o"; } else { - dataService.userBrodcast($scope.user); + apiService.updateUser(token, $scope.user).success(function(data){ + console.info('User Saved'); + dataService.userBrodcast($scope.user); + + }).error(function(e){ + console.error('Fail To Save User'); + }); $scope.profileMode = "Edit Profile"; $scope.profileModeIcon = "fa fa-pencil"; } From 42214390852a8e0dac49c9b92ddec17592b41a43 Mon Sep 17 00:00:00 2001 From: Sagi Dayan Date: Fri, 19 Jun 2015 00:02:06 +0300 Subject: [PATCH 15/15] Added a js chart lib + example in settings --- templates/js/app.js | 2 +- .../js/controllers/settingsController.js | 13 +- .../libs/angular-chart.js-0.7.2/.editorconfig | 18 + .../js/libs/angular-chart.js-0.7.2/.gitignore | 4 + .../js/libs/angular-chart.js-0.7.2/.jscsrc | 80 + .../libs/angular-chart.js-0.7.2/.jshintignore | 6 + .../js/libs/angular-chart.js-0.7.2/.jshintrc | 22 + .../libs/angular-chart.js-0.7.2/.travis.yml | 13 + .../js/libs/angular-chart.js-0.7.2/LICENSE | 27 + .../js/libs/angular-chart.js-0.7.2/README.md | 175 + .../angular-chart.js-0.7.2/angular-chart.js | 301 + .../angular-chart.js-0.7.2/angular-chart.less | 30 + .../js/libs/angular-chart.js-0.7.2/bower.json | 56 + .../dist/angular-chart.css | 2 + .../dist/angular-chart.css.map | 1 + .../dist/angular-chart.js | 301 + .../dist/angular-chart.js.tar.gz | Bin 0 -> 9230 bytes .../dist/angular-chart.min.js | 2 + .../dist/angular-chart.min.js.map | 1 + .../libs/angular-chart.js-0.7.2/dist/chart.js | 3477 ++++++++++ .../angular-chart.js-0.7.2/examples/app.css | 80 + .../angular-chart.js-0.7.2/examples/app.js | 185 + .../examples/bootstrap.css | 5785 +++++++++++++++++ .../examples/charts.html | 462 ++ .../examples/charts.template.html | 462 ++ .../examples/smoothscroll.min.js | 1 + .../examples/stacked-bars-directive.html | 39 + .../examples/stacked-bars.html | 32 + .../examples/tables.html | 46 + .../examples/ticks.html | 30 + .../libs/angular-chart.js-0.7.2/gulpfile.js | 135 + .../libs/angular-chart.js-0.7.2/package.json | 51 + .../test/fixtures/51-pie-update-colours.html | 36 + .../test/fixtures/51-pie-update-colours.js | 30 + .../test/fixtures/51-pie-update-colours.png | Bin 0 -> 35810 bytes .../test/fixtures/54-not-enough-colours.html | 37 + .../test/fixtures/54-not-enough-colours.js | 32 + .../test/fixtures/54-not-enough-colours.png | Bin 0 -> 35810 bytes .../test/fixtures/57-hex-colours.html | 36 + .../test/fixtures/57-hex-colours.js | 11 + .../test/fixtures/57-hex-colours.png | Bin 0 -> 34702 bytes .../test/fixtures/charts.html | 78 + .../test/fixtures/charts.js | 61 + .../test/fixtures/charts.png | Bin 0 -> 90895 bytes .../test/fixtures/configure-line-chart.html | 33 + .../test/fixtures/configure-line-chart.js | 32 + .../test/fixtures/configure-line-chart.png | Bin 0 -> 32774 bytes .../test/fixtures/custom-directive.html | 33 + .../test/fixtures/custom-directive.js | 17 + .../test/fixtures/custom-directive.png | Bin 0 -> 30363 bytes .../angular-chart.js-0.7.2/test/index.html | 30 + .../angular-chart.js-0.7.2/test/mocha.opts | 4 + .../test/support/setup.js | 11 + .../test/test.integration.js | 69 + .../angular-chart.js-0.7.2/test/test.unit.js | 372 ++ templates/views/index.html | 12 + templates/views/settings.html | 2 + 57 files changed, 12772 insertions(+), 3 deletions(-) create mode 100644 templates/js/libs/angular-chart.js-0.7.2/.editorconfig create mode 100644 templates/js/libs/angular-chart.js-0.7.2/.gitignore create mode 100644 templates/js/libs/angular-chart.js-0.7.2/.jscsrc create mode 100644 templates/js/libs/angular-chart.js-0.7.2/.jshintignore create mode 100644 templates/js/libs/angular-chart.js-0.7.2/.jshintrc create mode 100644 templates/js/libs/angular-chart.js-0.7.2/.travis.yml create mode 100644 templates/js/libs/angular-chart.js-0.7.2/LICENSE create mode 100644 templates/js/libs/angular-chart.js-0.7.2/README.md create mode 100644 templates/js/libs/angular-chart.js-0.7.2/angular-chart.js create mode 100644 templates/js/libs/angular-chart.js-0.7.2/angular-chart.less create mode 100644 templates/js/libs/angular-chart.js-0.7.2/bower.json create mode 100644 templates/js/libs/angular-chart.js-0.7.2/dist/angular-chart.css create mode 100755 templates/js/libs/angular-chart.js-0.7.2/dist/angular-chart.css.map create mode 100644 templates/js/libs/angular-chart.js-0.7.2/dist/angular-chart.js create mode 100755 templates/js/libs/angular-chart.js-0.7.2/dist/angular-chart.js.tar.gz create mode 100644 templates/js/libs/angular-chart.js-0.7.2/dist/angular-chart.min.js create mode 100644 templates/js/libs/angular-chart.js-0.7.2/dist/angular-chart.min.js.map create mode 100644 templates/js/libs/angular-chart.js-0.7.2/dist/chart.js create mode 100644 templates/js/libs/angular-chart.js-0.7.2/examples/app.css create mode 100644 templates/js/libs/angular-chart.js-0.7.2/examples/app.js create mode 100644 templates/js/libs/angular-chart.js-0.7.2/examples/bootstrap.css create mode 100644 templates/js/libs/angular-chart.js-0.7.2/examples/charts.html create mode 100644 templates/js/libs/angular-chart.js-0.7.2/examples/charts.template.html create mode 100644 templates/js/libs/angular-chart.js-0.7.2/examples/smoothscroll.min.js create mode 100644 templates/js/libs/angular-chart.js-0.7.2/examples/stacked-bars-directive.html create mode 100644 templates/js/libs/angular-chart.js-0.7.2/examples/stacked-bars.html create mode 100644 templates/js/libs/angular-chart.js-0.7.2/examples/tables.html create mode 100644 templates/js/libs/angular-chart.js-0.7.2/examples/ticks.html create mode 100644 templates/js/libs/angular-chart.js-0.7.2/gulpfile.js create mode 100644 templates/js/libs/angular-chart.js-0.7.2/package.json create mode 100644 templates/js/libs/angular-chart.js-0.7.2/test/fixtures/51-pie-update-colours.html create mode 100644 templates/js/libs/angular-chart.js-0.7.2/test/fixtures/51-pie-update-colours.js create mode 100644 templates/js/libs/angular-chart.js-0.7.2/test/fixtures/51-pie-update-colours.png create mode 100644 templates/js/libs/angular-chart.js-0.7.2/test/fixtures/54-not-enough-colours.html create mode 100644 templates/js/libs/angular-chart.js-0.7.2/test/fixtures/54-not-enough-colours.js create mode 100644 templates/js/libs/angular-chart.js-0.7.2/test/fixtures/54-not-enough-colours.png create mode 100644 templates/js/libs/angular-chart.js-0.7.2/test/fixtures/57-hex-colours.html create mode 100644 templates/js/libs/angular-chart.js-0.7.2/test/fixtures/57-hex-colours.js create mode 100644 templates/js/libs/angular-chart.js-0.7.2/test/fixtures/57-hex-colours.png create mode 100644 templates/js/libs/angular-chart.js-0.7.2/test/fixtures/charts.html create mode 100644 templates/js/libs/angular-chart.js-0.7.2/test/fixtures/charts.js create mode 100644 templates/js/libs/angular-chart.js-0.7.2/test/fixtures/charts.png create mode 100644 templates/js/libs/angular-chart.js-0.7.2/test/fixtures/configure-line-chart.html create mode 100644 templates/js/libs/angular-chart.js-0.7.2/test/fixtures/configure-line-chart.js create mode 100644 templates/js/libs/angular-chart.js-0.7.2/test/fixtures/configure-line-chart.png create mode 100644 templates/js/libs/angular-chart.js-0.7.2/test/fixtures/custom-directive.html create mode 100644 templates/js/libs/angular-chart.js-0.7.2/test/fixtures/custom-directive.js create mode 100644 templates/js/libs/angular-chart.js-0.7.2/test/fixtures/custom-directive.png create mode 100644 templates/js/libs/angular-chart.js-0.7.2/test/index.html create mode 100644 templates/js/libs/angular-chart.js-0.7.2/test/mocha.opts create mode 100644 templates/js/libs/angular-chart.js-0.7.2/test/support/setup.js create mode 100644 templates/js/libs/angular-chart.js-0.7.2/test/test.integration.js create mode 100644 templates/js/libs/angular-chart.js-0.7.2/test/test.unit.js diff --git a/templates/js/app.js b/templates/js/app.js index 0a154b5..3a9b514 100644 --- a/templates/js/app.js +++ b/templates/js/app.js @@ -2,7 +2,7 @@ var DEBUG = true; var welcome = angular.module('welcome', ['ngMaterial', 'seHub.services', 'ngRoute' , 'ngCookies']); -var app = angular.module('SeHub', ['ngMaterial', 'ngRoute', 'seHub.services', 'ngCookies']); +var app = angular.module('SeHub', ['ngMaterial', 'ngRoute', 'seHub.services', 'ngCookies', 'chart.js']); welcome.config(function($mdThemingProvider) { diff --git a/templates/js/controllers/settingsController.js b/templates/js/controllers/settingsController.js index a40122a..35c9531 100644 --- a/templates/js/controllers/settingsController.js +++ b/templates/js/controllers/settingsController.js @@ -35,11 +35,11 @@ angular.module('SeHub') $scope.profileMode = "Save Profile"; $scope.profileModeIcon = "fa fa-floppy-o"; } else { - apiService.updateUser(token, $scope.user).success(function(data){ + apiService.updateUser(token, $scope.user).success(function(data) { console.info('User Saved'); dataService.userBrodcast($scope.user); - }).error(function(e){ + }).error(function(e) { console.error('Fail To Save User'); }); $scope.profileMode = "Edit Profile"; @@ -80,5 +80,14 @@ angular.module('SeHub') }]; + $scope.labels = ['Commits', 'Issues Assigned', 'Messages', 'Open Tasks']; + $scope.series = ['Project A', 'Project B']; + + $scope.data = [ + [54, 3, 15, 3], + [28, 48, 40, 3] + ]; + + } ]); \ No newline at end of file diff --git a/templates/js/libs/angular-chart.js-0.7.2/.editorconfig b/templates/js/libs/angular-chart.js-0.7.2/.editorconfig new file mode 100644 index 0000000..8565360 --- /dev/null +++ b/templates/js/libs/angular-chart.js-0.7.2/.editorconfig @@ -0,0 +1,18 @@ +# This file is for unifying the coding style for different editors and IDEs +# editorconfig.org + +root = true + +[*] +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true + +# Tabs in JS unless otherwise specified +[**.js] +indent_style = space +indent_size = 2 + +[*.md] +trim_trailing_whitespace = false \ No newline at end of file diff --git a/templates/js/libs/angular-chart.js-0.7.2/.gitignore b/templates/js/libs/angular-chart.js-0.7.2/.gitignore new file mode 100644 index 0000000..aeb776d --- /dev/null +++ b/templates/js/libs/angular-chart.js-0.7.2/.gitignore @@ -0,0 +1,4 @@ +.idea/ +node_modules/ +test/fixtures/shots/ +bower_components/ diff --git a/templates/js/libs/angular-chart.js-0.7.2/.jscsrc b/templates/js/libs/angular-chart.js-0.7.2/.jscsrc new file mode 100644 index 0000000..2095ebc --- /dev/null +++ b/templates/js/libs/angular-chart.js-0.7.2/.jscsrc @@ -0,0 +1,80 @@ +{ + "requireCurlyBraces": [ + "try", + "catch", + "do" + ], + "requireCamelCaseOrUpperCaseIdentifiers": "ignoreProperties", + "requireCapitalizedConstructors": true, + "maximumLineLength": { + "value": 120, + "allowComments": true, + "allowRegex": true + }, + "validateIndentation": 2, + "validateQuoteMarks": "'", + + "disallowMultipleLineStrings": true, + "disallowMixedSpacesAndTabs": true, + "disallowTrailingWhitespace": true, + "disallowQuotedKeysInObjects": true, + "disallowSpaceAfterObjectKeys": true, + + "requireSpaceAfterKeywords": [ + "if", + "else", + "for", + "while", + "do", + "switch", + "return", + "try", + "catch", + "function", + "typeof" + ], + "requireSpaceBeforeBinaryOperators": [ + "=", "+=", "-=", "*=", "/=", "%=", "<<=", ">>=", ">>>=", + "&=", "|=", "^=", "+=", + + "+", "-", "*", "/", "%", "<<", ">>", ">>>", "&", + "|", "^", "&&", "||", "===", "==", ">=", + "<=", "<", ">", "!=", "!==" + ], + "requireSpaceAfterPrefixUnaryOperators": [ + "!" + ], + "requireSpacesInConditionalExpression": true, + "requireSpaceBeforeBlockStatements": true, + "requireSpacesInForStatement": true, + "requireLineFeedAtFileEnd": true, + "requireSpacesInFunctionExpression": { + "beforeOpeningCurlyBrace": true, + "beforeOpeningRoundBrace": true + }, + "requireSpacesInFunctionDeclaration": { + "beforeOpeningCurlyBrace": true, + "beforeOpeningRoundBrace": true + }, + "requireDotNotation": true, + "disallowSpacesInsideArrayBrackets": "all", + "disallowSpacesInsideParentheses": true, + + + "validateJSDoc": { + "checkParamNames": true, + "requireParamTypes": true + }, + + "disallowMultipleLineBreaks": true, + "disallowNewlineBeforeBlockStatements": true, + "disallowKeywords": [ "with" ], + + "excludeFiles": [ + "bower_components/**", + "node_modules/**", + "dist/**", + "test/coverage/**", + "examples/smoothscroll.min.js" + ] +} diff --git a/templates/js/libs/angular-chart.js-0.7.2/.jshintignore b/templates/js/libs/angular-chart.js-0.7.2/.jshintignore new file mode 100644 index 0000000..0ce3e64 --- /dev/null +++ b/templates/js/libs/angular-chart.js-0.7.2/.jshintignore @@ -0,0 +1,6 @@ +bower_components/ +node_modules/ +dist/ +tmp/ +examples/smoothscroll.min.js + diff --git a/templates/js/libs/angular-chart.js-0.7.2/.jshintrc b/templates/js/libs/angular-chart.js-0.7.2/.jshintrc new file mode 100644 index 0000000..59c7bdc --- /dev/null +++ b/templates/js/libs/angular-chart.js-0.7.2/.jshintrc @@ -0,0 +1,22 @@ +{ + "strict" : true, // true: Requires all functions run in ES5 Strict Mode + "undef" : true, // true: Require all non-global variables to be declared (prevents global leaks) + "unused" : true, // true: Require all defined variables be used + "noempty" : true, // Prohibit use of empty blocks + "trailing" : true, // Prohibit trailing whitespaces. + "white" : false, // Check against strict whitespace and indentation rules. + "indent" : 2, // {int} Number of spaces to use for indentation + "newcap" : true, // true: Require capitalization of all constructor functions e.g. `new F()` + "quotmark" : "single", // Quotation mark consistency + "-W058" : true, // Missing '()' invoking a constructor + "browser" : true, // Standard browser globals e.g. `window`, `document`. + "predef" : [ // Custom globals. + "angular", + "G_vmlCanvasManager", + "require", + "console", + "Chart", + "define", + "module" + ] +} diff --git a/templates/js/libs/angular-chart.js-0.7.2/.travis.yml b/templates/js/libs/angular-chart.js-0.7.2/.travis.yml new file mode 100644 index 0000000..08395fd --- /dev/null +++ b/templates/js/libs/angular-chart.js-0.7.2/.travis.yml @@ -0,0 +1,13 @@ +language: node_js +node_js: +- '0.10' +before_install: +- npm install -g bower +- bower install +- sudo apt-get install graphicsmagick +env: + global: + - secure: YWABlINoIkwl9RFLOW9G0lATEP3aiXXi+DS6TWfvQWWG/jkS5sn7IqWC2U67LjwQ0lDg0yevo3ZD7FyYQ5lr8AVuScAZ6P2o2dm9t/HBKGTG4u016dxbWWYVZ8MAlKT7TfjVD8iDzcWyZedsbpuyaNNp4pGr/CNcvq7TGdJLNkU= + - CI=1 + - TOLERANCE=0.002 + - DELAY=5000 diff --git a/templates/js/libs/angular-chart.js-0.7.2/LICENSE b/templates/js/libs/angular-chart.js-0.7.2/LICENSE new file mode 100644 index 0000000..f3bd714 --- /dev/null +++ b/templates/js/libs/angular-chart.js-0.7.2/LICENSE @@ -0,0 +1,27 @@ +Copyright (c) Jerome Touffe-Blin ("Author") +All rights reserved. + +The BSD License + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS +BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR +BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE +OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN +IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file diff --git a/templates/js/libs/angular-chart.js-0.7.2/README.md b/templates/js/libs/angular-chart.js-0.7.2/README.md new file mode 100644 index 0000000..28f65a1 --- /dev/null +++ b/templates/js/libs/angular-chart.js-0.7.2/README.md @@ -0,0 +1,175 @@ +# angular-chart.js + +[![Bower version](https://badge.fury.io/bo/angular-chart.js.svg)](http://badge.fury.io/bo/angular-chart.js) +[![npm version](https://badge.fury.io/js/angular-chart.js.svg)](http://badge.fury.io/js/angular-chart.js) +[![Build Status](https://travis-ci.org/jtblin/angular-chart.js.png)](https://travis-ci.org/jtblin/angular-chart.js) +[![Code Climate](https://codeclimate.com/github/jtblin/angular-chart.js/badges/gpa.svg)](https://codeclimate.com/github/jtblin/angular-chart.js) + +Beautiful, reactive, responsive charts for Angular.JS using [Chart.js](http://www.chartjs.org/). + +[Demo](http://jtblin.github.io/angular-chart.js/) + +# Installation + + bower install angular-chart.js --save + +or copy the files from `dist/`. Then add the sources to your code (adjust paths as needed) after +adding the dependencies for Angular and Chart.js first: + +```html + + + +``` + +# Utilisation + +There are 6 types of charts so 6 directives: `chart-line`, `chart-bar`, `chart-radar`, `chart-pie`, +`chart-polar-area`, `chart-doughnut`. + +They all use mostly the same API: + +- `data`: series data +- `labels`: x axis labels (line, bar, radar) or series labels (pie, doughnut, polar area) +- `options`: chart options (as from [Chart.js documentation](http://www.chartjs.org/docs/)) +- `series`: (default: `[]`): series labels (line, bar, radar) +- `colours`: data colours (will use default colours if not specified) +- `getColour`: function that returns a colour in case there are not enough (will use random colours if not specified) +- `click`: onclick event handler +- `hover`: onmousemove event handler +- `legend`: (default: `false`): show legend below the chart + +There is another directive `chart-base` that takes an extra attribute `chart-type` to define the type +dynamically, see [stacked bar example](http://jtblin.github.io/angular-chart.js/examples/stacked-bars.html). + +## Browser compatibility + +For IE8 and older browsers, you will need +to include [excanvas](https://code.google.com/p/explorercanvas/wiki/Instructions). +You will also need [shims](https://github.com/es-shims/es5-shim) for ES5 functions. + +```html + + + + +``` + +# Example + +## Markup + +```html + +``` + +## Javascript + +```javascript +angular.module("app", ["chart.js"]) + // Optional configuration + .config(['ChartJsProvider', function (ChartJsProvider) { + // Configure all charts + ChartJsProvider.setOptions({ + colours: ['#FF5252', '#FF8A80'], + responsive: false + }); + // Configure all line charts + ChartJsProvider.setOptions('Line', { + datasetFill: false + }); + }]) + .controller("LineCtrl", ['$scope', '$timeout', function ($scope, $timeout) { + + $scope.labels = ["January", "February", "March", "April", "May", "June", "July"]; + $scope.series = ['Series A', 'Series B']; + $scope.data = [ + [65, 59, 80, 81, 56, 55, 40], + [28, 48, 40, 19, 86, 27, 90] + ]; + $scope.onClick = function (points, evt) { + console.log(points, evt); + }; + + // Simulate async data update + $timeout(function () { + $scope.data = [ + [28, 48, 40, 19, 86, 27, 90], + [65, 59, 80, 81, 56, 55, 40] + ]; + }, 3000); +}]); +``` + +## Reactive + +angular-chart.js watch updates on data, series, labels, colours and options and will update, or destroy and recreate, +the chart on changes. + +## Events + +angular-chart.js emits the following events on the `scope` and pass the chart as argument: + +* `create`: when chart is created +* `update`: when chart is updated + +``` +$scope.$on('create', function (event, chart) { + console.log(chart); +}); +``` + +**Note**: the event can be emitted multiple times for each chart as the chart can be destroyed and +created multiple times during angular `watch` lifecycle. + +angular-chart.js listen to the scope `destroy` event and destroy the chart when it happens. + +## Colours + +There are a set of 7 default colours. Colours can be replaced using the `colours` attribute. +If there is more data than colours, colours are generated randomly or can be provided +via a function through the `getColour` attribute. + +Hex colours are converted to Chart.js colours automatically, +including different shades for highlight, fill, stroke, etc. + +# Issues + +**Issues or feature requests for Chart.js (e.g. new chart type, new axis, etc.) need to be opened on +[Chart.js issues tracker](https://github.com/nnnick/Chart.js/issues)** + +Please check if issue exists and otherwise open issue in [github](https://github.com/jtblin/angular-chart.js/issues). +**Please add a link to a plunker, jsbin, or equivalent.** +Here is a [jsbin template](http://jsbin.com/dufibi/3/edit?html,js,output) for convenience. + +# Contributing + +Pull requests welcome! + +1. Fork the repo +1. Make your changes +1. Run tests: `npm test` +1. Submit pull request + +## Contributors + +Thank you! + +* [@jantimon](https://twitter.com/jantimon) +* [RevanProdigalKnight](https://github.com/RevanProdigalKnight) +* [@ManuelRauber](https://twitter.com/ManuelRauber) +* [@vad710](https://twitter.com/vad710) +* [@JAAulde](https://twitter.com/JAAulde) +* [@offsky](https://twitter.com/offsky) +* [@jonathansampson](https://twitter.com/jonathansampson) +* [@idangozlan](https://twitter.com/idangozlan) + +# Author + +Jerome Touffe-Blin, [@jtblin](https://twitter.com/jtblin), [About me](http://about.me/jtblin) + +# License + +angular-chart.js is copyright 2015 Jerome Touffe-Blin and contributors. +It is licensed under the BSD license. See the include LICENSE file for details. diff --git a/templates/js/libs/angular-chart.js-0.7.2/angular-chart.js b/templates/js/libs/angular-chart.js-0.7.2/angular-chart.js new file mode 100644 index 0000000..158f3ed --- /dev/null +++ b/templates/js/libs/angular-chart.js-0.7.2/angular-chart.js @@ -0,0 +1,301 @@ +(function (factory) { + 'use strict'; + if (typeof define === 'function' && define.amd) { + // AMD. Register as an anonymous module. + define(['angular', 'chart.js'], factory); + } else if (typeof exports === 'object') { + // Node/CommonJS + module.exports = factory(require('angular'), require('chart.js')); + } else { + // Browser globals + factory(angular, Chart); + } +}(function (angular, Chart) { + 'use strict'; + + Chart.defaults.global.responsive = true; + Chart.defaults.global.multiTooltipTemplate = '<%if (datasetLabel){%><%=datasetLabel%>: <%}%><%= value %>'; + + Chart.defaults.global.colours = [ + '#97BBCD', // blue + '#DCDCDC', // light grey + '#F7464A', // red + '#46BFBD', // green + '#FDB45C', // yellow + '#949FB1', // grey + '#4D5360' // dark grey + ]; + + angular.module('chart.js', []) + .provider('ChartJs', ChartJsProvider) + .factory('ChartJsFactory', ['ChartJs', ChartJsFactory]) + .directive('chartBase', function (ChartJsFactory) { return new ChartJsFactory(); }) + .directive('chartLine', function (ChartJsFactory) { return new ChartJsFactory('Line'); }) + .directive('chartBar', function (ChartJsFactory) { return new ChartJsFactory('Bar'); }) + .directive('chartRadar', function (ChartJsFactory) { return new ChartJsFactory('Radar'); }) + .directive('chartDoughnut', function (ChartJsFactory) { return new ChartJsFactory('Doughnut'); }) + .directive('chartPie', function (ChartJsFactory) { return new ChartJsFactory('Pie'); }) + .directive('chartPolarArea', function (ChartJsFactory) { return new ChartJsFactory('PolarArea'); }); + + /** + * Wrapper for chart.js + * Allows configuring chart js using the provider + * + * angular.module('myModule', ['chart.js']).config(function(ChartJsProvider) { + * ChartJsProvider.setOptions({ responsive: true }); + * ChartJsProvider.setOptions('Line', { responsive: false }); + * }))) + */ + function ChartJsProvider () { + var options = {}; + var ChartJs = { + Chart: Chart, + getOptions: function (type) { + var typeOptions = type && options[type] || {}; + return angular.extend({}, options, typeOptions); + } + }; + + /** + * Allow to set global options during configuration + */ + this.setOptions = function (type, customOptions) { + // If no type was specified set option for the global object + if (! customOptions) { + customOptions = type; + options = angular.extend(options, customOptions); + return; + } + // Set options for the specific chart + options[type] = angular.extend(options[type] || {}, customOptions); + }; + + this.$get = function () { + return ChartJs; + }; + } + + function ChartJsFactory (ChartJs) { + return function chart (type) { + return { + restrict: 'CA', + scope: { + data: '=', + labels: '=', + options: '=', + series: '=', + colours: '=?', + getColour: '=?', + chartType: '=', + legend: '@', + click: '=', + hover: '=' + }, + link: function (scope, elem/*, attrs */) { + var chart, container = document.createElement('div'); + container.className = 'chart-container'; + elem.replaceWith(container); + container.appendChild(elem[0]); + + if (typeof window.G_vmlCanvasManager === 'object' && window.G_vmlCanvasManager !== null) { + if (typeof window.G_vmlCanvasManager.initElement === 'function') { + window.G_vmlCanvasManager.initElement(elem[0]); + } + } + + // Order of setting "watch" matter + + scope.$watch('data', function (newVal, oldVal) { + if (! newVal || ! newVal.length || (Array.isArray(newVal[0]) && ! newVal[0].length)) return; + var chartType = type || scope.chartType; + if (! chartType) return; + + if (chart) { + if (canUpdateChart(newVal, oldVal)) return updateChart(chart, newVal, scope); + chart.destroy(); + } + + chart = createChart(chartType, scope, elem); + }, true); + + scope.$watch('series', resetChart, true); + scope.$watch('labels', resetChart, true); + scope.$watch('options', resetChart, true); + scope.$watch('colours', resetChart, true); + + scope.$watch('chartType', function (newVal, oldVal) { + if (isEmpty(newVal)) return; + if (angular.equals(newVal, oldVal)) return; + if (chart) chart.destroy(); + chart = createChart(newVal, scope, elem); + }); + + scope.$on('$destroy', function () { + if (chart) chart.destroy(); + }); + + function resetChart (newVal, oldVal) { + if (isEmpty(newVal)) return; + if (angular.equals(newVal, oldVal)) return; + var chartType = type || scope.chartType; + if (! chartType) return; + + // chart.update() doesn't work for series and labels + // so we have to re-create the chart entirely + if (chart) chart.destroy(); + + chart = createChart(chartType, scope, elem); + } + } + }; + }; + + function canUpdateChart (newVal, oldVal) { + if (newVal && oldVal && newVal.length && oldVal.length) { + return Array.isArray(newVal[0]) ? + newVal.length === oldVal.length && newVal[0].length === oldVal[0].length : + oldVal.reduce(sum, 0) > 0 ? newVal.length === oldVal.length : false; + } + return false; + } + + function sum (carry, val) { + return carry + val; + } + + function createChart (type, scope, elem) { + if (! scope.data || ! scope.data.length) return; + scope.getColour = typeof scope.getColour === 'function' ? scope.getColour : getRandomColour; + scope.colours = getColours(type, scope); + var cvs = elem[0], ctx = cvs.getContext('2d'); + var data = Array.isArray(scope.data[0]) ? + getDataSets(scope.labels, scope.data, scope.series || [], scope.colours) : + getData(scope.labels, scope.data, scope.colours); + var options = angular.extend({}, ChartJs.getOptions(type), scope.options); + var chart = new ChartJs.Chart(ctx)[type](data, options); + scope.$emit('create', chart); + + ['hover', 'click'].forEach(function (action) { + if (scope[action]) cvs[action === 'click' ? 'onclick' : 'onmousemove'] = getEventHandler(scope, chart, action); + }); + if (scope.legend && scope.legend !== 'false') setLegend(elem, chart); + return chart; + } + + function getEventHandler (scope, chart, action) { + return function (evt) { + var atEvent = chart.getPointsAtEvent || chart.getBarsAtEvent || chart.getSegmentsAtEvent; + if (atEvent) { + var activePoints = atEvent.call(chart, evt); + scope[action](activePoints, evt); + scope.$apply(); + } + }; + } + + function getColours (type, scope) { + var colours = angular.copy(scope.colours || + ChartJs.getOptions(type).colours || + Chart.defaults.global.colours + ); + while (colours.length < scope.data.length) { + colours.push(scope.getColour()); + } + return colours.map(convertColour); + } + + function convertColour (colour) { + if (typeof colour === 'object' && colour !== null) return colour; + if (typeof colour === 'string' && colour[0] === '#') return getColour(hexToRgb(colour.substr(1))); + return getRandomColour(); + } + + function getRandomColour () { + var colour = [getRandomInt(0, 255), getRandomInt(0, 255), getRandomInt(0, 255)]; + return getColour(colour); + } + + function getColour (colour) { + return { + fillColor: rgba(colour, 0.2), + strokeColor: rgba(colour, 1), + pointColor: rgba(colour, 1), + pointStrokeColor: '#fff', + pointHighlightFill: '#fff', + pointHighlightStroke: rgba(colour, 0.8) + }; + } + + function getRandomInt (min, max) { + return Math.floor(Math.random() * (max - min + 1)) + min; + } + + function rgba (colour, alpha) { + return 'rgba(' + colour.concat(alpha).join(',') + ')'; + } + + // Credit: http://stackoverflow.com/a/11508164/1190235 + function hexToRgb (hex) { + var bigint = parseInt(hex, 16), + r = (bigint >> 16) & 255, + g = (bigint >> 8) & 255, + b = bigint & 255; + + return [r, g, b]; + } + + function getDataSets (labels, data, series, colours) { + return { + labels: labels, + datasets: data.map(function (item, i) { + return angular.extend({}, colours[i], { + label: series[i], + data: item + }); + }) + }; + } + + function getData (labels, data, colours) { + return labels.map(function (label, i) { + return angular.extend({}, colours[i], { + label: label, + value: data[i], + color: colours[i].strokeColor, + highlight: colours[i].pointHighlightStroke + }); + }); + } + + function setLegend (elem, chart) { + var $parent = elem.parent(), + $oldLegend = $parent.find('chart-legend'), + legend = '' + chart.generateLegend() + ''; + if ($oldLegend.length) $oldLegend.replaceWith(legend); + else $parent.append(legend); + } + + function updateChart (chart, values, scope) { + if (Array.isArray(scope.data[0])) { + chart.datasets.forEach(function (dataset, i) { + (dataset.points || dataset.bars).forEach(function (dataItem, j) { + dataItem.value = values[i][j]; + }); + }); + } else { + chart.segments.forEach(function (segment, i) { + segment.value = values[i]; + }); + } + chart.update(); + scope.$emit('update', chart); + } + + function isEmpty (value) { + return ! value || + (Array.isArray(value) && ! value.length) || + (typeof value === 'object' && ! Object.keys(value).length); + } + + } +})); diff --git a/templates/js/libs/angular-chart.js-0.7.2/angular-chart.less b/templates/js/libs/angular-chart.js-0.7.2/angular-chart.less new file mode 100644 index 0000000..ba6b18d --- /dev/null +++ b/templates/js/libs/angular-chart.js-0.7.2/angular-chart.less @@ -0,0 +1,30 @@ +.chart-legend, .bar-legend, .line-legend, .pie-legend, .radar-legend, .polararea-legend, .doughnut-legend { + list-style-type: none; + margin-top: 5px; + text-align: center; + /* NOTE: Browsers automatically add 40px of padding-left to all lists, so we should offset that, otherwise the legend is off-center */ + -webkit-padding-start:0; /* Webkit */ + -moz-padding-start:0; /* Mozilla */ + padding-left:0; /* IE (handles all cases, really, but we should also include the vendor-specific properties just to be safe) */ + + li { + display: inline-block; + white-space: nowrap; + position: relative; + margin-bottom: 4px; + border-radius: 5px; + padding: 2px 8px 2px 28px; + font-size: smaller; + cursor: default; + + span { + display: block; + position: absolute; + left: 0; + top: 0; + width: 20px; + height: 20px; + border-radius: 5px; + } + } +} diff --git a/templates/js/libs/angular-chart.js-0.7.2/bower.json b/templates/js/libs/angular-chart.js-0.7.2/bower.json new file mode 100644 index 0000000..df8c612 --- /dev/null +++ b/templates/js/libs/angular-chart.js-0.7.2/bower.json @@ -0,0 +1,56 @@ +{ + "name": "angular-chart.js", + "version": "0.7.2", + "main": [ + "./dist/angular-chart.js", + "./dist/angular-chart.css" + ], + "authors": [ + "Jerome Touffe-Blin " + ], + "repository": { + "type": "git", + "url": "git://github.com/jtblin/angular-chart.js.git" + }, + "description": "An angular.js wrapper for Chart.js - reactive, responsive, beautiful charts.", + "moduleType": [ + "globals" + ], + "keywords": [ + "angular", + "angular.js", + "chartjs", + "chart", + "reactive", + "responsive", + "graph", + "bar", + "line", + "area", + "donut" + ], + "license": "BSD", + "ignore": [ + "**/.*", + "node_modules", + "bower_components", + "test", + "tests" + ], + "dependencies": { + "angular": "1.x", + "Chart.js": "~1.0.1" + }, + "devDependencies": { + "angular-bootstrap": "~0.11.0", + "font-awesome": "~4.1.0", + "rainbow": "~1.1.9", + "Chart.StackedBar.js": "~1.0.1", + "angular-mocks": "~1.3.10" + }, + "resolutions": { + "Chart.js": "~1.0.1", + "angular": "1.x", + "angular-mocks": "1.3.10" + } +} diff --git a/templates/js/libs/angular-chart.js-0.7.2/dist/angular-chart.css b/templates/js/libs/angular-chart.js-0.7.2/dist/angular-chart.css new file mode 100644 index 0000000..ac9de0f --- /dev/null +++ b/templates/js/libs/angular-chart.js-0.7.2/dist/angular-chart.css @@ -0,0 +1,2 @@ +.chart-legend,.bar-legend,.line-legend,.pie-legend,.radar-legend,.polararea-legend,.doughnut-legend{list-style-type:none;margin-top:5px;text-align:center;-webkit-padding-start:0;-moz-padding-start:0;padding-left:0}.chart-legend li,.bar-legend li,.line-legend li,.pie-legend li,.radar-legend li,.polararea-legend li,.doughnut-legend li{display:inline-block;white-space:nowrap;position:relative;margin-bottom:4px;border-radius:5px;padding:2px 8px 2px 28px;font-size:smaller;cursor:default}.chart-legend li span,.bar-legend li span,.line-legend li span,.pie-legend li span,.radar-legend li span,.polararea-legend li span,.doughnut-legend li span{display:block;position:absolute;left:0;top:0;width:20px;height:20px;border-radius:5px} +/*# sourceMappingURL=angular-chart.css.map */ \ No newline at end of file diff --git a/templates/js/libs/angular-chart.js-0.7.2/dist/angular-chart.css.map b/templates/js/libs/angular-chart.js-0.7.2/dist/angular-chart.css.map new file mode 100755 index 0000000..2293371 --- /dev/null +++ b/templates/js/libs/angular-chart.js-0.7.2/dist/angular-chart.css.map @@ -0,0 +1 @@ +{"version":3,"sources":["angular-chart.less"],"names":[],"mappings":"AAAA;AAAe;AAAa;AAAc;AAAa;AAAe;AAAmB;EACvF,qBAAA;EACA,eAAA;EACA,kBAAA;;EAEA,wBAAA;;EACA,qBAAA;;EACA,eAAA;;;AAPF,aASE;AATa,WASb;AAT0B,YAS1B;AATwC,WASxC;AATqD,aASrD;AAToE,iBASpE;AATuF,gBASvF;EACE,qBAAA;EACA,mBAAA;EACA,kBAAA;EACA,kBAAA;EACA,kBAAA;EACA,yBAAA;EACA,kBAAA;EACA,eAAA;;AAjBJ,aASE,GAUE;AAnBW,WASb,GAUE;AAnBwB,YAS1B,GAUE;AAnBsC,WASxC,GAUE;AAnBmD,aASrD,GAUE;AAnBkE,iBASpE,GAUE;AAnBqF,gBASvF,GAUE;EACE,cAAA;EACA,kBAAA;EACA,OAAA;EACA,MAAA;EACA,WAAA;EACA,YAAA;EACA,kBAAA","file":"angular-chart.css","sourcesContent":[".chart-legend, .bar-legend, .line-legend, .pie-legend, .radar-legend, .polararea-legend, .doughnut-legend {\n list-style-type: none;\n margin-top: 5px;\n text-align: center;\n /* NOTE: Browsers automatically add 40px of padding-left to all lists, so we should offset that, otherwise the legend is off-center */\n -webkit-padding-start:0; /* Webkit */\n -moz-padding-start:0; /* Mozilla */\n padding-left:0; /* IE (handles all cases, really, but we should also include the vendor-specific properties just to be safe) */\n\n li {\n display: inline-block;\n white-space: nowrap;\n position: relative;\n margin-bottom: 4px;\n border-radius: 5px;\n padding: 2px 8px 2px 28px;\n font-size: smaller;\n cursor: default;\n\n span {\n display: block;\n position: absolute;\n left: 0;\n top: 0;\n width: 20px;\n height: 20px;\n border-radius: 5px;\n }\n }\n}\n"],"sourceRoot":"/source/"} \ No newline at end of file diff --git a/templates/js/libs/angular-chart.js-0.7.2/dist/angular-chart.js b/templates/js/libs/angular-chart.js-0.7.2/dist/angular-chart.js new file mode 100644 index 0000000..228ff26 --- /dev/null +++ b/templates/js/libs/angular-chart.js-0.7.2/dist/angular-chart.js @@ -0,0 +1,301 @@ +(function (factory) { + 'use strict'; + if (typeof define === 'function' && define.amd) { + // AMD. Register as an anonymous module. + define(['angular', 'chart.js'], factory); + } else if (typeof exports === 'object') { + // Node/CommonJS + module.exports = factory(require('angular'), require('chart.js')); + } else { + // Browser globals + factory(angular, Chart); + } +}(function (angular, Chart) { + 'use strict'; + + Chart.defaults.global.responsive = true; + Chart.defaults.global.multiTooltipTemplate = '<%if (datasetLabel){%><%=datasetLabel%>: <%}%><%= value %>'; + + Chart.defaults.global.colours = [ + '#97BBCD', // blue + '#DCDCDC', // light grey + '#F7464A', // red + '#46BFBD', // green + '#FDB45C', // yellow + '#949FB1', // grey + '#4D5360' // dark grey + ]; + + angular.module('chart.js', []) + .provider('ChartJs', ChartJsProvider) + .factory('ChartJsFactory', ['ChartJs', ChartJsFactory]) + .directive('chartBase', ['ChartJsFactory', function (ChartJsFactory) { return new ChartJsFactory(); }]) + .directive('chartLine', ['ChartJsFactory', function (ChartJsFactory) { return new ChartJsFactory('Line'); }]) + .directive('chartBar', ['ChartJsFactory', function (ChartJsFactory) { return new ChartJsFactory('Bar'); }]) + .directive('chartRadar', ['ChartJsFactory', function (ChartJsFactory) { return new ChartJsFactory('Radar'); }]) + .directive('chartDoughnut', ['ChartJsFactory', function (ChartJsFactory) { return new ChartJsFactory('Doughnut'); }]) + .directive('chartPie', ['ChartJsFactory', function (ChartJsFactory) { return new ChartJsFactory('Pie'); }]) + .directive('chartPolarArea', ['ChartJsFactory', function (ChartJsFactory) { return new ChartJsFactory('PolarArea'); }]); + + /** + * Wrapper for chart.js + * Allows configuring chart js using the provider + * + * angular.module('myModule', ['chart.js']).config(function(ChartJsProvider) { + * ChartJsProvider.setOptions({ responsive: true }); + * ChartJsProvider.setOptions('Line', { responsive: false }); + * }))) + */ + function ChartJsProvider () { + var options = {}; + var ChartJs = { + Chart: Chart, + getOptions: function (type) { + var typeOptions = type && options[type] || {}; + return angular.extend({}, options, typeOptions); + } + }; + + /** + * Allow to set global options during configuration + */ + this.setOptions = function (type, customOptions) { + // If no type was specified set option for the global object + if (! customOptions) { + customOptions = type; + options = angular.extend(options, customOptions); + return; + } + // Set options for the specific chart + options[type] = angular.extend(options[type] || {}, customOptions); + }; + + this.$get = function () { + return ChartJs; + }; + } + + function ChartJsFactory (ChartJs) { + return function chart (type) { + return { + restrict: 'CA', + scope: { + data: '=', + labels: '=', + options: '=', + series: '=', + colours: '=?', + getColour: '=?', + chartType: '=', + legend: '@', + click: '=', + hover: '=' + }, + link: function (scope, elem/*, attrs */) { + var chart, container = document.createElement('div'); + container.className = 'chart-container'; + elem.replaceWith(container); + container.appendChild(elem[0]); + + if (typeof window.G_vmlCanvasManager === 'object' && window.G_vmlCanvasManager !== null) { + if (typeof window.G_vmlCanvasManager.initElement === 'function') { + window.G_vmlCanvasManager.initElement(elem[0]); + } + } + + // Order of setting "watch" matter + + scope.$watch('data', function (newVal, oldVal) { + if (! newVal || ! newVal.length || (Array.isArray(newVal[0]) && ! newVal[0].length)) return; + var chartType = type || scope.chartType; + if (! chartType) return; + + if (chart) { + if (canUpdateChart(newVal, oldVal)) return updateChart(chart, newVal, scope); + chart.destroy(); + } + + chart = createChart(chartType, scope, elem); + }, true); + + scope.$watch('series', resetChart, true); + scope.$watch('labels', resetChart, true); + scope.$watch('options', resetChart, true); + scope.$watch('colours', resetChart, true); + + scope.$watch('chartType', function (newVal, oldVal) { + if (isEmpty(newVal)) return; + if (angular.equals(newVal, oldVal)) return; + if (chart) chart.destroy(); + chart = createChart(newVal, scope, elem); + }); + + scope.$on('$destroy', function () { + if (chart) chart.destroy(); + }); + + function resetChart (newVal, oldVal) { + if (isEmpty(newVal)) return; + if (angular.equals(newVal, oldVal)) return; + var chartType = type || scope.chartType; + if (! chartType) return; + + // chart.update() doesn't work for series and labels + // so we have to re-create the chart entirely + if (chart) chart.destroy(); + + chart = createChart(chartType, scope, elem); + } + } + }; + }; + + function canUpdateChart (newVal, oldVal) { + if (newVal && oldVal && newVal.length && oldVal.length) { + return Array.isArray(newVal[0]) ? + newVal.length === oldVal.length && newVal[0].length === oldVal[0].length : + oldVal.reduce(sum, 0) > 0 ? newVal.length === oldVal.length : false; + } + return false; + } + + function sum (carry, val) { + return carry + val; + } + + function createChart (type, scope, elem) { + if (! scope.data || ! scope.data.length) return; + scope.getColour = typeof scope.getColour === 'function' ? scope.getColour : getRandomColour; + scope.colours = getColours(type, scope); + var cvs = elem[0], ctx = cvs.getContext('2d'); + var data = Array.isArray(scope.data[0]) ? + getDataSets(scope.labels, scope.data, scope.series || [], scope.colours) : + getData(scope.labels, scope.data, scope.colours); + var options = angular.extend({}, ChartJs.getOptions(type), scope.options); + var chart = new ChartJs.Chart(ctx)[type](data, options); + scope.$emit('create', chart); + + ['hover', 'click'].forEach(function (action) { + if (scope[action]) cvs[action === 'click' ? 'onclick' : 'onmousemove'] = getEventHandler(scope, chart, action); + }); + if (scope.legend && scope.legend !== 'false') setLegend(elem, chart); + return chart; + } + + function getEventHandler (scope, chart, action) { + return function (evt) { + var atEvent = chart.getPointsAtEvent || chart.getBarsAtEvent || chart.getSegmentsAtEvent; + if (atEvent) { + var activePoints = atEvent.call(chart, evt); + scope[action](activePoints, evt); + scope.$apply(); + } + }; + } + + function getColours (type, scope) { + var colours = angular.copy(scope.colours || + ChartJs.getOptions(type).colours || + Chart.defaults.global.colours + ); + while (colours.length < scope.data.length) { + colours.push(scope.getColour()); + } + return colours.map(convertColour); + } + + function convertColour (colour) { + if (typeof colour === 'object' && colour !== null) return colour; + if (typeof colour === 'string' && colour[0] === '#') return getColour(hexToRgb(colour.substr(1))); + return getRandomColour(); + } + + function getRandomColour () { + var colour = [getRandomInt(0, 255), getRandomInt(0, 255), getRandomInt(0, 255)]; + return getColour(colour); + } + + function getColour (colour) { + return { + fillColor: rgba(colour, 0.2), + strokeColor: rgba(colour, 1), + pointColor: rgba(colour, 1), + pointStrokeColor: '#fff', + pointHighlightFill: '#fff', + pointHighlightStroke: rgba(colour, 0.8) + }; + } + + function getRandomInt (min, max) { + return Math.floor(Math.random() * (max - min + 1)) + min; + } + + function rgba (colour, alpha) { + return 'rgba(' + colour.concat(alpha).join(',') + ')'; + } + + // Credit: http://stackoverflow.com/a/11508164/1190235 + function hexToRgb (hex) { + var bigint = parseInt(hex, 16), + r = (bigint >> 16) & 255, + g = (bigint >> 8) & 255, + b = bigint & 255; + + return [r, g, b]; + } + + function getDataSets (labels, data, series, colours) { + return { + labels: labels, + datasets: data.map(function (item, i) { + return angular.extend({}, colours[i], { + label: series[i], + data: item + }); + }) + }; + } + + function getData (labels, data, colours) { + return labels.map(function (label, i) { + return angular.extend({}, colours[i], { + label: label, + value: data[i], + color: colours[i].strokeColor, + highlight: colours[i].pointHighlightStroke + }); + }); + } + + function setLegend (elem, chart) { + var $parent = elem.parent(), + $oldLegend = $parent.find('chart-legend'), + legend = '' + chart.generateLegend() + ''; + if ($oldLegend.length) $oldLegend.replaceWith(legend); + else $parent.append(legend); + } + + function updateChart (chart, values, scope) { + if (Array.isArray(scope.data[0])) { + chart.datasets.forEach(function (dataset, i) { + (dataset.points || dataset.bars).forEach(function (dataItem, j) { + dataItem.value = values[i][j]; + }); + }); + } else { + chart.segments.forEach(function (segment, i) { + segment.value = values[i]; + }); + } + chart.update(); + scope.$emit('update', chart); + } + + function isEmpty (value) { + return ! value || + (Array.isArray(value) && ! value.length) || + (typeof value === 'object' && ! Object.keys(value).length); + } + + } +})); diff --git a/templates/js/libs/angular-chart.js-0.7.2/dist/angular-chart.js.tar.gz b/templates/js/libs/angular-chart.js-0.7.2/dist/angular-chart.js.tar.gz new file mode 100755 index 0000000000000000000000000000000000000000..79a73737ca0b06f3efcdfd11a0218442e1c1ed2f GIT binary patch literal 9230 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 k^!>=Jn)CcLZ;pTY`T60?t.length===e.length:!1:!1}function a(t,e){return t+e}function o(e,r,a){if(r.data&&r.data.length){r.getColour="function"==typeof r.getColour?r.getColour:l,r.colours=c(e,r);var o=a[0],u=o.getContext("2d"),s=Array.isArray(r.data[0])?g(r.labels,r.data,r.series||[],r.colours):p(r.labels,r.data,r.colours),f=t.extend({},n.getOptions(e),r.options),h=new n.Chart(u)[e](s,f);return r.$emit("create",h),["hover","click"].forEach(function(t){r[t]&&(o["click"===t?"onclick":"onmousemove"]=i(r,h,t))}),r.legend&&"false"!==r.legend&&v(a,h),h}}function i(t,e,n){return function(r){var a=e.getPointsAtEvent||e.getBarsAtEvent||e.getSegmentsAtEvent;if(a){var o=a.call(e,r);t[n](o,r),t.$apply()}}}function c(r,a){for(var o=t.copy(a.colours||n.getOptions(r).colours||e.defaults.global.colours);o.length>16&255,r=e>>8&255,a=255&e;return[n,r,a]}function g(e,n,r,a){return{labels:e,datasets:n.map(function(e,n){return t.extend({},a[n],{label:r[n],data:e})})}}function p(e,n,r){return e.map(function(e,a){return t.extend({},r[a],{label:e,value:n[a],color:r[a].strokeColor,highlight:r[a].pointHighlightStroke})})}function v(t,e){var n=t.parent(),r=n.find("chart-legend"),a=""+e.generateLegend()+"";r.length?r.replaceWith(a):n.append(a)}function y(t,e,n){Array.isArray(n.data[0])?t.datasets.forEach(function(t,n){(t.points||t.bars).forEach(function(t,r){t.value=e[n][r]})}):t.segments.forEach(function(t,n){t.value=e[n]}),t.update(),n.$emit("update",t)}function C(t){return!t||Array.isArray(t)&&!t.length||"object"==typeof t&&!Object.keys(t).length}return function(e){return{restrict:"CA",scope:{data:"=",labels:"=",options:"=",series:"=",colours:"=?",getColour:"=?",chartType:"=",legend:"@",click:"=",hover:"="},link:function(n,a){function i(r,i){if(!C(r)&&!t.equals(r,i)){var u=e||n.chartType;u&&(c&&c.destroy(),c=o(u,n,a))}}var c,u=document.createElement("div");u.className="chart-container",a.replaceWith(u),u.appendChild(a[0]),"object"==typeof window.G_vmlCanvasManager&&null!==window.G_vmlCanvasManager&&"function"==typeof window.G_vmlCanvasManager.initElement&&window.G_vmlCanvasManager.initElement(a[0]),n.$watch("data",function(t,i){if(t&&t.length&&(!Array.isArray(t[0])||t[0].length)){var u=e||n.chartType;if(u){if(c){if(r(t,i))return y(c,t,n);c.destroy()}c=o(u,n,a)}}},!0),n.$watch("series",i,!0),n.$watch("labels",i,!0),n.$watch("options",i,!0),n.$watch("colours",i,!0),n.$watch("chartType",function(e,r){C(e)||t.equals(e,r)||(c&&c.destroy(),c=o(e,n,a))}),n.$on("$destroy",function(){c&&c.destroy()})}}}}e.defaults.global.responsive=!0,e.defaults.global.multiTooltipTemplate="<%if (datasetLabel){%><%=datasetLabel%>: <%}%><%= value %>",e.defaults.global.colours=["#97BBCD","#DCDCDC","#F7464A","#46BFBD","#FDB45C","#949FB1","#4D5360"],t.module("chart.js",[]).provider("ChartJs",n).factory("ChartJsFactory",["ChartJs",r]).directive("chartBase",["ChartJsFactory",function(t){return new t}]).directive("chartLine",["ChartJsFactory",function(t){return new t("Line")}]).directive("chartBar",["ChartJsFactory",function(t){return new t("Bar")}]).directive("chartRadar",["ChartJsFactory",function(t){return new t("Radar")}]).directive("chartDoughnut",["ChartJsFactory",function(t){return new t("Doughnut")}]).directive("chartPie",["ChartJsFactory",function(t){return new t("Pie")}]).directive("chartPolarArea",["ChartJsFactory",function(t){return new t("PolarArea")}])}); +//# sourceMappingURL=angular-chart.min.js.map \ No newline at end of file diff --git a/templates/js/libs/angular-chart.js-0.7.2/dist/angular-chart.min.js.map b/templates/js/libs/angular-chart.js-0.7.2/dist/angular-chart.min.js.map new file mode 100644 index 0000000..980b3c0 --- /dev/null +++ b/templates/js/libs/angular-chart.js-0.7.2/dist/angular-chart.min.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["angular-chart.min.js"],"names":["factory","define","amd","exports","module","require","angular","Chart","ChartJsProvider","options","ChartJs","getOptions","type","typeOptions","extend","this","setOptions","customOptions","$get","ChartJsFactory","canUpdateChart","newVal","oldVal","length","Array","isArray","reduce","sum","carry","val","createChart","scope","elem","data","getColour","getRandomColour","colours","getColours","cvs","ctx","getContext","getDataSets","labels","series","getData","chart","$emit","forEach","action","getEventHandler","legend","setLegend","evt","atEvent","getPointsAtEvent","getBarsAtEvent","getSegmentsAtEvent","activePoints","call","$apply","copy","defaults","global","push","map","convertColour","colour","hexToRgb","substr","getRandomInt","fillColor","rgba","strokeColor","pointColor","pointStrokeColor","pointHighlightFill","pointHighlightStroke","min","max","Math","floor","random","alpha","concat","join","hex","bigint","parseInt","r","g","b","datasets","item","i","label","value","color","highlight","$parent","parent","$oldLegend","find","generateLegend","replaceWith","append","updateChart","values","dataset","points","bars","dataItem","j","segments","segment","update","isEmpty","Object","keys","restrict","chartType","click","hover","link","resetChart","equals","destroy","container","document","createElement","className","appendChild","window","G_vmlCanvasManager","initElement","$watch","$on","responsive","multiTooltipTemplate","provider","directive"],"mappings":"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","file":"angular-chart.min.js","sourcesContent":["(function (factory) {\n 'use strict';\n if (typeof define === 'function' && define.amd) {\n // AMD. Register as an anonymous module.\n define(['angular', 'chart.js'], factory);\n } else if (typeof exports === 'object') {\n // Node/CommonJS\n module.exports = factory(require('angular'), require('chart.js'));\n } else {\n // Browser globals\n factory(angular, Chart);\n }\n}(function (angular, Chart) {\n 'use strict';\n\n Chart.defaults.global.responsive = true;\n Chart.defaults.global.multiTooltipTemplate = '<%if (datasetLabel){%><%=datasetLabel%>: <%}%><%= value %>';\n\n Chart.defaults.global.colours = [\n '#97BBCD', // blue\n '#DCDCDC', // light grey\n '#F7464A', // red\n '#46BFBD', // green\n '#FDB45C', // yellow\n '#949FB1', // grey\n '#4D5360' // dark grey\n ];\n\n angular.module('chart.js', [])\n .provider('ChartJs', ChartJsProvider)\n .factory('ChartJsFactory', ['ChartJs', ChartJsFactory])\n .directive('chartBase', ['ChartJsFactory', function (ChartJsFactory) { return new ChartJsFactory(); }])\n .directive('chartLine', ['ChartJsFactory', function (ChartJsFactory) { return new ChartJsFactory('Line'); }])\n .directive('chartBar', ['ChartJsFactory', function (ChartJsFactory) { return new ChartJsFactory('Bar'); }])\n .directive('chartRadar', ['ChartJsFactory', function (ChartJsFactory) { return new ChartJsFactory('Radar'); }])\n .directive('chartDoughnut', ['ChartJsFactory', function (ChartJsFactory) { return new ChartJsFactory('Doughnut'); }])\n .directive('chartPie', ['ChartJsFactory', function (ChartJsFactory) { return new ChartJsFactory('Pie'); }])\n .directive('chartPolarArea', ['ChartJsFactory', function (ChartJsFactory) { return new ChartJsFactory('PolarArea'); }]);\n\n /**\n * Wrapper for chart.js\n * Allows configuring chart js using the provider\n *\n * angular.module('myModule', ['chart.js']).config(function(ChartJsProvider) {\n * ChartJsProvider.setOptions({ responsive: true });\n * ChartJsProvider.setOptions('Line', { responsive: false });\n * })))\n */\n function ChartJsProvider () {\n var options = {};\n var ChartJs = {\n Chart: Chart,\n getOptions: function (type) {\n var typeOptions = type && options[type] || {};\n return angular.extend({}, options, typeOptions);\n }\n };\n\n /**\n * Allow to set global options during configuration\n */\n this.setOptions = function (type, customOptions) {\n // If no type was specified set option for the global object\n if (! customOptions) {\n customOptions = type;\n options = angular.extend(options, customOptions);\n return;\n }\n // Set options for the specific chart\n options[type] = angular.extend(options[type] || {}, customOptions);\n };\n\n this.$get = function () {\n return ChartJs;\n };\n }\n\n function ChartJsFactory (ChartJs) {\n return function chart (type) {\n return {\n restrict: 'CA',\n scope: {\n data: '=',\n labels: '=',\n options: '=',\n series: '=',\n colours: '=?',\n getColour: '=?',\n chartType: '=',\n legend: '@',\n click: '=',\n hover: '='\n },\n link: function (scope, elem/*, attrs */) {\n var chart, container = document.createElement('div');\n container.className = 'chart-container';\n elem.replaceWith(container);\n container.appendChild(elem[0]);\n\n if (typeof window.G_vmlCanvasManager === 'object' && window.G_vmlCanvasManager !== null) {\n if (typeof window.G_vmlCanvasManager.initElement === 'function') {\n window.G_vmlCanvasManager.initElement(elem[0]);\n }\n }\n\n // Order of setting \"watch\" matter\n\n scope.$watch('data', function (newVal, oldVal) {\n if (! newVal || ! newVal.length || (Array.isArray(newVal[0]) && ! newVal[0].length)) return;\n var chartType = type || scope.chartType;\n if (! chartType) return;\n\n if (chart) {\n if (canUpdateChart(newVal, oldVal)) return updateChart(chart, newVal, scope);\n chart.destroy();\n }\n\n chart = createChart(chartType, scope, elem);\n }, true);\n\n scope.$watch('series', resetChart, true);\n scope.$watch('labels', resetChart, true);\n scope.$watch('options', resetChart, true);\n scope.$watch('colours', resetChart, true);\n\n scope.$watch('chartType', function (newVal, oldVal) {\n if (isEmpty(newVal)) return;\n if (angular.equals(newVal, oldVal)) return;\n if (chart) chart.destroy();\n chart = createChart(newVal, scope, elem);\n });\n\n scope.$on('$destroy', function () {\n if (chart) chart.destroy();\n });\n\n function resetChart (newVal, oldVal) {\n if (isEmpty(newVal)) return;\n if (angular.equals(newVal, oldVal)) return;\n var chartType = type || scope.chartType;\n if (! chartType) return;\n\n // chart.update() doesn't work for series and labels\n // so we have to re-create the chart entirely\n if (chart) chart.destroy();\n\n chart = createChart(chartType, scope, elem);\n }\n }\n };\n };\n\n function canUpdateChart (newVal, oldVal) {\n if (newVal && oldVal && newVal.length && oldVal.length) {\n return Array.isArray(newVal[0]) ?\n newVal.length === oldVal.length && newVal[0].length === oldVal[0].length :\n oldVal.reduce(sum, 0) > 0 ? newVal.length === oldVal.length : false;\n }\n return false;\n }\n\n function sum (carry, val) {\n return carry + val;\n }\n\n function createChart (type, scope, elem) {\n if (! scope.data || ! scope.data.length) return;\n scope.getColour = typeof scope.getColour === 'function' ? scope.getColour : getRandomColour;\n scope.colours = getColours(type, scope);\n var cvs = elem[0], ctx = cvs.getContext('2d');\n var data = Array.isArray(scope.data[0]) ?\n getDataSets(scope.labels, scope.data, scope.series || [], scope.colours) :\n getData(scope.labels, scope.data, scope.colours);\n var options = angular.extend({}, ChartJs.getOptions(type), scope.options);\n var chart = new ChartJs.Chart(ctx)[type](data, options);\n scope.$emit('create', chart);\n\n ['hover', 'click'].forEach(function (action) {\n if (scope[action]) cvs[action === 'click' ? 'onclick' : 'onmousemove'] = getEventHandler(scope, chart, action);\n });\n if (scope.legend && scope.legend !== 'false') setLegend(elem, chart);\n return chart;\n }\n\n function getEventHandler (scope, chart, action) {\n return function (evt) {\n var atEvent = chart.getPointsAtEvent || chart.getBarsAtEvent || chart.getSegmentsAtEvent;\n if (atEvent) {\n var activePoints = atEvent.call(chart, evt);\n scope[action](activePoints, evt);\n scope.$apply();\n }\n };\n }\n\n function getColours (type, scope) {\n var colours = angular.copy(scope.colours ||\n ChartJs.getOptions(type).colours ||\n Chart.defaults.global.colours\n );\n while (colours.length < scope.data.length) {\n colours.push(scope.getColour());\n }\n return colours.map(convertColour);\n }\n\n function convertColour (colour) {\n if (typeof colour === 'object' && colour !== null) return colour;\n if (typeof colour === 'string' && colour[0] === '#') return getColour(hexToRgb(colour.substr(1)));\n return getRandomColour();\n }\n\n function getRandomColour () {\n var colour = [getRandomInt(0, 255), getRandomInt(0, 255), getRandomInt(0, 255)];\n return getColour(colour);\n }\n\n function getColour (colour) {\n return {\n fillColor: rgba(colour, 0.2),\n strokeColor: rgba(colour, 1),\n pointColor: rgba(colour, 1),\n pointStrokeColor: '#fff',\n pointHighlightFill: '#fff',\n pointHighlightStroke: rgba(colour, 0.8)\n };\n }\n\n function getRandomInt (min, max) {\n return Math.floor(Math.random() * (max - min + 1)) + min;\n }\n\n function rgba (colour, alpha) {\n return 'rgba(' + colour.concat(alpha).join(',') + ')';\n }\n\n // Credit: http://stackoverflow.com/a/11508164/1190235\n function hexToRgb (hex) {\n var bigint = parseInt(hex, 16),\n r = (bigint >> 16) & 255,\n g = (bigint >> 8) & 255,\n b = bigint & 255;\n\n return [r, g, b];\n }\n\n function getDataSets (labels, data, series, colours) {\n return {\n labels: labels,\n datasets: data.map(function (item, i) {\n return angular.extend({}, colours[i], {\n label: series[i],\n data: item\n });\n })\n };\n }\n\n function getData (labels, data, colours) {\n return labels.map(function (label, i) {\n return angular.extend({}, colours[i], {\n label: label,\n value: data[i],\n color: colours[i].strokeColor,\n highlight: colours[i].pointHighlightStroke\n });\n });\n }\n\n function setLegend (elem, chart) {\n var $parent = elem.parent(),\n $oldLegend = $parent.find('chart-legend'),\n legend = '' + chart.generateLegend() + '';\n if ($oldLegend.length) $oldLegend.replaceWith(legend);\n else $parent.append(legend);\n }\n\n function updateChart (chart, values, scope) {\n if (Array.isArray(scope.data[0])) {\n chart.datasets.forEach(function (dataset, i) {\n (dataset.points || dataset.bars).forEach(function (dataItem, j) {\n dataItem.value = values[i][j];\n });\n });\n } else {\n chart.segments.forEach(function (segment, i) {\n segment.value = values[i];\n });\n }\n chart.update();\n scope.$emit('update', chart);\n }\n\n function isEmpty (value) {\n return ! value ||\n (Array.isArray(value) && ! value.length) ||\n (typeof value === 'object' && ! Object.keys(value).length);\n }\n\n }\n}));\n"],"sourceRoot":"/source/"} \ No newline at end of file diff --git a/templates/js/libs/angular-chart.js-0.7.2/dist/chart.js b/templates/js/libs/angular-chart.js-0.7.2/dist/chart.js new file mode 100644 index 0000000..c264262 --- /dev/null +++ b/templates/js/libs/angular-chart.js-0.7.2/dist/chart.js @@ -0,0 +1,3477 @@ +/*! + * Chart.js + * http://chartjs.org/ + * Version: 1.0.2 + * + * Copyright 2015 Nick Downie + * Released under the MIT license + * https://github.com/nnnick/Chart.js/blob/master/LICENSE.md + */ + + +(function(){ + + "use strict"; + + //Declare root variable - window in the browser, global on the server + var root = this, + previous = root.Chart; + + //Occupy the global variable of Chart, and create a simple base class + var Chart = function(context){ + var chart = this; + this.canvas = context.canvas; + + this.ctx = context; + + //Variables global to the chart + var computeDimension = function(element,dimension) + { + if (element['offset'+dimension]) + { + return element['offset'+dimension]; + } + else + { + return document.defaultView.getComputedStyle(element).getPropertyValue(dimension); + } + } + + var width = this.width = computeDimension(context.canvas,'Width'); + var height = this.height = computeDimension(context.canvas,'Height'); + + // Firefox requires this to work correctly + context.canvas.width = width; + context.canvas.height = height; + + var width = this.width = context.canvas.width; + var height = this.height = context.canvas.height; + this.aspectRatio = this.width / this.height; + //High pixel density displays - multiply the size of the canvas height/width by the device pixel ratio, then scale. + helpers.retinaScale(this); + + return this; + }; + //Globally expose the defaults to allow for user updating/changing + Chart.defaults = { + global: { + // Boolean - Whether to animate the chart + animation: true, + + // Number - Number of animation steps + animationSteps: 60, + + // String - Animation easing effect + animationEasing: "easeOutQuart", + + // Boolean - If we should show the scale at all + showScale: true, + + // Boolean - If we want to override with a hard coded scale + scaleOverride: false, + + // ** Required if scaleOverride is true ** + // Number - The number of steps in a hard coded scale + scaleSteps: null, + // Number - The value jump in the hard coded scale + scaleStepWidth: null, + // Number - The scale starting value + scaleStartValue: null, + + // String - Colour of the scale line + scaleLineColor: "rgba(0,0,0,.1)", + + // Number - Pixel width of the scale line + scaleLineWidth: 1, + + // Boolean - Whether to show labels on the scale + scaleShowLabels: true, + + // Interpolated JS string - can access value + scaleLabel: "<%=value%>", + + // Boolean - Whether the scale should stick to integers, and not show any floats even if drawing space is there + scaleIntegersOnly: true, + + // Boolean - Whether the scale should start at zero, or an order of magnitude down from the lowest value + scaleBeginAtZero: false, + + // String - Scale label font declaration for the scale label + scaleFontFamily: "'Helvetica Neue', 'Helvetica', 'Arial', sans-serif", + + // Number - Scale label font size in pixels + scaleFontSize: 12, + + // String - Scale label font weight style + scaleFontStyle: "normal", + + // String - Scale label font colour + scaleFontColor: "#666", + + // Boolean - whether or not the chart should be responsive and resize when the browser does. + responsive: false, + + // Boolean - whether to maintain the starting aspect ratio or not when responsive, if set to false, will take up entire container + maintainAspectRatio: true, + + // Boolean - Determines whether to draw tooltips on the canvas or not - attaches events to touchmove & mousemove + showTooltips: true, + + // Boolean - Determines whether to draw built-in tooltip or call custom tooltip function + customTooltips: false, + + // Array - Array of string names to attach tooltip events + tooltipEvents: ["mousemove", "touchstart", "touchmove", "mouseout"], + + // String - Tooltip background colour + tooltipFillColor: "rgba(0,0,0,0.8)", + + // String - Tooltip label font declaration for the scale label + tooltipFontFamily: "'Helvetica Neue', 'Helvetica', 'Arial', sans-serif", + + // Number - Tooltip label font size in pixels + tooltipFontSize: 14, + + // String - Tooltip font weight style + tooltipFontStyle: "normal", + + // String - Tooltip label font colour + tooltipFontColor: "#fff", + + // String - Tooltip title font declaration for the scale label + tooltipTitleFontFamily: "'Helvetica Neue', 'Helvetica', 'Arial', sans-serif", + + // Number - Tooltip title font size in pixels + tooltipTitleFontSize: 14, + + // String - Tooltip title font weight style + tooltipTitleFontStyle: "bold", + + // String - Tooltip title font colour + tooltipTitleFontColor: "#fff", + + // Number - pixel width of padding around tooltip text + tooltipYPadding: 6, + + // Number - pixel width of padding around tooltip text + tooltipXPadding: 6, + + // Number - Size of the caret on the tooltip + tooltipCaretSize: 8, + + // Number - Pixel radius of the tooltip border + tooltipCornerRadius: 6, + + // Number - Pixel offset from point x to tooltip edge + tooltipXOffset: 10, + + // String - Template string for single tooltips + tooltipTemplate: "<%if (label){%><%=label%>: <%}%><%= value %>", + + // String - Template string for single tooltips + multiTooltipTemplate: "<%= value %>", + + // String - Colour behind the legend colour block + multiTooltipKeyBackground: '#fff', + + // Function - Will fire on animation progression. + onAnimationProgress: function(){}, + + // Function - Will fire on animation completion. + onAnimationComplete: function(){} + + } + }; + + //Create a dictionary of chart types, to allow for extension of existing types + Chart.types = {}; + + //Global Chart helpers object for utility methods and classes + var helpers = Chart.helpers = {}; + + //-- Basic js utility methods + var each = helpers.each = function(loopable,callback,self){ + var additionalArgs = Array.prototype.slice.call(arguments, 3); + // Check to see if null or undefined firstly. + if (loopable){ + if (loopable.length === +loopable.length){ + var i; + for (i=0; i= 0; i--) { + var currentItem = arrayToSearch[i]; + if (filterCallback(currentItem)){ + return currentItem; + } + } + }, + inherits = helpers.inherits = function(extensions){ + //Basic javascript inheritance based on the model created in Backbone.js + var parent = this; + var ChartElement = (extensions && extensions.hasOwnProperty("constructor")) ? extensions.constructor : function(){ return parent.apply(this, arguments); }; + + var Surrogate = function(){ this.constructor = ChartElement;}; + Surrogate.prototype = parent.prototype; + ChartElement.prototype = new Surrogate(); + + ChartElement.extend = inherits; + + if (extensions) extend(ChartElement.prototype, extensions); + + ChartElement.__super__ = parent.prototype; + + return ChartElement; + }, + noop = helpers.noop = function(){}, + uid = helpers.uid = (function(){ + var id=0; + return function(){ + return "chart-" + id++; + }; + })(), + warn = helpers.warn = function(str){ + //Method for warning of errors + if (window.console && typeof window.console.warn == "function") console.warn(str); + }, + amd = helpers.amd = (typeof define == 'function' && define.amd), + //-- Math methods + isNumber = helpers.isNumber = function(n){ + return !isNaN(parseFloat(n)) && isFinite(n); + }, + max = helpers.max = function(array){ + return Math.max.apply( Math, array ); + }, + min = helpers.min = function(array){ + return Math.min.apply( Math, array ); + }, + cap = helpers.cap = function(valueToCap,maxValue,minValue){ + if(isNumber(maxValue)) { + if( valueToCap > maxValue ) { + return maxValue; + } + } + else if(isNumber(minValue)){ + if ( valueToCap < minValue ){ + return minValue; + } + } + return valueToCap; + }, + getDecimalPlaces = helpers.getDecimalPlaces = function(num){ + if (num%1!==0 && isNumber(num)){ + return num.toString().split(".")[1].length; + } + else { + return 0; + } + }, + toRadians = helpers.radians = function(degrees){ + return degrees * (Math.PI/180); + }, + // Gets the angle from vertical upright to the point about a centre. + getAngleFromPoint = helpers.getAngleFromPoint = function(centrePoint, anglePoint){ + var distanceFromXCenter = anglePoint.x - centrePoint.x, + distanceFromYCenter = anglePoint.y - centrePoint.y, + radialDistanceFromCenter = Math.sqrt( distanceFromXCenter * distanceFromXCenter + distanceFromYCenter * distanceFromYCenter); + + + var angle = Math.PI * 2 + Math.atan2(distanceFromYCenter, distanceFromXCenter); + + //If the segment is in the top left quadrant, we need to add another rotation to the angle + if (distanceFromXCenter < 0 && distanceFromYCenter < 0){ + angle += Math.PI*2; + } + + return { + angle: angle, + distance: radialDistanceFromCenter + }; + }, + aliasPixel = helpers.aliasPixel = function(pixelWidth){ + return (pixelWidth % 2 === 0) ? 0 : 0.5; + }, + splineCurve = helpers.splineCurve = function(FirstPoint,MiddlePoint,AfterPoint,t){ + //Props to Rob Spencer at scaled innovation for his post on splining between points + //http://scaledinnovation.com/analytics/splines/aboutSplines.html + var d01=Math.sqrt(Math.pow(MiddlePoint.x-FirstPoint.x,2)+Math.pow(MiddlePoint.y-FirstPoint.y,2)), + d12=Math.sqrt(Math.pow(AfterPoint.x-MiddlePoint.x,2)+Math.pow(AfterPoint.y-MiddlePoint.y,2)), + fa=t*d01/(d01+d12),// scaling factor for triangle Ta + fb=t*d12/(d01+d12); + return { + inner : { + x : MiddlePoint.x-fa*(AfterPoint.x-FirstPoint.x), + y : MiddlePoint.y-fa*(AfterPoint.y-FirstPoint.y) + }, + outer : { + x: MiddlePoint.x+fb*(AfterPoint.x-FirstPoint.x), + y : MiddlePoint.y+fb*(AfterPoint.y-FirstPoint.y) + } + }; + }, + calculateOrderOfMagnitude = helpers.calculateOrderOfMagnitude = function(val){ + return Math.floor(Math.log(val) / Math.LN10); + }, + calculateScaleRange = helpers.calculateScaleRange = function(valuesArray, drawingSize, textSize, startFromZero, integersOnly){ + + //Set a minimum step of two - a point at the top of the graph, and a point at the base + var minSteps = 2, + maxSteps = Math.floor(drawingSize/(textSize * 1.5)), + skipFitting = (minSteps >= maxSteps); + + var maxValue = max(valuesArray), + minValue = min(valuesArray); + + // We need some degree of seperation here to calculate the scales if all the values are the same + // Adding/minusing 0.5 will give us a range of 1. + if (maxValue === minValue){ + maxValue += 0.5; + // So we don't end up with a graph with a negative start value if we've said always start from zero + if (minValue >= 0.5 && !startFromZero){ + minValue -= 0.5; + } + else{ + // Make up a whole number above the values + maxValue += 0.5; + } + } + + var valueRange = Math.abs(maxValue - minValue), + rangeOrderOfMagnitude = calculateOrderOfMagnitude(valueRange), + graphMax = Math.ceil(maxValue / (1 * Math.pow(10, rangeOrderOfMagnitude))) * Math.pow(10, rangeOrderOfMagnitude), + graphMin = (startFromZero) ? 0 : Math.floor(minValue / (1 * Math.pow(10, rangeOrderOfMagnitude))) * Math.pow(10, rangeOrderOfMagnitude), + graphRange = graphMax - graphMin, + stepValue = Math.pow(10, rangeOrderOfMagnitude), + numberOfSteps = Math.round(graphRange / stepValue); + + //If we have more space on the graph we'll use it to give more definition to the data + while((numberOfSteps > maxSteps || (numberOfSteps * 2) < maxSteps) && !skipFitting) { + if(numberOfSteps > maxSteps){ + stepValue *=2; + numberOfSteps = Math.round(graphRange/stepValue); + // Don't ever deal with a decimal number of steps - cancel fitting and just use the minimum number of steps. + if (numberOfSteps % 1 !== 0){ + skipFitting = true; + } + } + //We can fit in double the amount of scale points on the scale + else{ + //If user has declared ints only, and the step value isn't a decimal + if (integersOnly && rangeOrderOfMagnitude >= 0){ + //If the user has said integers only, we need to check that making the scale more granular wouldn't make it a float + if(stepValue/2 % 1 === 0){ + stepValue /=2; + numberOfSteps = Math.round(graphRange/stepValue); + } + //If it would make it a float break out of the loop + else{ + break; + } + } + //If the scale doesn't have to be an int, make the scale more granular anyway. + else{ + stepValue /=2; + numberOfSteps = Math.round(graphRange/stepValue); + } + + } + } + + if (skipFitting){ + numberOfSteps = minSteps; + stepValue = graphRange / numberOfSteps; + } + + return { + steps : numberOfSteps, + stepValue : stepValue, + min : graphMin, + max : graphMin + (numberOfSteps * stepValue) + }; + + }, + /* jshint ignore:start */ + // Blows up jshint errors based on the new Function constructor + //Templating methods + //Javascript micro templating by John Resig - source at http://ejohn.org/blog/javascript-micro-templating/ + template = helpers.template = function(templateString, valuesObject){ + + // If templateString is function rather than string-template - call the function for valuesObject + + if(templateString instanceof Function){ + return templateString(valuesObject); + } + + var cache = {}; + function tmpl(str, data){ + // Figure out if we're getting a template, or if we need to + // load the template - and be sure to cache the result. + var fn = !/\W/.test(str) ? + cache[str] = cache[str] : + + // Generate a reusable function that will serve as a template + // generator (and which will be cached). + new Function("obj", + "var p=[],print=function(){p.push.apply(p,arguments);};" + + + // Introduce the data as local variables using with(){} + "with(obj){p.push('" + + + // Convert the template into pure JavaScript + str + .replace(/[\r\t\n]/g, " ") + .split("<%").join("\t") + .replace(/((^|%>)[^\t]*)'/g, "$1\r") + .replace(/\t=(.*?)%>/g, "',$1,'") + .split("\t").join("');") + .split("%>").join("p.push('") + .split("\r").join("\\'") + + "');}return p.join('');" + ); + + // Provide some basic currying to the user + return data ? fn( data ) : fn; + } + return tmpl(templateString,valuesObject); + }, + /* jshint ignore:end */ + generateLabels = helpers.generateLabels = function(templateString,numberOfSteps,graphMin,stepValue){ + var labelsArray = new Array(numberOfSteps); + if (labelTemplateString){ + each(labelsArray,function(val,index){ + labelsArray[index] = template(templateString,{value: (graphMin + (stepValue*(index+1)))}); + }); + } + return labelsArray; + }, + //--Animation methods + //Easing functions adapted from Robert Penner's easing equations + //http://www.robertpenner.com/easing/ + easingEffects = helpers.easingEffects = { + linear: function (t) { + return t; + }, + easeInQuad: function (t) { + return t * t; + }, + easeOutQuad: function (t) { + return -1 * t * (t - 2); + }, + easeInOutQuad: function (t) { + if ((t /= 1 / 2) < 1) return 1 / 2 * t * t; + return -1 / 2 * ((--t) * (t - 2) - 1); + }, + easeInCubic: function (t) { + return t * t * t; + }, + easeOutCubic: function (t) { + return 1 * ((t = t / 1 - 1) * t * t + 1); + }, + easeInOutCubic: function (t) { + if ((t /= 1 / 2) < 1) return 1 / 2 * t * t * t; + return 1 / 2 * ((t -= 2) * t * t + 2); + }, + easeInQuart: function (t) { + return t * t * t * t; + }, + easeOutQuart: function (t) { + return -1 * ((t = t / 1 - 1) * t * t * t - 1); + }, + easeInOutQuart: function (t) { + if ((t /= 1 / 2) < 1) return 1 / 2 * t * t * t * t; + return -1 / 2 * ((t -= 2) * t * t * t - 2); + }, + easeInQuint: function (t) { + return 1 * (t /= 1) * t * t * t * t; + }, + easeOutQuint: function (t) { + return 1 * ((t = t / 1 - 1) * t * t * t * t + 1); + }, + easeInOutQuint: function (t) { + if ((t /= 1 / 2) < 1) return 1 / 2 * t * t * t * t * t; + return 1 / 2 * ((t -= 2) * t * t * t * t + 2); + }, + easeInSine: function (t) { + return -1 * Math.cos(t / 1 * (Math.PI / 2)) + 1; + }, + easeOutSine: function (t) { + return 1 * Math.sin(t / 1 * (Math.PI / 2)); + }, + easeInOutSine: function (t) { + return -1 / 2 * (Math.cos(Math.PI * t / 1) - 1); + }, + easeInExpo: function (t) { + return (t === 0) ? 1 : 1 * Math.pow(2, 10 * (t / 1 - 1)); + }, + easeOutExpo: function (t) { + return (t === 1) ? 1 : 1 * (-Math.pow(2, -10 * t / 1) + 1); + }, + easeInOutExpo: function (t) { + if (t === 0) return 0; + if (t === 1) return 1; + if ((t /= 1 / 2) < 1) return 1 / 2 * Math.pow(2, 10 * (t - 1)); + return 1 / 2 * (-Math.pow(2, -10 * --t) + 2); + }, + easeInCirc: function (t) { + if (t >= 1) return t; + return -1 * (Math.sqrt(1 - (t /= 1) * t) - 1); + }, + easeOutCirc: function (t) { + return 1 * Math.sqrt(1 - (t = t / 1 - 1) * t); + }, + easeInOutCirc: function (t) { + if ((t /= 1 / 2) < 1) return -1 / 2 * (Math.sqrt(1 - t * t) - 1); + return 1 / 2 * (Math.sqrt(1 - (t -= 2) * t) + 1); + }, + easeInElastic: function (t) { + var s = 1.70158; + var p = 0; + var a = 1; + if (t === 0) return 0; + if ((t /= 1) == 1) return 1; + if (!p) p = 1 * 0.3; + if (a < Math.abs(1)) { + a = 1; + s = p / 4; + } else s = p / (2 * Math.PI) * Math.asin(1 / a); + return -(a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t * 1 - s) * (2 * Math.PI) / p)); + }, + easeOutElastic: function (t) { + var s = 1.70158; + var p = 0; + var a = 1; + if (t === 0) return 0; + if ((t /= 1) == 1) return 1; + if (!p) p = 1 * 0.3; + if (a < Math.abs(1)) { + a = 1; + s = p / 4; + } else s = p / (2 * Math.PI) * Math.asin(1 / a); + return a * Math.pow(2, -10 * t) * Math.sin((t * 1 - s) * (2 * Math.PI) / p) + 1; + }, + easeInOutElastic: function (t) { + var s = 1.70158; + var p = 0; + var a = 1; + if (t === 0) return 0; + if ((t /= 1 / 2) == 2) return 1; + if (!p) p = 1 * (0.3 * 1.5); + if (a < Math.abs(1)) { + a = 1; + s = p / 4; + } else s = p / (2 * Math.PI) * Math.asin(1 / a); + if (t < 1) return -0.5 * (a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t * 1 - s) * (2 * Math.PI) / p)); + return a * Math.pow(2, -10 * (t -= 1)) * Math.sin((t * 1 - s) * (2 * Math.PI) / p) * 0.5 + 1; + }, + easeInBack: function (t) { + var s = 1.70158; + return 1 * (t /= 1) * t * ((s + 1) * t - s); + }, + easeOutBack: function (t) { + var s = 1.70158; + return 1 * ((t = t / 1 - 1) * t * ((s + 1) * t + s) + 1); + }, + easeInOutBack: function (t) { + var s = 1.70158; + if ((t /= 1 / 2) < 1) return 1 / 2 * (t * t * (((s *= (1.525)) + 1) * t - s)); + return 1 / 2 * ((t -= 2) * t * (((s *= (1.525)) + 1) * t + s) + 2); + }, + easeInBounce: function (t) { + return 1 - easingEffects.easeOutBounce(1 - t); + }, + easeOutBounce: function (t) { + if ((t /= 1) < (1 / 2.75)) { + return 1 * (7.5625 * t * t); + } else if (t < (2 / 2.75)) { + return 1 * (7.5625 * (t -= (1.5 / 2.75)) * t + 0.75); + } else if (t < (2.5 / 2.75)) { + return 1 * (7.5625 * (t -= (2.25 / 2.75)) * t + 0.9375); + } else { + return 1 * (7.5625 * (t -= (2.625 / 2.75)) * t + 0.984375); + } + }, + easeInOutBounce: function (t) { + if (t < 1 / 2) return easingEffects.easeInBounce(t * 2) * 0.5; + return easingEffects.easeOutBounce(t * 2 - 1) * 0.5 + 1 * 0.5; + } + }, + //Request animation polyfill - http://www.paulirish.com/2011/requestanimationframe-for-smart-animating/ + requestAnimFrame = helpers.requestAnimFrame = (function(){ + return window.requestAnimationFrame || + window.webkitRequestAnimationFrame || + window.mozRequestAnimationFrame || + window.oRequestAnimationFrame || + window.msRequestAnimationFrame || + function(callback) { + return window.setTimeout(callback, 1000 / 60); + }; + })(), + cancelAnimFrame = helpers.cancelAnimFrame = (function(){ + return window.cancelAnimationFrame || + window.webkitCancelAnimationFrame || + window.mozCancelAnimationFrame || + window.oCancelAnimationFrame || + window.msCancelAnimationFrame || + function(callback) { + return window.clearTimeout(callback, 1000 / 60); + }; + })(), + animationLoop = helpers.animationLoop = function(callback,totalSteps,easingString,onProgress,onComplete,chartInstance){ + + var currentStep = 0, + easingFunction = easingEffects[easingString] || easingEffects.linear; + + var animationFrame = function(){ + currentStep++; + var stepDecimal = currentStep/totalSteps; + var easeDecimal = easingFunction(stepDecimal); + + callback.call(chartInstance,easeDecimal,stepDecimal, currentStep); + onProgress.call(chartInstance,easeDecimal,stepDecimal); + if (currentStep < totalSteps){ + chartInstance.animationFrame = requestAnimFrame(animationFrame); + } else{ + onComplete.apply(chartInstance); + } + }; + requestAnimFrame(animationFrame); + }, + //-- DOM methods + getRelativePosition = helpers.getRelativePosition = function(evt){ + var mouseX, mouseY; + var e = evt.originalEvent || evt, + canvas = evt.currentTarget || evt.srcElement, + boundingRect = canvas.getBoundingClientRect(); + + if (e.touches){ + mouseX = e.touches[0].clientX - boundingRect.left; + mouseY = e.touches[0].clientY - boundingRect.top; + + } + else{ + mouseX = e.clientX - boundingRect.left; + mouseY = e.clientY - boundingRect.top; + } + + return { + x : mouseX, + y : mouseY + }; + + }, + addEvent = helpers.addEvent = function(node,eventType,method){ + if (node.addEventListener){ + node.addEventListener(eventType,method); + } else if (node.attachEvent){ + node.attachEvent("on"+eventType, method); + } else { + node["on"+eventType] = method; + } + }, + removeEvent = helpers.removeEvent = function(node, eventType, handler){ + if (node.removeEventListener){ + node.removeEventListener(eventType, handler, false); + } else if (node.detachEvent){ + node.detachEvent("on"+eventType,handler); + } else{ + node["on" + eventType] = noop; + } + }, + bindEvents = helpers.bindEvents = function(chartInstance, arrayOfEvents, handler){ + // Create the events object if it's not already present + if (!chartInstance.events) chartInstance.events = {}; + + each(arrayOfEvents,function(eventName){ + chartInstance.events[eventName] = function(){ + handler.apply(chartInstance, arguments); + }; + addEvent(chartInstance.chart.canvas,eventName,chartInstance.events[eventName]); + }); + }, + unbindEvents = helpers.unbindEvents = function (chartInstance, arrayOfEvents) { + each(arrayOfEvents, function(handler,eventName){ + removeEvent(chartInstance.chart.canvas, eventName, handler); + }); + }, + getMaximumWidth = helpers.getMaximumWidth = function(domNode){ + var container = domNode.parentNode; + // TODO = check cross browser stuff with this. + return container.clientWidth; + }, + getMaximumHeight = helpers.getMaximumHeight = function(domNode){ + var container = domNode.parentNode; + // TODO = check cross browser stuff with this. + return container.clientHeight; + }, + getMaximumSize = helpers.getMaximumSize = helpers.getMaximumWidth, // legacy support + retinaScale = helpers.retinaScale = function(chart){ + var ctx = chart.ctx, + width = chart.canvas.width, + height = chart.canvas.height; + + if (window.devicePixelRatio) { + ctx.canvas.style.width = width + "px"; + ctx.canvas.style.height = height + "px"; + ctx.canvas.height = height * window.devicePixelRatio; + ctx.canvas.width = width * window.devicePixelRatio; + ctx.scale(window.devicePixelRatio, window.devicePixelRatio); + } + }, + //-- Canvas methods + clear = helpers.clear = function(chart){ + chart.ctx.clearRect(0,0,chart.width,chart.height); + }, + fontString = helpers.fontString = function(pixelSize,fontStyle,fontFamily){ + return fontStyle + " " + pixelSize+"px " + fontFamily; + }, + longestText = helpers.longestText = function(ctx,font,arrayOfStrings){ + ctx.font = font; + var longest = 0; + each(arrayOfStrings,function(string){ + var textWidth = ctx.measureText(string).width; + longest = (textWidth > longest) ? textWidth : longest; + }); + return longest; + }, + drawRoundedRectangle = helpers.drawRoundedRectangle = function(ctx,x,y,width,height,radius){ + ctx.beginPath(); + ctx.moveTo(x + radius, y); + ctx.lineTo(x + width - radius, y); + ctx.quadraticCurveTo(x + width, y, x + width, y + radius); + ctx.lineTo(x + width, y + height - radius); + ctx.quadraticCurveTo(x + width, y + height, x + width - radius, y + height); + ctx.lineTo(x + radius, y + height); + ctx.quadraticCurveTo(x, y + height, x, y + height - radius); + ctx.lineTo(x, y + radius); + ctx.quadraticCurveTo(x, y, x + radius, y); + ctx.closePath(); + }; + + + //Store a reference to each instance - allowing us to globally resize chart instances on window resize. + //Destroy method on the chart will remove the instance of the chart from this reference. + Chart.instances = {}; + + Chart.Type = function(data,options,chart){ + this.options = options; + this.chart = chart; + this.id = uid(); + //Add the chart instance to the global namespace + Chart.instances[this.id] = this; + + // Initialize is always called when a chart type is created + // By default it is a no op, but it should be extended + if (options.responsive){ + this.resize(); + } + this.initialize.call(this,data); + }; + + //Core methods that'll be a part of every chart type + extend(Chart.Type.prototype,{ + initialize : function(){return this;}, + clear : function(){ + clear(this.chart); + return this; + }, + stop : function(){ + // Stops any current animation loop occuring + cancelAnimFrame(this.animationFrame); + return this; + }, + resize : function(callback){ + this.stop(); + var canvas = this.chart.canvas, + newWidth = getMaximumWidth(this.chart.canvas), + newHeight = this.options.maintainAspectRatio ? newWidth / this.chart.aspectRatio : getMaximumHeight(this.chart.canvas); + + canvas.width = this.chart.width = newWidth; + canvas.height = this.chart.height = newHeight; + + retinaScale(this.chart); + + if (typeof callback === "function"){ + callback.apply(this, Array.prototype.slice.call(arguments, 1)); + } + return this; + }, + reflow : noop, + render : function(reflow){ + if (reflow){ + this.reflow(); + } + if (this.options.animation && !reflow){ + helpers.animationLoop( + this.draw, + this.options.animationSteps, + this.options.animationEasing, + this.options.onAnimationProgress, + this.options.onAnimationComplete, + this + ); + } + else{ + this.draw(); + this.options.onAnimationComplete.call(this); + } + return this; + }, + generateLegend : function(){ + return template(this.options.legendTemplate,this); + }, + destroy : function(){ + this.clear(); + unbindEvents(this, this.events); + var canvas = this.chart.canvas; + + // Reset canvas height/width attributes starts a fresh with the canvas context + canvas.width = this.chart.width; + canvas.height = this.chart.height; + + // < IE9 doesn't support removeProperty + if (canvas.style.removeProperty) { + canvas.style.removeProperty('width'); + canvas.style.removeProperty('height'); + } else { + canvas.style.removeAttribute('width'); + canvas.style.removeAttribute('height'); + } + + delete Chart.instances[this.id]; + }, + showTooltip : function(ChartElements, forceRedraw){ + // Only redraw the chart if we've actually changed what we're hovering on. + if (typeof this.activeElements === 'undefined') this.activeElements = []; + + var isChanged = (function(Elements){ + var changed = false; + + if (Elements.length !== this.activeElements.length){ + changed = true; + return changed; + } + + each(Elements, function(element, index){ + if (element !== this.activeElements[index]){ + changed = true; + } + }, this); + return changed; + }).call(this, ChartElements); + + if (!isChanged && !forceRedraw){ + return; + } + else{ + this.activeElements = ChartElements; + } + this.draw(); + if(this.options.customTooltips){ + this.options.customTooltips(false); + } + if (ChartElements.length > 0){ + // If we have multiple datasets, show a MultiTooltip for all of the data points at that index + if (this.datasets && this.datasets.length > 1) { + var dataArray, + dataIndex; + + for (var i = this.datasets.length - 1; i >= 0; i--) { + dataArray = this.datasets[i].points || this.datasets[i].bars || this.datasets[i].segments; + dataIndex = indexOf(dataArray, ChartElements[0]); + if (dataIndex !== -1){ + break; + } + } + var tooltipLabels = [], + tooltipColors = [], + medianPosition = (function(index) { + + // Get all the points at that particular index + var Elements = [], + dataCollection, + xPositions = [], + yPositions = [], + xMax, + yMax, + xMin, + yMin; + helpers.each(this.datasets, function(dataset){ + dataCollection = dataset.points || dataset.bars || dataset.segments; + if (dataCollection[dataIndex] && dataCollection[dataIndex].hasValue()){ + Elements.push(dataCollection[dataIndex]); + } + }); + + helpers.each(Elements, function(element) { + xPositions.push(element.x); + yPositions.push(element.y); + + + //Include any colour information about the element + tooltipLabels.push(helpers.template(this.options.multiTooltipTemplate, element)); + tooltipColors.push({ + fill: element._saved.fillColor || element.fillColor, + stroke: element._saved.strokeColor || element.strokeColor + }); + + }, this); + + yMin = min(yPositions); + yMax = max(yPositions); + + xMin = min(xPositions); + xMax = max(xPositions); + + return { + x: (xMin > this.chart.width/2) ? xMin : xMax, + y: (yMin + yMax)/2 + }; + }).call(this, dataIndex); + + new Chart.MultiTooltip({ + x: medianPosition.x, + y: medianPosition.y, + xPadding: this.options.tooltipXPadding, + yPadding: this.options.tooltipYPadding, + xOffset: this.options.tooltipXOffset, + fillColor: this.options.tooltipFillColor, + textColor: this.options.tooltipFontColor, + fontFamily: this.options.tooltipFontFamily, + fontStyle: this.options.tooltipFontStyle, + fontSize: this.options.tooltipFontSize, + titleTextColor: this.options.tooltipTitleFontColor, + titleFontFamily: this.options.tooltipTitleFontFamily, + titleFontStyle: this.options.tooltipTitleFontStyle, + titleFontSize: this.options.tooltipTitleFontSize, + cornerRadius: this.options.tooltipCornerRadius, + labels: tooltipLabels, + legendColors: tooltipColors, + legendColorBackground : this.options.multiTooltipKeyBackground, + title: ChartElements[0].label, + chart: this.chart, + ctx: this.chart.ctx, + custom: this.options.customTooltips + }).draw(); + + } else { + each(ChartElements, function(Element) { + var tooltipPosition = Element.tooltipPosition(); + new Chart.Tooltip({ + x: Math.round(tooltipPosition.x), + y: Math.round(tooltipPosition.y), + xPadding: this.options.tooltipXPadding, + yPadding: this.options.tooltipYPadding, + fillColor: this.options.tooltipFillColor, + textColor: this.options.tooltipFontColor, + fontFamily: this.options.tooltipFontFamily, + fontStyle: this.options.tooltipFontStyle, + fontSize: this.options.tooltipFontSize, + caretHeight: this.options.tooltipCaretSize, + cornerRadius: this.options.tooltipCornerRadius, + text: template(this.options.tooltipTemplate, Element), + chart: this.chart, + custom: this.options.customTooltips + }).draw(); + }, this); + } + } + return this; + }, + toBase64Image : function(){ + return this.chart.canvas.toDataURL.apply(this.chart.canvas, arguments); + } + }); + + Chart.Type.extend = function(extensions){ + + var parent = this; + + var ChartType = function(){ + return parent.apply(this,arguments); + }; + + //Copy the prototype object of the this class + ChartType.prototype = clone(parent.prototype); + //Now overwrite some of the properties in the base class with the new extensions + extend(ChartType.prototype, extensions); + + ChartType.extend = Chart.Type.extend; + + if (extensions.name || parent.prototype.name){ + + var chartName = extensions.name || parent.prototype.name; + //Assign any potential default values of the new chart type + + //If none are defined, we'll use a clone of the chart type this is being extended from. + //I.e. if we extend a line chart, we'll use the defaults from the line chart if our new chart + //doesn't define some defaults of their own. + + var baseDefaults = (Chart.defaults[parent.prototype.name]) ? clone(Chart.defaults[parent.prototype.name]) : {}; + + Chart.defaults[chartName] = extend(baseDefaults,extensions.defaults); + + Chart.types[chartName] = ChartType; + + //Register this new chart type in the Chart prototype + Chart.prototype[chartName] = function(data,options){ + var config = merge(Chart.defaults.global, Chart.defaults[chartName], options || {}); + return new ChartType(data,config,this); + }; + } else{ + warn("Name not provided for this chart, so it hasn't been registered"); + } + return parent; + }; + + Chart.Element = function(configuration){ + extend(this,configuration); + this.initialize.apply(this,arguments); + this.save(); + }; + extend(Chart.Element.prototype,{ + initialize : function(){}, + restore : function(props){ + if (!props){ + extend(this,this._saved); + } else { + each(props,function(key){ + this[key] = this._saved[key]; + },this); + } + return this; + }, + save : function(){ + this._saved = clone(this); + delete this._saved._saved; + return this; + }, + update : function(newProps){ + each(newProps,function(value,key){ + this._saved[key] = this[key]; + this[key] = value; + },this); + return this; + }, + transition : function(props,ease){ + each(props,function(value,key){ + this[key] = ((value - this._saved[key]) * ease) + this._saved[key]; + },this); + return this; + }, + tooltipPosition : function(){ + return { + x : this.x, + y : this.y + }; + }, + hasValue: function(){ + return isNumber(this.value); + } + }); + + Chart.Element.extend = inherits; + + + Chart.Point = Chart.Element.extend({ + display: true, + inRange: function(chartX,chartY){ + var hitDetectionRange = this.hitDetectionRadius + this.radius; + return ((Math.pow(chartX-this.x, 2)+Math.pow(chartY-this.y, 2)) < Math.pow(hitDetectionRange,2)); + }, + draw : function(){ + if (this.display){ + var ctx = this.ctx; + ctx.beginPath(); + + ctx.arc(this.x, this.y, this.radius, 0, Math.PI*2); + ctx.closePath(); + + ctx.strokeStyle = this.strokeColor; + ctx.lineWidth = this.strokeWidth; + + ctx.fillStyle = this.fillColor; + + ctx.fill(); + ctx.stroke(); + } + + + //Quick debug for bezier curve splining + //Highlights control points and the line between them. + //Handy for dev - stripped in the min version. + + // ctx.save(); + // ctx.fillStyle = "black"; + // ctx.strokeStyle = "black" + // ctx.beginPath(); + // ctx.arc(this.controlPoints.inner.x,this.controlPoints.inner.y, 2, 0, Math.PI*2); + // ctx.fill(); + + // ctx.beginPath(); + // ctx.arc(this.controlPoints.outer.x,this.controlPoints.outer.y, 2, 0, Math.PI*2); + // ctx.fill(); + + // ctx.moveTo(this.controlPoints.inner.x,this.controlPoints.inner.y); + // ctx.lineTo(this.x, this.y); + // ctx.lineTo(this.controlPoints.outer.x,this.controlPoints.outer.y); + // ctx.stroke(); + + // ctx.restore(); + + + + } + }); + + Chart.Arc = Chart.Element.extend({ + inRange : function(chartX,chartY){ + + var pointRelativePosition = helpers.getAngleFromPoint(this, { + x: chartX, + y: chartY + }); + + //Check if within the range of the open/close angle + var betweenAngles = (pointRelativePosition.angle >= this.startAngle && pointRelativePosition.angle <= this.endAngle), + withinRadius = (pointRelativePosition.distance >= this.innerRadius && pointRelativePosition.distance <= this.outerRadius); + + return (betweenAngles && withinRadius); + //Ensure within the outside of the arc centre, but inside arc outer + }, + tooltipPosition : function(){ + var centreAngle = this.startAngle + ((this.endAngle - this.startAngle) / 2), + rangeFromCentre = (this.outerRadius - this.innerRadius) / 2 + this.innerRadius; + return { + x : this.x + (Math.cos(centreAngle) * rangeFromCentre), + y : this.y + (Math.sin(centreAngle) * rangeFromCentre) + }; + }, + draw : function(animationPercent){ + + var easingDecimal = animationPercent || 1; + + var ctx = this.ctx; + + ctx.beginPath(); + + ctx.arc(this.x, this.y, this.outerRadius, this.startAngle, this.endAngle); + + ctx.arc(this.x, this.y, this.innerRadius, this.endAngle, this.startAngle, true); + + ctx.closePath(); + ctx.strokeStyle = this.strokeColor; + ctx.lineWidth = this.strokeWidth; + + ctx.fillStyle = this.fillColor; + + ctx.fill(); + ctx.lineJoin = 'bevel'; + + if (this.showStroke){ + ctx.stroke(); + } + } + }); + + Chart.Rectangle = Chart.Element.extend({ + draw : function(){ + var ctx = this.ctx, + halfWidth = this.width/2, + leftX = this.x - halfWidth, + rightX = this.x + halfWidth, + top = this.base - (this.base - this.y), + halfStroke = this.strokeWidth / 2; + + // Canvas doesn't allow us to stroke inside the width so we can + // adjust the sizes to fit if we're setting a stroke on the line + if (this.showStroke){ + leftX += halfStroke; + rightX -= halfStroke; + top += halfStroke; + } + + ctx.beginPath(); + + ctx.fillStyle = this.fillColor; + ctx.strokeStyle = this.strokeColor; + ctx.lineWidth = this.strokeWidth; + + // It'd be nice to keep this class totally generic to any rectangle + // and simply specify which border to miss out. + ctx.moveTo(leftX, this.base); + ctx.lineTo(leftX, top); + ctx.lineTo(rightX, top); + ctx.lineTo(rightX, this.base); + ctx.fill(); + if (this.showStroke){ + ctx.stroke(); + } + }, + height : function(){ + return this.base - this.y; + }, + inRange : function(chartX,chartY){ + return (chartX >= this.x - this.width/2 && chartX <= this.x + this.width/2) && (chartY >= this.y && chartY <= this.base); + } + }); + + Chart.Tooltip = Chart.Element.extend({ + draw : function(){ + + var ctx = this.chart.ctx; + + ctx.font = fontString(this.fontSize,this.fontStyle,this.fontFamily); + + this.xAlign = "center"; + this.yAlign = "above"; + + //Distance between the actual element.y position and the start of the tooltip caret + var caretPadding = this.caretPadding = 2; + + var tooltipWidth = ctx.measureText(this.text).width + 2*this.xPadding, + tooltipRectHeight = this.fontSize + 2*this.yPadding, + tooltipHeight = tooltipRectHeight + this.caretHeight + caretPadding; + + if (this.x + tooltipWidth/2 >this.chart.width){ + this.xAlign = "left"; + } else if (this.x - tooltipWidth/2 < 0){ + this.xAlign = "right"; + } + + if (this.y - tooltipHeight < 0){ + this.yAlign = "below"; + } + + + var tooltipX = this.x - tooltipWidth/2, + tooltipY = this.y - tooltipHeight; + + ctx.fillStyle = this.fillColor; + + // Custom Tooltips + if(this.custom){ + this.custom(this); + } + else{ + switch(this.yAlign) + { + case "above": + //Draw a caret above the x/y + ctx.beginPath(); + ctx.moveTo(this.x,this.y - caretPadding); + ctx.lineTo(this.x + this.caretHeight, this.y - (caretPadding + this.caretHeight)); + ctx.lineTo(this.x - this.caretHeight, this.y - (caretPadding + this.caretHeight)); + ctx.closePath(); + ctx.fill(); + break; + case "below": + tooltipY = this.y + caretPadding + this.caretHeight; + //Draw a caret below the x/y + ctx.beginPath(); + ctx.moveTo(this.x, this.y + caretPadding); + ctx.lineTo(this.x + this.caretHeight, this.y + caretPadding + this.caretHeight); + ctx.lineTo(this.x - this.caretHeight, this.y + caretPadding + this.caretHeight); + ctx.closePath(); + ctx.fill(); + break; + } + + switch(this.xAlign) + { + case "left": + tooltipX = this.x - tooltipWidth + (this.cornerRadius + this.caretHeight); + break; + case "right": + tooltipX = this.x - (this.cornerRadius + this.caretHeight); + break; + } + + drawRoundedRectangle(ctx,tooltipX,tooltipY,tooltipWidth,tooltipRectHeight,this.cornerRadius); + + ctx.fill(); + + ctx.fillStyle = this.textColor; + ctx.textAlign = "center"; + ctx.textBaseline = "middle"; + ctx.fillText(this.text, tooltipX + tooltipWidth/2, tooltipY + tooltipRectHeight/2); + } + } + }); + + Chart.MultiTooltip = Chart.Element.extend({ + initialize : function(){ + this.font = fontString(this.fontSize,this.fontStyle,this.fontFamily); + + this.titleFont = fontString(this.titleFontSize,this.titleFontStyle,this.titleFontFamily); + + this.height = (this.labels.length * this.fontSize) + ((this.labels.length-1) * (this.fontSize/2)) + (this.yPadding*2) + this.titleFontSize *1.5; + + this.ctx.font = this.titleFont; + + var titleWidth = this.ctx.measureText(this.title).width, + //Label has a legend square as well so account for this. + labelWidth = longestText(this.ctx,this.font,this.labels) + this.fontSize + 3, + longestTextWidth = max([labelWidth,titleWidth]); + + this.width = longestTextWidth + (this.xPadding*2); + + + var halfHeight = this.height/2; + + //Check to ensure the height will fit on the canvas + if (this.y - halfHeight < 0 ){ + this.y = halfHeight; + } else if (this.y + halfHeight > this.chart.height){ + this.y = this.chart.height - halfHeight; + } + + //Decide whether to align left or right based on position on canvas + if (this.x > this.chart.width/2){ + this.x -= this.xOffset + this.width; + } else { + this.x += this.xOffset; + } + + + }, + getLineHeight : function(index){ + var baseLineHeight = this.y - (this.height/2) + this.yPadding, + afterTitleIndex = index-1; + + //If the index is zero, we're getting the title + if (index === 0){ + return baseLineHeight + this.titleFontSize/2; + } else{ + return baseLineHeight + ((this.fontSize*1.5*afterTitleIndex) + this.fontSize/2) + this.titleFontSize * 1.5; + } + + }, + draw : function(){ + // Custom Tooltips + if(this.custom){ + this.custom(this); + } + else{ + drawRoundedRectangle(this.ctx,this.x,this.y - this.height/2,this.width,this.height,this.cornerRadius); + var ctx = this.ctx; + ctx.fillStyle = this.fillColor; + ctx.fill(); + ctx.closePath(); + + ctx.textAlign = "left"; + ctx.textBaseline = "middle"; + ctx.fillStyle = this.titleTextColor; + ctx.font = this.titleFont; + + ctx.fillText(this.title,this.x + this.xPadding, this.getLineHeight(0)); + + ctx.font = this.font; + helpers.each(this.labels,function(label,index){ + ctx.fillStyle = this.textColor; + ctx.fillText(label,this.x + this.xPadding + this.fontSize + 3, this.getLineHeight(index + 1)); + + //A bit gnarly, but clearing this rectangle breaks when using explorercanvas (clears whole canvas) + //ctx.clearRect(this.x + this.xPadding, this.getLineHeight(index + 1) - this.fontSize/2, this.fontSize, this.fontSize); + //Instead we'll make a white filled block to put the legendColour palette over. + + ctx.fillStyle = this.legendColorBackground; + ctx.fillRect(this.x + this.xPadding, this.getLineHeight(index + 1) - this.fontSize/2, this.fontSize, this.fontSize); + + ctx.fillStyle = this.legendColors[index].fill; + ctx.fillRect(this.x + this.xPadding, this.getLineHeight(index + 1) - this.fontSize/2, this.fontSize, this.fontSize); + + + },this); + } + } + }); + + Chart.Scale = Chart.Element.extend({ + initialize : function(){ + this.fit(); + }, + buildYLabels : function(){ + this.yLabels = []; + + var stepDecimalPlaces = getDecimalPlaces(this.stepValue); + + for (var i=0; i<=this.steps; i++){ + this.yLabels.push(template(this.templateString,{value:(this.min + (i * this.stepValue)).toFixed(stepDecimalPlaces)})); + } + this.yLabelWidth = (this.display && this.showLabels) ? longestText(this.ctx,this.font,this.yLabels) : 0; + }, + addXLabel : function(label){ + this.xLabels.push(label); + this.valuesCount++; + this.fit(); + }, + removeXLabel : function(){ + this.xLabels.shift(); + this.valuesCount--; + this.fit(); + }, + // Fitting loop to rotate x Labels and figure out what fits there, and also calculate how many Y steps to use + fit: function(){ + // First we need the width of the yLabels, assuming the xLabels aren't rotated + + // To do that we need the base line at the top and base of the chart, assuming there is no x label rotation + this.startPoint = (this.display) ? this.fontSize : 0; + this.endPoint = (this.display) ? this.height - (this.fontSize * 1.5) - 5 : this.height; // -5 to pad labels + + // Apply padding settings to the start and end point. + this.startPoint += this.padding; + this.endPoint -= this.padding; + + // Cache the starting height, so can determine if we need to recalculate the scale yAxis + var cachedHeight = this.endPoint - this.startPoint, + cachedYLabelWidth; + + // Build the current yLabels so we have an idea of what size they'll be to start + /* + * This sets what is returned from calculateScaleRange as static properties of this class: + * + this.steps; + this.stepValue; + this.min; + this.max; + * + */ + this.calculateYRange(cachedHeight); + + // With these properties set we can now build the array of yLabels + // and also the width of the largest yLabel + this.buildYLabels(); + + this.calculateXLabelRotation(); + + while((cachedHeight > this.endPoint - this.startPoint)){ + cachedHeight = this.endPoint - this.startPoint; + cachedYLabelWidth = this.yLabelWidth; + + this.calculateYRange(cachedHeight); + this.buildYLabels(); + + // Only go through the xLabel loop again if the yLabel width has changed + if (cachedYLabelWidth < this.yLabelWidth){ + this.calculateXLabelRotation(); + } + } + + }, + calculateXLabelRotation : function(){ + //Get the width of each grid by calculating the difference + //between x offsets between 0 and 1. + + this.ctx.font = this.font; + + var firstWidth = this.ctx.measureText(this.xLabels[0]).width, + lastWidth = this.ctx.measureText(this.xLabels[this.xLabels.length - 1]).width, + firstRotated, + lastRotated; + + + this.xScalePaddingRight = lastWidth/2 + 3; + this.xScalePaddingLeft = (firstWidth/2 > this.yLabelWidth + 10) ? firstWidth/2 : this.yLabelWidth + 10; + + this.xLabelRotation = 0; + if (this.display){ + var originalLabelWidth = longestText(this.ctx,this.font,this.xLabels), + cosRotation, + firstRotatedWidth; + this.xLabelWidth = originalLabelWidth; + //Allow 3 pixels x2 padding either side for label readability + var xGridWidth = Math.floor(this.calculateX(1) - this.calculateX(0)) - 6; + + //Max label rotate should be 90 - also act as a loop counter + while ((this.xLabelWidth > xGridWidth && this.xLabelRotation === 0) || (this.xLabelWidth > xGridWidth && this.xLabelRotation <= 90 && this.xLabelRotation > 0)){ + cosRotation = Math.cos(toRadians(this.xLabelRotation)); + + firstRotated = cosRotation * firstWidth; + lastRotated = cosRotation * lastWidth; + + // We're right aligning the text now. + if (firstRotated + this.fontSize / 2 > this.yLabelWidth + 8){ + this.xScalePaddingLeft = firstRotated + this.fontSize / 2; + } + this.xScalePaddingRight = this.fontSize/2; + + + this.xLabelRotation++; + this.xLabelWidth = cosRotation * originalLabelWidth; + + } + if (this.xLabelRotation > 0){ + this.endPoint -= Math.sin(toRadians(this.xLabelRotation))*originalLabelWidth + 3; + } + } + else{ + this.xLabelWidth = 0; + this.xScalePaddingRight = this.padding; + this.xScalePaddingLeft = this.padding; + } + + }, + // Needs to be overidden in each Chart type + // Otherwise we need to pass all the data into the scale class + calculateYRange: noop, + drawingArea: function(){ + return this.startPoint - this.endPoint; + }, + calculateY : function(value){ + var scalingFactor = this.drawingArea() / (this.min - this.max); + return this.endPoint - (scalingFactor * (value - this.min)); + }, + calculateX : function(index){ + var isRotated = (this.xLabelRotation > 0), + // innerWidth = (this.offsetGridLines) ? this.width - offsetLeft - this.padding : this.width - (offsetLeft + halfLabelWidth * 2) - this.padding, + innerWidth = this.width - (this.xScalePaddingLeft + this.xScalePaddingRight), + valueWidth = innerWidth/Math.max((this.valuesCount - ((this.offsetGridLines) ? 0 : 1)), 1), + valueOffset = (valueWidth * index) + this.xScalePaddingLeft; + + if (this.offsetGridLines){ + valueOffset += (valueWidth/2); + } + + return Math.round(valueOffset); + }, + update : function(newProps){ + helpers.extend(this, newProps); + this.fit(); + }, + draw : function(){ + var ctx = this.ctx, + yLabelGap = (this.endPoint - this.startPoint) / this.steps, + xStart = Math.round(this.xScalePaddingLeft); + if (this.display){ + ctx.fillStyle = this.textColor; + ctx.font = this.font; + each(this.yLabels,function(labelString,index){ + var yLabelCenter = this.endPoint - (yLabelGap * index), + linePositionY = Math.round(yLabelCenter), + drawHorizontalLine = this.showHorizontalLines; + + ctx.textAlign = "right"; + ctx.textBaseline = "middle"; + if (this.showLabels){ + ctx.fillText(labelString,xStart - 10,yLabelCenter); + } + + // This is X axis, so draw it + if (index === 0 && !drawHorizontalLine){ + drawHorizontalLine = true; + } + + if (drawHorizontalLine){ + ctx.beginPath(); + } + + if (index > 0){ + // This is a grid line in the centre, so drop that + ctx.lineWidth = this.gridLineWidth; + ctx.strokeStyle = this.gridLineColor; + } else { + // This is the first line on the scale + ctx.lineWidth = this.lineWidth; + ctx.strokeStyle = this.lineColor; + } + + linePositionY += helpers.aliasPixel(ctx.lineWidth); + + if(drawHorizontalLine){ + ctx.moveTo(xStart, linePositionY); + ctx.lineTo(this.width, linePositionY); + ctx.stroke(); + ctx.closePath(); + } + + ctx.lineWidth = this.lineWidth; + ctx.strokeStyle = this.lineColor; + ctx.beginPath(); + ctx.moveTo(xStart - 5, linePositionY); + ctx.lineTo(xStart, linePositionY); + ctx.stroke(); + ctx.closePath(); + + },this); + + each(this.xLabels,function(label,index){ + var xPos = this.calculateX(index) + aliasPixel(this.lineWidth), + // Check to see if line/bar here and decide where to place the line + linePos = this.calculateX(index - (this.offsetGridLines ? 0.5 : 0)) + aliasPixel(this.lineWidth), + isRotated = (this.xLabelRotation > 0), + drawVerticalLine = this.showVerticalLines; + + // This is Y axis, so draw it + if (index === 0 && !drawVerticalLine){ + drawVerticalLine = true; + } + + if (drawVerticalLine){ + ctx.beginPath(); + } + + if (index > 0){ + // This is a grid line in the centre, so drop that + ctx.lineWidth = this.gridLineWidth; + ctx.strokeStyle = this.gridLineColor; + } else { + // This is the first line on the scale + ctx.lineWidth = this.lineWidth; + ctx.strokeStyle = this.lineColor; + } + + if (drawVerticalLine){ + ctx.moveTo(linePos,this.endPoint); + ctx.lineTo(linePos,this.startPoint - 3); + ctx.stroke(); + ctx.closePath(); + } + + + ctx.lineWidth = this.lineWidth; + ctx.strokeStyle = this.lineColor; + + + // Small lines at the bottom of the base grid line + ctx.beginPath(); + ctx.moveTo(linePos,this.endPoint); + ctx.lineTo(linePos,this.endPoint + 5); + ctx.stroke(); + ctx.closePath(); + + ctx.save(); + ctx.translate(xPos,(isRotated) ? this.endPoint + 12 : this.endPoint + 8); + ctx.rotate(toRadians(this.xLabelRotation)*-1); + ctx.font = this.font; + ctx.textAlign = (isRotated) ? "right" : "center"; + ctx.textBaseline = (isRotated) ? "middle" : "top"; + ctx.fillText(label, 0, 0); + ctx.restore(); + },this); + + } + } + + }); + + Chart.RadialScale = Chart.Element.extend({ + initialize: function(){ + this.size = min([this.height, this.width]); + this.drawingArea = (this.display) ? (this.size/2) - (this.fontSize/2 + this.backdropPaddingY) : (this.size/2); + }, + calculateCenterOffset: function(value){ + // Take into account half font size + the yPadding of the top value + var scalingFactor = this.drawingArea / (this.max - this.min); + + return (value - this.min) * scalingFactor; + }, + update : function(){ + if (!this.lineArc){ + this.setScaleSize(); + } else { + this.drawingArea = (this.display) ? (this.size/2) - (this.fontSize/2 + this.backdropPaddingY) : (this.size/2); + } + this.buildYLabels(); + }, + buildYLabels: function(){ + this.yLabels = []; + + var stepDecimalPlaces = getDecimalPlaces(this.stepValue); + + for (var i=0; i<=this.steps; i++){ + this.yLabels.push(template(this.templateString,{value:(this.min + (i * this.stepValue)).toFixed(stepDecimalPlaces)})); + } + }, + getCircumference : function(){ + return ((Math.PI*2) / this.valuesCount); + }, + setScaleSize: function(){ + /* + * Right, this is really confusing and there is a lot of maths going on here + * The gist of the problem is here: https://gist.github.com/nnnick/696cc9c55f4b0beb8fe9 + * + * Reaction: https://dl.dropboxusercontent.com/u/34601363/toomuchscience.gif + * + * Solution: + * + * We assume the radius of the polygon is half the size of the canvas at first + * at each index we check if the text overlaps. + * + * Where it does, we store that angle and that index. + * + * After finding the largest index and angle we calculate how much we need to remove + * from the shape radius to move the point inwards by that x. + * + * We average the left and right distances to get the maximum shape radius that can fit in the box + * along with labels. + * + * Once we have that, we can find the centre point for the chart, by taking the x text protrusion + * on each side, removing that from the size, halving it and adding the left x protrusion width. + * + * This will mean we have a shape fitted to the canvas, as large as it can be with the labels + * and position it in the most space efficient manner + * + * https://dl.dropboxusercontent.com/u/34601363/yeahscience.gif + */ + + + // Get maximum radius of the polygon. Either half the height (minus the text width) or half the width. + // Use this to calculate the offset + change. - Make sure L/R protrusion is at least 0 to stop issues with centre points + var largestPossibleRadius = min([(this.height/2 - this.pointLabelFontSize - 5), this.width/2]), + pointPosition, + i, + textWidth, + halfTextWidth, + furthestRight = this.width, + furthestRightIndex, + furthestRightAngle, + furthestLeft = 0, + furthestLeftIndex, + furthestLeftAngle, + xProtrusionLeft, + xProtrusionRight, + radiusReductionRight, + radiusReductionLeft, + maxWidthRadius; + this.ctx.font = fontString(this.pointLabelFontSize,this.pointLabelFontStyle,this.pointLabelFontFamily); + for (i=0;i furthestRight) { + furthestRight = pointPosition.x + halfTextWidth; + furthestRightIndex = i; + } + if (pointPosition.x - halfTextWidth < furthestLeft) { + furthestLeft = pointPosition.x - halfTextWidth; + furthestLeftIndex = i; + } + } + else if (i < this.valuesCount/2) { + // Less than half the values means we'll left align the text + if (pointPosition.x + textWidth > furthestRight) { + furthestRight = pointPosition.x + textWidth; + furthestRightIndex = i; + } + } + else if (i > this.valuesCount/2){ + // More than half the values means we'll right align the text + if (pointPosition.x - textWidth < furthestLeft) { + furthestLeft = pointPosition.x - textWidth; + furthestLeftIndex = i; + } + } + } + + xProtrusionLeft = furthestLeft; + + xProtrusionRight = Math.ceil(furthestRight - this.width); + + furthestRightAngle = this.getIndexAngle(furthestRightIndex); + + furthestLeftAngle = this.getIndexAngle(furthestLeftIndex); + + radiusReductionRight = xProtrusionRight / Math.sin(furthestRightAngle + Math.PI/2); + + radiusReductionLeft = xProtrusionLeft / Math.sin(furthestLeftAngle + Math.PI/2); + + // Ensure we actually need to reduce the size of the chart + radiusReductionRight = (isNumber(radiusReductionRight)) ? radiusReductionRight : 0; + radiusReductionLeft = (isNumber(radiusReductionLeft)) ? radiusReductionLeft : 0; + + this.drawingArea = largestPossibleRadius - (radiusReductionLeft + radiusReductionRight)/2; + + //this.drawingArea = min([maxWidthRadius, (this.height - (2 * (this.pointLabelFontSize + 5)))/2]) + this.setCenterPoint(radiusReductionLeft, radiusReductionRight); + + }, + setCenterPoint: function(leftMovement, rightMovement){ + + var maxRight = this.width - rightMovement - this.drawingArea, + maxLeft = leftMovement + this.drawingArea; + + this.xCenter = (maxLeft + maxRight)/2; + // Always vertically in the centre as the text height doesn't change + this.yCenter = (this.height/2); + }, + + getIndexAngle : function(index){ + var angleMultiplier = (Math.PI * 2) / this.valuesCount; + // Start from the top instead of right, so remove a quarter of the circle + + return index * angleMultiplier - (Math.PI/2); + }, + getPointPosition : function(index, distanceFromCenter){ + var thisAngle = this.getIndexAngle(index); + return { + x : (Math.cos(thisAngle) * distanceFromCenter) + this.xCenter, + y : (Math.sin(thisAngle) * distanceFromCenter) + this.yCenter + }; + }, + draw: function(){ + if (this.display){ + var ctx = this.ctx; + each(this.yLabels, function(label, index){ + // Don't draw a centre value + if (index > 0){ + var yCenterOffset = index * (this.drawingArea/this.steps), + yHeight = this.yCenter - yCenterOffset, + pointPosition; + + // Draw circular lines around the scale + if (this.lineWidth > 0){ + ctx.strokeStyle = this.lineColor; + ctx.lineWidth = this.lineWidth; + + if(this.lineArc){ + ctx.beginPath(); + ctx.arc(this.xCenter, this.yCenter, yCenterOffset, 0, Math.PI*2); + ctx.closePath(); + ctx.stroke(); + } else{ + ctx.beginPath(); + for (var i=0;i= 0; i--) { + if (this.angleLineWidth > 0){ + var outerPosition = this.getPointPosition(i, this.calculateCenterOffset(this.max)); + ctx.beginPath(); + ctx.moveTo(this.xCenter, this.yCenter); + ctx.lineTo(outerPosition.x, outerPosition.y); + ctx.stroke(); + ctx.closePath(); + } + // Extra 3px out for some label spacing + var pointLabelPosition = this.getPointPosition(i, this.calculateCenterOffset(this.max) + 5); + ctx.font = fontString(this.pointLabelFontSize,this.pointLabelFontStyle,this.pointLabelFontFamily); + ctx.fillStyle = this.pointLabelFontColor; + + var labelsCount = this.labels.length, + halfLabelsCount = this.labels.length/2, + quarterLabelsCount = halfLabelsCount/2, + upperHalf = (i < quarterLabelsCount || i > labelsCount - quarterLabelsCount), + exactQuarter = (i === quarterLabelsCount || i === labelsCount - quarterLabelsCount); + if (i === 0){ + ctx.textAlign = 'center'; + } else if(i === halfLabelsCount){ + ctx.textAlign = 'center'; + } else if (i < halfLabelsCount){ + ctx.textAlign = 'left'; + } else { + ctx.textAlign = 'right'; + } + + // Set the correct text baseline based on outer positioning + if (exactQuarter){ + ctx.textBaseline = 'middle'; + } else if (upperHalf){ + ctx.textBaseline = 'bottom'; + } else { + ctx.textBaseline = 'top'; + } + + ctx.fillText(this.labels[i], pointLabelPosition.x, pointLabelPosition.y); + } + } + } + } + }); + + // Attach global event to resize each chart instance when the browser resizes + helpers.addEvent(window, "resize", (function(){ + // Basic debounce of resize function so it doesn't hurt performance when resizing browser. + var timeout; + return function(){ + clearTimeout(timeout); + timeout = setTimeout(function(){ + each(Chart.instances,function(instance){ + // If the responsive flag is set in the chart instance config + // Cascade the resize event down to the chart. + if (instance.options.responsive){ + instance.resize(instance.render, true); + } + }); + }, 50); + }; + })()); + + + if (amd) { + define(function(){ + return Chart; + }); + } else if (typeof module === 'object' && module.exports) { + module.exports = Chart; + } + + root.Chart = Chart; + + Chart.noConflict = function(){ + root.Chart = previous; + return Chart; + }; + +}).call(this); + +(function(){ + "use strict"; + + var root = this, + Chart = root.Chart, + helpers = Chart.helpers; + + + var defaultConfig = { + //Boolean - Whether the scale should start at zero, or an order of magnitude down from the lowest value + scaleBeginAtZero : true, + + //Boolean - Whether grid lines are shown across the chart + scaleShowGridLines : true, + + //String - Colour of the grid lines + scaleGridLineColor : "rgba(0,0,0,.05)", + + //Number - Width of the grid lines + scaleGridLineWidth : 1, + + //Boolean - Whether to show horizontal lines (except X axis) + scaleShowHorizontalLines: true, + + //Boolean - Whether to show vertical lines (except Y axis) + scaleShowVerticalLines: true, + + //Boolean - If there is a stroke on each bar + barShowStroke : true, + + //Number - Pixel width of the bar stroke + barStrokeWidth : 2, + + //Number - Spacing between each of the X value sets + barValueSpacing : 5, + + //Number - Spacing between data sets within X values + barDatasetSpacing : 1, + + //String - A legend template + legendTemplate : "
    -legend\"><% for (var i=0; i
  • \"><%if(datasets[i].label){%><%=datasets[i].label%><%}%>
  • <%}%>
" + + }; + + + Chart.Type.extend({ + name: "Bar", + defaults : defaultConfig, + initialize: function(data){ + + //Expose options as a scope variable here so we can access it in the ScaleClass + var options = this.options; + + this.ScaleClass = Chart.Scale.extend({ + offsetGridLines : true, + calculateBarX : function(datasetCount, datasetIndex, barIndex){ + //Reusable method for calculating the xPosition of a given bar based on datasetIndex & width of the bar + var xWidth = this.calculateBaseWidth(), + xAbsolute = this.calculateX(barIndex) - (xWidth/2), + barWidth = this.calculateBarWidth(datasetCount); + + return xAbsolute + (barWidth * datasetIndex) + (datasetIndex * options.barDatasetSpacing) + barWidth/2; + }, + calculateBaseWidth : function(){ + return (this.calculateX(1) - this.calculateX(0)) - (2*options.barValueSpacing); + }, + calculateBarWidth : function(datasetCount){ + //The padding between datasets is to the right of each bar, providing that there are more than 1 dataset + var baseWidth = this.calculateBaseWidth() - ((datasetCount - 1) * options.barDatasetSpacing); + + return (baseWidth / datasetCount); + } + }); + + this.datasets = []; + + //Set up tooltip events on the chart + if (this.options.showTooltips){ + helpers.bindEvents(this, this.options.tooltipEvents, function(evt){ + var activeBars = (evt.type !== 'mouseout') ? this.getBarsAtEvent(evt) : []; + + this.eachBars(function(bar){ + bar.restore(['fillColor', 'strokeColor']); + }); + helpers.each(activeBars, function(activeBar){ + activeBar.fillColor = activeBar.highlightFill; + activeBar.strokeColor = activeBar.highlightStroke; + }); + this.showTooltip(activeBars); + }); + } + + //Declare the extension of the default point, to cater for the options passed in to the constructor + this.BarClass = Chart.Rectangle.extend({ + strokeWidth : this.options.barStrokeWidth, + showStroke : this.options.barShowStroke, + ctx : this.chart.ctx + }); + + //Iterate through each of the datasets, and build this into a property of the chart + helpers.each(data.datasets,function(dataset,datasetIndex){ + + var datasetObject = { + label : dataset.label || null, + fillColor : dataset.fillColor, + strokeColor : dataset.strokeColor, + bars : [] + }; + + this.datasets.push(datasetObject); + + helpers.each(dataset.data,function(dataPoint,index){ + //Add a new point for each piece of data, passing any required data to draw. + datasetObject.bars.push(new this.BarClass({ + value : dataPoint, + label : data.labels[index], + datasetLabel: dataset.label, + strokeColor : dataset.strokeColor, + fillColor : dataset.fillColor, + highlightFill : dataset.highlightFill || dataset.fillColor, + highlightStroke : dataset.highlightStroke || dataset.strokeColor + })); + },this); + + },this); + + this.buildScale(data.labels); + + this.BarClass.prototype.base = this.scale.endPoint; + + this.eachBars(function(bar, index, datasetIndex){ + helpers.extend(bar, { + width : this.scale.calculateBarWidth(this.datasets.length), + x: this.scale.calculateBarX(this.datasets.length, datasetIndex, index), + y: this.scale.endPoint + }); + bar.save(); + }, this); + + this.render(); + }, + update : function(){ + this.scale.update(); + // Reset any highlight colours before updating. + helpers.each(this.activeElements, function(activeElement){ + activeElement.restore(['fillColor', 'strokeColor']); + }); + + this.eachBars(function(bar){ + bar.save(); + }); + this.render(); + }, + eachBars : function(callback){ + helpers.each(this.datasets,function(dataset, datasetIndex){ + helpers.each(dataset.bars, callback, this, datasetIndex); + },this); + }, + getBarsAtEvent : function(e){ + var barsArray = [], + eventPosition = helpers.getRelativePosition(e), + datasetIterator = function(dataset){ + barsArray.push(dataset.bars[barIndex]); + }, + barIndex; + + for (var datasetIndex = 0; datasetIndex < this.datasets.length; datasetIndex++) { + for (barIndex = 0; barIndex < this.datasets[datasetIndex].bars.length; barIndex++) { + if (this.datasets[datasetIndex].bars[barIndex].inRange(eventPosition.x,eventPosition.y)){ + helpers.each(this.datasets, datasetIterator); + return barsArray; + } + } + } + + return barsArray; + }, + buildScale : function(labels){ + var self = this; + + var dataTotal = function(){ + var values = []; + self.eachBars(function(bar){ + values.push(bar.value); + }); + return values; + }; + + var scaleOptions = { + templateString : this.options.scaleLabel, + height : this.chart.height, + width : this.chart.width, + ctx : this.chart.ctx, + textColor : this.options.scaleFontColor, + fontSize : this.options.scaleFontSize, + fontStyle : this.options.scaleFontStyle, + fontFamily : this.options.scaleFontFamily, + valuesCount : labels.length, + beginAtZero : this.options.scaleBeginAtZero, + integersOnly : this.options.scaleIntegersOnly, + calculateYRange: function(currentHeight){ + var updatedRanges = helpers.calculateScaleRange( + dataTotal(), + currentHeight, + this.fontSize, + this.beginAtZero, + this.integersOnly + ); + helpers.extend(this, updatedRanges); + }, + xLabels : labels, + font : helpers.fontString(this.options.scaleFontSize, this.options.scaleFontStyle, this.options.scaleFontFamily), + lineWidth : this.options.scaleLineWidth, + lineColor : this.options.scaleLineColor, + showHorizontalLines : this.options.scaleShowHorizontalLines, + showVerticalLines : this.options.scaleShowVerticalLines, + gridLineWidth : (this.options.scaleShowGridLines) ? this.options.scaleGridLineWidth : 0, + gridLineColor : (this.options.scaleShowGridLines) ? this.options.scaleGridLineColor : "rgba(0,0,0,0)", + padding : (this.options.showScale) ? 0 : (this.options.barShowStroke) ? this.options.barStrokeWidth : 0, + showLabels : this.options.scaleShowLabels, + display : this.options.showScale + }; + + if (this.options.scaleOverride){ + helpers.extend(scaleOptions, { + calculateYRange: helpers.noop, + steps: this.options.scaleSteps, + stepValue: this.options.scaleStepWidth, + min: this.options.scaleStartValue, + max: this.options.scaleStartValue + (this.options.scaleSteps * this.options.scaleStepWidth) + }); + } + + this.scale = new this.ScaleClass(scaleOptions); + }, + addData : function(valuesArray,label){ + //Map the values array for each of the datasets + helpers.each(valuesArray,function(value,datasetIndex){ + //Add a new point for each piece of data, passing any required data to draw. + this.datasets[datasetIndex].bars.push(new this.BarClass({ + value : value, + label : label, + x: this.scale.calculateBarX(this.datasets.length, datasetIndex, this.scale.valuesCount+1), + y: this.scale.endPoint, + width : this.scale.calculateBarWidth(this.datasets.length), + base : this.scale.endPoint, + strokeColor : this.datasets[datasetIndex].strokeColor, + fillColor : this.datasets[datasetIndex].fillColor + })); + },this); + + this.scale.addXLabel(label); + //Then re-render the chart. + this.update(); + }, + removeData : function(){ + this.scale.removeXLabel(); + //Then re-render the chart. + helpers.each(this.datasets,function(dataset){ + dataset.bars.shift(); + },this); + this.update(); + }, + reflow : function(){ + helpers.extend(this.BarClass.prototype,{ + y: this.scale.endPoint, + base : this.scale.endPoint + }); + var newScaleProps = helpers.extend({ + height : this.chart.height, + width : this.chart.width + }); + this.scale.update(newScaleProps); + }, + draw : function(ease){ + var easingDecimal = ease || 1; + this.clear(); + + var ctx = this.chart.ctx; + + this.scale.draw(easingDecimal); + + //Draw all the bars for each dataset + helpers.each(this.datasets,function(dataset,datasetIndex){ + helpers.each(dataset.bars,function(bar,index){ + if (bar.hasValue()){ + bar.base = this.scale.endPoint; + //Transition then draw + bar.transition({ + x : this.scale.calculateBarX(this.datasets.length, datasetIndex, index), + y : this.scale.calculateY(bar.value), + width : this.scale.calculateBarWidth(this.datasets.length) + }, easingDecimal).draw(); + } + },this); + + },this); + } + }); + + +}).call(this); + +(function(){ + "use strict"; + + var root = this, + Chart = root.Chart, + //Cache a local reference to Chart.helpers + helpers = Chart.helpers; + + var defaultConfig = { + //Boolean - Whether we should show a stroke on each segment + segmentShowStroke : true, + + //String - The colour of each segment stroke + segmentStrokeColor : "#fff", + + //Number - The width of each segment stroke + segmentStrokeWidth : 2, + + //The percentage of the chart that we cut out of the middle. + percentageInnerCutout : 50, + + //Number - Amount of animation steps + animationSteps : 100, + + //String - Animation easing effect + animationEasing : "easeOutBounce", + + //Boolean - Whether we animate the rotation of the Doughnut + animateRotate : true, + + //Boolean - Whether we animate scaling the Doughnut from the centre + animateScale : false, + + //String - A legend template + legendTemplate : "
    -legend\"><% for (var i=0; i
  • \"><%if(segments[i].label){%><%=segments[i].label%><%}%>
  • <%}%>
" + + }; + + + Chart.Type.extend({ + //Passing in a name registers this chart in the Chart namespace + name: "Doughnut", + //Providing a defaults will also register the deafults in the chart namespace + defaults : defaultConfig, + //Initialize is fired when the chart is initialized - Data is passed in as a parameter + //Config is automatically merged by the core of Chart.js, and is available at this.options + initialize: function(data){ + + //Declare segments as a static property to prevent inheriting across the Chart type prototype + this.segments = []; + this.outerRadius = (helpers.min([this.chart.width,this.chart.height]) - this.options.segmentStrokeWidth/2)/2; + + this.SegmentArc = Chart.Arc.extend({ + ctx : this.chart.ctx, + x : this.chart.width/2, + y : this.chart.height/2 + }); + + //Set up tooltip events on the chart + if (this.options.showTooltips){ + helpers.bindEvents(this, this.options.tooltipEvents, function(evt){ + var activeSegments = (evt.type !== 'mouseout') ? this.getSegmentsAtEvent(evt) : []; + + helpers.each(this.segments,function(segment){ + segment.restore(["fillColor"]); + }); + helpers.each(activeSegments,function(activeSegment){ + activeSegment.fillColor = activeSegment.highlightColor; + }); + this.showTooltip(activeSegments); + }); + } + this.calculateTotal(data); + + helpers.each(data,function(datapoint, index){ + this.addData(datapoint, index, true); + },this); + + this.render(); + }, + getSegmentsAtEvent : function(e){ + var segmentsArray = []; + + var location = helpers.getRelativePosition(e); + + helpers.each(this.segments,function(segment){ + if (segment.inRange(location.x,location.y)) segmentsArray.push(segment); + },this); + return segmentsArray; + }, + addData : function(segment, atIndex, silent){ + var index = atIndex || this.segments.length; + this.segments.splice(index, 0, new this.SegmentArc({ + value : segment.value, + outerRadius : (this.options.animateScale) ? 0 : this.outerRadius, + innerRadius : (this.options.animateScale) ? 0 : (this.outerRadius/100) * this.options.percentageInnerCutout, + fillColor : segment.color, + highlightColor : segment.highlight || segment.color, + showStroke : this.options.segmentShowStroke, + strokeWidth : this.options.segmentStrokeWidth, + strokeColor : this.options.segmentStrokeColor, + startAngle : Math.PI * 1.5, + circumference : (this.options.animateRotate) ? 0 : this.calculateCircumference(segment.value), + label : segment.label + })); + if (!silent){ + this.reflow(); + this.update(); + } + }, + calculateCircumference : function(value){ + return (Math.PI*2)*(Math.abs(value) / this.total); + }, + calculateTotal : function(data){ + this.total = 0; + helpers.each(data,function(segment){ + this.total += Math.abs(segment.value); + },this); + }, + update : function(){ + this.calculateTotal(this.segments); + + // Reset any highlight colours before updating. + helpers.each(this.activeElements, function(activeElement){ + activeElement.restore(['fillColor']); + }); + + helpers.each(this.segments,function(segment){ + segment.save(); + }); + this.render(); + }, + + removeData: function(atIndex){ + var indexToDelete = (helpers.isNumber(atIndex)) ? atIndex : this.segments.length-1; + this.segments.splice(indexToDelete, 1); + this.reflow(); + this.update(); + }, + + reflow : function(){ + helpers.extend(this.SegmentArc.prototype,{ + x : this.chart.width/2, + y : this.chart.height/2 + }); + this.outerRadius = (helpers.min([this.chart.width,this.chart.height]) - this.options.segmentStrokeWidth/2)/2; + helpers.each(this.segments, function(segment){ + segment.update({ + outerRadius : this.outerRadius, + innerRadius : (this.outerRadius/100) * this.options.percentageInnerCutout + }); + }, this); + }, + draw : function(easeDecimal){ + var animDecimal = (easeDecimal) ? easeDecimal : 1; + this.clear(); + helpers.each(this.segments,function(segment,index){ + segment.transition({ + circumference : this.calculateCircumference(segment.value), + outerRadius : this.outerRadius, + innerRadius : (this.outerRadius/100) * this.options.percentageInnerCutout + },animDecimal); + + segment.endAngle = segment.startAngle + segment.circumference; + + segment.draw(); + if (index === 0){ + segment.startAngle = Math.PI * 1.5; + } + //Check to see if it's the last segment, if not get the next and update the start angle + if (index < this.segments.length-1){ + this.segments[index+1].startAngle = segment.endAngle; + } + },this); + + } + }); + + Chart.types.Doughnut.extend({ + name : "Pie", + defaults : helpers.merge(defaultConfig,{percentageInnerCutout : 0}) + }); + +}).call(this); +(function(){ + "use strict"; + + var root = this, + Chart = root.Chart, + helpers = Chart.helpers; + + var defaultConfig = { + + ///Boolean - Whether grid lines are shown across the chart + scaleShowGridLines : true, + + //String - Colour of the grid lines + scaleGridLineColor : "rgba(0,0,0,.05)", + + //Number - Width of the grid lines + scaleGridLineWidth : 1, + + //Boolean - Whether to show horizontal lines (except X axis) + scaleShowHorizontalLines: true, + + //Boolean - Whether to show vertical lines (except Y axis) + scaleShowVerticalLines: true, + + //Boolean - Whether the line is curved between points + bezierCurve : true, + + //Number - Tension of the bezier curve between points + bezierCurveTension : 0.4, + + //Boolean - Whether to show a dot for each point + pointDot : true, + + //Number - Radius of each point dot in pixels + pointDotRadius : 4, + + //Number - Pixel width of point dot stroke + pointDotStrokeWidth : 1, + + //Number - amount extra to add to the radius to cater for hit detection outside the drawn point + pointHitDetectionRadius : 20, + + //Boolean - Whether to show a stroke for datasets + datasetStroke : true, + + //Number - Pixel width of dataset stroke + datasetStrokeWidth : 2, + + //Boolean - Whether to fill the dataset with a colour + datasetFill : true, + + //String - A legend template + legendTemplate : "
    -legend\"><% for (var i=0; i
  • \"><%if(datasets[i].label){%><%=datasets[i].label%><%}%>
  • <%}%>
" + + }; + + + Chart.Type.extend({ + name: "Line", + defaults : defaultConfig, + initialize: function(data){ + //Declare the extension of the default point, to cater for the options passed in to the constructor + this.PointClass = Chart.Point.extend({ + strokeWidth : this.options.pointDotStrokeWidth, + radius : this.options.pointDotRadius, + display: this.options.pointDot, + hitDetectionRadius : this.options.pointHitDetectionRadius, + ctx : this.chart.ctx, + inRange : function(mouseX){ + return (Math.pow(mouseX-this.x, 2) < Math.pow(this.radius + this.hitDetectionRadius,2)); + } + }); + + this.datasets = []; + + //Set up tooltip events on the chart + if (this.options.showTooltips){ + helpers.bindEvents(this, this.options.tooltipEvents, function(evt){ + var activePoints = (evt.type !== 'mouseout') ? this.getPointsAtEvent(evt) : []; + this.eachPoints(function(point){ + point.restore(['fillColor', 'strokeColor']); + }); + helpers.each(activePoints, function(activePoint){ + activePoint.fillColor = activePoint.highlightFill; + activePoint.strokeColor = activePoint.highlightStroke; + }); + this.showTooltip(activePoints); + }); + } + + //Iterate through each of the datasets, and build this into a property of the chart + helpers.each(data.datasets,function(dataset){ + + var datasetObject = { + label : dataset.label || null, + fillColor : dataset.fillColor, + strokeColor : dataset.strokeColor, + pointColor : dataset.pointColor, + pointStrokeColor : dataset.pointStrokeColor, + points : [] + }; + + this.datasets.push(datasetObject); + + + helpers.each(dataset.data,function(dataPoint,index){ + //Add a new point for each piece of data, passing any required data to draw. + datasetObject.points.push(new this.PointClass({ + value : dataPoint, + label : data.labels[index], + datasetLabel: dataset.label, + strokeColor : dataset.pointStrokeColor, + fillColor : dataset.pointColor, + highlightFill : dataset.pointHighlightFill || dataset.pointColor, + highlightStroke : dataset.pointHighlightStroke || dataset.pointStrokeColor + })); + },this); + + this.buildScale(data.labels); + + + this.eachPoints(function(point, index){ + helpers.extend(point, { + x: this.scale.calculateX(index), + y: this.scale.endPoint + }); + point.save(); + }, this); + + },this); + + + this.render(); + }, + update : function(){ + this.scale.update(); + // Reset any highlight colours before updating. + helpers.each(this.activeElements, function(activeElement){ + activeElement.restore(['fillColor', 'strokeColor']); + }); + this.eachPoints(function(point){ + point.save(); + }); + this.render(); + }, + eachPoints : function(callback){ + helpers.each(this.datasets,function(dataset){ + helpers.each(dataset.points,callback,this); + },this); + }, + getPointsAtEvent : function(e){ + var pointsArray = [], + eventPosition = helpers.getRelativePosition(e); + helpers.each(this.datasets,function(dataset){ + helpers.each(dataset.points,function(point){ + if (point.inRange(eventPosition.x,eventPosition.y)) pointsArray.push(point); + }); + },this); + return pointsArray; + }, + buildScale : function(labels){ + var self = this; + + var dataTotal = function(){ + var values = []; + self.eachPoints(function(point){ + values.push(point.value); + }); + + return values; + }; + + var scaleOptions = { + templateString : this.options.scaleLabel, + height : this.chart.height, + width : this.chart.width, + ctx : this.chart.ctx, + textColor : this.options.scaleFontColor, + fontSize : this.options.scaleFontSize, + fontStyle : this.options.scaleFontStyle, + fontFamily : this.options.scaleFontFamily, + valuesCount : labels.length, + beginAtZero : this.options.scaleBeginAtZero, + integersOnly : this.options.scaleIntegersOnly, + calculateYRange : function(currentHeight){ + var updatedRanges = helpers.calculateScaleRange( + dataTotal(), + currentHeight, + this.fontSize, + this.beginAtZero, + this.integersOnly + ); + helpers.extend(this, updatedRanges); + }, + xLabels : labels, + font : helpers.fontString(this.options.scaleFontSize, this.options.scaleFontStyle, this.options.scaleFontFamily), + lineWidth : this.options.scaleLineWidth, + lineColor : this.options.scaleLineColor, + showHorizontalLines : this.options.scaleShowHorizontalLines, + showVerticalLines : this.options.scaleShowVerticalLines, + gridLineWidth : (this.options.scaleShowGridLines) ? this.options.scaleGridLineWidth : 0, + gridLineColor : (this.options.scaleShowGridLines) ? this.options.scaleGridLineColor : "rgba(0,0,0,0)", + padding: (this.options.showScale) ? 0 : this.options.pointDotRadius + this.options.pointDotStrokeWidth, + showLabels : this.options.scaleShowLabels, + display : this.options.showScale + }; + + if (this.options.scaleOverride){ + helpers.extend(scaleOptions, { + calculateYRange: helpers.noop, + steps: this.options.scaleSteps, + stepValue: this.options.scaleStepWidth, + min: this.options.scaleStartValue, + max: this.options.scaleStartValue + (this.options.scaleSteps * this.options.scaleStepWidth) + }); + } + + + this.scale = new Chart.Scale(scaleOptions); + }, + addData : function(valuesArray,label){ + //Map the values array for each of the datasets + + helpers.each(valuesArray,function(value,datasetIndex){ + //Add a new point for each piece of data, passing any required data to draw. + this.datasets[datasetIndex].points.push(new this.PointClass({ + value : value, + label : label, + x: this.scale.calculateX(this.scale.valuesCount+1), + y: this.scale.endPoint, + strokeColor : this.datasets[datasetIndex].pointStrokeColor, + fillColor : this.datasets[datasetIndex].pointColor + })); + },this); + + this.scale.addXLabel(label); + //Then re-render the chart. + this.update(); + }, + removeData : function(){ + this.scale.removeXLabel(); + //Then re-render the chart. + helpers.each(this.datasets,function(dataset){ + dataset.points.shift(); + },this); + this.update(); + }, + reflow : function(){ + var newScaleProps = helpers.extend({ + height : this.chart.height, + width : this.chart.width + }); + this.scale.update(newScaleProps); + }, + draw : function(ease){ + var easingDecimal = ease || 1; + this.clear(); + + var ctx = this.chart.ctx; + + // Some helper methods for getting the next/prev points + var hasValue = function(item){ + return item.value !== null; + }, + nextPoint = function(point, collection, index){ + return helpers.findNextWhere(collection, hasValue, index) || point; + }, + previousPoint = function(point, collection, index){ + return helpers.findPreviousWhere(collection, hasValue, index) || point; + }; + + this.scale.draw(easingDecimal); + + + helpers.each(this.datasets,function(dataset){ + var pointsWithValues = helpers.where(dataset.points, hasValue); + + //Transition each point first so that the line and point drawing isn't out of sync + //We can use this extra loop to calculate the control points of this dataset also in this loop + + helpers.each(dataset.points, function(point, index){ + if (point.hasValue()){ + point.transition({ + y : this.scale.calculateY(point.value), + x : this.scale.calculateX(index) + }, easingDecimal); + } + },this); + + + // Control points need to be calculated in a seperate loop, because we need to know the current x/y of the point + // This would cause issues when there is no animation, because the y of the next point would be 0, so beziers would be skewed + if (this.options.bezierCurve){ + helpers.each(pointsWithValues, function(point, index){ + var tension = (index > 0 && index < pointsWithValues.length - 1) ? this.options.bezierCurveTension : 0; + point.controlPoints = helpers.splineCurve( + previousPoint(point, pointsWithValues, index), + point, + nextPoint(point, pointsWithValues, index), + tension + ); + + // Prevent the bezier going outside of the bounds of the graph + + // Cap puter bezier handles to the upper/lower scale bounds + if (point.controlPoints.outer.y > this.scale.endPoint){ + point.controlPoints.outer.y = this.scale.endPoint; + } + else if (point.controlPoints.outer.y < this.scale.startPoint){ + point.controlPoints.outer.y = this.scale.startPoint; + } + + // Cap inner bezier handles to the upper/lower scale bounds + if (point.controlPoints.inner.y > this.scale.endPoint){ + point.controlPoints.inner.y = this.scale.endPoint; + } + else if (point.controlPoints.inner.y < this.scale.startPoint){ + point.controlPoints.inner.y = this.scale.startPoint; + } + },this); + } + + + //Draw the line between all the points + ctx.lineWidth = this.options.datasetStrokeWidth; + ctx.strokeStyle = dataset.strokeColor; + ctx.beginPath(); + + helpers.each(pointsWithValues, function(point, index){ + if (index === 0){ + ctx.moveTo(point.x, point.y); + } + else{ + if(this.options.bezierCurve){ + var previous = previousPoint(point, pointsWithValues, index); + + ctx.bezierCurveTo( + previous.controlPoints.outer.x, + previous.controlPoints.outer.y, + point.controlPoints.inner.x, + point.controlPoints.inner.y, + point.x, + point.y + ); + } + else{ + ctx.lineTo(point.x,point.y); + } + } + }, this); + + ctx.stroke(); + + if (this.options.datasetFill && pointsWithValues.length > 0){ + //Round off the line by going to the base of the chart, back to the start, then fill. + ctx.lineTo(pointsWithValues[pointsWithValues.length - 1].x, this.scale.endPoint); + ctx.lineTo(pointsWithValues[0].x, this.scale.endPoint); + ctx.fillStyle = dataset.fillColor; + ctx.closePath(); + ctx.fill(); + } + + //Now draw the points over the line + //A little inefficient double looping, but better than the line + //lagging behind the point positions + helpers.each(pointsWithValues,function(point){ + point.draw(); + }); + },this); + } + }); + + +}).call(this); + +(function(){ + "use strict"; + + var root = this, + Chart = root.Chart, + //Cache a local reference to Chart.helpers + helpers = Chart.helpers; + + var defaultConfig = { + //Boolean - Show a backdrop to the scale label + scaleShowLabelBackdrop : true, + + //String - The colour of the label backdrop + scaleBackdropColor : "rgba(255,255,255,0.75)", + + // Boolean - Whether the scale should begin at zero + scaleBeginAtZero : true, + + //Number - The backdrop padding above & below the label in pixels + scaleBackdropPaddingY : 2, + + //Number - The backdrop padding to the side of the label in pixels + scaleBackdropPaddingX : 2, + + //Boolean - Show line for each value in the scale + scaleShowLine : true, + + //Boolean - Stroke a line around each segment in the chart + segmentShowStroke : true, + + //String - The colour of the stroke on each segement. + segmentStrokeColor : "#fff", + + //Number - The width of the stroke value in pixels + segmentStrokeWidth : 2, + + //Number - Amount of animation steps + animationSteps : 100, + + //String - Animation easing effect. + animationEasing : "easeOutBounce", + + //Boolean - Whether to animate the rotation of the chart + animateRotate : true, + + //Boolean - Whether to animate scaling the chart from the centre + animateScale : false, + + //String - A legend template + legendTemplate : "
    -legend\"><% for (var i=0; i
  • \"><%if(segments[i].label){%><%=segments[i].label%><%}%>
  • <%}%>
" + }; + + + Chart.Type.extend({ + //Passing in a name registers this chart in the Chart namespace + name: "PolarArea", + //Providing a defaults will also register the deafults in the chart namespace + defaults : defaultConfig, + //Initialize is fired when the chart is initialized - Data is passed in as a parameter + //Config is automatically merged by the core of Chart.js, and is available at this.options + initialize: function(data){ + this.segments = []; + //Declare segment class as a chart instance specific class, so it can share props for this instance + this.SegmentArc = Chart.Arc.extend({ + showStroke : this.options.segmentShowStroke, + strokeWidth : this.options.segmentStrokeWidth, + strokeColor : this.options.segmentStrokeColor, + ctx : this.chart.ctx, + innerRadius : 0, + x : this.chart.width/2, + y : this.chart.height/2 + }); + this.scale = new Chart.RadialScale({ + display: this.options.showScale, + fontStyle: this.options.scaleFontStyle, + fontSize: this.options.scaleFontSize, + fontFamily: this.options.scaleFontFamily, + fontColor: this.options.scaleFontColor, + showLabels: this.options.scaleShowLabels, + showLabelBackdrop: this.options.scaleShowLabelBackdrop, + backdropColor: this.options.scaleBackdropColor, + backdropPaddingY : this.options.scaleBackdropPaddingY, + backdropPaddingX: this.options.scaleBackdropPaddingX, + lineWidth: (this.options.scaleShowLine) ? this.options.scaleLineWidth : 0, + lineColor: this.options.scaleLineColor, + lineArc: true, + width: this.chart.width, + height: this.chart.height, + xCenter: this.chart.width/2, + yCenter: this.chart.height/2, + ctx : this.chart.ctx, + templateString: this.options.scaleLabel, + valuesCount: data.length + }); + + this.updateScaleRange(data); + + this.scale.update(); + + helpers.each(data,function(segment,index){ + this.addData(segment,index,true); + },this); + + //Set up tooltip events on the chart + if (this.options.showTooltips){ + helpers.bindEvents(this, this.options.tooltipEvents, function(evt){ + var activeSegments = (evt.type !== 'mouseout') ? this.getSegmentsAtEvent(evt) : []; + helpers.each(this.segments,function(segment){ + segment.restore(["fillColor"]); + }); + helpers.each(activeSegments,function(activeSegment){ + activeSegment.fillColor = activeSegment.highlightColor; + }); + this.showTooltip(activeSegments); + }); + } + + this.render(); + }, + getSegmentsAtEvent : function(e){ + var segmentsArray = []; + + var location = helpers.getRelativePosition(e); + + helpers.each(this.segments,function(segment){ + if (segment.inRange(location.x,location.y)) segmentsArray.push(segment); + },this); + return segmentsArray; + }, + addData : function(segment, atIndex, silent){ + var index = atIndex || this.segments.length; + + this.segments.splice(index, 0, new this.SegmentArc({ + fillColor: segment.color, + highlightColor: segment.highlight || segment.color, + label: segment.label, + value: segment.value, + outerRadius: (this.options.animateScale) ? 0 : this.scale.calculateCenterOffset(segment.value), + circumference: (this.options.animateRotate) ? 0 : this.scale.getCircumference(), + startAngle: Math.PI * 1.5 + })); + if (!silent){ + this.reflow(); + this.update(); + } + }, + removeData: function(atIndex){ + var indexToDelete = (helpers.isNumber(atIndex)) ? atIndex : this.segments.length-1; + this.segments.splice(indexToDelete, 1); + this.reflow(); + this.update(); + }, + calculateTotal: function(data){ + this.total = 0; + helpers.each(data,function(segment){ + this.total += segment.value; + },this); + this.scale.valuesCount = this.segments.length; + }, + updateScaleRange: function(datapoints){ + var valuesArray = []; + helpers.each(datapoints,function(segment){ + valuesArray.push(segment.value); + }); + + var scaleSizes = (this.options.scaleOverride) ? + { + steps: this.options.scaleSteps, + stepValue: this.options.scaleStepWidth, + min: this.options.scaleStartValue, + max: this.options.scaleStartValue + (this.options.scaleSteps * this.options.scaleStepWidth) + } : + helpers.calculateScaleRange( + valuesArray, + helpers.min([this.chart.width, this.chart.height])/2, + this.options.scaleFontSize, + this.options.scaleBeginAtZero, + this.options.scaleIntegersOnly + ); + + helpers.extend( + this.scale, + scaleSizes, + { + size: helpers.min([this.chart.width, this.chart.height]), + xCenter: this.chart.width/2, + yCenter: this.chart.height/2 + } + ); + + }, + update : function(){ + this.calculateTotal(this.segments); + + helpers.each(this.segments,function(segment){ + segment.save(); + }); + + this.reflow(); + this.render(); + }, + reflow : function(){ + helpers.extend(this.SegmentArc.prototype,{ + x : this.chart.width/2, + y : this.chart.height/2 + }); + this.updateScaleRange(this.segments); + this.scale.update(); + + helpers.extend(this.scale,{ + xCenter: this.chart.width/2, + yCenter: this.chart.height/2 + }); + + helpers.each(this.segments, function(segment){ + segment.update({ + outerRadius : this.scale.calculateCenterOffset(segment.value) + }); + }, this); + + }, + draw : function(ease){ + var easingDecimal = ease || 1; + //Clear & draw the canvas + this.clear(); + helpers.each(this.segments,function(segment, index){ + segment.transition({ + circumference : this.scale.getCircumference(), + outerRadius : this.scale.calculateCenterOffset(segment.value) + },easingDecimal); + + segment.endAngle = segment.startAngle + segment.circumference; + + // If we've removed the first segment we need to set the first one to + // start at the top. + if (index === 0){ + segment.startAngle = Math.PI * 1.5; + } + + //Check to see if it's the last segment, if not get the next and update the start angle + if (index < this.segments.length - 1){ + this.segments[index+1].startAngle = segment.endAngle; + } + segment.draw(); + }, this); + this.scale.draw(); + } + }); + +}).call(this); +(function(){ + "use strict"; + + var root = this, + Chart = root.Chart, + helpers = Chart.helpers; + + + + Chart.Type.extend({ + name: "Radar", + defaults:{ + //Boolean - Whether to show lines for each scale point + scaleShowLine : true, + + //Boolean - Whether we show the angle lines out of the radar + angleShowLineOut : true, + + //Boolean - Whether to show labels on the scale + scaleShowLabels : false, + + // Boolean - Whether the scale should begin at zero + scaleBeginAtZero : true, + + //String - Colour of the angle line + angleLineColor : "rgba(0,0,0,.1)", + + //Number - Pixel width of the angle line + angleLineWidth : 1, + + //String - Point label font declaration + pointLabelFontFamily : "'Arial'", + + //String - Point label font weight + pointLabelFontStyle : "normal", + + //Number - Point label font size in pixels + pointLabelFontSize : 10, + + //String - Point label font colour + pointLabelFontColor : "#666", + + //Boolean - Whether to show a dot for each point + pointDot : true, + + //Number - Radius of each point dot in pixels + pointDotRadius : 3, + + //Number - Pixel width of point dot stroke + pointDotStrokeWidth : 1, + + //Number - amount extra to add to the radius to cater for hit detection outside the drawn point + pointHitDetectionRadius : 20, + + //Boolean - Whether to show a stroke for datasets + datasetStroke : true, + + //Number - Pixel width of dataset stroke + datasetStrokeWidth : 2, + + //Boolean - Whether to fill the dataset with a colour + datasetFill : true, + + //String - A legend template + legendTemplate : "
    -legend\"><% for (var i=0; i
  • \"><%if(datasets[i].label){%><%=datasets[i].label%><%}%>
  • <%}%>
" + + }, + + initialize: function(data){ + this.PointClass = Chart.Point.extend({ + strokeWidth : this.options.pointDotStrokeWidth, + radius : this.options.pointDotRadius, + display: this.options.pointDot, + hitDetectionRadius : this.options.pointHitDetectionRadius, + ctx : this.chart.ctx + }); + + this.datasets = []; + + this.buildScale(data); + + //Set up tooltip events on the chart + if (this.options.showTooltips){ + helpers.bindEvents(this, this.options.tooltipEvents, function(evt){ + var activePointsCollection = (evt.type !== 'mouseout') ? this.getPointsAtEvent(evt) : []; + + this.eachPoints(function(point){ + point.restore(['fillColor', 'strokeColor']); + }); + helpers.each(activePointsCollection, function(activePoint){ + activePoint.fillColor = activePoint.highlightFill; + activePoint.strokeColor = activePoint.highlightStroke; + }); + + this.showTooltip(activePointsCollection); + }); + } + + //Iterate through each of the datasets, and build this into a property of the chart + helpers.each(data.datasets,function(dataset){ + + var datasetObject = { + label: dataset.label || null, + fillColor : dataset.fillColor, + strokeColor : dataset.strokeColor, + pointColor : dataset.pointColor, + pointStrokeColor : dataset.pointStrokeColor, + points : [] + }; + + this.datasets.push(datasetObject); + + helpers.each(dataset.data,function(dataPoint,index){ + //Add a new point for each piece of data, passing any required data to draw. + var pointPosition; + if (!this.scale.animation){ + pointPosition = this.scale.getPointPosition(index, this.scale.calculateCenterOffset(dataPoint)); + } + datasetObject.points.push(new this.PointClass({ + value : dataPoint, + label : data.labels[index], + datasetLabel: dataset.label, + x: (this.options.animation) ? this.scale.xCenter : pointPosition.x, + y: (this.options.animation) ? this.scale.yCenter : pointPosition.y, + strokeColor : dataset.pointStrokeColor, + fillColor : dataset.pointColor, + highlightFill : dataset.pointHighlightFill || dataset.pointColor, + highlightStroke : dataset.pointHighlightStroke || dataset.pointStrokeColor + })); + },this); + + },this); + + this.render(); + }, + eachPoints : function(callback){ + helpers.each(this.datasets,function(dataset){ + helpers.each(dataset.points,callback,this); + },this); + }, + + getPointsAtEvent : function(evt){ + var mousePosition = helpers.getRelativePosition(evt), + fromCenter = helpers.getAngleFromPoint({ + x: this.scale.xCenter, + y: this.scale.yCenter + }, mousePosition); + + var anglePerIndex = (Math.PI * 2) /this.scale.valuesCount, + pointIndex = Math.round((fromCenter.angle - Math.PI * 1.5) / anglePerIndex), + activePointsCollection = []; + + // If we're at the top, make the pointIndex 0 to get the first of the array. + if (pointIndex >= this.scale.valuesCount || pointIndex < 0){ + pointIndex = 0; + } + + if (fromCenter.distance <= this.scale.drawingArea){ + helpers.each(this.datasets, function(dataset){ + activePointsCollection.push(dataset.points[pointIndex]); + }); + } + + return activePointsCollection; + }, + + buildScale : function(data){ + this.scale = new Chart.RadialScale({ + display: this.options.showScale, + fontStyle: this.options.scaleFontStyle, + fontSize: this.options.scaleFontSize, + fontFamily: this.options.scaleFontFamily, + fontColor: this.options.scaleFontColor, + showLabels: this.options.scaleShowLabels, + showLabelBackdrop: this.options.scaleShowLabelBackdrop, + backdropColor: this.options.scaleBackdropColor, + backdropPaddingY : this.options.scaleBackdropPaddingY, + backdropPaddingX: this.options.scaleBackdropPaddingX, + lineWidth: (this.options.scaleShowLine) ? this.options.scaleLineWidth : 0, + lineColor: this.options.scaleLineColor, + angleLineColor : this.options.angleLineColor, + angleLineWidth : (this.options.angleShowLineOut) ? this.options.angleLineWidth : 0, + // Point labels at the edge of each line + pointLabelFontColor : this.options.pointLabelFontColor, + pointLabelFontSize : this.options.pointLabelFontSize, + pointLabelFontFamily : this.options.pointLabelFontFamily, + pointLabelFontStyle : this.options.pointLabelFontStyle, + height : this.chart.height, + width: this.chart.width, + xCenter: this.chart.width/2, + yCenter: this.chart.height/2, + ctx : this.chart.ctx, + templateString: this.options.scaleLabel, + labels: data.labels, + valuesCount: data.datasets[0].data.length + }); + + this.scale.setScaleSize(); + this.updateScaleRange(data.datasets); + this.scale.buildYLabels(); + }, + updateScaleRange: function(datasets){ + var valuesArray = (function(){ + var totalDataArray = []; + helpers.each(datasets,function(dataset){ + if (dataset.data){ + totalDataArray = totalDataArray.concat(dataset.data); + } + else { + helpers.each(dataset.points, function(point){ + totalDataArray.push(point.value); + }); + } + }); + return totalDataArray; + })(); + + + var scaleSizes = (this.options.scaleOverride) ? + { + steps: this.options.scaleSteps, + stepValue: this.options.scaleStepWidth, + min: this.options.scaleStartValue, + max: this.options.scaleStartValue + (this.options.scaleSteps * this.options.scaleStepWidth) + } : + helpers.calculateScaleRange( + valuesArray, + helpers.min([this.chart.width, this.chart.height])/2, + this.options.scaleFontSize, + this.options.scaleBeginAtZero, + this.options.scaleIntegersOnly + ); + + helpers.extend( + this.scale, + scaleSizes + ); + + }, + addData : function(valuesArray,label){ + //Map the values array for each of the datasets + this.scale.valuesCount++; + helpers.each(valuesArray,function(value,datasetIndex){ + var pointPosition = this.scale.getPointPosition(this.scale.valuesCount, this.scale.calculateCenterOffset(value)); + this.datasets[datasetIndex].points.push(new this.PointClass({ + value : value, + label : label, + x: pointPosition.x, + y: pointPosition.y, + strokeColor : this.datasets[datasetIndex].pointStrokeColor, + fillColor : this.datasets[datasetIndex].pointColor + })); + },this); + + this.scale.labels.push(label); + + this.reflow(); + + this.update(); + }, + removeData : function(){ + this.scale.valuesCount--; + this.scale.labels.shift(); + helpers.each(this.datasets,function(dataset){ + dataset.points.shift(); + },this); + this.reflow(); + this.update(); + }, + update : function(){ + this.eachPoints(function(point){ + point.save(); + }); + this.reflow(); + this.render(); + }, + reflow: function(){ + helpers.extend(this.scale, { + width : this.chart.width, + height: this.chart.height, + size : helpers.min([this.chart.width, this.chart.height]), + xCenter: this.chart.width/2, + yCenter: this.chart.height/2 + }); + this.updateScaleRange(this.datasets); + this.scale.setScaleSize(); + this.scale.buildYLabels(); + }, + draw : function(ease){ + var easeDecimal = ease || 1, + ctx = this.chart.ctx; + this.clear(); + this.scale.draw(); + + helpers.each(this.datasets,function(dataset){ + + //Transition each point first so that the line and point drawing isn't out of sync + helpers.each(dataset.points,function(point,index){ + if (point.hasValue()){ + point.transition(this.scale.getPointPosition(index, this.scale.calculateCenterOffset(point.value)), easeDecimal); + } + },this); + + + + //Draw the line between all the points + ctx.lineWidth = this.options.datasetStrokeWidth; + ctx.strokeStyle = dataset.strokeColor; + ctx.beginPath(); + helpers.each(dataset.points,function(point,index){ + if (index === 0){ + ctx.moveTo(point.x,point.y); + } + else{ + ctx.lineTo(point.x,point.y); + } + },this); + ctx.closePath(); + ctx.stroke(); + + ctx.fillStyle = dataset.fillColor; + ctx.fill(); + + //Now draw the points over the line + //A little inefficient double looping, but better than the line + //lagging behind the point positions + helpers.each(dataset.points,function(point){ + if (point.hasValue()){ + point.draw(); + } + }); + + },this); + + } + + }); + + + + + +}).call(this); \ No newline at end of file diff --git a/templates/js/libs/angular-chart.js-0.7.2/examples/app.css b/templates/js/libs/angular-chart.js-0.7.2/examples/app.css new file mode 100644 index 0000000..8b18814 --- /dev/null +++ b/templates/js/libs/angular-chart.js-0.7.2/examples/app.css @@ -0,0 +1,80 @@ +body { padding-top: 50px; } + +.nav, .pagination, .carousel, .panel-title a { cursor: pointer; } + +#hero-bar { + position: absolute; + left: 0; + top: 0; + z-index: 1; + padding-right: 0; +} + +.container-fluid { + padding-left: 0; + padding-right: 0; +} + +.aspect-ratio { + width: 100%; + padding-bottom: 25%; + position: relative; +} + +.header { + position: absolute; + left: 0; + width: 100%; + top: 50%; + font-size: larger; + z-index: 500; +} + +.panel-heading { + font-weight: bold; +} + +.code .nav-tabs>li.active>a, .code .nav-tabs>li.active>a:hover, .code .nav-tabs>li.active>a:focus { + background-color: #f8f8f8; + border: 1px solid #ccc; + border-bottom-color: transparent; +} + +.code pre, .code code { + background-color: #f8f8f8; + border-top: none; + border-top-left-radius: 0; + border-top-right-radius: 0; +} + +.settings > a, .settings { + background-color: white ! important; +} + +.nav-tabs > li > a { + border-bottom: 1px solid #ccc; + margin-right: 0; +} + +.settings > a.active { + border: 1px solid transparent; +} + +div.settings { + border: 1px solid #ccc; + border-top: 0; + padding: 9.5px; + margin: 0 0 10px +} + +div.settings > code { + border-top: 1px solid #eaeaea; +} + +.footer { + text-align: center; + padding: 30px 0; + margin-top: 70px; + border-top: 1px solid #e5e5e5; + background-color: #f5f5f5; +} \ No newline at end of file diff --git a/templates/js/libs/angular-chart.js-0.7.2/examples/app.js b/templates/js/libs/angular-chart.js-0.7.2/examples/app.js new file mode 100644 index 0000000..f0dc636 --- /dev/null +++ b/templates/js/libs/angular-chart.js-0.7.2/examples/app.js @@ -0,0 +1,185 @@ +(function () { + 'use strict'; + + var app = angular.module('examples', ['chart.js', 'ui.bootstrap']); + + app.config(function (ChartJsProvider) { + // Configure all charts + ChartJsProvider.setOptions({ + colours: ['#97BBCD', '#DCDCDC', '#F7464A', '#46BFBD', '#FDB45C', '#949FB1', '#4D5360'], + responsive: true + }); + // Configure all doughnut charts + ChartJsProvider.setOptions('Doughnut', { + animateScale: true + }); + }); + + app.controller('MenuCtrl', function ($scope) { + $scope.isCollapsed = true; + $scope.charts = ['Line', 'Bar', 'Doughnut', 'Pie', 'Polar Area', 'Radar', 'Base']; + }); + + app.controller('LineCtrl', ['$scope', '$timeout', function ($scope, $timeout) { + $scope.labels = ['January', 'February', 'March', 'April', 'May', 'June', 'July']; + $scope.series = ['Series A', 'Series B']; + $scope.data = [ + [65, 59, 80, 81, 56, 55, 40], + [28, 48, 40, 19, 86, 27, 90] + ]; + $scope.onClick = function (points, evt) { + console.log(points, evt); + }; + $scope.onHover = function (points) { + if (points.length > 0) { + console.log('Point', points[0].value); + } else { + console.log('No point'); + } + }; + + $timeout(function () { + $scope.labels = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday']; + $scope.data = [ + [28, 48, 40, 19, 86, 27, 90], + [65, 59, 80, 81, 56, 55, 40] + ]; + $scope.series = ['Series C', 'Series D']; + }, 3000); + }]); + + app.controller('BarCtrl', ['$scope', '$timeout', function ($scope, $timeout) { + $scope.options = { scaleShowVerticalLines: false }; + $scope.labels = ['2006', '2007', '2008', '2009', '2010', '2011', '2012']; + $scope.series = ['Series A', 'Series B']; + $scope.data = [ + [65, 59, 80, 81, 56, 55, 40], + [28, 48, 40, 19, 86, 27, 90] + ]; + $timeout(function () { + $scope.options = { scaleShowVerticalLines: true }; + }, 3000); + }]); + + app.controller('DoughnutCtrl', ['$scope', '$timeout', function ($scope, $timeout) { + $scope.labels = ['Download Sales', 'In-Store Sales', 'Mail-Order Sales']; + $scope.data = [0, 0, 0]; + + $timeout(function () { + $scope.data = [350, 450, 100]; + }, 500); + }]); + + app.controller('PieCtrl', function ($scope) { + $scope.labels = ['Download Sales', 'In-Store Sales', 'Mail Sales']; + $scope.data = [300, 500, 100]; + }); + + app.controller('PolarAreaCtrl', function ($scope) { + $scope.labels = ['Download Sales', 'In-Store Sales', 'Mail Sales', 'Telesales', 'Corporate Sales']; + $scope.data = [300, 500, 100, 40, 120]; + }); + + app.controller('BaseCtrl', function ($scope) { + $scope.labels = ['Download Sales', 'Store Sales', 'Mail Sales', 'Telesales', 'Corporate Sales']; + $scope.data = [300, 500, 100, 40, 120]; + $scope.type = 'PolarArea'; + + $scope.toggle = function () { + $scope.type = $scope.type === 'PolarArea' ? 'Pie' : 'PolarArea'; + }; + }); + + app.controller('RadarCtrl', function ($scope) { + $scope.labels = ['Eating', 'Drinking', 'Sleeping', 'Designing', 'Coding', 'Cycling', 'Running']; + + $scope.data = [ + [65, 59, 90, 81, 56, 55, 40], + [28, 48, 40, 19, 96, 27, 100] + ]; + + $scope.onClick = function (points, evt) { + console.log(points, evt); + }; + }); + + app.controller('StackedBarCtrl', function ($scope) { + $scope.labels = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday']; + $scope.type = 'StackedBar'; + + $scope.data = [ + [65, 59, 90, 81, 56, 55, 40], + [28, 48, 40, 19, 96, 27, 100] + ]; + }); + + app.controller('DataTablesCtrl', function ($scope) { + $scope.labels = ['January', 'February', 'March', 'April', 'May', 'June', 'July']; + $scope.data = [ + [65, 59, 80, 81, 56, 55, 40], + [28, 48, 40, 19, 86, 27, 90] + ]; + $scope.colours = [ + { // grey + fillColor: 'rgba(148,159,177,0.2)', + strokeColor: 'rgba(148,159,177,1)', + pointColor: 'rgba(148,159,177,1)', + pointStrokeColor: '#fff', + pointHighlightFill: '#fff', + pointHighlightStroke: 'rgba(148,159,177,0.8)' + }, + { // dark grey + fillColor: 'rgba(77,83,96,0.2)', + strokeColor: 'rgba(77,83,96,1)', + pointColor: 'rgba(77,83,96,1)', + pointStrokeColor: '#fff', + pointHighlightFill: '#fff', + pointHighlightStroke: 'rgba(77,83,96,1)' + } + ]; + $scope.randomize = function () { + $scope.data = $scope.data.map(function (data) { + return data.map(function (y) { + y = y + Math.random() * 10 - 5; + return parseInt(y < 0 ? 0 : y > 100 ? 100 : y); + }); + }); + }; + }); + + app.controller('TicksCtrl', ['$scope', '$interval', function ($scope, $interval) { + var maximum = document.getElementById('container').clientWidth / 2 || 300; + $scope.data = [[]]; + $scope.labels = []; + $scope.options = { + animation: false, + showScale: false, + showTooltips: false, + pointDot: false, + datasetStrokeWidth: 0.5 + }; + + // Update the dataset at 25FPS for a smoothly-animating chart + $interval(function () { + getLiveChartData(); + }, 40); + + function getLiveChartData () { + if ($scope.data[0].length) { + $scope.labels = $scope.labels.slice(1); + $scope.data[0] = $scope.data[0].slice(1); + } + + while ($scope.data[0].length < maximum) { + $scope.labels.push(''); + $scope.data[0].push(getRandomValue($scope.data[0])); + } + } + }]); + + function getRandomValue (data) { + var l = data.length, previous = l ? data[l - 1] : 50; + var y = previous + Math.random() * 10 - 5; + return y < 0 ? 0 : y > 100 ? 100 : y; + } +})(); diff --git a/templates/js/libs/angular-chart.js-0.7.2/examples/bootstrap.css b/templates/js/libs/angular-chart.js-0.7.2/examples/bootstrap.css new file mode 100644 index 0000000..7f36651 --- /dev/null +++ b/templates/js/libs/angular-chart.js-0.7.2/examples/bootstrap.css @@ -0,0 +1,5785 @@ +/*! + * Bootstrap v3.1.1 (http://getbootstrap.com) + * Copyright 2011-2014 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + */ + +/*! normalize.css v3.0.0 | MIT License | git.io/normalize */ +html { + font-family: sans-serif; + -webkit-text-size-adjust: 100%; + -ms-text-size-adjust: 100%; +} +body { + margin: 0; +} +article, +aside, +details, +figcaption, +figure, +footer, +header, +hgroup, +main, +nav, +section, +summary { + display: block; +} +audio, +canvas, +progress, +video { + display: inline-block; + vertical-align: baseline; +} +audio:not([controls]) { + display: none; + height: 0; +} +[hidden], +template { + display: none; +} +a { + background: transparent; +} +a:active, +a:hover { + outline: 0; +} +abbr[title] { + border-bottom: 1px dotted; +} +b, +strong { + font-weight: bold; +} +dfn { + font-style: italic; +} +h1 { + margin: .67em 0; + font-size: 2em; +} +mark { + color: #000; + background: #ff0; +} +small { + font-size: 80%; +} +sub, +sup { + position: relative; + font-size: 75%; + line-height: 0; + vertical-align: baseline; +} +sup { + top: -.5em; +} +sub { + bottom: -.25em; +} +img { + border: 0; +} +svg:not(:root) { + overflow: hidden; +} +figure { + margin: 1em 40px; +} +hr { + height: 0; + -moz-box-sizing: content-box; + box-sizing: content-box; +} +pre { + overflow: auto; +} +code, +kbd, +pre, +samp { + font-family: monospace, monospace; + font-size: 1em; +} +button, +input, +optgroup, +select, +textarea { + margin: 0; + font: inherit; + color: inherit; +} +button { + overflow: visible; +} +button, +select { + text-transform: none; +} +button, +html input[type="button"], +input[type="reset"], +input[type="submit"] { + -webkit-appearance: button; + cursor: pointer; +} +button[disabled], +html input[disabled] { + cursor: default; +} +button::-moz-focus-inner, +input::-moz-focus-inner { + padding: 0; + border: 0; +} +input { + line-height: normal; +} +input[type="checkbox"], +input[type="radio"] { + box-sizing: border-box; + padding: 0; +} +input[type="number"]::-webkit-inner-spin-button, +input[type="number"]::-webkit-outer-spin-button { + height: auto; +} +input[type="search"] { + -webkit-box-sizing: content-box; + -moz-box-sizing: content-box; + box-sizing: content-box; + -webkit-appearance: textfield; +} +input[type="search"]::-webkit-search-cancel-button, +input[type="search"]::-webkit-search-decoration { + -webkit-appearance: none; +} +fieldset { + padding: .35em .625em .75em; + margin: 0 2px; + border: 1px solid #c0c0c0; +} +legend { + padding: 0; + border: 0; +} +textarea { + overflow: auto; +} +optgroup { + font-weight: bold; +} +table { + border-spacing: 0; + border-collapse: collapse; +} +td, +th { + padding: 0; +} +@media print { + * { + color: #000 !important; + text-shadow: none !important; + background: transparent !important; + box-shadow: none !important; + } + a, + a:visited { + text-decoration: underline; + } + a[href]:after { + content: " (" attr(href) ")"; + } + abbr[title]:after { + content: " (" attr(title) ")"; + } + a[href^="javascript:"]:after, + a[href^="#"]:after { + content: ""; + } + pre, + blockquote { + border: 1px solid #999; + + page-break-inside: avoid; + } + thead { + display: table-header-group; + } + tr, + img { + page-break-inside: avoid; + } + img { + max-width: 100% !important; + } + p, + h2, + h3 { + orphans: 3; + widows: 3; + } + h2, + h3 { + page-break-after: avoid; + } + select { + background: #fff !important; + } + .navbar { + display: none; + } + .table td, + .table th { + background-color: #fff !important; + } + .btn > .caret, + .dropup > .btn > .caret { + border-top-color: #000 !important; + } + .label { + border: 1px solid #000; + } + .table { + border-collapse: collapse !important; + } + .table-bordered th, + .table-bordered td { + border: 1px solid #ddd !important; + } +} +* { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +*:before, +*:after { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +html { + font-size: 62.5%; + + -webkit-tap-highlight-color: rgba(0, 0, 0, 0); +} +body { + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + font-size: 14px; + line-height: 1.42857143; + color: #333; + background-color: #fff; +} +input, +button, +select, +textarea { + font-family: inherit; + font-size: inherit; + line-height: inherit; +} +a { + color: #428bca; + text-decoration: none; +} +a:hover, +a:focus { + color: #2a6496; + text-decoration: underline; +} +a:focus { + outline: thin dotted; + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; +} +figure { + margin: 0; +} +img { + vertical-align: middle; +} +.img-responsive, +.thumbnail > img, +.thumbnail a > img, +.carousel-inner > .item > img, +.carousel-inner > .item > a > img { + display: block; + max-width: 100%; + height: auto; +} +.img-rounded { + border-radius: 6px; +} +.img-thumbnail { + display: inline-block; + max-width: 100%; + height: auto; + padding: 4px; + line-height: 1.42857143; + background-color: #fff; + border: 1px solid #ddd; + border-radius: 4px; + -webkit-transition: all .2s ease-in-out; + transition: all .2s ease-in-out; +} +.img-circle { + border-radius: 50%; +} +hr { + margin-top: 20px; + margin-bottom: 20px; + border: 0; + border-top: 1px solid #eee; +} +.sr-only { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + overflow: hidden; + clip: rect(0, 0, 0, 0); + border: 0; +} +h1, +h2, +h3, +h4, +h5, +h6, +.h1, +.h2, +.h3, +.h4, +.h5, +.h6 { + font-family: inherit; + font-weight: 500; + line-height: 1.1; + color: inherit; +} +h1 small, +h2 small, +h3 small, +h4 small, +h5 small, +h6 small, +.h1 small, +.h2 small, +.h3 small, +.h4 small, +.h5 small, +.h6 small, +h1 .small, +h2 .small, +h3 .small, +h4 .small, +h5 .small, +h6 .small, +.h1 .small, +.h2 .small, +.h3 .small, +.h4 .small, +.h5 .small, +.h6 .small { + font-weight: normal; + line-height: 1; + color: #999; +} +h1, +.h1, +h2, +.h2, +h3, +.h3 { + margin-top: 20px; + margin-bottom: 10px; +} +h1 small, +.h1 small, +h2 small, +.h2 small, +h3 small, +.h3 small, +h1 .small, +.h1 .small, +h2 .small, +.h2 .small, +h3 .small, +.h3 .small { + font-size: 65%; +} +h4, +.h4, +h5, +.h5, +h6, +.h6 { + margin-top: 10px; + margin-bottom: 10px; +} +h4 small, +.h4 small, +h5 small, +.h5 small, +h6 small, +.h6 small, +h4 .small, +.h4 .small, +h5 .small, +.h5 .small, +h6 .small, +.h6 .small { + font-size: 75%; +} +h1, +.h1 { + font-size: 36px; +} +h2, +.h2 { + font-size: 30px; +} +h3, +.h3 { + font-size: 24px; +} +h4, +.h4 { + font-size: 18px; +} +h5, +.h5 { + font-size: 14px; +} +h6, +.h6 { + font-size: 12px; +} +p { + margin: 0 0 10px; +} +.lead { + margin-bottom: 20px; + font-size: 16px; + font-weight: 200; + line-height: 1.4; +} +@media (min-width: 768px) { + .lead { + font-size: 21px; + } +} +small, +.small { + font-size: 85%; +} +cite { + font-style: normal; +} +.text-left { + text-align: left; +} +.text-right { + text-align: right; +} +.text-center { + text-align: center; +} +.text-justify { + text-align: justify; +} +.text-muted { + color: #999; +} +.text-primary { + color: #428bca; +} +a.text-primary:hover { + color: #3071a9; +} +.text-success { + color: #3c763d; +} +a.text-success:hover { + color: #2b542c; +} +.text-info { + color: #31708f; +} +a.text-info:hover { + color: #245269; +} +.text-warning { + color: #8a6d3b; +} +a.text-warning:hover { + color: #66512c; +} +.text-danger { + color: #a94442; +} +a.text-danger:hover { + color: #843534; +} +.bg-primary { + color: #fff; + background-color: #428bca; +} +a.bg-primary:hover { + background-color: #3071a9; +} +.bg-success { + background-color: #dff0d8; +} +a.bg-success:hover { + background-color: #c1e2b3; +} +.bg-info { + background-color: #d9edf7; +} +a.bg-info:hover { + background-color: #afd9ee; +} +.bg-warning { + background-color: #fcf8e3; +} +a.bg-warning:hover { + background-color: #f7ecb5; +} +.bg-danger { + background-color: #f2dede; +} +a.bg-danger:hover { + background-color: #e4b9b9; +} +.page-header { + padding-bottom: 9px; + margin: 40px 0 20px; + border-bottom: 1px solid #eee; +} +ul, +ol { + margin-top: 0; + margin-bottom: 10px; +} +ul ul, +ol ul, +ul ol, +ol ol { + margin-bottom: 0; +} +.list-unstyled { + padding-left: 0; + list-style: none; +} +.list-inline { + padding-left: 0; + margin-left: -5px; + list-style: none; +} +.list-inline > li { + display: inline-block; + padding-right: 5px; + padding-left: 5px; +} +dl { + margin-top: 0; + margin-bottom: 20px; +} +dt, +dd { + line-height: 1.42857143; +} +dt { + font-weight: bold; +} +dd { + margin-left: 0; +} +@media (min-width: 768px) { + .dl-horizontal dt { + float: left; + width: 160px; + overflow: hidden; + clear: left; + text-align: right; + text-overflow: ellipsis; + white-space: nowrap; + } + .dl-horizontal dd { + margin-left: 180px; + } +} +abbr[title], +abbr[data-original-title] { + cursor: help; + border-bottom: 1px dotted #999; +} +.initialism { + font-size: 90%; + text-transform: uppercase; +} +blockquote { + padding: 10px 20px; + margin: 0 0 20px; + font-size: 17.5px; + border-left: 5px solid #eee; +} +blockquote p:last-child, +blockquote ul:last-child, +blockquote ol:last-child { + margin-bottom: 0; +} +blockquote footer, +blockquote small, +blockquote .small { + display: block; + font-size: 80%; + line-height: 1.42857143; + color: #999; +} +blockquote footer:before, +blockquote small:before, +blockquote .small:before { + content: '\2014 \00A0'; +} +.blockquote-reverse, +blockquote.pull-right { + padding-right: 15px; + padding-left: 0; + text-align: right; + border-right: 5px solid #eee; + border-left: 0; +} +.blockquote-reverse footer:before, +blockquote.pull-right footer:before, +.blockquote-reverse small:before, +blockquote.pull-right small:before, +.blockquote-reverse .small:before, +blockquote.pull-right .small:before { + content: ''; +} +.blockquote-reverse footer:after, +blockquote.pull-right footer:after, +.blockquote-reverse small:after, +blockquote.pull-right small:after, +.blockquote-reverse .small:after, +blockquote.pull-right .small:after { + content: '\00A0 \2014'; +} +blockquote:before, +blockquote:after { + content: ""; +} +address { + margin-bottom: 20px; + font-style: normal; + line-height: 1.42857143; +} +code, +kbd, +pre, +samp { + font-family: Menlo, Monaco, Consolas, "Courier New", monospace; +} +code { + padding: 2px 4px; + font-size: 90%; + color: #c7254e; + white-space: nowrap; + background-color: #f9f2f4; + border-radius: 4px; +} +kbd { + padding: 2px 4px; + font-size: 90%; + color: #fff; + background-color: #333; + border-radius: 3px; + box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .25); +} +pre { + display: block; + padding: 9.5px; + margin: 0 0 10px; + font-size: 13px; + line-height: 1.42857143; + color: #333; + word-break: break-all; + word-wrap: break-word; + background-color: #f5f5f5; + border: 1px solid #ccc; + border-radius: 4px; +} +pre code { + padding: 0; + font-size: inherit; + color: inherit; + white-space: pre-wrap; + background-color: transparent; + border-radius: 0; +} +.pre-scrollable { + max-height: 340px; + overflow-y: scroll; +} +.container { + padding-right: 15px; + padding-left: 15px; + margin-right: auto; + margin-left: auto; +} +@media (min-width: 768px) { + .container { + width: 750px; + } +} +@media (min-width: 992px) { + .container { + width: 970px; + } +} +@media (min-width: 1200px) { + .container { + width: 1170px; + } +} +.container-fluid { + padding-right: 15px; + padding-left: 15px; + margin-right: auto; + margin-left: auto; +} +.row { + margin-right: -15px; + margin-left: -15px; +} +.col-xs-1, .col-sm-1, .col-md-1, .col-lg-1, .col-xs-2, .col-sm-2, .col-md-2, .col-lg-2, .col-xs-3, .col-sm-3, .col-md-3, .col-lg-3, .col-xs-4, .col-sm-4, .col-md-4, .col-lg-4, .col-xs-5, .col-sm-5, .col-md-5, .col-lg-5, .col-xs-6, .col-sm-6, .col-md-6, .col-lg-6, .col-xs-7, .col-sm-7, .col-md-7, .col-lg-7, .col-xs-8, .col-sm-8, .col-md-8, .col-lg-8, .col-xs-9, .col-sm-9, .col-md-9, .col-lg-9, .col-xs-10, .col-sm-10, .col-md-10, .col-lg-10, .col-xs-11, .col-sm-11, .col-md-11, .col-lg-11, .col-xs-12, .col-sm-12, .col-md-12, .col-lg-12 { + position: relative; + min-height: 1px; + padding-right: 15px; + padding-left: 15px; +} +.col-xs-1, .col-xs-2, .col-xs-3, .col-xs-4, .col-xs-5, .col-xs-6, .col-xs-7, .col-xs-8, .col-xs-9, .col-xs-10, .col-xs-11, .col-xs-12 { + float: left; +} +.col-xs-12 { + width: 100%; +} +.col-xs-11 { + width: 91.66666667%; +} +.col-xs-10 { + width: 83.33333333%; +} +.col-xs-9 { + width: 75%; +} +.col-xs-8 { + width: 66.66666667%; +} +.col-xs-7 { + width: 58.33333333%; +} +.col-xs-6 { + width: 50%; +} +.col-xs-5 { + width: 41.66666667%; +} +.col-xs-4 { + width: 33.33333333%; +} +.col-xs-3 { + width: 25%; +} +.col-xs-2 { + width: 16.66666667%; +} +.col-xs-1 { + width: 8.33333333%; +} +.col-xs-pull-12 { + right: 100%; +} +.col-xs-pull-11 { + right: 91.66666667%; +} +.col-xs-pull-10 { + right: 83.33333333%; +} +.col-xs-pull-9 { + right: 75%; +} +.col-xs-pull-8 { + right: 66.66666667%; +} +.col-xs-pull-7 { + right: 58.33333333%; +} +.col-xs-pull-6 { + right: 50%; +} +.col-xs-pull-5 { + right: 41.66666667%; +} +.col-xs-pull-4 { + right: 33.33333333%; +} +.col-xs-pull-3 { + right: 25%; +} +.col-xs-pull-2 { + right: 16.66666667%; +} +.col-xs-pull-1 { + right: 8.33333333%; +} +.col-xs-pull-0 { + right: 0; +} +.col-xs-push-12 { + left: 100%; +} +.col-xs-push-11 { + left: 91.66666667%; +} +.col-xs-push-10 { + left: 83.33333333%; +} +.col-xs-push-9 { + left: 75%; +} +.col-xs-push-8 { + left: 66.66666667%; +} +.col-xs-push-7 { + left: 58.33333333%; +} +.col-xs-push-6 { + left: 50%; +} +.col-xs-push-5 { + left: 41.66666667%; +} +.col-xs-push-4 { + left: 33.33333333%; +} +.col-xs-push-3 { + left: 25%; +} +.col-xs-push-2 { + left: 16.66666667%; +} +.col-xs-push-1 { + left: 8.33333333%; +} +.col-xs-push-0 { + left: 0; +} +.col-xs-offset-12 { + margin-left: 100%; +} +.col-xs-offset-11 { + margin-left: 91.66666667%; +} +.col-xs-offset-10 { + margin-left: 83.33333333%; +} +.col-xs-offset-9 { + margin-left: 75%; +} +.col-xs-offset-8 { + margin-left: 66.66666667%; +} +.col-xs-offset-7 { + margin-left: 58.33333333%; +} +.col-xs-offset-6 { + margin-left: 50%; +} +.col-xs-offset-5 { + margin-left: 41.66666667%; +} +.col-xs-offset-4 { + margin-left: 33.33333333%; +} +.col-xs-offset-3 { + margin-left: 25%; +} +.col-xs-offset-2 { + margin-left: 16.66666667%; +} +.col-xs-offset-1 { + margin-left: 8.33333333%; +} +.col-xs-offset-0 { + margin-left: 0; +} +@media (min-width: 768px) { + .col-sm-1, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12 { + float: left; + } + .col-sm-12 { + width: 100%; + } + .col-sm-11 { + width: 91.66666667%; + } + .col-sm-10 { + width: 83.33333333%; + } + .col-sm-9 { + width: 75%; + } + .col-sm-8 { + width: 66.66666667%; + } + .col-sm-7 { + width: 58.33333333%; + } + .col-sm-6 { + width: 50%; + } + .col-sm-5 { + width: 41.66666667%; + } + .col-sm-4 { + width: 33.33333333%; + } + .col-sm-3 { + width: 25%; + } + .col-sm-2 { + width: 16.66666667%; + } + .col-sm-1 { + width: 8.33333333%; + } + .col-sm-pull-12 { + right: 100%; + } + .col-sm-pull-11 { + right: 91.66666667%; + } + .col-sm-pull-10 { + right: 83.33333333%; + } + .col-sm-pull-9 { + right: 75%; + } + .col-sm-pull-8 { + right: 66.66666667%; + } + .col-sm-pull-7 { + right: 58.33333333%; + } + .col-sm-pull-6 { + right: 50%; + } + .col-sm-pull-5 { + right: 41.66666667%; + } + .col-sm-pull-4 { + right: 33.33333333%; + } + .col-sm-pull-3 { + right: 25%; + } + .col-sm-pull-2 { + right: 16.66666667%; + } + .col-sm-pull-1 { + right: 8.33333333%; + } + .col-sm-pull-0 { + right: 0; + } + .col-sm-push-12 { + left: 100%; + } + .col-sm-push-11 { + left: 91.66666667%; + } + .col-sm-push-10 { + left: 83.33333333%; + } + .col-sm-push-9 { + left: 75%; + } + .col-sm-push-8 { + left: 66.66666667%; + } + .col-sm-push-7 { + left: 58.33333333%; + } + .col-sm-push-6 { + left: 50%; + } + .col-sm-push-5 { + left: 41.66666667%; + } + .col-sm-push-4 { + left: 33.33333333%; + } + .col-sm-push-3 { + left: 25%; + } + .col-sm-push-2 { + left: 16.66666667%; + } + .col-sm-push-1 { + left: 8.33333333%; + } + .col-sm-push-0 { + left: 0; + } + .col-sm-offset-12 { + margin-left: 100%; + } + .col-sm-offset-11 { + margin-left: 91.66666667%; + } + .col-sm-offset-10 { + margin-left: 83.33333333%; + } + .col-sm-offset-9 { + margin-left: 75%; + } + .col-sm-offset-8 { + margin-left: 66.66666667%; + } + .col-sm-offset-7 { + margin-left: 58.33333333%; + } + .col-sm-offset-6 { + margin-left: 50%; + } + .col-sm-offset-5 { + margin-left: 41.66666667%; + } + .col-sm-offset-4 { + margin-left: 33.33333333%; + } + .col-sm-offset-3 { + margin-left: 25%; + } + .col-sm-offset-2 { + margin-left: 16.66666667%; + } + .col-sm-offset-1 { + margin-left: 8.33333333%; + } + .col-sm-offset-0 { + margin-left: 0; + } +} +@media (min-width: 992px) { + .col-md-1, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-10, .col-md-11, .col-md-12 { + float: left; + } + .col-md-12 { + width: 100%; + } + .col-md-11 { + width: 91.66666667%; + } + .col-md-10 { + width: 83.33333333%; + } + .col-md-9 { + width: 75%; + } + .col-md-8 { + width: 66.66666667%; + } + .col-md-7 { + width: 58.33333333%; + } + .col-md-6 { + width: 50%; + } + .col-md-5 { + width: 41.66666667%; + } + .col-md-4 { + width: 33.33333333%; + } + .col-md-3 { + width: 25%; + } + .col-md-2 { + width: 16.66666667%; + } + .col-md-1 { + width: 8.33333333%; + } + .col-md-pull-12 { + right: 100%; + } + .col-md-pull-11 { + right: 91.66666667%; + } + .col-md-pull-10 { + right: 83.33333333%; + } + .col-md-pull-9 { + right: 75%; + } + .col-md-pull-8 { + right: 66.66666667%; + } + .col-md-pull-7 { + right: 58.33333333%; + } + .col-md-pull-6 { + right: 50%; + } + .col-md-pull-5 { + right: 41.66666667%; + } + .col-md-pull-4 { + right: 33.33333333%; + } + .col-md-pull-3 { + right: 25%; + } + .col-md-pull-2 { + right: 16.66666667%; + } + .col-md-pull-1 { + right: 8.33333333%; + } + .col-md-pull-0 { + right: 0; + } + .col-md-push-12 { + left: 100%; + } + .col-md-push-11 { + left: 91.66666667%; + } + .col-md-push-10 { + left: 83.33333333%; + } + .col-md-push-9 { + left: 75%; + } + .col-md-push-8 { + left: 66.66666667%; + } + .col-md-push-7 { + left: 58.33333333%; + } + .col-md-push-6 { + left: 50%; + } + .col-md-push-5 { + left: 41.66666667%; + } + .col-md-push-4 { + left: 33.33333333%; + } + .col-md-push-3 { + left: 25%; + } + .col-md-push-2 { + left: 16.66666667%; + } + .col-md-push-1 { + left: 8.33333333%; + } + .col-md-push-0 { + left: 0; + } + .col-md-offset-12 { + margin-left: 100%; + } + .col-md-offset-11 { + margin-left: 91.66666667%; + } + .col-md-offset-10 { + margin-left: 83.33333333%; + } + .col-md-offset-9 { + margin-left: 75%; + } + .col-md-offset-8 { + margin-left: 66.66666667%; + } + .col-md-offset-7 { + margin-left: 58.33333333%; + } + .col-md-offset-6 { + margin-left: 50%; + } + .col-md-offset-5 { + margin-left: 41.66666667%; + } + .col-md-offset-4 { + margin-left: 33.33333333%; + } + .col-md-offset-3 { + margin-left: 25%; + } + .col-md-offset-2 { + margin-left: 16.66666667%; + } + .col-md-offset-1 { + margin-left: 8.33333333%; + } + .col-md-offset-0 { + margin-left: 0; + } +} +@media (min-width: 1200px) { + .col-lg-1, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-lg-10, .col-lg-11, .col-lg-12 { + float: left; + } + .col-lg-12 { + width: 100%; + } + .col-lg-11 { + width: 91.66666667%; + } + .col-lg-10 { + width: 83.33333333%; + } + .col-lg-9 { + width: 75%; + } + .col-lg-8 { + width: 66.66666667%; + } + .col-lg-7 { + width: 58.33333333%; + } + .col-lg-6 { + width: 50%; + } + .col-lg-5 { + width: 41.66666667%; + } + .col-lg-4 { + width: 33.33333333%; + } + .col-lg-3 { + width: 25%; + } + .col-lg-2 { + width: 16.66666667%; + } + .col-lg-1 { + width: 8.33333333%; + } + .col-lg-pull-12 { + right: 100%; + } + .col-lg-pull-11 { + right: 91.66666667%; + } + .col-lg-pull-10 { + right: 83.33333333%; + } + .col-lg-pull-9 { + right: 75%; + } + .col-lg-pull-8 { + right: 66.66666667%; + } + .col-lg-pull-7 { + right: 58.33333333%; + } + .col-lg-pull-6 { + right: 50%; + } + .col-lg-pull-5 { + right: 41.66666667%; + } + .col-lg-pull-4 { + right: 33.33333333%; + } + .col-lg-pull-3 { + right: 25%; + } + .col-lg-pull-2 { + right: 16.66666667%; + } + .col-lg-pull-1 { + right: 8.33333333%; + } + .col-lg-pull-0 { + right: 0; + } + .col-lg-push-12 { + left: 100%; + } + .col-lg-push-11 { + left: 91.66666667%; + } + .col-lg-push-10 { + left: 83.33333333%; + } + .col-lg-push-9 { + left: 75%; + } + .col-lg-push-8 { + left: 66.66666667%; + } + .col-lg-push-7 { + left: 58.33333333%; + } + .col-lg-push-6 { + left: 50%; + } + .col-lg-push-5 { + left: 41.66666667%; + } + .col-lg-push-4 { + left: 33.33333333%; + } + .col-lg-push-3 { + left: 25%; + } + .col-lg-push-2 { + left: 16.66666667%; + } + .col-lg-push-1 { + left: 8.33333333%; + } + .col-lg-push-0 { + left: 0; + } + .col-lg-offset-12 { + margin-left: 100%; + } + .col-lg-offset-11 { + margin-left: 91.66666667%; + } + .col-lg-offset-10 { + margin-left: 83.33333333%; + } + .col-lg-offset-9 { + margin-left: 75%; + } + .col-lg-offset-8 { + margin-left: 66.66666667%; + } + .col-lg-offset-7 { + margin-left: 58.33333333%; + } + .col-lg-offset-6 { + margin-left: 50%; + } + .col-lg-offset-5 { + margin-left: 41.66666667%; + } + .col-lg-offset-4 { + margin-left: 33.33333333%; + } + .col-lg-offset-3 { + margin-left: 25%; + } + .col-lg-offset-2 { + margin-left: 16.66666667%; + } + .col-lg-offset-1 { + margin-left: 8.33333333%; + } + .col-lg-offset-0 { + margin-left: 0; + } +} +table { + max-width: 100%; + background-color: transparent; +} +th { + text-align: left; +} +.table { + width: 100%; + margin-bottom: 20px; +} +.table > thead > tr > th, +.table > tbody > tr > th, +.table > tfoot > tr > th, +.table > thead > tr > td, +.table > tbody > tr > td, +.table > tfoot > tr > td { + padding: 8px; + line-height: 1.42857143; + vertical-align: top; + border-top: 1px solid #ddd; +} +.table > thead > tr > th { + vertical-align: bottom; + border-bottom: 2px solid #ddd; +} +.table > caption + thead > tr:first-child > th, +.table > colgroup + thead > tr:first-child > th, +.table > thead:first-child > tr:first-child > th, +.table > caption + thead > tr:first-child > td, +.table > colgroup + thead > tr:first-child > td, +.table > thead:first-child > tr:first-child > td { + border-top: 0; +} +.table > tbody + tbody { + border-top: 2px solid #ddd; +} +.table .table { + background-color: #fff; +} +.table-condensed > thead > tr > th, +.table-condensed > tbody > tr > th, +.table-condensed > tfoot > tr > th, +.table-condensed > thead > tr > td, +.table-condensed > tbody > tr > td, +.table-condensed > tfoot > tr > td { + padding: 5px; +} +.table-bordered { + border: 1px solid #ddd; +} +.table-bordered > thead > tr > th, +.table-bordered > tbody > tr > th, +.table-bordered > tfoot > tr > th, +.table-bordered > thead > tr > td, +.table-bordered > tbody > tr > td, +.table-bordered > tfoot > tr > td { + border: 1px solid #ddd; +} +.table-bordered > thead > tr > th, +.table-bordered > thead > tr > td { + border-bottom-width: 2px; +} +.table-striped > tbody > tr:nth-child(odd) > td, +.table-striped > tbody > tr:nth-child(odd) > th { + background-color: #f9f9f9; +} +.table-hover > tbody > tr:hover > td, +.table-hover > tbody > tr:hover > th { + background-color: #f5f5f5; +} +table col[class*="col-"] { + position: static; + display: table-column; + float: none; +} +table td[class*="col-"], +table th[class*="col-"] { + position: static; + display: table-cell; + float: none; +} +.table > thead > tr > td.active, +.table > tbody > tr > td.active, +.table > tfoot > tr > td.active, +.table > thead > tr > th.active, +.table > tbody > tr > th.active, +.table > tfoot > tr > th.active, +.table > thead > tr.active > td, +.table > tbody > tr.active > td, +.table > tfoot > tr.active > td, +.table > thead > tr.active > th, +.table > tbody > tr.active > th, +.table > tfoot > tr.active > th { + background-color: #f5f5f5; +} +.table-hover > tbody > tr > td.active:hover, +.table-hover > tbody > tr > th.active:hover, +.table-hover > tbody > tr.active:hover > td, +.table-hover > tbody > tr.active:hover > th { + background-color: #e8e8e8; +} +.table > thead > tr > td.success, +.table > tbody > tr > td.success, +.table > tfoot > tr > td.success, +.table > thead > tr > th.success, +.table > tbody > tr > th.success, +.table > tfoot > tr > th.success, +.table > thead > tr.success > td, +.table > tbody > tr.success > td, +.table > tfoot > tr.success > td, +.table > thead > tr.success > th, +.table > tbody > tr.success > th, +.table > tfoot > tr.success > th { + background-color: #dff0d8; +} +.table-hover > tbody > tr > td.success:hover, +.table-hover > tbody > tr > th.success:hover, +.table-hover > tbody > tr.success:hover > td, +.table-hover > tbody > tr.success:hover > th { + background-color: #d0e9c6; +} +.table > thead > tr > td.info, +.table > tbody > tr > td.info, +.table > tfoot > tr > td.info, +.table > thead > tr > th.info, +.table > tbody > tr > th.info, +.table > tfoot > tr > th.info, +.table > thead > tr.info > td, +.table > tbody > tr.info > td, +.table > tfoot > tr.info > td, +.table > thead > tr.info > th, +.table > tbody > tr.info > th, +.table > tfoot > tr.info > th { + background-color: #d9edf7; +} +.table-hover > tbody > tr > td.info:hover, +.table-hover > tbody > tr > th.info:hover, +.table-hover > tbody > tr.info:hover > td, +.table-hover > tbody > tr.info:hover > th { + background-color: #c4e3f3; +} +.table > thead > tr > td.warning, +.table > tbody > tr > td.warning, +.table > tfoot > tr > td.warning, +.table > thead > tr > th.warning, +.table > tbody > tr > th.warning, +.table > tfoot > tr > th.warning, +.table > thead > tr.warning > td, +.table > tbody > tr.warning > td, +.table > tfoot > tr.warning > td, +.table > thead > tr.warning > th, +.table > tbody > tr.warning > th, +.table > tfoot > tr.warning > th { + background-color: #fcf8e3; +} +.table-hover > tbody > tr > td.warning:hover, +.table-hover > tbody > tr > th.warning:hover, +.table-hover > tbody > tr.warning:hover > td, +.table-hover > tbody > tr.warning:hover > th { + background-color: #faf2cc; +} +.table > thead > tr > td.danger, +.table > tbody > tr > td.danger, +.table > tfoot > tr > td.danger, +.table > thead > tr > th.danger, +.table > tbody > tr > th.danger, +.table > tfoot > tr > th.danger, +.table > thead > tr.danger > td, +.table > tbody > tr.danger > td, +.table > tfoot > tr.danger > td, +.table > thead > tr.danger > th, +.table > tbody > tr.danger > th, +.table > tfoot > tr.danger > th { + background-color: #f2dede; +} +.table-hover > tbody > tr > td.danger:hover, +.table-hover > tbody > tr > th.danger:hover, +.table-hover > tbody > tr.danger:hover > td, +.table-hover > tbody > tr.danger:hover > th { + background-color: #ebcccc; +} +@media (max-width: 767px) { + .table-responsive { + width: 100%; + margin-bottom: 15px; + overflow-x: scroll; + overflow-y: hidden; + -webkit-overflow-scrolling: touch; + -ms-overflow-style: -ms-autohiding-scrollbar; + border: 1px solid #ddd; + } + .table-responsive > .table { + margin-bottom: 0; + } + .table-responsive > .table > thead > tr > th, + .table-responsive > .table > tbody > tr > th, + .table-responsive > .table > tfoot > tr > th, + .table-responsive > .table > thead > tr > td, + .table-responsive > .table > tbody > tr > td, + .table-responsive > .table > tfoot > tr > td { + white-space: nowrap; + } + .table-responsive > .table-bordered { + border: 0; + } + .table-responsive > .table-bordered > thead > tr > th:first-child, + .table-responsive > .table-bordered > tbody > tr > th:first-child, + .table-responsive > .table-bordered > tfoot > tr > th:first-child, + .table-responsive > .table-bordered > thead > tr > td:first-child, + .table-responsive > .table-bordered > tbody > tr > td:first-child, + .table-responsive > .table-bordered > tfoot > tr > td:first-child { + border-left: 0; + } + .table-responsive > .table-bordered > thead > tr > th:last-child, + .table-responsive > .table-bordered > tbody > tr > th:last-child, + .table-responsive > .table-bordered > tfoot > tr > th:last-child, + .table-responsive > .table-bordered > thead > tr > td:last-child, + .table-responsive > .table-bordered > tbody > tr > td:last-child, + .table-responsive > .table-bordered > tfoot > tr > td:last-child { + border-right: 0; + } + .table-responsive > .table-bordered > tbody > tr:last-child > th, + .table-responsive > .table-bordered > tfoot > tr:last-child > th, + .table-responsive > .table-bordered > tbody > tr:last-child > td, + .table-responsive > .table-bordered > tfoot > tr:last-child > td { + border-bottom: 0; + } +} +fieldset { + min-width: 0; + padding: 0; + margin: 0; + border: 0; +} +legend { + display: block; + width: 100%; + padding: 0; + margin-bottom: 20px; + font-size: 21px; + line-height: inherit; + color: #333; + border: 0; + border-bottom: 1px solid #e5e5e5; +} +label { + display: inline-block; + margin-bottom: 5px; + font-weight: bold; +} +input[type="search"] { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +input[type="radio"], +input[type="checkbox"] { + margin: 4px 0 0; + margin-top: 1px \9; + /* IE8-9 */ + line-height: normal; +} +input[type="file"] { + display: block; +} +input[type="range"] { + display: block; + width: 100%; +} +select[multiple], +select[size] { + height: auto; +} +input[type="file"]:focus, +input[type="radio"]:focus, +input[type="checkbox"]:focus { + outline: thin dotted; + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; +} +output { + display: block; + padding-top: 7px; + font-size: 14px; + line-height: 1.42857143; + color: #555; +} +.form-control { + display: block; + width: 100%; + height: 34px; + padding: 6px 12px; + font-size: 14px; + line-height: 1.42857143; + color: #555; + background-color: #fff; + background-image: none; + border: 1px solid #ccc; + border-radius: 4px; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); + -webkit-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s; + transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s; +} +.form-control:focus { + border-color: #66afe9; + outline: 0; + -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, .6); + box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, .6); +} +.form-control::-moz-placeholder { + color: #999; + opacity: 1; +} +.form-control:-ms-input-placeholder { + color: #999; +} +.form-control::-webkit-input-placeholder { + color: #999; +} +.form-control[disabled], +.form-control[readonly], +fieldset[disabled] .form-control { + cursor: not-allowed; + background-color: #eee; + opacity: 1; +} +textarea.form-control { + height: auto; +} +input[type="search"] { + -webkit-appearance: none; +} +input[type="date"] { + line-height: 34px; +} +.form-group { + margin-bottom: 15px; +} +.radio, +.checkbox { + display: block; + min-height: 20px; + padding-left: 20px; + margin-top: 10px; + margin-bottom: 10px; +} +.radio label, +.checkbox label { + display: inline; + font-weight: normal; + cursor: pointer; +} +.radio input[type="radio"], +.radio-inline input[type="radio"], +.checkbox input[type="checkbox"], +.checkbox-inline input[type="checkbox"] { + float: left; + margin-left: -20px; +} +.radio + .radio, +.checkbox + .checkbox { + margin-top: -5px; +} +.radio-inline, +.checkbox-inline { + display: inline-block; + padding-left: 20px; + margin-bottom: 0; + font-weight: normal; + vertical-align: middle; + cursor: pointer; +} +.radio-inline + .radio-inline, +.checkbox-inline + .checkbox-inline { + margin-top: 0; + margin-left: 10px; +} +input[type="radio"][disabled], +input[type="checkbox"][disabled], +.radio[disabled], +.radio-inline[disabled], +.checkbox[disabled], +.checkbox-inline[disabled], +fieldset[disabled] input[type="radio"], +fieldset[disabled] input[type="checkbox"], +fieldset[disabled] .radio, +fieldset[disabled] .radio-inline, +fieldset[disabled] .checkbox, +fieldset[disabled] .checkbox-inline { + cursor: not-allowed; +} +.input-sm { + height: 30px; + padding: 5px 10px; + font-size: 12px; + line-height: 1.5; + border-radius: 3px; +} +select.input-sm { + height: 30px; + line-height: 30px; +} +textarea.input-sm, +select[multiple].input-sm { + height: auto; +} +.input-lg { + height: 46px; + padding: 10px 16px; + font-size: 18px; + line-height: 1.33; + border-radius: 6px; +} +select.input-lg { + height: 46px; + line-height: 46px; +} +textarea.input-lg, +select[multiple].input-lg { + height: auto; +} +.has-feedback { + position: relative; +} +.has-feedback .form-control { + padding-right: 42.5px; +} +.has-feedback .form-control-feedback { + position: absolute; + top: 25px; + right: 0; + display: block; + width: 34px; + height: 34px; + line-height: 34px; + text-align: center; +} +.has-success .help-block, +.has-success .control-label, +.has-success .radio, +.has-success .checkbox, +.has-success .radio-inline, +.has-success .checkbox-inline { + color: #3c763d; +} +.has-success .form-control { + border-color: #3c763d; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); +} +.has-success .form-control:focus { + border-color: #2b542c; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #67b168; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #67b168; +} +.has-success .input-group-addon { + color: #3c763d; + background-color: #dff0d8; + border-color: #3c763d; +} +.has-success .form-control-feedback { + color: #3c763d; +} +.has-warning .help-block, +.has-warning .control-label, +.has-warning .radio, +.has-warning .checkbox, +.has-warning .radio-inline, +.has-warning .checkbox-inline { + color: #8a6d3b; +} +.has-warning .form-control { + border-color: #8a6d3b; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); +} +.has-warning .form-control:focus { + border-color: #66512c; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #c0a16b; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #c0a16b; +} +.has-warning .input-group-addon { + color: #8a6d3b; + background-color: #fcf8e3; + border-color: #8a6d3b; +} +.has-warning .form-control-feedback { + color: #8a6d3b; +} +.has-error .help-block, +.has-error .control-label, +.has-error .radio, +.has-error .checkbox, +.has-error .radio-inline, +.has-error .checkbox-inline { + color: #a94442; +} +.has-error .form-control { + border-color: #a94442; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); +} +.has-error .form-control:focus { + border-color: #843534; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #ce8483; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #ce8483; +} +.has-error .input-group-addon { + color: #a94442; + background-color: #f2dede; + border-color: #a94442; +} +.has-error .form-control-feedback { + color: #a94442; +} +.form-control-static { + margin-bottom: 0; +} +.help-block { + display: block; + margin-top: 5px; + margin-bottom: 10px; + color: #737373; +} +@media (min-width: 768px) { + .form-inline .form-group { + display: inline-block; + margin-bottom: 0; + vertical-align: middle; + } + .form-inline .form-control { + display: inline-block; + width: auto; + vertical-align: middle; + } + .form-inline .input-group > .form-control { + width: 100%; + } + .form-inline .control-label { + margin-bottom: 0; + vertical-align: middle; + } + .form-inline .radio, + .form-inline .checkbox { + display: inline-block; + padding-left: 0; + margin-top: 0; + margin-bottom: 0; + vertical-align: middle; + } + .form-inline .radio input[type="radio"], + .form-inline .checkbox input[type="checkbox"] { + float: none; + margin-left: 0; + } + .form-inline .has-feedback .form-control-feedback { + top: 0; + } +} +.form-horizontal .control-label, +.form-horizontal .radio, +.form-horizontal .checkbox, +.form-horizontal .radio-inline, +.form-horizontal .checkbox-inline { + padding-top: 7px; + margin-top: 0; + margin-bottom: 0; +} +.form-horizontal .radio, +.form-horizontal .checkbox { + min-height: 27px; +} +.form-horizontal .form-group { + margin-right: -15px; + margin-left: -15px; +} +.form-horizontal .form-control-static { + padding-top: 7px; +} +@media (min-width: 768px) { + .form-horizontal .control-label { + text-align: right; + } +} +.form-horizontal .has-feedback .form-control-feedback { + top: 0; + right: 15px; +} +.btn { + display: inline-block; + padding: 6px 12px; + margin-bottom: 0; + font-size: 14px; + font-weight: normal; + line-height: 1.42857143; + text-align: center; + white-space: nowrap; + vertical-align: middle; + cursor: pointer; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + background-image: none; + border: 1px solid transparent; + border-radius: 4px; +} +.btn:focus, +.btn:active:focus, +.btn.active:focus { + outline: thin dotted; + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; +} +.btn:hover, +.btn:focus { + color: #333; + text-decoration: none; +} +.btn:active, +.btn.active { + background-image: none; + outline: 0; + -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125); + box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125); +} +.btn.disabled, +.btn[disabled], +fieldset[disabled] .btn { + pointer-events: none; + cursor: not-allowed; + filter: alpha(opacity=65); + -webkit-box-shadow: none; + box-shadow: none; + opacity: .65; +} +.btn-default { + color: #333; + background-color: #fff; + border-color: #ccc; +} +.btn-default:hover, +.btn-default:focus, +.btn-default:active, +.btn-default.active, +.open .dropdown-toggle.btn-default { + color: #333; + background-color: #ebebeb; + border-color: #adadad; +} +.btn-default:active, +.btn-default.active, +.open .dropdown-toggle.btn-default { + background-image: none; +} +.btn-default.disabled, +.btn-default[disabled], +fieldset[disabled] .btn-default, +.btn-default.disabled:hover, +.btn-default[disabled]:hover, +fieldset[disabled] .btn-default:hover, +.btn-default.disabled:focus, +.btn-default[disabled]:focus, +fieldset[disabled] .btn-default:focus, +.btn-default.disabled:active, +.btn-default[disabled]:active, +fieldset[disabled] .btn-default:active, +.btn-default.disabled.active, +.btn-default[disabled].active, +fieldset[disabled] .btn-default.active { + background-color: #fff; + border-color: #ccc; +} +.btn-default .badge { + color: #fff; + background-color: #333; +} +.btn-primary { + color: #fff; + background-color: #428bca; + border-color: #357ebd; +} +.btn-primary:hover, +.btn-primary:focus, +.btn-primary:active, +.btn-primary.active, +.open .dropdown-toggle.btn-primary { + color: #fff; + background-color: #3276b1; + border-color: #285e8e; +} +.btn-primary:active, +.btn-primary.active, +.open .dropdown-toggle.btn-primary { + background-image: none; +} +.btn-primary.disabled, +.btn-primary[disabled], +fieldset[disabled] .btn-primary, +.btn-primary.disabled:hover, +.btn-primary[disabled]:hover, +fieldset[disabled] .btn-primary:hover, +.btn-primary.disabled:focus, +.btn-primary[disabled]:focus, +fieldset[disabled] .btn-primary:focus, +.btn-primary.disabled:active, +.btn-primary[disabled]:active, +fieldset[disabled] .btn-primary:active, +.btn-primary.disabled.active, +.btn-primary[disabled].active, +fieldset[disabled] .btn-primary.active { + background-color: #428bca; + border-color: #357ebd; +} +.btn-primary .badge { + color: #428bca; + background-color: #fff; +} +.btn-success { + color: #fff; + background-color: #5cb85c; + border-color: #4cae4c; +} +.btn-success:hover, +.btn-success:focus, +.btn-success:active, +.btn-success.active, +.open .dropdown-toggle.btn-success { + color: #fff; + background-color: #47a447; + border-color: #398439; +} +.btn-success:active, +.btn-success.active, +.open .dropdown-toggle.btn-success { + background-image: none; +} +.btn-success.disabled, +.btn-success[disabled], +fieldset[disabled] .btn-success, +.btn-success.disabled:hover, +.btn-success[disabled]:hover, +fieldset[disabled] .btn-success:hover, +.btn-success.disabled:focus, +.btn-success[disabled]:focus, +fieldset[disabled] .btn-success:focus, +.btn-success.disabled:active, +.btn-success[disabled]:active, +fieldset[disabled] .btn-success:active, +.btn-success.disabled.active, +.btn-success[disabled].active, +fieldset[disabled] .btn-success.active { + background-color: #5cb85c; + border-color: #4cae4c; +} +.btn-success .badge { + color: #5cb85c; + background-color: #fff; +} +.btn-info { + color: #fff; + background-color: #5bc0de; + border-color: #46b8da; +} +.btn-info:hover, +.btn-info:focus, +.btn-info:active, +.btn-info.active, +.open .dropdown-toggle.btn-info { + color: #fff; + background-color: #39b3d7; + border-color: #269abc; +} +.btn-info:active, +.btn-info.active, +.open .dropdown-toggle.btn-info { + background-image: none; +} +.btn-info.disabled, +.btn-info[disabled], +fieldset[disabled] .btn-info, +.btn-info.disabled:hover, +.btn-info[disabled]:hover, +fieldset[disabled] .btn-info:hover, +.btn-info.disabled:focus, +.btn-info[disabled]:focus, +fieldset[disabled] .btn-info:focus, +.btn-info.disabled:active, +.btn-info[disabled]:active, +fieldset[disabled] .btn-info:active, +.btn-info.disabled.active, +.btn-info[disabled].active, +fieldset[disabled] .btn-info.active { + background-color: #5bc0de; + border-color: #46b8da; +} +.btn-info .badge { + color: #5bc0de; + background-color: #fff; +} +.btn-warning { + color: #fff; + background-color: #f0ad4e; + border-color: #eea236; +} +.btn-warning:hover, +.btn-warning:focus, +.btn-warning:active, +.btn-warning.active, +.open .dropdown-toggle.btn-warning { + color: #fff; + background-color: #ed9c28; + border-color: #d58512; +} +.btn-warning:active, +.btn-warning.active, +.open .dropdown-toggle.btn-warning { + background-image: none; +} +.btn-warning.disabled, +.btn-warning[disabled], +fieldset[disabled] .btn-warning, +.btn-warning.disabled:hover, +.btn-warning[disabled]:hover, +fieldset[disabled] .btn-warning:hover, +.btn-warning.disabled:focus, +.btn-warning[disabled]:focus, +fieldset[disabled] .btn-warning:focus, +.btn-warning.disabled:active, +.btn-warning[disabled]:active, +fieldset[disabled] .btn-warning:active, +.btn-warning.disabled.active, +.btn-warning[disabled].active, +fieldset[disabled] .btn-warning.active { + background-color: #f0ad4e; + border-color: #eea236; +} +.btn-warning .badge { + color: #f0ad4e; + background-color: #fff; +} +.btn-danger { + color: #fff; + background-color: #d9534f; + border-color: #d43f3a; +} +.btn-danger:hover, +.btn-danger:focus, +.btn-danger:active, +.btn-danger.active, +.open .dropdown-toggle.btn-danger { + color: #fff; + background-color: #d2322d; + border-color: #ac2925; +} +.btn-danger:active, +.btn-danger.active, +.open .dropdown-toggle.btn-danger { + background-image: none; +} +.btn-danger.disabled, +.btn-danger[disabled], +fieldset[disabled] .btn-danger, +.btn-danger.disabled:hover, +.btn-danger[disabled]:hover, +fieldset[disabled] .btn-danger:hover, +.btn-danger.disabled:focus, +.btn-danger[disabled]:focus, +fieldset[disabled] .btn-danger:focus, +.btn-danger.disabled:active, +.btn-danger[disabled]:active, +fieldset[disabled] .btn-danger:active, +.btn-danger.disabled.active, +.btn-danger[disabled].active, +fieldset[disabled] .btn-danger.active { + background-color: #d9534f; + border-color: #d43f3a; +} +.btn-danger .badge { + color: #d9534f; + background-color: #fff; +} +.btn-link { + font-weight: normal; + color: #428bca; + cursor: pointer; + border-radius: 0; +} +.btn-link, +.btn-link:active, +.btn-link[disabled], +fieldset[disabled] .btn-link { + background-color: transparent; + -webkit-box-shadow: none; + box-shadow: none; +} +.btn-link, +.btn-link:hover, +.btn-link:focus, +.btn-link:active { + border-color: transparent; +} +.btn-link:hover, +.btn-link:focus { + color: #2a6496; + text-decoration: underline; + background-color: transparent; +} +.btn-link[disabled]:hover, +fieldset[disabled] .btn-link:hover, +.btn-link[disabled]:focus, +fieldset[disabled] .btn-link:focus { + color: #999; + text-decoration: none; +} +.btn-lg, +.btn-group-lg > .btn { + padding: 10px 16px; + font-size: 18px; + line-height: 1.33; + border-radius: 6px; +} +.btn-sm, +.btn-group-sm > .btn { + padding: 5px 10px; + font-size: 12px; + line-height: 1.5; + border-radius: 3px; +} +.btn-xs, +.btn-group-xs > .btn { + padding: 1px 5px; + font-size: 12px; + line-height: 1.5; + border-radius: 3px; +} +.btn-block { + display: block; + width: 100%; + padding-right: 0; + padding-left: 0; +} +.btn-block + .btn-block { + margin-top: 5px; +} +input[type="submit"].btn-block, +input[type="reset"].btn-block, +input[type="button"].btn-block { + width: 100%; +} +.fade { + opacity: 0; + -webkit-transition: opacity .15s linear; + transition: opacity .15s linear; +} +.fade.in { + opacity: 1; +} +.collapse { + display: none; +} +.collapse.in { + display: block; +} +.collapsing { + position: relative; + height: 0; + overflow: hidden; + -webkit-transition: height .35s ease; + transition: height .35s ease; +} +@font-face { + font-family: 'Glyphicons Halflings'; + + src: url('../fonts/glyphicons-halflings-regular.eot'); + src: url('../fonts/glyphicons-halflings-regular.eot?#iefix') format('embedded-opentype'), url('../fonts/glyphicons-halflings-regular.woff') format('woff'), url('../fonts/glyphicons-halflings-regular.ttf') format('truetype'), url('../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular') format('svg'); +} +.glyphicon { + position: relative; + top: 1px; + display: inline-block; + font-family: 'Glyphicons Halflings'; + font-style: normal; + font-weight: normal; + line-height: 1; + + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} +.glyphicon-asterisk:before { + content: "\2a"; +} +.glyphicon-plus:before { + content: "\2b"; +} +.glyphicon-euro:before { + content: "\20ac"; +} +.glyphicon-minus:before { + content: "\2212"; +} +.glyphicon-cloud:before { + content: "\2601"; +} +.glyphicon-envelope:before { + content: "\2709"; +} +.glyphicon-pencil:before { + content: "\270f"; +} +.glyphicon-glass:before { + content: "\e001"; +} +.glyphicon-music:before { + content: "\e002"; +} +.glyphicon-search:before { + content: "\e003"; +} +.glyphicon-heart:before { + content: "\e005"; +} +.glyphicon-star:before { + content: "\e006"; +} +.glyphicon-star-empty:before { + content: "\e007"; +} +.glyphicon-user:before { + content: "\e008"; +} +.glyphicon-film:before { + content: "\e009"; +} +.glyphicon-th-large:before { + content: "\e010"; +} +.glyphicon-th:before { + content: "\e011"; +} +.glyphicon-th-list:before { + content: "\e012"; +} +.glyphicon-ok:before { + content: "\e013"; +} +.glyphicon-remove:before { + content: "\e014"; +} +.glyphicon-zoom-in:before { + content: "\e015"; +} +.glyphicon-zoom-out:before { + content: "\e016"; +} +.glyphicon-off:before { + content: "\e017"; +} +.glyphicon-signal:before { + content: "\e018"; +} +.glyphicon-cog:before { + content: "\e019"; +} +.glyphicon-trash:before { + content: "\e020"; +} +.glyphicon-home:before { + content: "\e021"; +} +.glyphicon-file:before { + content: "\e022"; +} +.glyphicon-time:before { + content: "\e023"; +} +.glyphicon-road:before { + content: "\e024"; +} +.glyphicon-download-alt:before { + content: "\e025"; +} +.glyphicon-download:before { + content: "\e026"; +} +.glyphicon-upload:before { + content: "\e027"; +} +.glyphicon-inbox:before { + content: "\e028"; +} +.glyphicon-play-circle:before { + content: "\e029"; +} +.glyphicon-repeat:before { + content: "\e030"; +} +.glyphicon-refresh:before { + content: "\e031"; +} +.glyphicon-list-alt:before { + content: "\e032"; +} +.glyphicon-lock:before { + content: "\e033"; +} +.glyphicon-flag:before { + content: "\e034"; +} +.glyphicon-headphones:before { + content: "\e035"; +} +.glyphicon-volume-off:before { + content: "\e036"; +} +.glyphicon-volume-down:before { + content: "\e037"; +} +.glyphicon-volume-up:before { + content: "\e038"; +} +.glyphicon-qrcode:before { + content: "\e039"; +} +.glyphicon-barcode:before { + content: "\e040"; +} +.glyphicon-tag:before { + content: "\e041"; +} +.glyphicon-tags:before { + content: "\e042"; +} +.glyphicon-book:before { + content: "\e043"; +} +.glyphicon-bookmark:before { + content: "\e044"; +} +.glyphicon-print:before { + content: "\e045"; +} +.glyphicon-camera:before { + content: "\e046"; +} +.glyphicon-font:before { + content: "\e047"; +} +.glyphicon-bold:before { + content: "\e048"; +} +.glyphicon-italic:before { + content: "\e049"; +} +.glyphicon-text-height:before { + content: "\e050"; +} +.glyphicon-text-width:before { + content: "\e051"; +} +.glyphicon-align-left:before { + content: "\e052"; +} +.glyphicon-align-center:before { + content: "\e053"; +} +.glyphicon-align-right:before { + content: "\e054"; +} +.glyphicon-align-justify:before { + content: "\e055"; +} +.glyphicon-list:before { + content: "\e056"; +} +.glyphicon-indent-left:before { + content: "\e057"; +} +.glyphicon-indent-right:before { + content: "\e058"; +} +.glyphicon-facetime-video:before { + content: "\e059"; +} +.glyphicon-picture:before { + content: "\e060"; +} +.glyphicon-map-marker:before { + content: "\e062"; +} +.glyphicon-adjust:before { + content: "\e063"; +} +.glyphicon-tint:before { + content: "\e064"; +} +.glyphicon-edit:before { + content: "\e065"; +} +.glyphicon-share:before { + content: "\e066"; +} +.glyphicon-check:before { + content: "\e067"; +} +.glyphicon-move:before { + content: "\e068"; +} +.glyphicon-step-backward:before { + content: "\e069"; +} +.glyphicon-fast-backward:before { + content: "\e070"; +} +.glyphicon-backward:before { + content: "\e071"; +} +.glyphicon-play:before { + content: "\e072"; +} +.glyphicon-pause:before { + content: "\e073"; +} +.glyphicon-stop:before { + content: "\e074"; +} +.glyphicon-forward:before { + content: "\e075"; +} +.glyphicon-fast-forward:before { + content: "\e076"; +} +.glyphicon-step-forward:before { + content: "\e077"; +} +.glyphicon-eject:before { + content: "\e078"; +} +.glyphicon-chevron-left:before { + content: "\e079"; +} +.glyphicon-chevron-right:before { + content: "\e080"; +} +.glyphicon-plus-sign:before { + content: "\e081"; +} +.glyphicon-minus-sign:before { + content: "\e082"; +} +.glyphicon-remove-sign:before { + content: "\e083"; +} +.glyphicon-ok-sign:before { + content: "\e084"; +} +.glyphicon-question-sign:before { + content: "\e085"; +} +.glyphicon-info-sign:before { + content: "\e086"; +} +.glyphicon-screenshot:before { + content: "\e087"; +} +.glyphicon-remove-circle:before { + content: "\e088"; +} +.glyphicon-ok-circle:before { + content: "\e089"; +} +.glyphicon-ban-circle:before { + content: "\e090"; +} +.glyphicon-arrow-left:before { + content: "\e091"; +} +.glyphicon-arrow-right:before { + content: "\e092"; +} +.glyphicon-arrow-up:before { + content: "\e093"; +} +.glyphicon-arrow-down:before { + content: "\e094"; +} +.glyphicon-share-alt:before { + content: "\e095"; +} +.glyphicon-resize-full:before { + content: "\e096"; +} +.glyphicon-resize-small:before { + content: "\e097"; +} +.glyphicon-exclamation-sign:before { + content: "\e101"; +} +.glyphicon-gift:before { + content: "\e102"; +} +.glyphicon-leaf:before { + content: "\e103"; +} +.glyphicon-fire:before { + content: "\e104"; +} +.glyphicon-eye-open:before { + content: "\e105"; +} +.glyphicon-eye-close:before { + content: "\e106"; +} +.glyphicon-warning-sign:before { + content: "\e107"; +} +.glyphicon-plane:before { + content: "\e108"; +} +.glyphicon-calendar:before { + content: "\e109"; +} +.glyphicon-random:before { + content: "\e110"; +} +.glyphicon-comment:before { + content: "\e111"; +} +.glyphicon-magnet:before { + content: "\e112"; +} +.glyphicon-chevron-up:before { + content: "\e113"; +} +.glyphicon-chevron-down:before { + content: "\e114"; +} +.glyphicon-retweet:before { + content: "\e115"; +} +.glyphicon-shopping-cart:before { + content: "\e116"; +} +.glyphicon-folder-close:before { + content: "\e117"; +} +.glyphicon-folder-open:before { + content: "\e118"; +} +.glyphicon-resize-vertical:before { + content: "\e119"; +} +.glyphicon-resize-horizontal:before { + content: "\e120"; +} +.glyphicon-hdd:before { + content: "\e121"; +} +.glyphicon-bullhorn:before { + content: "\e122"; +} +.glyphicon-bell:before { + content: "\e123"; +} +.glyphicon-certificate:before { + content: "\e124"; +} +.glyphicon-thumbs-up:before { + content: "\e125"; +} +.glyphicon-thumbs-down:before { + content: "\e126"; +} +.glyphicon-hand-right:before { + content: "\e127"; +} +.glyphicon-hand-left:before { + content: "\e128"; +} +.glyphicon-hand-up:before { + content: "\e129"; +} +.glyphicon-hand-down:before { + content: "\e130"; +} +.glyphicon-circle-arrow-right:before { + content: "\e131"; +} +.glyphicon-circle-arrow-left:before { + content: "\e132"; +} +.glyphicon-circle-arrow-up:before { + content: "\e133"; +} +.glyphicon-circle-arrow-down:before { + content: "\e134"; +} +.glyphicon-globe:before { + content: "\e135"; +} +.glyphicon-wrench:before { + content: "\e136"; +} +.glyphicon-tasks:before { + content: "\e137"; +} +.glyphicon-filter:before { + content: "\e138"; +} +.glyphicon-briefcase:before { + content: "\e139"; +} +.glyphicon-fullscreen:before { + content: "\e140"; +} +.glyphicon-dashboard:before { + content: "\e141"; +} +.glyphicon-paperclip:before { + content: "\e142"; +} +.glyphicon-heart-empty:before { + content: "\e143"; +} +.glyphicon-link:before { + content: "\e144"; +} +.glyphicon-phone:before { + content: "\e145"; +} +.glyphicon-pushpin:before { + content: "\e146"; +} +.glyphicon-usd:before { + content: "\e148"; +} +.glyphicon-gbp:before { + content: "\e149"; +} +.glyphicon-sort:before { + content: "\e150"; +} +.glyphicon-sort-by-alphabet:before { + content: "\e151"; +} +.glyphicon-sort-by-alphabet-alt:before { + content: "\e152"; +} +.glyphicon-sort-by-order:before { + content: "\e153"; +} +.glyphicon-sort-by-order-alt:before { + content: "\e154"; +} +.glyphicon-sort-by-attributes:before { + content: "\e155"; +} +.glyphicon-sort-by-attributes-alt:before { + content: "\e156"; +} +.glyphicon-unchecked:before { + content: "\e157"; +} +.glyphicon-expand:before { + content: "\e158"; +} +.glyphicon-collapse-down:before { + content: "\e159"; +} +.glyphicon-collapse-up:before { + content: "\e160"; +} +.glyphicon-log-in:before { + content: "\e161"; +} +.glyphicon-flash:before { + content: "\e162"; +} +.glyphicon-log-out:before { + content: "\e163"; +} +.glyphicon-new-window:before { + content: "\e164"; +} +.glyphicon-record:before { + content: "\e165"; +} +.glyphicon-save:before { + content: "\e166"; +} +.glyphicon-open:before { + content: "\e167"; +} +.glyphicon-saved:before { + content: "\e168"; +} +.glyphicon-import:before { + content: "\e169"; +} +.glyphicon-export:before { + content: "\e170"; +} +.glyphicon-send:before { + content: "\e171"; +} +.glyphicon-floppy-disk:before { + content: "\e172"; +} +.glyphicon-floppy-saved:before { + content: "\e173"; +} +.glyphicon-floppy-remove:before { + content: "\e174"; +} +.glyphicon-floppy-save:before { + content: "\e175"; +} +.glyphicon-floppy-open:before { + content: "\e176"; +} +.glyphicon-credit-card:before { + content: "\e177"; +} +.glyphicon-transfer:before { + content: "\e178"; +} +.glyphicon-cutlery:before { + content: "\e179"; +} +.glyphicon-header:before { + content: "\e180"; +} +.glyphicon-compressed:before { + content: "\e181"; +} +.glyphicon-earphone:before { + content: "\e182"; +} +.glyphicon-phone-alt:before { + content: "\e183"; +} +.glyphicon-tower:before { + content: "\e184"; +} +.glyphicon-stats:before { + content: "\e185"; +} +.glyphicon-sd-video:before { + content: "\e186"; +} +.glyphicon-hd-video:before { + content: "\e187"; +} +.glyphicon-subtitles:before { + content: "\e188"; +} +.glyphicon-sound-stereo:before { + content: "\e189"; +} +.glyphicon-sound-dolby:before { + content: "\e190"; +} +.glyphicon-sound-5-1:before { + content: "\e191"; +} +.glyphicon-sound-6-1:before { + content: "\e192"; +} +.glyphicon-sound-7-1:before { + content: "\e193"; +} +.glyphicon-copyright-mark:before { + content: "\e194"; +} +.glyphicon-registration-mark:before { + content: "\e195"; +} +.glyphicon-cloud-download:before { + content: "\e197"; +} +.glyphicon-cloud-upload:before { + content: "\e198"; +} +.glyphicon-tree-conifer:before { + content: "\e199"; +} +.glyphicon-tree-deciduous:before { + content: "\e200"; +} +.caret { + display: inline-block; + width: 0; + height: 0; + margin-left: 2px; + vertical-align: middle; + border-top: 4px solid; + border-right: 4px solid transparent; + border-left: 4px solid transparent; +} +.dropdown { + position: relative; +} +.dropdown-toggle:focus { + outline: 0; +} +.dropdown-menu { + position: absolute; + top: 100%; + left: 0; + z-index: 1000; + display: none; + float: left; + min-width: 160px; + padding: 5px 0; + margin: 2px 0 0; + font-size: 14px; + list-style: none; + background-color: #fff; + background-clip: padding-box; + border: 1px solid #ccc; + border: 1px solid rgba(0, 0, 0, .15); + border-radius: 4px; + -webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, .175); + box-shadow: 0 6px 12px rgba(0, 0, 0, .175); +} +.dropdown-menu.pull-right { + right: 0; + left: auto; +} +.dropdown-menu .divider { + height: 1px; + margin: 9px 0; + overflow: hidden; + background-color: #e5e5e5; +} +.dropdown-menu > li > a { + display: block; + padding: 3px 20px; + clear: both; + font-weight: normal; + line-height: 1.42857143; + color: #333; + white-space: nowrap; +} +.dropdown-menu > li > a:hover, +.dropdown-menu > li > a:focus { + color: #262626; + text-decoration: none; + background-color: #f5f5f5; +} +.dropdown-menu > .active > a, +.dropdown-menu > .active > a:hover, +.dropdown-menu > .active > a:focus { + color: #fff; + text-decoration: none; + background-color: #428bca; + outline: 0; +} +.dropdown-menu > .disabled > a, +.dropdown-menu > .disabled > a:hover, +.dropdown-menu > .disabled > a:focus { + color: #999; +} +.dropdown-menu > .disabled > a:hover, +.dropdown-menu > .disabled > a:focus { + text-decoration: none; + cursor: not-allowed; + background-color: transparent; + background-image: none; + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); +} +.open > .dropdown-menu { + display: block; +} +.open > a { + outline: 0; +} +.dropdown-menu-right { + right: 0; + left: auto; +} +.dropdown-menu-left { + right: auto; + left: 0; +} +.dropdown-header { + display: block; + padding: 3px 20px; + font-size: 12px; + line-height: 1.42857143; + color: #999; +} +.dropdown-backdrop { + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 990; +} +.pull-right > .dropdown-menu { + right: 0; + left: auto; +} +.dropup .caret, +.navbar-fixed-bottom .dropdown .caret { + content: ""; + border-top: 0; + border-bottom: 4px solid; +} +.dropup .dropdown-menu, +.navbar-fixed-bottom .dropdown .dropdown-menu { + top: auto; + bottom: 100%; + margin-bottom: 1px; +} +@media (min-width: 768px) { + .navbar-right .dropdown-menu { + right: 0; + left: auto; + } + .navbar-right .dropdown-menu-left { + right: auto; + left: 0; + } +} +.btn-group, +.btn-group-vertical { + position: relative; + display: inline-block; + vertical-align: middle; +} +.btn-group > .btn, +.btn-group-vertical > .btn { + position: relative; + float: left; +} +.btn-group > .btn:hover, +.btn-group-vertical > .btn:hover, +.btn-group > .btn:focus, +.btn-group-vertical > .btn:focus, +.btn-group > .btn:active, +.btn-group-vertical > .btn:active, +.btn-group > .btn.active, +.btn-group-vertical > .btn.active { + z-index: 2; +} +.btn-group > .btn:focus, +.btn-group-vertical > .btn:focus { + outline: none; +} +.btn-group .btn + .btn, +.btn-group .btn + .btn-group, +.btn-group .btn-group + .btn, +.btn-group .btn-group + .btn-group { + margin-left: -1px; +} +.btn-toolbar { + margin-left: -5px; +} +.btn-toolbar .btn-group, +.btn-toolbar .input-group { + float: left; +} +.btn-toolbar > .btn, +.btn-toolbar > .btn-group, +.btn-toolbar > .input-group { + margin-left: 5px; +} +.btn-group > .btn:not(:first-child):not(:last-child):not(.dropdown-toggle) { + border-radius: 0; +} +.btn-group > .btn:first-child { + margin-left: 0; +} +.btn-group > .btn:first-child:not(:last-child):not(.dropdown-toggle) { + border-top-right-radius: 0; + border-bottom-right-radius: 0; +} +.btn-group > .btn:last-child:not(:first-child), +.btn-group > .dropdown-toggle:not(:first-child) { + border-top-left-radius: 0; + border-bottom-left-radius: 0; +} +.btn-group > .btn-group { + float: left; +} +.btn-group > .btn-group:not(:first-child):not(:last-child) > .btn { + border-radius: 0; +} +.btn-group > .btn-group:first-child > .btn:last-child, +.btn-group > .btn-group:first-child > .dropdown-toggle { + border-top-right-radius: 0; + border-bottom-right-radius: 0; +} +.btn-group > .btn-group:last-child > .btn:first-child { + border-top-left-radius: 0; + border-bottom-left-radius: 0; +} +.btn-group .dropdown-toggle:active, +.btn-group.open .dropdown-toggle { + outline: 0; +} +.btn-group > .btn + .dropdown-toggle { + padding-right: 8px; + padding-left: 8px; +} +.btn-group > .btn-lg + .dropdown-toggle { + padding-right: 12px; + padding-left: 12px; +} +.btn-group.open .dropdown-toggle { + -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125); + box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125); +} +.btn-group.open .dropdown-toggle.btn-link { + -webkit-box-shadow: none; + box-shadow: none; +} +.btn .caret { + margin-left: 0; +} +.btn-lg .caret { + border-width: 5px 5px 0; + border-bottom-width: 0; +} +.dropup .btn-lg .caret { + border-width: 0 5px 5px; +} +.btn-group-vertical > .btn, +.btn-group-vertical > .btn-group, +.btn-group-vertical > .btn-group > .btn { + display: block; + float: none; + width: 100%; + max-width: 100%; +} +.btn-group-vertical > .btn-group > .btn { + float: none; +} +.btn-group-vertical > .btn + .btn, +.btn-group-vertical > .btn + .btn-group, +.btn-group-vertical > .btn-group + .btn, +.btn-group-vertical > .btn-group + .btn-group { + margin-top: -1px; + margin-left: 0; +} +.btn-group-vertical > .btn:not(:first-child):not(:last-child) { + border-radius: 0; +} +.btn-group-vertical > .btn:first-child:not(:last-child) { + border-top-right-radius: 4px; + border-bottom-right-radius: 0; + border-bottom-left-radius: 0; +} +.btn-group-vertical > .btn:last-child:not(:first-child) { + border-top-left-radius: 0; + border-top-right-radius: 0; + border-bottom-left-radius: 4px; +} +.btn-group-vertical > .btn-group:not(:first-child):not(:last-child) > .btn { + border-radius: 0; +} +.btn-group-vertical > .btn-group:first-child:not(:last-child) > .btn:last-child, +.btn-group-vertical > .btn-group:first-child:not(:last-child) > .dropdown-toggle { + border-bottom-right-radius: 0; + border-bottom-left-radius: 0; +} +.btn-group-vertical > .btn-group:last-child:not(:first-child) > .btn:first-child { + border-top-left-radius: 0; + border-top-right-radius: 0; +} +.btn-group-justified { + display: table; + width: 100%; + table-layout: fixed; + border-collapse: separate; +} +.btn-group-justified > .btn, +.btn-group-justified > .btn-group { + display: table-cell; + float: none; + width: 1%; +} +.btn-group-justified > .btn-group .btn { + width: 100%; +} +[data-toggle="buttons"] > .btn > input[type="radio"], +[data-toggle="buttons"] > .btn > input[type="checkbox"] { + display: none; +} +.input-group { + position: relative; + display: table; + border-collapse: separate; +} +.input-group[class*="col-"] { + float: none; + padding-right: 0; + padding-left: 0; +} +.input-group .form-control { + position: relative; + z-index: 2; + float: left; + width: 100%; + margin-bottom: 0; +} +.input-group-lg > .form-control, +.input-group-lg > .input-group-addon, +.input-group-lg > .input-group-btn > .btn { + height: 46px; + padding: 10px 16px; + font-size: 18px; + line-height: 1.33; + border-radius: 6px; +} +select.input-group-lg > .form-control, +select.input-group-lg > .input-group-addon, +select.input-group-lg > .input-group-btn > .btn { + height: 46px; + line-height: 46px; +} +textarea.input-group-lg > .form-control, +textarea.input-group-lg > .input-group-addon, +textarea.input-group-lg > .input-group-btn > .btn, +select[multiple].input-group-lg > .form-control, +select[multiple].input-group-lg > .input-group-addon, +select[multiple].input-group-lg > .input-group-btn > .btn { + height: auto; +} +.input-group-sm > .form-control, +.input-group-sm > .input-group-addon, +.input-group-sm > .input-group-btn > .btn { + height: 30px; + padding: 5px 10px; + font-size: 12px; + line-height: 1.5; + border-radius: 3px; +} +select.input-group-sm > .form-control, +select.input-group-sm > .input-group-addon, +select.input-group-sm > .input-group-btn > .btn { + height: 30px; + line-height: 30px; +} +textarea.input-group-sm > .form-control, +textarea.input-group-sm > .input-group-addon, +textarea.input-group-sm > .input-group-btn > .btn, +select[multiple].input-group-sm > .form-control, +select[multiple].input-group-sm > .input-group-addon, +select[multiple].input-group-sm > .input-group-btn > .btn { + height: auto; +} +.input-group-addon, +.input-group-btn, +.input-group .form-control { + display: table-cell; +} +.input-group-addon:not(:first-child):not(:last-child), +.input-group-btn:not(:first-child):not(:last-child), +.input-group .form-control:not(:first-child):not(:last-child) { + border-radius: 0; +} +.input-group-addon, +.input-group-btn { + width: 1%; + white-space: nowrap; + vertical-align: middle; +} +.input-group-addon { + padding: 6px 12px; + font-size: 14px; + font-weight: normal; + line-height: 1; + color: #555; + text-align: center; + background-color: #eee; + border: 1px solid #ccc; + border-radius: 4px; +} +.input-group-addon.input-sm { + padding: 5px 10px; + font-size: 12px; + border-radius: 3px; +} +.input-group-addon.input-lg { + padding: 10px 16px; + font-size: 18px; + border-radius: 6px; +} +.input-group-addon input[type="radio"], +.input-group-addon input[type="checkbox"] { + margin-top: 0; +} +.input-group .form-control:first-child, +.input-group-addon:first-child, +.input-group-btn:first-child > .btn, +.input-group-btn:first-child > .btn-group > .btn, +.input-group-btn:first-child > .dropdown-toggle, +.input-group-btn:last-child > .btn:not(:last-child):not(.dropdown-toggle), +.input-group-btn:last-child > .btn-group:not(:last-child) > .btn { + border-top-right-radius: 0; + border-bottom-right-radius: 0; +} +.input-group-addon:first-child { + border-right: 0; +} +.input-group .form-control:last-child, +.input-group-addon:last-child, +.input-group-btn:last-child > .btn, +.input-group-btn:last-child > .btn-group > .btn, +.input-group-btn:last-child > .dropdown-toggle, +.input-group-btn:first-child > .btn:not(:first-child), +.input-group-btn:first-child > .btn-group:not(:first-child) > .btn { + border-top-left-radius: 0; + border-bottom-left-radius: 0; +} +.input-group-addon:last-child { + border-left: 0; +} +.input-group-btn { + position: relative; + font-size: 0; + white-space: nowrap; +} +.input-group-btn > .btn { + position: relative; +} +.input-group-btn > .btn + .btn { + margin-left: -1px; +} +.input-group-btn > .btn:hover, +.input-group-btn > .btn:focus, +.input-group-btn > .btn:active { + z-index: 2; +} +.input-group-btn:first-child > .btn, +.input-group-btn:first-child > .btn-group { + margin-right: -1px; +} +.input-group-btn:last-child > .btn, +.input-group-btn:last-child > .btn-group { + margin-left: -1px; +} +.nav { + padding-left: 0; + margin-bottom: 0; + list-style: none; +} +.nav > li { + position: relative; + display: block; +} +.nav > li > a { + position: relative; + display: block; + padding: 10px 15px; +} +.nav > li > a:hover, +.nav > li > a:focus { + text-decoration: none; + background-color: #eee; +} +.nav > li.disabled > a { + color: #999; +} +.nav > li.disabled > a:hover, +.nav > li.disabled > a:focus { + color: #999; + text-decoration: none; + cursor: not-allowed; + background-color: transparent; +} +.nav .open > a, +.nav .open > a:hover, +.nav .open > a:focus { + background-color: #eee; + border-color: #428bca; +} +.nav .nav-divider { + height: 1px; + margin: 9px 0; + overflow: hidden; + background-color: #e5e5e5; +} +.nav > li > a > img { + max-width: none; +} +.nav-tabs { + border-bottom: 1px solid #ddd; +} +.nav-tabs > li { + float: left; + margin-bottom: -1px; +} +.nav-tabs > li > a { + margin-right: 2px; + line-height: 1.42857143; + border: 1px solid transparent; + border-radius: 4px 4px 0 0; +} +.nav-tabs > li > a:hover { + border-color: #eee #eee #ddd; +} +.nav-tabs > li.active > a, +.nav-tabs > li.active > a:hover, +.nav-tabs > li.active > a:focus { + color: #555; + cursor: default; + background-color: #fff; + border: 1px solid #ddd; + border-bottom-color: transparent; +} +.nav-tabs.nav-justified { + width: 100%; + border-bottom: 0; +} +.nav-tabs.nav-justified > li { + float: none; +} +.nav-tabs.nav-justified > li > a { + margin-bottom: 5px; + text-align: center; +} +.nav-tabs.nav-justified > .dropdown .dropdown-menu { + top: auto; + left: auto; +} +@media (min-width: 768px) { + .nav-tabs.nav-justified > li { + display: table-cell; + width: 1%; + } + .nav-tabs.nav-justified > li > a { + margin-bottom: 0; + } +} +.nav-tabs.nav-justified > li > a { + margin-right: 0; + border-radius: 4px; +} +.nav-tabs.nav-justified > .active > a, +.nav-tabs.nav-justified > .active > a:hover, +.nav-tabs.nav-justified > .active > a:focus { + border: 1px solid #ddd; +} +@media (min-width: 768px) { + .nav-tabs.nav-justified > li > a { + border-bottom: 1px solid #ddd; + border-radius: 4px 4px 0 0; + } + .nav-tabs.nav-justified > .active > a, + .nav-tabs.nav-justified > .active > a:hover, + .nav-tabs.nav-justified > .active > a:focus { + border-bottom-color: #fff; + } +} +.nav-pills > li { + float: left; +} +.nav-pills > li > a { + border-radius: 4px; +} +.nav-pills > li + li { + margin-left: 2px; +} +.nav-pills > li.active > a, +.nav-pills > li.active > a:hover, +.nav-pills > li.active > a:focus { + color: #fff; + background-color: #428bca; +} +.nav-stacked > li { + float: none; +} +.nav-stacked > li + li { + margin-top: 2px; + margin-left: 0; +} +.nav-justified { + width: 100%; +} +.nav-justified > li { + float: none; +} +.nav-justified > li > a { + margin-bottom: 5px; + text-align: center; +} +.nav-justified > .dropdown .dropdown-menu { + top: auto; + left: auto; +} +@media (min-width: 768px) { + .nav-justified > li { + display: table-cell; + width: 1%; + } + .nav-justified > li > a { + margin-bottom: 0; + } +} +.nav-tabs-justified { + border-bottom: 0; +} +.nav-tabs-justified > li > a { + margin-right: 0; + border-radius: 4px; +} +.nav-tabs-justified > .active > a, +.nav-tabs-justified > .active > a:hover, +.nav-tabs-justified > .active > a:focus { + border: 1px solid #ddd; +} +@media (min-width: 768px) { + .nav-tabs-justified > li > a { + border-bottom: 1px solid #ddd; + border-radius: 4px 4px 0 0; + } + .nav-tabs-justified > .active > a, + .nav-tabs-justified > .active > a:hover, + .nav-tabs-justified > .active > a:focus { + border-bottom-color: #fff; + } +} +.tab-content > .tab-pane { + display: none; +} +.tab-content > .active { + display: block; +} +.nav-tabs .dropdown-menu { + margin-top: -1px; + border-top-left-radius: 0; + border-top-right-radius: 0; +} +.navbar { + position: relative; + min-height: 50px; + margin-bottom: 20px; + border: 1px solid transparent; +} +@media (min-width: 768px) { + .navbar { + border-radius: 4px; + } +} +@media (min-width: 768px) { + .navbar-header { + float: left; + } +} +.navbar-collapse { + max-height: 340px; + padding-right: 15px; + padding-left: 15px; + overflow-x: visible; + -webkit-overflow-scrolling: touch; + border-top: 1px solid transparent; + box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1); +} +.navbar-collapse.in { + overflow-y: auto; +} +@media (min-width: 768px) { + .navbar-collapse { + width: auto; + border-top: 0; + box-shadow: none; + } + .navbar-collapse.collapse { + display: block !important; + height: auto !important; + padding-bottom: 0; + overflow: visible !important; + } + .navbar-collapse.in { + overflow-y: visible; + } + .navbar-fixed-top .navbar-collapse, + .navbar-static-top .navbar-collapse, + .navbar-fixed-bottom .navbar-collapse { + padding-right: 0; + padding-left: 0; + } +} +.container > .navbar-header, +.container-fluid > .navbar-header, +.container > .navbar-collapse, +.container-fluid > .navbar-collapse { + margin-right: -15px; + margin-left: -15px; +} +@media (min-width: 768px) { + .container > .navbar-header, + .container-fluid > .navbar-header, + .container > .navbar-collapse, + .container-fluid > .navbar-collapse { + margin-right: 0; + margin-left: 0; + } +} +.navbar-static-top { + z-index: 1000; + border-width: 0 0 1px; +} +@media (min-width: 768px) { + .navbar-static-top { + border-radius: 0; + } +} +.navbar-fixed-top, +.navbar-fixed-bottom { + position: fixed; + right: 0; + left: 0; + z-index: 1030; +} +@media (min-width: 768px) { + .navbar-fixed-top, + .navbar-fixed-bottom { + border-radius: 0; + } +} +.navbar-fixed-top { + top: 0; + border-width: 0 0 1px; +} +.navbar-fixed-bottom { + bottom: 0; + margin-bottom: 0; + border-width: 1px 0 0; +} +.navbar-brand { + float: left; + height: 50px; + padding: 15px 15px; + font-size: 18px; + line-height: 20px; +} +.navbar-brand:hover, +.navbar-brand:focus { + text-decoration: none; +} +@media (min-width: 768px) { + .navbar > .container .navbar-brand, + .navbar > .container-fluid .navbar-brand { + margin-left: -15px; + } +} +.navbar-toggle { + position: relative; + float: right; + padding: 9px 10px; + margin-top: 8px; + margin-right: 15px; + margin-bottom: 8px; + background-color: transparent; + background-image: none; + border: 1px solid transparent; + border-radius: 4px; +} +.navbar-toggle:focus { + outline: none; +} +.navbar-toggle .icon-bar { + display: block; + width: 22px; + height: 2px; + border-radius: 1px; +} +.navbar-toggle .icon-bar + .icon-bar { + margin-top: 4px; +} +@media (min-width: 768px) { + .navbar-toggle { + display: none; + } +} +.navbar-nav { + margin: 7.5px -15px; +} +.navbar-nav > li > a { + padding-top: 10px; + padding-bottom: 10px; + line-height: 20px; +} +@media (max-width: 767px) { + .navbar-nav .open .dropdown-menu { + position: static; + float: none; + width: auto; + margin-top: 0; + background-color: transparent; + border: 0; + box-shadow: none; + } + .navbar-nav .open .dropdown-menu > li > a, + .navbar-nav .open .dropdown-menu .dropdown-header { + padding: 5px 15px 5px 25px; + } + .navbar-nav .open .dropdown-menu > li > a { + line-height: 20px; + } + .navbar-nav .open .dropdown-menu > li > a:hover, + .navbar-nav .open .dropdown-menu > li > a:focus { + background-image: none; + } +} +@media (min-width: 768px) { + .navbar-nav { + float: left; + margin: 0; + } + .navbar-nav > li { + float: left; + } + .navbar-nav > li > a { + padding-top: 15px; + padding-bottom: 15px; + } + .navbar-nav.navbar-right:last-child { + margin-right: -15px; + } +} +@media (min-width: 768px) { + .navbar-left { + float: left !important; + } + .navbar-right { + float: right !important; + } +} +.navbar-form { + padding: 10px 15px; + margin-top: 8px; + margin-right: -15px; + margin-bottom: 8px; + margin-left: -15px; + border-top: 1px solid transparent; + border-bottom: 1px solid transparent; + -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1), 0 1px 0 rgba(255, 255, 255, .1); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1), 0 1px 0 rgba(255, 255, 255, .1); +} +@media (min-width: 768px) { + .navbar-form .form-group { + display: inline-block; + margin-bottom: 0; + vertical-align: middle; + } + .navbar-form .form-control { + display: inline-block; + width: auto; + vertical-align: middle; + } + .navbar-form .input-group > .form-control { + width: 100%; + } + .navbar-form .control-label { + margin-bottom: 0; + vertical-align: middle; + } + .navbar-form .radio, + .navbar-form .checkbox { + display: inline-block; + padding-left: 0; + margin-top: 0; + margin-bottom: 0; + vertical-align: middle; + } + .navbar-form .radio input[type="radio"], + .navbar-form .checkbox input[type="checkbox"] { + float: none; + margin-left: 0; + } + .navbar-form .has-feedback .form-control-feedback { + top: 0; + } +} +@media (max-width: 767px) { + .navbar-form .form-group { + margin-bottom: 5px; + } +} +@media (min-width: 768px) { + .navbar-form { + width: auto; + padding-top: 0; + padding-bottom: 0; + margin-right: 0; + margin-left: 0; + border: 0; + -webkit-box-shadow: none; + box-shadow: none; + } + .navbar-form.navbar-right:last-child { + margin-right: -15px; + } +} +.navbar-nav > li > .dropdown-menu { + margin-top: 0; + border-top-left-radius: 0; + border-top-right-radius: 0; +} +.navbar-fixed-bottom .navbar-nav > li > .dropdown-menu { + border-bottom-right-radius: 0; + border-bottom-left-radius: 0; +} +.navbar-btn { + margin-top: 8px; + margin-bottom: 8px; +} +.navbar-btn.btn-sm { + margin-top: 10px; + margin-bottom: 10px; +} +.navbar-btn.btn-xs { + margin-top: 14px; + margin-bottom: 14px; +} +.navbar-text { + margin-top: 15px; + margin-bottom: 15px; +} +@media (min-width: 768px) { + .navbar-text { + float: left; + margin-right: 15px; + margin-left: 15px; + } + .navbar-text.navbar-right:last-child { + margin-right: 0; + } +} +.navbar-default { + background-color: #f8f8f8; + border-color: #e7e7e7; +} +.navbar-default .navbar-brand { + color: #777; +} +.navbar-default .navbar-brand:hover, +.navbar-default .navbar-brand:focus { + color: #5e5e5e; + background-color: transparent; +} +.navbar-default .navbar-text { + color: #777; +} +.navbar-default .navbar-nav > li > a { + color: #777; +} +.navbar-default .navbar-nav > li > a:hover, +.navbar-default .navbar-nav > li > a:focus { + color: #333; + background-color: transparent; +} +.navbar-default .navbar-nav > .active > a, +.navbar-default .navbar-nav > .active > a:hover, +.navbar-default .navbar-nav > .active > a:focus { + color: #555; + background-color: #e7e7e7; +} +.navbar-default .navbar-nav > .disabled > a, +.navbar-default .navbar-nav > .disabled > a:hover, +.navbar-default .navbar-nav > .disabled > a:focus { + color: #ccc; + background-color: transparent; +} +.navbar-default .navbar-toggle { + border-color: #ddd; +} +.navbar-default .navbar-toggle:hover, +.navbar-default .navbar-toggle:focus { + background-color: #ddd; +} +.navbar-default .navbar-toggle .icon-bar { + background-color: #888; +} +.navbar-default .navbar-collapse, +.navbar-default .navbar-form { + border-color: #e7e7e7; +} +.navbar-default .navbar-nav > .open > a, +.navbar-default .navbar-nav > .open > a:hover, +.navbar-default .navbar-nav > .open > a:focus { + color: #555; + background-color: #e7e7e7; +} +@media (max-width: 767px) { + .navbar-default .navbar-nav .open .dropdown-menu > li > a { + color: #777; + } + .navbar-default .navbar-nav .open .dropdown-menu > li > a:hover, + .navbar-default .navbar-nav .open .dropdown-menu > li > a:focus { + color: #333; + background-color: transparent; + } + .navbar-default .navbar-nav .open .dropdown-menu > .active > a, + .navbar-default .navbar-nav .open .dropdown-menu > .active > a:hover, + .navbar-default .navbar-nav .open .dropdown-menu > .active > a:focus { + color: #555; + background-color: #e7e7e7; + } + .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a, + .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:hover, + .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:focus { + color: #ccc; + background-color: transparent; + } +} +.navbar-default .navbar-link { + color: #777; +} +.navbar-default .navbar-link:hover { + color: #333; +} +.navbar-inverse { + background-color: #222; + border-color: #080808; +} +.navbar-inverse .navbar-brand { + color: #999; +} +.navbar-inverse .navbar-brand:hover, +.navbar-inverse .navbar-brand:focus { + color: #fff; + background-color: transparent; +} +.navbar-inverse .navbar-text { + color: #999; +} +.navbar-inverse .navbar-nav > li > a { + color: #999; +} +.navbar-inverse .navbar-nav > li > a:hover, +.navbar-inverse .navbar-nav > li > a:focus { + color: #fff; + background-color: transparent; +} +.navbar-inverse .navbar-nav > .active > a, +.navbar-inverse .navbar-nav > .active > a:hover, +.navbar-inverse .navbar-nav > .active > a:focus { + color: #fff; + background-color: #080808; +} +.navbar-inverse .navbar-nav > .disabled > a, +.navbar-inverse .navbar-nav > .disabled > a:hover, +.navbar-inverse .navbar-nav > .disabled > a:focus { + color: #444; + background-color: transparent; +} +.navbar-inverse .navbar-toggle { + border-color: #333; +} +.navbar-inverse .navbar-toggle:hover, +.navbar-inverse .navbar-toggle:focus { + background-color: #333; +} +.navbar-inverse .navbar-toggle .icon-bar { + background-color: #fff; +} +.navbar-inverse .navbar-collapse, +.navbar-inverse .navbar-form { + border-color: #101010; +} +.navbar-inverse .navbar-nav > .open > a, +.navbar-inverse .navbar-nav > .open > a:hover, +.navbar-inverse .navbar-nav > .open > a:focus { + color: #fff; + background-color: #080808; +} +@media (max-width: 767px) { + .navbar-inverse .navbar-nav .open .dropdown-menu > .dropdown-header { + border-color: #080808; + } + .navbar-inverse .navbar-nav .open .dropdown-menu .divider { + background-color: #080808; + } + .navbar-inverse .navbar-nav .open .dropdown-menu > li > a { + color: #999; + } + .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:hover, + .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:focus { + color: #fff; + background-color: transparent; + } + .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a, + .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:hover, + .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:focus { + color: #fff; + background-color: #080808; + } + .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a, + .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:hover, + .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:focus { + color: #444; + background-color: transparent; + } +} +.navbar-inverse .navbar-link { + color: #999; +} +.navbar-inverse .navbar-link:hover { + color: #fff; +} +.breadcrumb { + padding: 8px 15px; + margin-bottom: 20px; + list-style: none; + background-color: #f5f5f5; + border-radius: 4px; +} +.breadcrumb > li { + display: inline-block; +} +.breadcrumb > li + li:before { + padding: 0 5px; + color: #ccc; + content: "/\00a0"; +} +.breadcrumb > .active { + color: #999; +} +.pagination { + display: inline-block; + padding-left: 0; + margin: 20px 0; + border-radius: 4px; +} +.pagination > li { + display: inline; +} +.pagination > li > a, +.pagination > li > span { + position: relative; + float: left; + padding: 6px 12px; + margin-left: -1px; + line-height: 1.42857143; + color: #428bca; + text-decoration: none; + background-color: #fff; + border: 1px solid #ddd; +} +.pagination > li:first-child > a, +.pagination > li:first-child > span { + margin-left: 0; + border-top-left-radius: 4px; + border-bottom-left-radius: 4px; +} +.pagination > li:last-child > a, +.pagination > li:last-child > span { + border-top-right-radius: 4px; + border-bottom-right-radius: 4px; +} +.pagination > li > a:hover, +.pagination > li > span:hover, +.pagination > li > a:focus, +.pagination > li > span:focus { + color: #2a6496; + background-color: #eee; + border-color: #ddd; +} +.pagination > .active > a, +.pagination > .active > span, +.pagination > .active > a:hover, +.pagination > .active > span:hover, +.pagination > .active > a:focus, +.pagination > .active > span:focus { + z-index: 2; + color: #fff; + cursor: default; + background-color: #428bca; + border-color: #428bca; +} +.pagination > .disabled > span, +.pagination > .disabled > span:hover, +.pagination > .disabled > span:focus, +.pagination > .disabled > a, +.pagination > .disabled > a:hover, +.pagination > .disabled > a:focus { + color: #999; + cursor: not-allowed; + background-color: #fff; + border-color: #ddd; +} +.pagination-lg > li > a, +.pagination-lg > li > span { + padding: 10px 16px; + font-size: 18px; +} +.pagination-lg > li:first-child > a, +.pagination-lg > li:first-child > span { + border-top-left-radius: 6px; + border-bottom-left-radius: 6px; +} +.pagination-lg > li:last-child > a, +.pagination-lg > li:last-child > span { + border-top-right-radius: 6px; + border-bottom-right-radius: 6px; +} +.pagination-sm > li > a, +.pagination-sm > li > span { + padding: 5px 10px; + font-size: 12px; +} +.pagination-sm > li:first-child > a, +.pagination-sm > li:first-child > span { + border-top-left-radius: 3px; + border-bottom-left-radius: 3px; +} +.pagination-sm > li:last-child > a, +.pagination-sm > li:last-child > span { + border-top-right-radius: 3px; + border-bottom-right-radius: 3px; +} +.pager { + padding-left: 0; + margin: 20px 0; + text-align: center; + list-style: none; +} +.pager li { + display: inline; +} +.pager li > a, +.pager li > span { + display: inline-block; + padding: 5px 14px; + background-color: #fff; + border: 1px solid #ddd; + border-radius: 15px; +} +.pager li > a:hover, +.pager li > a:focus { + text-decoration: none; + background-color: #eee; +} +.pager .next > a, +.pager .next > span { + float: right; +} +.pager .previous > a, +.pager .previous > span { + float: left; +} +.pager .disabled > a, +.pager .disabled > a:hover, +.pager .disabled > a:focus, +.pager .disabled > span { + color: #999; + cursor: not-allowed; + background-color: #fff; +} +.label { + display: inline; + padding: .2em .6em .3em; + font-size: 75%; + font-weight: bold; + line-height: 1; + color: #fff; + text-align: center; + white-space: nowrap; + vertical-align: baseline; + border-radius: .25em; +} +.label[href]:hover, +.label[href]:focus { + color: #fff; + text-decoration: none; + cursor: pointer; +} +.label:empty { + display: none; +} +.btn .label { + position: relative; + top: -1px; +} +.label-default { + background-color: #999; +} +.label-default[href]:hover, +.label-default[href]:focus { + background-color: #808080; +} +.label-primary { + background-color: #428bca; +} +.label-primary[href]:hover, +.label-primary[href]:focus { + background-color: #3071a9; +} +.label-success { + background-color: #5cb85c; +} +.label-success[href]:hover, +.label-success[href]:focus { + background-color: #449d44; +} +.label-info { + background-color: #5bc0de; +} +.label-info[href]:hover, +.label-info[href]:focus { + background-color: #31b0d5; +} +.label-warning { + background-color: #f0ad4e; +} +.label-warning[href]:hover, +.label-warning[href]:focus { + background-color: #ec971f; +} +.label-danger { + background-color: #d9534f; +} +.label-danger[href]:hover, +.label-danger[href]:focus { + background-color: #c9302c; +} +.badge { + display: inline-block; + min-width: 10px; + padding: 3px 7px; + font-size: 12px; + font-weight: bold; + line-height: 1; + color: #fff; + text-align: center; + white-space: nowrap; + vertical-align: baseline; + background-color: #999; + border-radius: 10px; +} +.badge:empty { + display: none; +} +.btn .badge { + position: relative; + top: -1px; +} +.btn-xs .badge { + top: 0; + padding: 1px 5px; +} +a.badge:hover, +a.badge:focus { + color: #fff; + text-decoration: none; + cursor: pointer; +} +a.list-group-item.active > .badge, +.nav-pills > .active > a > .badge { + color: #428bca; + background-color: #fff; +} +.nav-pills > li > a > .badge { + margin-left: 3px; +} +.jumbotron { + padding: 30px; + margin-bottom: 30px; + color: inherit; + background-color: #eee; +} +.jumbotron h1, +.jumbotron .h1 { + color: inherit; +} +.jumbotron p { + margin-bottom: 15px; + font-size: 21px; + font-weight: 200; +} +.container .jumbotron { + border-radius: 6px; +} +.jumbotron .container { + max-width: 100%; +} +@media screen and (min-width: 768px) { + .jumbotron { + padding-top: 48px; + padding-bottom: 48px; + } + .container .jumbotron { + padding-right: 60px; + padding-left: 60px; + } + .jumbotron h1, + .jumbotron .h1 { + font-size: 63px; + } +} +.thumbnail { + display: block; + padding: 4px; + margin-bottom: 20px; + line-height: 1.42857143; + background-color: #fff; + border: 1px solid #ddd; + border-radius: 4px; + -webkit-transition: all .2s ease-in-out; + transition: all .2s ease-in-out; +} +.thumbnail > img, +.thumbnail a > img { + margin-right: auto; + margin-left: auto; +} +a.thumbnail:hover, +a.thumbnail:focus, +a.thumbnail.active { + border-color: #428bca; +} +.thumbnail .caption { + padding: 9px; + color: #333; +} +.alert { + padding: 15px; + margin-bottom: 20px; + border: 1px solid transparent; + border-radius: 4px; +} +.alert h4 { + margin-top: 0; + color: inherit; +} +.alert .alert-link { + font-weight: bold; +} +.alert > p, +.alert > ul { + margin-bottom: 0; +} +.alert > p + p { + margin-top: 5px; +} +.alert-dismissable { + padding-right: 35px; +} +.alert-dismissable .close { + position: relative; + top: -2px; + right: -21px; + color: inherit; +} +.alert-success { + color: #3c763d; + background-color: #dff0d8; + border-color: #d6e9c6; +} +.alert-success hr { + border-top-color: #c9e2b3; +} +.alert-success .alert-link { + color: #2b542c; +} +.alert-info { + color: #31708f; + background-color: #d9edf7; + border-color: #bce8f1; +} +.alert-info hr { + border-top-color: #a6e1ec; +} +.alert-info .alert-link { + color: #245269; +} +.alert-warning { + color: #8a6d3b; + background-color: #fcf8e3; + border-color: #faebcc; +} +.alert-warning hr { + border-top-color: #f7e1b5; +} +.alert-warning .alert-link { + color: #66512c; +} +.alert-danger { + color: #a94442; + background-color: #f2dede; + border-color: #ebccd1; +} +.alert-danger hr { + border-top-color: #e4b9c0; +} +.alert-danger .alert-link { + color: #843534; +} +@-webkit-keyframes progress-bar-stripes { + from { + background-position: 40px 0; + } + to { + background-position: 0 0; + } +} +@keyframes progress-bar-stripes { + from { + background-position: 40px 0; + } + to { + background-position: 0 0; + } +} +.progress { + height: 20px; + margin-bottom: 20px; + overflow: hidden; + background-color: #f5f5f5; + border-radius: 4px; + -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, .1); + box-shadow: inset 0 1px 2px rgba(0, 0, 0, .1); +} +.progress-bar { + float: left; + width: 0; + height: 100%; + font-size: 12px; + line-height: 20px; + color: #fff; + text-align: center; + background-color: #428bca; + -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .15); + box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .15); + -webkit-transition: width .6s ease; + transition: width .6s ease; +} +.progress-striped .progress-bar { + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); + background-size: 40px 40px; +} +.progress.active .progress-bar { + -webkit-animation: progress-bar-stripes 2s linear infinite; + animation: progress-bar-stripes 2s linear infinite; +} +.progress-bar-success { + background-color: #5cb85c; +} +.progress-striped .progress-bar-success { + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); +} +.progress-bar-info { + background-color: #5bc0de; +} +.progress-striped .progress-bar-info { + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); +} +.progress-bar-warning { + background-color: #f0ad4e; +} +.progress-striped .progress-bar-warning { + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); +} +.progress-bar-danger { + background-color: #d9534f; +} +.progress-striped .progress-bar-danger { + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); +} +.media, +.media-body { + overflow: hidden; + zoom: 1; +} +.media, +.media .media { + margin-top: 15px; +} +.media:first-child { + margin-top: 0; +} +.media-object { + display: block; +} +.media-heading { + margin: 0 0 5px; +} +.media > .pull-left { + margin-right: 10px; +} +.media > .pull-right { + margin-left: 10px; +} +.media-list { + padding-left: 0; + list-style: none; +} +.list-group { + padding-left: 0; + margin-bottom: 20px; +} +.list-group-item { + position: relative; + display: block; + padding: 10px 15px; + margin-bottom: -1px; + background-color: #fff; + border: 1px solid #ddd; +} +.list-group-item:first-child { + border-top-left-radius: 4px; + border-top-right-radius: 4px; +} +.list-group-item:last-child { + margin-bottom: 0; + border-bottom-right-radius: 4px; + border-bottom-left-radius: 4px; +} +.list-group-item > .badge { + float: right; +} +.list-group-item > .badge + .badge { + margin-right: 5px; +} +a.list-group-item { + color: #555; +} +a.list-group-item .list-group-item-heading { + color: #333; +} +a.list-group-item:hover, +a.list-group-item:focus { + text-decoration: none; + background-color: #f5f5f5; +} +a.list-group-item.active, +a.list-group-item.active:hover, +a.list-group-item.active:focus { + z-index: 2; + color: #fff; + background-color: #428bca; + border-color: #428bca; +} +a.list-group-item.active .list-group-item-heading, +a.list-group-item.active:hover .list-group-item-heading, +a.list-group-item.active:focus .list-group-item-heading { + color: inherit; +} +a.list-group-item.active .list-group-item-text, +a.list-group-item.active:hover .list-group-item-text, +a.list-group-item.active:focus .list-group-item-text { + color: #e1edf7; +} +.list-group-item-success { + color: #3c763d; + background-color: #dff0d8; +} +a.list-group-item-success { + color: #3c763d; +} +a.list-group-item-success .list-group-item-heading { + color: inherit; +} +a.list-group-item-success:hover, +a.list-group-item-success:focus { + color: #3c763d; + background-color: #d0e9c6; +} +a.list-group-item-success.active, +a.list-group-item-success.active:hover, +a.list-group-item-success.active:focus { + color: #fff; + background-color: #3c763d; + border-color: #3c763d; +} +.list-group-item-info { + color: #31708f; + background-color: #d9edf7; +} +a.list-group-item-info { + color: #31708f; +} +a.list-group-item-info .list-group-item-heading { + color: inherit; +} +a.list-group-item-info:hover, +a.list-group-item-info:focus { + color: #31708f; + background-color: #c4e3f3; +} +a.list-group-item-info.active, +a.list-group-item-info.active:hover, +a.list-group-item-info.active:focus { + color: #fff; + background-color: #31708f; + border-color: #31708f; +} +.list-group-item-warning { + color: #8a6d3b; + background-color: #fcf8e3; +} +a.list-group-item-warning { + color: #8a6d3b; +} +a.list-group-item-warning .list-group-item-heading { + color: inherit; +} +a.list-group-item-warning:hover, +a.list-group-item-warning:focus { + color: #8a6d3b; + background-color: #faf2cc; +} +a.list-group-item-warning.active, +a.list-group-item-warning.active:hover, +a.list-group-item-warning.active:focus { + color: #fff; + background-color: #8a6d3b; + border-color: #8a6d3b; +} +.list-group-item-danger { + color: #a94442; + background-color: #f2dede; +} +a.list-group-item-danger { + color: #a94442; +} +a.list-group-item-danger .list-group-item-heading { + color: inherit; +} +a.list-group-item-danger:hover, +a.list-group-item-danger:focus { + color: #a94442; + background-color: #ebcccc; +} +a.list-group-item-danger.active, +a.list-group-item-danger.active:hover, +a.list-group-item-danger.active:focus { + color: #fff; + background-color: #a94442; + border-color: #a94442; +} +.list-group-item-heading { + margin-top: 0; + margin-bottom: 5px; +} +.list-group-item-text { + margin-bottom: 0; + line-height: 1.3; +} +.panel { + margin-bottom: 20px; + background-color: #fff; + border: 1px solid transparent; + border-radius: 4px; + -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, .05); + box-shadow: 0 1px 1px rgba(0, 0, 0, .05); +} +.panel-body { + padding: 15px; +} +.panel-heading { + padding: 10px 15px; + border-bottom: 1px solid transparent; + border-top-left-radius: 3px; + border-top-right-radius: 3px; +} +.panel-heading > .dropdown .dropdown-toggle { + color: inherit; +} +.panel-title { + margin-top: 0; + margin-bottom: 0; + font-size: 16px; + color: inherit; +} +.panel-title > a { + color: inherit; +} +.panel-footer { + padding: 10px 15px; + background-color: #f5f5f5; + border-top: 1px solid #ddd; + border-bottom-right-radius: 3px; + border-bottom-left-radius: 3px; +} +.panel > .list-group { + margin-bottom: 0; +} +.panel > .list-group .list-group-item { + border-width: 1px 0; + border-radius: 0; +} +.panel > .list-group:first-child .list-group-item:first-child { + border-top: 0; + border-top-left-radius: 3px; + border-top-right-radius: 3px; +} +.panel > .list-group:last-child .list-group-item:last-child { + border-bottom: 0; + border-bottom-right-radius: 3px; + border-bottom-left-radius: 3px; +} +.panel-heading + .list-group .list-group-item:first-child { + border-top-width: 0; +} +.panel > .table, +.panel > .table-responsive > .table { + margin-bottom: 0; +} +.panel > .table:first-child, +.panel > .table-responsive:first-child > .table:first-child { + border-top-left-radius: 3px; + border-top-right-radius: 3px; +} +.panel > .table:first-child > thead:first-child > tr:first-child td:first-child, +.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:first-child, +.panel > .table:first-child > tbody:first-child > tr:first-child td:first-child, +.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:first-child, +.panel > .table:first-child > thead:first-child > tr:first-child th:first-child, +.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:first-child, +.panel > .table:first-child > tbody:first-child > tr:first-child th:first-child, +.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:first-child { + border-top-left-radius: 3px; +} +.panel > .table:first-child > thead:first-child > tr:first-child td:last-child, +.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:last-child, +.panel > .table:first-child > tbody:first-child > tr:first-child td:last-child, +.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:last-child, +.panel > .table:first-child > thead:first-child > tr:first-child th:last-child, +.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:last-child, +.panel > .table:first-child > tbody:first-child > tr:first-child th:last-child, +.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:last-child { + border-top-right-radius: 3px; +} +.panel > .table:last-child, +.panel > .table-responsive:last-child > .table:last-child { + border-bottom-right-radius: 3px; + border-bottom-left-radius: 3px; +} +.panel > .table:last-child > tbody:last-child > tr:last-child td:first-child, +.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:first-child, +.panel > .table:last-child > tfoot:last-child > tr:last-child td:first-child, +.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:first-child, +.panel > .table:last-child > tbody:last-child > tr:last-child th:first-child, +.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:first-child, +.panel > .table:last-child > tfoot:last-child > tr:last-child th:first-child, +.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:first-child { + border-bottom-left-radius: 3px; +} +.panel > .table:last-child > tbody:last-child > tr:last-child td:last-child, +.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:last-child, +.panel > .table:last-child > tfoot:last-child > tr:last-child td:last-child, +.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:last-child, +.panel > .table:last-child > tbody:last-child > tr:last-child th:last-child, +.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:last-child, +.panel > .table:last-child > tfoot:last-child > tr:last-child th:last-child, +.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:last-child { + border-bottom-right-radius: 3px; +} +.panel > .panel-body + .table, +.panel > .panel-body + .table-responsive { + border-top: 1px solid #ddd; +} +.panel > .table > tbody:first-child > tr:first-child th, +.panel > .table > tbody:first-child > tr:first-child td { + border-top: 0; +} +.panel > .table-bordered, +.panel > .table-responsive > .table-bordered { + border: 0; +} +.panel > .table-bordered > thead > tr > th:first-child, +.panel > .table-responsive > .table-bordered > thead > tr > th:first-child, +.panel > .table-bordered > tbody > tr > th:first-child, +.panel > .table-responsive > .table-bordered > tbody > tr > th:first-child, +.panel > .table-bordered > tfoot > tr > th:first-child, +.panel > .table-responsive > .table-bordered > tfoot > tr > th:first-child, +.panel > .table-bordered > thead > tr > td:first-child, +.panel > .table-responsive > .table-bordered > thead > tr > td:first-child, +.panel > .table-bordered > tbody > tr > td:first-child, +.panel > .table-responsive > .table-bordered > tbody > tr > td:first-child, +.panel > .table-bordered > tfoot > tr > td:first-child, +.panel > .table-responsive > .table-bordered > tfoot > tr > td:first-child { + border-left: 0; +} +.panel > .table-bordered > thead > tr > th:last-child, +.panel > .table-responsive > .table-bordered > thead > tr > th:last-child, +.panel > .table-bordered > tbody > tr > th:last-child, +.panel > .table-responsive > .table-bordered > tbody > tr > th:last-child, +.panel > .table-bordered > tfoot > tr > th:last-child, +.panel > .table-responsive > .table-bordered > tfoot > tr > th:last-child, +.panel > .table-bordered > thead > tr > td:last-child, +.panel > .table-responsive > .table-bordered > thead > tr > td:last-child, +.panel > .table-bordered > tbody > tr > td:last-child, +.panel > .table-responsive > .table-bordered > tbody > tr > td:last-child, +.panel > .table-bordered > tfoot > tr > td:last-child, +.panel > .table-responsive > .table-bordered > tfoot > tr > td:last-child { + border-right: 0; +} +.panel > .table-bordered > thead > tr:first-child > td, +.panel > .table-responsive > .table-bordered > thead > tr:first-child > td, +.panel > .table-bordered > tbody > tr:first-child > td, +.panel > .table-responsive > .table-bordered > tbody > tr:first-child > td, +.panel > .table-bordered > thead > tr:first-child > th, +.panel > .table-responsive > .table-bordered > thead > tr:first-child > th, +.panel > .table-bordered > tbody > tr:first-child > th, +.panel > .table-responsive > .table-bordered > tbody > tr:first-child > th { + border-bottom: 0; +} +.panel > .table-bordered > tbody > tr:last-child > td, +.panel > .table-responsive > .table-bordered > tbody > tr:last-child > td, +.panel > .table-bordered > tfoot > tr:last-child > td, +.panel > .table-responsive > .table-bordered > tfoot > tr:last-child > td, +.panel > .table-bordered > tbody > tr:last-child > th, +.panel > .table-responsive > .table-bordered > tbody > tr:last-child > th, +.panel > .table-bordered > tfoot > tr:last-child > th, +.panel > .table-responsive > .table-bordered > tfoot > tr:last-child > th { + border-bottom: 0; +} +.panel > .table-responsive { + margin-bottom: 0; + border: 0; +} +.panel-group { + margin-bottom: 20px; +} +.panel-group .panel { + margin-bottom: 0; + overflow: hidden; + border-radius: 4px; +} +.panel-group .panel + .panel { + margin-top: 5px; +} +.panel-group .panel-heading { + border-bottom: 0; +} +.panel-group .panel-heading + .panel-collapse .panel-body { + border-top: 1px solid #ddd; +} +.panel-group .panel-footer { + border-top: 0; +} +.panel-group .panel-footer + .panel-collapse .panel-body { + border-bottom: 1px solid #ddd; +} +.panel-default { + border-color: #ddd; +} +.panel-default > .panel-heading { + color: #333; + background-color: #f5f5f5; + border-color: #ddd; +} +.panel-default > .panel-heading + .panel-collapse .panel-body { + border-top-color: #ddd; +} +.panel-default > .panel-footer + .panel-collapse .panel-body { + border-bottom-color: #ddd; +} +.panel-primary { + border-color: #428bca; +} +.panel-primary > .panel-heading { + color: #fff; + background-color: #428bca; + border-color: #428bca; +} +.panel-primary > .panel-heading + .panel-collapse .panel-body { + border-top-color: #428bca; +} +.panel-primary > .panel-footer + .panel-collapse .panel-body { + border-bottom-color: #428bca; +} +.panel-success { + border-color: #d6e9c6; +} +.panel-success > .panel-heading { + color: #3c763d; + background-color: #dff0d8; + border-color: #d6e9c6; +} +.panel-success > .panel-heading + .panel-collapse .panel-body { + border-top-color: #d6e9c6; +} +.panel-success > .panel-footer + .panel-collapse .panel-body { + border-bottom-color: #d6e9c6; +} +.panel-info { + border-color: #bce8f1; +} +.panel-info > .panel-heading { + color: #31708f; + background-color: #d9edf7; + border-color: #bce8f1; +} +.panel-info > .panel-heading + .panel-collapse .panel-body { + border-top-color: #bce8f1; +} +.panel-info > .panel-footer + .panel-collapse .panel-body { + border-bottom-color: #bce8f1; +} +.panel-warning { + border-color: #faebcc; +} +.panel-warning > .panel-heading { + color: #8a6d3b; + background-color: #fcf8e3; + border-color: #faebcc; +} +.panel-warning > .panel-heading + .panel-collapse .panel-body { + border-top-color: #faebcc; +} +.panel-warning > .panel-footer + .panel-collapse .panel-body { + border-bottom-color: #faebcc; +} +.panel-danger { + border-color: #ebccd1; +} +.panel-danger > .panel-heading { + color: #a94442; + background-color: #f2dede; + border-color: #ebccd1; +} +.panel-danger > .panel-heading + .panel-collapse .panel-body { + border-top-color: #ebccd1; +} +.panel-danger > .panel-footer + .panel-collapse .panel-body { + border-bottom-color: #ebccd1; +} +.well { + min-height: 20px; + padding: 19px; + margin-bottom: 20px; + background-color: #f5f5f5; + border: 1px solid #e3e3e3; + border-radius: 4px; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .05); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, .05); +} +.well blockquote { + border-color: #ddd; + border-color: rgba(0, 0, 0, .15); +} +.well-lg { + padding: 24px; + border-radius: 6px; +} +.well-sm { + padding: 9px; + border-radius: 3px; +} +.close { + float: right; + font-size: 21px; + font-weight: bold; + line-height: 1; + color: #000; + text-shadow: 0 1px 0 #fff; + filter: alpha(opacity=20); + opacity: .2; +} +.close:hover, +.close:focus { + color: #000; + text-decoration: none; + cursor: pointer; + filter: alpha(opacity=50); + opacity: .5; +} +button.close { + -webkit-appearance: none; + padding: 0; + cursor: pointer; + background: transparent; + border: 0; +} +.modal-open { + overflow: hidden; +} +.modal { + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 1050; + display: none; + overflow: auto; + overflow-y: scroll; + -webkit-overflow-scrolling: touch; + outline: 0; +} +.modal.fade .modal-dialog { + -webkit-transition: -webkit-transform .3s ease-out; + -moz-transition: -moz-transform .3s ease-out; + -o-transition: -o-transform .3s ease-out; + transition: transform .3s ease-out; + -webkit-transform: translate(0, -25%); + -ms-transform: translate(0, -25%); + transform: translate(0, -25%); +} +.modal.in .modal-dialog { + -webkit-transform: translate(0, 0); + -ms-transform: translate(0, 0); + transform: translate(0, 0); +} +.modal-dialog { + position: relative; + width: auto; + margin: 10px; +} +.modal-content { + position: relative; + background-color: #fff; + background-clip: padding-box; + border: 1px solid #999; + border: 1px solid rgba(0, 0, 0, .2); + border-radius: 6px; + outline: none; + -webkit-box-shadow: 0 3px 9px rgba(0, 0, 0, .5); + box-shadow: 0 3px 9px rgba(0, 0, 0, .5); +} +.modal-backdrop { + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 1040; + background-color: #000; +} +.modal-backdrop.fade { + filter: alpha(opacity=0); + opacity: 0; +} +.modal-backdrop.in { + filter: alpha(opacity=50); + opacity: .5; +} +.modal-header { + min-height: 16.42857143px; + padding: 15px; + border-bottom: 1px solid #e5e5e5; +} +.modal-header .close { + margin-top: -2px; +} +.modal-title { + margin: 0; + line-height: 1.42857143; +} +.modal-body { + position: relative; + padding: 20px; +} +.modal-footer { + padding: 19px 20px 20px; + margin-top: 15px; + text-align: right; + border-top: 1px solid #e5e5e5; +} +.modal-footer .btn + .btn { + margin-bottom: 0; + margin-left: 5px; +} +.modal-footer .btn-group .btn + .btn { + margin-left: -1px; +} +.modal-footer .btn-block + .btn-block { + margin-left: 0; +} +@media (min-width: 768px) { + .modal-dialog { + width: 600px; + margin: 30px auto; + } + .modal-content { + -webkit-box-shadow: 0 5px 15px rgba(0, 0, 0, .5); + box-shadow: 0 5px 15px rgba(0, 0, 0, .5); + } + .modal-sm { + width: 300px; + } +} +@media (min-width: 992px) { + .modal-lg { + width: 900px; + } +} +.tooltip { + position: absolute; + z-index: 1030; + display: block; + font-size: 12px; + line-height: 1.4; + visibility: visible; + filter: alpha(opacity=0); + opacity: 0; +} +.tooltip.in { + filter: alpha(opacity=90); + opacity: .9; +} +.tooltip.top { + padding: 5px 0; + margin-top: -3px; +} +.tooltip.right { + padding: 0 5px; + margin-left: 3px; +} +.tooltip.bottom { + padding: 5px 0; + margin-top: 3px; +} +.tooltip.left { + padding: 0 5px; + margin-left: -3px; +} +.tooltip-inner { + max-width: 200px; + padding: 3px 8px; + color: #fff; + text-align: center; + text-decoration: none; + background-color: #000; + border-radius: 4px; +} +.tooltip-arrow { + position: absolute; + width: 0; + height: 0; + border-color: transparent; + border-style: solid; +} +.tooltip.top .tooltip-arrow { + bottom: 0; + left: 50%; + margin-left: -5px; + border-width: 5px 5px 0; + border-top-color: #000; +} +.tooltip.top-left .tooltip-arrow { + bottom: 0; + left: 5px; + border-width: 5px 5px 0; + border-top-color: #000; +} +.tooltip.top-right .tooltip-arrow { + right: 5px; + bottom: 0; + border-width: 5px 5px 0; + border-top-color: #000; +} +.tooltip.right .tooltip-arrow { + top: 50%; + left: 0; + margin-top: -5px; + border-width: 5px 5px 5px 0; + border-right-color: #000; +} +.tooltip.left .tooltip-arrow { + top: 50%; + right: 0; + margin-top: -5px; + border-width: 5px 0 5px 5px; + border-left-color: #000; +} +.tooltip.bottom .tooltip-arrow { + top: 0; + left: 50%; + margin-left: -5px; + border-width: 0 5px 5px; + border-bottom-color: #000; +} +.tooltip.bottom-left .tooltip-arrow { + top: 0; + left: 5px; + border-width: 0 5px 5px; + border-bottom-color: #000; +} +.tooltip.bottom-right .tooltip-arrow { + top: 0; + right: 5px; + border-width: 0 5px 5px; + border-bottom-color: #000; +} +.popover { + position: absolute; + top: 0; + left: 0; + z-index: 1010; + display: none; + max-width: 276px; + padding: 1px; + text-align: left; + white-space: normal; + background-color: #fff; + background-clip: padding-box; + border: 1px solid #ccc; + border: 1px solid rgba(0, 0, 0, .2); + border-radius: 6px; + -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, .2); + box-shadow: 0 5px 10px rgba(0, 0, 0, .2); +} +.popover.top { + margin-top: -10px; +} +.popover.right { + margin-left: 10px; +} +.popover.bottom { + margin-top: 10px; +} +.popover.left { + margin-left: -10px; +} +.popover-title { + padding: 8px 14px; + margin: 0; + font-size: 14px; + font-weight: normal; + line-height: 18px; + background-color: #f7f7f7; + border-bottom: 1px solid #ebebeb; + border-radius: 5px 5px 0 0; +} +.popover-content { + padding: 9px 14px; +} +.popover > .arrow, +.popover > .arrow:after { + position: absolute; + display: block; + width: 0; + height: 0; + border-color: transparent; + border-style: solid; +} +.popover > .arrow { + border-width: 11px; +} +.popover > .arrow:after { + content: ""; + border-width: 10px; +} +.popover.top > .arrow { + bottom: -11px; + left: 50%; + margin-left: -11px; + border-top-color: #999; + border-top-color: rgba(0, 0, 0, .25); + border-bottom-width: 0; +} +.popover.top > .arrow:after { + bottom: 1px; + margin-left: -10px; + content: " "; + border-top-color: #fff; + border-bottom-width: 0; +} +.popover.right > .arrow { + top: 50%; + left: -11px; + margin-top: -11px; + border-right-color: #999; + border-right-color: rgba(0, 0, 0, .25); + border-left-width: 0; +} +.popover.right > .arrow:after { + bottom: -10px; + left: 1px; + content: " "; + border-right-color: #fff; + border-left-width: 0; +} +.popover.bottom > .arrow { + top: -11px; + left: 50%; + margin-left: -11px; + border-top-width: 0; + border-bottom-color: #999; + border-bottom-color: rgba(0, 0, 0, .25); +} +.popover.bottom > .arrow:after { + top: 1px; + margin-left: -10px; + content: " "; + border-top-width: 0; + border-bottom-color: #fff; +} +.popover.left > .arrow { + top: 50%; + right: -11px; + margin-top: -11px; + border-right-width: 0; + border-left-color: #999; + border-left-color: rgba(0, 0, 0, .25); +} +.popover.left > .arrow:after { + right: 1px; + bottom: -10px; + content: " "; + border-right-width: 0; + border-left-color: #fff; +} +.carousel { + position: relative; +} +.carousel-inner { + position: relative; + width: 100%; + overflow: hidden; +} +.carousel-inner > .item { + position: relative; + display: none; + -webkit-transition: .6s ease-in-out left; + transition: .6s ease-in-out left; +} +.carousel-inner > .item > img, +.carousel-inner > .item > a > img { + line-height: 1; +} +.carousel-inner > .active, +.carousel-inner > .next, +.carousel-inner > .prev { + display: block; +} +.carousel-inner > .active { + left: 0; +} +.carousel-inner > .next, +.carousel-inner > .prev { + position: absolute; + top: 0; + width: 100%; +} +.carousel-inner > .next { + left: 100%; +} +.carousel-inner > .prev { + left: -100%; +} +.carousel-inner > .next.left, +.carousel-inner > .prev.right { + left: 0; +} +.carousel-inner > .active.left { + left: -100%; +} +.carousel-inner > .active.right { + left: 100%; +} +.carousel-control { + position: absolute; + top: 0; + bottom: 0; + left: 0; + width: 15%; + font-size: 20px; + color: #fff; + text-align: center; + text-shadow: 0 1px 2px rgba(0, 0, 0, .6); + filter: alpha(opacity=50); + opacity: .5; +} +.carousel-control.left { + background-image: -webkit-linear-gradient(left, color-stop(rgba(0, 0, 0, .5) 0%), color-stop(rgba(0, 0, 0, .0001) 100%)); + background-image: linear-gradient(to right, rgba(0, 0, 0, .5) 0%, rgba(0, 0, 0, .0001) 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1); + background-repeat: repeat-x; +} +.carousel-control.right { + right: 0; + left: auto; + background-image: -webkit-linear-gradient(left, color-stop(rgba(0, 0, 0, .0001) 0%), color-stop(rgba(0, 0, 0, .5) 100%)); + background-image: linear-gradient(to right, rgba(0, 0, 0, .0001) 0%, rgba(0, 0, 0, .5) 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1); + background-repeat: repeat-x; +} +.carousel-control:hover, +.carousel-control:focus { + color: #fff; + text-decoration: none; + filter: alpha(opacity=90); + outline: none; + opacity: .9; +} +.carousel-control .icon-prev, +.carousel-control .icon-next, +.carousel-control .glyphicon-chevron-left, +.carousel-control .glyphicon-chevron-right { + position: absolute; + top: 50%; + z-index: 5; + display: inline-block; +} +.carousel-control .icon-prev, +.carousel-control .glyphicon-chevron-left { + left: 50%; +} +.carousel-control .icon-next, +.carousel-control .glyphicon-chevron-right { + right: 50%; +} +.carousel-control .icon-prev, +.carousel-control .icon-next { + width: 20px; + height: 20px; + margin-top: -10px; + margin-left: -10px; + font-family: serif; +} +.carousel-control .icon-prev:before { + content: '\2039'; +} +.carousel-control .icon-next:before { + content: '\203a'; +} +.carousel-indicators { + position: absolute; + bottom: 10px; + left: 50%; + z-index: 15; + width: 60%; + padding-left: 0; + margin-left: -30%; + text-align: center; + list-style: none; +} +.carousel-indicators li { + display: inline-block; + width: 10px; + height: 10px; + margin: 1px; + text-indent: -999px; + cursor: pointer; + background-color: #000 \9; + background-color: rgba(0, 0, 0, 0); + border: 1px solid #fff; + border-radius: 10px; +} +.carousel-indicators .active { + width: 12px; + height: 12px; + margin: 0; + background-color: #fff; +} +.carousel-caption { + position: absolute; + right: 15%; + bottom: 20px; + left: 15%; + z-index: 10; + padding-top: 20px; + padding-bottom: 20px; + color: #fff; + text-align: center; + text-shadow: 0 1px 2px rgba(0, 0, 0, .6); +} +.carousel-caption .btn { + text-shadow: none; +} +@media screen and (min-width: 768px) { + .carousel-control .glyphicon-chevron-left, + .carousel-control .glyphicon-chevron-right, + .carousel-control .icon-prev, + .carousel-control .icon-next { + width: 30px; + height: 30px; + margin-top: -15px; + margin-left: -15px; + font-size: 30px; + } + .carousel-caption { + right: 20%; + left: 20%; + padding-bottom: 30px; + } + .carousel-indicators { + bottom: 20px; + } +} +.clearfix:before, +.clearfix:after, +.container:before, +.container:after, +.container-fluid:before, +.container-fluid:after, +.row:before, +.row:after, +.form-horizontal .form-group:before, +.form-horizontal .form-group:after, +.btn-toolbar:before, +.btn-toolbar:after, +.btn-group-vertical > .btn-group:before, +.btn-group-vertical > .btn-group:after, +.nav:before, +.nav:after, +.navbar:before, +.navbar:after, +.navbar-header:before, +.navbar-header:after, +.navbar-collapse:before, +.navbar-collapse:after, +.pager:before, +.pager:after, +.panel-body:before, +.panel-body:after, +.modal-footer:before, +.modal-footer:after { + display: table; + content: " "; +} +.clearfix:after, +.container:after, +.container-fluid:after, +.row:after, +.form-horizontal .form-group:after, +.btn-toolbar:after, +.btn-group-vertical > .btn-group:after, +.nav:after, +.navbar:after, +.navbar-header:after, +.navbar-collapse:after, +.pager:after, +.panel-body:after, +.modal-footer:after { + clear: both; +} +.center-block { + display: block; + margin-right: auto; + margin-left: auto; +} +.pull-right { + float: right !important; +} +.pull-left { + float: left !important; +} +.hide { + display: none !important; +} +.show { + display: block !important; +} +.invisible { + visibility: hidden; +} +.text-hide { + font: 0/0 a; + color: transparent; + text-shadow: none; + background-color: transparent; + border: 0; +} +.hidden { + display: none !important; + visibility: hidden !important; +} +.affix { + position: fixed; +} +@-ms-viewport { + width: device-width; +} +.visible-xs, +.visible-sm, +.visible-md, +.visible-lg { + display: none !important; +} +@media (max-width: 767px) { + .visible-xs { + display: block !important; + } + table.visible-xs { + display: table; + } + tr.visible-xs { + display: table-row !important; + } + th.visible-xs, + td.visible-xs { + display: table-cell !important; + } +} +@media (min-width: 768px) and (max-width: 991px) { + .visible-sm { + display: block !important; + } + table.visible-sm { + display: table; + } + tr.visible-sm { + display: table-row !important; + } + th.visible-sm, + td.visible-sm { + display: table-cell !important; + } +} +@media (min-width: 992px) and (max-width: 1199px) { + .visible-md { + display: block !important; + } + table.visible-md { + display: table; + } + tr.visible-md { + display: table-row !important; + } + th.visible-md, + td.visible-md { + display: table-cell !important; + } +} +@media (min-width: 1200px) { + .visible-lg { + display: block !important; + } + table.visible-lg { + display: table; + } + tr.visible-lg { + display: table-row !important; + } + th.visible-lg, + td.visible-lg { + display: table-cell !important; + } +} +@media (max-width: 767px) { + .hidden-xs { + display: none !important; + } +} +@media (min-width: 768px) and (max-width: 991px) { + .hidden-sm { + display: none !important; + } +} +@media (min-width: 992px) and (max-width: 1199px) { + .hidden-md { + display: none !important; + } +} +@media (min-width: 1200px) { + .hidden-lg { + display: none !important; + } +} +.visible-print { + display: none !important; +} +@media print { + .visible-print { + display: block !important; + } + table.visible-print { + display: table; + } + tr.visible-print { + display: table-row !important; + } + th.visible-print, + td.visible-print { + display: table-cell !important; + } +} +@media print { + .hidden-print { + display: none !important; + } +} +/*# sourceMappingURL=bootstrap.css.map */ diff --git a/templates/js/libs/angular-chart.js-0.7.2/examples/charts.html b/templates/js/libs/angular-chart.js-0.7.2/examples/charts.html new file mode 100644 index 0000000..b9e141b --- /dev/null +++ b/templates/js/libs/angular-chart.js-0.7.2/examples/charts.html @@ -0,0 +1,462 @@ + + + + + Charts + + + + + + + + +
+
+ +
+

+ Angular Chart +

+ +

Reactive, responsive, beautiful charts for AngularJS based on Chart.js

+ +

+ Code on Github + + Download (0.7.2) + +

+
+
+
+
+
+ +

Dependencies

+

+ This repository contains a set of native AngularJS directives for Chart.js. The only required dependencies are: +

+
    +
  • AngularJS (tested with 1.2.20 and 1.3.10 although it probably works with older versions)
  • +
  • Chart.js (requires Chart.js 1.0, tested with version 1.0.1-beta.2, 1.0.1-beta.4, and and 1.0.1).
  • +
+

Files to download

+

+ The easiest is to download with bower: +

bower install angular-chart.js --save
+ Alternatively files can be downloaded downloaded from Github. +

+

Whichever method you choose the good news is that the overall size is very small: + <5kb for all directives (~1kb with gzip compression!)

+

Installation

+

<script src="bower_components/dist/angular-chart.js"></script>
+

As soon as you've got all the files downloaded and included in your page you just need to declare + a dependency on the chart.js module:
+

angular.module('myModule', ['chart.js']);
+

+

CSS

+

You need to include a link to the css file in your page.

+

<link rel="stylesheet" href="bower_components/dist/angular-chart.css">
+

+

Colours

+

Series have beautiful pre-sets colours (to a maximum of 7 series, after that colours will be randomly generated). + They can be overwritten using Chart.defaults.global.colours.

+
    +
  1. Blue
  2. +
  3. Light grey
  4. +
  5. Red
  6. +
  7. Green
  8. +
  9. Yellow
  10. +
  11. Grey
  12. +
  13. Dark Grey
  14. +
+
+
+ +
+
+
+
Line Chart
+
+ +
+
+
+
+ + +
+ .chart-line +
    +
  • data: series data
  • +
  • labels: x axis labels
  • +
  • legend (default: false): show legend below the chart
  • +
  • options (default: {}): Chart.js options
  • +
  • series (default: []): series labels
  • +
  • click (optional): onclick event handler
  • +
  • colours (default to global colours): colours for the chart
  • +
+
+
+ +
<canvas id="line" class="chart chart-line" data="data"
+  labels="labels" legend="true" series="series"
+  click="onClick">
+</canvas> 
+
+ +
angular.module("app", ["chart.js"]).controller("LineCtrl", function ($scope) {
+
+  $scope.labels = ["January", "February", "March", "April", "May", "June", "July"];
+  $scope.series = ['Series A', 'Series B'];
+  $scope.data = [
+    [65, 59, 80, 81, 56, 55, 40],
+    [28, 48, 40, 19, 86, 27, 90]
+  ];
+  $scope.onClick = function (points, evt) {
+    console.log(points, evt);
+  };
+});
+              
+
+
+
+
+
+
+ + +
+ .chart-bar +
    +
  • data: series data
  • +
  • labels: x axis labels
  • +
  • legend (default: false): show legend below the chart
  • +
  • options (default: {}): Chart.js options
  • +
  • series (default: []): series labels
  • +
  • colours (default to global colours): colours for the chart
  • +
+
+
+ +
<canvas id="bar" class="chart chart-bar" data="data"
+  labels="labels"></canvas> 
+
+ +
angular.module("app", ["chart.js"]).controller("BarCtrl", function ($scope) {
+  $scope.labels = ['2006', '2007', '2008', '2009', '2010', '2011', '2012'];
+  $scope.series = ['Series A', 'Series B'];
+
+  $scope.data = [
+    [65, 59, 80, 81, 56, 55, 40],
+    [28, 48, 40, 19, 86, 27, 90]
+  ];
+});
+              
+
+
+
+
+
+
Bar Chart
+
+ +
+
+
+
+
+
+
+
Doughnut Chart
+
+ +
+
+
+
+ + +
+ .chart-doughnut +
    +
  • data: series data
  • +
  • labels: series labels
  • +
  • legend (default: false): show legend below the chart
  • +
  • options (default: {}): Chart.js options
  • +
  • colours (default to global colours): colours for the chart
  • +
+
+
+ +
<canvas id="doughnut" class="chart chart-doughnut" data="data"
+  labels="labels"></canvas> 
+
+ +
angular.module("app", ["chart.js"]).controller("DoughnutCtrl", function ($scope) {
+  $scope.labels = ["Download Sales", "In-Store Sales", "Mail-Order Sales"];
+  $scope.data = [300, 500, 100];
+});
+              
+
+
+
+
+
+
+ + +
+ .chart-radar +
    +
  • data: series data
  • +
  • labels: series labels
  • +
  • legend (default: false): show legend below the chart
  • +
  • options (default: {}): Chart.js options
  • +
  • series (default: []): series labels
  • +
  • click (optional): onclick event handler
  • +
  • colours (default to global colours): colours for the chart
  • +
+
+
+ +
<canvas id="radar" class="chart chart-radar" data="data"
+  labels="labels"></canvas> 
+
+ +
angular.module("app", ["chart.js"]).controller("RadarCtrl", function ($scope) {
+  $scope.labels =["Eating", "Drinking", "Sleeping", "Designing", "Coding", "Cycling", "Running"];
+
+  $scope.data = [
+    [65, 59, 90, 81, 56, 55, 40],
+    [28, 48, 40, 19, 96, 27, 100]
+  ];
+});
+              
+
+
+
+
+
+
Radar Chart
+
+ +
+
+
+
+
+
+
+
Pie Chart
+
+ +
+
+
+
+ + +
+ .chart-pie +
    +
  • data: series data
  • +
  • labels: series labels
  • +
  • legend (default: false): show legend below the chart
  • +
  • options (default: {}): Chart.js options
  • +
  • colours (default to global colours): colours for the chart
  • +
+
+
+ +
<canvas id="pie" class="chart chart-pie" data="data"
+  labels="labels"></canvas> 
+
+ +
angular.module("app", ["chart.js"]).controller("PieCtrl", function ($scope) {
+  $scope.labels = ["Download Sales", "In-Store Sales", "Mail-Order Sales"];
+  $scope.data = [300, 500, 100];
+});
+              
+
+
+
+
+
+
+ + +
+ .chart-polar-area +
    +
  • data: series data
  • +
  • labels: series labels
  • +
  • legend (default: false): show legend below the chart
  • +
  • options (default: {}): Chart.js options
  • +
  • colours (default to global colours): colours for the chart
  • +
+
+
+ +
<canvas id="polar-area" class="chart chart-polar-area" data="data"
+  labels="labels"></canvas> 
+
+ +
angular.module("app", ["chart.js"]).controller("PolarAreaCtrl", function ($scope) {
+  $scope.labels = ["Download Sales", "In-Store Sales", "Mail-Order Sales", "Tele Sales", "Corporate Sales"];
+  $scope.data = [300, 500, 100, 40, 120];
+});
+              
+
+
+
+
+
+
Polar Area Chart
+
+ +
+
+
+
+
+
+
+
Dynamic Chart
+
+ +
+
+ +
+
+ + +
+ .chart-base +
    +
  • chart-type: chart type e.g. Bar, PolarArea, etc. or other plugins
  • +
  • other options according to chart type
  • +
+
+
+ +
<canvas id="base" class="chart-base" chart-type="type" data="data"
+  labels="labels" legend="true"></canvas> 
+
+ +
angular.module("app", ["chart.js"]).controller("BaseCtrl",
+  function ($scope) {
+    $scope.labels = ["Download Sales", "In-Store Sales", "Mail-Order Sales", "Tele Sales", "Corporate Sales"];
+    $scope.data = [300, 500, 100, 40, 120];
+    $scope.type = 'PolarArea';
+
+    $scope.toggle = function () {
+      $scope.type = $scope.type === 'PolarArea' ?
+        'Pie' : 'PolarArea';
+    };
+});
+              
+
+
+
+
+
+
+ +
+
+
+
Chart Data
+
+ + + + + + + +
{{label}}
{{data[$parent.$index][$index]}}
+ +
+
+
+
+
+
Reactive Chart
+
+ +
+
+
+
+
+
+ + + + + + + + + + + + + + diff --git a/templates/js/libs/angular-chart.js-0.7.2/examples/charts.template.html b/templates/js/libs/angular-chart.js-0.7.2/examples/charts.template.html new file mode 100644 index 0000000..9850286 --- /dev/null +++ b/templates/js/libs/angular-chart.js-0.7.2/examples/charts.template.html @@ -0,0 +1,462 @@ + + + + + Charts + + + + + + + + +
+
+ +
+

+ Angular Chart +

+ +

Reactive, responsive, beautiful charts for AngularJS based on Chart.js

+ +

+ Code on Github + + Download () + +

+
+
+
+
+
+ +

Dependencies

+

+ This repository contains a set of native AngularJS directives for Chart.js. The only required dependencies are: +

+
    +
  • AngularJS (tested with 1.2.20 and 1.3.10 although it probably works with older versions)
  • +
  • Chart.js (requires Chart.js 1.0, tested with version 1.0.1-beta.2, 1.0.1-beta.4, and and 1.0.1).
  • +
+

Files to download

+

+ The easiest is to download with bower: +

bower install angular-chart.js --save
+ Alternatively files can be downloaded downloaded from Github. +

+

Whichever method you choose the good news is that the overall size is very small: + <5kb for all directives (~1kb with gzip compression!)

+

Installation

+

<script src="bower_components/dist/angular-chart.js"></script>
+

As soon as you've got all the files downloaded and included in your page you just need to declare + a dependency on the chart.js module:
+

angular.module('myModule', ['chart.js']);
+

+

CSS

+

You need to include a link to the css file in your page.

+

<link rel="stylesheet" href="bower_components/dist/angular-chart.css">
+

+

Colours

+

Series have beautiful pre-sets colours (to a maximum of 7 series, after that colours will be randomly generated). + They can be overwritten using Chart.defaults.global.colours.

+
    +
  1. Blue
  2. +
  3. Light grey
  4. +
  5. Red
  6. +
  7. Green
  8. +
  9. Yellow
  10. +
  11. Grey
  12. +
  13. Dark Grey
  14. +
+
+
+ +
+
+
+
Line Chart
+
+ +
+
+
+
+ + +
+ .chart-line +
    +
  • data: series data
  • +
  • labels: x axis labels
  • +
  • legend (default: false): show legend below the chart
  • +
  • options (default: {}): Chart.js options
  • +
  • series (default: []): series labels
  • +
  • click (optional): onclick event handler
  • +
  • colours (default to global colours): colours for the chart
  • +
+
+
+ +
<canvas id="line" class="chart chart-line" data="data"
+  labels="labels" legend="true" series="series"
+  click="onClick">
+</canvas> 
+
+ +
angular.module("app", ["chart.js"]).controller("LineCtrl", function ($scope) {
+
+  $scope.labels = ["January", "February", "March", "April", "May", "June", "July"];
+  $scope.series = ['Series A', 'Series B'];
+  $scope.data = [
+    [65, 59, 80, 81, 56, 55, 40],
+    [28, 48, 40, 19, 86, 27, 90]
+  ];
+  $scope.onClick = function (points, evt) {
+    console.log(points, evt);
+  };
+});
+              
+
+
+
+
+
+
+ + +
+ .chart-bar +
    +
  • data: series data
  • +
  • labels: x axis labels
  • +
  • legend (default: false): show legend below the chart
  • +
  • options (default: {}): Chart.js options
  • +
  • series (default: []): series labels
  • +
  • colours (default to global colours): colours for the chart
  • +
+
+
+ +
<canvas id="bar" class="chart chart-bar" data="data"
+  labels="labels"></canvas> 
+
+ +
angular.module("app", ["chart.js"]).controller("BarCtrl", function ($scope) {
+  $scope.labels = ['2006', '2007', '2008', '2009', '2010', '2011', '2012'];
+  $scope.series = ['Series A', 'Series B'];
+
+  $scope.data = [
+    [65, 59, 80, 81, 56, 55, 40],
+    [28, 48, 40, 19, 86, 27, 90]
+  ];
+});
+              
+
+
+
+
+
+
Bar Chart
+
+ +
+
+
+
+
+
+
+
Doughnut Chart
+
+ +
+
+
+
+ + +
+ .chart-doughnut +
    +
  • data: series data
  • +
  • labels: series labels
  • +
  • legend (default: false): show legend below the chart
  • +
  • options (default: {}): Chart.js options
  • +
  • colours (default to global colours): colours for the chart
  • +
+
+
+ +
<canvas id="doughnut" class="chart chart-doughnut" data="data"
+  labels="labels"></canvas> 
+
+ +
angular.module("app", ["chart.js"]).controller("DoughnutCtrl", function ($scope) {
+  $scope.labels = ["Download Sales", "In-Store Sales", "Mail-Order Sales"];
+  $scope.data = [300, 500, 100];
+});
+              
+
+
+
+
+
+
+ + +
+ .chart-radar +
    +
  • data: series data
  • +
  • labels: series labels
  • +
  • legend (default: false): show legend below the chart
  • +
  • options (default: {}): Chart.js options
  • +
  • series (default: []): series labels
  • +
  • click (optional): onclick event handler
  • +
  • colours (default to global colours): colours for the chart
  • +
+
+
+ +
<canvas id="radar" class="chart chart-radar" data="data"
+  labels="labels"></canvas> 
+
+ +
angular.module("app", ["chart.js"]).controller("RadarCtrl", function ($scope) {
+  $scope.labels =["Eating", "Drinking", "Sleeping", "Designing", "Coding", "Cycling", "Running"];
+
+  $scope.data = [
+    [65, 59, 90, 81, 56, 55, 40],
+    [28, 48, 40, 19, 96, 27, 100]
+  ];
+});
+              
+
+
+
+
+
+
Radar Chart
+
+ +
+
+
+
+
+
+
+
Pie Chart
+
+ +
+
+
+
+ + +
+ .chart-pie +
    +
  • data: series data
  • +
  • labels: series labels
  • +
  • legend (default: false): show legend below the chart
  • +
  • options (default: {}): Chart.js options
  • +
  • colours (default to global colours): colours for the chart
  • +
+
+
+ +
<canvas id="pie" class="chart chart-pie" data="data"
+  labels="labels"></canvas> 
+
+ +
angular.module("app", ["chart.js"]).controller("PieCtrl", function ($scope) {
+  $scope.labels = ["Download Sales", "In-Store Sales", "Mail-Order Sales"];
+  $scope.data = [300, 500, 100];
+});
+              
+
+
+
+
+
+
+ + +
+ .chart-polar-area +
    +
  • data: series data
  • +
  • labels: series labels
  • +
  • legend (default: false): show legend below the chart
  • +
  • options (default: {}): Chart.js options
  • +
  • colours (default to global colours): colours for the chart
  • +
+
+
+ +
<canvas id="polar-area" class="chart chart-polar-area" data="data"
+  labels="labels"></canvas> 
+
+ +
angular.module("app", ["chart.js"]).controller("PolarAreaCtrl", function ($scope) {
+  $scope.labels = ["Download Sales", "In-Store Sales", "Mail-Order Sales", "Tele Sales", "Corporate Sales"];
+  $scope.data = [300, 500, 100, 40, 120];
+});
+              
+
+
+
+
+
+
Polar Area Chart
+
+ +
+
+
+
+
+
+
+
Dynamic Chart
+
+ +
+
+ +
+
+ + +
+ .chart-base +
    +
  • chart-type: chart type e.g. Bar, PolarArea, etc. or other plugins
  • +
  • other options according to chart type
  • +
+
+
+ +
<canvas id="base" class="chart-base" chart-type="type" data="data"
+  labels="labels" legend="true"></canvas> 
+
+ +
angular.module("app", ["chart.js"]).controller("BaseCtrl",
+  function ($scope) {
+    $scope.labels = ["Download Sales", "In-Store Sales", "Mail-Order Sales", "Tele Sales", "Corporate Sales"];
+    $scope.data = [300, 500, 100, 40, 120];
+    $scope.type = 'PolarArea';
+
+    $scope.toggle = function () {
+      $scope.type = $scope.type === 'PolarArea' ?
+        'Pie' : 'PolarArea';
+    };
+});
+              
+
+
+
+
+
+
+ +
+
+
+
Chart Data
+
+ + + + + + + +
{{label}}
{{data[$parent.$index][$index]}}
+ +
+
+
+
+
+
Reactive Chart
+
+ +
+
+
+
+
+
+ + + + + + + + + + + + + + diff --git a/templates/js/libs/angular-chart.js-0.7.2/examples/smoothscroll.min.js b/templates/js/libs/angular-chart.js-0.7.2/examples/smoothscroll.min.js new file mode 100644 index 0000000..631953c --- /dev/null +++ b/templates/js/libs/angular-chart.js-0.7.2/examples/smoothscroll.min.js @@ -0,0 +1 @@ +window.smoothScroll=function(){if(document.querySelectorAll===void 0||window.pageYOffset===void 0||history.pushState===void 0){return}var e=function(e){if(e.nodeName==="HTML")return-window.pageYOffset;return e.getBoundingClientRect().top+window.pageYOffset};var t=function(e){return e<.5?4*e*e*e:(e-1)*(2*e-2)*(2*e-2)+1};var n=function(e,n,r,i){if(r>i)return n;return e+(n-e)*t(r/i)};var r=function(t,r,i){r=r||500;var s=window.pageYOffset;if(typeof t==="number"){var o=parseInt(t)}else{var o=e(t)}var u=Date.now();var a=window.requestAnimationFrame||window.mozRequestAnimationFrame||window.webkitRequestAnimationFrame||function(e){window.setTimeout(e,15)};var f=function(){var e=Date.now()-u;window.scroll(0,n(s,o,e,r));if(e>r){if(typeof i==="function"){i(t)}}else{a(f)}};f()};var i=function(e){e.preventDefault();if(location.hash!==this.hash)window.history.pushState(null,null,this.hash);r(document.getElementById(this.hash.substring(1)),500,function(e){location.replace("#"+e.id)})};document.addEventListener("DOMContentLoaded",function(){var e=document.querySelectorAll('a[href^="#"]'),t;for(var n=e.length;t=e[--n];){t.addEventListener("click",i,false)}});return r}() diff --git a/templates/js/libs/angular-chart.js-0.7.2/examples/stacked-bars-directive.html b/templates/js/libs/angular-chart.js-0.7.2/examples/stacked-bars-directive.html new file mode 100644 index 0000000..bec90e8 --- /dev/null +++ b/templates/js/libs/angular-chart.js-0.7.2/examples/stacked-bars-directive.html @@ -0,0 +1,39 @@ + + + + + Stacked Bar chart + + + + +
+
+
+
+
+
+
Stacked Bar Chart
+
+ +
+
+
+
+
+ + + + + + + + + + diff --git a/templates/js/libs/angular-chart.js-0.7.2/examples/stacked-bars.html b/templates/js/libs/angular-chart.js-0.7.2/examples/stacked-bars.html new file mode 100644 index 0000000..dbcca28 --- /dev/null +++ b/templates/js/libs/angular-chart.js-0.7.2/examples/stacked-bars.html @@ -0,0 +1,32 @@ + + + + + Stacked Bar chart + + + + +
+
+
+
+
+
+
Stacked Bar Chart
+
+ +
+
+
+
+
+ + + + + + + + + diff --git a/templates/js/libs/angular-chart.js-0.7.2/examples/tables.html b/templates/js/libs/angular-chart.js-0.7.2/examples/tables.html new file mode 100644 index 0000000..4c0296c --- /dev/null +++ b/templates/js/libs/angular-chart.js-0.7.2/examples/tables.html @@ -0,0 +1,46 @@ + + + + + Data tables + + + + +
+
+
+
+
+
Chart Data
+
+ + + + + + + +
{{label}}
{{data[$parent.$index][$index]}}
+ +
+
+
+
+
+
Reactive Chart
+
+ +
+
+
+
+
+ + + + + + + + diff --git a/templates/js/libs/angular-chart.js-0.7.2/examples/ticks.html b/templates/js/libs/angular-chart.js-0.7.2/examples/ticks.html new file mode 100644 index 0000000..0355cb6 --- /dev/null +++ b/templates/js/libs/angular-chart.js-0.7.2/examples/ticks.html @@ -0,0 +1,30 @@ + + + + + Realtime ticks + + + + +
+
+
+
+
+
Ticks Chart
+
+ +
+
+
+
+
+ + + + + + + + diff --git a/templates/js/libs/angular-chart.js-0.7.2/gulpfile.js b/templates/js/libs/angular-chart.js-0.7.2/gulpfile.js new file mode 100644 index 0000000..bdbbe02 --- /dev/null +++ b/templates/js/libs/angular-chart.js-0.7.2/gulpfile.js @@ -0,0 +1,135 @@ +(function () { + 'use strict'; + + var gulp = require('gulp'); + var less = require('gulp-less'); + var sourcemaps = require('gulp-sourcemaps'); + var uglify = require('gulp-uglify'); + var csso = require('gulp-csso'); + var jshint = require('gulp-jshint'); + var stylish = require('jshint-stylish'); + var jscs = require('gulp-jscs'); + var mocha = require('gulp-spawn-mocha'); + var tar = require('gulp-tar'); + var gzip = require('gulp-gzip'); + var bumper = require('gulp-bump'); + var git = require('gulp-git'); + var shell = require('gulp-shell'); + var rename = require('gulp-rename'); + var fs = require('fs'); + var sequence = require('gulp-sequence'); + var ngAnnotate = require('gulp-ng-annotate'); + + gulp.task('less', function () { + return gulp.src('./*.less') + .pipe(sourcemaps.init()) + .pipe(less()) + .pipe(csso()) + .pipe(sourcemaps.write('./')) + .pipe(gulp.dest('./dist')); + }); + + gulp.task('lint', function () { + return gulp.src('**/*.js') + .pipe(jshint()) + .pipe(jshint.reporter(stylish)); + }); + + gulp.task('style', function () { + return gulp.src('**/*.js') + .pipe(jscs()); + }); + + gulp.task('unit', shell.task([ + ' ./node_modules/mocha-phantomjs/bin/mocha-phantomjs -R spec test/index.html ' + ])); + + gulp.task('integration', function () { + return gulp.src('test/test.integration.js', {read: false}) + .pipe(mocha({ reporter: 'list', timeout: 10000, require: 'test/support/setup.js' })); + }); + + gulp.task('bump-patch', bump('patch')); + gulp.task('bump-minor', bump('minor')); + gulp.task('bump-major', bump('major')); + + gulp.task('bower', function () { + return gulp.src('./angular-chart.js') + .pipe(ngAnnotate({single_quotes: true})) + .pipe(gulp.dest('./dist')); + }); + + gulp.task('js', ['lint', 'style', 'bower'], function () { + return gulp.src('./angular-chart.js') + .pipe(rename('angular-chart.min.js')) + .pipe(ngAnnotate({single_quotes: true})) + .pipe(sourcemaps.init()) + .pipe(uglify()) + .pipe(sourcemaps.write('./')) + .pipe(gulp.dest('./dist')); + }); + + gulp.task('build', function () { + return gulp.src(['dist/*', '!./dist/*.tar.gz']) + .pipe(tar('angular-chart.js.tar')) + .pipe(gzip({ gzipOptions: { level: 9 } })) + .pipe(gulp.dest('dist/')); + }); + + gulp.task('update', function (cb) { + fs.readFile('./examples/charts.template.html', 'utf8', function (err, file) { + if (err) return cb(err); + file = file.replace('', version()); + fs.writeFile('./examples/charts.html', file, cb); + }); + }); + + gulp.task('git-commit', function () { + var v = version(); + gulp.src(['./dist/*', './package.json', './bower.json', './examples/charts.html']) + .pipe(git.add()) + .pipe(git.commit(v)) + ; + }); + + gulp.task('git-push', function (cb) { + var v = version(); + git.push('origin', 'master', function (err) { + if (err) return cb(err); + git.tag(v, v, function (err) { + if (err) return cb(err); + git.push('origin', 'master', {args: '--tags' }, cb); + }); + }); + }); + + gulp.task('npm', shell.task([ + 'npm publish' + ])); + + gulp.task('watch', function () { + gulp.watch('./*.js', ['js']); + gulp.watch('./*.less', ['less']); + return true; + }); + + function bump (level) { + return function () { + return gulp.src(['./package.json', './bower.json']) + .pipe(bumper({type: level})) + .pipe(gulp.dest('./')); + }; + } + + function version () { + return JSON.parse(fs.readFileSync('package.json', 'utf8')).version; + } + + gulp.task('default', sequence('check', ['less', 'js'], 'build')); + gulp.task('test', sequence('unit', 'integration')); + gulp.task('check', sequence(['lint', 'style'], 'test')); + gulp.task('deploy-patch', sequence('default', 'bump-patch', 'update', 'git-commit', 'git-push', 'npm')); + gulp.task('deploy-minor', sequence('default', 'bump-minor', 'update', 'git-commit', 'git-push', 'npm')); + gulp.task('deploy-major', sequence('default', 'bump-patch', 'update', 'git-commit', 'git-push', 'npm')); + +})(); diff --git a/templates/js/libs/angular-chart.js-0.7.2/package.json b/templates/js/libs/angular-chart.js-0.7.2/package.json new file mode 100644 index 0000000..53cc23a --- /dev/null +++ b/templates/js/libs/angular-chart.js-0.7.2/package.json @@ -0,0 +1,51 @@ +{ + "name": "angular-chart.js", + "version": "0.7.2", + "description": "An angular.js wrapper for Chart.js", + "main": "dist/angular-chart.js", + "directories": { + "example": "examples" + }, + "scripts": { + "test": "gulp check" + }, + "author": "Jerome Touffe-Blin ", + "repository": { + "type": "git", + "url": "git://github.com/jtblin/angular-chart.js.git" + }, + "license": "BSD", + "devDependencies": { + "chai": "^1.10.0", + "chai-string": "^1.1.1", + "cp": "^0.2.0", + "gm": "^1.17.0", + "gulp": "^3.8.6", + "gulp-bump": "^0.1.11", + "gulp-csso": "^0.2.9", + "gulp-git": "^0.5.6", + "gulp-gzip": "0.0.8", + "gulp-jscs": "^1.4.0", + "gulp-jshint": "^1.9.2", + "gulp-less": "^1.3.1", + "gulp-ng-annotate": "^0.5.2", + "gulp-rename": "^1.2.0", + "gulp-sequence": "^0.3.1", + "gulp-shell": "^0.2.11", + "gulp-sourcemaps": "^1.0.0", + "gulp-spawn-mocha": "^2.0.1", + "gulp-tar": "^0.5.0", + "gulp-uglify": "^0.3.1", + "imgur-node-api": "^0.1.0", + "jshint-stylish": "^1.0.0", + "less": "^1.7.3", + "mkdirp": "^0.5.0", + "mocha": "^2.1.0", + "mocha-phantomjs": "^3.5.3", + "sinon": "^1.12.2", + "sinon-chai": "^2.7.0", + "testatic": "^0.1.0", + "tmp-sync": "jtblin/node-tmp-sync", + "webshot": "^0.15.3" + } +} diff --git a/templates/js/libs/angular-chart.js-0.7.2/test/fixtures/51-pie-update-colours.html b/templates/js/libs/angular-chart.js-0.7.2/test/fixtures/51-pie-update-colours.html new file mode 100644 index 0000000..5064fec --- /dev/null +++ b/templates/js/libs/angular-chart.js-0.7.2/test/fixtures/51-pie-update-colours.html @@ -0,0 +1,36 @@ + + + + + Pie update colours + + + + +
+
+ + +
+
+ + + + + + + diff --git a/templates/js/libs/angular-chart.js-0.7.2/test/fixtures/51-pie-update-colours.js b/templates/js/libs/angular-chart.js-0.7.2/test/fixtures/51-pie-update-colours.js new file mode 100644 index 0000000..784fbbf --- /dev/null +++ b/templates/js/libs/angular-chart.js-0.7.2/test/fixtures/51-pie-update-colours.js @@ -0,0 +1,30 @@ +(function () { + 'use strict'; + + var app = angular.module('pie', ['chart.js']); + app.controller('PieCtrl', ['$scope', '$timeout', function ($scope, $timeout) { + $scope.labels = ['Series A', 'Series B']; + $scope.data = [65, 59]; + $scope.colours = [{ // red + fillColor: 'rgba(247,70,74,0.2)', + strokeColor: 'rgba(247,70,74,1)', + pointColor: 'rgba(247,70,74,1)', + pointStrokeColor: '#fff', + pointHighlightFill: '#fff', + pointHighlightStroke: 'rgba(247,70,74,0.8)' + }, + { // green + fillColor: 'rgba(70,191,189,0.2)', + strokeColor: 'rgba(70,191,189,1)', + pointColor: 'rgba(70,191,189,1)', + pointStrokeColor: '#fff', + pointHighlightFill: '#fff', + pointHighlightStroke: 'rgba(70,191,189,0.8)' + }]; + + $timeout(function () { + $scope.data = [49, 65]; + }, 0); + }]); + +})(); diff --git a/templates/js/libs/angular-chart.js-0.7.2/test/fixtures/51-pie-update-colours.png b/templates/js/libs/angular-chart.js-0.7.2/test/fixtures/51-pie-update-colours.png new file mode 100644 index 0000000000000000000000000000000000000000..86b7d883be53b3770afbe75c300f99dbcbec0e59 GIT binary patch literal 35810 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 + + + + Not enough colours + + + + +
+
+ + +
+
+ + + + + + + diff --git a/templates/js/libs/angular-chart.js-0.7.2/test/fixtures/54-not-enough-colours.js b/templates/js/libs/angular-chart.js-0.7.2/test/fixtures/54-not-enough-colours.js new file mode 100644 index 0000000..b8601d6 --- /dev/null +++ b/templates/js/libs/angular-chart.js-0.7.2/test/fixtures/54-not-enough-colours.js @@ -0,0 +1,32 @@ +(function () { + 'use strict'; + + var app = angular.module('pie', ['chart.js']); + app.controller('PieCtrl', ['$scope', function ($scope) { + var cnt = 0; + $scope.colours = []; + $scope.labels = ['Series A', 'Series B']; + $scope.getColour = function () { + return ++cnt % 2 > 0 ? + { // red + fillColor: 'rgba(247,70,74,0.2)', + strokeColor: 'rgba(247,70,74,1)', + pointColor: 'rgba(247,70,74,1)', + pointStrokeColor: '#fff', + pointHighlightFill: '#fff', + pointHighlightStroke: 'rgba(247,70,74,0.8)' + } + : + { // green + fillColor: 'rgba(70,191,189,0.2)', + strokeColor: 'rgba(70,191,189,1)', + pointColor: 'rgba(70,191,189,1)', + pointStrokeColor: '#fff', + pointHighlightFill: '#fff', + pointHighlightStroke: 'rgba(70,191,189,0.8)' + }; + }; + $scope.data = [49, 65]; + }]); + +})(); diff --git a/templates/js/libs/angular-chart.js-0.7.2/test/fixtures/54-not-enough-colours.png b/templates/js/libs/angular-chart.js-0.7.2/test/fixtures/54-not-enough-colours.png new file mode 100644 index 0000000000000000000000000000000000000000..86b7d883be53b3770afbe75c300f99dbcbec0e59 GIT binary patch literal 35810 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 + + + + Hex colours + + + + +
+
+ + +
+
+ + + + + + + diff --git a/templates/js/libs/angular-chart.js-0.7.2/test/fixtures/57-hex-colours.js b/templates/js/libs/angular-chart.js-0.7.2/test/fixtures/57-hex-colours.js new file mode 100644 index 0000000..a6d9d02 --- /dev/null +++ b/templates/js/libs/angular-chart.js-0.7.2/test/fixtures/57-hex-colours.js @@ -0,0 +1,11 @@ +(function () { + 'use strict'; + + var app = angular.module('pie', ['chart.js']); + app.controller('PieCtrl', ['$scope', function ($scope) { + $scope.labels = ['Series A', 'Series B']; + $scope.colours = ['#9AFEFF', '#D1D0CE']; + $scope.data = [49, 65]; + }]); + +})(); diff --git a/templates/js/libs/angular-chart.js-0.7.2/test/fixtures/57-hex-colours.png b/templates/js/libs/angular-chart.js-0.7.2/test/fixtures/57-hex-colours.png new file mode 100644 index 0000000000000000000000000000000000000000..fb1c382e4c3e614353ca49873d758f416282373d GIT binary patch literal 34702 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 literal 0 HcmV?d00001 diff --git a/templates/js/libs/angular-chart.js-0.7.2/test/fixtures/charts.html b/templates/js/libs/angular-chart.js-0.7.2/test/fixtures/charts.html new file mode 100644 index 0000000..aef98b2 --- /dev/null +++ b/templates/js/libs/angular-chart.js-0.7.2/test/fixtures/charts.html @@ -0,0 +1,78 @@ + + + + + Charts + + + + +
+
+ +
+
+
+
Line Chart
+
+ +
+
+
+
+
+
Bar Chart
+
+ +
+
+
+
+
+
Doughnut Chart
+
+ +
+
+
+
+
+
+
+
Radar Chart
+
+ +
+
+
+
+
+
Pie Chart
+
+ +
+
+
+
+
+
Polar Area Chart
+
+ +
+
+
+
+
+
+
+
+ + + + + + + diff --git a/templates/js/libs/angular-chart.js-0.7.2/test/fixtures/charts.js b/templates/js/libs/angular-chart.js-0.7.2/test/fixtures/charts.js new file mode 100644 index 0000000..ed9813d --- /dev/null +++ b/templates/js/libs/angular-chart.js-0.7.2/test/fixtures/charts.js @@ -0,0 +1,61 @@ +(function () { + 'use strict'; + + var app = angular.module('charts', ['chart.js']); + + app.controller('LineCtrl', ['$scope', '$timeout', function ($scope, $timeout) { + $scope.labels = ['January', 'February', 'March', 'April', 'May', 'June', 'July']; + $scope.series = ['Series A', 'Series B']; + $scope.data = [ + [65, 59, 80, 81, 56, 55, 40], + [28, 48, 40, 19, 86, 27, 90] + ]; + $timeout(function () { + $scope.labels = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday']; + $scope.data = [ + [28, 48, 40, 19, 86, 27, 90], + [65, 59, 80, 81, 56, 55, 40] + ]; + $scope.series = ['Series C', 'Series D']; + }, 0); + }]); + + app.controller('BarCtrl', ['$scope', '$timeout', function ($scope, $timeout) { + $scope.options = { scaleShowVerticalLines: false }; + $scope.labels = ['2006', '2007', '2008', '2009', '2010', '2011', '2012']; + $scope.series = ['Series A', 'Series B']; + $scope.data = [ + [65, 59, 80, 81, 56, 55, 40], + [28, 48, 40, 19, 86, 27, 90] + ]; + $timeout(function () { + $scope.options = { scaleShowVerticalLines: true }; + }, 0); + }]); + + app.controller('DoughnutCtrl', function ($scope) { + $scope.labels = ['Download Sales', 'In-Store Sales', 'Mail-Order Sales']; + $scope.data = [350, 450, 100]; + }); + + app.controller('PieCtrl', ['$scope', '$timeout', function ($scope, $timeout) { + $scope.labels = ['Download Sales', 'In-Store Sales', 'Mail Sales']; + $scope.data = [0, 0, 0]; + $timeout(function () { + $scope.data = [350, 450, 100]; + }, 0); + }]); + + app.controller('PolarAreaCtrl', function ($scope) { + $scope.labels = ['Download Sales', 'In-Store Sales', 'Mail Sales', 'Telesales', 'Corporate Sales']; + $scope.data = [300, 500, 100, 40, 120]; + }); + + app.controller('RadarCtrl', function ($scope) { + $scope.labels = ['Eating', 'Drinking', 'Sleeping', 'Designing', 'Coding', 'Cycling', 'Running']; + $scope.data = [ + [65, 59, 90, 81, 56, 55, 40], + [28, 48, 40, 19, 96, 27, 100] + ]; + }); +})(); diff --git a/templates/js/libs/angular-chart.js-0.7.2/test/fixtures/charts.png b/templates/js/libs/angular-chart.js-0.7.2/test/fixtures/charts.png new file mode 100644 index 0000000000000000000000000000000000000000..cdbbbeef44c02b34dae787e6521fd9c67f94ef71 GIT binary patch literal 90895 zcmeFZc|6p8`#y|JL{dqLETssAWZ$Kzm?*~1DElt^zEw&RC4?ABmN8>rXE3A)+0EFu z?913^Fk^T=(|up}{k@;B>%ZrD{r>pf*Xwo3jG6cTKF{Mg&hz|4=|0e8Vd7+>p`l^9 zclY)q8XAxR4b2f6#-qSHoyv;efPd&cZ{5>p1pW(Rw0;G=KIVSc*pr5anT`5CEltX& zb2K!3H1}?+>HAqMj~)v$v#C8;hZ4*0^=3PuR+rBRrC!Q67%8|U9Kp1WDyr~MtImAI zD9pj}edcwhMIZbp#P#99Nd8qm^m3p>_^s_M7gUyUimlFm=eCfb4A@Q}*;*j^=B7U> z#qfRd%{j%n;Ov`od$Zen=?IJdH<2`SjC^5-{1CSeU%n{T5^?xnfp1uZ)eDQ!)1OqO zq5a=K_#V*G?ahx*@<-`o2icQxFMQ9?5#C#TtGWyC?jXSv86 z?K8NuKIPK%=Df7)NYyVjOPxb6{@pOZ3exjslY|WrMvp`HH(~gF^6GXtHXK<~GjjHt zktOfJPBZ>Ho6d!uwUE$pkGAW?9xbt5a;Mzf1qIUlmu=HXh5s1JUzho=9blUsg1izw zlS*NfUm-x#rfzO-eM&CQ&Sg2UkfHGt^7DM?o!`-Tq+764-;5#B#3oj8<5lQhS?_~r zl$jBa?oqds?ghEIMQ}L0$SW=6(jjK=%{yQMHzIV1wo6M(czAw6NltozBMjUQQyFJH zFr+E|{JFu=(b1VgBH+5aCzAqa5)7A1+C)nWLkRiA^z9nK!BOoff*7=JeT`C9h zmE*2~#O3utB$PbV@BHogG2*NY#ve0NedMpz`JYBOT$|%(hgX=_a46_bA!a{7MGev= zTC;Wwy@Fc0bQDtlhAtPj`^zo}XDj{=VrZCT{`3cXMKGD@#s4Jq(4{|D46Mm1wrm{J zO7$F%9*cfC0&$H@>c_0yguLuIAv-}sZeR_u92^XUo^7?jlI#z+-9?2!Gm-&!uC{H> zrn;>Re~H&o9vq{r_%@fnWabbZvD-OtKa!s!D{>0FbgvH;v41%rcyx3$Y5;;eZ1GNB zqIE<>&ReqJuqu0#tQ8Ku*>yjZ*Q0cf6Fnp? zl7=+l^J~p2``tW#6STusPrty9YsFi)rz!L^II8S4u#%1sH4Nd9rg+Q&8G}!@OD}dA zt{@~xUcG+3d~wlHuV@E2O{H?4v$xH#q5E^8DY(x>w*#V^fxiCqky7e;gRU-O^O1RZ zEuxq`kHFoTB#K9a4rPC5Dwce0JR>b|rCJ);%sLDqT5+Xn>I4Q6;s%`H-@l)v%0A5$ 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 WT-NwjcU!Q)M?pqaxGs*9OV)K literal 0 HcmV?d00001 diff --git a/templates/js/libs/angular-chart.js-0.7.2/test/fixtures/configure-line-chart.html b/templates/js/libs/angular-chart.js-0.7.2/test/fixtures/configure-line-chart.html new file mode 100644 index 0000000..21b220f --- /dev/null +++ b/templates/js/libs/angular-chart.js-0.7.2/test/fixtures/configure-line-chart.html @@ -0,0 +1,33 @@ + + + + + Pie update colours + + + + +

+
+ +
+
+
+
Line Chart
+
+ +
+
+
+
+
+
+ + + + + + + diff --git a/templates/js/libs/angular-chart.js-0.7.2/test/fixtures/configure-line-chart.js b/templates/js/libs/angular-chart.js-0.7.2/test/fixtures/configure-line-chart.js new file mode 100644 index 0000000..ffde2f7 --- /dev/null +++ b/templates/js/libs/angular-chart.js-0.7.2/test/fixtures/configure-line-chart.js @@ -0,0 +1,32 @@ +(function () { + 'use strict'; + + var app = angular.module('line', ['chart.js']); + + app.config(function (ChartJsProvider) { + // Configure all charts + ChartJsProvider.setOptions({ + colours: ['#FF5252', '#FF8A80'], + responsive: false + }); + // Configure all line charts + ChartJsProvider.setOptions('Line', { + datasetFill: false + }); + }); + + app.controller('LineCtrl', ['$scope', '$timeout', function ($scope, $timeout) { + $scope.labels = ['Series A', 'Series B']; + $scope.data = [[15, 23], [59, 80]]; + + // Configure only this instance + $scope.options = { + scaleLineWidth: 5 + }; + + $timeout(function () { + $scope.data = [[15, 23], [59, 80]]; + }, 0); + }]); + +})(); diff --git a/templates/js/libs/angular-chart.js-0.7.2/test/fixtures/configure-line-chart.png b/templates/js/libs/angular-chart.js-0.7.2/test/fixtures/configure-line-chart.png new file mode 100644 index 0000000000000000000000000000000000000000..fd047c3d157faa87a73d1dfb0958106f46e281b5 GIT binary patch literal 32774 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 literal 0 HcmV?d00001 diff --git a/templates/js/libs/angular-chart.js-0.7.2/test/fixtures/custom-directive.html b/templates/js/libs/angular-chart.js-0.7.2/test/fixtures/custom-directive.html new file mode 100644 index 0000000..9457779 --- /dev/null +++ b/templates/js/libs/angular-chart.js-0.7.2/test/fixtures/custom-directive.html @@ -0,0 +1,33 @@ + + + + + Pie update colours + + + + +
+
+ +
+
+
+
Pie Chart
+
+ +
+
+
+
+
+
+ + + + + + + diff --git a/templates/js/libs/angular-chart.js-0.7.2/test/fixtures/custom-directive.js b/templates/js/libs/angular-chart.js-0.7.2/test/fixtures/custom-directive.js new file mode 100644 index 0000000..68c666f --- /dev/null +++ b/templates/js/libs/angular-chart.js-0.7.2/test/fixtures/custom-directive.js @@ -0,0 +1,17 @@ +(function () { + 'use strict'; + + var app = angular.module('pie', ['chart.js']); + + app.directive('mySpecialPie', function (ChartJsFactory) { return new ChartJsFactory('Pie'); }); + + app.controller('PieCtrl', ['$scope', '$timeout', function ($scope, $timeout) { + $scope.labels = ['Series A', 'Series B']; + $scope.data = [5, 59]; + + $timeout(function () { + $scope.data = [5, 65]; + }, 0); + }]); + +})(); diff --git a/templates/js/libs/angular-chart.js-0.7.2/test/fixtures/custom-directive.png b/templates/js/libs/angular-chart.js-0.7.2/test/fixtures/custom-directive.png new file mode 100644 index 0000000000000000000000000000000000000000..383cfcf805380bbc0a3fb4b785e63bb1560c3bb1 GIT binary patch literal 30363 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 literal 0 HcmV?d00001 diff --git a/templates/js/libs/angular-chart.js-0.7.2/test/index.html b/templates/js/libs/angular-chart.js-0.7.2/test/index.html new file mode 100644 index 0000000..9c8ad6b --- /dev/null +++ b/templates/js/libs/angular-chart.js-0.7.2/test/index.html @@ -0,0 +1,30 @@ + + + + Mocha Tests + + + +
+ + + + + + + + + + + + + + diff --git a/templates/js/libs/angular-chart.js-0.7.2/test/mocha.opts b/templates/js/libs/angular-chart.js-0.7.2/test/mocha.opts new file mode 100644 index 0000000..0cfde2d --- /dev/null +++ b/templates/js/libs/angular-chart.js-0.7.2/test/mocha.opts @@ -0,0 +1,4 @@ +--slow 20 +--growl +--reporter spec +--require test/support/setup diff --git a/templates/js/libs/angular-chart.js-0.7.2/test/support/setup.js b/templates/js/libs/angular-chart.js-0.7.2/test/support/setup.js new file mode 100644 index 0000000..de98414 --- /dev/null +++ b/templates/js/libs/angular-chart.js-0.7.2/test/support/setup.js @@ -0,0 +1,11 @@ +/*jshint node:true*/ +(function () { + 'use strict'; + + var chai = require('chai'); + global.chai = chai; + global.should = chai.should(); + global.expect = chai.expect; + global.assert = chai.assert; + +})(); diff --git a/templates/js/libs/angular-chart.js-0.7.2/test/test.integration.js b/templates/js/libs/angular-chart.js-0.7.2/test/test.integration.js new file mode 100644 index 0000000..e694fc9 --- /dev/null +++ b/templates/js/libs/angular-chart.js-0.7.2/test/test.integration.js @@ -0,0 +1,69 @@ +/*jshint node:true*/ +/*jshint mocha:true*/ +/*global assert:true*/ +describe('integration', function () { + 'use strict'; + + var webshot = require('webshot'), + gm = require('gm'), + tmp = require('tmp-sync'), + mkdirp = require('mkdirp').sync, + cp = require('cp').sync, + imgur = require('imgur-node-api'), + server = require('testatic')(), + WEBSHOT_OPTIONS = { renderDelay: process.env.DELAY || 2500, windowSize: { width: 1366, height: 768 }}, + WEBSHOT_FAILED_DIR = 'test/fixtures/shots/', + dir; + + beforeEach(function () { + dir = tmp.in() + '/'; + }); + + afterEach(function () { + tmp.clean(); + }); + + after(function () { + server.close(); + }); + + mkdirp(WEBSHOT_FAILED_DIR); + + [ + '57-hex-colours', + '54-not-enough-colours', + '51-pie-update-colours', + 'configure-line-chart', + 'custom-directive', + 'charts' + ].forEach(function (name) { + it('compares screenshots for: ' + name, function (done) { + var image = dir + name + '.png', + url = 'http://localhost:8080/test/fixtures/' + name + '.html', + expected = 'test/fixtures/' + name + '.png'; + + webshot(url, image, WEBSHOT_OPTIONS, function (err) { + if (err) return done(err); + gm.compare(expected, image, process.env.TOLERANCE || 0.0001, function (err, isEqual) { + if (err) return done(err); + if (! isEqual) { + var failed = WEBSHOT_FAILED_DIR + name + '-failed.png', + msg = 'Expected screenshots to be similar. Screenshot saved to ' + failed; + cp(image, failed); + if (process.env.CI && process.env.IMGUR_ID) { + imgur.setClientID(process.env.IMGUR_ID); + imgur.upload(image, function (err, res) { + if (err) return done(err); + assert.fail(isEqual, true, msg + ', uploaded to ' + res.data.link); + }); + } else { + assert.fail(isEqual, true, msg); + } + return; + } + done(); + }); + }); + }); + }); +}); diff --git a/templates/js/libs/angular-chart.js-0.7.2/test/test.unit.js b/templates/js/libs/angular-chart.js-0.7.2/test/test.unit.js new file mode 100644 index 0000000..7e1e5b4 --- /dev/null +++ b/templates/js/libs/angular-chart.js-0.7.2/test/test.unit.js @@ -0,0 +1,372 @@ +/*jshint mocha:true*/ +/*global module:true*/ +/*global inject:true*/ +/*global expect:true*/ +/*global sinon:true*/ +describe('Unit testing', function () { + 'use strict'; + + var $compile, scope, sandbox, ChartJs, ChartJsProvider; + + beforeEach(module('chart.js', function (_ChartJsProvider_) { + ChartJsProvider = _ChartJsProvider_; + })); + + beforeEach(inject(function (_$compile_, _$rootScope_, _ChartJs_) { + // The injector unwraps the underscores (_) from around the parameter names when matching + $compile = _$compile_; + scope = _$rootScope_; + ChartJs = _ChartJs_; + sandbox = sinon.sandbox.create(); + })); + + afterEach(function () { + sandbox.restore(); + }); + + describe('base', function () { + it('replaces the element with the appropriate content', function () { + var markup = '
' + + '
'; + + scope.labels = ['January', 'February', 'March', 'April', 'May', 'June', 'July']; + scope.data = [ + [65, 59, 80, 81, 56, 55, 40], + [28, 48, 40, 19, 86, 27, 90] + ]; + + var element = $compile(markup)(scope); + scope.$digest(); + + expect(element.html()).to.startWith('
'; + + scope.labels = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday']; + + if (['Line', 'Bar', 'Radar'].indexOf(type) > - 1) + scope.data = [ + [65, 59, 80, 81, 56, 55, 40], + [28, 48, 40, 19, 86, 27, 90] + ]; + else + scope.data = [300, 500, 100]; + + var mock = sandbox.mock(Chart.prototype); + mock.expects(type); + + $compile(markup)(scope); + scope.$digest(); + + mock.verify(); + }); + + it('creates a ' + type + ' chart using the "chart-type" attribute"', function () { + var markup = '
' + + '
'; + + scope.labels = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday']; + scope.type = type; + + if (['Line', 'Bar', 'Radar'].indexOf(type) > - 1) + scope.data = [ + [65, 59, 80, 81, 56, 55, 40], + [28, 48, 40, 19, 86, 27, 90] + ]; + else + scope.data = [300, 500, 100]; + + var mock = sandbox.mock(Chart.prototype); + mock.expects(type); + + $compile(markup)(scope); + scope.$digest(); + + mock.verify(); + }); + }); + }); + + it('generates the legend', function () { + var markup = '
' + + '
'; + + scope.labels = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday']; + scope.data = [ + [65, 59, 80, 81, 56, 55, 40], + [28, 48, 40, 19, 86, 27, 90] + ]; + + var element = $compile(markup)(scope); + scope.$digest(); + + expect(element.html()).to.have.string(''); + }); + }); + + describe('lifecycle', function () { + it('watches the attributes of the chart', function () { + var markup = '
' + + '
'; + + scope.labels = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday']; + scope.data = [ + [65, 59, 80, 81, 56, 55, 40], + [28, 48, 40, 19, 86, 27, 90] + ]; + + var mock = sandbox.mock(scope); + // cannot get a hold of the child scope as it isn't created yet + // so cannot be more precise on expectations + mock.expects('$watch').atLeast(6); + + $compile(markup)(scope); + + mock.verify(); + }); + + it('creates the chart only once', function () { + var markup = '
' + + '
'; + var count = 0; + + scope.labels = ['January', 'February', 'March', 'April', 'May', 'June', 'July']; + scope.series = ['Series A', 'Series B']; + scope.data = [ + [65, 59, 80, 81, 56, 55, 40], + [28, 48, 40, 19, 86, 27, 90] + ]; + scope.$on('create', function () { + count++; + }); + + $compile(markup)(scope); + scope.$digest(); + + expect(count).to.equal(1); + }); + + it('updates the chart', function () { + var markup = '
' + + '
'; + var count = 0; + + scope.labels = ['January', 'February', 'March', 'April', 'May', 'June', 'July']; + scope.series = ['Series A', 'Series B']; + scope.data = [ + [65, 59, 80, 81, 56, 55, 40], + [28, 48, 40, 19, 86, 27, 90] + ]; + + scope.$on('update', function () { + count++; + }); + + $compile(markup)(scope); + scope.$digest(); + + scope.data = [ + [28, 48, 40, 19, 86, 27, 90], + [65, 59, 80, 81, 56, 55, 40] + ]; + scope.$digest(); + + expect(count).to.equal(1); + }); + + it('re-create the chart if data added or removed', function () { + var markup = '
' + + '
'; + var countCreate = 0, countUpdate = 0; + + scope.labels = ['January', 'February', 'March', 'April', 'May', 'June', 'July']; + scope.data = [ + [65, 59, 80, 81, 56, 55, 40], + [28, 48, 40, 19, 86, 27, 90] + ]; + + scope.$on('create', function () { + countCreate++; + }); + + scope.$on('update', function () { + countUpdate++; + }); + + $compile(markup)(scope); + scope.$digest(); + + scope.data = [ + [28, 48, 40, 19, 86, 27, 90], + [65, 59, 80, 81, 56, 55, 40], + [65, 59, 80, 81, 56, 55, 40] + ]; + scope.$digest(); + + expect(countCreate).to.equal(2); + expect(countUpdate).to.equal(0); + }); + + it('should allow to set a configuration', function () { + ChartJsProvider.setOptions({responsive: false}); + expect(ChartJs.getOptions().responsive).to.equal(false); + expect(ChartJs.getOptions('Line').responsive).to.equal(false); + ChartJsProvider.setOptions({responsive: true}); + expect(ChartJs.getOptions().responsive).to.equal(true); + expect(ChartJs.getOptions('Line').responsive).to.equal(true); + }); + + it('should allow to set a configuration for a chart type', function () { + ChartJsProvider.setOptions('Line', {responsive: false}); + expect(ChartJs.getOptions('Line').responsive).to.equal(false); + ChartJsProvider.setOptions('Line', {responsive: true}); + expect(ChartJs.getOptions('Line').responsive).to.equal(true); + }); + + ['labels', 'colours', 'series', 'options'].forEach(function (attr) { + it('re-creates the chart on ' + attr + ' changes', function () { + var markup = '
' + + '
'; + var count = 0; + + scope.options = { scaleShowVerticalLines: false }; + scope.labels = ['January', 'February', 'March', 'April', 'May', 'June', 'July']; + scope.series = ['Series A', 'Series B']; + scope.colours = [{ + fillColor: 'rgba(127,253,31,0.2)', + pointColor: 'rgba(127,253,31,1)', + pointHighlightFill: '#fff', + pointHighlightStroke: 'rgba(127,253,31,0.8)', + pointStrokeColor: '#fff', + strokeColor: 'rgba(127,253,31,1)' + }, { + fillColor: 'rgba(104,240,0,0.2)', + pointColor: 'rgba(104,240,0,1)', + pointHighlightFill: '#fff', + pointHighlightStroke: 'rgba(104,240,0,0.8)', + pointStrokeColor: '#fff', + strokeColor: 'rgba(104,240,0,1)' + }]; + scope.data = [ + [65, 59, 80, 81, 56, 55, 40], + [28, 48, 40, 19, 86, 27, 90] + ]; + scope.$on('create', function () { + count++; + }); + + $compile(markup)(scope); + scope.$digest(); + + switch (attr) { + case 'labels': + scope.labels = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday']; + break; + case 'colours': + scope.colours = [{ + fillColor: 'rgba(253,31,94,0.2)', + pointColor: 'rgba(253,31,94,1)', + pointHighlightFill: '#fff', + pointHighlightStroke: 'rgba(253,31,94,0.8)', + pointStrokeColor: '#fff', + strokeColor: 'rgba(253,31,94,1)' + }, { + fillColor: 'rgba(30,249,161,0.2)', + pointColor: 'rgba(30,249,161,1)', + pointHighlightFill: '#fff', + pointHighlightStroke: 'rgba(30,249,161,0.8)', + pointStrokeColor: '#fff', + strokeColor: 'rgba(30,249,161,1)' + }]; + break; + case 'series': + scope.series = ['Series C', 'Series D']; + break; + case 'options': + scope.options = { scaleShowVerticalLines: true }; + break; + } + scope.$digest(); + + expect(count).to.equal(2); + }); + }); + + ['labels', 'colours', 'series', 'options'].forEach(function (attr) { + it('does not re-create the chart on ' + attr + ' not changed', function () { + var markup = '
' + + '
'; + var count = 0; + + scope.options = { scaleShowVerticalLines: false }; + scope.labels = ['January', 'February', 'March', 'April', 'May', 'June', 'July']; + scope.series = ['Series A', 'Series B']; + scope.colours = [{ + fillColor: 'rgba(127,253,31,0.2)', + pointColor: 'rgba(127,253,31,1)', + pointHighlightFill: '#fff', + pointHighlightStroke: 'rgba(127,253,31,0.8)', + pointStrokeColor: '#fff', + strokeColor: 'rgba(127,253,31,1)' + }, { + fillColor: 'rgba(104,240,0,0.2)', + pointColor: 'rgba(104,240,0,1)', + pointHighlightFill: '#fff', + pointHighlightStroke: 'rgba(104,240,0,0.8)', + pointStrokeColor: '#fff', + strokeColor: 'rgba(104,240,0,1)' + }]; + scope.data = [ + [65, 59, 80, 81, 56, 55, 40], + [28, 48, 40, 19, 86, 27, 90] + ]; + scope.$on('create', function () { + count++; + }); + + $compile(markup)(scope); + scope.$digest(); + + switch (attr) { + case 'labels': + scope.labels = ['January', 'February', 'March', 'April', 'May', 'June', 'July']; + break; + case 'colours': + scope.colours = [{ + fillColor: 'rgba(127,253,31,0.2)', + pointColor: 'rgba(127,253,31,1)', + pointHighlightFill: '#fff', + pointHighlightStroke: 'rgba(127,253,31,0.8)', + pointStrokeColor: '#fff', + strokeColor: 'rgba(127,253,31,1)' + }, { + fillColor: 'rgba(104,240,0,0.2)', + pointColor: 'rgba(104,240,0,1)', + pointHighlightFill: '#fff', + pointHighlightStroke: 'rgba(104,240,0,0.8)', + pointStrokeColor: '#fff', + strokeColor: 'rgba(104,240,0,1)' + }]; + break; + case 'series': + scope.series = ['Series A', 'Series B']; + break; + case 'options': + scope.options = { scaleShowVerticalLines: false }; + break; + } + scope.$digest(); + + expect(count).to.equal(1); + }); + }); + }); +}); diff --git a/templates/views/index.html b/templates/views/index.html index c683489..f1fef9e 100644 --- a/templates/views/index.html +++ b/templates/views/index.html @@ -6,6 +6,10 @@ + + + + @@ -79,6 +83,14 @@ + + + + + + + + diff --git a/templates/views/settings.html b/templates/views/settings.html index 7f07403..8121fb4 100644 --- a/templates/views/settings.html +++ b/templates/views/settings.html @@ -55,6 +55,8 @@
+