From 6b5f5f504de2873054966069dbb5ebabf0ac2c70 Mon Sep 17 00:00:00 2001 From: Enrico Fasoli Date: Fri, 13 Mar 2015 21:03:11 +0100 Subject: [PATCH] can now view graphs --- .gitignore | 1 + .npmignore | 1 + client/bower.json | 21 +++++++++++++++++++++ client/index.html | 20 ++++++++++++++++++++ package.json | 5 +++-- scripts/build.sh | 1 + src/pert-cli.coffee | 19 +++++++++++++++++++ src/pert-ui.coffee | 17 +++++++++++++++++ src/pert.coffee | 17 +++++++++++++++-- 9 files changed, 98 insertions(+), 4 deletions(-) create mode 100644 client/bower.json create mode 100644 client/index.html create mode 100644 src/pert-ui.coffee diff --git a/.gitignore b/.gitignore index 064485c..2c17fa9 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ node_modules/ +client/bower_components/ test/ lib/ bin/ diff --git a/.npmignore b/.npmignore index ea9bfd0..00b7ffc 100644 --- a/.npmignore +++ b/.npmignore @@ -1,2 +1,3 @@ src/ +client/bower_components/ test/ diff --git a/client/bower.json b/client/bower.json new file mode 100644 index 0000000..ee54d8c --- /dev/null +++ b/client/bower.json @@ -0,0 +1,21 @@ +{ + "name": "pert-gui", + "version": "0.1.0", + "homepage": "https://github.com/fazo96/pert", + "authors": [ + "Enrico Fasoli " + ], + "description": "web ui for pert", + "license": "MIT", + "private": true, + "ignore": [ + "**/.*", + "node_modules", + "bower_components", + "test", + "tests" + ], + "dependencies": { + "vis": "~3.11.0" + } +} diff --git a/client/index.html b/client/index.html new file mode 100644 index 0000000..04888cd --- /dev/null +++ b/client/index.html @@ -0,0 +1,20 @@ + + + + Pert + + + + + + +
+ + + diff --git a/package.json b/package.json index a09ab9a..7e210ca 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,7 @@ "main": "lib/pert.js", "bin": { "pert": "./bin/pert" - }, + }, "scripts": { "prepublish": "scripts/build.sh", "build": "scripts/build.sh", @@ -23,7 +23,8 @@ "homepage": "https://github.com/fazo96/pert", "dependencies": { "chalk": "^1.0.0", - "commander": "^2.6.0" + "commander": "^2.6.0", + "express": "^4.12.2" }, "devDependencies": { "coffee-script": "^1.9.1" diff --git a/scripts/build.sh b/scripts/build.sh index c2eb0c7..cfc4f43 100755 --- a/scripts/build.sh +++ b/scripts/build.sh @@ -3,3 +3,4 @@ echo '#!/usr/bin/env node' > bin/pert coffee -b -c --no-header -p src/pert-cli.coffee >> bin/pert chmod +x bin/pert coffee -b -c --no-header -p src/pert.coffee > lib/pert.js +coffee -b -c --no-header -p src/pert-ui.coffee > client/pert-ui.js diff --git a/src/pert-cli.coffee b/src/pert-cli.coffee index 848d7da..d9f27fe 100755 --- a/src/pert-cli.coffee +++ b/src/pert-cli.coffee @@ -3,6 +3,7 @@ chalk = require 'chalk' cli = require 'commander' fs = require 'fs' Pert = require '../lib/pert.js' +express = require 'express' ex = [{id: 0, depends: [], duration: 2}, { id: 1, depends: [0], duration: 3},{id: 2, depends: [0,1], duration: 4}] @@ -36,6 +37,24 @@ cli pert = new Pert JSON.parse(content), cli.verbose console.log pert.calculate options +cli + .command 'graph ' + .description 'serve HTTP GUI with pert graph of given JSON document' + .alias 'g' + .action (file) -> + didSomething = yes + fs.readFile file, (error,content) -> + if error then err error + else + pert = new Pert JSON.parse(content), cli.verbose + data = pert.calculate() + app = express() + app.use express.static 'client' + app.get '/data', (req,res) -> res.json data + app.listen 3000 + console.log chalk.green('Started Web Server'), 'on port', chalk.bold(3000) + + cli.parse process.argv if !didSomething then console.log chalk.green('Tip:'), 'see', chalk.bold(cli.name()+' --help') diff --git a/src/pert-ui.coffee b/src/pert-ui.coffee new file mode 100644 index 0000000..9f5ef97 --- /dev/null +++ b/src/pert-ui.coffee @@ -0,0 +1,17 @@ +$.get 'data', (data) -> + console.log data + i = 0 + nodes = data.days.map (x) -> {id: x, label: ""+x} + connections = [] + data.activities.forEach (x) -> + connections.push + from: x.startDay, to: x.endDay + label: x.id+" ("+(if x.permittedDelay > 0 then x.duration+"/"+(x.duration+x.permittedDelay) else x.duration)+")" + if x.permittedDelay > 0 + connections.push from: x.endDay, to: x.endDay+x.permittedDelay, color: 'green', label: "("+x.permittedDelay+")" + console.log nodes + console.log connections + options = + edges: + style: 'arrow' + network = new vis.Network (document.getElementById 'pert'), { nodes: nodes, edges: connections }, options diff --git a/src/pert.coffee b/src/pert.coffee index f443192..fa30383 100755 --- a/src/pert.coffee +++ b/src/pert.coffee @@ -3,6 +3,7 @@ fs = require 'fs' module.exports = class Pert constructor: (@list, @verbose) -> + @days = [] log: (x...) -> if @verbose then console.log chalk.bold("Pert:"), x... err: (x...) -> console.log chalk.bold (chalk.red "Pert:"), x... @@ -25,11 +26,14 @@ module.exports = class Pert @log "start day of",item.id,"is",item.startDay item.endDay = item.startDay + item.duration @log "end day of",item.id,"is",item.endDay + @insertDay item.endDay return item.endDay # Find out which day the activity starts calculateStartDay: (item) => - if !item.depends? or item.depends.length is 0 then return item.startDay = 0 + if !item.depends? or item.depends.length is 0 + @insertDay 0 + return item.startDay = 0 item.startDay = @maxa item.depends.map(@toActivity).map @calculateEndDay @log "start day of",item.id,"is",item.startDay # write max delay time to each depend @@ -41,11 +45,20 @@ module.exports = class Pert @log "written permittedDelay to dependency", x, "of", item, "as", i.permittedDelay else @log "aborting permittedDelay: already calculated" @log "permitted delay of",x,"is",i.permittedDelay + @insertDay item.startDay return item.startDay # Find out which activity has the highest id highestID: => return @maxa(@list.map (x) -> x.id) + # Insert a day to the list of days if it's not there already + insertDay: (day) => + for d in @days + if day is d then return + @days.push day + calculate: (options) -> @calculateEndDay @toActivity @highestID() - if options?.json then JSON.stringify @list else @list + results = activities: @list, days: @days + if options?.json then JSON.stringify results else results +