Skip to content

Commit

Permalink
Merge branch 'v0.2'
Browse files Browse the repository at this point in the history
Conflicts:
	.gitignore
  • Loading branch information
huston committed Aug 18, 2014
2 parents 4edd410 + ad07872 commit 0022106
Show file tree
Hide file tree
Showing 116 changed files with 7,413 additions and 3,314 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,4 @@ app/index.html
site/dist
.grunt
archive
s3.yml
s3.yml
71 changes: 71 additions & 0 deletions BUILD.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
Build this repo locally
=======================
Alchemy.js leverages yeoman.io heavily for workflow. At the heart of Yeoman is the Gruntfile which is used to run tasks. The Alchemy.js app `./app` builds a `./dist` folder containing Alchemy.js and dependencies, while the Alchemy.js site is built from a seperate Yeoman project in the `./site` folder which publishes to the gh-pages branch of this repo. Additionally, we use [CoffeeScript](http://coffeescript.org), [Sass](http://sass-lang.com/), [d3](http://sass-lang.com/), and [lodash](http://lodash.com/). If you are looking to contribute, each project has fantastic documentation.

##### Up and Running with Yeoman:
```
# If you don't have Node find fast Wifi
brew update
brew doctor
brew install node
# If you don't have Yeoman find fast Wifi
npm install -g yo
# Install Coffee for compiling CoffeeScript into JavaScript
npm install -g coffee-script
# Install Compass for compiling Sass into css
gem install compass
# Download this directory
git clone [email protected]:GraphAlchemist/Alchemy.git
cd Alchemy
```

Building the Alchemy app
------------------------
Get Alchemy up and running locally:
```
# Make sure you are in the Alchemy directory and
# completed the Up and Running with Yeoman steps
# Install project specific Node dependencies
npm install
# Install project specific front end dependencies
bower install
# Fire up the grunt dev server
grunt serve
```

Alchemy will now be running at localhost:9000. The Alchemy app that is running is based on the inline configuration in `./app/index.html`. Additionally, there are a number of sample data sets to play with in the `./app/sample_data/` directory.

Building the Docs
-----------------
One of the best ways to contribute is helping clean up the docs.

The Alchemy.js site is in angular and is hosted on gh-pages from this repo. The site builds from the site folder `./site`. All of the documentation is written in Markdown can be found in the docs folder `./site/app/docs`.

Here's how to get the docs up and running locally:
```
# Make sure you are in the site directory and
# completed the Up and Running with Yeoman steps
# Install Node depedencies
npm install
# Install Bower depedencies
bower install
# Install Jekyll and its depedencies
gem install jekyll
gem install codearray
gem install kramdown
# Run the documentation locally
grunt serve
```

The docs should now be running locally on port :9002.
82 changes: 69 additions & 13 deletions Gruntfile.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ module.exports = (grunt) ->
require("load-grunt-tasks") grunt
require("time-grunt") grunt
pkg = grunt.file.readJSON('./package.json')
s3Config = grunt.file.readYAML('./s3.yml')
grunt.initConfig

# Project settings
Expand All @@ -18,6 +19,21 @@ module.exports = (grunt) ->
app: "app"
dist: "dist"

# Upload to CDN.
s3:
options:
#Accesses environment variables
key: s3Config.AWS_ACCESS_KEY_ID
secret: s3Config.AWS_SECRET_ACCESS_KEY
access: 'public-read'
production:
bucket: "cdn.graphalchemist.com"
upload:[
# upload the files without version to CDN
src: ".tmp/s3/**"
dest: "/"
]

'string-replace':
version:
files:
Expand All @@ -42,6 +58,8 @@ module.exports = (grunt) ->
command: "git commit -am 'commit dist files for #{pkg.version}'"
docs:
command: 'grunt --gruntfile site/Gruntfile.js'
loadEnvVariables:
command: 'source s3.sh'

# Watches files for changes and runs tasks based on the changed files
watch:
Expand All @@ -57,7 +75,7 @@ module.exports = (grunt) ->
files: ["Gruntfile.coffee"]

compass:
files: ["<%= yeoman.app %>/styles/{,*/}*.{scss,sass}"]
files: ["<%= yeoman.app %>/styles/{,*/,*/*/}*.{scss,sass}"]
tasks: ["compass:server", "autoprefixer"]

styles:
Expand Down Expand Up @@ -316,7 +334,37 @@ module.exports = (grunt) ->
src: '.tmp/styles/alchemy.css'
}
]

s3:
files: [
dest: '.tmp/s3/alchemy.min.js'
src: ['<%= yeoman.dist %>/scripts/vendor.js'
'<%= yeoman.dist %>/alchemy.min.js']
, # I think this comma format is elegant - if anyone hates it
# feel free to comment
dest: '.tmp/s3/alchemy.js'
src: ['<%= yeoman.dist %>/scripts/vendor.js'
'<%= yeoman.dist %>/alchemy.js']
,
dest: '.tmp/s3/alchemy.min.css'
src: ['<%= yeoman.dist %>/styles/vendor.css'
'<%= yeoman.dist %>/alchemy.min.css']
,
dest: '.tmp/s3/alchemy.css'
src: ['<%= yeoman.dist %>/styles/vendor.css'
'<%= yeoman.dist %>/alchemy.css']
]
s3Version:
files: [
expand: true
cwd: ".tmp/s3/"
src: "alchemy{,*}.*"
dest: ".tmp/s3/"
rename: (dest, src) ->
name = src.substring(0, src.indexOf('.'))
ext = src.substring(src.indexOf('.'), src.length)
versioned = "#{name}.#{pkg.version}#{ext}"
dest + versioned
]
buildAlchemy:
files: [
{
Expand Down Expand Up @@ -352,6 +400,13 @@ module.exports = (grunt) ->
dest: "<%= yeoman.dist %>"
src: ["*.{ico,png,txt}", "images/{,*/}*.webp", "{,*/}*.html", "styles/fonts/{,*/}*.*", "sample_data/{,*/}*.json"]
]
s3:
files: [
expand: true
cwd: "<%= yeoman.dist %>/styles"
dest: ".tmp/s3/"
src: ["fonts/*", "images/*"]
]

styles:
expand: true
Expand Down Expand Up @@ -392,6 +447,7 @@ module.exports = (grunt) ->
grunt.loadNpmTasks('grunt-shell')
grunt.loadNpmTasks('grunt-release')
grunt.loadNpmTasks('grunt-string-replace')
# grunt.loadNpmTasks('grunt-s3') # yeoman already includes

grunt.registerTask 'bumpBower', ->
bower = grunt.file.readJSON('./bower.json')
Expand Down Expand Up @@ -430,20 +486,20 @@ module.exports = (grunt) ->
grunt.registerTask "default",
if releaseFlag
["newer:jshint",
# run tests
"test",
# build alchemy
"build",
"string-replace",
# publish docs
"shell:docs",
"shell:commitBuild",
"bumpBower",
# create tag and version
"release"]
"string-replace", # apply version to alchemy.js
"shell:docs", # publish docs
"shell:commitBuild", # commit dist files
"bumpBower", # bump bower version
"release", # create tag and version
"archiveDist", # create archive of files to zip for github release
"concat:s3", # squash vendor and alchemy files for cdn
"concat:s3Version", # apply version numbers for cdn
"shell:loadEnvVariables", # load aws keys for deployment
"s3:production" # publish files to s3 for cdn
]
else
["newer:jshint",
# run tests
"test",
# build alchemy
"build"]
2 changes: 1 addition & 1 deletion app/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
<script src="scripts/else.js"></script>
<script type="text/javascript">
var config = {
dataSource: 'sample_data/contrib.json',
dataSource: 'sample_data/contrib.json'
};

alchemy.begin(config)
Expand Down
2 changes: 1 addition & 1 deletion app/sample_data/contrib.json
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@
{
"source": 4,
"target": 0,
"caption": "Often Breaks"
"caption": "Often_Breaks"
},
{
"source": 5,
Expand Down
93 changes: 93 additions & 0 deletions app/scripts/alchemy/Alchemy.coffee
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
"""
Alchemy.js is a graph drawing application for the web.
Copyright (C) 2014 GraphAlchemist, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
lets
"""

class Alchemy
constructor: () ->
@version = "#VERSION#"
@layout = {}
@interactions = {}
@utils = {}
@visControls = {}
@styles = {}
@models = {}
@drawing = {}
@editor = {}

@log = {}
@state = {
"interactions": "default"
"layout": "default"
"filters": {
"edges": {},
"nodes": {}
}
}

getState: (key) =>
if @state.key?
@state.key

setState: (key, value) =>
@state.key = value

begin: (userConf) =>
@conf = _.assign({}, alchemy.defaults, userConf)
if typeof alchemy.conf.dataSource == 'string'
d3.json(alchemy.conf.dataSource, alchemy.startGraph)
else if typeof alchemy.conf.dataSource == 'object'
alchemy.startGraph(alchemy.conf.dataSource)

#API methods
getNodes: (id, ids...) =>
# returns one or more nodes as an array
if ids
ids.push(id)
params = _.union(ids)
results = []
for p in params
results.push(alchemy._nodes[p].properties)
results
else
[@_nodes[id].properties]

getEdges: (id=null, target=null) =>
# returns one or more edges as an array
if id? and target?
edge_id = "#{id}-#{target}"
edge = @_edges[edge_id]
[edge.properties]
else if id? and not target?
results = _.map(@_edges, (edge) ->
if (edge.properties.source is id) or (edge.properties.target is id)
edge.properties)
_.compact(results) # best way to do this?

allNodes: =>
_.map(@_nodes, (n) -> n.properties)

allEdges: =>
_.map(@_edges, (e) -> e.properties)


currentRelationshipTypes = {}

if typeof module isnt 'undefined' and module.exports
module.exports = new Alchemy()
else
@alchemy = new Alchemy()
Loading

0 comments on commit 0022106

Please sign in to comment.