11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
26 |
29 |
30 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
--------------------------------------------------------------------------------
/dist/onedatastyle.css:
--------------------------------------------------------------------------------
1 | body {
2 | font-family: sans-serif;
3 | }
4 |
5 | .button-overlay {
6 | position: absolute;
7 | top: 40px;
8 | left: 40px;
9 | z-index: 10;
10 | }
11 |
12 | .button-overlay button {
13 | display: block;
14 | padding: 10px;
15 | margin-bottom: 15px;
16 | border-radius: 10px;
17 | border: none;
18 | box-shadow: none;
19 | color: #fff;
20 | font-size: 20px;
21 | background-color: #F15B26;
22 | }
23 |
24 | .button-overlay button:hover:not(:disabled) {
25 | border: 4px solid #b03911;
26 | border-radius: 5px;
27 |
28 | margin: -4px;
29 | margin-bottom: 11px;
30 | }
31 |
32 | .button-overlay button:disabled {
33 | -webkit-filter: brightness(70%);
34 | filter: brightness(70%);
35 | }
36 |
37 | .fc-node {
38 | z-index: 1;
39 | }
40 |
41 | .innerNode {
42 | display: flex;
43 | justify-content: center;
44 | align-items: center;
45 | min-width: 100px;
46 | border-radius: 5px;
47 |
48 | background-color: #F15B26;
49 | color: #fff;
50 | font-size: 20px;
51 | }
52 |
53 | .fc-node.fc-hover {
54 | -webkit-filter: brightness(70%);
55 | filter: brightness(70%);;
56 | }
57 |
58 | .fc-node.fc-selected {
59 | -webkit-filter: brightness(70%);
60 | filter: brightness(70%);
61 | }
62 |
63 | .fc-node.fc-dragging {
64 | z-index: 10;
65 | }
66 |
67 | .fc-node p {
68 | padding: 0 15px;
69 | text-align: center;
70 | }
71 |
72 | .fc-topConnectors, .fc-bottomConnectors {
73 | position: absolute;
74 | left: 0;
75 | width: 100%;
76 |
77 | display: flex;
78 | flex-direction: row;
79 |
80 | z-index: -10;
81 | }
82 |
83 | .fc-topConnectors {
84 | top: -40px;
85 | }
86 |
87 | .fc-bottomConnectors {
88 | bottom: -40px;
89 | }
90 |
91 | .fc-magnet {
92 | display: flex;
93 | flex-grow: 1;
94 | height: 60px;
95 |
96 | justify-content: center;
97 | }
98 |
99 | .fc-topConnectors .fc-magnet {
100 | align-items: flex-end;
101 | }
102 |
103 | .fc-bottomConnectors .fc-magnet {
104 | align-items: flex-start;
105 | }
106 |
107 | .fc-connector {
108 | width: 18px;
109 | height: 18px;
110 |
111 | border: 10px solid transparent;
112 | -moz-background-clip: padding; /* Firefox 3.6 */
113 | -webkit-background-clip: padding; /* Safari 4? Chrome 6? */
114 | background-clip: padding-box;
115 | border-radius: 50% 50%;
116 | background-color: #F7A789;
117 | color: #fff;
118 | }
119 |
120 | .fc-connector.fc-hover {
121 | background-color: #000;
122 | }
123 |
124 | .fc-edge {
125 | stroke: gray;
126 | stroke-width: 4;
127 | fill: transparent;
128 | }
129 |
130 | .fc-edge.fc-hover {
131 | stroke: gray;
132 | stroke-width: 6;
133 | fill: transparent;
134 | }
135 |
136 | @keyframes dash {
137 | from {
138 | stroke-dashoffset: 500;
139 | }
140 | }
141 |
142 | .fc-edge.fc-selected {
143 | stroke: red;
144 | stroke-width: 4;
145 | fill: transparent;
146 | }
147 |
148 | .fc-edge.fc-active {
149 | animation: dash 3s linear infinite;
150 | stroke-dasharray: 20;
151 | }
152 |
153 | .fc-edge.fc-dragging {
154 | pointer-events: none;
155 | }
156 |
157 | .edge-endpoint {
158 | fill: gray;
159 | }
160 |
161 | .fc-nodedelete {
162 | display: none;
163 | }
164 |
165 | .fc-selected .fc-nodedelete {
166 | display: block;
167 | position: absolute;
168 | right: -13px;
169 | top: -13px;
170 | border: solid 2px white;
171 |
172 | border-radius: 50%;
173 | font-weight: 600;
174 | font-size: 20px;
175 |
176 | height: 25px;
177 | padding-top: 2px;
178 | width: 27px;
179 |
180 | background: #494949;
181 | color: #fff;
182 | text-align: center;
183 | vertical-align: bottom;
184 | }
185 |
186 |
--------------------------------------------------------------------------------
/gulpfile.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var gulp = require('gulp'),
4 | concat = require('gulp-concat'),
5 | merge2 = require('merge2'),
6 | del = require('del'),
7 | open = require('gulp-open'),
8 | connect = require('gulp-connect'),
9 | ngAnnotate = require('gulp-ng-annotate'),
10 | ngFilesort = require('gulp-angular-filesort'),
11 | ngHtml2Js = require('gulp-ng-html2js'),
12 | bowerFiles = require('main-bower-files'),
13 | karma = require('karma').server;
14 | //postcss = require('gulp-postcss'),
15 | //sourcemaps = require('gulp-sourcemaps'),
16 | //autoprefixer = require('autoprefixer-core');
17 |
18 | var safeReload = 0; // Semaphore for the reload task, should not run at same time as build tasks. If 0 it is save to run reload.
19 |
20 | var jsFilter = {
21 | filter: /\.js$/i
22 | };
23 |
24 | gulp.task('vendorScripts', function() {
25 | safeReload++;
26 | var ret = gulp.src(bowerFiles(jsFilter))
27 | .pipe(concat('vendor.js'))
28 | .pipe(gulp.dest('dist/'));
29 | safeReload--;
30 | return ret;
31 | });
32 |
33 | gulp.task('flowchartScripts', function() {
34 | safeReload++;
35 | var ret = merge2(
36 | gulp.src(['app/flowchart/*.js', 'app/bower_components/bind-polyfill/index.js', '!app/flowchart/*_test.js'])
37 | .pipe(ngAnnotate())
38 | .pipe(ngFilesort()),
39 | gulp.src('app/flowchart/*.html')
40 | .pipe(ngHtml2Js({
41 | moduleName: 'flowchart-templates',
42 | prefix: 'flowchart/'
43 | }))
44 | )
45 | .pipe(concat('ngFlowchart.js'))
46 | .pipe(gulp.dest('dist'));
47 | safeReload--;
48 | return ret;
49 | });
50 |
51 | gulp.task('connect', ['build'], function() {
52 | connect.server({
53 | root: ['dist'],
54 | port: 8000,
55 | livereload: true
56 | });
57 | });
58 |
59 |
60 | gulp.task('open', function() {
61 | var options = {
62 | url: 'http://localhost:' + 8000
63 | };
64 | gulp.src('dist/index.html')
65 | .pipe(open('', options));
66 | });
67 |
68 | gulp.task('watch', function() {
69 | gulp.watch('app/flowchart/flowchart.css', ['flowchartCss']);
70 | gulp.watch(['app/flowchart/*.js', '!app/flowchart/*_test.js', 'app/flowchart/*.html'], ['flowchartScripts']);
71 | gulp.watch('dist/**', ['reload']);
72 | });
73 |
74 | gulp.task('reload', function() {
75 | if (safeReload === 0) {
76 | return gulp.src('dist/**')
77 | .pipe(connect.reload());
78 | }
79 | });
80 |
81 | gulp.task('flowchartCss', function() {
82 | gulp.src('app/flowchart/flowchart.css')
83 | .pipe(gulp.dest('dist'));
84 | //gulp.src('dist/onedatastyle.css')
85 | // .pipe(postcss([autoprefixer({ browsers: ['last 2 version'] }) ]))
86 | // .pipe(gulp.dest('dist/compiled/'))
87 | });
88 |
89 | gulp.task('test', function(done) {
90 | karma.start({
91 | configFile: __dirname + '/karma.conf.js',
92 | singleRun: true
93 | }, function() {
94 | done();
95 | });
96 | });
97 |
98 | gulp.task('clean', function(done) {
99 | del(['dist/ngFlowchart.js', 'dist/vendor.js', 'dist/flowchart.css'], done);
100 | });
101 |
102 | gulp.task('build', ['flowchartScripts', 'flowchartCss', 'vendorScripts']);
103 | gulp.task('default', ['connect', 'open', 'watch']);
104 |
105 |
106 |
107 |
108 |
--------------------------------------------------------------------------------
/jscs.json:
--------------------------------------------------------------------------------
1 | {
2 | "excludeFiles": [""],
3 | "disallowKeywords": ["with"],
4 | "disallowKeywordsOnNewLine": ["else"],
5 | "disallowMixedSpacesAndTabs": true,
6 | "disallowMultipleLineStrings": true,
7 | "disallowNewlineBeforeBlockStatements": true,
8 | "disallowSpaceAfterObjectKeys": true,
9 | "disallowSpaceAfterPrefixUnaryOperators": ["++", "--", "+", "-", "~", "!"],
10 | "disallowSpaceBeforeBinaryOperators": [","],
11 | "disallowSpaceBeforePostfixUnaryOperators": ["++", "--"],
12 | "disallowSpacesInAnonymousFunctionExpression": {
13 | "beforeOpeningRoundBrace": true
14 | },
15 | "disallowSpacesInCallExpression": true,
16 | "disallowSpacesInFunctionDeclaration": {
17 | "beforeOpeningRoundBrace": true
18 | },
19 | "disallowSpacesInNamedFunctionExpression": {
20 | "beforeOpeningRoundBrace": true
21 | },
22 | "disallowSpacesInsideArrayBrackets": true,
23 | "requireSpaceBeforeKeywords": [
24 | "else",
25 | "while",
26 | "catch"
27 | ],
28 | "disallowSpacesInsideParentheses": true,
29 | "disallowTrailingComma": true,
30 | "disallowTrailingWhitespace": true,
31 | "requireCommaBeforeLineBreak": true,
32 | "requireLineFeedAtFileEnd": true,
33 | "requireSpaceAfterBinaryOperators": ["?", ":", "+", "-", "/", "*", "%", "==", "===", "!=", "!==", ">", ">=", "<", "<=", "&&", "||"],
34 | "requireSpaceBeforeBinaryOperators": ["?", ":", "+", "-", "/", "*", "%", "==", "===", "!=", "!==", ">", ">=", "<", "<=", "&&", "||"],
35 | "requireSpaceAfterKeywords": ["if", "else", "for", "while", "do", "switch", "return", "try", "catch"],
36 | "requireSpaceBeforeBlockStatements": true,
37 | "requireSpacesInConditionalExpression": {
38 | "afterTest": true,
39 | "beforeConsequent": true,
40 | "afterConsequent": true,
41 | "beforeAlternate": true
42 | },
43 | "requireSpacesInForStatement": true,
44 | "requireSpacesInFunction": {
45 | "beforeOpeningCurlyBrace": true
46 | },
47 | "validateLineBreaks": "LF"
48 | }
49 |
--------------------------------------------------------------------------------
/karma.conf.js:
--------------------------------------------------------------------------------
1 | // Karma configuration
2 | // Generated on Thu Apr 23 2015 14:37:29 GMT+0200 (Mitteleuropäische Sommerzeit)
3 |
4 | module.exports = function(config) {
5 | config.set({
6 |
7 | // base path that will be used to resolve all patterns (eg. files, exclude)
8 | basePath: 'app',
9 |
10 | // frameworks to use
11 | // available frameworks: https://npmjs.org/browse/keyword/karma-adapter
12 | frameworks: ['jasmine'],
13 |
14 | // list of files / patterns to load in the browser
15 | files: [
16 | 'bower_components/angular/angular.js',
17 | 'bower_components/angular-loader/angular-loader.min.js',
18 | 'bower_components/angular-mocks/angular-mocks.js',
19 | 'bower_components/angular-route/angular-route.min.js',
20 | 'bower_components/bind-polyfill/index.js',
21 | 'flowchart/flowchart.js',
22 | 'flowchart/**/*.js',
23 | 'flowchart/**.html'
24 | ],
25 |
26 |
27 | // list of files to exclude
28 | exclude: [
29 | '**/*.md',
30 | ],
31 |
32 | // preprocess matching files before serving them to the browser
33 | // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
34 | preprocessors: {
35 | '**/*.html': ['ng-html2js']
36 | },
37 |
38 | ngHtml2JsPreprocessor: {
39 | // prepend this to the
40 | prependPrefix: '',
41 | // setting this option will create only a single module that contains templates
42 | // from all the files, so you can load them all with module('foo')
43 | moduleName: 'flowchart-templates'
44 | },
45 |
46 | // test results reporter to use
47 | // possible values: 'dots', 'progress'
48 | // available reporters: https://npmjs.org/browse/keyword/karma-reporter
49 | reporters: ['progress'],
50 |
51 |
52 | // web server port
53 | port: 9876,
54 |
55 |
56 | // enable / disable colors in the output (reporters and logs)
57 | colors: true,
58 |
59 |
60 | // level of logging
61 | // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
62 | logLevel: config.LOG_INFO,
63 |
64 |
65 | // enable / disable watching file and executing tests whenever any file changes
66 | autoWatch: false,
67 |
68 |
69 | // start these browsers
70 | // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
71 | browsers: ['PhantomJS',
72 | 'Firefox',
73 | 'Chrome',
74 | 'IE'],
75 |
76 |
77 | // Continuous Integration mode
78 | // if true, Karma captures browsers, runs the tests and exits
79 | singleRun: false
80 | });
81 | };
82 |
--------------------------------------------------------------------------------
/liveDemo.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DaHaiz/ngFlowchart/cf65822ce379dc889b67261bca889884075165a2/liveDemo.gif
--------------------------------------------------------------------------------
/ngFlowchartDependency.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DaHaiz/ngFlowchart/cf65822ce379dc889b67261bca889884075165a2/ngFlowchartDependency.png
--------------------------------------------------------------------------------
/ngFlowchartDependencyGraph.dia:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DaHaiz/ngFlowchart/cf65822ce379dc889b67261bca889884075165a2/ngFlowchartDependencyGraph.dia
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "ngFlowchart",
3 | "version": "0.5.1",
4 | "description": "Customizable drag & drop flowchart directive for AngularJS",
5 | "repository": "https://github.com/ONE-LOGIC/ngFlowchart",
6 | "license": "MIT",
7 | "devDependencies": {
8 | "bower": "^1.3.1",
9 | "del": "^1.1.1",
10 | "gulp": "^3.8.11",
11 | "gulp-angular-filesort": "^1.1.1",
12 | "gulp-concat": "^2.5.2",
13 | "gulp-connect": "^2.2.0",
14 | "gulp-ng-annotate": "^0.5.3",
15 | "gulp-ng-html2js": "^0.2.0",
16 | "gulp-open": "^0.3.2",
17 | "jasmine-core": "^2.2.0",
18 | "karma": "^0.12.31",
19 | "karma-chrome-launcher": "^0.1.8",
20 | "karma-firefox-launcher": "^0.1.4",
21 | "karma-ie-launcher": "^0.1.5",
22 | "karma-jasmine": "^0.3.5",
23 | "karma-junit-reporter": "^0.2.2",
24 | "karma-ng-html2js-preprocessor": "^0.1.2",
25 | "karma-phantomjs-launcher": "^0.1.4",
26 | "main-bower-files": "^2.7.0",
27 | "merge2": "^0.3.5",
28 | "wallaby-ng-html2js-preprocessor": "^0.1.0"
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/wallaby.js:
--------------------------------------------------------------------------------
1 | module.exports = function (wallaby) {
2 | return {
3 |
4 | testFramework: 'jasmine@2.2.1',
5 | files: [
6 | 'app/bower_components/angular/angular.js',
7 | 'app/bower_components/angular-loader/angular-loader.min.js',
8 | 'app/bower_components/angular-mocks/angular-mocks.js',
9 | 'app/bower_components/angular-route/angular-route.min.js',
10 | 'app/bower_components/bind-polyfill/index.js',
11 | 'app/*.js',
12 | 'dist/onedatastyle.css',
13 | 'app/flowchart/**/*.html',
14 | 'app/flowchart/flowchart.js',
15 | 'app/flowchart/**/*.js',
16 | '!app/flowchart/**/*_test.js',
17 | '!app/server.js'
18 | ],
19 | tests: [
20 | 'app/flowchart/**/*_test.js'
21 | ],
22 | preprocessors: {
23 | 'app/**/*.html': function (file) {
24 | return require('wallaby-ng-html2js-preprocessor').transform(file, {
25 | // strip this from the file path
26 | stripPrefix: 'app/',
27 | //stripSufix: '.ext',
28 | // prepend this to the
29 | //prependPrefix: '/',
30 |
31 | // setting this option will create only a single module that contains templates
32 | // from all the files, so you can load them all with module('foo')
33 | moduleName: 'flowchart-templates'
34 | })
35 | },
36 | }
37 | };
38 | }
39 | ;
40 |
--------------------------------------------------------------------------------