Merge branch 'master' of https://github.com/sagidayan/SE-Hub into QA

This commit is contained in:
etyemyer 2015-06-19 07:48:15 +03:00
commit 9d5cc26abd
66 changed files with 13415 additions and 169 deletions

View file

@ -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')

View file

@ -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()

View file

@ -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/<string:token>', methods=["GET"])
@auto.doc()
def getUserByToken(token):
@ -59,6 +59,9 @@ def getUserByToken(token):
<br>
403 - No User Found
"""
if token is None:
return no_content("Token Is Empty, No User Found")
query = User.all()
query.filter("seToken =", token)

View file

@ -2,10 +2,10 @@
body{
font-family: "Alef Hebrew",
Helvetica Neue,
Helvetica,
Arial,
sans-serif;
Helvetica Neue,
Helvetica,
Arial,
sans-serif;
}
.menuBtn {
@ -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;
-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,37 +104,33 @@ body.noscroll
}*/
.campusAvatar img
{
/*
margin-top: 1em;
margin-right: 1em;
position: center;
*/
.campusAvatar img
{
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,13 +138,55 @@ body.noscroll
position:relative;
}
/*div.img campusAvatar
.listdemoBasicUsage md-divider
{
border: 1px solid #0000ff;
padding-right: 10px;
float:right;
}*/
margin-top: 10px;
margin-bottom: 10px;
}
.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%;
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;
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);
}
/*.dropDown /* TODO *
{
@ -166,10 +197,47 @@ body.noscroll
border-radius: 1px black solid;
}*/
.gray-font{
.gray-font
{
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{
@ -189,7 +257,6 @@ body.noscroll
-moz-border-radius: 100px;
border-radius: 50px;
width: 30%;
/*top: -40px;*/
position: relative;
z-index: 50;
}
@ -235,7 +302,6 @@ body.noscroll
.user-box img{
width: 100%;
border: 4px #7f7f7f solid;
-webkit-border-radius: 5px;
-moz-border-radius: 5px;
border-radius: 5px;
@ -247,4 +313,112 @@ body.noscroll
.se-menu ul a{
text-decoration: none !important;
color: #7f7f7f;
}
}
/*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;
}
/*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;
}
.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 {
font-size: inherit;
height: inherit;
text-align: left;
text-transform: none;
width: 300px;
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*/

View file

@ -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) {
@ -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'
});
}
]);

View file

@ -1,9 +1,57 @@
/**
* 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: '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"
},
];
// animation
$scope.isEnterd = top.setIsEnterd;
}]);

View file

@ -1,78 +1,90 @@
angular.module('SeHub')
.controller('mainController', ['$scope', '$rootScope', 'apiService', '$cookies', '$location', function($scope, $rootScope, apiService, $cookies, $location) {
.controller('mainController', ['$scope', '$rootScope', 'dataService','apiService', '$cookies', '$cookieStore', '$location', '$window',
var token = $cookies['com.sehub.www'];
function($scope, $rootScope, dataService, apiService, $cookies, $cookieStore, $location, $window) {
top.setIsEnterd = true;
var token = $cookies['com.sehub.www'];
$scope.loadingData = true;
$scope.isInRegisterMode = false;
$scope.loadingData = true;
$scope.isInRegisterMode = false;
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.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;
dataService.initService($scope); //Start Data Sync Service (For User)
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": "/tasks"
}, {
"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 = "";
}
};
top.setIsEnterd = false;
$location.path(route);
}
}
}]);
]);

View file

@ -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)

View file

@ -1,30 +1,93 @@
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'];
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 {
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";
}
}
});
/**
* 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.labels = ['Commits', 'Issues Assigned', 'Messages', 'Open Tasks'];
$scope.series = ['Project A', 'Project B'];
$scope.data = [
[54, 3, 15, 3],
[28, 48, 40, 3]
];
}]);
}
]);

View file

@ -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

View file

@ -0,0 +1,4 @@
.idea/
node_modules/
test/fixtures/shots/
bower_components/

View file

@ -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"
]
}

View file

@ -0,0 +1,6 @@
bower_components/
node_modules/
dist/
tmp/
examples/smoothscroll.min.js

View file

@ -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"
]
}

View file

@ -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

View file

@ -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.

View file

@ -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
<script src="../bower_components/angular/angular.min.js"></script>
<script src="/bower_components/Chart.js/Chart.min.js"></script>
<script src="/bower_components/angular-chart.js/dist/angular-chart.js"></script>
```
# 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
<head>
<!--[if lt IE 9]><script src="excanvas.js"></script><![endif]-->
<!--[if lt IE 9]><script src="es5-shim.js"></script><![endif]-->
</head>
```
# Example
## Markup
```html
<canvas id="line" class="chart chart-line" data="data" labels="labels"
legend="true" series="series" click="onClick"></canvas>
```
## 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.

View file

@ -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-legend>' + chart.generateLegend() + '</chart-legend>';
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);
}
}
}));

View file

@ -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;
}
}
}

View file

@ -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 <jtblin@gmail.com>"
],
"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"
}
}

View file

@ -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 */

View file

@ -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/"}

View file

@ -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-legend>' + chart.generateLegend() + '</chart-legend>';
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);
}
}
}));

Binary file not shown.

View file

@ -0,0 +1,2 @@
!function(t){"use strict";"function"==typeof define&&define.amd?define(["angular","chart.js"],t):"object"==typeof exports?module.exports=t(require("angular"),require("chart.js")):t(angular,Chart)}(function(t,e){"use strict";function n(){var n={},r={Chart:e,getOptions:function(e){var r=e&&n[e]||{};return t.extend({},n,r)}};this.setOptions=function(e,r){return r?(n[e]=t.extend(n[e]||{},r),void 0):(r=e,n=t.extend(n,r),void 0)},this.$get=function(){return r}}function r(n){function r(t,e){return t&&e&&t.length&&e.length?Array.isArray(t[0])?t.length===e.length&&t[0].length===e[0].length:e.reduce(a,0)>0?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<a.data.length;)o.push(a.getColour());return o.map(u)}function u(t){return"object"==typeof t&&null!==t?t:"string"==typeof t&&"#"===t[0]?s(d(t.substr(1))):l()}function l(){var t=[f(0,255),f(0,255),f(0,255)];return s(t)}function s(t){return{fillColor:h(t,.2),strokeColor:h(t,1),pointColor:h(t,1),pointStrokeColor:"#fff",pointHighlightFill:"#fff",pointHighlightStroke:h(t,.8)}}function f(t,e){return Math.floor(Math.random()*(e-t+1))+t}function h(t,e){return"rgba("+t.concat(e).join(",")+")"}function d(t){var e=parseInt(t,16),n=e>>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="<chart-legend>"+e.generateLegend()+"</chart-legend>";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

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load diff

View file

@ -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;
}

View file

@ -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;
}
})();

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,462 @@
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>Charts</title>
<link rel="stylesheet" href="../dist/angular-chart.css">
<link rel="stylesheet" href="../bower_components/font-awesome/css/font-awesome.min.css">
<link rel="stylesheet" href="../bower_components/rainbow/themes/github.css">
<link href="bootstrap.css" rel="stylesheet">
<link href="app.css" rel="stylesheet">
</head>
<body ng-app="examples" id="top">
<div class="navbar navbar-default navbar-fixed-top">
<div class="container" ng-controller="MenuCtrl">
<div class="navbar-header">
<button type="button" class="navbar-toggle" ng-click="isCollapsed = !isCollapsed">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand visible-xs" href="#">Angular Charts</a>
</div>
<nav class="hidden-xs">
<ul class="nav navbar-nav">
<li>
<a href="#top" role="button" class="navbar-brand">
Angular Chart
</a>
</li>
<li class="dropdown">
<a role="button" class="dropdown-toggle" aria-haspopup="true" aria-expanded="false">
Directives <b class="caret"></b>
</a>
<ul class="dropdown-menu">
<li ng-repeat="chart in charts"><a ng-href="#{{chart | lowercase }}-chart">{{chart}}</a></li>
</ul>
</li>
<li><a href="#getting_started">Getting started</a></li>
<li><a href="#reactive">Reactive</a></li>
</ul>
</nav>
<nav class="collapse" collapse="isCollapsed" style="height: 0px;">
<ul class="nav navbar-nav">
<li><a href="#getting_started" ng-click="isCollapsed = !isCollapsed">Getting started</a></li>
<li><a href="#directives" ng-click="isCollapsed = !isCollapsed">Directives</a></li>
</ul>
</nav>
</div>
</div>
<div class="container-fluid">
<div class="text-center aspect-ratio" id="container" ng-controller="TicksCtrl">
<canvas width='1200' height='300' id="hero-bar" class="chart chart-line chart-xl" data="data" options="options" labels="labels"></canvas>
<div class="header">
<h1>
Angular Chart
</h1>
<p>Reactive, responsive, beautiful charts for <a href="http://angularjs.org">AngularJS</a> based on <a href="http://www.chartjs.org">Chart.js</a></p>
<p>
<a class="btn btn-default btn-lg" href="https://github.com/jtblin/angular-chart"><i class="icon-github"></i>Code on Github</a>
<a class="btn btn-success btn-lg" href="../dist/angular-chart.js.tar.gz" download="angular-chart.js.tar.gz">
<i class="fa fa-download"></i> Download <small>(0.7.2)</small>
</a>
</p>
</div>
</div>
</div>
<div class="container">
<section id="getting_started">
<div class="page-header">
<h1>Getting started</h1>
</div>
<h3>Dependencies</h3>
<p>
This repository contains a set of <strong>native AngularJS directives</strong> for Chart.js. The <strong>only required dependencies</strong> are:
</p>
<ul>
<li><a href="http://angularjs.org" target="_blank">AngularJS</a> (tested with 1.2.20 and 1.3.10 although it probably works with older versions)</li>
<li><a href="http://chartjs.org" target="_blank">Chart.js</a> (requires Chart.js 1.0, tested with version 1.0.1-beta.2, 1.0.1-beta.4, and and 1.0.1).</li>
</ul>
<h3>Files to download</h3>
<p>
The easiest is to download with <strong>bower</strong>:
<pre>bower install angular-chart.js --save</pre>
Alternatively files can be downloaded <a href="https://github.com/jtblin/angular-chart.js">downloaded from Github</a>.
</p>
<p>Whichever method you choose the good news is that the overall size is very small:
&lt;5kb for all directives (~1kb with gzip compression!)</p>
<h3>Installation</h3>
</p><pre><code>&lt;script src=&quot;bower_components/dist/angular-chart.js&quot;&gt;&lt;/script&gt;</code></pre>
<p>As soon as you've got all the files downloaded and included in your page you just need to declare
a dependency on the <code>chart.js</code> <a href="http://docs.angularjs.org/guide/module">module</a>:<br>
</p><pre><code>angular.module('myModule', ['chart.js']);</code></pre>
<p></p>
<h3>CSS</h3>
<p>You need to include a link to the css file in your page.</p>
</p><pre><code>&lt;link rel=&quot;stylesheet&quot; href=&quot;bower_components/dist/angular-chart.css&quot;&gt;</code></pre>
<p></p>
<h3>Colours</h3>
<p>Series have beautiful pre-sets colours (to a maximum of 7 series, after that colours will be randomly generated).
They can be overwritten using <code>Chart.defaults.global.colours</code>.</p>
<ol class="chart-legend">
<li><span style="background-color: rgba(151,187,205,1)"></span> Blue</li>
<li><span style="background-color: rgba(220,220,220,1)"></span>Light grey</li>
<li><span style="background-color: rgba(247,70,74,1)"></span>Red</li>
<li><span style="background-color: rgba(70,191,189,1)"></span>Green</li>
<li><span style="background-color: rgba(253,180,92,1)"></span>Yellow</li>
<li><span style="background-color: rgba(148,159,177,1)"></span>Grey</li>
<li><span style="background-color: rgba(77,83,96,1)"></span>Dark Grey</li>
</ol>
</section>
<section id="directives">
<div class="page-header">
<h1>Directives</h1>
</div>
<div class="row">
<div class="col-lg-6 col-sm-12" id="line-chart" ng-controller="LineCtrl">
<div class="panel panel-default">
<div class="panel-heading">Line Chart</div>
<div class="panel-body">
<canvas id="line" class="chart chart-line" data="data" labels="labels" legend="true"
click="onClick" hover="onHover" series="series"></canvas>
</div>
</div>
</div>
<div class="col-lg-6 col-sm-12 code">
<tabset>
<tab heading="Settings" class="settings">
<div class="settings">
<code>.chart-line</code>
<ul>
<li><code>data</code>: series data</li>
<li><code>labels</code>: x axis labels</li>
<li><code>legend</code> (default: <code>false</code>): show legend below the chart</li>
<li><code>options</code> (default: <code>{}</code>): Chart.js options</li>
<li><code>series</code> (default: <code>[]</code>): series labels</li>
<li><code>click</code> (optional): onclick event handler</li>
<li><code>colours</code> (default to global colours): colours for the chart</li>
</ul>
</div>
</tab>
<tab heading="Markup">
<pre><code data-language="html">&lt;canvas id=&quot;line&quot; class=&quot;chart chart-line&quot; data=&quot;data&quot;
labels=&quot;labels&quot; legend=&quot;true&quot; series=&quot;series&quot;
click=&quot;onClick&quot;&gt;
&lt;/canvas&gt; </code></pre>
</tab>
<tab heading="Javascript">
<pre><code data-language="javascript">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);
};
});
</code></pre>
</tab>
</tabset>
</div>
</div>
<div class="row">
<div class="col-lg-6 col-sm-12 code">
<tabset>
<tab heading="Settings" class="settings">
<div class="settings">
<code>.chart-bar</code>
<ul>
<li><code>data</code>: series data</li>
<li><code>labels</code>: x axis labels</li>
<li><code>legend</code> (default: <code>false</code>): show legend below the chart</li>
<li><code>options</code> (default: <code>{}</code>): Chart.js options</li>
<li><code>series</code> (default: <code>[]</code>): series labels</li>
<li><code>colours</code> (default to global colours): colours for the chart</li>
</ul>
</div>
</tab>
<tab heading="Markup">
<pre><code data-language="html">&lt;canvas id=&quot;bar&quot; class=&quot;chart chart-bar&quot; data=&quot;data&quot;
labels=&quot;labels&quot;&gt;&lt;/canvas&gt; </code></pre>
</tab>
<tab heading="Javascript">
<pre><code data-language="javascript">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]
];
});
</code></pre>
</tab>
</tabset>
</div>
<div class="col-lg-6 col-sm-12" id="bar-chart" ng-controller="BarCtrl">
<div class="panel panel-default">
<div class="panel-heading">Bar Chart</div>
<div class="panel-body">
<canvas id="bar" class="chart chart-bar" data="data" labels="labels" series="series"
options="options"></canvas>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-lg-6 col-sm-12" id="doughnut-chart" ng-controller="DoughnutCtrl">
<div class="panel panel-default">
<div class="panel-heading">Doughnut Chart</div>
<div class="panel-body">
<canvas id="doughnut" class="chart chart-doughnut chart-xs" data="data" labels="labels" legend="false"></canvas>
</div>
</div>
</div>
<div class="col-lg-6 col-sm-12 code">
<tabset>
<tab heading="Settings" class="settings">
<div class="settings">
<code>.chart-doughnut</code>
<ul>
<li><code>data</code>: series data</li>
<li><code>labels</code>: series labels</li>
<li><code>legend</code> (default: <code>false</code>): show legend below the chart</li>
<li><code>options</code> (default: <code>{}</code>): Chart.js options</li>
<li><code>colours</code> (default to global colours): colours for the chart</li>
</ul>
</div>
</tab>
<tab heading="Markup">
<pre><code data-language="html">&lt;canvas id=&quot;doughnut&quot; class=&quot;chart chart-doughnut&quot; data=&quot;data&quot;
labels=&quot;labels&quot;&gt;&lt;/canvas&gt; </code></pre>
</tab>
<tab heading="Javascript">
<pre><code data-language="javascript">angular.module("app", ["chart.js"]).controller("DoughnutCtrl", function ($scope) {
$scope.labels = ["Download Sales", "In-Store Sales", "Mail-Order Sales"];
$scope.data = [300, 500, 100];
});
</code></pre>
</tab>
</tabset>
</div>
</div>
<div class="row">
<div class="col-lg-6 col-sm-12 code">
<tabset>
<tab heading="Settings" class="settings">
<div class="settings">
<code>.chart-radar</code>
<ul>
<li><code>data</code>: series data</li>
<li><code>labels</code>: series labels</li>
<li><code>legend</code> (default: <code>false</code>): show legend below the chart</li>
<li><code>options</code> (default: <code>{}</code>): Chart.js options</li>
<li><code>series</code> (default: <code>[]</code>): series labels</li>
<li><code>click</code> (optional): onclick event handler</li>
<li><code>colours</code> (default to global colours): colours for the chart</li>
</ul>
</div>
</tab>
<tab heading="Markup">
<pre><code data-language="html">&lt;canvas id=&quot;radar&quot; class=&quot;chart chart-radar&quot; data=&quot;data&quot;
labels=&quot;labels&quot;&gt;&lt;/canvas&gt; </code></pre>
</tab>
<tab heading="Javascript">
<pre><code data-language="javascript">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]
];
});
</code></pre>
</tab>
</tabset>
</div>
<div class="col-lg-6 col-sm-12" id="radar-chart" ng-controller="RadarCtrl">
<div class="panel panel-default">
<div class="panel-heading">Radar Chart</div>
<div class="panel-body">
<canvas id="area" class="chart chart-radar" data="data" labels="labels" click="onClick"></canvas>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-lg-6 col-sm-12" id="pie-chart" ng-controller="PieCtrl">
<div class="panel panel-default">
<div class="panel-heading">Pie Chart</div>
<div class="panel-body">
<canvas id="pie" class="chart chart-pie chart-xs" data="data" labels="labels"></canvas>
</div>
</div>
</div>
<div class="col-lg-6 col-sm-12 code">
<tabset>
<tab heading="Settings" class="settings">
<div class="settings">
<code>.chart-pie</code>
<ul>
<li><code>data</code>: series data</li>
<li><code>labels</code>: series labels</li>
<li><code>legend</code> (default: <code>false</code>): show legend below the chart</li>
<li><code>options</code> (default: <code>{}</code>): Chart.js options</li>
<li><code>colours</code> (default to global colours): colours for the chart</li>
</ul>
</div>
</tab>
<tab heading="Markup">
<pre><code data-language="html">&lt;canvas id=&quot;pie&quot; class=&quot;chart chart-pie&quot; data=&quot;data&quot;
labels=&quot;labels&quot;&gt;&lt;/canvas&gt; </code></pre>
</tab>
<tab heading="Javascript">
<pre><code data-language="javascript">angular.module("app", ["chart.js"]).controller("PieCtrl", function ($scope) {
$scope.labels = ["Download Sales", "In-Store Sales", "Mail-Order Sales"];
$scope.data = [300, 500, 100];
});
</code></pre>
</tab>
</tabset>
</div>
</div>
<div class="row">
<div class="col-lg-6 col-sm-12 code">
<tabset>
<tab heading="Settings" class="settings">
<div class="settings">
<code>.chart-polar-area</code>
<ul>
<li><code>data</code>: series data</li>
<li><code>labels</code>: series labels</li>
<li><code>legend</code> (default: <code>false</code>): show legend below the chart</li>
<li><code>options</code> (default: <code>{}</code>): Chart.js options</li>
<li><code>colours</code> (default to global colours): colours for the chart</li>
</ul>
</div>
</tab>
<tab heading="Markup">
<pre><code data-language="html">&lt;canvas id=&quot;polar-area&quot; class=&quot;chart chart-polar-area&quot; data=&quot;data&quot;
labels=&quot;labels&quot;&gt;&lt;/canvas&gt; </code></pre>
</tab>
<tab heading="Javascript">
<pre><code data-language="javascript">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];
});
</code></pre>
</tab>
</tabset>
</div>
<div class="col-lg-6 col-sm-12" id="polar area-chart" ng-controller="PolarAreaCtrl">
<div class="panel panel-default">
<div class="panel-heading">Polar Area Chart</div>
<div class="panel-body">
<canvas id="polar" class="chart chart-polar-area" data="data" labels="labels"></canvas>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-lg-6 col-sm-12" id="base-chart" ng-controller="BaseCtrl">
<div class="panel panel-default">
<div class="panel-heading">Dynamic Chart</div>
<div class="panel-body">
<canvas id="base" class="chart chart-base" chart-type="type" data="data" labels="labels" legend="true"></canvas>
</div>
</div>
<button type="button" class="btn btn-primary pull-right" ng-click="toggle()">Toggle</button>
</div>
<div class="col-lg-6 col-sm-12 code">
<tabset>
<tab heading="Settings" class="settings">
<div class="settings">
<code>.chart-base</code>
<ul>
<li><code>chart-type</code>: chart type e.g. Bar, PolarArea, etc. or other plugins</li>
<li>other options according to chart type</li>
</ul>
</div>
</tab>
<tab heading="Markup">
<pre><code data-language="html">&lt;canvas id=&quot;base&quot; class=&quot;chart-base&quot; chart-type=&quot;type&quot; data=&quot;data&quot;
labels=&quot;labels&quot; legend=&quot;true&quot;&gt;&lt;/canvas&gt; </code></pre>
</tab>
<tab heading="Javascript">
<pre><code data-language="javascript">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';
};
});
</code></pre>
</tab>
</tabset>
</div>
</div>
</section>
<section id="reactive">
<div class="page-header">
<h1>Reactive</h1>
<p>All charts are reactive and will update automatically when data changes.</p>
</div>
<div class="row" ng-controller="DataTablesCtrl">
<div class="col-lg-6 col-sm-12">
<div class="panel panel-default">
<div class="panel-heading">Chart Data</div>
<div class="panel-body">
<table class="table table-responsive table-condensed table-striped">
<tr>
<th ng-repeat="label in labels">{{label}}</th>
</tr>
<tr ng-repeat="dataSet in data">
<td ng-repeat="set in dataSet track by $index"><span style="text-align: right;">{{data[$parent.$index][$index]}}</span></td>
</tr>
</table>
<button type="button" class="btn btn-primary pull-right" ng-click="randomize()">Randomize</button>
</div>
</div>
</div>
<div class="col-lg-6 col-sm-12">
<div class="panel panel-default">
<div class="panel-heading">Reactive Chart</div>
<div class="panel-body">
<canvas id="tables" class="chart chart-line" data="data" labels="labels" colours="colours"></canvas>
</div>
</div>
</div>
</div>
</section>
</div>
<footer class="footer">
<div class="container">
<p>Designed and built by <a href="https://github.com/jtblin" target="_blank">Jerome Touffe-Blin</a></p>
<p>Code licensed under <a href="https://github.com/jtblin/angular-chart.js/blob/master/LICENSE">BSD License</a>.</p>
<p><a href="https://github.com/jtblin/angular-chart.js/issues?state=open">Issues</a></p>
<p><strong>Credits</strong>: <a href="http://www.chartjs.org/">Chart.js</a> and <a href="https://angularjs.org/">AngularJS</a></p>
</div>
</footer>
<script src="../bower_components/angular/angular.min.js"></script>
<script src="../bower_components/Chart.js/Chart.js"></script>
<script src="../bower_components/angular-bootstrap/ui-bootstrap-tpls.min.js"></script>
<script src="../bower_components/rainbow/js/rainbow.min.js"></script>
<script src="../bower_components/rainbow/js/language/generic.js"></script>
<script src="../bower_components/rainbow/js/language/html.js"></script>
<script src="../bower_components/rainbow/js/language/javascript.js"></script>
<script src="../angular-chart.js"></script>
<script src="smoothscroll.min.js"></script>
<script src="app.js"></script>
</body>
</html>

View file

@ -0,0 +1,462 @@
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>Charts</title>
<link rel="stylesheet" href="../dist/angular-chart.css">
<link rel="stylesheet" href="../bower_components/font-awesome/css/font-awesome.min.css">
<link rel="stylesheet" href="../bower_components/rainbow/themes/github.css">
<link href="bootstrap.css" rel="stylesheet">
<link href="app.css" rel="stylesheet">
</head>
<body ng-app="examples" id="top">
<div class="navbar navbar-default navbar-fixed-top">
<div class="container" ng-controller="MenuCtrl">
<div class="navbar-header">
<button type="button" class="navbar-toggle" ng-click="isCollapsed = !isCollapsed">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand visible-xs" href="#">Angular Charts</a>
</div>
<nav class="hidden-xs">
<ul class="nav navbar-nav">
<li>
<a href="#top" role="button" class="navbar-brand">
Angular Chart
</a>
</li>
<li class="dropdown">
<a role="button" class="dropdown-toggle" aria-haspopup="true" aria-expanded="false">
Directives <b class="caret"></b>
</a>
<ul class="dropdown-menu">
<li ng-repeat="chart in charts"><a ng-href="#{{chart | lowercase }}-chart">{{chart}}</a></li>
</ul>
</li>
<li><a href="#getting_started">Getting started</a></li>
<li><a href="#reactive">Reactive</a></li>
</ul>
</nav>
<nav class="collapse" collapse="isCollapsed" style="height: 0px;">
<ul class="nav navbar-nav">
<li><a href="#getting_started" ng-click="isCollapsed = !isCollapsed">Getting started</a></li>
<li><a href="#directives" ng-click="isCollapsed = !isCollapsed">Directives</a></li>
</ul>
</nav>
</div>
</div>
<div class="container-fluid">
<div class="text-center aspect-ratio" id="container" ng-controller="TicksCtrl">
<canvas width='1200' height='300' id="hero-bar" class="chart chart-line chart-xl" data="data" options="options" labels="labels"></canvas>
<div class="header">
<h1>
Angular Chart
</h1>
<p>Reactive, responsive, beautiful charts for <a href="http://angularjs.org">AngularJS</a> based on <a href="http://www.chartjs.org">Chart.js</a></p>
<p>
<a class="btn btn-default btn-lg" href="https://github.com/jtblin/angular-chart"><i class="icon-github"></i>Code on Github</a>
<a class="btn btn-success btn-lg" href="../dist/angular-chart.js.tar.gz" download="angular-chart.js.tar.gz">
<i class="fa fa-download"></i> Download <small>(<!-- version -->)</small>
</a>
</p>
</div>
</div>
</div>
<div class="container">
<section id="getting_started">
<div class="page-header">
<h1>Getting started</h1>
</div>
<h3>Dependencies</h3>
<p>
This repository contains a set of <strong>native AngularJS directives</strong> for Chart.js. The <strong>only required dependencies</strong> are:
</p>
<ul>
<li><a href="http://angularjs.org" target="_blank">AngularJS</a> (tested with 1.2.20 and 1.3.10 although it probably works with older versions)</li>
<li><a href="http://chartjs.org" target="_blank">Chart.js</a> (requires Chart.js 1.0, tested with version 1.0.1-beta.2, 1.0.1-beta.4, and and 1.0.1).</li>
</ul>
<h3>Files to download</h3>
<p>
The easiest is to download with <strong>bower</strong>:
<pre>bower install angular-chart.js --save</pre>
Alternatively files can be downloaded <a href="https://github.com/jtblin/angular-chart.js">downloaded from Github</a>.
</p>
<p>Whichever method you choose the good news is that the overall size is very small:
&lt;5kb for all directives (~1kb with gzip compression!)</p>
<h3>Installation</h3>
</p><pre><code>&lt;script src=&quot;bower_components/dist/angular-chart.js&quot;&gt;&lt;/script&gt;</code></pre>
<p>As soon as you've got all the files downloaded and included in your page you just need to declare
a dependency on the <code>chart.js</code> <a href="http://docs.angularjs.org/guide/module">module</a>:<br>
</p><pre><code>angular.module('myModule', ['chart.js']);</code></pre>
<p></p>
<h3>CSS</h3>
<p>You need to include a link to the css file in your page.</p>
</p><pre><code>&lt;link rel=&quot;stylesheet&quot; href=&quot;bower_components/dist/angular-chart.css&quot;&gt;</code></pre>
<p></p>
<h3>Colours</h3>
<p>Series have beautiful pre-sets colours (to a maximum of 7 series, after that colours will be randomly generated).
They can be overwritten using <code>Chart.defaults.global.colours</code>.</p>
<ol class="chart-legend">
<li><span style="background-color: rgba(151,187,205,1)"></span> Blue</li>
<li><span style="background-color: rgba(220,220,220,1)"></span>Light grey</li>
<li><span style="background-color: rgba(247,70,74,1)"></span>Red</li>
<li><span style="background-color: rgba(70,191,189,1)"></span>Green</li>
<li><span style="background-color: rgba(253,180,92,1)"></span>Yellow</li>
<li><span style="background-color: rgba(148,159,177,1)"></span>Grey</li>
<li><span style="background-color: rgba(77,83,96,1)"></span>Dark Grey</li>
</ol>
</section>
<section id="directives">
<div class="page-header">
<h1>Directives</h1>
</div>
<div class="row">
<div class="col-lg-6 col-sm-12" id="line-chart" ng-controller="LineCtrl">
<div class="panel panel-default">
<div class="panel-heading">Line Chart</div>
<div class="panel-body">
<canvas id="line" class="chart chart-line" data="data" labels="labels" legend="true"
click="onClick" hover="onHover" series="series"></canvas>
</div>
</div>
</div>
<div class="col-lg-6 col-sm-12 code">
<tabset>
<tab heading="Settings" class="settings">
<div class="settings">
<code>.chart-line</code>
<ul>
<li><code>data</code>: series data</li>
<li><code>labels</code>: x axis labels</li>
<li><code>legend</code> (default: <code>false</code>): show legend below the chart</li>
<li><code>options</code> (default: <code>{}</code>): Chart.js options</li>
<li><code>series</code> (default: <code>[]</code>): series labels</li>
<li><code>click</code> (optional): onclick event handler</li>
<li><code>colours</code> (default to global colours): colours for the chart</li>
</ul>
</div>
</tab>
<tab heading="Markup">
<pre><code data-language="html">&lt;canvas id=&quot;line&quot; class=&quot;chart chart-line&quot; data=&quot;data&quot;
labels=&quot;labels&quot; legend=&quot;true&quot; series=&quot;series&quot;
click=&quot;onClick&quot;&gt;
&lt;/canvas&gt; </code></pre>
</tab>
<tab heading="Javascript">
<pre><code data-language="javascript">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);
};
});
</code></pre>
</tab>
</tabset>
</div>
</div>
<div class="row">
<div class="col-lg-6 col-sm-12 code">
<tabset>
<tab heading="Settings" class="settings">
<div class="settings">
<code>.chart-bar</code>
<ul>
<li><code>data</code>: series data</li>
<li><code>labels</code>: x axis labels</li>
<li><code>legend</code> (default: <code>false</code>): show legend below the chart</li>
<li><code>options</code> (default: <code>{}</code>): Chart.js options</li>
<li><code>series</code> (default: <code>[]</code>): series labels</li>
<li><code>colours</code> (default to global colours): colours for the chart</li>
</ul>
</div>
</tab>
<tab heading="Markup">
<pre><code data-language="html">&lt;canvas id=&quot;bar&quot; class=&quot;chart chart-bar&quot; data=&quot;data&quot;
labels=&quot;labels&quot;&gt;&lt;/canvas&gt; </code></pre>
</tab>
<tab heading="Javascript">
<pre><code data-language="javascript">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]
];
});
</code></pre>
</tab>
</tabset>
</div>
<div class="col-lg-6 col-sm-12" id="bar-chart" ng-controller="BarCtrl">
<div class="panel panel-default">
<div class="panel-heading">Bar Chart</div>
<div class="panel-body">
<canvas id="bar" class="chart chart-bar" data="data" labels="labels" series="series"
options="options"></canvas>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-lg-6 col-sm-12" id="doughnut-chart" ng-controller="DoughnutCtrl">
<div class="panel panel-default">
<div class="panel-heading">Doughnut Chart</div>
<div class="panel-body">
<canvas id="doughnut" class="chart chart-doughnut chart-xs" data="data" labels="labels" legend="false"></canvas>
</div>
</div>
</div>
<div class="col-lg-6 col-sm-12 code">
<tabset>
<tab heading="Settings" class="settings">
<div class="settings">
<code>.chart-doughnut</code>
<ul>
<li><code>data</code>: series data</li>
<li><code>labels</code>: series labels</li>
<li><code>legend</code> (default: <code>false</code>): show legend below the chart</li>
<li><code>options</code> (default: <code>{}</code>): Chart.js options</li>
<li><code>colours</code> (default to global colours): colours for the chart</li>
</ul>
</div>
</tab>
<tab heading="Markup">
<pre><code data-language="html">&lt;canvas id=&quot;doughnut&quot; class=&quot;chart chart-doughnut&quot; data=&quot;data&quot;
labels=&quot;labels&quot;&gt;&lt;/canvas&gt; </code></pre>
</tab>
<tab heading="Javascript">
<pre><code data-language="javascript">angular.module("app", ["chart.js"]).controller("DoughnutCtrl", function ($scope) {
$scope.labels = ["Download Sales", "In-Store Sales", "Mail-Order Sales"];
$scope.data = [300, 500, 100];
});
</code></pre>
</tab>
</tabset>
</div>
</div>
<div class="row">
<div class="col-lg-6 col-sm-12 code">
<tabset>
<tab heading="Settings" class="settings">
<div class="settings">
<code>.chart-radar</code>
<ul>
<li><code>data</code>: series data</li>
<li><code>labels</code>: series labels</li>
<li><code>legend</code> (default: <code>false</code>): show legend below the chart</li>
<li><code>options</code> (default: <code>{}</code>): Chart.js options</li>
<li><code>series</code> (default: <code>[]</code>): series labels</li>
<li><code>click</code> (optional): onclick event handler</li>
<li><code>colours</code> (default to global colours): colours for the chart</li>
</ul>
</div>
</tab>
<tab heading="Markup">
<pre><code data-language="html">&lt;canvas id=&quot;radar&quot; class=&quot;chart chart-radar&quot; data=&quot;data&quot;
labels=&quot;labels&quot;&gt;&lt;/canvas&gt; </code></pre>
</tab>
<tab heading="Javascript">
<pre><code data-language="javascript">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]
];
});
</code></pre>
</tab>
</tabset>
</div>
<div class="col-lg-6 col-sm-12" id="radar-chart" ng-controller="RadarCtrl">
<div class="panel panel-default">
<div class="panel-heading">Radar Chart</div>
<div class="panel-body">
<canvas id="area" class="chart chart-radar" data="data" labels="labels" click="onClick"></canvas>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-lg-6 col-sm-12" id="pie-chart" ng-controller="PieCtrl">
<div class="panel panel-default">
<div class="panel-heading">Pie Chart</div>
<div class="panel-body">
<canvas id="pie" class="chart chart-pie chart-xs" data="data" labels="labels"></canvas>
</div>
</div>
</div>
<div class="col-lg-6 col-sm-12 code">
<tabset>
<tab heading="Settings" class="settings">
<div class="settings">
<code>.chart-pie</code>
<ul>
<li><code>data</code>: series data</li>
<li><code>labels</code>: series labels</li>
<li><code>legend</code> (default: <code>false</code>): show legend below the chart</li>
<li><code>options</code> (default: <code>{}</code>): Chart.js options</li>
<li><code>colours</code> (default to global colours): colours for the chart</li>
</ul>
</div>
</tab>
<tab heading="Markup">
<pre><code data-language="html">&lt;canvas id=&quot;pie&quot; class=&quot;chart chart-pie&quot; data=&quot;data&quot;
labels=&quot;labels&quot;&gt;&lt;/canvas&gt; </code></pre>
</tab>
<tab heading="Javascript">
<pre><code data-language="javascript">angular.module("app", ["chart.js"]).controller("PieCtrl", function ($scope) {
$scope.labels = ["Download Sales", "In-Store Sales", "Mail-Order Sales"];
$scope.data = [300, 500, 100];
});
</code></pre>
</tab>
</tabset>
</div>
</div>
<div class="row">
<div class="col-lg-6 col-sm-12 code">
<tabset>
<tab heading="Settings" class="settings">
<div class="settings">
<code>.chart-polar-area</code>
<ul>
<li><code>data</code>: series data</li>
<li><code>labels</code>: series labels</li>
<li><code>legend</code> (default: <code>false</code>): show legend below the chart</li>
<li><code>options</code> (default: <code>{}</code>): Chart.js options</li>
<li><code>colours</code> (default to global colours): colours for the chart</li>
</ul>
</div>
</tab>
<tab heading="Markup">
<pre><code data-language="html">&lt;canvas id=&quot;polar-area&quot; class=&quot;chart chart-polar-area&quot; data=&quot;data&quot;
labels=&quot;labels&quot;&gt;&lt;/canvas&gt; </code></pre>
</tab>
<tab heading="Javascript">
<pre><code data-language="javascript">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];
});
</code></pre>
</tab>
</tabset>
</div>
<div class="col-lg-6 col-sm-12" id="polar area-chart" ng-controller="PolarAreaCtrl">
<div class="panel panel-default">
<div class="panel-heading">Polar Area Chart</div>
<div class="panel-body">
<canvas id="polar" class="chart chart-polar-area" data="data" labels="labels"></canvas>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-lg-6 col-sm-12" id="base-chart" ng-controller="BaseCtrl">
<div class="panel panel-default">
<div class="panel-heading">Dynamic Chart</div>
<div class="panel-body">
<canvas id="base" class="chart chart-base" chart-type="type" data="data" labels="labels" legend="true"></canvas>
</div>
</div>
<button type="button" class="btn btn-primary pull-right" ng-click="toggle()">Toggle</button>
</div>
<div class="col-lg-6 col-sm-12 code">
<tabset>
<tab heading="Settings" class="settings">
<div class="settings">
<code>.chart-base</code>
<ul>
<li><code>chart-type</code>: chart type e.g. Bar, PolarArea, etc. or other plugins</li>
<li>other options according to chart type</li>
</ul>
</div>
</tab>
<tab heading="Markup">
<pre><code data-language="html">&lt;canvas id=&quot;base&quot; class=&quot;chart-base&quot; chart-type=&quot;type&quot; data=&quot;data&quot;
labels=&quot;labels&quot; legend=&quot;true&quot;&gt;&lt;/canvas&gt; </code></pre>
</tab>
<tab heading="Javascript">
<pre><code data-language="javascript">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';
};
});
</code></pre>
</tab>
</tabset>
</div>
</div>
</section>
<section id="reactive">
<div class="page-header">
<h1>Reactive</h1>
<p>All charts are reactive and will update automatically when data changes.</p>
</div>
<div class="row" ng-controller="DataTablesCtrl">
<div class="col-lg-6 col-sm-12">
<div class="panel panel-default">
<div class="panel-heading">Chart Data</div>
<div class="panel-body">
<table class="table table-responsive table-condensed table-striped">
<tr>
<th ng-repeat="label in labels">{{label}}</th>
</tr>
<tr ng-repeat="dataSet in data">
<td ng-repeat="set in dataSet track by $index"><span style="text-align: right;">{{data[$parent.$index][$index]}}</span></td>
</tr>
</table>
<button type="button" class="btn btn-primary pull-right" ng-click="randomize()">Randomize</button>
</div>
</div>
</div>
<div class="col-lg-6 col-sm-12">
<div class="panel panel-default">
<div class="panel-heading">Reactive Chart</div>
<div class="panel-body">
<canvas id="tables" class="chart chart-line" data="data" labels="labels" colours="colours"></canvas>
</div>
</div>
</div>
</div>
</section>
</div>
<footer class="footer">
<div class="container">
<p>Designed and built by <a href="https://github.com/jtblin" target="_blank">Jerome Touffe-Blin</a></p>
<p>Code licensed under <a href="https://github.com/jtblin/angular-chart.js/blob/master/LICENSE">BSD License</a>.</p>
<p><a href="https://github.com/jtblin/angular-chart.js/issues?state=open">Issues</a></p>
<p><strong>Credits</strong>: <a href="http://www.chartjs.org/">Chart.js</a> and <a href="https://angularjs.org/">AngularJS</a></p>
</div>
</footer>
<script src="../bower_components/angular/angular.min.js"></script>
<script src="../bower_components/Chart.js/Chart.js"></script>
<script src="../bower_components/angular-bootstrap/ui-bootstrap-tpls.min.js"></script>
<script src="../bower_components/rainbow/js/rainbow.min.js"></script>
<script src="../bower_components/rainbow/js/language/generic.js"></script>
<script src="../bower_components/rainbow/js/language/html.js"></script>
<script src="../bower_components/rainbow/js/language/javascript.js"></script>
<script src="../angular-chart.js"></script>
<script src="smoothscroll.min.js"></script>
<script src="app.js"></script>
</body>
</html>

View file

@ -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}()

View file

@ -0,0 +1,39 @@
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>Stacked Bar chart</title>
<link rel="stylesheet" href="../dist/angular-chart.css">
<link href="bootstrap.css" rel="stylesheet">
</head>
<body ng-app="examples">
<br/>
<div class="container"></div>
<div id="container" class="container">
<div class="row" ng-controller="StackedBarCtrl">
<div class="col-lg-6 col-sm-12">
<div class="panel panel-default">
<div class="panel-heading">Stacked Bar Chart</div>
<div class="panel-body">
<canvas class="chart chart-stacked-bar" data="data" labels="labels"></canvas>
</div>
</div>
</div>
</div>
</div>
<script src="../bower_components/angular/angular.js"></script>
<script src="../bower_components/angular-bootstrap/ui-bootstrap-tpls.min.js"></script>
<script src="../bower_components/Chart.js/Chart.js"></script>
<script src="../bower_components/Chart.StackedBar.js/src/Chart.StackedBar.js"></script>
<script src="../angular-chart.js"></script>
<script src="app.js"></script>
<script>
// Create the 'chart-stacked-bar' class/attribute directive:
angular.module('examples')
.directive('chartStackedBar', function (ChartJsFactory) {
return new ChartJsFactory('StackedBar');
});
</script>
</body>
</html>

View file

@ -0,0 +1,32 @@
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>Stacked Bar chart</title>
<link rel="stylesheet" href="../dist/angular-chart.css">
<link href="bootstrap.css" rel="stylesheet">
</head>
<body ng-app="examples">
<br/>
<div class="container"></div>
<div id="container" class="container">
<div class="row" ng-controller="StackedBarCtrl">
<div class="col-lg-6 col-sm-12">
<div class="panel panel-default">
<div class="panel-heading">Stacked Bar Chart</div>
<div class="panel-body">
<canvas class="chart chart-base" chart-type="type" data="data" labels="labels"></canvas>
</div>
</div>
</div>
</div>
</div>
<script src="../bower_components/angular/angular.js"></script>
<script src="../bower_components/angular-bootstrap/ui-bootstrap-tpls.min.js"></script>
<script src="../bower_components/Chart.js/Chart.js"></script>
<script src="../bower_components/Chart.StackedBar.js/src/Chart.StackedBar.js"></script>
<script src="../angular-chart.js"></script>
<script src="app.js"></script>
</body>
</html>

View file

@ -0,0 +1,46 @@
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>Data tables</title>
<link rel="stylesheet" href="../dist/angular-chart.css">
<link href="bootstrap.css" rel="stylesheet">
</head>
<body ng-app="examples">
<div class="container"></div>
<div id="container" class="container">
<div class="row" ng-controller="DataTablesCtrl">
<div class="col-lg-6 col-sm-12">
<div class="panel panel-default">
<div class="panel-heading">Chart Data</div>
<div class="panel-body">
<table class="table table-responsive table-condensed">
<tr>
<th ng-repeat="label in labels">{{label}}</th>
</tr>
<tr ng-repeat="dataSet in data">
<td ng-repeat="set in dataSet track by $index"><span style="text-align: right;">{{data[$parent.$index][$index]}}</span></td>
</tr>
</table>
<input ng-click="randomize()" value="Randomize" type="button" class="pull-right"/>
</div>
</div>
</div>
<div class="col-lg-6 col-sm-12">
<div class="panel panel-default">
<div class="panel-heading">Reactive Chart</div>
<div class="panel-body">
<canvas id="tables" class="chart chart-line" data="data" labels="labels"></canvas>
</div>
</div>
</div>
</div>
</div>
<script src="../bower_components/angular/angular.min.js"></script>
<script src="../bower_components/angular-bootstrap/ui-bootstrap-tpls.min.js"></script>
<script src="../bower_components/Chart.js/Chart.min.js"></script>
<script src="../angular-chart.js"></script>
<script src="app.js"></script>
</body>
</html>

View file

@ -0,0 +1,30 @@
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>Realtime ticks</title>
<link rel="stylesheet" href="../dist/angular-chart.css">
<link href="bootstrap.css" rel="stylesheet">
</head>
<body ng-app="examples">
<div class="container"></div>
<div id="container" class="container">
<div class="row">
<div class="col-lg-8 col-sm-12" ng-controller="TicksCtrl">
<div class="panel panel-default">
<div class="panel-heading">Ticks Chart</div>
<div class="panel-body">
<canvas id="ticks" class="chart chart-line chart-xl" data="data" options="options" labels="labels"></canvas>
</div>
</div>
</div>
</div>
</div>
<script src="../bower_components/angular/angular.min.js"></script>
<script src="../bower_components/angular-bootstrap/ui-bootstrap-tpls.min.js"></script>
<script src="../bower_components/Chart.js/Chart.min.js"></script>
<script src="../angular-chart.js"></script>
<script src="app.js"></script>
</body>
</html>

View file

@ -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 -->', 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'));
})();

View file

@ -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 <jtblin@gmail.com>",
"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"
}
}

View file

@ -0,0 +1,36 @@
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>Pie update colours</title>
<link rel="stylesheet" href="../../dist/angular-chart.css">
<link href="../../examples/bootstrap.css" rel="stylesheet">
</head>
<body ng-app="pie" id="top">
<div class="container">
<section id="charts">
<div class="page-header">
<h1>Charts</h1>
</div>
<div class="row">
<div class="col-lg-4 col-sm-12" ng-controller="PieCtrl">
<div class="panel panel-default">
<div class="panel-heading">Pie Chart</div>
<div class="panel-body">
<canvas class="chart chart-pie" data="data" labels="labels" colours="colours"></canvas>
</div>
<p align="center"><a href="https://github.com/jtblin/angular-chart.js/issues/51">
https://github.com/jtblin/angular-chart.js/issues/51
</a></p>
</div>
</div>
</div>
</section>
</div>
<script src="../../bower_components/angular/angular.min.js"></script>
<script src="../../bower_components/Chart.js/Chart.js"></script>
<script src="../../angular-chart.js"></script>
<script src="51-pie-update-colours.js"></script>
</body>
</html>

View file

@ -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);
}]);
})();

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

View file

@ -0,0 +1,37 @@
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>Not enough colours</title>
<link rel="stylesheet" href="../../dist/angular-chart.css">
<link href="../../examples/bootstrap.css" rel="stylesheet">
</head>
<body ng-app="pie" id="top">
<div class="container">
<section id="charts">
<div class="page-header">
<h1>Charts</h1>
</div>
<div class="row">
<div class="col-lg-4 col-sm-12" ng-controller="PieCtrl">
<div class="panel panel-default">
<div class="panel-heading">Pie Chart</div>
<div class="panel-body">
<canvas class="chart chart-pie" data="data" labels="labels"
colours="colours" get-colour="getColour"></canvas>
</div>
<p align="center"><a href="https://github.com/jtblin/angular-chart.js/issues/51">
https://github.com/jtblin/angular-chart.js/issues/54
</a></p>
</div>
</div>
</div>
</section>
</div>
<script src="../../bower_components/angular/angular.min.js"></script>
<script src="../../bower_components/Chart.js/Chart.js"></script>
<script src="../../angular-chart.js"></script>
<script src="54-not-enough-colours.js"></script>
</body>
</html>

View file

@ -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];
}]);
})();

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

View file

@ -0,0 +1,36 @@
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>Hex colours</title>
<link rel="stylesheet" href="../../dist/angular-chart.css">
<link href="../../examples/bootstrap.css" rel="stylesheet">
</head>
<body ng-app="pie" id="top">
<div class="container">
<section id="charts">
<div class="page-header">
<h1>Charts</h1>
</div>
<div class="row">
<div class="col-lg-4 col-sm-12" ng-controller="PieCtrl">
<div class="panel panel-default">
<div class="panel-heading">Pie Chart</div>
<div class="panel-body">
<canvas class="chart chart-pie" data="data" labels="labels" colours="colours"></canvas>
</div>
<p align="center"><a href="https://github.com/jtblin/angular-chart.js/issues/51">
https://github.com/jtblin/angular-chart.js/issues/57
</a></p>
</div>
</div>
</div>
</section>
</div>
<script src="../../bower_components/angular/angular.min.js"></script>
<script src="../../bower_components/Chart.js/Chart.js"></script>
<script src="../../angular-chart.js"></script>
<script src="57-hex-colours.js"></script>
</body>
</html>

View file

@ -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];
}]);
})();

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

View file

@ -0,0 +1,78 @@
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>Charts</title>
<link rel="stylesheet" href="../../dist/angular-chart.css">
<link href="../../examples/bootstrap.css" rel="stylesheet">
</head>
<body ng-app="charts" id="top">
<div class="container">
<section id="charts">
<div class="page-header">
<h1>Charts</h1>
</div>
<div class="row">
<div class="col-lg-4 col-sm-12" id="line-chart" ng-controller="LineCtrl">
<div class="panel panel-default">
<div class="panel-heading">Line Chart</div>
<div class="panel-body">
<canvas id="line" class="chart chart-line" data="data" labels="labels" series="series"></canvas>
</div>
</div>
</div>
<div class="col-lg-4 col-sm-12" id="bar-chart" ng-controller="BarCtrl">
<div class="panel panel-default">
<div class="panel-heading">Bar Chart</div>
<div class="panel-body">
<canvas id="bar" class="chart chart-bar" data="data" labels="labels"
series="series" options="options"></canvas>
</div>
</div>
</div>
<div class="col-lg-4 col-sm-12" id="doughnut-chart" ng-controller="DoughnutCtrl">
<div class="panel panel-default">
<div class="panel-heading">Doughnut Chart</div>
<div class="panel-body">
<canvas id="doughnut" class="chart chart-doughnut" data="data" labels="labels" legend="false"></canvas>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-lg-4 col-sm-12" id="radar-chart" ng-controller="RadarCtrl">
<div class="panel panel-default">
<div class="panel-heading">Radar Chart</div>
<div class="panel-body">
<canvas id="area" class="chart chart-radar" data="data" labels="labels"></canvas>
</div>
</div>
</div>
<div class="col-lg-4 col-sm-12" id="pie-chart" ng-controller="PieCtrl">
<div class="panel panel-default">
<div class="panel-heading">Pie Chart</div>
<div class="panel-body">
<canvas id="pie" class="chart chart-pie" data="data" labels="labels"></canvas>
</div>
</div>
</div>
<div class="col-lg-4 col-sm-12" id="polar area-chart" ng-controller="PolarAreaCtrl">
<div class="panel panel-default">
<div class="panel-heading">Polar Area Chart</div>
<div class="panel-body">
<canvas id="polar" class="chart chart-polar-area" data="data" labels="labels"></canvas>
</div>
</div>
</div>
</div>
<div class="row">
</div>
</section>
</div>
<script src="../../bower_components/angular/angular.min.js"></script>
<script src="../../bower_components/Chart.js/Chart.js"></script>
<script src="../../angular-chart.js"></script>
<script src="charts.js"></script>
</body>
</html>

View file

@ -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]
];
});
})();

Binary file not shown.

After

Width:  |  Height:  |  Size: 89 KiB

View file

@ -0,0 +1,33 @@
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>Pie update colours</title>
<link rel="stylesheet" href="../../dist/angular-chart.css">
<link href="../../examples/bootstrap.css" rel="stylesheet">
</head>
<body ng-app="line" id="top">
<div class="container">
<section id="charts">
<div class="page-header">
<h1>Charts</h1>
</div>
<div class="row">
<div class="col-lg-4 col-sm-12" ng-controller="LineCtrl">
<div class="panel panel-default">
<div class="panel-heading">Line Chart</div>
<div class="panel-body">
<canvas class="chart chart-line" options="options" data="data" labels="labels" colours="colours"></canvas>
</div>
</div>
</div>
</div>
</section>
</div>
<script src="../../bower_components/angular/angular.min.js"></script>
<script src="../../bower_components/Chart.js/Chart.js"></script>
<script src="../../angular-chart.js"></script>
<script src="configure-line-chart.js"></script>
</body>
</html>

View file

@ -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);
}]);
})();

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

View file

@ -0,0 +1,33 @@
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>Pie update colours</title>
<link rel="stylesheet" href="../../dist/angular-chart.css">
<link href="../../examples/bootstrap.css" rel="stylesheet">
</head>
<body ng-app="pie" id="top">
<div class="container">
<section id="charts">
<div class="page-header">
<h1>Charts</h1>
</div>
<div class="row">
<div class="col-lg-4 col-sm-12" ng-controller="PieCtrl">
<div class="panel panel-default">
<div class="panel-heading">Pie Chart</div>
<div class="panel-body">
<canvas class="chart my-special-pie" data="data" labels="labels" colours="colours"></canvas>
</div>
</div>
</div>
</div>
</section>
</div>
<script src="../../bower_components/angular/angular.min.js"></script>
<script src="../../bower_components/Chart.js/Chart.js"></script>
<script src="../../angular-chart.js"></script>
<script src="custom-directive.js"></script>
</body>
</html>

View file

@ -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);
}]);
})();

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

View file

@ -0,0 +1,30 @@
<html>
<head>
<meta charset="utf-8">
<title>Mocha Tests</title>
<link rel="stylesheet" href="../node_modules/mocha/mocha.css" />
</head>
<body ng-app="chart.js">
<div id="mocha"></div>
<script src="../bower_components/angular/angular.min.js"></script>
<script src="../bower_components/Chart.js/Chart.js"></script>
<script src="../angular-chart.js"></script>
<script src="../node_modules/mocha/mocha.js"></script>
<script src="../node_modules/chai/chai.js"></script>
<script src="../node_modules/chai-string/chai-string.js"></script>
<script src="../node_modules/sinon/pkg/sinon.js"></script>
<script src="../node_modules/sinon-chai/lib/sinon-chai.js"></script>
<script>mocha.setup('bdd')</script>
<script src="../bower_components/angular-mocks/angular-mocks.js"></script>
<script src="../test/test.unit.js"></script>
<script>
var expect = chai.expect;
mocha.checkLeaks();
mocha.globals(['angular', 'Chart', 'angular', 'chai', 'expect', 'sinon', 'sinonChai']);
if (window.mochaPhantomJS)
mochaPhantomJS.run();
else
mocha.run();
</script>
</body>
</html>

View file

@ -0,0 +1,4 @@
--slow 20
--growl
--reporter spec
--require test/support/setup

View file

@ -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;
})();

View file

@ -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();
});
});
});
});
});

View file

@ -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 = '<div style="width: 250px; height:120px">' +
'<canvas class="chart chart-line" data="data" labels="labels"></canvas></div>';
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('<div class="chart-container"><canvas ');
});
describe('chart types', function () {
['Line', 'Bar', 'Radar', 'Pie', 'Doughnut', 'PolarArea'].forEach(function (type) {
it('creates a ' + type + ' chart using the directive', function () {
var markup = '<div style="width: 250px; height:120px"><canvas class="chart chart-' +
(type === 'PolarArea' ? 'polar-area' : type.toLowerCase()) +
'" data="data" labels="labels"></canvas></div>';
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 = '<div style="width: 250px; height:120px">' +
'<canvas class="chart chart-base" data="data" labels="labels" chart-type="type"></canvas></div>';
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 = '<div style="width: 250px; height:120px">' +
'<canvas class="chart chart-line" data="data" labels="labels" legend="true"></canvas></div>';
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('<chart-legend>');
});
});
describe('lifecycle', function () {
it('watches the attributes of the chart', function () {
var markup = '<div style="width: 250px; height:120px">' +
'<canvas class="chart chart-line" data="data" labels="labels" chart-type="type"></canvas></div>';
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 = '<div style="width: 250px; height:120px">' +
'<canvas class="chart chart-line" data="data" labels="labels" series="series"></canvas></div>';
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 = '<div style="width: 250px; height:120px">' +
'<canvas class="chart chart-line" data="data" labels="labels" series="series"></canvas></div>';
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 = '<div style="width: 250px; height:120px">' +
'<canvas class="chart chart-line" data="data" labels="labels" series="series"></canvas></div>';
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 = '<div style="width: 250px; height:120px">' +
'<canvas class="chart chart-line" data="data" labels="labels" series="series" ' +
'colours="colours" options="options"></canvas></div>';
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 = '<div style="width: 250px; height:120px">' +
'<canvas class="chart chart-line" data="data" labels="labels" series="series" ' +
'colours="colours" options="options"></canvas></div>';
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);
});
});
});
});

View file

@ -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));
}
};
}]);

View file

@ -3,7 +3,7 @@
<md-progress-circular md-mode="indeterminate"></md-progress-circular>
</div>
<md-content layout-padding>
<md-card class="gray-font">
<md-card class="gray-font fadeOutUp" ng-if="isEnterd">
<div layout="row">
<div class="spacer"></div>
<div>
@ -15,12 +15,59 @@
<div class="spacer"></div>
<div>
<h1>Welcome To SE-Hub</h1>
<p>
This Is your Home Page
</p>
<P>Software Engineering Course Made Easy</P>
v1.0
</div>
<div class="spacer"></div>
</div>
</md-card>
</md-content>
<md-content layout-padding>
<md-card>
<div class = "feed">
<md-grid-list
md-cols-sm="1" md-cols-md="2" md-cols-gt-md="6"
md-row-height-gt-md="1:1" md-row-height="2:2"
md-gutter="12px" md-gutter-gt-sm="8px" >
<md-grid-tile class="aliceblue"
md-rowspan="2" md-colspan="3" md-colspan-sm="1">
<md-grid-tile-header>
<h3>Messages</h3>
</md-grid-tile-header>
In The Future Will Enter Wanted MESSAGES Text Here
</md-grid-tile>
<md-grid-tile class="gray"
md-rowspan="2" md-colspan="3" md-colspan-sm="1">
<md-grid-tile-header>
<h3>Tasks</h3>
</md-grid-tile-header>
<!-- In The Future Will Enter Wanted TASKS Text Here -->
<div class = "tasksContent" style:"text-align= left;">
For Task 3 Press: <a href="http://localhost:8080/home#/tasks">Task #3</a>
<br>=====================</br>
For Task 4 Press: <a href="http://localhost:8080/home#/home">Task #4</a>
</div>
</md-grid-tile>
</md-grid-list>
</div>
</md-card>
</md-content>
<!-- <div layout="row" layout-fill style="padding-right: 320px;">
<md-whiteframe class="md-whiteframe-z4" layout layout-align="center center">
<span>.md-whiteframe-z4</span>
</md-whiteframe>
<md-whiteframe class="md-whiteframe-z5" layout layout-align="center center">
<span>.md-whiteframe-z5</span>
</md-whiteframe>
</div> -->
</div>

View file

@ -6,6 +6,10 @@
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css">
<link rel="stylesheet" href="templates/css/theme.css">
<!--charts css-->
<link rel="stylesheet" href="templates/js/libs/angular-chart.js-0.7.2/dist/angular-chart.css"/>
<meta name="viewport" content="initial-scale=1, maximum-scale=1" />
</head>
@ -79,8 +83,17 @@
<!-- Angular App -->
<script src="templates/js/app.js"></script>
<!--Angular Libs (Third Party)-->
<!--charts-->
<!--docs: http://jtblin.github.io/angular-chart.js/-->
<script src="templates/js/libs/angular-chart.js-0.7.2/dist/chart.js"></script>
<script src="templates/js/libs/angular-chart.js-0.7.2/dist/angular-chart.js"></script>
<!-- Services -->
<script src="templates/js/services/apiService.js"></script>
<script src="templates/js/services/dataService.js"></script>
<!-- Controllers -->
<script src="templates/js/controllers/mainController.js"></script>

View file

@ -5,6 +5,112 @@
<md-content layout-padding>
<md-card layout-padding>
<h1><i class="fa fa-cogs"></i> {{title}}</h1>
<div layout="row">
<div>
<md-card layout-padding>
<div id="profile" layout="column">
<!-- User Profile Box -->
<div class="user-box" layout="row">
<div>
<img ng-src="{{user.avatar_url}}" alt="" style="width:20%">
</div>
<div flex="70%">
<md-button class="md-raised" ng-click="changeProfileMode()">
<i ng-class="profileModeIcon"></i> {{profileMode}}
</md-button>
</div>
</div>
</div>
<!-- Start View Profile -->
<div layout="column" ng-if="!isEditMode">
<div>
<h2>{{user.name}}</h2>
</div>
<div>
Email: {{user.email}}
</div>
<div>
I Am a: {{(user.isLecturer) ? "Lecturer" : "Student"}}
</div>
</div>
<!-- End View Profile -->
<!-- Starting Edit Mode Div -->
<div layout="column" ng-if="isEditMode">
<div>
<md-input-container>
<label>Full Name</label>
<input ng-model="user.name">
</md-input-container>
</div>
<div>
<md-input-container>
<label>Email</label>
<input ng-model="user.email">
</md-input-container>
</div>
<div>
<md-switch ng-model="user.isLecturer" aria-label="Switch 1">
I Am a: {{(user.isLecturer) ? "Lecturer" : "Student"}}
</md-switch>
</div>
</div>
<!-- End Edit Div -->
<canvas id="bar" class="chart chart-bar" data="data"
labels="labels" series="series"></canvas>
</md-card>
</div>
<!-- Campuses & Classes Div -->
<div flex>
<md-card layout-padding>
<h3><i class="fa fa-graduation-cap"></i> My Classes</h3>
<div class="settingList">
<div class="settingListRoot">
<div ng-repeat="course in courses" class="settingListItem" layout="row">
<div>
<img alt="{{ person.name }}" ng-src="{{ course.campus_avatar }}" class="md-avatar" />
</div>
<div class="port_spacer">
{{ course.courseName }} - <strong>IN</strong> {{course.campusName}}
</div>
<div class="spacer"></div>
<div>
<md-button class="">
X
</md-button>
</div>
<md-divider ng-if="!$last"></md-divider>
</div>
</div>
</div>
<h3><i class="fa fa-university"></i> My Campuses</h3>
<div class="settingList">
<div class="settingListRoot">
<div ng-repeat="campus in campuses" class="settingListItem" layout="row">
<div>
<img alt="{{ person.name }}" ng-src="{{ campus.avatar_url }}" class="md-avatar" />
</div>
<div class="port_spacer">
{{ campus.title }} -
</div>
<div class="spacer"></div>
<div>
<md-button class="">
X
</md-button>
</div>
<md-divider ng-if="!$last"></md-divider>
</div>
</div>
</div>
</md-card>
</div>
<!-- End Campuses & Classes Div -->
</div>
</md-card>
</md-content>
</div>