Refactored structure and added basic website / documentation

This commit is contained in:
Gion Kunz 2014-02-25 22:24:50 +01:00
commit 11a66a3d72
25 changed files with 2825 additions and 0 deletions

3
.bowerrc Normal file
View File

@ -0,0 +1,3 @@
{
"directory": "app/bower_components"
}

21
.editorconfig Normal file
View File

@ -0,0 +1,21 @@
# EditorConfig helps developers define and maintain consistent
# coding styles between different editors and IDEs
# editorconfig.org
root = true
[*]
# Change these settings to your own preference
indent_style = space
indent_size = 2
# We recommend you to keep these unchanged
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
[*.md]
trim_trailing_whitespace = false

1
.gitattributes vendored Normal file
View File

@ -0,0 +1 @@
* text=auto

5
.gitignore vendored Normal file
View File

@ -0,0 +1,5 @@
node_modules
dist
.tmp
.sass-cache
app/bower_components

28
.jshintrc Normal file
View File

@ -0,0 +1,28 @@
{
"node": true,
"browser": true,
"esnext": true,
"bitwise": true,
"camelcase": false,
"curly": true,
"eqeqeq": true,
"immed": true,
"indent": 2,
"latedef": true,
"newcap": false,
"noarg": true,
"quotmark": "single",
"regexp": true,
"undef": true,
"unused": true,
"strict": true,
"trailing": true,
"smarttabs": true,
"globals": {
"angular": false,
"jQuery": false,
"$": false,
"Snap": false,
"Foundation": false
}
}

7
.travis.yml Normal file
View File

@ -0,0 +1,7 @@
language: node_js
node_js:
- '0.8'
- '0.10'
before_script:
- 'npm install -g bower grunt-cli'
- 'bower install'

377
Gruntfile.js Normal file
View File

@ -0,0 +1,377 @@
'use strict';
// # Globbing
// for performance reasons we're only matching one level down:
// 'test/spec/{,*/}*.js'
// use this if you want to recursively match all subfolders:
// 'test/spec/**/*.js'
module.exports = function (grunt) {
// Load grunt tasks automatically
require('load-grunt-tasks')(grunt);
// Time how long tasks take. Can help when optimizing build times
require('time-grunt')(grunt);
// Define the configuration for all the tasks
grunt.initConfig({
// Project settings
settings: {
// configurable paths
app: require('./bower.json').appPath || 'app',
dist: 'dist'
},
// Watches files for changes and runs tasks based on the changed files
watch: {
js: {
files: ['<%= settings.app %>/scripts/{,*/}*.js'],
tasks: ['newer:jshint:all'],
options: {
livereload: true
}
},
jsTest: {
files: ['test/spec/{,*/}*.js'],
tasks: ['newer:jshint:test', 'karma']
},
compass: {
files: ['<%= settings.app %>/styles/{,*/}*.{scss,sass}'],
tasks: ['compass:server']
},
gruntfile: {
files: ['Gruntfile.js']
},
livereload: {
options: {
livereload: '<%= connect.options.livereload %>'
},
files: [
'<%= settings.app %>/{,*/}*.html',
'.tmp/styles/{,*/}*.css',
'<%= settings.app %>/images/{,*/}*.{png,jpg,jpeg,gif,webp,svg}'
]
}
},
// The actual grunt server settings
connect: {
options: {
port: 9000,
// Change this to '0.0.0.0' to access the server from outside.
hostname: '0.0.0.0',
livereload: 35729
},
livereload: {
options: {
open: true,
base: [
'.tmp',
'<%= settings.app %>'
]
}
},
test: {
options: {
port: 9001,
base: [
'.tmp',
'test',
'<%= settings.app %>'
]
}
},
dist: {
options: {
base: '<%= settings.dist %>'
}
}
},
// Make sure code styles are up to par and there are no obvious mistakes
jshint: {
options: {
jshintrc: '.jshintrc',
reporter: require('jshint-stylish')
},
all: [
'Gruntfile.js',
'<%= settings.app %>/scripts/{,*/}*.js'
],
test: {
options: {
jshintrc: 'test/.jshintrc'
},
src: ['test/spec/{,*/}*.js']
}
},
// Empties folders to start fresh
clean: {
dist: {
files: [{
dot: true,
src: [
'.tmp',
'<%= settings.dist %>/*',
'!<%= settings.dist %>/.git*'
]
}]
},
server: '.tmp'
},
// Add vendor prefixed styles
/* autoprefixer: {
options: {
browsers: ['last 1 version']
},
dist: {
files: [{
expand: true,
cwd: '.tmp/styles/',
src: '{,*//*}*.css',
dest: '.tmp/styles/'
}]
}
},*/
// Automatically inject Bower components into the app
'bower-install': {
app: {
html: '<%= settings.app %>/index.html',
ignorePath: '<%= settings.app %>/',
exclude: ['bower_components/foundation/css/foundation.css']
}
},
// Compiles Sass to CSS and generates necessary files if requested
compass: {
options: {
sassDir: '<%= settings.app %>/styles',
cssDir: '.tmp/styles',
generatedImagesDir: '.tmp/images/generated',
imagesDir: '<%= settings.app %>/images',
javascriptsDir: '<%= settings.app %>/scripts',
fontsDir: '<%= settings.app %>/styles/fonts',
importPath: '<%= settings.app %>/bower_components',
httpImagesPath: '/images',
httpGeneratedImagesPath: '/images/generated',
httpFontsPath: '/styles/fonts',
relativeAssets: false,
assetCacheBuster: false,
raw: 'Sass::Script::Number.precision = 10\n'
},
dist: {
options: {
generatedImagesDir: '<%= settings.dist %>/images/generated'
}
},
server: {
options: {
debugInfo: true
}
}
},
// Renames files for browser caching purposes
rev: {
dist: {
files: {
src: [
'<%= settings.dist %>/scripts/{,*/}*.js',
'<%= settings.dist %>/styles/{,*/}*.css',
'<%= settings.dist %>/images/{,*/}*.{png,jpg,jpeg,gif,webp,svg}',
'<%= settings.dist %>/styles/fonts/*'
]
}
}
},
// Reads HTML for usemin blocks to enable smart builds that automatically
// concat, minify and revision files. Creates configurations in memory so
// additional tasks can operate on them
useminPrepare: {
html: '<%= settings.app %>/index.html',
options: {
dest: '<%= settings.dist %>'
}
},
// Performs rewrites based on rev and the useminPrepare configuration
usemin: {
html: ['<%= settings.dist %>/{,*/}*.html'],
css: ['<%= settings.dist %>/styles/{,*/}*.css'],
options: {
assetsDirs: ['<%= settings.dist %>']
}
},
// The following *-min tasks produce minified files in the dist folder
imagemin: {
dist: {
files: [{
expand: true,
cwd: '<%= settings.app %>/images',
src: '{,*/}*.{png,jpg,jpeg,gif}',
dest: '<%= settings.dist %>/images'
}]
}
},
svgmin: {
dist: {
files: [{
expand: true,
cwd: '<%= settings.app %>/images',
src: '{,*/}*.svg',
dest: '<%= settings.dist %>/images'
}]
}
},
htmlmin: {
dist: {
options: {
collapseWhitespace: true,
collapseBooleanAttributes: true,
removeCommentsFromCDATA: true,
removeOptionalTags: true
},
files: [{
expand: true,
cwd: '<%= settings.dist %>',
src: ['*.html'],
dest: '<%= settings.dist %>'
}]
}
},
// Allow the use of non-minsafe AngularJS files. Automatically makes it
// minsafe compatible so Uglify does not destroy the ng references
ngmin: {
dist: {
files: [{
expand: true,
cwd: '.tmp/concat/scripts',
src: '*.js',
dest: '.tmp/concat/scripts'
}]
}
},
// Replace Google CDN references
cdnify: {
dist: {
html: ['<%= settings.dist %>/*.html']
}
},
// Copies remaining files to places other tasks can use
copy: {
dist: {
files: [{
expand: true,
dot: true,
cwd: '<%= settings.app %>',
dest: '<%= settings.dist %>',
src: [
'*.{ico,png,txt}',
'.htaccess',
'*.html',
'views/{,*/}*.html',
'bower_components/**/*',
'images/{,*/}*.{webp}',
'fonts/*'
]
}, {
expand: true,
cwd: '.tmp/images',
dest: '<%= settings.dist %>/images',
src: ['generated/*']
}]
},
styles: {
expand: true,
cwd: '<%= settings.app %>/styles',
dest: '.tmp/styles/',
src: '{,*/}*.css'
}
},
// Run some tasks in parallel to speed up the build process
concurrent: {
server: [
'compass:server'
],
test: [
'compass'
],
dist: [
'compass:dist',
'imagemin',
'svgmin'
]
},
// Test settings
karma: {
unit: {
configFile: 'karma.conf.js',
singleRun: true
}
}
});
grunt.registerTask('serve', function (target) {
if (target === 'dist') {
return grunt.task.run(['build', 'connect:dist:keepalive']);
}
grunt.task.run([
'clean:server',
'bower-install',
'concurrent:server',
'connect:livereload',
'watch'
]);
});
grunt.registerTask('server', function () {
grunt.log.warn('The `server` task has been deprecated. Use `grunt serve` to start a server.');
grunt.task.run(['serve']);
});
grunt.registerTask('test', [
'clean:server',
'concurrent:test',
'connect:test',
'karma'
]);
grunt.registerTask('build', [
'clean:dist',
'bower-install',
'useminPrepare',
'concurrent:dist',
'concat',
'ngmin',
'copy:dist',
'cdnify',
'cssmin',
'uglify',
'rev',
'usemin',
'htmlmin'
]);
grunt.registerTask('default', [
'newer:jshint',
'test',
'build'
]);
};

1
app/.buildignore Normal file
View File

@ -0,0 +1 @@
*.coffee

157
app/404.html Normal file
View File

@ -0,0 +1,157 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Page Not Found :(</title>
<style>
::-moz-selection {
background: #b3d4fc;
text-shadow: none;
}
::selection {
background: #b3d4fc;
text-shadow: none;
}
html {
padding: 30px 10px;
font-size: 20px;
line-height: 1.4;
color: #737373;
background: #f0f0f0;
-webkit-text-size-adjust: 100%;
-ms-text-size-adjust: 100%;
}
html,
input {
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
}
body {
max-width: 500px;
_width: 500px;
padding: 30px 20px 50px;
border: 1px solid #b3b3b3;
border-radius: 4px;
margin: 0 auto;
box-shadow: 0 1px 10px #a7a7a7, inset 0 1px 0 #fff;
background: #fcfcfc;
}
h1 {
margin: 0 10px;
font-size: 50px;
text-align: center;
}
h1 span {
color: #bbb;
}
h3 {
margin: 1.5em 0 0.5em;
}
p {
margin: 1em 0;
}
ul {
padding: 0 0 0 40px;
margin: 1em 0;
}
.container {
max-width: 380px;
_width: 380px;
margin: 0 auto;
}
/* google search */
#goog-fixurl ul {
list-style: none;
padding: 0;
margin: 0;
}
#goog-fixurl form {
margin: 0;
}
#goog-wm-qt,
#goog-wm-sb {
border: 1px solid #bbb;
font-size: 16px;
line-height: normal;
vertical-align: top;
color: #444;
border-radius: 2px;
}
#goog-wm-qt {
width: 220px;
height: 20px;
padding: 5px;
margin: 5px 10px 0 0;
box-shadow: inset 0 1px 1px #ccc;
}
#goog-wm-sb {
display: inline-block;
height: 32px;
padding: 0 10px;
margin: 5px 0 0;
white-space: nowrap;
cursor: pointer;
background-color: #f5f5f5;
background-image: -webkit-linear-gradient(rgba(255,255,255,0), #f1f1f1);
background-image: -moz-linear-gradient(rgba(255,255,255,0), #f1f1f1);
background-image: -ms-linear-gradient(rgba(255,255,255,0), #f1f1f1);
background-image: -o-linear-gradient(rgba(255,255,255,0), #f1f1f1);
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
*overflow: visible;
*display: inline;
*zoom: 1;
}
#goog-wm-sb:hover,
#goog-wm-sb:focus {
border-color: #aaa;
box-shadow: 0 1px 1px rgba(0, 0, 0, 0.1);
background-color: #f8f8f8;
}
#goog-wm-qt:hover,
#goog-wm-qt:focus {
border-color: #105cb6;
outline: 0;
color: #222;
}
input::-moz-focus-inner {
padding: 0;
border: 0;
}
</style>
</head>
<body>
<div class="container">
<h1>Not found <span>:(</span></h1>
<p>Sorry, but the page you were trying to view does not exist.</p>
<p>It looks like this was the result of either:</p>
<ul>
<li>a mistyped address</li>
<li>an out-of-date link</li>
</ul>
<script>
var GOOG_FIXURL_LANG = (navigator.language || '').slice(0,2),GOOG_FIXURL_SITE = location.host;
</script>
<script src="//linkhelp.clients.google.com/tbproxy/lh/wm/fixurl.js"></script>
</div>
</body>
</html>

BIN
app/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

127
app/images/chartist-guy.svg Executable file
View File

@ -0,0 +1,127 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 15.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="guy" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve">
<g>
<g id="shadows" opacity="0.1">
<path d="M55.997,405.221c0,3.051,41.857,5.499,93.509,5.499c51.643,0,93.494-2.448,93.494-5.499
c0-3.037-41.851-5.515-93.494-5.515C97.854,399.706,55.997,402.184,55.997,405.221z"/>
<path d="M265.91,405.218c0,1.604,25.276,2.895,56.469,2.895c31.186,0,56.458-1.291,56.458-2.895c0-1.6-25.272-2.905-56.458-2.905
C291.187,402.313,265.91,403.618,265.91,405.218z"/>
<path d="M390.533,405.218c0,1.604,5.264,2.895,11.76,2.895c6.494,0,11.756-1.291,11.756-2.895c0-1.6-5.262-2.905-11.756-2.905
C395.797,402.313,390.533,403.618,390.533,405.218z"/>
</g>
<g id="canvas">
<g>
<g>
<path fill="#844E29" d="M99.383,397.553c-1.92,5.045-5.994,8.171-9.103,6.984l0,0c-3.105-1.187-4.066-6.231-2.144-11.271
l27.838-73.037c1.922-5.04,5.999-8.169,9.103-6.986l0,0c3.108,1.187,4.067,6.237,2.147,11.276L99.383,397.553z"/>
</g>
<g>
<path fill="#844E29" d="M196.125,397.553c1.917,5.045,5.997,8.171,9.101,6.984l0,0c3.106-1.187,4.07-6.231,2.147-11.271
l-27.838-73.037c-1.922-5.04-5.999-8.169-9.108-6.986l0,0c-3.104,1.187-4.063,6.237-2.143,11.276L196.125,397.553z"/>
</g>
<g>
<rect x="50.055" y="189.846" fill="#EADBC4" width="195.399" height="136.78"/>
<path fill="#8C5733" d="M249.363,330.538H46.146v-144.6h203.217V330.538z M53.963,322.721h187.584V193.754H53.963V322.721z"/>
</g>
</g>
</g>
<g>
<path fill="#231F20" d="M365.406,347.481l0.982,53.303h-8.344l-4.399-40.897c0,0-7.466,1.87-26.572,1.87
c-19.109,0-28.33-1.335-28.33-1.335l-11.923,40.59l-8.343-0.133l10.16-53.469l5.705-2.122l68.967-0.797L365.406,347.481z"/>
</g>
<path fill="#231F20" d="M357.917,400.262c0,0-1.015,2.634-0.089,4.063h6.008v-0.631c0,0,0.641,0.631,3.556,0.664
c2.908,0.023,9.429,0.114,11.37-1.115c0,0,1.387-1.072-1.2-1.129c0,0-5.678,0.844-8.738-0.105c0,0-2.31-0.807-2.357-1.708
C366.466,400.3,361.666,401.316,357.917,400.262z"/>
<path fill="#231F20" d="M287.119,400.262c0,0,1.017,2.634,0.091,4.063h-6.014v-0.631c0,0-0.641,0.631-3.55,0.664
c-2.909,0.023-9.425,0.114-11.371-1.115c0,0-1.376-1.072,1.201-1.129c0,0,5.681,0.844,8.746-0.105c0,0,2.298-0.807,2.354-1.708
C278.576,400.3,283.386,401.316,287.119,400.262z"/>
<g>
<path fill="#231F20" d="M367.541,263.194l9.831,8.097l-11.966,77.11c0,0-18.571,3.236-38.553,3.236
c-19.991,0-38.216-3.312-38.216-3.312l-13.279-76.988l11.974-7.143l34.154,13.281l42.312-12.768L367.541,263.194z"/>
</g>
<path fill="#231F20" d="M374.023,270.917c0,0,34.299,3.662,49.058,46.511l-6.689,3.905c0,0-17.488-37.537-42.646-32.047
L374.023,270.917z"/>
<g>
<g>
<path fill-rule="evenodd" clip-rule="evenodd" fill="#414042" d="M455.557,147.756c-0.801,5.217-5.587,8.985-10.896,8.468
l-6.288-0.81c7.505-87.959,7.051-87.907-2.574-0.154l-17.126-1.765c7.509-87.96,7.059-87.907-2.57-0.154l-7.24-0.805
c-5.491-0.534-9.554-5.47-9.018-10.963c6.129-74.353,5.82-73.637-2.561,0.761l-0.138,1.374
c-0.566,5.793,3.716,10.997,9.506,11.562l16.726,1.631l-0.83,8.526l6.411,0.626l0.83-8.527l16.727,1.631
c5.79,0.564,10.997-3.714,11.561-9.506l0.101-1.376C464.496,72.451,463.787,74.093,455.557,147.756z"/>
</g>
<path fill-rule="evenodd" clip-rule="evenodd" fill="#844E29" d="M429.494,160.577l-6.416-0.627l-2.663,6.799L397.308,403.73
c0,0.01,0,0.016,0,0.023c-0.111,1.092,2.126,2.203,4.991,2.484c2.867,0.278,5.277-0.38,5.383-1.472c0.004-0.01,0-0.016,0-0.023
l23.113-237.035L429.494,160.577z"/>
</g>
<path fill="#D39C76" d="M422.704,316.815l1.037,1.704c0,0,2.687,1.159,3.317,2.059c0.841,1.234,1.401,2.037,1.974,3.851
c0.559,1.813-6.853,6.974-8.845,6.324c-1.975-0.652-2.015-3.35-2.015-3.35s-0.445,2.204-0.797,3.158
c-0.358,0.982-2.236,1.507-2.921-0.169c-0.728-1.647-0.025-3.652,0.306-5.063c0.323-1.405,1.542-3.278,1.542-3.278l0.266-2.204
L422.704,316.815z"/>
<g>
<path fill="#D39C76" d="M223.65,272.968l-2.672-1.159c0,0-2.254,0.328-3.31-0.209c-1.41-0.712-3.899-2.577-5.352-3.995
c-1.447-1.416-2.411-3.148-2.687-4.152c-0.464-1.767,2.708-6.679,4.91-7.092c2.188-0.384,8.052,4.366,8.052,4.366
s-0.71-2.315-0.864-3.397c-0.146-1.088,1.344-2.521,2.846-1.325c1.497,1.221,1.849,3.445,2.256,4.937
c0.401,1.505,0.205,3.858,0.205,3.858l0.854,2.196L223.65,272.968z"/>
<path fill="#231F20" d="M275.358,271.338c0,0-23.175,16.36-47.895-5.434l-4.644,6.707c0,0,20.482,22.947,60.228,13.9
L275.358,271.338z"/>
</g>
<g>
<path fill="#D70206" d="M364.686,283.888c-1.819-3.882-2.165-9.354-1.941-14.52c-5.225,3.139-13.096,7.187-22.706,10.078
c-5.585,8.248-13.825,13.896-13.825,13.896l-2.406,53.768l6.616,9.878c0,0,11.415-4.414,21.338-6.726
c9.915-2.306,23.438-4.831,23.438-4.831s-3.114-11.776-3-24.361c0.062-7.8,3-23.522,3-23.522S369.188,293.556,364.686,283.888z"/>
</g>
<g>
<path fill="#D70206" d="M324.613,292.854l0.471-0.328c0.023-0.004,0.431-0.299,1.129-0.82c-2.197-1.732-5.705-4.76-8.937-8.645
c-8.197,0.158-16.934-1.004-25.899-4.224c-0.318,1.837-0.773,3.569-1.466,5.051c-4.519,9.668-10.528,13.659-10.528,13.659
s2.938,15.723,3.01,23.522c0.104,12.585-3.01,24.361-3.01,24.361s13.522,2.525,23.445,4.831c9.926,2.312,21.35,6.726,21.35,6.726
l2.23-3.332l-4.224-6.309L324.613,292.854z"/>
</g>
<path fill="#231F20" d="M337.912,337.627c-0.133,2.848-2.553,5.051-5.396,4.912c-2.855-0.132-5.049-2.549-4.916-5.396
c0.132-2.852,2.549-5.049,5.4-4.916C335.844,332.359,338.051,334.775,337.912,337.627z"/>
<path fill="#231F20" d="M339.284,308.496c-0.132,2.852-2.559,5.051-5.4,4.916c-2.854-0.132-5.051-2.547-4.912-5.4
c0.133-2.848,2.543-5.049,5.395-4.912C337.214,303.232,339.417,305.648,339.284,308.496z"/>
<path fill="#231F20" d="M338.601,323.063c-0.133,2.848-2.558,5.049-5.401,4.916c-2.852-0.132-5.051-2.553-4.916-5.4
c0.133-2.848,2.547-5.051,5.4-4.918C336.525,317.795,338.732,320.215,338.601,323.063z"/>
<g id="head">
<g>
<path fill="#75543B" d="M316.574,211.633c0,0,8.435,31.83-21.068,31.83l26.222,9.832l21.53-27.049L316.574,211.633z"/>
<path fill="#B24949" d="M334.372,239.252c0,0-22.004-9.845-31.367,7.018l19.658,5.608L334.372,239.252z"/>
</g>
<g>
<path fill="#D39C76" d="M295.506,242.203c11.187,6.773,26.598,4.005,32.273,0.256c8.082-5.339,8.306-19.212,5.661-20.375
c-0.915-0.407-11.94,8.321-31.836,0.466l2.335-21.066l-31.826-1.407l22.467-66.457c0,0,37.447-18.722,74.884,0v67.299
c1.993-0.861,4.044-1.032,5.877-0.266c4.642,1.956,6.093,9.043,3.245,15.835c-2.003,4.744-5.563,8.021-9.122,8.941v39.227
c0,0-38.372,30.437-80.969,13.105c0,0-13.222-4.966-12.34-21.7C276.155,256.062,275.393,245.005,295.506,242.203z"/>
</g>
<path fill="#BF8862" d="M289.241,267.313c4.742,0,9.64-3.363,9.933-3.577l-0.529-0.765c-0.105,0.061-9.665,6.634-14.415,1.253
c-2.742-3.104-2.925-5.976-2.606-7.854c0.394-2.244,1.757-4.254,3.542-5.244c1.931-1.078,5.049-1.715,7.636-0.731
c1.627,0.612,2.729,1.752,3.328,3.407c0.929,2.61-0.285,4.501-1.084,5.396c-1.391,1.566-3.56,2.435-5.13,2.061
c-1.681-0.39-3.176-1.904-3.488-3.526c-0.17-0.822-0.075-2.017,1.306-2.996c0.844-0.587,1.613-0.769,2.287-0.587
c1.149,0.36,1.713,1.764,1.723,1.784l0.864-0.347c-0.023-0.081-0.731-1.847-2.315-2.321c-0.959-0.295-2.01-0.052-3.108,0.708
c-1.387,0.973-1.976,2.373-1.671,3.939c0.379,1.993,2.146,3.763,4.193,4.247c1.905,0.432,4.448-0.535,6.038-2.345
c1.619-1.808,2.07-4.059,1.268-6.341c-0.675-1.88-2.014-3.261-3.878-3.953c-2.848-1.087-6.293-0.399-8.425,0.787
c-2.044,1.116-3.573,3.394-4,5.905c-0.366,2.078-0.166,5.263,2.813,8.632C285.136,266.673,287.166,267.313,289.241,267.313z"/>
<g>
<path fill="#634128" d="M322.743,167.376c0,2.438,3.327,4.407,7.373,4.407c4.08,0,7.384-1.97,7.384-4.407
s-3.304-4.409-7.384-4.409C326.07,162.967,322.743,164.938,322.743,167.376z"/>
<path fill="#634128" d="M300.015,167.376c0,2.438,3.228,4.407,7.232,4.407c4.003,0,7.253-1.97,7.253-4.407
s-3.25-4.409-7.253-4.409C303.242,162.967,300.015,164.938,300.015,167.376z"/>
</g>
<g>
<path fill="#231F20" d="M370.385,133.598c-0.033-0.007-0.066-0.014-0.108-0.021c-0.062-9.229-0.081-21.111,0.133-28.556
c0.66-22.939,7.451-32.7,2.102-33.735c-5.353-1.034-17.218-3.519-41.704-3.519c-21.931,0-38.58,3.105-43.791,4.138
c-5.212,1.037,3.649,19.666,5.211,33.116c0.736,6.313,0.783,15.91,0.621,24.336c-17.873,3.106-28.286,10.71-30.616,17.658h154.12
C416.352,147.015,403.171,140.195,370.385,133.598z"/>
</g>
<path fill="#353433" d="M311.12,223.019c16.584,17.84,55.861,14.924,58.319-13.076c0.729-8.251-2.638-2.152-5.784,0.342
c-4.637,3.675-13.508,3.738-18.191,0.054c-8.121-6.398-21.927-25.92-34.344-11.528c-12.648-14.393-26.71,5.13-34.988,11.528
c-4.764,3.684-13.806,3.621-18.527-0.054c-3.204-2.495-6.631-8.593-5.896-0.342C254.215,237.943,294.234,240.859,311.12,223.019z"
/>
<g>
<polygon fill="#BF8862" points="369.464,147.015 290.052,147.015 287.353,155 369.464,155 "/>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 9.2 KiB

BIN
app/images/yeoman.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

94
app/index.html Normal file
View File

@ -0,0 +1,94 @@
<!doctype html>
<!--[if lt IE 7]>
<html class="no-js lt-ie9 lt-ie8 lt-ie7"> <![endif]-->
<!--[if IE 7]>
<html class="no-js lt-ie9 lt-ie8"> <![endif]-->
<!--[if IE 8]>
<html class="no-js lt-ie9"> <![endif]-->
<!--[if gt IE 8]><!-->
<html class="no-js"> <!--<![endif]-->
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title></title>
<meta name="description" content="">
<meta name="viewport" content="width=device-width">
<!-- Place favicon.ico and apple-touch-icon.png in the root directory -->
<!-- build:css styles/vendor.css -->
<!-- bower:css -->
<!-- endbower -->
<!-- endbuild -->
<!-- build:css({.tmp,app}) styles/main.css -->
<link rel="stylesheet" href="styles/main.css">
<!-- endbuild -->
</head>
<body ng-app="snapSvgAngularApp">
<!--[if lt IE 9]>
<p class="browsehappy">You are using an <strong>outdated</strong> browser. Please <a href="http://browsehappy.com/">upgrade
your browser</a> to improve your experience.</p>
<![endif]-->
<header class="page-header">
<h1>Chartist.js<small> Simple responsive charts</small></h1>
<figure>
<img src="/images/chartist-guy.svg" alt="Chartist Guy"/>
</figure>
</header>
<section class="documentation-section">
<header>
<h2>Chart CSS animation example</h2>
</header>
<div class="content">
<div class="chart-container">
<svg id="chart"></svg>
</div>
</div>
<aside class="side-notes">
<p>Specifying the style of your chart in CSS is not only cleaner but also enables you to use awesome CSS animations and transitions to be applied to your SVG elements!</p>
</aside>
</section>
<!-- Add your site or application content here -->
<article class="main" role="main" ng-view=""></article>
<!-- Google Analytics: change UA-XXXXX-X to be your site's ID -->
<script>
(function (i, s, o, g, r, a, m) {
i['GoogleAnalyticsObject'] = r;
i[r] = i[r] || function () {
(i[r].q = i[r].q || []).push(arguments)
}, i[r].l = 1 * new Date();
a = s.createElement(o),
m = s.getElementsByTagName(o)[0];
a.async = 1;
a.src = g;
m.parentNode.insertBefore(a, m)
})(window, document, 'script', '//www.google-analytics.com/analytics.js', 'ga');
ga('create', 'UA-XXXXX-X');
ga('send', 'pageview');
</script>
<!--[if lt IE 9]>
<script src="bower_components/es5-shim/es5-shim.js"></script>
<script src="bower_components/json3/lib/json3.min.js"></script>
<![endif]-->
<!-- build:js scripts/vendor.js -->
<!-- bower:js -->
<script src="bower_components/modernizr/modernizr.js"></script>
<script src="bower_components/jquery/dist/jquery.js"></script>
<script src="bower_components/snap.svg/dist/snap.svg-min.js"></script>
<script src="bower_components/fastclick/lib/fastclick.js"></script>
<script src="bower_components/jquery.cookie/jquery.cookie.js"></script>
<script src="bower_components/foundation/js/foundation.js"></script>
<!-- endbower -->
<!-- endbuild -->
<!-- build:js({.tmp,app}) scripts/scripts.js -->
<script src="scripts/chartist.js"></script>
<script src="scripts/main.js"></script>
<!-- endbuild -->
</body>
</html>

3
app/robots.txt Normal file
View File

@ -0,0 +1,3 @@
# robotstxt.org
User-agent: *

329
app/scripts/chartist.js Normal file
View File

@ -0,0 +1,329 @@
//TODO: The whole library needs to be extracted into its own library project and not together with the website / documentation
//TODO: Add more chart types!
//TODO: Refactor library structure to optimize scopes and closures
(function (document, window, undefined) {
'use strict';
// Some utility functions
function extend(target, source) {
target = target || {};
for (var prop in source) {
if (typeof source[prop] === 'object') {
target[prop] = extend(target[prop], source[prop]);
} else {
target[prop] = source[prop];
}
}
return target;
}
var LineChartHelpers = {
// Internal functions
getDataArray: function (data) {
var array = [];
for (var i = 0; i < data.series.length; i++) {
array[i] = data.series[i].data;
}
return array;
},
// Add missing values at the end of the arrays
normalizeDataArray: function (dataArray, length) {
for (var i = 0; i < dataArray.length; i++) {
if (dataArray[i].length === length) {
continue;
}
for (var j = dataArray[i].length; j < length; j++) {
dataArray[i][j] = 0;
}
}
return dataArray;
},
// Create points from positions
createPoints: function (paper, positions, options) {
var points = [];
for (var i = 0; i < positions.length; i++) {
var point = paper.line(positions[i].x, positions[i].y, positions[i].x, positions[i].y);
if (options.classNames.point) {
point.node.setAttribute('class', options.classNames.point);
}
points.push(point);
}
return points;
},
// Create lines from positions
createLines: function (paper, positions, options) {
var path = 'M' + positions[0].x + ',' + positions[0].y + ' ' + (options.lineSmooth ? 'R' : 'L');
for (var i = 1; i < positions.length; i++) {
path += ' ' + positions[i].x + ',' + positions[i].y;
}
var snapPath = paper.path(path);
snapPath.node.setAttribute('class', options.classNames.line);
return snapPath;
},
createLabels: function (paper, labels, positions, options) {
var labelElements = [];
for (var i = 0; i < positions.length; i++) {
// Exit based on sampling to skip label rendering
if (i % options.labelSampling !== 0) {
continue;
}
// Add labels with configured padding (left)
var label = paper.text(positions[i].x + options.labelPadding, positions[i].y, options.labelInterpolationFnc(labels[i]));
if (options.classNames.labels) {
label.node.setAttribute('class', options.classNames.labels);
}
labelElements.push(label);
}
return labelElements;
},
createVerticalGrid: function (paper, positions, options) {
var gridElements = [];
for (var i = 0; i < positions.length; i++) {
// Exit based on sampling to skip grid line rendering
if (i % options.verticalGridSampling !== 0) {
continue;
}
// Add grid line
var gridElement = paper.line(positions[i].x, positions[i].y, positions[i].x, options.chartPadding);
if (options.classNames.verticalGridLine) {
gridElement.node.setAttribute('class', options.classNames.verticalGridLine);
}
gridElements.push(gridElement);
}
return gridElements;
},
createHorizontalGrid: function (paper, bounds, options) {
var gridElements = [];
for (var i = bounds.min; i <= bounds.max; i += bounds.step) {
// Add grid line
var gridLineY = LineChartHelpers.projectPoint(paper, i, bounds, options);
var gridElement = paper.line(options.chartPadding, gridLineY, paper.node.clientWidth - options.chartPadding, gridLineY);
if (options.classNames.horizontalGridLine) {
gridElement.node.setAttribute('class', options.classNames.horizontalGridLine);
}
gridElements.push(gridElement);
}
return gridElements;
},
orderOfMagnitude: function (value) {
return Math.floor(Math.log(Math.abs(value)) / Math.LN10);
},
projectPoint: function (paper, value, bounds, options) {
var availableHeight = LineChartHelpers.getAvailableHeight(paper, options);
return availableHeight - (value / bounds.range * availableHeight) + options.chartPadding + (bounds.min / bounds.range * availableHeight);
},
projectLength: function (paper, length, bounds, options) {
var availableHeight = LineChartHelpers.getAvailableHeight(paper, options);
return (length / bounds.range * availableHeight);
},
getAvailableHeight: function (paper, options) {
return paper.node.clientHeight - (options.chartPadding * 2) - options.labelOffset;
},
// Find the highest and lowest values in a two dimensional array and calculate scale based on order of magnitude
getBounds: function (paper, dataArray, options) {
var i,
j,
newMin,
newMax,
bounds = {
low: Number.MAX_VALUE,
high: Number.MIN_VALUE
};
for (i = 0; i < dataArray.length; i++) {
for (j = 0; j < dataArray[i].length; j++) {
if (dataArray[i][j] > bounds.high) {
bounds.high = dataArray[i][j];
}
if (dataArray[i][j] < bounds.low) {
bounds.low = dataArray[i][j];
}
}
}
bounds.valueRange = bounds.high - bounds.low;
bounds.oom = LineChartHelpers.orderOfMagnitude(bounds.valueRange);
bounds.min = Math.floor(bounds.low / Math.pow(10, bounds.oom)) * Math.pow(10, bounds.oom);
bounds.max = Math.ceil(bounds.high / Math.pow(10, bounds.oom)) * Math.pow(10, bounds.oom);
bounds.range = bounds.max - bounds.min;
bounds.step = Math.pow(10, bounds.oom);
bounds.numberOfSteps = Math.round(bounds.range / bounds.step);
// Optimize scale step by checking if subdivision is possible based on horizontalGridMinSpace
while (true) {
var length = LineChartHelpers.projectLength(paper, bounds.step / 2, bounds, options);
if (length >= options.horizontalGridMinSpace) {
bounds.step /= 2;
} else {
break;
}
}
// Narrow min and max based on new step
newMin = bounds.min;
newMax = bounds.max;
for (i = bounds.min; i <= bounds.max; i += bounds.step) {
if (i + bounds.step < bounds.low) {
newMin += bounds.step;
}
if (i - bounds.step > bounds.high) {
newMax -= bounds.step;
}
}
bounds.min = newMin;
bounds.max = newMax;
bounds.range = bounds.max - bounds.min;
return bounds;
}
};
window.Chartist = function (query, data, baseOptions) {
var responsiveOptions,
paper = Snap(query),
dataArray = LineChartHelpers.normalizeDataArray(LineChartHelpers.getDataArray(data), data.labels.length),
i,
j;
if (arguments[3]) {
responsiveOptions = arguments[3];
}
this.reflow = function () {
reflow();
};
function reflow() {
createChart();
}
// Callback for matchMedia to trigger reflow
function mediaQueryTrigger() {
reflow();
}
if (!window.matchMedia) {
throw 'window.matchMedia not found! Make sure you\'re using a polyfill.';
} else if (responsiveOptions) {
for (i = 0; i < responsiveOptions.length; i++) {
var mql = window.matchMedia(responsiveOptions[i][0]);
mql.addListener(mediaQueryTrigger);
// Trigger the first time manually
if (mql.matches) {
mediaQueryTrigger();
}
}
}
function createChart() {
var options,
positions = [],
labelPositions = [],
seriesGroups = [],
bounds;
// Clear the stage
paper.clear();
// Construct current options based on responsive option overrides (overrides in sequence of responsiveOptions)
options = extend({}, baseOptions);
for (i = 0; i < responsiveOptions.length; i++) {
var mql = window.matchMedia(responsiveOptions[i][0]);
if (mql.matches) {
options = extend(options, responsiveOptions[i][1]);
}
}
// initialize bounds
bounds = LineChartHelpers.getBounds(paper, dataArray, options);
// initialize series groups and position array
for (j = 0; j < data.series.length; j++) {
seriesGroups[j] = paper.g();
seriesGroups[j].node.setAttribute('class', options.classNames.series + ' ' + data.series[j].className);
positions[j] = [];
}
for (i = 0; i < data.labels.length; i++) {
for (j = 0; j < dataArray.length; j++) {
positions[j][i] = {
x: ((paper.node.clientWidth - options.chartPadding * 2) / data.labels.length * i) + options.chartPadding,
y: LineChartHelpers.projectPoint(paper, dataArray[j][i], bounds, options)
};
labelPositions[i] = {
x: ((paper.node.clientWidth - options.chartPadding * 2) / data.labels.length * i) + options.chartPadding,
y: paper.node.clientHeight - options.chartPadding
};
}
}
// Create SVG objects based on positions
// TODO: Optimize performance so we only loop once
// First draw the grids
if (options.showVerticalGrid) {
var verticalGrid = paper.g();
verticalGrid.add(LineChartHelpers.createVerticalGrid(paper, labelPositions, options));
verticalGrid.prependTo(paper);
}
if (options.showHorizontalGrid) {
var horizontalGrid = paper.g();
horizontalGrid.add(LineChartHelpers.createHorizontalGrid(paper, bounds, options));
horizontalGrid.prependTo(paper);
}
// Draw the series
for (j = 0; j < data.series.length; j++) {
if (options.showLines) {
seriesGroups[j].add(LineChartHelpers.createLines(paper, positions[j], options));
}
if (options.showPoint) {
seriesGroups[j].add(LineChartHelpers.createPoints(paper, positions[j], options));
}
}
if (options.showLabels) {
var labels = paper.g();
labels.add(LineChartHelpers.createLabels(paper, data.labels, labelPositions, options));
labels.appendTo(paper);
}
}
createChart();
return this;
};
}(document, window));

67
app/scripts/main.js Normal file
View File

@ -0,0 +1,67 @@
'use strict';
var options = {
labelOffset: 40,
labelPadding: 5,
labelSampling: 1,
labelInterpolationFnc: function (l) {
return l;
},
showLines: true,
showPoint: true,
showLabels: true,
showVerticalGrid: true,
showHorizontalGrid: true,
horizontalGridMinSpace: 40,
verticalGridSampling: 1,
lineSmooth: true,
chartPadding: 20,
classNames: {
labels: 'crt-label',
series: 'crt-series',
line: 'crt-line',
point: 'crt-point',
verticalGridLine: 'crt-vertical-grid',
horizontalGridLine: 'crt-horizontal-grid'
}
};
var optionsSmall = {
labelSampling: 2,
chartPadding: 10,
labelOffset: 20
};
var data = {
labels: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
series: [
{
name: 'Investment',
className: 'investment',
data: [1, 2, 2.7, 0, 3, 5, 3, 4, 8, 10, 12, 7]
},
{
name: 'Income',
className: 'income',
data: [0, 1.2, 2, 7, 2.5, 9, 5, 8, 9, 11, 20]
}
]
};
/*// Create new
var chartistGuySnap = Snap('#chartist-guy');
// Load Chartist guy SVG
Snap.load('/images/chartist-guy.svg', function(fragment) {
fragment.select('svg').attr({
'width': '100%',
'height': '100%'
});
chartistGuySnap.append(fragment);
});*/
// Initialize test line chart with override settings for small breakpoint
var chartist = window.Chartist('#chart', data, options, [[Foundation.media_queries.small, optionsSmall]]);
// On window resize trigger reflow
window.addEventListener('resize', function() {
chartist.reflow();
});

164
app/styles/main.scss Normal file
View File

@ -0,0 +1,164 @@
@import "settings/chartist-web";
@import "settings/foundation";
@import "foundation/scss/normalize";
@import "foundation/scss/foundation";
@import "compass/css3";
body {
line-height: 1.4;
}
* {
box-sizing: border-box;
}
h1, h2, h3, h4, h5, h6 {
font-family: "Oxygen";
font-weight: 300;
text-transform: uppercase;
color: $color-gray;
}
h1 {
font-size: rem-calc(32px);
@media #{$medium-up} {
font-size: 46px;
}
}
h2 {
font-size: 26px;
@media #{$medium-up} {
font-size: 34px;
}
}
.page-header {
background-color: $color-yellow;
@include background(linear-gradient(top, $color-yellow 0%, lighten($color-yellow, 5%) 70%, $color-yellow 100%));
min-height: 200px;
text-align: center;
> h1 {
font-size: rem-calc(48px);
margin: 0;
display: inline-block;
width: 100%;
font-weight: 700;
color: white;
line-height: 0.5;
margin-top: 2rem;
@include text-shadow(1px 1px rgba(0, 0, 0, 0.2));
@media #{$medium-up} {
font-size: rem-calc(80px);
}
> small {
font-size: rem-calc(19px);
display: inline-block;
width: 100%;
}
}
> figure {
display: inline-block;
max-width: 380px;
}
}
.documentation-section {
@include grid-row();
> header {
@include grid-column(12);
}
> .content {
@include grid-column(12);
@media #{$medium-up} {
@include grid-column(9);
}
> .chart-container {
width: 100%;
height: 0;
padding-bottom: 67%;
background-color: $color-black;
}
}
> .side-notes {
@include grid-column(12);
@media #{$medium-up} {
@include grid-column(3);
}
}
}
@include keyframes(dashoffset) {
0% {
stroke-dashoffset: 0px;
}
100% {
stroke-dashoffset: -20px;
}
}
.crt-label {
fill: $color-white;
font-size: 13px;
}
.crt-vertical-grid {
stroke: lighten($color-black, 5%);
stroke-dasharray: 3px;
stroke-width: 1px;
}
.crt-horizontal-grid {
stroke: lighten($color-black, 10%);
stroke-dasharray: 3px;
stroke-width: 1px;
}
.crt-series {
&.investment {
.crt-point {
stroke: $color-grapefruit;
stroke-width: 10px;
stroke-linecap: square;
}
.crt-line {
fill: none;
stroke-dasharray: 5px;
stroke-dashoffset: 0px;
stroke: $color-grapefruit;
stroke-width: 4px;
@include animation(dashoffset, 1s linear infinite);
}
}
&.income {
.crt-point {
stroke: $color-mint;
stroke-width: 13px;
stroke-linecap: round;
}
.crt-line {
fill: none;
stroke: $color-mint;
stroke-width: 4px;
}
}
}
@import url("http://fonts.googleapis.com/css?family=Varela+Round|Oxygen:400,300,700");

View File

@ -0,0 +1,33 @@
@mixin keyframes($name) {
@-webkit-keyframes #{$name} {
@content;
}
@-moz-keyframes #{$name} {
@content;
}
@-ms-keyframes #{$name} {
@content;
}
@keyframes #{$name} {
@content;
}
}
@mixin animation($name, $params) {
-webkit-animation: #{$name} $params; /* Safari 4+ */
-moz-animation: #{$name} $params; /* Fx 5+ */
-o-animation: #{$name} $params; /* Opera 12+ */
animation: #{$name} $params; /* IE 10+ */
}
$color-white: #EADBC4;
$color-mint: #A8DACF;
$color-green: #046971;
$color-dark-green: #001A25;
$color-grapefruit: #F05B4F;
$color-red: #D70206;
$color-yellow: #F4C63D;
$color-black: #222222;
$color-gray: #453D3F;
$font-body: "Oxygen";

File diff suppressed because it is too large Load Diff

10
bower.json Normal file
View File

@ -0,0 +1,10 @@
{
"name": "chartist",
"version": "0.0.1",
"dependencies": {
"json3": "~3.2.6",
"es5-shim": "~2.1.0",
"snap.svg": "~0.2.0",
"foundation": "~5.1.1"
}
}

54
karma-e2e.conf.js Normal file
View File

@ -0,0 +1,54 @@
// Karma configuration
// http://karma-runner.github.io/0.10/config/configuration-file.html
module.exports = function(config) {
config.set({
// base path, that will be used to resolve files and exclude
basePath: '',
// testing framework to use (jasmine/mocha/qunit/...)
frameworks: ['jasmine'],
// list of files / patterns to load in the browser
files: [
'test/e2e/**/*.js'
],
// list of files / patterns to exclude
exclude: [],
// web server port
port: 8080,
// level of logging
// possible values: LOG_DISABLE || LOG_ERROR || LOG_WARN || LOG_INFO || LOG_DEBUG
logLevel: config.LOG_INFO,
// enable / disable watching file and executing tests whenever any file changes
autoWatch: false,
// Start these browsers, currently available:
// - Chrome
// - ChromeCanary
// - Firefox
// - Opera
// - Safari (only Mac)
// - PhantomJS
// - IE (only Windows)
browsers: ['Chrome'],
// Continuous Integration mode
// if true, it capture browsers, run tests and exit
singleRun: false
// Uncomment the following lines if you are using grunt's server to run the tests
// proxies: {
// '/': 'http://localhost:9000/'
// },
// URL root prevent conflicts with the site root
// urlRoot: '_karma_'
});
};

54
karma.conf.js Normal file
View File

@ -0,0 +1,54 @@
// Karma configuration
// http://karma-runner.github.io/0.10/config/configuration-file.html
module.exports = function(config) {
config.set({
// base path, that will be used to resolve files and exclude
basePath: '',
// testing framework to use (jasmine/mocha/qunit/...)
frameworks: ['jasmine'],
// list of files / patterns to load in the browser
files: [
'app/bower_components/jquery/dist/jquery.min.js',
'app/bower_components/fastclick/lib/fastclick.js',
'app/bower_components/foundation/js/foundation.min.js',
'app/bower_components/snap.svg/dist/snap.svg-min.js',
'app/scripts/*.js',
'app/scripts/**/*.js',
'test/mock/**/*.js',
'test/spec/**/*.js'
],
// list of files / patterns to exclude
exclude: [],
// web server port
port: 8080,
// level of logging
// possible values: LOG_DISABLE || LOG_ERROR || LOG_WARN || LOG_INFO || LOG_DEBUG
logLevel: config.LOG_INFO,
// enable / disable watching file and executing tests whenever any file changes
autoWatch: false,
// Start these browsers, currently available:
// - Chrome
// - ChromeCanary
// - Firefox
// - Opera
// - Safari (only Mac)
// - PhantomJS
// - IE (only Windows)
browsers: ['Chrome'],
// Continuous Integration mode
// if true, it capture browsers, run tests and exit
singleRun: false
});
};

51
package.json Normal file
View File

@ -0,0 +1,51 @@
{
"name": "chartist",
"version": "0.0.1",
"dependencies": {},
"devDependencies": {
"grunt": "~0.4.1",
"grunt-autoprefixer": "~0.4.0",
"grunt-bower-install": "~0.7.0",
"grunt-concurrent": "~0.4.1",
"grunt-contrib-clean": "~0.5.0",
"grunt-contrib-coffee": "~0.7.0",
"grunt-contrib-compass": "~0.6.0",
"grunt-contrib-concat": "~0.3.0",
"grunt-contrib-connect": "~0.5.0",
"grunt-contrib-copy": "~0.4.1",
"grunt-contrib-cssmin": "~0.7.0",
"grunt-contrib-htmlmin": "~0.1.3",
"grunt-contrib-imagemin": "~0.3.0",
"grunt-contrib-jshint": "~0.7.1",
"grunt-contrib-uglify": "~0.2.0",
"grunt-contrib-watch": "~0.5.2",
"grunt-google-cdn": "~0.2.0",
"grunt-newer": "~0.5.4",
"grunt-ngmin": "~0.0.2",
"grunt-rev": "~0.1.0",
"grunt-svgmin": "~0.2.0",
"grunt-usemin": "~2.0.0",
"jshint-stylish": "~0.1.3",
"load-grunt-tasks": "~0.2.0",
"time-grunt": "~0.2.1",
"karma-ng-scenario": "~0.1.0",
"grunt-karma": "~0.6.2",
"karma-script-launcher": "~0.1.0",
"karma-chrome-launcher": "~0.1.2",
"karma-firefox-launcher": "~0.1.3",
"karma-html2js-preprocessor": "~0.1.0",
"karma-jasmine": "~0.1.5",
"requirejs": "~2.1.11",
"karma-requirejs": "~0.2.1",
"karma-coffee-preprocessor": "~0.1.3",
"karma-phantomjs-launcher": "~0.1.2",
"karma": "~0.10.9",
"karma-ng-html2js-preprocessor": "~0.1.0"
},
"engines": {
"node": ">=0.8.0"
},
"scripts": {
"test": "grunt test"
}
}

36
test/.jshintrc Normal file
View File

@ -0,0 +1,36 @@
{
"node": true,
"browser": true,
"esnext": true,
"bitwise": true,
"camelcase": true,
"curly": true,
"eqeqeq": true,
"immed": true,
"indent": 2,
"latedef": true,
"newcap": true,
"noarg": true,
"quotmark": "single",
"regexp": true,
"undef": true,
"unused": true,
"strict": true,
"trailing": true,
"smarttabs": true,
"globals": {
"after": false,
"afterEach": false,
"angular": false,
"before": false,
"beforeEach": false,
"browser": false,
"describe": false,
"expect": false,
"inject": false,
"it": false,
"jasmine": false,
"spyOn": false
}
}

9
test/runner.html Normal file
View File

@ -0,0 +1,9 @@
<!doctype html>
<html lang="en">
<head>
<title>End2end Test Runner</title>
</head>
<body>
<svg id="chart"></svg>
</body>
</html>