├── .gitignore
├── bower.json
├── index.html
├── readme.adoc
├── scripts
├── codemirror-cypher.js
├── codemirror.js
├── cy2neod3.js
├── cypher.datatable.js
├── data.js
├── jquery.dataTables.min.js
├── neo4d3.js
├── neod3-visualization.js
├── neod3.js
├── sweet-alert.min.js
└── vendor.js
└── styles
├── codemirror-neo.css
├── codemirror.css
├── cy2neo.css
├── datatable.css
├── fonts
├── FontAwesome.otf
├── fontawesome-webfont.eot
├── fontawesome-webfont.svg
├── fontawesome-webfont.ttf
└── fontawesome-webfont.woff
├── gh-fork-ribbon.css
├── images
└── maze-black.png
├── neod3.css
├── sweet-alert.css
└── vendor.css
/.gitignore:
--------------------------------------------------------------------------------
1 | bower_components
2 | issues.txt
3 | node_modules
4 | .DS_Store
5 | *.map
6 |
--------------------------------------------------------------------------------
/bower.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "cy2neo",
3 | "version": "0.0.1",
4 | "authors": [
5 | "Michael Hunger "
6 | ],
7 | "description": "Cy2Neo Tiny Neo4j Cypher Workbench with Alchemy.js Viz",
8 | "main": "cy2neo.js",
9 | "keywords": [
10 | "neo4j",
11 | "cypher",
12 | "graph",
13 | "database",
14 | "repl",
15 | "shell",
16 | "console",
17 | "graphviz",
18 | "d3",
19 | "graph"
20 | ],
21 | "license": "MIT",
22 | "homepage": "http://jexp.github.io/cy2neo",
23 | "private": true,
24 | "ignore": [
25 | "**/.*",
26 | "node_modules",
27 | "bower_components",
28 | "test",
29 | "tests"
30 | ]
31 | }
32 |
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 | Cy2NeoD3 - Tiny Neo4j Cypher Workbench
12 |
13 |
14 |
25 |
26 |
27 |
28 |
29 |
33 |
34 |
35 |
43 |
44 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
73 |
74 |
--------------------------------------------------------------------------------
/readme.adoc:
--------------------------------------------------------------------------------
1 | == Cy2Neo - Tiny Neo4j Cypher Workbench with custom D3 Visualization
2 |
3 | Cy2Neo is a tiny *Neo4j query console*, in a single HTML-page using client-side JavaScript only.
4 |
5 | http://neo4j.com/developer[Neo4j] is an open source graph database and http://neo4j.com/developer/cypher[Cypher] is Neo4j's graph query language.
6 |
7 | Cypher queries are highlighted with http://codemirror.net/[CodeMirror].
8 |
9 | Graph query results are rendered with https://d3js.org/[D3] using a custom renderer based on neo4j's browser rendering that is https://github.com/jexp/cy2neo/blob/neod3/scripts/neod3.js[part of this project].
10 |
11 | Cy2Neo uses a simple Neo4j HTTP-connector that posts Cypher queries to Neo4j's transactional http://neo4j.com/docs/developer-manual/current/#rest-api-transactional[Cypher HTTP endpoint] using jQuery Ajax requests.
12 |
13 | You can http://jexp.github.io/cy2neo[try it live here], it should be able to connect to any Neo4j 2.x and 3.x instance that's accessible from your machine.
14 | Just enter the Neo4j-URL, username and password in the boxes on the right side.
15 |
16 | [NOTE]
17 | I wrote most of it while flying from OSCON 2014 in Portland,OR to Chicago on my way home to Dresden, Germany.
18 |
--------------------------------------------------------------------------------
/scripts/codemirror-cypher.js:
--------------------------------------------------------------------------------
1 | // Generated by CoffeeScript 1.6.3
2 | /*!
3 | Copyright (c) 2002-2014 "Neo Technology,"
4 | Network Engine for Objects in Lund AB [http://neotechnology.com]
5 |
6 | This file is part of Neo4j.
7 |
8 | Neo4j is free software: you can redistribute it and/or modify
9 | it under the terms of the GNU General Public License as published by
10 | the Free Software Foundation, either version 3 of the License, or
11 | (at your option) any later version.
12 |
13 | This program is distributed in the hope that it will be useful,
14 | but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 | GNU General Public License for more details.
17 |
18 | You should have received a copy of the GNU General Public License
19 | along with this program. If not, see .
20 | */
21 |
22 |
23 | (function() {
24 | var wordRegexp;
25 |
26 | wordRegexp = function(words) {
27 | return new RegExp("^(?:" + words.join("|") + ")$", "i");
28 | };
29 |
30 | CodeMirror.defineMode("cypher", function(config) {
31 | var curPunc, funcs, indentUnit, keywords, operatorChars, popContext, preds, pushContext, tokenBase, tokenLiteral;
32 | tokenBase = function(stream, state) {
33 | var ch, curPunc, type, word;
34 | ch = stream.next();
35 | curPunc = null;
36 | if (ch === "\"" || ch === "'") {
37 | stream.match(/.+?["']/);
38 | return "string";
39 | }
40 | if (/[{}\(\),\.;\[\]]/.test(ch)) {
41 | curPunc = ch;
42 | return "node";
43 | } else if (ch === "/" && stream.eat("/")) {
44 | stream.skipToEnd();
45 | return "comment";
46 | } else if (operatorChars.test(ch)) {
47 | stream.eatWhile(operatorChars);
48 | return null;
49 | } else {
50 | stream.eatWhile(/[_\w\d]/);
51 | if (stream.eat(":")) {
52 | stream.eatWhile(/[\w\d_\-]/);
53 | return "atom";
54 | }
55 | word = stream.current();
56 | type = void 0;
57 | if (funcs.test(word)) {
58 | return "builtin";
59 | }
60 | if (preds.test(word)) {
61 | return "def";
62 | } else if (keywords.test(word)) {
63 | return "keyword";
64 | } else {
65 | return "variable";
66 | }
67 | }
68 | };
69 | tokenLiteral = function(quote) {
70 | return function(stream, state) {
71 | var ch, escaped;
72 | escaped = false;
73 | ch = void 0;
74 | while ((ch = stream.next()) != null) {
75 | if (ch === quote && !escaped) {
76 | state.tokenize = tokenBase;
77 | break;
78 | }
79 | escaped = !escaped && ch === "\\";
80 | }
81 | return "string";
82 | };
83 | };
84 | pushContext = function(state, type, col) {
85 | return state.context = {
86 | prev: state.context,
87 | indent: state.indent,
88 | col: col,
89 | type: type
90 | };
91 | };
92 | popContext = function(state) {
93 | state.indent = state.context.indent;
94 | return state.context = state.context.prev;
95 | };
96 | indentUnit = config.indentUnit;
97 | curPunc = void 0;
98 | funcs = wordRegexp(["abs", "acos", "allShortestPaths", "asin", "atan", "atan2", "avg", "ceil", "coalesce", "collect", "cos", "cot", "count", "degrees", "e", "endnode", "exp", "extract", "filter", "floor", "haversin", "head", "id", "labels", "last", "left", "length", "log", "log10", "lower", "ltrim", "max", "min", "node", "nodes", "percentileCont", "percentileDisc", "pi", "radians", "rand", "range", "reduce", "rel", "relationship", "relationships", "replace", "right", "round", "rtrim", "shortestPath", "sign", "sin", "split", "sqrt", "startnode", "stdev", "stdevp", "str", "substring", "sum", "tail", "tan", "timestamp", "toFloat", "toInt", "trim", "type", "upper"]);
99 | preds = wordRegexp(["all", "and", "any", "has", "in", "none", "not", "or", "single", "xor"]);
100 | keywords = wordRegexp(["as", "asc", "ascending", "assert", "by", "case", "commit", "constraint", "create", "csv", "cypher", "delete", "desc", "descending", "distinct", "drop", "else", "end", "false", "foreach", "from", "headers", "in", "index", "is", "limit", "load", "match", "merge", "null", "on", "optional", "order", "periodic", "remove", "return", "scan", "set", "skip", "start", "then", "true", "union", "unique", "using", "when", "where", "with"]);
101 | operatorChars = /[*+\-<>=&|~%^]/;
102 | return {
103 | startState: function(base) {
104 | return {
105 | tokenize: tokenBase,
106 | context: null,
107 | indent: 0,
108 | col: 0
109 | };
110 | },
111 | token: function(stream, state) {
112 | var style;
113 | if (stream.sol()) {
114 | if (state.context && (state.context.align == null)) {
115 | state.context.align = false;
116 | }
117 | state.indent = stream.indentation();
118 | }
119 | if (stream.eatSpace()) {
120 | return null;
121 | }
122 | style = state.tokenize(stream, state);
123 | if (style !== "comment" && state.context && (state.context.align == null) && state.context.type !== "pattern") {
124 | state.context.align = true;
125 | }
126 | if (curPunc === "(") {
127 | pushContext(state, ")", stream.column());
128 | } else if (curPunc === "[") {
129 | pushContext(state, "]", stream.column());
130 | } else if (curPunc === "{") {
131 | pushContext(state, "}", stream.column());
132 | } else if (/[\]\}\)]/.test(curPunc)) {
133 | while (state.context && state.context.type === "pattern") {
134 | popContext(state);
135 | }
136 | if (state.context && curPunc === state.context.type) {
137 | popContext(state);
138 | }
139 | } else if (curPunc === "." && state.context && state.context.type === "pattern") {
140 | popContext(state);
141 | } else if (/atom|string|variable/.test(style) && state.context) {
142 | if (/[\}\]]/.test(state.context.type)) {
143 | pushContext(state, "pattern", stream.column());
144 | } else if (state.context.type === "pattern" && !state.context.align) {
145 | state.context.align = true;
146 | state.context.col = stream.column();
147 | }
148 | }
149 | return style;
150 | },
151 | indent: function(state, textAfter) {
152 | var closing, context, firstChar;
153 | firstChar = textAfter && textAfter.charAt(0);
154 | context = state.context;
155 | if (/[\]\}]/.test(firstChar)) {
156 | while (context && context.type === "pattern") {
157 | context = context.prev;
158 | }
159 | }
160 | closing = context && firstChar === context.type;
161 | if (!context) {
162 | return 0;
163 | } else if (context.type === "keywords") {
164 | return newlineAndIndent;
165 | } else if (context.align) {
166 | return context.col + (closing ? 0 : 1);
167 | } else {
168 | return context.indent + (closing ? 0 : indentUnit);
169 | }
170 | }
171 | };
172 | });
173 |
174 | CodeMirror.modeExtensions["cypher"] = {
175 | autoFormatLineBreaks: function(text) {
176 | var i, lines, reProcessedPortion;
177 | lines = text.split("\n");
178 | reProcessedPortion = /\s+\b(return|where|order by|match|with|skip|limit|create|delete|set)\b\s/g;
179 | i = 0;
180 | while (i < lines.length) {
181 | lines[i] = lines[i].replace(reProcessedPortion, " \n$1 ").trim();
182 | i++;
183 | }
184 | return lines.join("\n");
185 | }
186 | };
187 |
188 | CodeMirror.defineMIME("application/x-cypher-query", "cypher");
189 |
190 | }).call(this);
191 |
--------------------------------------------------------------------------------
/scripts/cy2neod3.js:
--------------------------------------------------------------------------------
1 | function Cy2NeoD3(config, graphId, tableId, sourceId, execId, urlSource, renderGraph, cbResult) {
2 | function createEditor() {
3 | return CodeMirror.fromTextArea(document.getElementById(sourceId), {
4 | parserfile: ["codemirror-cypher.js"],
5 | path: "scripts",
6 | stylesheet: "styles/codemirror-neo.css",
7 | autoMatchParens: true,
8 | lineNumbers: true,
9 | enterMode: "keep",
10 | value: "some value"
11 | });
12 | }
13 | var neod3 = new Neod3Renderer();
14 | var neo = new Neo(urlSource);
15 | var editor = createEditor();
16 | $("#"+execId).click(function(evt) {
17 | try {
18 | evt.preventDefault();
19 | var query = editor.getValue();
20 | console.log("Executing Query",query);
21 | var execButton = $(this).find('i');
22 | execButton.toggleClass('fa-play-circle-o fa-spinner fa-spin')
23 | neo.executeQuery(query,{},function(err,res) {
24 | execButton.toggleClass('fa-spinner fa-spin fa-play-circle-o')
25 | res = res || {}
26 | var graph=res.graph;
27 | if (renderGraph) {
28 | if (graph) {
29 | var c=$("#"+graphId);
30 | c.empty();
31 | neod3.render(graphId, c ,graph);
32 | renderResult(tableId, res.table);
33 | } else {
34 | if (err) {
35 | console.log(err);
36 | if (err.length > 0) {
37 | sweetAlert("Cypher error", err[0].code + "\n" + err[0].message, "error");
38 | } else {
39 | sweetAlert("Ajax " + err.statusText, "Status " + err.status + ": " + err.state(), "error");
40 | }
41 | }
42 | }
43 | }
44 | if(cbResult) cbResult(res);
45 | });
46 | } catch(e) {
47 | console.log(e);
48 | sweetAlert("Catched error", e, "error");
49 | }
50 | return false;
51 | });
52 | }
53 |
--------------------------------------------------------------------------------
/scripts/cypher.datatable.js:
--------------------------------------------------------------------------------
1 | function convertResult(data) {
2 | var charWidth = 14;
3 | var result = { columns: [], data: []};
4 | var columns = Object.keys(data[0]);
5 | var count = columns.length;
6 | var rows = data.length;
7 | for (var col = 0; col < count; col++) {
8 | result.columns[col] = {"sTitle": columns[col], sWidth: columns[col].length * charWidth};
9 | }
10 | for (var row = 0; row < rows; row++) {
11 | var currentRow = data[row];
12 | var newRow = [];
13 | for (var col = 0; col < count; col++) {
14 | var value = convertCell(currentRow[columns[col]]);
15 | newRow[col] = value;
16 | result.columns[col].sWidth = Math.max(value.length * charWidth, result.columns[col].sWidth);
17 | }
18 | result.data[row] = newRow;
19 | }
20 | var width = 0;
21 | for (var col = 0; col < count; col++) {
22 | width += result.columns[col].sWidth;
23 | }
24 | var windowWith = $(window).width() / 2;
25 | for (var col = 0; col < count; col++) {
26 | // result.columns[col].sWidth=windowWith * result.columns[col].sWidth / width;
27 | result.columns[col].sWidth = "" + Math.round(100 * result.columns[col].sWidth / width) + "%";
28 | // console.log(result.columns[col].sWidth);
29 | }
30 | return result;
31 | }
32 |
33 | function convertCell(cell) {
34 | if (cell == null) return "";
35 | if (cell instanceof Array) {
36 | var result = [];
37 | for (var i = 0; i < cell.length; i++) {
38 | result.push(convertCell(cell[i]));
39 | }
40 | return "[" + result.join(", ") + "]";
41 | }
42 | if (cell instanceof Object) {
43 | if (cell["_type"]) {
44 | return "(" + cell["_start"] + ")-[" + cell["_id"] + ":" + cell["_type"] + props(cell) + "]->(" + cell["_end"] + ")";
45 | } else
46 | if (typeof(cell["_id"]) !== "undefined") {
47 | var labels = "";
48 | if (cell["_labels"]) {
49 | labels = ":" + cell["_labels"].join(":");
50 | }
51 | return "(" + cell["_id"] + labels + props(cell) + ")";
52 | }
53 | return props(cell);
54 | }
55 | return cell;
56 | }
57 |
58 | function props(cell) {
59 | var props = [];
60 | for (key in cell) {
61 | if (cell.hasOwnProperty(key) && key[0] != '_') {
62 | props.push([key] + ":" + JSON.stringify(cell[key]));
63 | }
64 | }
65 | return props.length ? " {" + props.join(", ") + "}" : "";
66 | }
67 |
68 | function renderResult(id, data) {
69 | if (!data || !data.length) return;
70 | var result = convertResult(data);
71 | var table = $('').appendTo($("#" + id));
72 | var large = result.data.length > 10;
73 | var dataTable = table.dataTable({
74 | aoColumns: result.columns,
75 | bFilter: large,
76 | bInfo: large,
77 | bLengthChange: large,
78 | bPaginate: large,
79 | aaData: result.data,
80 | // bAutoWidth: true,
81 | aLengthMenu: [
82 | [10, 25, 50, -1],
83 | [10, 25, 50, "All"]
84 | ],
85 | aaSorting: [],
86 | bSortable: true,
87 | oLanguage: {
88 | oPaginate: {
89 | sNext: " >> ",
90 | sPrevious: " << "
91 | }
92 | }
93 | });
94 | }
95 |
--------------------------------------------------------------------------------
/scripts/data.js:
--------------------------------------------------------------------------------
1 | var graph = {
2 | "nodes": [
3 | {
4 | "caption": "Screen Actors Guild Award for Outstanding Performance by a Female Actor in a Miniseries or Television Movie",
5 | "type": "award",
6 | "id": 595472
7 | },
8 | {
9 | "caption": "Children of the Corn III: Urban Harvest",
10 | "type": "movie",
11 | "id": 626470
12 | },
13 | {
14 | "caption": "Sleepwalking",
15 | "type": "movie",
16 | "id": 795744
17 | },
18 | {
19 | "caption": "That Thing You Do!",
20 | "type": "movie",
21 | "id": 692946
22 | },
23 | {
24 | "caption": "Trapped",
25 | "type": "movie",
26 | "id": 689794
27 | },
28 | {
29 | "caption": "Head in the Clouds",
30 | "type": "movie",
31 | "id": 709577
32 | },
33 | {
34 | "caption": "Waking Up in Reno",
35 | "type": "movie",
36 | "id": 635905
37 | },
38 | {
39 | "caption": "Battle in Seattle",
40 | "type": "movie",
41 | "id": 734583
42 | },
43 | {
44 | "caption": "Mighty Joe Young",
45 | "type": "movie",
46 | "id": 662595
47 | },
48 | {
49 | "caption": "Academy Award for Actress in a Leading Role",
50 | "type": "award",
51 | "id": 593781
52 | },
53 | {
54 | "caption": "The Devil's Advocate",
55 | "type": "movie",
56 | "id": 740763
57 | },
58 | {
59 | "caption": "Screen Actors Guild Award for Outstanding Performance by a Cast in a Motion Picture",
60 | "type": "award",
61 | "id": 595440
62 | },
63 | {
64 | "caption": "Silver Bear for Best Actress",
65 | "type": "award",
66 | "id": 601507
67 | },
68 | {
69 | "caption": "The Curse of the Jade Scorpion",
70 | "type": "movie",
71 | "id": 649461
72 | },
73 | {
74 | "caption": "MTV Movie Award for Best Female Performance",
75 | "type": "award",
76 | "id": 595074
77 | },
78 | {
79 | "caption": "15 Minutes",
80 | "type": "movie",
81 | "id": 634248
82 | },
83 | {
84 | "caption": "The Burning Plain",
85 | "type": "movie",
86 | "id": 670704
87 | },
88 | {
89 | "caption": "The Life and Death of Peter Sellers",
90 | "type": "movie",
91 | "id": 794982
92 | },
93 | {
94 | "caption": "Prometheus",
95 | "type": "movie",
96 | "id": 608746
97 | },
98 | {
99 | "caption": "Teen Choice Award for Choice Summer Movie Star: Female",
100 | "type": "award",
101 | "id": 599909
102 | },
103 | {
104 | "caption": "Chicago Film Critics Association Award for Best Actress",
105 | "type": "award",
106 | "id": 623686
107 | },
108 | {
109 | "caption": "Golden Globe Award for Best Supporting Actress - Series, Miniseries or Television Film",
110 | "type": "award",
111 | "id": 598027
112 | },
113 | {
114 | "caption": "Golden Globe Award for Best Actress - Musical or Comedy Film",
115 | "type": "award",
116 | "id": 595206
117 | },
118 | {
119 | "caption": "Mad Max: Fury Road",
120 | "type": "movie",
121 | "id": 804341
122 | },
123 | {
124 | "caption": "In the Valley of Elah",
125 | "type": "movie",
126 | "id": 621675
127 | },
128 | {
129 | "caption": "Screen Actors Guild Award for Outstanding Performance by a Female Actor in a Leading Role",
130 | "type": "award",
131 | "id": 593954
132 | },
133 | {
134 | "caption": "Golden Raspberry Award for Worst Actress",
135 | "type": "award",
136 | "id": 594134
137 | },
138 | {
139 | "caption": "East of Havana",
140 | "type": "movie",
141 | "id": 609415
142 | },
143 | {
144 | "caption": "The Road",
145 | "type": "movie",
146 | "id": 627715
147 | },
148 | {
149 | "caption": "Golden Globe Award for Best Actress - Drama Film",
150 | "type": "award",
151 | "id": 593776
152 | },
153 | {
154 | "caption": "Charles Jacobus Theron",
155 | "type": "person",
156 | "id": 314008
157 | },
158 | {
159 | "caption": "Jackson Theron",
160 | "type": "person",
161 | "id": 314009
162 | },
163 | {
164 | "caption": "Primetime Emmy Award for Outstanding Supporting Actress in a Miniseries or a Movie",
165 | "type": "award",
166 | "id": 595684
167 | },
168 | {
169 | "caption": "The Cider House Rules",
170 | "type": "movie",
171 | "id": 801237
172 | },
173 | {
174 | "caption": "The Astronaut's Wife",
175 | "type": "movie",
176 | "id": 657006
177 | },
178 | {
179 | "caption": "Broadcast Film Critics Association Award for Best Actress",
180 | "type": "award",
181 | "id": 601849
182 | },
183 | {
184 | "caption": "Hancock",
185 | "type": "movie",
186 | "id": 652245
187 | },
188 | {
189 | "caption": "Charlize Theron",
190 | "root": true,
191 | "id": 314003
192 | },
193 | {
194 | "caption": "Stuart Townsend",
195 | "type": "person",
196 | "id": 314004
197 | },
198 | {
199 | "caption": "Stephan Jenkins",
200 | "type": "person",
201 | "id": 314005
202 | },
203 | {
204 | "caption": "Benoni, Gauteng",
205 | "type": "person",
206 | "id": 314006
207 | },
208 | {
209 | "caption": "Gerda Jacoba Aletta Maritz",
210 | "type": "person",
211 | "id": 314007
212 | },
213 | {
214 | "caption": "Æon Flux",
215 | "type": "movie",
216 | "id": 663286
217 | },
218 | {
219 | "caption": "Snow White and the Huntsman",
220 | "type": "movie",
221 | "id": 599907
222 | },
223 | {
224 | "caption": "Young Adult",
225 | "type": "movie",
226 | "id": 661733
227 | },
228 | {
229 | "caption": "Reindeer Games",
230 | "type": "movie",
231 | "id": 761000
232 | },
233 | {
234 | "caption": "Monster",
235 | "type": "movie",
236 | "id": 729778
237 | },
238 | {
239 | "caption": "The Legend of Bagger Vance",
240 | "type": "movie",
241 | "id": 804616
242 | },
243 | {
244 | "caption": "Teen Choice Award for Choice Hissy Fit: Film",
245 | "type": "award",
246 | "id": 599908
247 | },
248 | {
249 | "caption": "The Yards",
250 | "type": "movie",
251 | "id": 781638
252 | },
253 | {
254 | "caption": "MTV Movie Award for Best Kiss",
255 | "type": "award",
256 | "id": 595095
257 | },
258 | {
259 | "caption": "Celebrity",
260 | "type": "movie",
261 | "id": 611629
262 | },
263 | {
264 | "caption": "Astro Boy",
265 | "type": "movie",
266 | "id": 818608
267 | },
268 | {
269 | "caption": "North Country",
270 | "type": "movie",
271 | "id": 784437
272 | },
273 | {
274 | "caption": "2 Days in the Valley",
275 | "type": "movie",
276 | "id": 615556
277 | },
278 | {
279 | "caption": "Satellite Award for Best Actress – Motion Picture",
280 | "type": "award",
281 | "id": 595704
282 | },
283 | {
284 | "caption": "Trial and Error",
285 | "type": "movie",
286 | "id": 799574
287 | },
288 | {
289 | "caption": "National Society of Film Critics Award for Best Actress",
290 | "type": "award",
291 | "id": 595702
292 | },
293 | {
294 | "caption": "Independent Spirit Award for Best Female Lead",
295 | "type": "award",
296 | "id": 595703
297 | },
298 | {
299 | "caption": "Two Eyes Staring",
300 | "type": "movie",
301 | "id": 788889
302 | },
303 | {
304 | "caption": "Sweet November",
305 | "type": "movie",
306 | "id": 811358
307 | },
308 | {
309 | "caption": "Teen Choice Movie Award: Villain",
310 | "type": "award",
311 | "id": 595082
312 | },
313 | {
314 | "caption": "Satellite Award for Best Supporting Actress – Drama",
315 | "type": "award",
316 | "id": 602151
317 | },
318 | {
319 | "caption": "San Francisco Film Critics Circle Award for Best Actress",
320 | "type": "award",
321 | "id": 669827
322 | },
323 | {
324 | "caption": "Independent Spirit Award for Best First Feature",
325 | "type": "award",
326 | "id": 599387
327 | },
328 | {
329 | "caption": "The Italian Job",
330 | "type": "movie",
331 | "id": 817380
332 | },
333 | {
334 | "caption": "Hollywood Confidential",
335 | "type": "movie",
336 | "id": 711550
337 | },
338 | {
339 | "caption": "Men of Honor",
340 | "type": "movie",
341 | "id": 682763
342 | },
343 | {
344 | "caption": "BAFTA Award for Best Actress in a Leading Role",
345 | "type": "award",
346 | "id": 594478
347 | }
348 | ],
349 | "edges": [
350 | {
351 | "source": 314003,
352 | "target": 621675,
353 | "caption": "ACTED_IN"
354 | },
355 | {
356 | "source": 314003,
357 | "target": 818608,
358 | "caption": "ACTED_IN"
359 | },
360 | {
361 | "source": 314003,
362 | "target": 601849,
363 | "caption": "NOMINATED"
364 | },
365 | {
366 | "source": 314003,
367 | "target": 649461,
368 | "caption": "ACTED_IN"
369 | },
370 | {
371 | "source": 314003,
372 | "target": 669827,
373 | "caption": "RECEIVED"
374 | },
375 | {
376 | "source": 314003,
377 | "target": 608746,
378 | "caption": "ACTED_IN"
379 | },
380 | {
381 | "source": 314003,
382 | "target": 593954,
383 | "caption": "RECEIVED"
384 | },
385 | {
386 | "source": 314003,
387 | "target": 595702,
388 | "caption": "NOMINATED"
389 | },
390 | {
391 | "source": 314003,
392 | "target": 601849,
393 | "caption": "RECEIVED"
394 | },
395 | {
396 | "source": 314003,
397 | "target": 595095,
398 | "caption": "NOMINATED"
399 | },
400 | {
401 | "source": 314003,
402 | "target": 729778,
403 | "caption": "ACTED_IN"
404 | },
405 | {
406 | "source": 314003,
407 | "target": 595703,
408 | "caption": "NOMINATED"
409 | },
410 | {
411 | "source": 314003,
412 | "target": 811358,
413 | "caption": "ACTED_IN"
414 | },
415 | {
416 | "source": 314003,
417 | "target": 595472,
418 | "caption": "NOMINATED"
419 | },
420 | {
421 | "source": 314003,
422 | "target": 661733,
423 | "caption": "PRODUCED"
424 | },
425 | {
426 | "source": 314003,
427 | "target": 784437,
428 | "caption": "ACTED_IN"
429 | },
430 | {
431 | "source": 314003,
432 | "target": 634248,
433 | "caption": "ACTED_IN"
434 | },
435 | {
436 | "source": 314003,
437 | "target": 662595,
438 | "caption": "ACTED_IN"
439 | },
440 | {
441 | "source": 314003,
442 | "target": 804616,
443 | "caption": "ACTED_IN"
444 | },
445 | {
446 | "source": 314003,
447 | "target": 595703,
448 | "caption": "RECEIVED"
449 | },
450 | {
451 | "source": 314003,
452 | "target": 626470,
453 | "caption": "ACTED_IN"
454 | },
455 | {
456 | "source": 314003,
457 | "target": 599387,
458 | "caption": "RECEIVED"
459 | },
460 | {
461 | "source": 314003,
462 | "target": 599908,
463 | "caption": "RECEIVED"
464 | },
465 | {
466 | "source": 314003,
467 | "target": 682763,
468 | "caption": "ACTED_IN"
469 | },
470 | {
471 | "source": 314003,
472 | "target": 595702,
473 | "caption": "RECEIVED"
474 | },
475 | {
476 | "source": 314003,
477 | "target": 788889,
478 | "caption": "ACTED_IN"
479 | },
480 | {
481 | "source": 314003,
482 | "target": 657006,
483 | "caption": "ACTED_IN"
484 | },
485 | {
486 | "source": 314003,
487 | "target": 795744,
488 | "caption": "ACTED_IN"
489 | },
490 | {
491 | "source": 314003,
492 | "target": 593781,
493 | "caption": "RECEIVED"
494 | },
495 | {
496 | "source": 314003,
497 | "target": 594478,
498 | "caption": "NOMINATED"
499 | },
500 | {
501 | "source": 314003,
502 | "target": 594134,
503 | "caption": "NOMINATED"
504 | },
505 | {
506 | "source": 314003,
507 | "target": 595074,
508 | "caption": "NOMINATED"
509 | },
510 | {
511 | "source": 314003,
512 | "target": 692946,
513 | "caption": "ACTED_IN"
514 | },
515 | {
516 | "source": 314003,
517 | "target": 740763,
518 | "caption": "ACTED_IN"
519 | },
520 | {
521 | "source": 314005,
522 | "target": 314003,
523 | "caption": "PARTNER_OF"
524 | },
525 | {
526 | "source": 314003,
527 | "target": 711550,
528 | "caption": "ACTED_IN"
529 | },
530 | {
531 | "source": 314003,
532 | "target": 595440,
533 | "caption": "NOMINATED"
534 | },
535 | {
536 | "source": 314003,
537 | "target": 801237,
538 | "caption": "ACTED_IN"
539 | },
540 | {
541 | "source": 314003,
542 | "target": 599907,
543 | "caption": "ACTED_IN"
544 | },
545 | {
546 | "source": 314003,
547 | "target": 761000,
548 | "caption": "ACTED_IN"
549 | },
550 | {
551 | "source": 314003,
552 | "target": 781638,
553 | "caption": "ACTED_IN"
554 | },
555 | {
556 | "source": 314003,
557 | "target": 670704,
558 | "caption": "ACTED_IN"
559 | },
560 | {
561 | "source": 314003,
562 | "target": 609415,
563 | "caption": "PRODUCED"
564 | },
565 | {
566 | "source": 314003,
567 | "target": 314009,
568 | "caption": "PARENT_OF"
569 | },
570 | {
571 | "source": 314003,
572 | "target": 652245,
573 | "caption": "ACTED_IN"
574 | },
575 | {
576 | "source": 314003,
577 | "target": 661733,
578 | "caption": "ACTED_IN"
579 | },
580 | {
581 | "source": 314003,
582 | "target": 602151,
583 | "caption": "NOMINATED"
584 | },
585 | {
586 | "source": 314003,
587 | "target": 635905,
588 | "caption": "ACTED_IN"
589 | },
590 | {
591 | "source": 314003,
592 | "target": 799574,
593 | "caption": "ACTED_IN"
594 | },
595 | {
596 | "source": 314003,
597 | "target": 593781,
598 | "caption": "NOMINATED"
599 | },
600 | {
601 | "source": 314003,
602 | "target": 817380,
603 | "caption": "ACTED_IN"
604 | },
605 | {
606 | "source": 314003,
607 | "target": 611629,
608 | "caption": "ACTED_IN"
609 | },
610 | {
611 | "source": 314003,
612 | "target": 729778,
613 | "caption": "PRODUCED"
614 | },
615 | {
616 | "source": 314003,
617 | "target": 709577,
618 | "caption": "ACTED_IN"
619 | },
620 | {
621 | "source": 314003,
622 | "target": 804341,
623 | "caption": "ACTED_IN"
624 | },
625 | {
626 | "source": 314003,
627 | "target": 627715,
628 | "caption": "ACTED_IN"
629 | },
630 | {
631 | "source": 314003,
632 | "target": 794982,
633 | "caption": "ACTED_IN"
634 | },
635 | {
636 | "source": 314003,
637 | "target": 623686,
638 | "caption": "RECEIVED"
639 | },
640 | {
641 | "source": 314003,
642 | "target": 595082,
643 | "caption": "NOMINATED"
644 | },
645 | {
646 | "source": 314003,
647 | "target": 689794,
648 | "caption": "ACTED_IN"
649 | },
650 | {
651 | "source": 314003,
652 | "target": 788889,
653 | "caption": "PRODUCED"
654 | },
655 | {
656 | "source": 314007,
657 | "target": 314003,
658 | "caption": "PARENT_OF"
659 | },
660 | {
661 | "source": 314003,
662 | "target": 593776,
663 | "caption": "NOMINATED"
664 | },
665 | {
666 | "source": 314003,
667 | "target": 734583,
668 | "caption": "ACTED_IN"
669 | },
670 | {
671 | "source": 314003,
672 | "target": 598027,
673 | "caption": "NOMINATED"
674 | },
675 | {
676 | "source": 314003,
677 | "target": 601507,
678 | "caption": "RECEIVED"
679 | },
680 | {
681 | "source": 314003,
682 | "target": 599909,
683 | "caption": "NOMINATED"
684 | },
685 | {
686 | "source": 314003,
687 | "target": 314004,
688 | "caption": "PARTNER_OF"
689 | },
690 | {
691 | "source": 314003,
692 | "target": 663286,
693 | "caption": "ACTED_IN"
694 | },
695 | {
696 | "source": 314003,
697 | "target": 314006,
698 | "caption": "BORN_AT"
699 | },
700 | {
701 | "source": 314003,
702 | "target": 615556,
703 | "caption": "ACTED_IN"
704 | },
705 | {
706 | "source": 314004,
707 | "target": 314003,
708 | "caption": "PARTNER_OF"
709 | },
710 | {
711 | "source": 314008,
712 | "target": 314003,
713 | "caption": "PARENT_OF"
714 | },
715 | {
716 | "source": 314003,
717 | "target": 314005,
718 | "caption": "PARTNER_OF"
719 | },
720 | {
721 | "source": 314003,
722 | "target": 795744,
723 | "caption": "PRODUCED"
724 | },
725 | {
726 | "source": 314003,
727 | "target": 595704,
728 | "caption": "RECEIVED"
729 | },
730 | {
731 | "source": 314003,
732 | "target": 670704,
733 | "caption": "EXEC_PRODUCED"
734 | },
735 | {
736 | "source": 314003,
737 | "target": 593954,
738 | "caption": "NOMINATED"
739 | },
740 | {
741 | "source": 314003,
742 | "target": 595206,
743 | "caption": "NOMINATED"
744 | },
745 | {
746 | "source": 314003,
747 | "target": 593776,
748 | "caption": "RECEIVED"
749 | },
750 | {
751 | "source": 314003,
752 | "target": 595704,
753 | "caption": "NOMINATED"
754 | },
755 | {
756 | "source": 314003,
757 | "target": 595684,
758 | "caption": "NOMINATED"
759 | },
760 | {
761 | "source": 314003,
762 | "target": 599387,
763 | "caption": "NOMINATED"
764 | }
765 | ]
766 | }
--------------------------------------------------------------------------------
/scripts/jquery.dataTables.min.js:
--------------------------------------------------------------------------------
1 | /*
2 | * File: jquery.dataTables.min.js
3 | * Version: 1.9.4
4 | * Author: Allan Jardine (www.sprymedia.co.uk)
5 | * Info: www.datatables.net
6 | *
7 | * Copyright 2008-2012 Allan Jardine, all rights reserved.
8 | *
9 | * This source file is free software, under either the GPL v2 license or a
10 | * BSD style license, available at:
11 | * http://datatables.net/license_gpl2
12 | * http://datatables.net/license_bsd
13 | *
14 | * This source file is distributed in the hope that it will be useful, but
15 | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16 | * or FITNESS FOR A PARTICULAR PURPOSE. See the license files for details.
17 | */
18 | (function(la,s,p){(function(i){if(typeof define==="function"&&define.amd)define(["jquery"],i);else jQuery&&!jQuery.fn.dataTable&&i(jQuery)})(function(i){var l=function(h){function n(a,b){var c=l.defaults.columns,d=a.aoColumns.length;b=i.extend({},l.models.oColumn,c,{sSortingClass:a.oClasses.sSortable,sSortingClassJUI:a.oClasses.sSortJUI,nTh:b?b:s.createElement("th"),sTitle:c.sTitle?c.sTitle:b?b.innerHTML:"",aDataSort:c.aDataSort?c.aDataSort:[d],mData:c.mData?c.oDefaults:d});a.aoColumns.push(b);if(a.aoPreSearchCols[d]===
19 | p||a.aoPreSearchCols[d]===null)a.aoPreSearchCols[d]=i.extend({},l.models.oSearch);else{b=a.aoPreSearchCols[d];if(b.bRegex===p)b.bRegex=true;if(b.bSmart===p)b.bSmart=true;if(b.bCaseInsensitive===p)b.bCaseInsensitive=true}q(a,d,null)}function q(a,b,c){var d=a.aoColumns[b];if(c!==p&&c!==null){if(c.mDataProp&&!c.mData)c.mData=c.mDataProp;if(c.sType!==p){d.sType=c.sType;d._bAutoType=false}i.extend(d,c);r(d,c,"sWidth","sWidthOrig");if(c.iDataSort!==p)d.aDataSort=[c.iDataSort];r(d,c,"aDataSort")}var e=d.mRender?
20 | ca(d.mRender):null,f=ca(d.mData);d.fnGetData=function(g,j){var k=f(g,j);if(d.mRender&&j&&j!=="")return e(k,j,g);return k};d.fnSetData=Ja(d.mData);if(!a.oFeatures.bSort)d.bSortable=false;if(!d.bSortable||i.inArray("asc",d.asSorting)==-1&&i.inArray("desc",d.asSorting)==-1){d.sSortingClass=a.oClasses.sSortableNone;d.sSortingClassJUI=""}else if(i.inArray("asc",d.asSorting)==-1&&i.inArray("desc",d.asSorting)==-1){d.sSortingClass=a.oClasses.sSortable;d.sSortingClassJUI=a.oClasses.sSortJUI}else if(i.inArray("asc",
21 | d.asSorting)!=-1&&i.inArray("desc",d.asSorting)==-1){d.sSortingClass=a.oClasses.sSortableAsc;d.sSortingClassJUI=a.oClasses.sSortJUIAscAllowed}else if(i.inArray("asc",d.asSorting)==-1&&i.inArray("desc",d.asSorting)!=-1){d.sSortingClass=a.oClasses.sSortableDesc;d.sSortingClassJUI=a.oClasses.sSortJUIDescAllowed}}function o(a){if(a.oFeatures.bAutoWidth===false)return false;ta(a);for(var b=0,c=a.aoColumns.length;b=0;e--){var m=b[e].aTargets;i.isArray(m)||O(a,1,"aTargets must be an array of targets, not a "+typeof m);f=0;for(g=m.length;f=0){for(;a.aoColumns.length<=m[f];)n(a);d(m[f],b[e])}else if(typeof m[f]==="number"&&m[f]<0)d(a.aoColumns.length+m[f],b[e]);else if(typeof m[f]===
24 | "string"){j=0;for(k=a.aoColumns.length;jb&&a[d]--;c!=-1&&a.splice(c,1)}function da(a,b,c){var d=a.aoColumns[c];return d.fnRender({iDataRow:b,iDataColumn:c,oSettings:a,
33 | aData:a.aoData[b]._aData,mDataProp:d.mData},F(a,b,c,"display"))}function ua(a,b){var c=a.aoData[b],d;if(c.nTr===null){c.nTr=s.createElement("tr");c.nTr._DT_RowIndex=b;if(c._aData.DT_RowId)c.nTr.id=c._aData.DT_RowId;if(c._aData.DT_RowClass)c.nTr.className=c._aData.DT_RowClass;for(var e=0,f=a.aoColumns.length;e=0;f--)!a.aoColumns[f].bVisible&&!c&&g[d].splice(f,1);j.push([])}d=0;for(e=g.length;d=a.fnRecordsDisplay()?0:a.iInitDisplayStart;a.iInitDisplayStart=-1;I(a)}if(a.bDeferLoading){a.bDeferLoading=false;a.iDraw++}else if(a.oFeatures.bServerSide){if(!a.bDestroying&&!La(a))return}else a.iDraw++;if(a.aiDisplay.length!==0){var g=a._iDisplayStart;d=a._iDisplayEnd;if(a.oFeatures.bServerSide){g=0;d=a.aoData.length}for(g=g;g")[0];a.nTable.parentNode.insertBefore(b,a.nTable);a.nTableWrapper=i('')[0];a.nTableReinsertBefore=a.nTable.nextSibling;for(var c=a.nTableWrapper,d=a.sDom.split(""),e,f,g,j,k,m,u,x=0;x")[0];k=d[x+1];if(k=="'"||k=='"'){m="";for(u=2;d[x+u]!=k;){m+=d[x+u];u++}if(m=="H")m=a.oClasses.sJUIHeader;else if(m=="F")m=a.oClasses.sJUIFooter;if(m.indexOf(".")!=-1){k=
44 | m.split(".");j.id=k[0].substr(1,k[0].length-1);j.className=k[1]}else if(m.charAt(0)=="#")j.id=m.substr(1,m.length-1);else j.className=m;x+=u}c.appendChild(j);c=j}else if(g==">")c=c.parentNode;else if(g=="l"&&a.oFeatures.bPaginate&&a.oFeatures.bLengthChange){e=Na(a);f=1}else if(g=="f"&&a.oFeatures.bFilter){e=Oa(a);f=1}else if(g=="r"&&a.oFeatures.bProcessing){e=Pa(a);f=1}else if(g=="t"){e=Qa(a);f=1}else if(g=="i"&&a.oFeatures.bInfo){e=Ra(a);f=1}else if(g=="p"&&a.oFeatures.bPaginate){e=Sa(a);f=1}else if(l.ext.aoFeatures.length!==
45 | 0){j=l.ext.aoFeatures;u=0;for(k=j.length;u'):c===""?'':c+' ';var d=s.createElement("div");d.className=a.oClasses.sFilter;d.innerHTML="";if(!a.aanFeatures.f)d.id=a.sTableId+"_filter";c=i('input[type="text"]',d);d._DT_Input=c[0];c.val(b.sSearch.replace('"',"""));c.bind("keyup.DT",function(){for(var e=a.aanFeatures.f,f=this.value===""?"":this.value,g=0,j=e.length;g=0;d--){e=Ya(F(a,a.aiDisplay[d],c,
54 | "filter"),a.aoColumns[c].sType);if(!b.test(e)){a.aiDisplay.splice(d,1);g++}}}}function Va(a,b,c,d,e,f){d=Ca(b,d,e,f);e=a.oPreviousSearch;c||(c=0);if(l.ext.afnFiltering.length!==0)c=1;if(b.length<=0){a.aiDisplay.splice(0,a.aiDisplay.length);a.aiDisplay=a.aiDisplayMaster.slice()}else if(a.aiDisplay.length==a.aiDisplayMaster.length||e.sSearch.length>b.length||c==1||b.indexOf(e.sSearch)!==0){a.aiDisplay.splice(0,a.aiDisplay.length);Ba(a,1);for(b=0;b").html(a).text();return a.replace(/[\n\r]/g," ")}function Ca(a,b,c,d){if(c){a=b?a.split(" "):
56 | Ea(a).split(" ");a="^(?=.*?"+a.join(")(?=.*?")+").*$";return new RegExp(a,d?"i":"")}else{a=b?a:Ea(a);return new RegExp(a,d?"i":"")}}function Ya(a,b){if(typeof l.ext.ofnSearch[b]==="function")return l.ext.ofnSearch[b](a);else if(a===null)return"";else if(b=="html")return a.replace(/[\r\n]/g," ").replace(/<.*?>/g,"");else if(typeof a==="string")return a.replace(/[\r\n]/g," ");return a}function Ea(a){return a.replace(new RegExp("(\\/|\\.|\\*|\\+|\\?|\\||\\(|\\)|\\[|\\]|\\{|\\}|\\\\|\\$|\\^|\\-)","g"),
57 | "\\$1")}function Ra(a){var b=s.createElement("div");b.className=a.oClasses.sInfo;if(!a.aanFeatures.i){a.aoDrawCallback.push({fn:Za,sName:"information"});b.id=a.sTableId+"_info"}a.nTable.setAttribute("aria-describedby",a.sTableId+"_info");return b}function Za(a){if(!(!a.oFeatures.bInfo||a.aanFeatures.i.length===0)){var b=a.oLanguage,c=a._iDisplayStart+1,d=a.fnDisplayEnd(),e=a.fnRecordsTotal(),f=a.fnRecordsDisplay(),g;g=f===0?b.sInfoEmpty:b.sInfo;if(f!=e)g+=" "+b.sInfoFiltered;g+=b.sInfoPostFix;g=za(a,
58 | g);if(b.fnInfoCallback!==null)g=b.fnInfoCallback.call(a.oInstance,a,c,d,e,f,g);a=a.aanFeatures.i;b=0;for(c=a.length;b",c,d,e=a.aLengthMenu;if(e.length==2&&typeof e[0]==="object"&&typeof e[1]==="object"){c=0;for(d=e[0].length;c'+e[1][c]+""}else{c=0;for(d=e.length;c'+e[c]+""}b+="";
62 | e=s.createElement("div");if(!a.aanFeatures.l)e.id=a.sTableId+"_length";e.className=a.oClasses.sLength;e.innerHTML="";i('select option[value="'+a._iDisplayLength+'"]',e).attr("selected",true);i("select",e).bind("change.DT",function(){var f=i(this).val(),g=a.aanFeatures.l;c=0;for(d=g.length;ca.aiDisplay.length||a._iDisplayLength==-1?a.aiDisplay.length:a._iDisplayStart+a._iDisplayLength}function Sa(a){if(a.oScroll.bInfinite)return null;var b=s.createElement("div");b.className=a.oClasses.sPaging+
64 | a.sPaginationType;l.ext.oPagination[a.sPaginationType].fnInit(a,b,function(c){I(c);H(c)});a.aanFeatures.p||a.aoDrawCallback.push({fn:function(c){l.ext.oPagination[c.sPaginationType].fnUpdate(c,function(d){I(d);H(d)})},sName:"pagination"});return b}function Ga(a,b){var c=a._iDisplayStart;if(typeof b==="number"){a._iDisplayStart=b*a._iDisplayLength;if(a._iDisplayStart>a.fnRecordsDisplay())a._iDisplayStart=0}else if(b=="first")a._iDisplayStart=0;else if(b=="previous"){a._iDisplayStart=a._iDisplayLength>=
65 | 0?a._iDisplayStart-a._iDisplayLength:0;if(a._iDisplayStart<0)a._iDisplayStart=0}else if(b=="next")if(a._iDisplayLength>=0){if(a._iDisplayStart+a._iDisplayLength=0){b=parseInt((a.fnRecordsDisplay()-1)/a._iDisplayLength,10)+1;a._iDisplayStart=(b-1)*a._iDisplayLength}else a._iDisplayStart=0;else O(a,0,"Unknown paging action: "+b);i(a.oInstance).trigger("page",a);return c!=a._iDisplayStart}
66 | function Pa(a){var b=s.createElement("div");if(!a.aanFeatures.r)b.id=a.sTableId+"_processing";b.innerHTML=a.oLanguage.sProcessing;b.className=a.oClasses.sProcessing;a.nTable.parentNode.insertBefore(b,a.nTable);return b}function P(a,b){if(a.oFeatures.bProcessing)for(var c=a.aanFeatures.r,d=0,e=c.length;d0){d=d[0];if(d._captionSide==="top")j.appendChild(d);else d._captionSide==="bottom"&&u&&k.appendChild(d)}if(a.oScroll.sX!==""){c.style.width=t(a.oScroll.sX);e.style.width=t(a.oScroll.sX);if(u!==null)f.style.width=t(a.oScroll.sX);i(e).scroll(function(){c.scrollLeft=this.scrollLeft;if(u!==null)f.scrollLeft=this.scrollLeft})}if(a.oScroll.sY!=="")e.style.height=t(a.oScroll.sY);a.aoDrawCallback.push({fn:$a,sName:"scrolling"});a.oScroll.bInfinite&&
70 | i(e).scroll(function(){if(!a.bDrawing&&i(this).scrollTop()!==0)if(i(this).scrollTop()+i(this).height()>i(a.nTable).height()-a.oScroll.iLoadGap)if(a.fnDisplayEnd()d.offsetHeight||i(d).css("overflow-y")=="scroll"))a.nTable.style.width=t(i(a.nTable).outerWidth()-
73 | a.oScroll.iBarWidth)}else if(a.oScroll.sXInner!=="")a.nTable.style.width=t(a.oScroll.sXInner);else if(e==i(d).width()&&i(d).height()e-a.oScroll.iBarWidth)a.nTable.style.width=t(e)}else a.nTable.style.width=t(e);e=i(a.nTable).outerWidth();N(ja,j);N(function(z){y.push(t(i(z).width()))},j);N(function(z,Q){z.style.width=y[Q]},g);i(j).height(0);if(a.nTFoot!==null){N(ja,k);N(function(z){B.push(t(i(z).width()))},
74 | k);N(function(z,Q){z.style.width=B[Q]},m);i(k).height(0)}N(function(z,Q){z.innerHTML="";z.style.width=y[Q]},j);a.nTFoot!==null&&N(function(z,Q){z.innerHTML="";z.style.width=B[Q]},k);if(i(a.nTable).outerWidth()d.offsetHeight||i(d).css("overflow-y")=="scroll"?e+a.oScroll.iBarWidth:e;if(L&&(d.scrollHeight>d.offsetHeight||i(d).css("overflow-y")=="scroll"))a.nTable.style.width=t(g-a.oScroll.iBarWidth);d.style.width=t(g);a.nScrollHead.style.width=t(g);if(a.nTFoot!==null)a.nScrollFoot.style.width=
75 | t(g);if(a.oScroll.sX==="")O(a,1,"The table cannot fit into the current element which will cause column misalignment. The table has been drawn at its minimum possible width.");else a.oScroll.sXInner!==""&&O(a,1,"The table cannot fit into the current element which will cause column misalignment. Increase the sScrollXInner value or remove it to allow automatic calculation")}else{d.style.width=t("100%");a.nScrollHead.style.width=t("100%");if(a.nTFoot!==null)a.nScrollFoot.style.width=t("100%")}if(a.oScroll.sY===
76 | "")if(L)d.style.height=t(a.nTable.offsetHeight+a.oScroll.iBarWidth);if(a.oScroll.sY!==""&&a.oScroll.bCollapse){d.style.height=t(a.oScroll.sY);L=a.oScroll.sX!==""&&a.nTable.offsetWidth>d.offsetWidth?a.oScroll.iBarWidth:0;if(a.nTable.offsetHeightd.clientHeight||i(d).css("overflow-y")=="scroll";b.style.paddingRight=c?a.oScroll.iBarWidth+"px":"0px";if(a.nTFoot!==
77 | null){M.style.width=t(L);T.style.width=t(L);T.style.paddingRight=c?a.oScroll.iBarWidth+"px":"0px"}i(d).scroll();if(a.bSorted||a.bFiltered)d.scrollTop=0}function N(a,b,c){for(var d=0,e=0,f=b.length,g,j;etd",b);j=Z(a,f);for(f=d=0;f0)a.aoColumns[f].sWidth=t(g);d++}e=i(b).css("width");
82 | a.nTable.style.width=e.indexOf("%")!==-1?e:t(i(b).outerWidth());b.parentNode.removeChild(b)}if(k)a.nTable.style.width=t(k)}function cb(a,b){if(a.oScroll.sX===""&&a.oScroll.sY!==""){i(b).width();b.style.width=t(i(b).outerWidth()-a.oScroll.iBarWidth)}else if(a.oScroll.sX!=="")b.style.width=t(i(b).outerWidth())}function bb(a,b){var c=db(a,b);if(c<0)return null;if(a.aoData[c].nTr===null){var d=s.createElement("td");d.innerHTML=F(a,c,b,"");return d}return W(a,c)[b]}function db(a,b){for(var c=-1,d=-1,e=
83 | 0;e/g,"");if(f.length>c){c=f.length;d=e}}return d}function t(a){if(a===null)return"0px";if(typeof a=="number"){if(a<0)return"0px";return a+"px"}var b=a.charCodeAt(a.length-1);if(b<48||b>57)return a;return a+"px"}function eb(){var a=s.createElement("p"),b=a.style;b.width="100%";b.height="200px";b.padding="0px";var c=s.createElement("div");b=c.style;b.position="absolute";b.top="0px";b.left="0px";b.visibility="hidden";b.width="200px";
84 | b.height="150px";b.padding="0px";b.overflow="hidden";c.appendChild(a);s.body.appendChild(c);b=a.offsetWidth;c.style.overflow="scroll";a=a.offsetWidth;if(b==a)a=c.clientWidth;s.body.removeChild(c);return b-a}function $(a,b){var c,d,e,f,g,j,k=[],m=[],u=l.ext.oSort,x=a.aoData,y=a.aoColumns,B=a.oLanguage.oAria;if(!a.oFeatures.bServerSide&&(a.aaSorting.length!==0||a.aaSortingFixed!==null)){k=a.aaSortingFixed!==null?a.aaSortingFixed.concat(a.aaSorting):a.aaSorting.slice();for(c=0;c/g,"");b=y[c].nTh;b.removeAttribute("aria-sort");b.removeAttribute("aria-label");
87 | if(y[c].bSortable)if(k.length>0&&k[0][0]==c){b.setAttribute("aria-sort",k[0][1]=="asc"?"ascending":"descending");b.setAttribute("aria-label",e+((y[c].asSorting[k[0][2]+1]?y[c].asSorting[k[0][2]+1]:y[c].asSorting[0])=="asc"?B.sSortAscending:B.sSortDescending))}else b.setAttribute("aria-label",e+(y[c].asSorting[0]=="asc"?B.sSortAscending:B.sSortDescending));else b.setAttribute("aria-label",e)}a.bSorted=true;i(a.oInstance).trigger("sort",a);if(a.oFeatures.bFilter)X(a,a.oPreviousSearch,1);else{a.aiDisplay=
88 | a.aiDisplayMaster.slice();a._iDisplayStart=0;I(a);H(a)}}function ya(a,b,c,d){fb(b,{},function(e){if(a.aoColumns[c].bSortable!==false){var f=function(){var g,j;if(e.shiftKey){for(var k=false,m=0;m0&&d.indexOf(k)==-1)a[b].className=d+" "+k}}}function Ha(a){if(!(!a.oFeatures.bStateSave||a.bDestroying)){var b,c;b=a.oScroll.bInfinite;var d={iCreate:(new Date).getTime(),iStart:b?0:a._iDisplayStart,iEnd:b?a._iDisplayLength:a._iDisplayEnd,iLength:a._iDisplayLength,aaSorting:i.extend(true,[],a.aaSorting),oSearch:i.extend(true,{},a.oPreviousSearch),aoSearchCols:i.extend(true,[],a.aoPreSearchCols),abVisCols:[]};b=0;for(c=a.aoColumns.length;b4096){for(var j=0,k=a.length;j4096;){if(f.length===0)return;d=f.pop();s.cookie=d.name+"=; expires=Thu, 01-Jan-1970 00:00:01 GMT; path="+
96 | c.join("/")+"/"}}s.cookie=b}function mb(a){var b=la.location.pathname.split("/");a=a+"_"+b[b.length-1].replace(/[\/:]/g,"").toLowerCase()+"=";b=s.cookie.split(";");for(var c=0;c=0;f--)e.push(b[f].fn.apply(a.oInstance,d));c!==null&&i(a.oInstance).trigger(c,d);return e}function ib(a){var b=i('')[0];s.body.appendChild(b);
100 | a.oBrowser.bScrollOversize=i("#DT_BrowserTest",b)[0].offsetWidth===100?true:false;s.body.removeChild(b)}function jb(a){return function(){var b=[C(this[l.ext.iApiIndex])].concat(Array.prototype.slice.call(arguments));return l.ext.oApi[a].apply(this,b)}}var ga=/\[.*?\]$/,kb=la.JSON?JSON.stringify:function(a){var b=typeof a;if(b!=="object"||a===null){if(b==="string")a='"'+a+'"';return a+""}var c,d,e=[],f=i.isArray(a);for(c in a){d=a[c];b=typeof d;if(b==="string")d='"'+d+'"';else if(b==="object"&&d!==
101 | null)d=kb(d);e.push((f?"":'"'+c+'":')+d)}return(f?"[":"{")+e+(f?"]":"}")};this.$=function(a,b){var c,d=[],e;c=C(this[l.ext.iApiIndex]);var f=c.aoData,g=c.aiDisplay,j=c.aiDisplayMaster;b||(b={});b=i.extend({},{filter:"none",order:"current",page:"all"},b);if(b.page=="current"){b=c._iDisplayStart;for(c=c.fnDisplayEnd();b=d.fnRecordsDisplay()){d._iDisplayStart-=d._iDisplayLength;if(d._iDisplayStart<0)d._iDisplayStart=0}if(c===p||c){I(d);H(d)}return g};this.fnDestroy=function(a){var b=C(this[l.ext.iApiIndex]),c=b.nTableWrapper.parentNode,d=b.nTBody,e,f;a=a===p?false:a;b.bDestroying=true;K(b,"aoDestroyCallback","destroy",[b]);if(!a){e=0;for(f=b.aoColumns.length;e<
106 | f;e++)b.aoColumns[e].bVisible===false&&this.fnSetColumnVis(e,true)}i(b.nTableWrapper).find("*").andSelf().unbind(".DT");i("tbody>tr>td."+b.oClasses.sRowEmpty,b.nTable).parent().remove();if(b.nTable!=b.nTHead.parentNode){i(b.nTable).children("thead").remove();b.nTable.appendChild(b.nTHead)}if(b.nTFoot&&b.nTable!=b.nTFoot.parentNode){i(b.nTable).children("tfoot").remove();b.nTable.appendChild(b.nTFoot)}b.nTable.parentNode.removeChild(b.nTable);i(b.nTableWrapper).remove();b.aaSorting=[];b.aaSortingFixed=
107 | [];ba(b);i(fa(b)).removeClass(b.asStripeClasses.join(" "));i("th, td",b.nTHead).removeClass([b.oClasses.sSortable,b.oClasses.sSortableAsc,b.oClasses.sSortableDesc,b.oClasses.sSortableNone].join(" "));if(b.bJUI){i("th span."+b.oClasses.sSortIcon+", td span."+b.oClasses.sSortIcon,b.nTHead).remove();i("th, td",b.nTHead).each(function(){var g=i("div."+b.oClasses.sSortJUIWrapper,this),j=g.contents();i(this).append(j);g.remove()})}if(!a&&b.nTableReinsertBefore)c.insertBefore(b.nTable,b.nTableReinsertBefore);
108 | else a||c.appendChild(b.nTable);e=0;for(f=b.aoData.length;e=D(d);if(!m)for(e=a;et<"F"ip>'}else i.extend(g.oClasses,l.ext.oStdClasses);
125 | i(this).addClass(g.oClasses.sTable);if(g.oScroll.sX!==""||g.oScroll.sY!=="")g.oScroll.iBarWidth=eb();if(g.iInitDisplayStart===p){g.iInitDisplayStart=h.iDisplayStart;g._iDisplayStart=h.iDisplayStart}if(h.bStateSave){g.oFeatures.bStateSave=true;gb(g,h);J(g,"aoDrawCallback",Ha,"state_save")}if(h.iDeferLoading!==null){g.bDeferLoading=true;a=i.isArray(h.iDeferLoading);g._iRecordsDisplay=a?h.iDeferLoading[0]:h.iDeferLoading;g._iRecordsTotal=a?h.iDeferLoading[1]:h.iDeferLoading}if(h.aaData!==null)f=true;
126 | if(h.oLanguage.sUrl!==""){g.oLanguage.sUrl=h.oLanguage.sUrl;i.getJSON(g.oLanguage.sUrl,null,function(k){Fa(k);i.extend(true,g.oLanguage,h.oLanguage,k);ra(g)});e=true}else i.extend(true,g.oLanguage,h.oLanguage);if(h.asStripeClasses===null)g.asStripeClasses=[g.oClasses.sStripeOdd,g.oClasses.sStripeEven];b=g.asStripeClasses.length;g.asDestroyStripes=[];if(b){c=false;d=i(this).children("tbody").children("tr:lt("+b+")");for(a=0;a=g.aoColumns.length)g.aaSorting[a][0]=
128 | 0;var j=g.aoColumns[g.aaSorting[a][0]];if(g.aaSorting[a][2]===p)g.aaSorting[a][2]=0;if(h.aaSorting===p&&g.saved_aaSorting===p)g.aaSorting[a][1]=j.asSorting[0];c=0;for(d=j.asSorting.length;c0&&(g.oScroll.sX!==""||g.oScroll.sY!=="")){b=[s.createElement("tfoot")];this.appendChild(b[0])}if(b.length>0){g.nTFoot=b[0];ha(g.aoFooter,g.nTFoot)}if(f)for(a=0;a=parseInt(v,10)};l.fnIsDataTable=function(h){for(var n=l.settings,q=0;q'+o.sPrevious+''+o.sNext+"":'';i(n).append(o);var w=i("a",n);o=w[0];w=w[1];h.oApi._fnBindAction(o,{action:"previous"},v);h.oApi._fnBindAction(w,{action:"next"},v);
150 | if(!h.aanFeatures.p){n.id=h.sTableId+"_paginate";o.id=h.sTableId+"_previous";w.id=h.sTableId+"_next";o.setAttribute("aria-controls",h.sTableId);w.setAttribute("aria-controls",h.sTableId)}},fnUpdate:function(h){if(h.aanFeatures.p)for(var n=h.oClasses,q=h.aanFeatures.p,o,v=0,w=q.length;v'+o.sFirst+''+o.sPrevious+''+o.sNext+''+o.sLast+"");var D=i("a",n);o=D[0];v=D[1];var A=D[2];D=D[3];h.oApi._fnBindAction(o,{action:"first"},w);h.oApi._fnBindAction(v,{action:"previous"},w);h.oApi._fnBindAction(A,{action:"next"},w);h.oApi._fnBindAction(D,{action:"last"},w);if(!h.aanFeatures.p){n.id=h.sTableId+"_paginate";o.id=h.sTableId+"_first";v.id=h.sTableId+"_previous";A.id=h.sTableId+"_next";D.id=h.sTableId+"_last"}},fnUpdate:function(h,n){if(h.aanFeatures.p){var q=l.ext.oPagination.iFullNumbersShowPages,o=Math.floor(q/2),v=
153 | Math.ceil(h.fnRecordsDisplay()/h._iDisplayLength),w=Math.ceil(h._iDisplayStart/h._iDisplayLength)+1,D="",A,G=h.oClasses,E,Y=h.aanFeatures.p,ma=function(R){h.oApi._fnBindAction(this,{page:R+A-1},function(ea){h.oApi._fnPageChange(h,ea.data.page);n(h);ea.preventDefault()})};if(h._iDisplayLength===-1)w=o=A=1;else if(v=v-o){A=v-q+1;o=v}else{A=w-Math.ceil(q/2)+1;o=A+q-1}for(q=A;q<=o;q++)D+=w!==q?''+h.fnFormatNumber(q)+
154 | "":''+h.fnFormatNumber(q)+"";q=0;for(o=Y.length;qn?1:0},"string-desc":function(h,n){return hn?-1:0},"html-pre":function(h){return h.replace(/<.*?>/g,"").toLowerCase()},"html-asc":function(h,n){return hn?1:0},"html-desc":function(h,n){return hn?-1:0},"date-pre":function(h){h=Date.parse(h);if(isNaN(h)||h==="")h=Date.parse("01/01/1970 00:00:00");
156 | return h},"date-asc":function(h,n){return h-n},"date-desc":function(h,n){return n-h},"numeric-pre":function(h){return h=="-"||h===""?0:h*1},"numeric-asc":function(h,n){return h-n},"numeric-desc":function(h,n){return n-h}});i.extend(l.ext.aTypes,[function(h){if(typeof h==="number")return"numeric";else if(typeof h!=="string")return null;var n,q=false;n=h.charAt(0);if("0123456789-".indexOf(n)==-1)return null;for(var o=1;o")!=-1)return"html";return null}]);i.fn.DataTable=l;i.fn.dataTable=l;i.fn.dataTableSettings=l.settings;i.fn.dataTableExt=l.ext})})(window,document);
158 |
--------------------------------------------------------------------------------
/scripts/neo4d3.js:
--------------------------------------------------------------------------------
1 | function Neo(urlSource) {
2 | function txUrl() {
3 | var connection = urlSource();
4 | var url = (connection.url || "http://localhost:7474").replace(/\/db\/data.*/,"");
5 | return url + "/db/data/transaction/commit";
6 | }
7 | var me = {
8 | executeQuery: function(query, params, cb) {
9 | var connection = urlSource();
10 | var auth = ((connection.user || "") == "") ? "" : "Basic " + btoa(connection.user + ":" + connection.pass);
11 | $.ajax(txUrl(), {
12 | type: "POST",
13 | data: JSON.stringify({
14 | statements: [{
15 | statement: query,
16 | parameters: params || {},
17 | resultDataContents: ["row", "graph"]
18 | }]
19 | }),
20 | contentType: "application/json",
21 | error: function(err) {
22 | cb(err);
23 | },
24 | beforeSend: function (xhr) {
25 | if (auth && auth.length) xhr.setRequestHeader ("Authorization", auth);
26 | },
27 | success: function(res) {
28 | if (res.errors.length > 0) {
29 | cb(res.errors);
30 | } else {
31 | var cols = res.results[0].columns;
32 | var rows = res.results[0].data.map(function(row) {
33 | var r = {};
34 | cols.forEach(function(col, index) {
35 | r[col] = row.row[index];
36 | });
37 | return r;
38 | });
39 | var nodes = [];
40 | var rels = [];
41 | var labels = [];
42 | function findNode(nodes, id) {
43 | for (var i=0;i 0;
51 | if (!found) {
52 | //n.props=n.properties;
53 | for(var p in n.properties||{}) { n[p]=n.properties[p];delete n.properties[p];}
54 | delete n.properties;
55 | nodes.push(n);
56 | labels=labels.concat(n.labels.filter(function(l) { labels.indexOf(l) == -1 }))
57 | }
58 | });
59 | rels = rels.concat(row.graph.relationships.map(
60 | function(r) {
61 | return { id: r.id, start:r.startNode, end:r.endNode, type:r.type } }
62 | ));
63 | });
64 | cb(null,{table:rows,graph:{nodes:nodes, links:rels},labels:labels});
65 | }
66 | }
67 | });
68 | }
69 | };
70 | return me;
71 | }
72 |
--------------------------------------------------------------------------------
/scripts/neod3-visualization.js:
--------------------------------------------------------------------------------
1 | function Neod3Renderer() {
2 |
3 | var styleContents =
4 | "node {\
5 | diameter: 40px;\
6 | color: #DFE1E3;\
7 | border-color: #D4D6D7;\
8 | border-width: 2px;\
9 | text-color-internal: #000000;\
10 | text-color-external: #000000;\
11 | caption: '{name}';\
12 | font-size: 12px;\
13 | }\
14 | relationship {\
15 | color: #4356C0;\
16 | shaft-width: 3px;\
17 | font-size: 9px;\
18 | padding: 3px;\
19 | text-color-external: #000000;\
20 | text-color-internal: #FFFFFF;\
21 | }\n";
22 |
23 | var skip = ["id", "start", "end", "source", "target", "labels", "type", "selected","properties"];
24 | var prio_props = ["name", "title", "tag", "username", "lastname","caption"];
25 |
26 | var serializer = null;
27 |
28 | var $downloadSvgLink = $(' Download SVG').hide().click(function () {
29 | $downloadSvgLink.hide();
30 | });
31 | var downloadSvgLink = $downloadSvgLink[0];
32 | var blobSupport = 'Blob' in window;
33 | var URLSupport = 'URL' in window && 'createObjectURL' in window.URL;
34 | var msBlobSupport = typeof window.navigator.msSaveOrOpenBlob !== 'undefined';
35 | var svgStyling = '';
36 | var stylingUrl = window.location.hostname === 'www.neo4j.org' ? 'http://gist.neo4j.org/css/neod3' : 'styles/neod3';
37 | if (window.isInternetExplorer) {
38 | stylingUrl += '-ie.css';
39 | } else {
40 | stylingUrl += '.css';
41 | }
42 |
43 | var existingStyles = {};
44 | var currentColor = 1;
45 |
46 | function dummyFunc() {
47 | }
48 |
49 | function render(id, $container, visualization) {
50 | function extract_props(pc) {
51 | var p = {};
52 | for (var key in pc) {
53 | if (!pc.hasOwnProperty(key) || skip.indexOf(key) != -1) continue;
54 | p[key] = pc[key];
55 | }
56 | return p;
57 | }
58 |
59 | function node_styles(nodes) {
60 | function label(n) {
61 | var labels = n["labels"];
62 | if (labels && labels.length) {
63 | return labels[labels.length - 1];
64 | }
65 | return "";
66 | }
67 |
68 | var style = {};
69 | for (var i = 0; i < nodes.length; i++) {
70 | var props= nodes[i].properties = extract_props(nodes[i]);
71 | var keys = Object.keys(props);
72 | if (label(nodes[i]) !== "" && keys.length > 0) {
73 | var selected_keys = prio_props.filter(function (k) {
74 | return keys.indexOf(k) !== -1
75 | });
76 | selected_keys = selected_keys.concat(keys).concat(['id']);
77 | var selector = "node." + label(nodes[i]);
78 | var selectedKey = selected_keys[0];
79 | if (typeof(props[selectedKey]) === "string" && props[selectedKey].length > 30) {
80 | props[selectedKey] = props[selectedKey].substring(0,30)+" ...";
81 | }
82 | style[selector] = style[selector] || selectedKey;
83 | }
84 | }
85 | return style;
86 | }
87 | function style_sheet(styles, styleContents) {
88 | function format(key) {
89 | var item=styles[key];
90 | return item.selector +
91 | " {caption: '{" + item.caption +
92 | "}'; color: " + item.color +
93 | "; border-color: " + item['border-color'] +
94 | "; text-color-internal: " + item['text-color-internal'] +
95 | "; text-color-external: " + item['text-color-external'] +
96 | "; }"
97 | }
98 | return styleContents + Object.keys(styles).map(format).join("\n");
99 | }
100 | function create_styles(styleCaptions, styles) {
101 | var colors = neo.style.defaults.colors;
102 | for (var selector in styleCaptions) {
103 | if (!(selector in styles)) {
104 | var color = colors[currentColor];
105 | currentColor = (currentColor + 1) % colors.length;
106 | var textColor = window.isInternetExplorer ? '#000000' : color['text-color-internal'];
107 | var style = {selector:selector, caption:styleCaptions[selector], color:color.color,
108 | "border-color":color['border-color'], "text-color-internal":textColor,"text-color-external": textColor }
109 | styles[selector] = style;
110 | }
111 | }
112 | return styles;
113 | }
114 |
115 | function applyZoom() {
116 | renderer.select(".nodes").attr("transform", "translate(" + d3.event.translate + ")scale(" + d3.event.scale + ")");
117 | renderer.select(".relationships").attr("transform", "translate(" + d3.event.translate + ")scale(" + d3.event.scale + ")");
118 | }
119 |
120 | function enableZoomHandlers() {
121 | renderer.on("wheel.zoom",zoomHandlers.wheel);
122 | renderer.on("mousewheel.zoom",zoomHandlers.mousewheel);
123 | renderer.on("mousedown.zoom",zoomHandlers.mousedown);
124 | renderer.on("DOMMouseScroll.zoom",zoomHandlers.DOMMouseScroll);
125 | renderer.on("touchstart.zoom",zoomHandlers.touchstart);
126 | renderer.on("touchmove.zoom",zoomHandlers.touchmove);
127 | renderer.on("touchend.zoom",zoomHandlers.touchend);
128 | }
129 |
130 | function disableZoomHandlers() {
131 | renderer.on("wheel.zoom",null);
132 | renderer.on("mousewheel.zoom",null);
133 | renderer.on("mousedown.zoom", null);
134 | renderer.on("DOMMouseScroll.zoom", null);
135 | renderer.on("touchstart.zoom",null);
136 | renderer.on("touchmove.zoom",null);
137 | renderer.on("touchend.zoom",null);
138 | }
139 |
140 | function legend(svg, styles) {
141 | var keys = Object.keys(styles).sort();
142 | var circles = svg.selectAll('circle.legend').data(keys);
143 | var r=20;
144 | circles.enter().append('circle').classed('legend', true).attr({
145 | cx: 2*r,
146 | r : r
147 | });
148 | circles.attr({
149 | cy: function(node) {
150 | return (keys.indexOf(node)+1)*2.2*r;
151 | },
152 | fill: function(node) {
153 | return styles[node]['color'];
154 | },
155 | stroke: function(node) {
156 | return styles[node]['border-color'];
157 | },
158 | 'stroke-width': function(node) {
159 | return "2px";
160 | }
161 | });
162 | var text = svg.selectAll('text.legend').data(keys);
163 | text.enter().append('text').classed('legend',true).attr({
164 | 'text-anchor': 'left',
165 | 'font-weight': 'bold',
166 | 'stroke-width' : '0',
167 | 'stroke-color' : 'black',
168 | 'fill' : 'black',
169 | 'x' : 3.2*r,
170 | 'font-size' : "12px"
171 | });
172 | text.text(function(node) {
173 | var label = styles[node].selector;
174 | return label ? label.substring(5) : "";
175 | }).attr('y', function(node) {
176 | return (keys.indexOf(node)+1)*2.2*r+6;
177 | })
178 | /*
179 | .attr('stroke', function(node) {
180 | return styles[node]['color'];
181 | })
182 | .attr('fill', function(node) {
183 | return styles[node]['text-color-internal'];
184 | });
185 | */
186 | return circles.exit().remove();
187 | }
188 | function keyHandler() {
189 | if (d3.event.altKey || d3.event.shiftKey) {
190 | enableZoomHandlers();
191 | }
192 | else {
193 | disableZoomHandlers();
194 | }
195 | }
196 |
197 | var links = visualization.links;
198 | var nodes = visualization.nodes;
199 | for (var i = 0; i < links.length; i++) {
200 | links[i].source = links[i].start;
201 | links[i].target = links[i].end;
202 | // links[i].properties = props(links[i]);
203 | }
204 | var nodeStyles = node_styles(nodes);
205 | create_styles(nodeStyles, existingStyles);
206 | var styleSheet = style_sheet(existingStyles, styleContents);
207 | var graphModel = neo.graphModel()
208 | .nodes(nodes)
209 | .relationships(links);
210 | var graphView = neo.graphView()
211 | .style(styleSheet)
212 | .width($container.width()).height($container.height()).on('nodeClicked', dummyFunc).on('relationshipClicked', dummyFunc).on('nodeDblClicked', dummyFunc);
213 | var svg = d3.select("#" + id).append("svg");
214 | var renderer = svg.data([graphModel]);
215 | legend(svg,existingStyles);
216 | var zoomHandlers = {};
217 | var zoomBehavior = d3.behavior.zoom().on("zoom", applyZoom).scaleExtent([0.2, 8]);
218 |
219 | renderer.call(graphView);
220 | renderer.call(zoomBehavior);
221 |
222 | zoomHandlers.wheel = renderer.on("wheel.zoom");
223 | zoomHandlers.mousewheel = renderer.on("mousewheel.zoom");
224 | zoomHandlers.mousedown = renderer.on("mousedown.zoom");
225 | zoomHandlers.DOMMouseScroll = renderer.on("DOMMouseScroll.zoom");
226 | zoomHandlers.touchstart = renderer.on("touchstart.zoom");
227 | zoomHandlers.touchmove = renderer.on("touchmove.zoom")
228 | zoomHandlers.touchend = renderer.on("touchend.zoom");
229 | disableZoomHandlers();
230 |
231 | d3.select('body').on("keydown", keyHandler).on("keyup", keyHandler);
232 |
233 | function refresh() {
234 | graphView.height($container.height());
235 | graphView.width($container.width());
236 | renderer.call(graphView);
237 | }
238 |
239 | function saveToSvg() {
240 | var svgElement = $('#' + id).children('svg').first()[0];
241 | var xml = serializeSvg(svgElement, $container);
242 | if (!msBlobSupport && downloadSvgLink.href !== '#') {
243 | window.URL.revokeObjectURL(downloadSvgLink.href);
244 | }
245 | var blob = new window.Blob([xml], {
246 | 'type': 'image/svg+xml'
247 | });
248 | var fileName = id + '.svg';
249 | if (!msBlobSupport) {
250 | downloadSvgLink.href = window.URL.createObjectURL(blob);
251 | $downloadSvgLink.appendTo($container).show();
252 | $downloadSvgLink.attr('download', fileName);
253 | } else {
254 | window.navigator.msSaveOrOpenBlob(blob, fileName);
255 | }
256 | }
257 |
258 | function getFunctions() {
259 | var funcs = {};
260 | if (blobSupport && (URLSupport || msBlobSupport)) {
261 | funcs['icon-download-alt'] = {'title': 'Save as SVG', 'func':saveToSvg};
262 | }
263 | return funcs;
264 | }
265 |
266 | return {
267 | 'subscriptions': {
268 | 'expand': refresh,
269 | 'contract': refresh,
270 | 'sizeChange': refresh
271 | },
272 | 'actions': getFunctions()
273 | };
274 | }
275 |
276 | function serializeSvg(element, $container) {
277 | if (serializer === null) {
278 | if (typeof window.XMLSerializer !== 'undefined') {
279 | var xmlSerializer = new XMLSerializer();
280 | serializer = function (emnt) {
281 | return xmlSerializer.serializeToString(emnt);
282 | };
283 | } else {
284 | serializer = function (emnt) {
285 | return '';
286 | }
287 | }
288 | }
289 | var svg = serializer(element);
290 | svg = svg.replace('