├── .babelrc
├── .eslintignore
├── .eslintrc.json
├── .gitignore
├── .npmignore
├── .travis.yml
├── LICENSE
├── README.md
├── browser-sync.config.js
├── build
├── .bundle.js.swo
├── bundle.js
└── demo.js
├── demo.html
├── demo.js
├── demo.json
├── demo.webpack.config.js
├── demo.xml
├── package.json
├── pages
├── build
├── demo.json
└── index.html
├── src
├── index.js
└── sbgnStyle
│ ├── element.js
│ ├── glyph
│ ├── auxiliaryItems.js
│ ├── baseShapes.js
│ ├── containerNodes.js
│ ├── entityPoolNodes.js
│ ├── index.js
│ └── processNodes.js
│ ├── index.js
│ └── util
│ ├── sbgn.js
│ └── svg.js
├── test-data.js
├── test
├── shapeTest.js
├── test.js
└── testenv
│ └── tests.html
└── webpack.config.js
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": [
3 | "env"
4 | ],
5 | "ignore": "node_modules/**/*"
6 | }
7 |
--------------------------------------------------------------------------------
/.eslintignore:
--------------------------------------------------------------------------------
1 | node_modules/**/*
2 |
--------------------------------------------------------------------------------
/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "env": {
3 | "browser": true,
4 | "commonjs": true,
5 | "es6": true,
6 | "node": true,
7 | "mocha": true
8 | },
9 | "extends": "eslint:recommended",
10 | "parserOptions": {
11 | "ecmaFeatures": {
12 | "jsx": true
13 | }
14 | },
15 | "plugins": [],
16 | "rules": {
17 | "semi": "error"
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | package-lock.json
3 |
4 |
5 | test/testenv/test-bundle.js
6 | # Logs
7 | logs
8 | *.log
9 | npm-debug.log*
10 |
11 | # Runtime data
12 | pids
13 | *.pid
14 | *.seed
15 |
16 | # Directory for instrumented libs generated by jscoverage/JSCover
17 | lib-cov
18 |
19 | # Coverage directory used by tools like istanbul
20 | coverage
21 |
22 | # nyc test coverage
23 | .nyc_output
24 |
25 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
26 | .grunt
27 |
28 | # node-waf configuration
29 | .lock-wscript
30 |
31 | # Compiled binary addons (http://nodejs.org/api/addons.html)
32 | build/Release
33 |
34 | # Dependency directories
35 | node_modules
36 | jspm_packages
37 |
38 | # Optional npm cache directory
39 | .npm
40 |
41 | # Optional REPL history
42 | .node_repl_history
43 |
44 | .DS_Store
45 |
46 | demo/browserify-bundle.js
47 |
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | node_modules/**/*
2 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 | node_js:
3 | - "6"
4 | - "7"
5 | - "8"
6 | - "stable"
7 | sudo: false
8 | script: npm run test
9 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) Dylan Fong
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy of
4 | this software and associated documentation files (the “Software”), to deal in
5 | the Software without restriction, including without limitation the rights to
6 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
7 | of the Software, and to permit persons to whom the Software is furnished to do
8 | so, subject to the following conditions:
9 |
10 | The above copyright notice and this permission notice shall be included in all
11 | copies or substantial portions of the Software.
12 |
13 | THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19 | SOFTWARE.
20 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # cytoscape-sbgn-stylesheet
2 | A Cytoscape.js package that provides SBGN specific glyph styles ([demo](https://pathwaycommons.github.io/cytoscape-sbgn-stylesheet/))
3 |
4 | ### Purpose
5 | To render SBGN-PD(Systems Biology Graphical Notation) graphs -- a visual language for representing biological processes.
6 |
7 | ### Installation
8 | Install via npm
9 |
10 | ```
11 | npm install cytoscape-sbgn-stylesheet
12 | ```
13 |
14 | ### Usage
15 |
16 | Initialize cytoscape.js and call this module as a stylesheet parameter
17 |
18 | ```js
19 | var cytoscape = require('cytoscape');
20 | var sbgnStylesheet = require('cytoscape-sbgn-stylesheet');
21 |
22 | var cy = cytoscape({
23 | container: container,
24 | style: sbgnStylesheet(cytoscape),
25 | // other arguments here
26 | });
27 |
28 | ```
29 |
30 | ### Requirements
31 | Input needs to be formatted Cytoscape.js graph JSON.
32 |
33 | The following graph JSON structure is required:
34 | ```
35 | {
36 | nodes: [], // array of nodes
37 | edges: [] // array of edges
38 | }
39 | ```
40 |
41 | #### Supported SBGN PD glyphs
42 | * simple chemical multimer
43 | * macromolecule multimer
44 | * nucleic acid feature multimer
45 | * complex multimer
46 | * simple chemical
47 | * macromolecule
48 | * nucleic acid feature
49 | * compartment
50 | * unspecified entity
51 | * perturbing agent
52 | * complex
53 | * phenotype
54 | * tag
55 | * process
56 | * uncertain process
57 | * omitted process
58 | * source and sink
59 | * dissociation
60 | * association
61 | * and
62 | * or
63 | * not
64 |
65 | #### Supported SBGN PD arcs
66 | * necessary stimulation
67 | * production
68 | * consumption
69 | * stimulation
70 | * catalysis
71 | * inhibition
72 |
73 | #### Unsupported SBGN PD glyphs
74 | * submap
75 | * ports
76 |
77 |
78 | The following node JSON structure is required:
79 | ```
80 | "data": {
81 | "id": "glyph23", // id of the node
82 | "class": "simple chemical", // class of the node (see classes section for a list of supported sbgn glyphs
83 | "label": "Ca2+", // label to be displayed on the node
84 | "parent": "glyph2", // parent node id if any
85 | "clonemarker": false, // whether the node has a clonemarker or not
86 | "stateVariables": [], // an array of state variables
87 | "unitsOfInformation": [], // an array of units of information
88 | }
89 | ```
90 | The following edge JSON structure is required:
91 | ```
92 | "data": {
93 | "id": "glyph19-glyph5", // id
94 | "class": "production", // sbgn class
95 | "cardinality": 0, // cardinality
96 | "source": "glyph19", // source node id
97 | "target": "glyph5", // target node id
98 | "portSource": "glyph19", // port of the source
99 | "portTarget": "glyph5" // port of the target
100 | }
101 | ```
102 |
103 | To get Cytoscape.js graph JSON, you need the following:
104 | * SBGN-ML files; xml files that represent biological networks.
105 | * An [SBGN-ML to Cytoscape.js converter](https://github.com/PathwayCommons/sbgnml-to-cytoscape).
106 |
107 |
108 | #### Style Incompatibilities
109 |
110 | The following cytoscape.js style properties are used to render SBGN PD graphics. Overriding these entirely will produce unexpected behaviour:
111 | * ```shape```
112 | * ```width```
113 | * ```height```
114 | * ```background-image```
115 | * ```background-width```
116 | * ```background-position-x```
117 | * ```background-position-y```
118 | * ```background-fit```
119 | * ```background-clip```
120 | * ```padding```
121 | * ```border-width```
122 |
123 | ## Run targets
124 |
125 | - `npm run build` : build project
126 | - `npm run build-prod` : build the project for production
127 | - `npm run bundle-profile` : visualise the bundle dependencies
128 | - `npm run clean` : clean the project
129 | - `npm run watch` : watch mode (debug mode enabled, autorebuild, autoreload)
130 | - `npm test` : run tests
131 | - `npm run lint` : lint the project
132 |
133 | ## Testing
134 |
135 | All files `/test` will be run by [Mocha](https://mochajs.org/). You can `npm test` to run all tests, or you can run `mocha -g specific-test-name` (prerequisite: `npm install -g mocha`) to run specific tests.
136 |
137 | [Chai](http://chaijs.com/) is included to make the tests easier to read and write.
138 |
139 | ## Publishing a release
140 |
141 | 1. Make sure the tests are passing: `npm test`
142 | 1. Do a prod build: `npm run build-prod`
143 | 1. Make sure the linting is passing: `npm run lint`
144 | 1. Bump the version number with `npm version`, in accordance with [semver](http://semver.org/). The `version` command in `npm` updates both `package.json` and git tags, but note that it uses a `v` prefix on the tags (e.g. `v1.2.3`).
145 | 1. For a bug fix / patch release, run `npm version patch`.
146 | 1. For a new feature release, run `npm version minor`.
147 | 1. For a breaking API change, run `npm version major.`
148 | 1. For a specific version number (e.g. 1.2.3), run `npm version 1.2.3`.
149 | 1. Push the release: `git push origin --tags`
150 | 1. Publish to npm: `npm publish .`
151 |
--------------------------------------------------------------------------------
/browser-sync.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | port: 3001,
3 | ghostMode: false,
4 | notify: false,
5 | server: true,
6 | startPath: "demo.html",
7 | files: [ 'build/*', 'demo.html' ]
8 | };
9 |
--------------------------------------------------------------------------------
/build/.bundle.js.swo:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PathwayCommons/cytoscape-sbgn-stylesheet/c5760ad13788f23c2b72774c304467c5018254ed/build/.bundle.js.swo
--------------------------------------------------------------------------------
/build/bundle.js:
--------------------------------------------------------------------------------
1 | (function webpackUniversalModuleDefinition(root, factory) {
2 | if(typeof exports === 'object' && typeof module === 'object')
3 | module.exports = factory(require("lodash.memoize"), require("text-width"));
4 | else if(typeof define === 'function' && define.amd)
5 | define(["lodash.memoize", "text-width"], factory);
6 | else if(typeof exports === 'object')
7 | exports["cytoscapeSbgnStylesheet"] = factory(require("lodash.memoize"), require("text-width"));
8 | else
9 | root["cytoscapeSbgnStylesheet"] = factory(root["lodash.memoize"], root["text-width"]);
10 | })(typeof self !== 'undefined' ? self : this, function(__WEBPACK_EXTERNAL_MODULE_5__, __WEBPACK_EXTERNAL_MODULE_10__) {
11 | return /******/ (function(modules) { // webpackBootstrap
12 | /******/ // The module cache
13 | /******/ var installedModules = {};
14 | /******/
15 | /******/ // The require function
16 | /******/ function __webpack_require__(moduleId) {
17 | /******/
18 | /******/ // Check if module is in cache
19 | /******/ if(installedModules[moduleId]) {
20 | /******/ return installedModules[moduleId].exports;
21 | /******/ }
22 | /******/ // Create a new module (and put it into the cache)
23 | /******/ var module = installedModules[moduleId] = {
24 | /******/ i: moduleId,
25 | /******/ l: false,
26 | /******/ exports: {}
27 | /******/ };
28 | /******/
29 | /******/ // Execute the module function
30 | /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
31 | /******/
32 | /******/ // Flag the module as loaded
33 | /******/ module.l = true;
34 | /******/
35 | /******/ // Return the exports of the module
36 | /******/ return module.exports;
37 | /******/ }
38 | /******/
39 | /******/
40 | /******/ // expose the modules object (__webpack_modules__)
41 | /******/ __webpack_require__.m = modules;
42 | /******/
43 | /******/ // expose the module cache
44 | /******/ __webpack_require__.c = installedModules;
45 | /******/
46 | /******/ // define getter function for harmony exports
47 | /******/ __webpack_require__.d = function(exports, name, getter) {
48 | /******/ if(!__webpack_require__.o(exports, name)) {
49 | /******/ Object.defineProperty(exports, name, {
50 | /******/ configurable: false,
51 | /******/ enumerable: true,
52 | /******/ get: getter
53 | /******/ });
54 | /******/ }
55 | /******/ };
56 | /******/
57 | /******/ // getDefaultExport function for compatibility with non-harmony modules
58 | /******/ __webpack_require__.n = function(module) {
59 | /******/ var getter = module && module.__esModule ?
60 | /******/ function getDefault() { return module['default']; } :
61 | /******/ function getModuleExports() { return module; };
62 | /******/ __webpack_require__.d(getter, 'a', getter);
63 | /******/ return getter;
64 | /******/ };
65 | /******/
66 | /******/ // Object.prototype.hasOwnProperty.call
67 | /******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
68 | /******/
69 | /******/ // __webpack_public_path__
70 | /******/ __webpack_require__.p = "";
71 | /******/
72 | /******/ // Load entry module and return exports
73 | /******/ return __webpack_require__(__webpack_require__.s = 6);
74 | /******/ })
75 | /************************************************************************/
76 | /******/ ([
77 | /* 0 */
78 | /***/ (function(module, exports, __webpack_require__) {
79 |
80 | "use strict";
81 |
82 |
83 | var sbgnDataHandler = {
84 | isMultimer: function isMultimer(node) {
85 | return node.data('class').includes('multimer');
86 | },
87 | hasClonemarker: function hasClonemarker(node) {
88 | return node.data('clonemarker');
89 | },
90 | getStateVars: function getStateVars(node) {
91 | return node.data('stateVariables');
92 | },
93 | getUnitInfos: function getUnitInfos(node) {
94 | return node.data('unitsOfInformation');
95 | },
96 | hasAuxItems: function hasAuxItems(node) {
97 | return node.data('stateVariables').length + node.data('unitsOfInformation').length > 0;
98 | },
99 | sbgnClass: function sbgnClass(element) {
100 | return element.data('class');
101 | },
102 | sbgnLabel: function sbgnLabel(element) {
103 | return element.data('label');
104 | },
105 | stateVarLabel: function stateVarLabel(stateVar) {
106 | var variable = stateVar.state.variable;
107 | var value = stateVar.state.value;
108 | if (value && variable) {
109 | return value + '@' + variable;
110 | }
111 | if (value) {
112 | return value;
113 | }
114 |
115 | if (variable) {
116 | return variable;
117 | }
118 | return '';
119 | }
120 | };
121 |
122 | module.exports = sbgnDataHandler;
123 |
124 | /***/ }),
125 | /* 1 */
126 | /***/ (function(module, exports, __webpack_require__) {
127 |
128 | "use strict";
129 |
130 |
131 | var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();
132 |
133 | var styleMap2Str = function styleMap2Str(styleMap) {
134 | if (!styleMap) {
135 | return '';
136 | }
137 |
138 | var s = '';
139 |
140 | var _iteratorNormalCompletion = true;
141 | var _didIteratorError = false;
142 | var _iteratorError = undefined;
143 |
144 | try {
145 | for (var _iterator = styleMap[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
146 | var _ref = _step.value;
147 |
148 | var _ref2 = _slicedToArray(_ref, 2);
149 |
150 | var k = _ref2[0];
151 | var v = _ref2[1];
152 |
153 | s += k + '=' + '"' + v + '"' + ' ';
154 | }
155 | } catch (err) {
156 | _didIteratorError = true;
157 | _iteratorError = err;
158 | } finally {
159 | try {
160 | if (!_iteratorNormalCompletion && _iterator.return) {
161 | _iterator.return();
162 | }
163 | } finally {
164 | if (_didIteratorError) {
165 | throw _iteratorError;
166 | }
167 | }
168 | }
169 |
170 | return s;
171 | };
172 |
173 | var svg = function svg(svgStr) {
174 | var width = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 100;
175 | var height = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 100;
176 |
177 | var parser = new DOMParser();
178 | var svgText = '';
179 | return parser.parseFromString(svgText, 'text/xml').documentElement;
180 | };
181 |
182 | var svgStr = function svgStr(svgText, viewPortWidth, viewPortHeight, viewBoxX, viewBoxY, viewBoxWidth, viewBoxHeight) {
183 | var s = svg(svgText, viewPortWidth, viewPortHeight, viewBoxX, viewBoxY, viewBoxWidth, viewBoxHeight);
184 |
185 | // base64
186 | // let data = 'data:image/svg+xml;base64,' + btoa(s.outerHTML);
187 |
188 | // uri component string
189 | var data = 'data:image/svg+xml;utf8,' + encodeURIComponent(s.outerHTML);
190 |
191 | return data;
192 | };
193 |
194 | module.exports = {
195 | svgStr: svgStr,
196 | styleMap2Str: styleMap2Str
197 | };
198 |
199 | /***/ }),
200 | /* 2 */
201 | /***/ (function(module, exports, __webpack_require__) {
202 |
203 | "use strict";
204 |
205 |
206 | function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
207 |
208 | var styleMap2Str = __webpack_require__(1).styleMap2Str;
209 |
210 | var baseRectangle = function baseRectangle(x, y, w, h, r1, r2, r3, r4, styleMap) {
211 | return '\n \n ';
212 | };
213 |
214 | var baseShapes = {
215 | barrel: function barrel(x, y, width, height, styleMap) {
216 | return '\n\n \n \n\n \n\n \n\n \n \n\n ';
217 | },
218 | circle: function circle(cx, cy, r, styleMap) {
219 | return '';
220 | },
221 | clipPath: function clipPath(id, baseShapeFn, baseShapeFnArgs, styleMap) {
222 | return '\n \n \n ' + baseShapeFn.apply(undefined, _toConsumableArray(baseShapeFnArgs)) + '\n \n \n ';
223 | },
224 | concaveHexagon: function concaveHexagon(x, y, width, height, styleMap) {
225 | return '\n ';
226 | },
227 | cutRectangle: function cutRectangle(x, y, width, height, cornerLength, styleMap) {
228 | return '\n \n ';
229 | },
230 | ellipse: function ellipse(cx, cy, rx, ry, styleMap) {
231 | return '\n \n ';
232 | },
233 | hexagon: function hexagon(x, y, width, height, styleMap) {
234 | return '\n ';
235 | },
236 | line: function line(x1, y1, x2, y2, styleMap) {
237 | return '';
238 | },
239 | rectangle: function rectangle(x, y, width, height, styleMap) {
240 | return baseRectangle(x, y, width, height, 0, 0, 0, 0, styleMap);
241 | },
242 | roundBottomRectangle: function roundBottomRectangle(x, y, width, height, styleMap) {
243 | return baseRectangle(x, y, width, height, 0, 0, .3 * height, .3 * height, styleMap);
244 | },
245 | roundRectangle: function roundRectangle(x, y, width, height, styleMap) {
246 | return baseRectangle(x, y, width, height, .04 * width, .04 * width, .04 * width, .04 * width, styleMap);
247 | },
248 | stadium: function stadium(x, y, width, height, styleMap) {
249 | var radiusRatio = .24 * Math.max(width, height);
250 | return baseRectangle(x, y, width, height, radiusRatio, radiusRatio, radiusRatio, radiusRatio, styleMap);
251 | },
252 | square: function square(x, y, length, styleMap) {
253 | return baseRectangle(x, y, length, length, 0, 0, 0, 0, styleMap);
254 | },
255 | text: function text(t, x, y, styleMap) {
256 | return '' + t + '';
257 | }
258 | };
259 |
260 | module.exports = baseShapes;
261 |
262 | /***/ }),
263 | /* 3 */
264 | /***/ (function(module, exports, __webpack_require__) {
265 |
266 | "use strict";
267 |
268 |
269 | var sbgnData = __webpack_require__(0);
270 |
271 | var sbgnStyle = new Map().set('unspecified entity', { w: 32, h: 32, shape: 'ellipse' }).set('simple chemical', { w: 48, h: 48, shape: 'ellipse' }).set('simple chemical multimer', { w: 48, h: 48, shape: 'ellipse' }).set('macromolecule', { w: 96, h: 48, shape: 'roundrectangle' }).set('macromolecule multimer', { w: 96, h: 48, shape: 'roundrectangle' }).set('nucleic acid feature', { w: 88, h: 56, shape: 'bottomroundrectangle' }).set('nucleic acid feature multimer', { w: 88, h: 52, shape: 'bottomroundrectangle' }).set('complex', { w: 10, h: 10, shape: 'cutrectangle' }).set('complex multimer', { w: 10, h: 10, shape: 'cutrectangle' }).set('source and sink', { w: 60, h: 60, shape: 'polygon' }).set('perturbing agent', { w: 140, h: 60, shape: 'concavehexagon' }).set('phenotype', { w: 140, h: 60, shape: 'hexagon' }).set('process', { w: 25, h: 25, shape: 'square' }).set('uncertain process', { w: 25, h: 25, shape: 'square' }).set('omitted process', { w: 25, h: 25, shape: 'square' }).set('association', { w: 25, h: 25, shape: 'ellipse' }).set('dissociation', { w: 25, h: 25, shape: 'ellipse' }).set('compartment', { w: 50, h: 50, shape: 'barrel' }).set('tag', { w: 100, h: 65, shape: 'tag' }).set('and', { w: 40, h: 40, shape: 'ellipse' }).set('or', { w: 40, h: 40, shape: 'ellipse' }).set('not', { w: 40, h: 40, shape: 'ellipse' });
272 |
273 | var sbgnArrowMap = new Map().set('necessary stimulation', 'triangle-cross').set('inhibition', 'tee').set('catalysis', 'circle').set('stimulation', 'triangle').set('production', 'triangle').set('modulation', 'diamond');
274 |
275 | var elementStyle = {
276 | sbgnShape: function sbgnShape(node) {
277 | var sbgnClass = sbgnData.sbgnClass(node).replace(' multimer', '');
278 | var style = sbgnStyle.get(sbgnClass);
279 | return style ? style.shape : 'ellipse';
280 | },
281 | sbgnArrowShape: function sbgnArrowShape(edge) {
282 | var sbgnClass = sbgnData.sbgnClass(edge);
283 | var shape = sbgnArrowMap.get(sbgnClass);
284 | return shape ? shape : 'none';
285 | },
286 | sbgnContent: function sbgnContent(node) {
287 | var sbgnClass = sbgnData.sbgnClass(node).replace(' multimer', '');
288 | var content = sbgnData.sbgnLabel(node);
289 |
290 | if (sbgnClass == 'and') {
291 | content = 'AND';
292 | }
293 | if (sbgnClass == 'or') {
294 | content = 'OR';
295 | }
296 | if (sbgnClass == 'not') {
297 | content = 'NOT';
298 | }
299 | if (sbgnClass == 'omitted process') {
300 | content = '\\\\';
301 | }
302 | if (sbgnClass == 'uncertain process') {
303 | content = '?';
304 | }
305 |
306 | return content;
307 | },
308 | dimensions: function dimensions(node) {
309 | var sbgnClass = sbgnData.sbgnClass(node);
310 | var dim = sbgnStyle.get(sbgnClass);
311 | if (dim == null) {
312 | throw new TypeError(sbgnClass + ' does not have a default width / height');
313 | }
314 | return dim;
315 | },
316 | width: function width(node) {
317 | return this.dimensions(node).w;
318 | },
319 | height: function height(node) {
320 | return this.dimensions(node).h;
321 | }
322 | };
323 |
324 | module.exports = elementStyle;
325 |
326 | /***/ }),
327 | /* 4 */
328 | /***/ (function(module, exports, __webpack_require__) {
329 |
330 | "use strict";
331 |
332 |
333 | function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
334 |
335 | var textWidth = __webpack_require__(10);
336 |
337 | var baseShapes = __webpack_require__(2);
338 | var sbgnData = __webpack_require__(0);
339 |
340 | var auxiliaryItems = {
341 | multiImgCloneMarker: function multiImgCloneMarker(x, y, width, height) {
342 |
343 | var cloneStyle = new Map().set('stroke', '#6A6A6A').set('stroke-width', '1').set('fill', '#D2D2D2');
344 |
345 | return baseShapes.rectangle(x, y, width, height, cloneStyle);
346 | },
347 | multiImgUnitOfInformation: function multiImgUnitOfInformation(x, y, width, height, uInfo) {
348 | var borderWidth = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : 3;
349 | var fontSize = arguments.length > 6 && arguments[6] !== undefined ? arguments[6] : 14;
350 |
351 | var text = uInfo.label.text;
352 | var uinfoRectStyle = new Map().set('stroke', '#555555').set('stroke-width', '' + borderWidth).set('fill', 'white').set('fill-opacity', 1);
353 |
354 | var textStyle = new Map().set('alignment-baseline', 'middle').set('font-size', fontSize + 'px').set('font-family', 'Helvetica Neue, Helvetica, sans-serif').set('text-anchor', 'middle');
355 |
356 | var uInfoWidth = textWidth(text, { family: textStyle.get('font-family'), size: fontSize }) + 5;
357 |
358 | var unitOfInformationSvg = '\n ' + baseShapes.roundRectangle(x, y, uInfoWidth, height, uinfoRectStyle) + '\n ' + baseShapes.text(text, x + uInfoWidth / 2, y + height / 2, textStyle) + '\n ';
359 |
360 | return unitOfInformationSvg;
361 | },
362 | multiImgStateVar: function multiImgStateVar(x, y, width, height, stateVar) {
363 | var borderWidth = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : 3;
364 | var fontSize = arguments.length > 6 && arguments[6] !== undefined ? arguments[6] : 14;
365 |
366 |
367 | var stateVarStyle = new Map().set('stroke', '#555555').set('stroke-width', '' + borderWidth).set('fill', 'white').set('fill-opacity', 1);
368 |
369 | var textStyle = new Map().set('alignment-baseline', 'middle').set('font-size', fontSize + 'px').set('font-family', 'Helvetica Neue, Helvetica, sans-serif').set('text-anchor', 'middle');
370 |
371 | var tw = textWidth(sbgnData.stateVarLabel(stateVar), { family: textStyle.get('font-family'), size: fontSize }) + 10;
372 | var w = Math.max(tw, 30);
373 | var statevariableSvg = '\n ' + baseShapes.stadium(x, y, w, height, stateVarStyle) + '\n ' + baseShapes.text(sbgnData.stateVarLabel(stateVar), x + w / 2, y + height / 2, textStyle) + '\n ';
374 |
375 | return statevariableSvg;
376 | },
377 | cloneMarker: function cloneMarker(nodeWidth, nodeHeight, shapeFn, shapeFnArgs) {
378 | var clipId = 'clonemarker';
379 |
380 | var cloneMarkerStyle = new Map().set('stroke', '#6A6A6A').set('stroke-width', '1.5').set('clip-path', 'url(#' + clipId + ')').set('fill', '#D2D2D2');
381 |
382 | var cloneMarkerSvg = '\n ' + baseShapes.clipPath(clipId, baseShapes.rectangle, [0, 3 * nodeHeight / 4, nodeWidth, nodeHeight, new Map()]) + '\n ' + shapeFn.apply(undefined, _toConsumableArray(shapeFnArgs).concat([cloneMarkerStyle])) + '\n ';
383 |
384 | return cloneMarkerSvg;
385 | }
386 | };
387 |
388 | module.exports = auxiliaryItems;
389 |
390 | /***/ }),
391 | /* 5 */
392 | /***/ (function(module, exports) {
393 |
394 | module.exports = __WEBPACK_EXTERNAL_MODULE_5__;
395 |
396 | /***/ }),
397 | /* 6 */
398 | /***/ (function(module, exports, __webpack_require__) {
399 |
400 | "use strict";
401 |
402 |
403 | var sbgnStyleSheet = __webpack_require__(7);
404 |
405 | var defaultOptions = {};
406 |
407 | module.exports = function (cytoscape) {
408 | return sbgnStyleSheet(cytoscape);
409 | };
410 |
411 | /***/ }),
412 | /* 7 */
413 | /***/ (function(module, exports, __webpack_require__) {
414 |
415 | "use strict";
416 |
417 |
418 | var elementStyle = __webpack_require__(3);
419 | var sbgnsvg = __webpack_require__(8);
420 |
421 | var sbgnStyleSheet = function sbgnStyleSheet(cytoscape) {
422 |
423 | return cytoscape.stylesheet()
424 | // general node style
425 | .selector('node').css({
426 | 'shape': function shape(node) {
427 | return elementStyle.sbgnShape(node);
428 | },
429 | 'content': function content(node) {
430 | return elementStyle.sbgnContent(node);
431 | },
432 | 'font-size': 20,
433 | 'width': function width(node) {
434 | return elementStyle.width(node);
435 | },
436 | 'height': function height(node) {
437 | return elementStyle.height(node);
438 | },
439 | 'text-valign': 'center',
440 | 'text-halign': 'center',
441 | 'border-width': 1.5,
442 | 'border-color': '#555',
443 | 'background-color': '#f6f6f6',
444 | 'text-opacity': 1,
445 | 'opacity': 1,
446 | 'text-outline-color': 'white',
447 | 'text-outline-opacity': 1,
448 | 'text-outline-width': 0.75
449 | }).selector('node:selected').css({
450 | 'background-color': '#d67614',
451 | 'target-arrow-color': '#000',
452 | 'text-outline-color': '#000'
453 | }).selector('node:active').css({
454 | 'overlay-color': '#d67614',
455 | 'overlay-padding': '14'
456 | })
457 |
458 | // draw sbgn specific styling (auxiliary items, clonemarker, etc.)
459 | .selector('\n node[class="unspecified entity"],\n node[class="simple chemical"], node[class="simple chemical multimer"],\n node[class="macromolecule"], node[class="macromolecule multimer"],\n node[class="nucleic acid feature"], node[class="nucleic acid feature multimer"],\n node[class="perturbing agent"],\n node[class="phenotype"],\n node[class="complex"], node[class="complex multimer"], node[class="compartment"]\n ').css({
460 | 'background-image': function backgroundImage(node) {
461 | return sbgnsvg.draw(node).bgImage;
462 | },
463 | 'background-width': function backgroundWidth(node) {
464 | return sbgnsvg.draw(node).bgWidth;
465 | },
466 | 'background-position-x': function backgroundPositionX(node) {
467 | return sbgnsvg.draw(node).bgPosX;
468 | },
469 | 'background-position-y': function backgroundPositionY(node) {
470 | return sbgnsvg.draw(node).bgPosY;
471 | },
472 | 'background-fit': function backgroundFit(node) {
473 | return sbgnsvg.draw(node).bgFit;
474 | },
475 | 'background-clip': function backgroundClip(node) {
476 | return sbgnsvg.draw(node).bgClip;
477 | },
478 | 'padding': function padding(node) {
479 | return sbgnsvg.draw(node).padding;
480 | },
481 | 'border-width': function borderWidth(node) {
482 | return sbgnsvg.draw(node).borderWidth;
483 | }
484 | }).selector('\n node[class="simple chemical multimer"],\n node[class="macromolecule multimer"],\n node[class="nucleic acid feature multimer"],\n node[class="complex multimer"]\n ').css({
485 | 'ghost': 'yes',
486 | 'ghost-opacity': 1
487 | }).selector('\n node[class="macromolecule multimer"],\n node[class="nucleic acid feature multimer"]\n ').css({
488 | 'ghost-offset-x': 12,
489 | 'ghost-offset-y': 12
490 | }).selector('\n node[class="simple chemical multimer"]\n ').css({
491 | 'ghost-offset-x': 5,
492 | 'ghost-offset-y': 5
493 | }).selector('\n node[class="complex multimer"]\n ').css({
494 | 'ghost-offset-x': 16,
495 | 'ghost-offset-y': 16
496 | })
497 |
498 | // compound node specific style
499 | .selector('node[class="complex"], node[class="complex multimer"], node[class="compartment"]').css({
500 | 'compound-sizing-wrt-labels': 'exclude',
501 | 'text-valign': 'bottom',
502 | 'text-halign': 'center'
503 | })
504 |
505 | // process node specific style
506 | .selector('node[class="association"], node[class="dissociation"]').css({
507 | 'background-opacity': 1
508 | }).selector('node[class="association"]').css({
509 | 'background-color': '#6B6B6B'
510 | })
511 |
512 | // source and sink and dissociation are drawn differently because
513 | // of their unique shape
514 | .selector('node[class="source and sink"]').css({
515 | 'background-image': function backgroundImage(node) {
516 | return sbgnsvg.draw(node);
517 | },
518 | 'background-fit': 'none',
519 | 'background-width': '100%',
520 | 'background-height': '100%',
521 | 'background-clip': 'none',
522 | 'background-repeat': 'no-repeat',
523 | 'border-width': 0,
524 | 'shape-polygon-points': '-0.86, 0.5, -0.75, 0.65, -1, 0.95, -0.95, 1, -0.65, 0.75, -0.5, 0.86, 0, 1, 0.5, 0.86, 0.71, 0.71, 0.86, 0.5, 1, 0, 0.86, -0.5, 0.75, -0.65, 1, -0.95, 0.95, -1, 0.65, -0.75, 0.5, -0.86, 0, -1, -0.5, -0.86, -0.71, -0.71, -0.86, -0.5, -1, 0'
525 | })
526 |
527 | // source and sink and dissociation are drawn differently because
528 | // of their unique shape
529 | .selector('node[class="dissociation"]').css({
530 | 'background-image': function backgroundImage(node) {
531 | return sbgnsvg.draw(node);
532 | },
533 | 'background-fit': 'none',
534 | 'background-width': '100%',
535 | 'background-height': '100%',
536 | 'background-clip': 'none',
537 | 'background-repeat': 'no-repeat',
538 | 'border-width': 0
539 | })
540 |
541 | // edge styling
542 | .selector('edge').css({
543 | 'arrow-scale': 1.75,
544 | 'curve-style': 'bezier',
545 | 'line-color': '#555',
546 | 'target-arrow-fill': 'hollow',
547 | 'source-arrow-fill': 'hollow',
548 | 'width': 1.5,
549 | 'target-arrow-color': '#555',
550 | 'source-arrow-color': '#555',
551 | 'text-border-color': '#555',
552 | 'color': '#555'
553 | }).selector('edge:selected').css({
554 | 'color': '#d67614',
555 | 'line-color': '#d67614',
556 | 'text-border-color': '#d67614',
557 | 'source-arrow-color': '#d67614',
558 | 'target-arrow-color': '#d67614'
559 | }).selector('edge:active').css({
560 | 'background-opacity': 0.7, 'overlay-color': '#d67614',
561 | 'overlay-padding': '8'
562 | }).selector('edge[cardinality > 0]').css({
563 | 'text-background-shape': 'rectangle',
564 | 'text-border-opacity': '1',
565 | 'text-border-width': '1',
566 | 'text-background-color': 'white',
567 | 'text-background-opacity': '1'
568 | }).selector('edge[class="consumption"][cardinality > 0], edge[class="production"][cardinality > 0]').css({
569 | 'source-label': function sourceLabel(edge) {
570 | return '' + edge.data('cardinality');
571 | },
572 | 'source-text-offset': 10
573 | }).selector('edge[class]').css({
574 | 'target-arrow-shape': function targetArrowShape(edge) {
575 | return elementStyle.sbgnArrowShape(edge);
576 | },
577 | 'source-arrow-shape': 'none'
578 | }).selector('edge[class="inhibition"]').css({
579 | 'target-arrow-fill': 'filled'
580 | }).selector('edge[class="production"]').css({
581 | 'target-arrow-fill': 'filled'
582 | })
583 |
584 | // core
585 | .selector('core').css({
586 | 'selection-box-color': '#d67614',
587 | 'selection-box-opacity': '0.2', 'selection-box-border-color': '#d67614'
588 | });
589 | };
590 |
591 | module.exports = sbgnStyleSheet;
592 |
593 | /***/ }),
594 | /* 8 */
595 | /***/ (function(module, exports, __webpack_require__) {
596 |
597 | "use strict";
598 |
599 |
600 | var memoize = __webpack_require__(5);
601 |
602 | var containerNodes = __webpack_require__(9);
603 | var entityPoolNodes = __webpack_require__(11);
604 | var processNodes = __webpack_require__(12);
605 |
606 | var sbgnData = __webpack_require__(0);
607 |
608 | var cacheKeyFn = function cacheKeyFn(node) {
609 | return '' + JSON.stringify(node.id());
610 | };
611 |
612 | var sbgnNodeShapeMap = new Map()
613 | // process nodes
614 | .set('dissociation', memoize(processNodes.dissociation, cacheKeyFn)).set('phenotype', memoize(processNodes.phenotype, cacheKeyFn))
615 |
616 | // entity pool nodes
617 | .set('source and sink', memoize(entityPoolNodes.sourceAndSink, cacheKeyFn)).set('unspecified entity', memoize(entityPoolNodes.unspecifiedEntity, cacheKeyFn)).set('simple chemical', memoize(entityPoolNodes.simpleChemical, cacheKeyFn)).set('macromolecule', memoize(entityPoolNodes.macromolecule, cacheKeyFn)).set('nucleic acid feature', memoize(entityPoolNodes.nucleicAcidFeature, cacheKeyFn)).set('complex', memoize(entityPoolNodes.complex, cacheKeyFn)).set('perturbing agent', memoize(entityPoolNodes.perturbingAgent, cacheKeyFn))
618 |
619 | // container nodes
620 | .set('compartment', memoize(containerNodes.compartment, cacheKeyFn));
621 |
622 | var draw = function draw(node) {
623 | var sbgnClass = sbgnData.sbgnClass(node).replace(' multimer', '');
624 | var shapeFn = sbgnNodeShapeMap.get(sbgnClass);
625 | if (shapeFn == null) {
626 | throw new TypeError(sbgnClass + ' does not have a shape implementation');
627 | }
628 | return shapeFn(node);
629 | };
630 |
631 | module.exports = {
632 | draw: draw
633 | };
634 |
635 | /***/ }),
636 | /* 9 */
637 | /***/ (function(module, exports, __webpack_require__) {
638 |
639 | "use strict";
640 |
641 |
642 | var svgStr = __webpack_require__(1).svgStr;
643 | var sbgnData = __webpack_require__(0);
644 | var memoize = __webpack_require__(5);
645 |
646 | var auxiliaryItems = __webpack_require__(4);
647 | var baseShapes = __webpack_require__(2);
648 |
649 | var containerNodes = {
650 | compartment: function compartment(node) {
651 | var auxItemWidth = 60;
652 | var auxItemHeight = 40;
653 | var uInfos = sbgnData.getUnitInfos(node);
654 |
655 | var style = new Map().set('stroke', '#555555').set('stroke-width', '6');
656 |
657 | var uInfoSvg = svgStr(uInfos.length > 0 ? auxiliaryItems.multiImgUnitOfInformation(2, 0, auxItemWidth - 5, auxItemHeight - 3, uInfos[0]) : '', auxItemWidth, auxItemHeight);
658 |
659 | var lineSvg = svgStr(uInfos.length > 0 ? baseShapes.line(0, 0, auxItemWidth, 0, style) : '', auxItemWidth, auxItemHeight);
660 |
661 | return {
662 | bgImage: [lineSvg, uInfoSvg],
663 | bgWidth: ['100%'],
664 | bgPosX: ['0%', '25%'],
665 | bgPosY: ['19px', '0%'],
666 | bgFit: ['contain', 'none'],
667 | bgClip: 'node',
668 | padding: '38px',
669 | borderWidth: '4'
670 | };
671 | }
672 | };
673 |
674 | module.exports = containerNodes;
675 |
676 | /***/ }),
677 | /* 10 */
678 | /***/ (function(module, exports) {
679 |
680 | module.exports = __WEBPACK_EXTERNAL_MODULE_10__;
681 |
682 | /***/ }),
683 | /* 11 */
684 | /***/ (function(module, exports, __webpack_require__) {
685 |
686 | "use strict";
687 |
688 |
689 | var baseShapes = __webpack_require__(2);
690 | var auxiliaryItems = __webpack_require__(4);
691 |
692 | var svgStr = __webpack_require__(1).svgStr;
693 | var getUnitInfos = __webpack_require__(0).getUnitInfos;
694 | var getStateVars = __webpack_require__(0).getStateVars;
695 | var hasClonemarker = __webpack_require__(0).hasClonemarker;
696 |
697 | var element = __webpack_require__(3);
698 |
699 | var entityPoolNodes = {
700 | unspecifiedEntity: function unspecifiedEntity(node) {
701 | var auxItemWidth = 100;
702 | var auxItemHeight = 20;
703 | var borderWidth = 2;
704 | var fontSize = 10;
705 | var uInfos = getUnitInfos(node);
706 | var sVars = getStateVars(node);
707 |
708 | var style = new Map().set('stroke', '#6A6A6A').set('stroke-width', '1');
709 |
710 | var cloneMarkerSvg = svgStr(hasClonemarker(node) ? auxiliaryItems.multiImgCloneMarker(0, 2, auxItemWidth, auxItemHeight - 3) : '', auxItemWidth, auxItemHeight);
711 |
712 | var uInfoSvg = svgStr(uInfos.length > 0 ? auxiliaryItems.multiImgUnitOfInformation(2, 0, auxItemWidth - 5, auxItemHeight - 3, uInfos[0], borderWidth, fontSize) : '', auxItemWidth, auxItemHeight);
713 |
714 | var sVarSvg = svgStr(sVars.length > 0 ? auxiliaryItems.multiImgStateVar(2, 0, auxItemWidth - 5, auxItemHeight - 3, sVars[0], borderWidth, fontSize) : '', auxItemWidth, auxItemHeight);
715 |
716 | var topLine = svgStr(uInfos.length + sVars.length > 0 ? baseShapes.line(0, 0, auxItemWidth, 0, style) : '', auxItemWidth, auxItemHeight);
717 |
718 | var bottomLine = svgStr(hasClonemarker(node) || uInfos.length > 0 ? baseShapes.line(0, 0, auxItemWidth, 0, style) : '', auxItemWidth, auxItemHeight);
719 | return {
720 | bgImage: [bottomLine, topLine, cloneMarkerSvg, uInfoSvg, sVarSvg],
721 | bgWidth: ['100%', '100%', '100%'],
722 | bgPosX: ['0%', '0%', '0%', '20px', '40px'],
723 | bgPosY: ['52px', '8px', '32px', '44px', '0%'],
724 | bgFit: ['cover', 'cover', 'none', 'none'],
725 | bgClip: 'node',
726 | padding: '8px',
727 | borderWidth: 2
728 | };
729 | },
730 | simpleChemical: function simpleChemical(node) {
731 | var auxItemWidth = 100;
732 | var auxItemHeight = 20;
733 | var borderWidth = 2;
734 | var fontSize = 10;
735 | var uInfos = getUnitInfos(node);
736 |
737 | var style = new Map().set('stroke', '#6A6A6A').set('stroke-width', '1');
738 |
739 | var cloneMarkerSvg = svgStr(hasClonemarker(node) ? auxiliaryItems.multiImgCloneMarker(0, 2, auxItemWidth, auxItemHeight - 3) : '', auxItemWidth, auxItemHeight);
740 |
741 | var uInfoSvg = svgStr(uInfos.length > 0 ? auxiliaryItems.multiImgUnitOfInformation(2, 0, auxItemWidth - 5, auxItemHeight - 3, uInfos[0], borderWidth, fontSize) : '', auxItemWidth, auxItemHeight);
742 |
743 | var topLine = svgStr(uInfos.length > 0 ? baseShapes.line(0, 0, auxItemWidth, 0, style) : '', auxItemWidth, auxItemHeight);
744 |
745 | var bottomLine = svgStr(hasClonemarker(node) || uInfos.length > 0 ? baseShapes.line(0, 0, auxItemWidth, 0, style) : '', auxItemWidth, auxItemHeight);
746 |
747 | return {
748 | bgImage: [bottomLine, topLine, cloneMarkerSvg, uInfoSvg],
749 | bgWidth: ['100%', '100%', '100%'],
750 | bgPosX: ['0%', '0%', '0%', '12px'],
751 | bgPosY: ['52px', '8px', '48px', '0px'],
752 | bgFit: ['cover', 'cover', 'none', 'none'],
753 | bgClip: 'node',
754 | padding: '8px',
755 | borderWidth: 2
756 | };
757 | },
758 | macromolecule: function macromolecule(node) {
759 | var auxItemWidth = 100;
760 | var auxItemHeight = 20;
761 | var borderWidth = 2;
762 | var fontSize = 10;
763 | var uInfos = getUnitInfos(node);
764 | var sVars = getStateVars(node);
765 |
766 | var style = new Map().set('stroke', '#6A6A6A').set('stroke-width', '1');
767 |
768 | var cloneMarkerSvg = svgStr(hasClonemarker(node) ? auxiliaryItems.multiImgCloneMarker(0, 2, auxItemWidth, auxItemHeight - 3) : '', auxItemWidth, auxItemHeight);
769 |
770 | var uInfoSvg = svgStr(uInfos.length > 0 ? auxiliaryItems.multiImgUnitOfInformation(2, 0, auxItemWidth - 5, auxItemHeight - 3, uInfos[0], borderWidth, fontSize) : '', auxItemWidth, auxItemHeight);
771 |
772 | var sVarSvg = svgStr(sVars.length > 0 ? auxiliaryItems.multiImgStateVar(2, 0, auxItemWidth - 5, auxItemHeight - 3, sVars[0], borderWidth, fontSize) : '', auxItemWidth, auxItemHeight);
773 |
774 | var topLine = svgStr(uInfos.length + sVars.length > 0 ? baseShapes.line(0, 0, auxItemWidth, 0, style) : '', auxItemWidth, auxItemHeight);
775 |
776 | var bottomLine = svgStr(hasClonemarker(node) || uInfos.length > 0 ? baseShapes.line(0, 0, auxItemWidth, 0, style) : '', auxItemWidth, auxItemHeight);
777 |
778 | return {
779 | bgImage: [bottomLine, topLine, cloneMarkerSvg, uInfoSvg, sVarSvg],
780 | bgWidth: ['100%', '100%', '100%'],
781 | bgPosX: ['0%', '0%', '0%', '20px', '40px'],
782 | bgPosY: ['52px', '8px', '52px', '44px', '0%'],
783 | bgFit: ['cover', 'cover', 'none', 'none'],
784 | bgClip: 'node',
785 | padding: '8px',
786 | borderWidth: 2
787 | };
788 | },
789 | nucleicAcidFeature: function nucleicAcidFeature(node) {
790 | var auxItemWidth = 100;
791 | var auxItemHeight = 20;
792 | var borderWidth = 2;
793 | var fontSize = 10;
794 | var uInfos = getUnitInfos(node);
795 | var sVars = getStateVars(node);
796 |
797 | var style = new Map().set('stroke', '#6A6A6A').set('stroke-width', '1');
798 |
799 | var cloneMarkerSvg = svgStr(hasClonemarker(node) ? auxiliaryItems.multiImgCloneMarker(0, 2, auxItemWidth, auxItemHeight - 3) : '', auxItemWidth, auxItemHeight);
800 |
801 | var uInfoSvg = svgStr(uInfos.length > 0 ? auxiliaryItems.multiImgUnitOfInformation(2, 0, auxItemWidth - 5, auxItemHeight - 3, uInfos[0], borderWidth, fontSize) : '', auxItemWidth, auxItemHeight);
802 |
803 | var sVarSvg = svgStr(sVars.length > 0 ? auxiliaryItems.multiImgStateVar(2, 0, auxItemWidth - 5, auxItemHeight - 3, sVars[0], borderWidth, fontSize) : '', auxItemWidth, auxItemHeight);
804 |
805 | var topLine = svgStr(sVars.length > 0 ? baseShapes.line(0, 0, auxItemWidth, 0, style) : '', auxItemWidth, auxItemHeight);
806 |
807 | var bottomLine = svgStr(hasClonemarker(node) || uInfos.length > 0 ? baseShapes.line(0, 0, auxItemWidth, 0, style) : '', auxItemWidth, auxItemHeight);
808 |
809 | return {
810 | bgImage: [bottomLine, topLine, cloneMarkerSvg, uInfoSvg, sVarSvg],
811 | bgWidth: ['100%', '100%', '100%'],
812 | bgPosX: ['0%', '0%', '0%', '20px', '40px'],
813 | bgPosY: ['52px', '8px', '52px', '44px', '0%'],
814 | bgFit: ['cover', 'cover', 'none', 'none'],
815 | bgClip: 'node',
816 | padding: '8px',
817 | borderWidth: 2
818 | };
819 | },
820 | complex: function complex(node) {
821 | var itemW = 60;
822 | var itemH = 24;
823 | var uInfos = getUnitInfos(node);
824 | var sVars = getStateVars(node);
825 |
826 | var images = [];
827 | var bgWidth = [];
828 | var bgHeight = [];
829 | var bgPosX = [];
830 | var bgPosY = [];
831 | var bgFit = [];
832 |
833 | var style = new Map().set('stroke', '#555555').set('stroke-width', '6');
834 |
835 | // order of svg image generation matters
836 | if (uInfos.length + sVars.length > 0) {
837 | var topLineSvg = svgStr(baseShapes.line(0, 0, itemW, 0, style), itemW, itemH);
838 | images.push(topLineSvg);
839 | bgWidth.push('100%');
840 | bgPosX.push('0%');
841 | bgPosY.push('11px');
842 | bgFit.push('none');
843 | }
844 |
845 | if (hasClonemarker(node)) {
846 | var bottomLineSvg = svgStr(baseShapes.line(0, 0, itemW, 0, style), itemW, itemH);
847 | images.push(bottomLineSvg);
848 | bgWidth.push('100%');
849 | bgPosX.push('0%');
850 | bgPosY.push('100%');
851 | bgFit.push('none');
852 | }
853 |
854 | if (hasClonemarker(node)) {
855 | var cloneSvg = svgStr(auxiliaryItems.multiImgCloneMarker(0, 2, itemW, itemH - 3), itemW, itemH);
856 | images.push(cloneSvg);
857 | bgWidth.push('100%');
858 | bgPosX.push('0%');
859 | bgPosY.push('100%');
860 | bgFit.push('none');
861 | }
862 |
863 | if (uInfos.length > 0) {
864 | var uInfoSvg = svgStr(auxiliaryItems.multiImgUnitOfInformation(2, 0, itemW - 5, itemH - 3, uInfos[0]), itemW, itemH);
865 | images.push(uInfoSvg);
866 | bgPosX.push('25%');
867 | bgPosY.push('0%');
868 | bgFit.push('none');
869 | }
870 |
871 | if (sVars.length > 0) {
872 | var sVarSvg = svgStr(auxiliaryItems.multiImgStateVar(2, 0, itemW - 5, itemH - 3, sVars[0]), itemW, itemH);
873 | images.push(sVarSvg);
874 | bgPosX.push('88%');
875 | bgPosY.push('0%');
876 | bgFit.push('none');
877 | }
878 |
879 | return {
880 | bgImage: images,
881 | bgWidth: bgWidth,
882 | bgPosX: bgPosX,
883 | bgPosY: bgPosY,
884 | bgFit: bgFit,
885 | bgClip: 'node',
886 | padding: '22px',
887 | borderWidth: 4
888 | };
889 | },
890 | sourceAndSink: function sourceAndSink(node) {
891 | var _element$dimensions = element.dimensions(node),
892 | nw = _element$dimensions.w,
893 | nh = _element$dimensions.h;
894 |
895 | var centerX = nw / 2;
896 | var centerY = nh / 2;
897 | var radius = (nw - 2) / 2;
898 |
899 | var styleMap = new Map().set('stroke', '#6A6A6A').set('stroke-linecap', 'square').set('stroke-width', '1.5').set('fill', 'none');
900 |
901 | var shapeArgs = [centerX, centerY, radius];
902 |
903 | var sourceAndSinkSvg = '\n ' + baseShapes.circle.apply(baseShapes, shapeArgs.concat([styleMap])) + '\n ' + (hasClonemarker(node) ? auxiliaryItems.cloneMarker(nw, nh, baseShapes.circle, shapeArgs) : '') + '\n ' + baseShapes.line(0, nh, nw, 0, styleMap) + '\n ';
904 |
905 | return svgStr(sourceAndSinkSvg, nw, nh, 0, 0, nw, nh);
906 | },
907 | perturbingAgent: function perturbingAgent(node) {
908 | var auxItemWidth = 100;
909 | var auxItemHeight = 20;
910 | var borderWidth = 2;
911 | var fontSize = 10;
912 | var uInfos = getUnitInfos(node);
913 |
914 | var style = new Map().set('stroke', '#6A6A6A').set('stroke-width', '1');
915 |
916 | var cloneMarkerSvg = svgStr(hasClonemarker(node) ? auxiliaryItems.multiImgCloneMarker(0, 2, auxItemWidth, auxItemHeight - 3) : '', auxItemWidth, auxItemHeight);
917 |
918 | var uInfoSvg = svgStr(uInfos.length > 0 ? auxiliaryItems.multiImgUnitOfInformation(2, 0, auxItemWidth - 5, auxItemHeight - 3, uInfos[0], borderWidth, fontSize) : '', auxItemWidth, auxItemHeight);
919 |
920 | var topLine = svgStr(uInfos.length > 0 ? baseShapes.line(0, 0, auxItemWidth, 0, style) : '', auxItemWidth, auxItemHeight);
921 |
922 | var bottomLine = svgStr(hasClonemarker(node) || uInfos.length > 0 ? baseShapes.line(0, 0, auxItemWidth, 0, style) : '', auxItemWidth, auxItemHeight);
923 |
924 | return {
925 | bgImage: [bottomLine, topLine, cloneMarkerSvg, uInfoSvg],
926 | bgWidth: ['100%', '100%', '100%'],
927 | bgPosX: ['0%', '0%', '0%', '20px'],
928 | bgPosY: ['56px', '8px', '56px', '0%'],
929 | bgFit: ['cover', 'cover', 'none', 'none'],
930 | bgClip: 'node',
931 | padding: '8px',
932 | borderWidth: 2
933 | };
934 | }
935 | };
936 |
937 | module.exports = entityPoolNodes;
938 |
939 | /***/ }),
940 | /* 12 */
941 | /***/ (function(module, exports, __webpack_require__) {
942 |
943 | "use strict";
944 |
945 |
946 | var baseShapes = __webpack_require__(2);
947 | var auxiliaryItems = __webpack_require__(4);
948 |
949 | var svgStr = __webpack_require__(1).svgStr;
950 | var hasClonemarker = __webpack_require__(0).hasClonemarker;
951 |
952 | var element = __webpack_require__(3);
953 |
954 | var processNodes = {
955 | dissociation: function dissociation(node) {
956 | var _element$dimensions = element.dimensions(node),
957 | nw = _element$dimensions.w,
958 | nh = _element$dimensions.h;
959 |
960 | var centerX = nw / 2;
961 | var centerY = nh / 2;
962 | var outerRadius = (Math.min(nw, nh) - 2) / 2;
963 | var innerRadius = (Math.min(nw, nh) - 2) / 3;
964 |
965 | var styleMap = new Map().set('stroke', '#6A6A6A').set('stroke-width', '2').set('fill', 'none');
966 |
967 | var dissociationSvg = '\n ' + baseShapes.circle(centerX, centerY, outerRadius, styleMap) + '\n ' + baseShapes.circle(centerX, centerY, innerRadius, styleMap) + '\n ';
968 | return svgStr(dissociationSvg, nw, nh);
969 | },
970 | phenotype: function phenotype(node) {
971 | var auxItemWidth = 100;
972 | var auxItemHeight = 20;
973 |
974 | var style = new Map().set('stroke', '#6A6A6A').set('stroke-width', '1');
975 |
976 | var cloneMarkerSvg = svgStr(hasClonemarker(node) ? auxiliaryItems.multiImgCloneMarker(0, 2, auxItemWidth, auxItemHeight - 3) : '', auxItemWidth, auxItemHeight, 0, 0, auxItemWidth, auxItemHeight);
977 |
978 | var bottomLine = svgStr(hasClonemarker(node) ? baseShapes.line(0, 0, auxItemWidth, 0, style) : '', auxItemWidth, auxItemHeight, 0, 0, auxItemWidth, auxItemHeight);
979 |
980 | return {
981 | bgImage: [bottomLine, cloneMarkerSvg],
982 | bgWidth: ['100%', '100%'],
983 | bgPosX: ['0%', '0%'],
984 | bgPosY: ['56px', '56px'],
985 | bgFit: ['cover', 'none'],
986 | bgClip: 'node',
987 | padding: '8px',
988 | borderWidth: 2
989 | };
990 | }
991 | };
992 |
993 | module.exports = processNodes;
994 |
995 | /***/ })
996 | /******/ ]);
997 | });
--------------------------------------------------------------------------------
/demo.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | SBGN stylesheet demo
8 |
9 |
10 |
11 |
12 |
35 |
36 |
37 |
38 | cytoscape-sbgn-stylesheet demo
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
--------------------------------------------------------------------------------
/demo.js:
--------------------------------------------------------------------------------
1 | var sbgnStylesheet = require('./build/bundle.js');
2 | var cytoscape = window.cytoscape;
3 |
4 | var cy = window.cy = cytoscape({
5 | container: document.getElementById('cy'),
6 | elements: fetch('./demo.json').then( res => res.json() ),
7 | layout: { name: 'preset' },
8 | style: sbgnStylesheet(cytoscape)
9 | });
--------------------------------------------------------------------------------
/demo.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "data": {
4 | "id": "glyph23",
5 | "class": "simple chemical",
6 | "label": "Ca2+",
7 | "parent": "glyph2",
8 | "clonemarker": false,
9 | "stateVariables": [],
10 | "unitsOfInformation": [],
11 | "bbox": {
12 | "x": 1409.3416303507177,
13 | "y": 170.3243361927971,
14 | "w": 60,
15 | "h": 60
16 | }
17 | },
18 | "position": {
19 | "x": 1234.605196936252,
20 | "y": 69.5655680733905
21 | },
22 | "group": "nodes",
23 | "removed": false,
24 | "selected": false,
25 | "selectable": true,
26 | "locked": false,
27 | "grabbable": true,
28 | "pannable": false,
29 | "classes": ""
30 | },
31 | {
32 | "data": {
33 | "id": "glyph32",
34 | "class": "phenotype",
35 | "label": "muscle contraction",
36 | "parent": "glyph2",
37 | "clonemarker": false,
38 | "stateVariables": [],
39 | "unitsOfInformation": [],
40 | "bbox": {
41 | "x": 1976.8873538946682,
42 | "y": 651.7369383828263,
43 | "w": 160,
44 | "h": 60
45 | }
46 | },
47 | "position": {
48 | "x": 2197.7323146171566,
49 | "y": 1095.7604895957215
50 | },
51 | "group": "nodes",
52 | "removed": false,
53 | "selected": false,
54 | "selectable": true,
55 | "locked": false,
56 | "grabbable": true,
57 | "pannable": false,
58 | "classes": ""
59 | },
60 | {
61 | "data": {
62 | "id": "glyph37",
63 | "class": "complex",
64 | "label": "",
65 | "parent": "glyph2",
66 | "clonemarker": false,
67 | "stateVariables": [
68 | {
69 | "id": "glyph37a",
70 | "class": "state variable",
71 | "state": {
72 | "variable": "",
73 | "value": "tense"
74 | }
75 | }
76 | ],
77 | "unitsOfInformation": [],
78 | "bbox": {
79 | "x": 1891.4159362399225,
80 | "y": 479.6244130185455,
81 | "w": 121.5,
82 | "h": 136.5
83 | }
84 | },
85 | "position": {
86 | "x": 2200.592163339548,
87 | "y": 824.7365081837149
88 | },
89 | "group": "nodes",
90 | "removed": false,
91 | "selected": false,
92 | "selectable": true,
93 | "locked": false,
94 | "grabbable": true,
95 | "pannable": false,
96 | "classes": ""
97 | },
98 | {
99 | "data": {
100 | "id": "glyph39",
101 | "class": "macromolecule",
102 | "label": "myosin",
103 | "parent": "glyph37",
104 | "clonemarker": false,
105 | "stateVariables": [],
106 | "unitsOfInformation": [],
107 | "bbox": {
108 | "x": 1891.4159362399225,
109 | "y": 517.1244130185455,
110 | "w": 120,
111 | "h": 60
112 | }
113 | },
114 | "position": {
115 | "x": 2201.011704216743,
116 | "y": 780.2521185889852
117 | },
118 | "group": "nodes",
119 | "removed": false,
120 | "selected": false,
121 | "selectable": true,
122 | "locked": false,
123 | "grabbable": true,
124 | "pannable": false,
125 | "classes": ""
126 | },
127 | {
128 | "data": {
129 | "id": "glyph31",
130 | "class": "macromolecule",
131 | "label": "actin",
132 | "parent": "glyph37",
133 | "clonemarker": false,
134 | "stateVariables": [],
135 | "unitsOfInformation": [],
136 | "bbox": {
137 | "x": 1891.4159362399225,
138 | "y": 442.1244130185455,
139 | "w": 120,
140 | "h": 60
141 | }
142 | },
143 | "position": {
144 | "x": 2200.1726224623526,
145 | "y": 869.2208977784445
146 | },
147 | "group": "nodes",
148 | "removed": false,
149 | "selected": false,
150 | "selectable": true,
151 | "locked": false,
152 | "grabbable": true,
153 | "pannable": false,
154 | "classes": ""
155 | },
156 | {
157 | "data": {
158 | "id": "glyph41",
159 | "class": "process",
160 | "label": "",
161 | "parent": "glyph2",
162 | "clonemarker": false,
163 | "stateVariables": [],
164 | "unitsOfInformation": [],
165 | "bbox": {
166 | "x": 1488.6367504586137,
167 | "y": 248.3516476521878,
168 | "w": 20,
169 | "h": 20
170 | }
171 | },
172 | "position": {
173 | "x": 1371.5738448257136,
174 | "y": 69.14739321378485
175 | },
176 | "group": "nodes",
177 | "removed": false,
178 | "selected": false,
179 | "selectable": true,
180 | "locked": false,
181 | "grabbable": true,
182 | "pannable": false,
183 | "classes": ""
184 | },
185 | {
186 | "data": {
187 | "id": "glyph21",
188 | "class": "macromolecule",
189 | "label": "nAChR",
190 | "parent": "glyph2",
191 | "clonemarker": false,
192 | "stateVariables": [
193 | {
194 | "id": "glyph21a",
195 | "class": "state variable",
196 | "state": {
197 | "variable": "",
198 | "value": "open"
199 | }
200 | }
201 | ],
202 | "unitsOfInformation": [],
203 | "bbox": {
204 | "x": 1384.4372296707947,
205 | "y": 318.76950553546544,
206 | "w": 120,
207 | "h": 60
208 | }
209 | },
210 | "position": {
211 | "x": 1369.384921498512,
212 | "y": 215.979564984629
213 | },
214 | "group": "nodes",
215 | "removed": false,
216 | "selected": false,
217 | "selectable": true,
218 | "locked": false,
219 | "grabbable": true,
220 | "pannable": false,
221 | "classes": ""
222 | },
223 | {
224 | "data": {
225 | "id": "glyph36",
226 | "class": "complex",
227 | "label": "",
228 | "parent": "glyph2",
229 | "clonemarker": false,
230 | "stateVariables": [],
231 | "unitsOfInformation": [],
232 | "bbox": {
233 | "x": 1804.8844575025842,
234 | "y": 102.97480600819699,
235 | "w": 121.5,
236 | "h": 136.5
237 | }
238 | },
239 | "position": {
240 | "x": 1817.9165947430324,
241 | "y": 230.45301725763466
242 | },
243 | "group": "nodes",
244 | "removed": false,
245 | "selected": false,
246 | "selectable": true,
247 | "locked": false,
248 | "grabbable": true,
249 | "pannable": false,
250 | "classes": ""
251 | },
252 | {
253 | "data": {
254 | "id": "glyph35",
255 | "class": "simple chemical",
256 | "label": "ATP",
257 | "parent": "glyph36",
258 | "clonemarker": false,
259 | "stateVariables": [],
260 | "unitsOfInformation": [],
261 | "bbox": {
262 | "x": 1774.8844575025842,
263 | "y": 140.474806008197,
264 | "w": 60,
265 | "h": 60
266 | }
267 | },
268 | "position": {
269 | "x": 1819.1560429828219,
270 | "y": 188.21180713306424
271 | },
272 | "group": "nodes",
273 | "removed": false,
274 | "selected": false,
275 | "selectable": true,
276 | "locked": false,
277 | "grabbable": true,
278 | "pannable": false,
279 | "classes": ""
280 | },
281 | {
282 | "data": {
283 | "id": "glyph28",
284 | "class": "macromolecule",
285 | "label": "myosin",
286 | "parent": "glyph36",
287 | "clonemarker": false,
288 | "stateVariables": [],
289 | "unitsOfInformation": [],
290 | "bbox": {
291 | "x": 1804.8844575025842,
292 | "y": 65.47480600819699,
293 | "w": 120,
294 | "h": 60
295 | }
296 | },
297 | "position": {
298 | "x": 1817.9165947430324,
299 | "y": 272.6942273822051
300 | },
301 | "group": "nodes",
302 | "removed": false,
303 | "selected": false,
304 | "selectable": true,
305 | "locked": false,
306 | "grabbable": true,
307 | "pannable": false,
308 | "classes": ""
309 | },
310 | {
311 | "data": {
312 | "id": "glyph45",
313 | "class": "association",
314 | "label": "",
315 | "parent": "glyph2",
316 | "clonemarker": false,
317 | "stateVariables": [],
318 | "unitsOfInformation": [],
319 | "bbox": {
320 | "x": 1967.0754642626248,
321 | "y": 151.57845482385733,
322 | "w": 20,
323 | "h": 20
324 | }
325 | },
326 | "position": {
327 | "x": 1642.8063632769129,
328 | "y": 230.12306141176143
329 | },
330 | "group": "nodes",
331 | "removed": false,
332 | "selected": false,
333 | "selectable": true,
334 | "locked": false,
335 | "grabbable": true,
336 | "pannable": false,
337 | "classes": ""
338 | },
339 | {
340 | "data": {
341 | "id": "glyph27",
342 | "class": "macromolecule",
343 | "label": "myosin",
344 | "parent": "glyph2",
345 | "clonemarker": false,
346 | "stateVariables": [],
347 | "unitsOfInformation": [],
348 | "bbox": {
349 | "x": 2003.3717441786537,
350 | "y": 245.72390413349126,
351 | "w": 120,
352 | "h": 60
353 | }
354 | },
355 | "position": {
356 | "x": 1540.132053723101,
357 | "y": 279.80120982473704
358 | },
359 | "group": "nodes",
360 | "removed": false,
361 | "selected": false,
362 | "selectable": true,
363 | "locked": false,
364 | "grabbable": true,
365 | "pannable": false,
366 | "classes": ""
367 | },
368 | {
369 | "data": {
370 | "id": "glyph25",
371 | "class": "simple chemical",
372 | "label": "ATP",
373 | "parent": "glyph2",
374 | "clonemarker": false,
375 | "stateVariables": [],
376 | "unitsOfInformation": [],
377 | "bbox": {
378 | "x": 2054.788436248919,
379 | "y": 96.8211999690675,
380 | "w": 60,
381 | "h": 60
382 | }
383 | },
384 | "position": {
385 | "x": 1539.5639014474805,
386 | "y": 183.31193386431147
387 | },
388 | "group": "nodes",
389 | "removed": false,
390 | "selected": false,
391 | "selectable": true,
392 | "locked": false,
393 | "grabbable": true,
394 | "pannable": false,
395 | "classes": ""
396 | },
397 | {
398 | "data": {
399 | "id": "glyph26",
400 | "class": "macromolecule",
401 | "label": "actin",
402 | "parent": "glyph2",
403 | "clonemarker": false,
404 | "stateVariables": [],
405 | "unitsOfInformation": [],
406 | "bbox": {
407 | "x": 1820.439889522249,
408 | "y": 268.820483039897,
409 | "w": 120,
410 | "h": 60
411 | }
412 | },
413 | "position": {
414 | "x": 1815.1991122293518,
415 | "y": 382.139183750573
416 | },
417 | "group": "nodes",
418 | "removed": false,
419 | "selected": false,
420 | "selectable": true,
421 | "locked": false,
422 | "grabbable": true,
423 | "pannable": false,
424 | "classes": ""
425 | },
426 | {
427 | "data": {
428 | "id": "glyph44",
429 | "class": "dissociation",
430 | "label": "",
431 | "parent": "glyph2",
432 | "clonemarker": false,
433 | "stateVariables": [],
434 | "unitsOfInformation": [],
435 | "bbox": {
436 | "x": 1935.250386913732,
437 | "y": 330.8071031300308,
438 | "w": 20,
439 | "h": 20
440 | }
441 | },
442 | "position": {
443 | "x": 1813.0103916593941,
444 | "y": 495.46808601139895
445 | },
446 | "group": "nodes",
447 | "removed": false,
448 | "selected": false,
449 | "selectable": true,
450 | "locked": false,
451 | "grabbable": true,
452 | "pannable": false,
453 | "classes": ""
454 | },
455 | {
456 | "data": {
457 | "id": "glyph40",
458 | "class": "simple chemical",
459 | "label": "ADP",
460 | "parent": "glyph2",
461 | "clonemarker": false,
462 | "stateVariables": [],
463 | "unitsOfInformation": [],
464 | "bbox": {
465 | "x": 1759.2930830609844,
466 | "y": 647.3483839558924,
467 | "w": 60,
468 | "h": 60
469 | }
470 | },
471 | "position": {
472 | "x": 2122.661865282198,
473 | "y": 665.6326904740338
474 | },
475 | "group": "nodes",
476 | "removed": false,
477 | "selected": false,
478 | "selectable": true,
479 | "locked": false,
480 | "grabbable": true,
481 | "pannable": false,
482 | "classes": ""
483 | },
484 | {
485 | "data": {
486 | "id": "glyph43",
487 | "class": "process",
488 | "label": "",
489 | "parent": "glyph2",
490 | "clonemarker": false,
491 | "stateVariables": [],
492 | "unitsOfInformation": [],
493 | "bbox": {
494 | "x": 1751.2193616265988,
495 | "y": 549.6009389943749,
496 | "w": 20,
497 | "h": 20
498 | }
499 | },
500 | "position": {
501 | "x": 2201.540688499251,
502 | "y": 568.5858231560827
503 | },
504 | "group": "nodes",
505 | "removed": false,
506 | "selected": false,
507 | "selectable": true,
508 | "locked": false,
509 | "grabbable": true,
510 | "pannable": false,
511 | "classes": ""
512 | },
513 | {
514 | "data": {
515 | "id": "glyph33",
516 | "class": "simple chemical",
517 | "label": "Pi",
518 | "parent": "glyph2",
519 | "clonemarker": false,
520 | "stateVariables": [],
521 | "unitsOfInformation": [],
522 | "bbox": {
523 | "x": 1657.0448245589985,
524 | "y": 580.5826529205284,
525 | "w": 60,
526 | "h": 60
527 | }
528 | },
529 | "position": {
530 | "x": 2279.8999661788876,
531 | "y": 665.7298263988102
532 | },
533 | "group": "nodes",
534 | "removed": false,
535 | "selected": false,
536 | "selectable": true,
537 | "locked": false,
538 | "grabbable": true,
539 | "pannable": false,
540 | "classes": ""
541 | },
542 | {
543 | "data": {
544 | "id": "glyph38",
545 | "class": "complex multimer",
546 | "label": "",
547 | "parent": "glyph2",
548 | "clonemarker": false,
549 | "stateVariables": [
550 | {
551 | "id": "glyph38a",
552 | "class": "state variable",
553 | "state": {
554 | "variable": "",
555 | "value": "relaxed"
556 | }
557 | }
558 | ],
559 | "unitsOfInformation": [],
560 | "bbox": {
561 | "x": 1624.6397609318626,
562 | "y": 402.55565593238714,
563 | "w": 196.5,
564 | "h": 136.5
565 | }
566 | },
567 | "position": {
568 | "x": 2202.1722769486146,
569 | "y": 281.97139861309836
570 | },
571 | "group": "nodes",
572 | "removed": false,
573 | "selected": false,
574 | "selectable": true,
575 | "locked": false,
576 | "grabbable": true,
577 | "pannable": false,
578 | "classes": ""
579 | },
580 | {
581 | "data": {
582 | "id": "glyph46",
583 | "class": "simple chemical",
584 | "label": "ATP",
585 | "parent": "glyph38",
586 | "clonemarker": false,
587 | "stateVariables": [],
588 | "unitsOfInformation": [],
589 | "bbox": {
590 | "x": 1692.1397609318626,
591 | "y": 365.05565593238714,
592 | "w": 60,
593 | "h": 60
594 | }
595 | },
596 | "position": {
597 | "x": 2201.8585383740638,
598 | "y": 193.410429481047
599 | },
600 | "group": "nodes",
601 | "removed": false,
602 | "selected": false,
603 | "selectable": true,
604 | "locked": false,
605 | "grabbable": true,
606 | "pannable": false,
607 | "classes": ""
608 | },
609 | {
610 | "data": {
611 | "id": "glyph30",
612 | "class": "macromolecule",
613 | "label": "actin",
614 | "parent": "glyph38",
615 | "clonemarker": false,
616 | "stateVariables": [],
617 | "unitsOfInformation": [],
618 | "bbox": {
619 | "x": 1587.1397609318626,
620 | "y": 440.05565593238714,
621 | "w": 120,
622 | "h": 60
623 | }
624 | },
625 | "position": {
626 | "x": 2203.329337099064,
627 | "y": 370.53236774514977
628 | },
629 | "group": "nodes",
630 | "removed": false,
631 | "selected": false,
632 | "selectable": true,
633 | "locked": false,
634 | "grabbable": true,
635 | "pannable": false,
636 | "classes": ""
637 | },
638 | {
639 | "data": {
640 | "id": "glyph29",
641 | "class": "macromolecule",
642 | "label": "myosin",
643 | "parent": "glyph38",
644 | "clonemarker": false,
645 | "stateVariables": [],
646 | "unitsOfInformation": [],
647 | "bbox": {
648 | "x": 1587.1397609318626,
649 | "y": 365.05565593238714,
650 | "w": 120,
651 | "h": 60
652 | }
653 | },
654 | "position": {
655 | "x": 2201.015216798165,
656 | "y": 276.61286375336715
657 | },
658 | "group": "nodes",
659 | "removed": false,
660 | "selected": false,
661 | "selectable": true,
662 | "locked": false,
663 | "grabbable": true,
664 | "pannable": false,
665 | "classes": ""
666 | },
667 | {
668 | "data": {
669 | "id": "glyph42",
670 | "class": "association",
671 | "label": "",
672 | "parent": "glyph2",
673 | "clonemarker": false,
674 | "stateVariables": [],
675 | "unitsOfInformation": [],
676 | "bbox": {
677 | "x": 1690.9446371300062,
678 | "y": 251.92937531016833,
679 | "w": 20,
680 | "h": 20
681 | }
682 | },
683 | "position": {
684 | "x": 2007.2230653255717,
685 | "y": 283.7108784686492
686 | },
687 | "group": "nodes",
688 | "removed": false,
689 | "selected": false,
690 | "selectable": true,
691 | "locked": false,
692 | "grabbable": true,
693 | "pannable": false,
694 | "classes": ""
695 | },
696 | {
697 | "data": {
698 | "id": "glyph22",
699 | "class": "simple chemical",
700 | "label": "Ca2+",
701 | "parent": "glyph2",
702 | "clonemarker": false,
703 | "stateVariables": [],
704 | "unitsOfInformation": [],
705 | "bbox": {
706 | "x": 1589.5695675154066,
707 | "y": 232.05000581952652,
708 | "w": 60,
709 | "h": 60
710 | }
711 | },
712 | "position": {
713 | "x": 2008.9438830755585,
714 | "y": 72.23150482055803
715 | },
716 | "group": "nodes",
717 | "removed": false,
718 | "selected": false,
719 | "selectable": true,
720 | "locked": false,
721 | "grabbable": true,
722 | "pannable": false,
723 | "classes": ""
724 | },
725 | {
726 | "data": {
727 | "id": "glyph24",
728 | "class": "process",
729 | "label": "",
730 | "parent": "glyph2",
731 | "clonemarker": false,
732 | "stateVariables": [],
733 | "unitsOfInformation": [],
734 | "bbox": {
735 | "x": 1301.6362730997278,
736 | "y": 398.6650341622118,
737 | "w": 20,
738 | "h": 20
739 | }
740 | },
741 | "position": {
742 | "x": 1368.5291072898137,
743 | "y": 359.5976077972136
744 | },
745 | "group": "nodes",
746 | "removed": false,
747 | "selected": false,
748 | "selectable": true,
749 | "locked": false,
750 | "grabbable": true,
751 | "pannable": false,
752 | "classes": ""
753 | },
754 | {
755 | "data": {
756 | "id": "glyph20",
757 | "class": "macromolecule",
758 | "label": "nAChR",
759 | "parent": "glyph2",
760 | "clonemarker": false,
761 | "stateVariables": [
762 | {
763 | "id": "glyph20a",
764 | "class": "state variable",
765 | "state": {
766 | "variable": "",
767 | "value": "closed"
768 | }
769 | }
770 | ],
771 | "unitsOfInformation": [],
772 | "bbox": {
773 | "x": 1283.999018133457,
774 | "y": 492.58732111519737,
775 | "w": 120,
776 | "h": 60
777 | }
778 | },
779 | "position": {
780 | "x": 1365.3513405760298,
781 | "y": 498.03249059468095
782 | },
783 | "group": "nodes",
784 | "removed": false,
785 | "selected": false,
786 | "selectable": true,
787 | "locked": false,
788 | "grabbable": true,
789 | "pannable": false,
790 | "classes": ""
791 | },
792 | {
793 | "data": {
794 | "id": "glyph2",
795 | "class": "compartment",
796 | "label": "muscle cytosol",
797 | "clonemarker": false,
798 | "stateVariables": [],
799 | "unitsOfInformation": [],
800 | "bbox": {
801 | "x": 1654.393727191188,
802 | "y": 350.73087219551167,
803 | "w": 862.289418115462,
804 | "h": 663.5121323746293
805 | }
806 | },
807 | "position": {
808 | "x": 1757.2525815575698,
809 | "y": 585.663028834556
810 | },
811 | "group": "nodes",
812 | "removed": false,
813 | "selected": false,
814 | "selectable": true,
815 | "locked": false,
816 | "grabbable": true,
817 | "pannable": false,
818 | "classes": ""
819 | },
820 | {
821 | "data": {
822 | "id": "glyph16",
823 | "class": "process",
824 | "label": "",
825 | "parent": "glyph0",
826 | "clonemarker": false,
827 | "stateVariables": [],
828 | "unitsOfInformation": [],
829 | "bbox": {
830 | "x": 207.27865035440527,
831 | "y": 260.8070789152547,
832 | "w": 20,
833 | "h": 20
834 | }
835 | },
836 | "position": {
837 | "x": -87.88227756031358,
838 | "y": 351.9597184183295
839 | },
840 | "group": "nodes",
841 | "removed": false,
842 | "selected": false,
843 | "selectable": true,
844 | "locked": false,
845 | "grabbable": true,
846 | "pannable": false,
847 | "classes": ""
848 | },
849 | {
850 | "data": {
851 | "id": "glyph47",
852 | "class": "simple chemical",
853 | "label": "acetyl CoA",
854 | "parent": "glyph0",
855 | "clonemarker": false,
856 | "stateVariables": [],
857 | "unitsOfInformation": [],
858 | "bbox": {
859 | "x": 155.17928220362705,
860 | "y": 171.2675330945018,
861 | "w": 60,
862 | "h": 60
863 | }
864 | },
865 | "position": {
866 | "x": -208.0103304062723,
867 | "y": 273.135587371003
868 | },
869 | "group": "nodes",
870 | "removed": false,
871 | "selected": false,
872 | "selectable": true,
873 | "locked": false,
874 | "grabbable": true,
875 | "pannable": false,
876 | "classes": ""
877 | },
878 | {
879 | "data": {
880 | "id": "glyph12",
881 | "class": "simple chemical",
882 | "label": "choline",
883 | "parent": "glyph0",
884 | "clonemarker": false,
885 | "stateVariables": [],
886 | "unitsOfInformation": [],
887 | "bbox": {
888 | "x": 273.0840166839621,
889 | "y": 349.41797443653786,
890 | "w": 60,
891 | "h": 60
892 | }
893 | },
894 | "position": {
895 | "x": -212.23274557501688,
896 | "y": 423.89923769794325
897 | },
898 | "group": "nodes",
899 | "removed": false,
900 | "selected": false,
901 | "selectable": true,
902 | "locked": false,
903 | "grabbable": true,
904 | "pannable": false,
905 | "classes": ""
906 | },
907 | {
908 | "data": {
909 | "id": "glyph15",
910 | "class": "process",
911 | "label": "",
912 | "parent": "glyph0",
913 | "clonemarker": false,
914 | "stateVariables": [],
915 | "unitsOfInformation": [],
916 | "bbox": {
917 | "x": 352.0061729818583,
918 | "y": 433.5590129724641,
919 | "w": 20,
920 | "h": 20
921 | }
922 | },
923 | "position": {
924 | "x": 275.88008415416454,
925 | "y": 504.97508201006804
926 | },
927 | "group": "nodes",
928 | "removed": false,
929 | "selected": false,
930 | "selectable": true,
931 | "locked": false,
932 | "grabbable": true,
933 | "pannable": false,
934 | "classes": ""
935 | },
936 | {
937 | "data": {
938 | "id": "glyph9",
939 | "class": "macromolecule",
940 | "label": "SNARE",
941 | "parent": "glyph0",
942 | "clonemarker": false,
943 | "stateVariables": [],
944 | "unitsOfInformation": [],
945 | "bbox": {
946 | "x": 432.77215278290015,
947 | "y": 618.9409568808867,
948 | "w": 120,
949 | "h": 60
950 | }
951 | },
952 | "position": {
953 | "x": 471.8375697127895,
954 | "y": 151.32063347240833
955 | },
956 | "group": "nodes",
957 | "removed": false,
958 | "selected": false,
959 | "selectable": true,
960 | "locked": false,
961 | "grabbable": true,
962 | "pannable": false,
963 | "classes": ""
964 | },
965 | {
966 | "data": {
967 | "id": "glyph3",
968 | "class": "macromolecule",
969 | "label": "ChAT",
970 | "parent": "glyph0",
971 | "clonemarker": false,
972 | "stateVariables": [],
973 | "unitsOfInformation": [],
974 | "bbox": {
975 | "x": 80.62697950944448,
976 | "y": 284.8423494357676,
977 | "w": 120,
978 | "h": 60
979 | }
980 | },
981 | "position": {
982 | "x": -88.65649385340895,
983 | "y": 153.6186718124465
984 | },
985 | "group": "nodes",
986 | "removed": false,
987 | "selected": false,
988 | "selectable": true,
989 | "locked": false,
990 | "grabbable": true,
991 | "pannable": false,
992 | "classes": ""
993 | },
994 | {
995 | "data": {
996 | "id": "glyph18",
997 | "class": "process",
998 | "label": "",
999 | "parent": "glyph0",
1000 | "clonemarker": false,
1001 | "stateVariables": [],
1002 | "unitsOfInformation": [],
1003 | "bbox": {
1004 | "x": 391.3423913539207,
1005 | "y": 175.79855923606135,
1006 | "w": 20,
1007 | "h": 20
1008 | }
1009 | },
1010 | "position": {
1011 | "x": 174.31229729898033,
1012 | "y": 353.76323636111226
1013 | },
1014 | "group": "nodes",
1015 | "removed": false,
1016 | "selected": false,
1017 | "selectable": true,
1018 | "locked": false,
1019 | "grabbable": true,
1020 | "pannable": false,
1021 | "classes": ""
1022 | },
1023 | {
1024 | "data": {
1025 | "id": "glyph4",
1026 | "class": "macromolecule",
1027 | "label": "vAChT",
1028 | "parent": "glyph0",
1029 | "clonemarker": false,
1030 | "stateVariables": [],
1031 | "unitsOfInformation": [],
1032 | "bbox": {
1033 | "x": 401.0948426971652,
1034 | "y": 80.0319137104878,
1035 | "w": 120,
1036 | "h": 60
1037 | }
1038 | },
1039 | "position": {
1040 | "x": 175.38354488002722,
1041 | "y": 150.64622355826125
1042 | },
1043 | "group": "nodes",
1044 | "removed": false,
1045 | "selected": false,
1046 | "selectable": true,
1047 | "locked": false,
1048 | "grabbable": true,
1049 | "pannable": false,
1050 | "classes": ""
1051 | },
1052 | {
1053 | "data": {
1054 | "id": "glyph13",
1055 | "class": "simple chemical",
1056 | "label": "Ach",
1057 | "parent": "glyph0",
1058 | "clonemarker": false,
1059 | "stateVariables": [],
1060 | "unitsOfInformation": [],
1061 | "bbox": {
1062 | "x": 296.06141509780923,
1063 | "y": 204.40035574974667,
1064 | "w": 60,
1065 | "h": 60
1066 | }
1067 | },
1068 | "position": {
1069 | "x": 52.987709756276075,
1070 | "y": 354.1511206476554
1071 | },
1072 | "group": "nodes",
1073 | "removed": false,
1074 | "selected": false,
1075 | "selectable": true,
1076 | "locked": false,
1077 | "grabbable": true,
1078 | "pannable": false,
1079 | "classes": ""
1080 | },
1081 | {
1082 | "data": {
1083 | "id": "glyph8",
1084 | "class": "macromolecule",
1085 | "label": "CHT1",
1086 | "parent": "glyph0",
1087 | "clonemarker": false,
1088 | "stateVariables": [],
1089 | "unitsOfInformation": [],
1090 | "bbox": {
1091 | "x": 233.13067713678856,
1092 | "y": 493.88399094919043,
1093 | "w": 120,
1094 | "h": 60
1095 | }
1096 | },
1097 | "position": {
1098 | "x": 271.3344503874855,
1099 | "y": 673.8201635022664
1100 | },
1101 | "group": "nodes",
1102 | "removed": false,
1103 | "selected": false,
1104 | "selectable": true,
1105 | "locked": false,
1106 | "grabbable": true,
1107 | "pannable": false,
1108 | "classes": ""
1109 | },
1110 | {
1111 | "data": {
1112 | "id": "glyph6",
1113 | "class": "simple chemical",
1114 | "label": "ACh",
1115 | "parent": "glyph14",
1116 | "clonemarker": false,
1117 | "stateVariables": [],
1118 | "unitsOfInformation": [],
1119 | "bbox": {
1120 | "x": 492.2542134972042,
1121 | "y": 240.85518711003323,
1122 | "w": 60,
1123 | "h": 60
1124 | }
1125 | },
1126 | "position": {
1127 | "x": 337.4193930595747,
1128 | "y": 354.3103607223483
1129 | },
1130 | "group": "nodes",
1131 | "removed": false,
1132 | "selected": false,
1133 | "selectable": true,
1134 | "locked": false,
1135 | "grabbable": true,
1136 | "pannable": false,
1137 | "classes": ""
1138 | },
1139 | {
1140 | "data": {
1141 | "id": "glyph14",
1142 | "class": "compartment",
1143 | "label": "synaptic vesicle",
1144 | "parent": "glyph0",
1145 | "clonemarker": false,
1146 | "stateVariables": [],
1147 | "unitsOfInformation": [],
1148 | "bbox": {
1149 | "x": 492.2542134972042,
1150 | "y": 240.85518711003323,
1151 | "w": 61.5,
1152 | "h": 61.5
1153 | }
1154 | },
1155 | "position": {
1156 | "x": 337.4193930595747,
1157 | "y": 354.3103607223483
1158 | },
1159 | "group": "nodes",
1160 | "removed": false,
1161 | "selected": false,
1162 | "selectable": true,
1163 | "locked": false,
1164 | "grabbable": true,
1165 | "pannable": false,
1166 | "classes": ""
1167 | },
1168 | {
1169 | "data": {
1170 | "id": "glyph0",
1171 | "class": "compartment",
1172 | "label": "synaptic button",
1173 | "clonemarker": false,
1174 | "stateVariables": [],
1175 | "unitsOfInformation": [],
1176 | "bbox": {
1177 | "x": 284.06559650332434,
1178 | "y": 349.4864352956872,
1179 | "w": 528.3772339877597,
1180 | "h": 600.409043170399
1181 | }
1182 | },
1183 | "position": {
1184 | "x": 141.80241206888627,
1185 | "y": 412.2331935302638
1186 | },
1187 | "group": "nodes",
1188 | "removed": false,
1189 | "selected": false,
1190 | "selectable": true,
1191 | "locked": false,
1192 | "grabbable": true,
1193 | "pannable": false,
1194 | "classes": ""
1195 | },
1196 | {
1197 | "data": {
1198 | "id": "glyph5",
1199 | "class": "simple chemical",
1200 | "label": "choline",
1201 | "parent": "glyph1",
1202 | "clonemarker": false,
1203 | "stateVariables": [],
1204 | "unitsOfInformation": [],
1205 | "bbox": {
1206 | "x": 673.7541361913168,
1207 | "y": 591.1376395474406,
1208 | "w": 60,
1209 | "h": 60
1210 | }
1211 | },
1212 | "position": {
1213 | "x": 793.480241396369,
1214 | "y": 605.1306967237942
1215 | },
1216 | "group": "nodes",
1217 | "removed": false,
1218 | "selected": false,
1219 | "selectable": true,
1220 | "locked": false,
1221 | "grabbable": true,
1222 | "pannable": false,
1223 | "classes": ""
1224 | },
1225 | {
1226 | "data": {
1227 | "id": "glyph7",
1228 | "class": "simple chemical",
1229 | "label": "ACh",
1230 | "parent": "glyph1",
1231 | "clonemarker": false,
1232 | "stateVariables": [],
1233 | "unitsOfInformation": [],
1234 | "bbox": {
1235 | "x": 842.867868440539,
1236 | "y": 547.3570926019304,
1237 | "w": 60,
1238 | "h": 60
1239 | }
1240 | },
1241 | "position": {
1242 | "x": 882.2928388452633,
1243 | "y": 357.34186136664005
1244 | },
1245 | "group": "nodes",
1246 | "removed": false,
1247 | "selected": false,
1248 | "selectable": true,
1249 | "locked": false,
1250 | "grabbable": true,
1251 | "pannable": false,
1252 | "classes": ""
1253 | },
1254 | {
1255 | "data": {
1256 | "id": "glyph17",
1257 | "class": "process",
1258 | "label": "",
1259 | "parent": "glyph1",
1260 | "clonemarker": false,
1261 | "stateVariables": [],
1262 | "unitsOfInformation": [],
1263 | "bbox": {
1264 | "x": 780.4404211840899,
1265 | "y": 462.2172628114067,
1266 | "w": 20,
1267 | "h": 20
1268 | }
1269 | },
1270 | "position": {
1271 | "x": 646.8941101946878,
1272 | "y": 359.3586638434937
1273 | },
1274 | "group": "nodes",
1275 | "removed": false,
1276 | "selected": false,
1277 | "selectable": true,
1278 | "locked": false,
1279 | "grabbable": true,
1280 | "pannable": false,
1281 | "classes": ""
1282 | },
1283 | {
1284 | "data": {
1285 | "id": "glyph11",
1286 | "class": "simple chemical",
1287 | "label": "acetate",
1288 | "parent": "glyph1",
1289 | "clonemarker": false,
1290 | "stateVariables": [],
1291 | "unitsOfInformation": [],
1292 | "bbox": {
1293 | "x": 866.343685007812,
1294 | "y": 672.9950321120291,
1295 | "w": 60,
1296 | "h": 60
1297 | }
1298 | },
1299 | "position": {
1300 | "x": 962.1964798668208,
1301 | "y": 611.0275563691539
1302 | },
1303 | "group": "nodes",
1304 | "removed": false,
1305 | "selected": false,
1306 | "selectable": true,
1307 | "locked": false,
1308 | "grabbable": true,
1309 | "pannable": false,
1310 | "classes": ""
1311 | },
1312 | {
1313 | "data": {
1314 | "id": "glyph19",
1315 | "class": "process",
1316 | "label": "",
1317 | "parent": "glyph1",
1318 | "clonemarker": false,
1319 | "stateVariables": [],
1320 | "unitsOfInformation": [],
1321 | "bbox": {
1322 | "x": 771.6065327100307,
1323 | "y": 632.7047526281501,
1324 | "w": 20,
1325 | "h": 20
1326 | }
1327 | },
1328 | "position": {
1329 | "x": 878.3108322717865,
1330 | "y": 492.6064430254964
1331 | },
1332 | "group": "nodes",
1333 | "removed": false,
1334 | "selected": false,
1335 | "selectable": true,
1336 | "locked": false,
1337 | "grabbable": true,
1338 | "pannable": false,
1339 | "classes": ""
1340 | },
1341 | {
1342 | "data": {
1343 | "id": "glyph10",
1344 | "class": "macromolecule",
1345 | "label": "AChE",
1346 | "parent": "glyph1",
1347 | "clonemarker": false,
1348 | "stateVariables": [],
1349 | "unitsOfInformation": [],
1350 | "bbox": {
1351 | "x": 729.7050429901893,
1352 | "y": 725.5935040834514,
1353 | "w": 120,
1354 | "h": 60
1355 | }
1356 | },
1357 | "position": {
1358 | "x": 1038.2473300230395,
1359 | "y": 496.5128559182721
1360 | },
1361 | "group": "nodes",
1362 | "removed": false,
1363 | "selected": false,
1364 | "selectable": true,
1365 | "locked": false,
1366 | "grabbable": true,
1367 | "pannable": false,
1368 | "classes": ""
1369 | },
1370 | {
1371 | "data": {
1372 | "id": "glyph1",
1373 | "class": "compartment",
1374 | "label": "synaptic cleft",
1375 | "clonemarker": false,
1376 | "stateVariables": [],
1377 | "unitsOfInformation": [],
1378 | "bbox": {
1379 | "x": 770.0489105995644,
1380 | "y": 603.9053834474291,
1381 | "w": 254.08954881649527,
1382 | "h": 304.8762412720447
1383 | }
1384 | },
1385 | "position": {
1386 | "x": 864.4457201088636,
1387 | "y": 484.184708867897
1388 | },
1389 | "group": "nodes",
1390 | "removed": false,
1391 | "selected": false,
1392 | "selectable": true,
1393 | "locked": false,
1394 | "grabbable": true,
1395 | "pannable": false,
1396 | "classes": ""
1397 | },
1398 | {
1399 | "data": {
1400 | "id": "glyph8-glyph15",
1401 | "class": "necessary stimulation",
1402 | "cardinality": 0,
1403 | "source": "glyph8",
1404 | "target": "glyph15",
1405 | "bendPointPositions": [],
1406 | "portSource": "glyph8",
1407 | "portTarget": "glyph15"
1408 | },
1409 | "position": {
1410 | "x": 0,
1411 | "y": 0
1412 | },
1413 | "group": "edges",
1414 | "removed": false,
1415 | "selected": false,
1416 | "selectable": true,
1417 | "locked": false,
1418 | "grabbable": true,
1419 | "pannable": true,
1420 | "classes": ""
1421 | },
1422 | {
1423 | "data": {
1424 | "id": "glyph12-glyph16",
1425 | "class": "consumption",
1426 | "cardinality": 0,
1427 | "source": "glyph12",
1428 | "target": "glyph16",
1429 | "bendPointPositions": [],
1430 | "portSource": "glyph12",
1431 | "portTarget": "glyph16"
1432 | },
1433 | "position": {
1434 | "x": 0,
1435 | "y": 0
1436 | },
1437 | "group": "edges",
1438 | "removed": false,
1439 | "selected": false,
1440 | "selectable": true,
1441 | "locked": false,
1442 | "grabbable": true,
1443 | "pannable": true,
1444 | "classes": ""
1445 | },
1446 | {
1447 | "data": {
1448 | "id": "glyph16-glyph13",
1449 | "class": "production",
1450 | "cardinality": 0,
1451 | "source": "glyph16",
1452 | "target": "glyph13",
1453 | "bendPointPositions": [],
1454 | "portSource": "glyph16",
1455 | "portTarget": "glyph13"
1456 | },
1457 | "position": {
1458 | "x": 0,
1459 | "y": 0
1460 | },
1461 | "group": "edges",
1462 | "removed": false,
1463 | "selected": false,
1464 | "selectable": true,
1465 | "locked": false,
1466 | "grabbable": true,
1467 | "pannable": true,
1468 | "classes": ""
1469 | },
1470 | {
1471 | "data": {
1472 | "id": "glyph13-glyph18",
1473 | "class": "consumption",
1474 | "cardinality": 0,
1475 | "source": "glyph13",
1476 | "target": "glyph18",
1477 | "bendPointPositions": [],
1478 | "portSource": "glyph13",
1479 | "portTarget": "glyph18"
1480 | },
1481 | "position": {
1482 | "x": 0,
1483 | "y": 0
1484 | },
1485 | "group": "edges",
1486 | "removed": false,
1487 | "selected": false,
1488 | "selectable": true,
1489 | "locked": false,
1490 | "grabbable": true,
1491 | "pannable": true,
1492 | "classes": ""
1493 | },
1494 | {
1495 | "data": {
1496 | "id": "glyph18-glyph6",
1497 | "class": "production",
1498 | "cardinality": 0,
1499 | "source": "glyph18",
1500 | "target": "glyph6",
1501 | "bendPointPositions": [],
1502 | "portSource": "glyph18",
1503 | "portTarget": "glyph6"
1504 | },
1505 | "position": {
1506 | "x": 0,
1507 | "y": 0
1508 | },
1509 | "group": "edges",
1510 | "removed": false,
1511 | "selected": false,
1512 | "selectable": true,
1513 | "locked": false,
1514 | "grabbable": true,
1515 | "pannable": true,
1516 | "classes": ""
1517 | },
1518 | {
1519 | "data": {
1520 | "id": "glyph4-glyph18",
1521 | "class": "necessary stimulation",
1522 | "cardinality": 0,
1523 | "source": "glyph4",
1524 | "target": "glyph18",
1525 | "bendPointPositions": [],
1526 | "portSource": "glyph4",
1527 | "portTarget": "glyph18"
1528 | },
1529 | "position": {
1530 | "x": 0,
1531 | "y": 0
1532 | },
1533 | "group": "edges",
1534 | "removed": false,
1535 | "selected": false,
1536 | "selectable": true,
1537 | "locked": false,
1538 | "grabbable": true,
1539 | "pannable": true,
1540 | "classes": ""
1541 | },
1542 | {
1543 | "data": {
1544 | "id": "glyph3-glyph16",
1545 | "class": "catalysis",
1546 | "cardinality": 0,
1547 | "source": "glyph3",
1548 | "target": "glyph16",
1549 | "bendPointPositions": [],
1550 | "portSource": "glyph3",
1551 | "portTarget": "glyph16"
1552 | },
1553 | "position": {
1554 | "x": 0,
1555 | "y": 0
1556 | },
1557 | "group": "edges",
1558 | "removed": false,
1559 | "selected": false,
1560 | "selectable": true,
1561 | "locked": false,
1562 | "grabbable": true,
1563 | "pannable": true,
1564 | "classes": ""
1565 | },
1566 | {
1567 | "data": {
1568 | "id": "glyph10-glyph19",
1569 | "class": "catalysis",
1570 | "cardinality": 0,
1571 | "source": "glyph10",
1572 | "target": "glyph19",
1573 | "bendPointPositions": [],
1574 | "portSource": "glyph10",
1575 | "portTarget": "glyph19"
1576 | },
1577 | "position": {
1578 | "x": 0,
1579 | "y": 0
1580 | },
1581 | "group": "edges",
1582 | "removed": false,
1583 | "selected": false,
1584 | "selectable": true,
1585 | "locked": false,
1586 | "grabbable": true,
1587 | "pannable": true,
1588 | "classes": ""
1589 | },
1590 | {
1591 | "data": {
1592 | "id": "glyph7-glyph19",
1593 | "class": "consumption",
1594 | "cardinality": 0,
1595 | "source": "glyph7",
1596 | "target": "glyph19",
1597 | "bendPointPositions": [],
1598 | "portSource": "glyph7",
1599 | "portTarget": "glyph19"
1600 | },
1601 | "position": {
1602 | "x": 0,
1603 | "y": 0
1604 | },
1605 | "group": "edges",
1606 | "removed": false,
1607 | "selected": false,
1608 | "selectable": true,
1609 | "locked": false,
1610 | "grabbable": true,
1611 | "pannable": true,
1612 | "classes": ""
1613 | },
1614 | {
1615 | "data": {
1616 | "id": "glyph19-glyph5",
1617 | "class": "production",
1618 | "cardinality": 0,
1619 | "source": "glyph19",
1620 | "target": "glyph5",
1621 | "bendPointPositions": [],
1622 | "portSource": "glyph19",
1623 | "portTarget": "glyph5"
1624 | },
1625 | "position": {
1626 | "x": 0,
1627 | "y": 0
1628 | },
1629 | "group": "edges",
1630 | "removed": false,
1631 | "selected": false,
1632 | "selectable": true,
1633 | "locked": false,
1634 | "grabbable": true,
1635 | "pannable": true,
1636 | "classes": ""
1637 | },
1638 | {
1639 | "data": {
1640 | "id": "glyph19-glyph11",
1641 | "class": "production",
1642 | "cardinality": 0,
1643 | "source": "glyph19",
1644 | "target": "glyph11",
1645 | "bendPointPositions": [],
1646 | "portSource": "glyph19",
1647 | "portTarget": "glyph11"
1648 | },
1649 | "position": {
1650 | "x": 0,
1651 | "y": 0
1652 | },
1653 | "group": "edges",
1654 | "removed": false,
1655 | "selected": false,
1656 | "selectable": true,
1657 | "locked": false,
1658 | "grabbable": true,
1659 | "pannable": true,
1660 | "classes": ""
1661 | },
1662 | {
1663 | "data": {
1664 | "id": "glyph9-glyph17",
1665 | "class": "necessary stimulation",
1666 | "cardinality": 0,
1667 | "source": "glyph9",
1668 | "target": "glyph17",
1669 | "bendPointPositions": [],
1670 | "portSource": "glyph9",
1671 | "portTarget": "glyph17"
1672 | },
1673 | "position": {
1674 | "x": 0,
1675 | "y": 0
1676 | },
1677 | "group": "edges",
1678 | "removed": false,
1679 | "selected": false,
1680 | "selectable": true,
1681 | "locked": false,
1682 | "grabbable": true,
1683 | "pannable": true,
1684 | "classes": ""
1685 | },
1686 | {
1687 | "data": {
1688 | "id": "glyph6-glyph17",
1689 | "class": "consumption",
1690 | "cardinality": 0,
1691 | "source": "glyph6",
1692 | "target": "glyph17",
1693 | "bendPointPositions": [],
1694 | "portSource": "glyph6",
1695 | "portTarget": "glyph17"
1696 | },
1697 | "position": {
1698 | "x": 0,
1699 | "y": 0
1700 | },
1701 | "group": "edges",
1702 | "removed": false,
1703 | "selected": false,
1704 | "selectable": true,
1705 | "locked": false,
1706 | "grabbable": true,
1707 | "pannable": true,
1708 | "classes": ""
1709 | },
1710 | {
1711 | "data": {
1712 | "id": "glyph17-glyph7",
1713 | "class": "production",
1714 | "cardinality": 0,
1715 | "source": "glyph17",
1716 | "target": "glyph7",
1717 | "bendPointPositions": [],
1718 | "portSource": "glyph17",
1719 | "portTarget": "glyph7"
1720 | },
1721 | "position": {
1722 | "x": 0,
1723 | "y": 0
1724 | },
1725 | "group": "edges",
1726 | "removed": false,
1727 | "selected": false,
1728 | "selectable": true,
1729 | "locked": false,
1730 | "grabbable": true,
1731 | "pannable": true,
1732 | "classes": ""
1733 | },
1734 | {
1735 | "data": {
1736 | "id": "glyph7-glyph24",
1737 | "class": "necessary stimulation",
1738 | "cardinality": 0,
1739 | "source": "glyph7",
1740 | "target": "glyph24",
1741 | "bendPointPositions": [],
1742 | "portSource": "glyph7",
1743 | "portTarget": "glyph24"
1744 | },
1745 | "position": {
1746 | "x": 0,
1747 | "y": 0
1748 | },
1749 | "group": "edges",
1750 | "removed": false,
1751 | "selected": false,
1752 | "selectable": true,
1753 | "locked": false,
1754 | "grabbable": true,
1755 | "pannable": true,
1756 | "classes": ""
1757 | },
1758 | {
1759 | "data": {
1760 | "id": "glyph20-glyph24",
1761 | "class": "consumption",
1762 | "cardinality": 0,
1763 | "source": "glyph20",
1764 | "target": "glyph24",
1765 | "bendPointPositions": [],
1766 | "portSource": "glyph20",
1767 | "portTarget": "glyph24"
1768 | },
1769 | "position": {
1770 | "x": 0,
1771 | "y": 0
1772 | },
1773 | "group": "edges",
1774 | "removed": false,
1775 | "selected": false,
1776 | "selectable": true,
1777 | "locked": false,
1778 | "grabbable": true,
1779 | "pannable": true,
1780 | "classes": ""
1781 | },
1782 | {
1783 | "data": {
1784 | "id": "glyph24-glyph21",
1785 | "class": "production",
1786 | "cardinality": 0,
1787 | "source": "glyph24",
1788 | "target": "glyph21",
1789 | "bendPointPositions": [],
1790 | "portSource": "glyph24",
1791 | "portTarget": "glyph21"
1792 | },
1793 | "position": {
1794 | "x": 0,
1795 | "y": 0
1796 | },
1797 | "group": "edges",
1798 | "removed": false,
1799 | "selected": false,
1800 | "selectable": true,
1801 | "locked": false,
1802 | "grabbable": true,
1803 | "pannable": true,
1804 | "classes": ""
1805 | },
1806 | {
1807 | "data": {
1808 | "id": "glyph41-glyph22",
1809 | "class": "production",
1810 | "cardinality": 0,
1811 | "source": "glyph41",
1812 | "target": "glyph22",
1813 | "bendPointPositions": [],
1814 | "portSource": "glyph41",
1815 | "portTarget": "glyph22"
1816 | },
1817 | "position": {
1818 | "x": 0,
1819 | "y": 0
1820 | },
1821 | "group": "edges",
1822 | "removed": false,
1823 | "selected": false,
1824 | "selectable": true,
1825 | "locked": false,
1826 | "grabbable": true,
1827 | "pannable": true,
1828 | "classes": ""
1829 | },
1830 | {
1831 | "data": {
1832 | "id": "glyph22-glyph42",
1833 | "class": "stimulation",
1834 | "cardinality": 0,
1835 | "source": "glyph22",
1836 | "target": "glyph42",
1837 | "bendPointPositions": [],
1838 | "portSource": "glyph22",
1839 | "portTarget": "glyph42"
1840 | },
1841 | "position": {
1842 | "x": 0,
1843 | "y": 0
1844 | },
1845 | "group": "edges",
1846 | "removed": false,
1847 | "selected": false,
1848 | "selectable": true,
1849 | "locked": false,
1850 | "grabbable": true,
1851 | "pannable": true,
1852 | "classes": ""
1853 | },
1854 | {
1855 | "data": {
1856 | "id": "glyph36-glyph42",
1857 | "class": "consumption",
1858 | "cardinality": 0,
1859 | "source": "glyph36",
1860 | "target": "glyph42",
1861 | "bendPointPositions": [],
1862 | "portSource": "glyph36",
1863 | "portTarget": "glyph42"
1864 | },
1865 | "position": {
1866 | "x": 0,
1867 | "y": 0
1868 | },
1869 | "group": "edges",
1870 | "removed": false,
1871 | "selected": false,
1872 | "selectable": true,
1873 | "locked": false,
1874 | "grabbable": true,
1875 | "pannable": true,
1876 | "classes": ""
1877 | },
1878 | {
1879 | "data": {
1880 | "id": "glyph26-glyph42",
1881 | "class": "consumption",
1882 | "cardinality": 0,
1883 | "source": "glyph26",
1884 | "target": "glyph42",
1885 | "bendPointPositions": [],
1886 | "portSource": "glyph26",
1887 | "portTarget": "glyph42"
1888 | },
1889 | "position": {
1890 | "x": 0,
1891 | "y": 0
1892 | },
1893 | "group": "edges",
1894 | "removed": false,
1895 | "selected": false,
1896 | "selectable": true,
1897 | "locked": false,
1898 | "grabbable": true,
1899 | "pannable": true,
1900 | "classes": ""
1901 | },
1902 | {
1903 | "data": {
1904 | "id": "glyph42-glyph38",
1905 | "class": "production",
1906 | "cardinality": 0,
1907 | "source": "glyph42",
1908 | "target": "glyph38",
1909 | "bendPointPositions": [],
1910 | "portSource": "glyph42",
1911 | "portTarget": "glyph38"
1912 | },
1913 | "position": {
1914 | "x": 0,
1915 | "y": 0
1916 | },
1917 | "group": "edges",
1918 | "removed": false,
1919 | "selected": false,
1920 | "selectable": true,
1921 | "locked": false,
1922 | "grabbable": true,
1923 | "pannable": true,
1924 | "classes": ""
1925 | },
1926 | {
1927 | "data": {
1928 | "id": "glyph38-glyph43",
1929 | "class": "consumption",
1930 | "cardinality": 0,
1931 | "source": "glyph38",
1932 | "target": "glyph43",
1933 | "bendPointPositions": [],
1934 | "portSource": "glyph38",
1935 | "portTarget": "glyph43"
1936 | },
1937 | "position": {
1938 | "x": 0,
1939 | "y": 0
1940 | },
1941 | "group": "edges",
1942 | "removed": false,
1943 | "selected": false,
1944 | "selectable": true,
1945 | "locked": false,
1946 | "grabbable": true,
1947 | "pannable": true,
1948 | "classes": ""
1949 | },
1950 | {
1951 | "data": {
1952 | "id": "glyph43-glyph37",
1953 | "class": "production",
1954 | "cardinality": 0,
1955 | "source": "glyph43",
1956 | "target": "glyph37",
1957 | "bendPointPositions": [],
1958 | "portSource": "glyph43",
1959 | "portTarget": "glyph37"
1960 | },
1961 | "position": {
1962 | "x": 0,
1963 | "y": 0
1964 | },
1965 | "group": "edges",
1966 | "removed": false,
1967 | "selected": false,
1968 | "selectable": true,
1969 | "locked": false,
1970 | "grabbable": true,
1971 | "pannable": true,
1972 | "classes": ""
1973 | },
1974 | {
1975 | "data": {
1976 | "id": "glyph43-glyph33",
1977 | "class": "production",
1978 | "cardinality": 0,
1979 | "source": "glyph43",
1980 | "target": "glyph33",
1981 | "bendPointPositions": [],
1982 | "portSource": "glyph43",
1983 | "portTarget": "glyph33"
1984 | },
1985 | "position": {
1986 | "x": 0,
1987 | "y": 0
1988 | },
1989 | "group": "edges",
1990 | "removed": false,
1991 | "selected": false,
1992 | "selectable": true,
1993 | "locked": false,
1994 | "grabbable": true,
1995 | "pannable": true,
1996 | "classes": ""
1997 | },
1998 | {
1999 | "data": {
2000 | "id": "glyph43-glyph40",
2001 | "class": "production",
2002 | "cardinality": 0,
2003 | "source": "glyph43",
2004 | "target": "glyph40",
2005 | "bendPointPositions": [],
2006 | "portSource": "glyph43",
2007 | "portTarget": "glyph40"
2008 | },
2009 | "position": {
2010 | "x": 0,
2011 | "y": 0
2012 | },
2013 | "group": "edges",
2014 | "removed": false,
2015 | "selected": false,
2016 | "selectable": true,
2017 | "locked": false,
2018 | "grabbable": true,
2019 | "pannable": true,
2020 | "classes": ""
2021 | },
2022 | {
2023 | "data": {
2024 | "id": "glyph37-glyph44",
2025 | "class": "consumption",
2026 | "cardinality": 0,
2027 | "source": "glyph37",
2028 | "target": "glyph44",
2029 | "bendPointPositions": [],
2030 | "portSource": "glyph37",
2031 | "portTarget": "glyph44"
2032 | },
2033 | "position": {
2034 | "x": 0,
2035 | "y": 0
2036 | },
2037 | "group": "edges",
2038 | "removed": false,
2039 | "selected": false,
2040 | "selectable": true,
2041 | "locked": false,
2042 | "grabbable": true,
2043 | "pannable": true,
2044 | "classes": ""
2045 | },
2046 | {
2047 | "data": {
2048 | "id": "glyph44-glyph27",
2049 | "class": "production",
2050 | "cardinality": 0,
2051 | "source": "glyph44",
2052 | "target": "glyph27",
2053 | "bendPointPositions": [],
2054 | "portSource": "glyph44",
2055 | "portTarget": "glyph27"
2056 | },
2057 | "position": {
2058 | "x": 0,
2059 | "y": 0
2060 | },
2061 | "group": "edges",
2062 | "removed": false,
2063 | "selected": false,
2064 | "selectable": true,
2065 | "locked": false,
2066 | "grabbable": true,
2067 | "pannable": true,
2068 | "classes": ""
2069 | },
2070 | {
2071 | "data": {
2072 | "id": "glyph44-glyph26",
2073 | "class": "production",
2074 | "cardinality": 0,
2075 | "source": "glyph44",
2076 | "target": "glyph26",
2077 | "bendPointPositions": [],
2078 | "portSource": "glyph44",
2079 | "portTarget": "glyph26"
2080 | },
2081 | "position": {
2082 | "x": 0,
2083 | "y": 0
2084 | },
2085 | "group": "edges",
2086 | "removed": false,
2087 | "selected": false,
2088 | "selectable": true,
2089 | "locked": false,
2090 | "grabbable": true,
2091 | "pannable": true,
2092 | "classes": ""
2093 | },
2094 | {
2095 | "data": {
2096 | "id": "glyph25-glyph45",
2097 | "class": "consumption",
2098 | "cardinality": 0,
2099 | "source": "glyph25",
2100 | "target": "glyph45",
2101 | "bendPointPositions": [],
2102 | "portSource": "glyph25",
2103 | "portTarget": "glyph45"
2104 | },
2105 | "position": {
2106 | "x": 0,
2107 | "y": 0
2108 | },
2109 | "group": "edges",
2110 | "removed": false,
2111 | "selected": false,
2112 | "selectable": true,
2113 | "locked": false,
2114 | "grabbable": true,
2115 | "pannable": true,
2116 | "classes": ""
2117 | },
2118 | {
2119 | "data": {
2120 | "id": "glyph27-glyph45",
2121 | "class": "consumption",
2122 | "cardinality": 0,
2123 | "source": "glyph27",
2124 | "target": "glyph45",
2125 | "bendPointPositions": [],
2126 | "portSource": "glyph27",
2127 | "portTarget": "glyph45"
2128 | },
2129 | "position": {
2130 | "x": 0,
2131 | "y": 0
2132 | },
2133 | "group": "edges",
2134 | "removed": false,
2135 | "selected": false,
2136 | "selectable": true,
2137 | "locked": false,
2138 | "grabbable": true,
2139 | "pannable": true,
2140 | "classes": ""
2141 | },
2142 | {
2143 | "data": {
2144 | "id": "glyph45-glyph36",
2145 | "class": "production",
2146 | "cardinality": 0,
2147 | "source": "glyph45",
2148 | "target": "glyph36",
2149 | "bendPointPositions": [],
2150 | "portSource": "glyph45",
2151 | "portTarget": "glyph36"
2152 | },
2153 | "position": {
2154 | "x": 0,
2155 | "y": 0
2156 | },
2157 | "group": "edges",
2158 | "removed": false,
2159 | "selected": false,
2160 | "selectable": true,
2161 | "locked": false,
2162 | "grabbable": true,
2163 | "pannable": true,
2164 | "classes": ""
2165 | },
2166 | {
2167 | "data": {
2168 | "id": "glyph21-glyph41",
2169 | "class": "necessary stimulation",
2170 | "cardinality": 0,
2171 | "source": "glyph21",
2172 | "target": "glyph41",
2173 | "bendPointPositions": [],
2174 | "portSource": "glyph21",
2175 | "portTarget": "glyph41"
2176 | },
2177 | "position": {
2178 | "x": 0,
2179 | "y": 0
2180 | },
2181 | "group": "edges",
2182 | "removed": false,
2183 | "selected": false,
2184 | "selectable": true,
2185 | "locked": false,
2186 | "grabbable": true,
2187 | "pannable": true,
2188 | "classes": ""
2189 | },
2190 | {
2191 | "data": {
2192 | "id": "glyph5-glyph15",
2193 | "class": "consumption",
2194 | "cardinality": 0,
2195 | "source": "glyph5",
2196 | "target": "glyph15",
2197 | "bendPointPositions": [],
2198 | "portSource": "glyph5",
2199 | "portTarget": "glyph15"
2200 | },
2201 | "position": {
2202 | "x": 0,
2203 | "y": 0
2204 | },
2205 | "group": "edges",
2206 | "removed": false,
2207 | "selected": false,
2208 | "selectable": true,
2209 | "locked": false,
2210 | "grabbable": true,
2211 | "pannable": true,
2212 | "classes": ""
2213 | },
2214 | {
2215 | "data": {
2216 | "id": "glyph15-glyph12",
2217 | "class": "production",
2218 | "cardinality": 0,
2219 | "source": "glyph15",
2220 | "target": "glyph12",
2221 | "bendPointPositions": [],
2222 | "portSource": "glyph15",
2223 | "portTarget": "glyph12"
2224 | },
2225 | "position": {
2226 | "x": 0,
2227 | "y": 0
2228 | },
2229 | "group": "edges",
2230 | "removed": false,
2231 | "selected": false,
2232 | "selectable": true,
2233 | "locked": false,
2234 | "grabbable": true,
2235 | "pannable": true,
2236 | "classes": ""
2237 | },
2238 | {
2239 | "data": {
2240 | "id": "glyph47-glyph16",
2241 | "class": "consumption",
2242 | "cardinality": 0,
2243 | "source": "glyph47",
2244 | "target": "glyph16",
2245 | "bendPointPositions": [],
2246 | "portSource": "glyph47",
2247 | "portTarget": "glyph16"
2248 | },
2249 | "position": {
2250 | "x": 0,
2251 | "y": 0
2252 | },
2253 | "group": "edges",
2254 | "removed": false,
2255 | "selected": false,
2256 | "selectable": true,
2257 | "locked": false,
2258 | "grabbable": true,
2259 | "pannable": true,
2260 | "classes": ""
2261 | },
2262 | {
2263 | "data": {
2264 | "id": "glyph37-glyph32",
2265 | "class": "stimulation",
2266 | "cardinality": 0,
2267 | "source": "glyph37",
2268 | "target": "glyph32",
2269 | "bendPointPositions": [],
2270 | "portSource": "glyph37",
2271 | "portTarget": "glyph32"
2272 | },
2273 | "position": {
2274 | "x": 0,
2275 | "y": 0
2276 | },
2277 | "group": "edges",
2278 | "removed": false,
2279 | "selected": false,
2280 | "selectable": true,
2281 | "locked": false,
2282 | "grabbable": true,
2283 | "pannable": true,
2284 | "classes": ""
2285 | },
2286 | {
2287 | "data": {
2288 | "id": "glyph23-glyph41",
2289 | "class": "consumption",
2290 | "cardinality": 0,
2291 | "source": "glyph23",
2292 | "target": "glyph41",
2293 | "bendPointPositions": [],
2294 | "portSource": "glyph23",
2295 | "portTarget": "glyph41"
2296 | },
2297 | "position": {
2298 | "x": 0,
2299 | "y": 0
2300 | },
2301 | "group": "edges",
2302 | "removed": false,
2303 | "selected": false,
2304 | "selectable": true,
2305 | "locked": false,
2306 | "grabbable": true,
2307 | "pannable": true,
2308 | "classes": ""
2309 | }
2310 | ]
--------------------------------------------------------------------------------
/demo.webpack.config.js:
--------------------------------------------------------------------------------
1 | let conf = {
2 | entry: './demo.js',
3 |
4 | devtool: 'inline-source-map',
5 |
6 | output: {
7 | filename: './build/demo.js'
8 | },
9 |
10 | module: {
11 | rules: [
12 | { test: /\.js$/, exclude: /node_modules/, loader: 'babel-loader' }
13 | ]
14 | }
15 | };
16 |
17 | module.exports = conf;
18 |
--------------------------------------------------------------------------------
/demo.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
347 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "cytoscape-sbgn-stylesheet",
3 | "version": "4.0.2",
4 | "description": "cytoscape.js stylesheet for sbgn PD glyphs ",
5 | "repository": {
6 | "type": "git",
7 | "url": "https://github.com/PathwayCommons/cytoscape-sbgn-stylesheet.git"
8 | },
9 | "bugs": {
10 | "url": "https://github.com/PathwayCommons/cytoscape-sbgn-stylesheet/issues"
11 | },
12 | "homepage": "https://github.com/PathwayCommons/cytoscape-sbgn-stylesheet",
13 | "main": "./build/bundle.js",
14 | "scripts": {
15 | "postpublish": "run-s gh-pages",
16 | "gh-pages": "gh-pages -d pages",
17 | "prepublish": "run-s build",
18 | "lint:js": "eslint ./src",
19 | "bundle:js": "webpack",
20 | "bundle:demojs": "webpack --config demo.webpack.config.js",
21 | "watch:js": "webpack --watch",
22 | "watch:sync-bundle": "browser-sync start --config browser-sync.config.js",
23 | "dev": "webpack-dev-server --watch --open --open-page demo.html",
24 | "bundle": "run-s bundle:*",
25 | "build": "run-p bundle",
26 | "build-prod": "cross-env NODE_ENV=production run-s build",
27 | "clean": "rimraf build/*",
28 | "lint": "run-s lint:*",
29 | "watch": "run-p watch:*",
30 | "test": "mocha"
31 | },
32 | "dependencies": {
33 | "camelcase": "^4.1.0",
34 | "extend": "^3.0.0",
35 | "lodash.defaultsdeep": "^4.6.0",
36 | "lodash.memoize": "^4.1.2",
37 | "text-width": "^1.2.0"
38 | },
39 | "peerDependencies": {
40 | "cytoscape": "^3.2.0"
41 | },
42 | "devDependencies": {
43 | "babel-core": "^6.26.0",
44 | "babel-loader": "^7.1.2",
45 | "babel-polyfill": "^6.9.1",
46 | "babel-preset-env": "^1.6.0",
47 | "browser-sync": "^2.18.13",
48 | "chai": "^4.1.2",
49 | "cross-env": "^5.0.0",
50 | "echo-cli": "^1.0.8",
51 | "eslint": "^4.6.1",
52 | "eslint-config-standard": "^10.2.1",
53 | "eslint-plugin-import": "^2.7.0",
54 | "eslint-plugin-node": "^5.1.1",
55 | "eslint-plugin-promise": "^3.5.0",
56 | "eslint-plugin-standard": "^3.0.1",
57 | "gh-pages": "^2.2.0",
58 | "mocha": "^3.5.3",
59 | "npm-run-all": "^4.1.1",
60 | "rimraf": "^2.6.2",
61 | "uglifyjs-webpack-plugin": "^0.4.6",
62 | "webpack": "^3.10.0",
63 | "webpack-bundle-analyzer": "^2.9.0",
64 | "webpack-dev-server": "^2.11.1"
65 | },
66 | "engines": {
67 | "node": ">=6.3.0"
68 | },
69 | "browserslist": "last 3 versions, >1%"
70 | }
71 |
--------------------------------------------------------------------------------
/pages/build:
--------------------------------------------------------------------------------
1 | ../build
--------------------------------------------------------------------------------
/pages/demo.json:
--------------------------------------------------------------------------------
1 | ../demo.json
--------------------------------------------------------------------------------
/pages/index.html:
--------------------------------------------------------------------------------
1 | ../demo.html
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | let sbgnStyleSheet = require('./sbgnStyle/');
2 |
3 | let defaultOptions = {
4 | };
5 |
6 | module.exports = function(cytoscape){
7 | return sbgnStyleSheet(cytoscape);
8 | };
9 |
--------------------------------------------------------------------------------
/src/sbgnStyle/element.js:
--------------------------------------------------------------------------------
1 | const sbgnData = require('./util/sbgn.js');
2 |
3 | const sbgnStyle = new Map()
4 | .set('unspecified entity', {w: 32, h: 32, shape: 'ellipse'})
5 | .set('simple chemical', {w: 48, h: 48, shape: 'ellipse'})
6 | .set('simple chemical multimer', {w: 48, h: 48, shape: 'ellipse'})
7 | .set('macromolecule', {w: 96, h: 48, shape: 'roundrectangle'})
8 | .set('macromolecule multimer', {w: 96, h: 48, shape: 'roundrectangle'})
9 | .set('nucleic acid feature', {w: 88, h: 56, shape: 'bottomroundrectangle'})
10 | .set('nucleic acid feature multimer', {w: 88, h: 52, shape: 'bottomroundrectangle'})
11 | .set('complex', {w: 10, h: 10, shape: 'cutrectangle'})
12 | .set('complex multimer', {w: 10, h: 10, shape: 'cutrectangle'})
13 | .set('source and sink', {w: 60, h: 60, shape: 'polygon'})
14 | .set('perturbing agent', {w: 140, h: 60, shape: 'concavehexagon'})
15 |
16 | .set('phenotype', {w: 140, h: 60, shape: 'hexagon'})
17 | .set('process', {w:25, h: 25, shape: 'square'})
18 | .set('uncertain process', {w:25, h: 25, shape: 'square'})
19 | .set('omitted process', {w:25, h: 25, shape: 'square'})
20 | .set('association', {w:25, h: 25, shape: 'ellipse'})
21 | .set('dissociation', {w:25, h: 25, shape: 'ellipse'})
22 |
23 | .set('compartment', {w: 50, h: 50, shape: 'barrel'})
24 |
25 | .set('tag', {w: 100, h: 65, shape: 'tag'})
26 | .set('and', {w: 40, h: 40, shape: 'ellipse'})
27 | .set('or', {w: 40, h: 40, shape: 'ellipse'})
28 | .set('not', {w: 40, h: 40, shape: 'ellipse'});
29 |
30 | const sbgnArrowMap = new Map()
31 | .set('necessary stimulation', 'triangle-cross')
32 | .set('inhibition', 'tee')
33 | .set('catalysis', 'circle')
34 | .set('stimulation', 'triangle')
35 | .set('production', 'triangle')
36 | .set('modulation', 'diamond');
37 |
38 | const elementStyle = {
39 | sbgnShape (node) {
40 | const sbgnClass = sbgnData.sbgnClass(node).replace(' multimer', '');
41 | const style = sbgnStyle.get(sbgnClass);
42 | return style ? style.shape : 'ellipse';
43 | },
44 |
45 | sbgnArrowShape (edge) {
46 | const sbgnClass = sbgnData.sbgnClass(edge);
47 | const shape = sbgnArrowMap.get(sbgnClass);
48 | return shape ? shape : 'none';
49 | },
50 |
51 | sbgnContent (node) {
52 | const sbgnClass = sbgnData.sbgnClass(node).replace(' multimer', '');
53 | let content = sbgnData.sbgnLabel(node);
54 |
55 | if (sbgnClass == 'and') {
56 | content = 'AND';
57 | }
58 | if (sbgnClass == 'or') {
59 | content = 'OR';
60 | }
61 | if (sbgnClass == 'not') {
62 | content = 'NOT';
63 | }
64 | if (sbgnClass == 'omitted process') {
65 | content = '\\\\';
66 | }
67 | if (sbgnClass == 'uncertain process') {
68 | content = '?';
69 | }
70 |
71 | return content;
72 | },
73 |
74 | dimensions (node) {
75 | const sbgnClass = sbgnData.sbgnClass(node);
76 | const dim = sbgnStyle.get(sbgnClass);
77 | if (dim == null) {
78 | throw new TypeError(`${sbgnClass} does not have a default width / height`);
79 | }
80 | return dim;
81 | },
82 |
83 | width (node) {
84 | return this.dimensions(node).w;
85 | },
86 |
87 | height (node) {
88 | return this.dimensions(node).h;
89 | }
90 | };
91 |
92 | module.exports = elementStyle;
93 |
--------------------------------------------------------------------------------
/src/sbgnStyle/glyph/auxiliaryItems.js:
--------------------------------------------------------------------------------
1 | const textWidth = require('text-width');
2 |
3 | const baseShapes = require('./baseShapes.js');
4 | const sbgnData = require('../util/sbgn');
5 |
6 | const auxiliaryItems = {
7 |
8 | multiImgCloneMarker (x, y, width, height) {
9 |
10 | const cloneStyle = new Map()
11 | .set('stroke', '#6A6A6A')
12 | .set('stroke-width', '1')
13 | .set('fill', '#D2D2D2');
14 |
15 | return baseShapes.rectangle(x, y, width, height, cloneStyle);
16 | },
17 |
18 | multiImgUnitOfInformation (x, y, width, height, uInfo, borderWidth=3, fontSize=14) {
19 | const text = uInfo.label.text;
20 | const uinfoRectStyle = new Map()
21 | .set('stroke', '#555555')
22 | .set('stroke-width', `${borderWidth}`)
23 | .set('fill', 'white')
24 | .set('fill-opacity', 1);
25 |
26 |
27 | const textStyle = new Map()
28 | .set('alignment-baseline', 'middle')
29 | .set('font-size', `${fontSize}px`)
30 | .set('font-family', 'Helvetica Neue, Helvetica, sans-serif')
31 | .set('text-anchor', 'middle');
32 |
33 | const uInfoWidth = textWidth(text, { family: textStyle.get('font-family'), size: fontSize}) + 5;
34 |
35 | const unitOfInformationSvg =
36 | `
37 | ${baseShapes.roundRectangle(x, y, uInfoWidth, height, uinfoRectStyle)}
38 | ${baseShapes.text(text, x + (uInfoWidth / 2), y + ( height / 2), textStyle)}
39 | `;
40 |
41 | return unitOfInformationSvg;
42 | },
43 |
44 | multiImgStateVar (x, y, width, height, stateVar, borderWidth=3, fontSize=14) {
45 |
46 | const stateVarStyle = new Map()
47 | .set('stroke', '#555555')
48 | .set('stroke-width', `${borderWidth}`)
49 | .set('fill', 'white')
50 | .set('fill-opacity', 1);
51 |
52 | const textStyle = new Map()
53 | .set('alignment-baseline', 'middle')
54 | .set('font-size', `${fontSize}px`)
55 | .set('font-family', 'Helvetica Neue, Helvetica, sans-serif')
56 | .set('text-anchor', 'middle');
57 |
58 | const tw = textWidth(sbgnData.stateVarLabel(stateVar), { family: textStyle.get('font-family'), size: fontSize}) + 10;
59 | const w = Math.max(tw, 30);
60 | const statevariableSvg =
61 | `
62 | ${baseShapes.stadium(x, y, w, height, stateVarStyle)}
63 | ${baseShapes.text(sbgnData.stateVarLabel(stateVar), x + ( w / 2 ), y + height / 2, textStyle)}
64 | `;
65 |
66 | return statevariableSvg;
67 | },
68 |
69 | cloneMarker (nodeWidth, nodeHeight, shapeFn, shapeFnArgs) {
70 | const clipId = 'clonemarker';
71 |
72 | const cloneMarkerStyle = new Map()
73 | .set('stroke', '#6A6A6A')
74 | .set('stroke-width', '1.5')
75 | .set('clip-path', `url(#${clipId})`)
76 | .set('fill', '#D2D2D2');
77 |
78 | const cloneMarkerSvg =
79 | `
80 | ${baseShapes.clipPath(clipId, baseShapes.rectangle, [0, 3 * nodeHeight / 4, nodeWidth, nodeHeight, new Map()])}
81 | ${shapeFn(...shapeFnArgs, cloneMarkerStyle)}
82 | `;
83 |
84 | return cloneMarkerSvg;
85 | }
86 | };
87 |
88 | module.exports = auxiliaryItems;
89 |
--------------------------------------------------------------------------------
/src/sbgnStyle/glyph/baseShapes.js:
--------------------------------------------------------------------------------
1 | const styleMap2Str = require('../util/svg.js').styleMap2Str;
2 |
3 | let baseRectangle = function (x, y, w, h, r1, r2, r3, r4, styleMap) {
4 | return `
5 |
13 | `;
14 | };
15 |
16 | const baseShapes = {
17 | barrel (x, y, width, height, styleMap) {
18 | return `
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 | `;
31 | },
32 |
33 | circle (cx, cy, r, styleMap) {
34 | return ``;
35 | },
36 |
37 | clipPath (id, baseShapeFn, baseShapeFnArgs, styleMap) {
38 | return `
39 |
40 |
41 | ${baseShapeFn(...baseShapeFnArgs)}
42 |
43 |
44 | `;
45 | },
46 |
47 | concaveHexagon (x, y, width, height, styleMap) {
48 | return `
49 | `;
52 | },
53 |
54 | cutRectangle (x, y, width, height, cornerLength, styleMap) {
55 | return `
56 |
62 | `;
63 | },
64 |
65 | ellipse (cx, cy, rx, ry, styleMap) {
66 | return `
67 |
68 | `;
69 | },
70 |
71 | hexagon (x, y, width, height, styleMap) {
72 | return `
73 | `;
76 | },
77 |
78 | line (x1, y1, x2, y2, styleMap) {
79 | return ``;
80 | },
81 |
82 | rectangle (x, y, width, height, styleMap) {
83 | return baseRectangle(x, y, width, height, 0, 0, 0, 0, styleMap);
84 | },
85 |
86 | roundBottomRectangle (x, y, width, height, styleMap) {
87 | return baseRectangle(x, y, width, height, 0, 0, .3*height, .3*height, styleMap);
88 | },
89 |
90 | roundRectangle (x, y, width, height, styleMap) {
91 | return baseRectangle(x, y, width, height, .04*width, .04*width, .04*width, .04*width, styleMap);
92 | },
93 |
94 | stadium (x, y, width, height, styleMap) {
95 | const radiusRatio = .24 * Math.max(width, height);
96 | return baseRectangle(x, y, width, height, radiusRatio, radiusRatio, radiusRatio, radiusRatio, styleMap);
97 | },
98 |
99 | square (x, y, length, styleMap) {
100 | return baseRectangle(x, y, length, length, 0, 0, 0, 0, styleMap);
101 | },
102 |
103 | text (t, x, y, styleMap) {
104 | return `${t}`;
105 | }
106 |
107 | };
108 |
109 |
110 | module.exports = baseShapes;
111 |
--------------------------------------------------------------------------------
/src/sbgnStyle/glyph/containerNodes.js:
--------------------------------------------------------------------------------
1 | const svgStr = require('../util/svg').svgStr;
2 | const sbgnData = require('../util/sbgn');
3 | const memoize = require('lodash.memoize');
4 |
5 | const auxiliaryItems = require('./auxiliaryItems');
6 | const baseShapes = require('./baseShapes');
7 |
8 | const containerNodes = {
9 |
10 | compartment (node) {
11 | const auxItemWidth = 60;
12 | const auxItemHeight = 40;
13 | const uInfos = sbgnData.getUnitInfos(node);
14 |
15 | const style = new Map()
16 | .set('stroke', '#555555')
17 | .set('stroke-width', '6');
18 |
19 | const uInfoSvg = svgStr(
20 | uInfos.length > 0 ? auxiliaryItems.multiImgUnitOfInformation(2, 0, auxItemWidth - 5, auxItemHeight - 3, uInfos[0]) : '',
21 | auxItemWidth, auxItemHeight
22 | );
23 |
24 | let lineSvg = svgStr(
25 | uInfos.length > 0 ? baseShapes.line(0, 0, auxItemWidth, 0, style) : '',
26 | auxItemWidth, auxItemHeight
27 | );
28 |
29 | return {
30 | bgImage: [lineSvg, uInfoSvg],
31 | bgWidth: ['100%'],
32 | bgPosX: ['0%', '25%'],
33 | bgPosY: ['19px', '0%'],
34 | bgFit: ['contain', 'none'],
35 | bgClip: 'node',
36 | padding: '38px',
37 | borderWidth: '4'
38 | };
39 | }
40 | };
41 |
42 | module.exports = containerNodes;
43 |
--------------------------------------------------------------------------------
/src/sbgnStyle/glyph/entityPoolNodes.js:
--------------------------------------------------------------------------------
1 | const baseShapes = require('./baseShapes');
2 | const auxiliaryItems = require('./auxiliaryItems');
3 |
4 | const svgStr = require('../util/svg').svgStr;
5 | const getUnitInfos = require('../util/sbgn').getUnitInfos;
6 | const getStateVars = require('../util/sbgn').getStateVars;
7 | const hasClonemarker = require('../util/sbgn').hasClonemarker;
8 |
9 | const element = require('../element');
10 |
11 |
12 | const entityPoolNodes = {
13 |
14 | unspecifiedEntity (node) {
15 | const auxItemWidth = 100;
16 | const auxItemHeight = 20;
17 | const borderWidth = 2;
18 | const fontSize = 10;
19 | const uInfos = getUnitInfos(node);
20 | const sVars = getStateVars(node);
21 |
22 | const style = new Map()
23 | .set('stroke', '#6A6A6A')
24 | .set('stroke-width', '1');
25 |
26 | const cloneMarkerSvg = svgStr(
27 | hasClonemarker(node) ? auxiliaryItems.multiImgCloneMarker(0, 2, auxItemWidth, auxItemHeight - 3) : '',
28 | auxItemWidth, auxItemHeight
29 | );
30 |
31 | const uInfoSvg = svgStr(
32 | uInfos.length > 0 ? auxiliaryItems.multiImgUnitOfInformation(2, 0, auxItemWidth - 5, auxItemHeight - 3, uInfos[0], borderWidth, fontSize) : '',
33 | auxItemWidth, auxItemHeight
34 | );
35 |
36 | const sVarSvg = svgStr(
37 | sVars.length > 0 ? auxiliaryItems.multiImgStateVar(2, 0, auxItemWidth - 5, auxItemHeight - 3, sVars[0], borderWidth, fontSize) : '',
38 | auxItemWidth, auxItemHeight
39 | );
40 |
41 | const topLine = svgStr(
42 | uInfos.length + sVars.length > 0 ? baseShapes.line(0, 0, auxItemWidth, 0, style) : '',
43 | auxItemWidth, auxItemHeight
44 | );
45 |
46 | const bottomLine = svgStr(
47 | hasClonemarker(node) || uInfos.length > 0 ? baseShapes.line(0, 0, auxItemWidth, 0, style) : '',
48 | auxItemWidth, auxItemHeight
49 | );
50 | return {
51 | bgImage: [bottomLine, topLine, cloneMarkerSvg, uInfoSvg, sVarSvg],
52 | bgWidth: ['100%', '100%', '100%'],
53 | bgPosX: ['0%', '0%', '0%', '20px', '40px'],
54 | bgPosY: ['52px', '8px', '32px', '44px', '0%'],
55 | bgFit: ['cover', 'cover', 'none', 'none'],
56 | bgClip: 'node',
57 | padding: '8px',
58 | borderWidth: 2
59 | };
60 |
61 | },
62 |
63 | simpleChemical (node) {
64 | const auxItemWidth = 100;
65 | const auxItemHeight = 20;
66 | const borderWidth = 2;
67 | const fontSize = 10;
68 | const uInfos = getUnitInfos(node);
69 |
70 | const style = new Map()
71 | .set('stroke', '#6A6A6A')
72 | .set('stroke-width', '1');
73 |
74 | const cloneMarkerSvg = svgStr(
75 | hasClonemarker(node) ? auxiliaryItems.multiImgCloneMarker(0, 2, auxItemWidth, auxItemHeight - 3) : '',
76 | auxItemWidth, auxItemHeight
77 | );
78 |
79 | const uInfoSvg = svgStr(
80 | uInfos.length > 0 ? auxiliaryItems.multiImgUnitOfInformation(2, 0, auxItemWidth - 5, auxItemHeight - 3, uInfos[0], borderWidth, fontSize) : '',
81 | auxItemWidth, auxItemHeight
82 | );
83 |
84 | const topLine = svgStr(
85 | uInfos.length > 0 ? baseShapes.line(0, 0, auxItemWidth, 0, style) : '',
86 | auxItemWidth, auxItemHeight
87 | );
88 |
89 | const bottomLine = svgStr(
90 | hasClonemarker(node) || uInfos.length > 0 ? baseShapes.line(0, 0, auxItemWidth, 0, style) : '',
91 | auxItemWidth, auxItemHeight
92 | );
93 |
94 | return {
95 | bgImage: [bottomLine, topLine, cloneMarkerSvg, uInfoSvg],
96 | bgWidth: ['100%', '100%', '100%'],
97 | bgPosX: ['0%', '0%', '0%', '12px'],
98 | bgPosY: ['52px', '8px', '48px', '0px'],
99 | bgFit: ['cover', 'cover', 'none', 'none'],
100 | bgClip: 'node',
101 | padding: '8px',
102 | borderWidth: 2
103 | };
104 | },
105 |
106 | macromolecule(node) {
107 | const auxItemWidth = 100;
108 | const auxItemHeight = 20;
109 | const borderWidth = 2;
110 | const fontSize = 10;
111 | const uInfos = getUnitInfos(node);
112 | const sVars = getStateVars(node);
113 |
114 | const style = new Map()
115 | .set('stroke', '#6A6A6A')
116 | .set('stroke-width', '1');
117 |
118 | const cloneMarkerSvg = svgStr(
119 | hasClonemarker(node) ? auxiliaryItems.multiImgCloneMarker(0, 2, auxItemWidth, auxItemHeight - 3) : '',
120 | auxItemWidth, auxItemHeight
121 | );
122 |
123 | const uInfoSvg = svgStr(
124 | uInfos.length > 0 ? auxiliaryItems.multiImgUnitOfInformation(2, 0, auxItemWidth - 5, auxItemHeight - 3, uInfos[0], borderWidth, fontSize) : '',
125 | auxItemWidth, auxItemHeight
126 | );
127 |
128 | const sVarSvg = svgStr(
129 | sVars.length > 0 ? auxiliaryItems.multiImgStateVar(2, 0, auxItemWidth - 5, auxItemHeight - 3, sVars[0], borderWidth, fontSize) : '',
130 | auxItemWidth, auxItemHeight
131 | );
132 |
133 | const topLine = svgStr(
134 | uInfos.length + sVars.length > 0 ? baseShapes.line(0, 0, auxItemWidth, 0, style) : '',
135 | auxItemWidth, auxItemHeight
136 | );
137 |
138 | const bottomLine = svgStr(
139 | hasClonemarker(node) || uInfos.length > 0 ? baseShapes.line(0, 0, auxItemWidth, 0, style) : '',
140 | auxItemWidth, auxItemHeight
141 | );
142 |
143 | return {
144 | bgImage: [bottomLine, topLine, cloneMarkerSvg, uInfoSvg, sVarSvg],
145 | bgWidth: ['100%', '100%', '100%'],
146 | bgPosX: ['0%', '0%', '0%', '20px', '40px'],
147 | bgPosY: ['52px', '8px', '52px', '44px', '0%'],
148 | bgFit: ['cover', 'cover', 'none', 'none'],
149 | bgClip: 'node',
150 | padding: '8px',
151 | borderWidth: 2
152 | }; },
153 |
154 | nucleicAcidFeature (node) {
155 | const auxItemWidth = 100;
156 | const auxItemHeight = 20;
157 | const borderWidth = 2;
158 | const fontSize = 10;
159 | const uInfos = getUnitInfos(node);
160 | const sVars = getStateVars(node);
161 |
162 | const style = new Map()
163 | .set('stroke', '#6A6A6A')
164 | .set('stroke-width', '1');
165 |
166 | const cloneMarkerSvg = svgStr(
167 | hasClonemarker(node) ? auxiliaryItems.multiImgCloneMarker(0, 2, auxItemWidth, auxItemHeight - 3) : '',
168 | auxItemWidth, auxItemHeight
169 | );
170 |
171 | const uInfoSvg = svgStr(
172 | uInfos.length > 0 ? auxiliaryItems.multiImgUnitOfInformation(2, 0, auxItemWidth - 5, auxItemHeight - 3, uInfos[0], borderWidth, fontSize) : '',
173 | auxItemWidth, auxItemHeight
174 | );
175 |
176 | const sVarSvg = svgStr(
177 | sVars.length > 0 ? auxiliaryItems.multiImgStateVar(2, 0, auxItemWidth - 5, auxItemHeight - 3, sVars[0], borderWidth, fontSize) : '',
178 | auxItemWidth, auxItemHeight
179 | );
180 |
181 | const topLine = svgStr(
182 | sVars.length > 0 ? baseShapes.line(0, 0, auxItemWidth, 0, style) : '',
183 | auxItemWidth, auxItemHeight
184 | );
185 |
186 | const bottomLine = svgStr(
187 | hasClonemarker(node) || uInfos.length > 0 ? baseShapes.line(0, 0, auxItemWidth, 0, style) : '',
188 | auxItemWidth, auxItemHeight
189 | );
190 |
191 | return {
192 | bgImage: [bottomLine, topLine, cloneMarkerSvg, uInfoSvg, sVarSvg],
193 | bgWidth: ['100%', '100%', '100%'],
194 | bgPosX: ['0%', '0%', '0%', '20px', '40px'],
195 | bgPosY: ['52px', '8px', '52px', '44px', '0%'],
196 | bgFit: ['cover', 'cover', 'none', 'none'],
197 | bgClip: 'node',
198 | padding: '8px',
199 | borderWidth: 2
200 | };
201 | },
202 |
203 | complex (node) {
204 | const itemW = 60;
205 | const itemH = 24;
206 | const uInfos = getUnitInfos(node);
207 | const sVars = getStateVars(node);
208 |
209 | const images = [];
210 | const bgWidth = [];
211 | const bgHeight = [];
212 | const bgPosX = [];
213 | const bgPosY = [];
214 | const bgFit = [];
215 |
216 | const style = new Map()
217 | .set('stroke', '#555555')
218 | .set('stroke-width', '6');
219 |
220 | // order of svg image generation matters
221 | if (uInfos.length + sVars.length > 0) {
222 | const topLineSvg = svgStr(baseShapes.line(0, 0, itemW, 0, style), itemW, itemH);
223 | images.push(topLineSvg);
224 | bgWidth.push('100%');
225 | bgPosX.push('0%');
226 | bgPosY.push('11px');
227 | bgFit.push('none');
228 | }
229 |
230 | if (hasClonemarker(node)) {
231 | const bottomLineSvg = svgStr(baseShapes.line(0, 0, itemW, 0, style), itemW, itemH);
232 | images.push(bottomLineSvg);
233 | bgWidth.push('100%');
234 | bgPosX.push('0%');
235 | bgPosY.push('100%');
236 | bgFit.push('none');
237 | }
238 |
239 | if (hasClonemarker(node)) {
240 | const cloneSvg = svgStr(auxiliaryItems.multiImgCloneMarker(0, 2, itemW, itemH - 3), itemW, itemH);
241 | images.push(cloneSvg);
242 | bgWidth.push('100%');
243 | bgPosX.push('0%');
244 | bgPosY.push('100%');
245 | bgFit.push('none');
246 | }
247 |
248 | if (uInfos.length > 0) {
249 | const uInfoSvg = svgStr(auxiliaryItems.multiImgUnitOfInformation(2, 0, itemW - 5, itemH - 3, uInfos[0]), itemW, itemH);
250 | images.push(uInfoSvg);
251 | bgPosX.push('25%');
252 | bgPosY.push('0%');
253 | bgFit.push('none');
254 | }
255 |
256 | if (sVars.length > 0) {
257 | const sVarSvg = svgStr(auxiliaryItems.multiImgStateVar(2, 0, itemW - 5, itemH - 3, sVars[0]), itemW, itemH);
258 | images.push(sVarSvg);
259 | bgPosX.push('88%');
260 | bgPosY.push('0%');
261 | bgFit.push('none');
262 | }
263 |
264 | return {
265 | bgImage: images,
266 | bgWidth: bgWidth,
267 | bgPosX: bgPosX,
268 | bgPosY: bgPosY,
269 | bgFit: bgFit,
270 | bgClip: 'node',
271 | padding: '22px',
272 | borderWidth: 4
273 | };
274 | },
275 |
276 | sourceAndSink (node) {
277 | const {w: nw, h: nh} = element.dimensions(node);
278 |
279 | const centerX = nw / 2;
280 | const centerY = nh / 2;
281 | const radius = (nw - 2) / 2;
282 |
283 | const styleMap = new Map()
284 | .set('stroke', '#6A6A6A')
285 | .set('stroke-linecap', 'square')
286 | .set('stroke-width', '1.5')
287 | .set('fill', 'none');
288 |
289 | const shapeArgs = [centerX, centerY, radius];
290 |
291 | const sourceAndSinkSvg =
292 | `
293 | ${baseShapes.circle(...shapeArgs, styleMap)}
294 | ${hasClonemarker(node) ? auxiliaryItems.cloneMarker(nw, nh, baseShapes.circle, shapeArgs) : ''}
295 | ${baseShapes.line(0, nh, nw, 0, styleMap)}
296 | `;
297 |
298 | return svgStr(sourceAndSinkSvg, nw, nh, 0, 0, nw, nh);
299 | },
300 |
301 | perturbingAgent (node) {
302 | const auxItemWidth = 100;
303 | const auxItemHeight = 20;
304 | const borderWidth = 2;
305 | const fontSize = 10;
306 | const uInfos = getUnitInfos(node);
307 |
308 | const style = new Map()
309 | .set('stroke', '#6A6A6A')
310 | .set('stroke-width', '1');
311 |
312 | const cloneMarkerSvg = svgStr(
313 | hasClonemarker(node) ? auxiliaryItems.multiImgCloneMarker(0, 2, auxItemWidth, auxItemHeight - 3) : '',
314 | auxItemWidth, auxItemHeight
315 | );
316 |
317 | const uInfoSvg = svgStr(
318 | uInfos.length > 0 ? auxiliaryItems.multiImgUnitOfInformation(2, 0, auxItemWidth - 5, auxItemHeight - 3, uInfos[0], borderWidth, fontSize) : '',
319 | auxItemWidth, auxItemHeight
320 | );
321 |
322 | const topLine = svgStr(
323 | uInfos.length > 0 ? baseShapes.line(0, 0, auxItemWidth, 0, style) : '',
324 | auxItemWidth, auxItemHeight
325 | );
326 |
327 | const bottomLine = svgStr(
328 | hasClonemarker(node) || uInfos.length > 0 ? baseShapes.line(0, 0, auxItemWidth, 0, style) : '',
329 | auxItemWidth, auxItemHeight
330 | );
331 |
332 | return {
333 | bgImage: [bottomLine, topLine, cloneMarkerSvg, uInfoSvg],
334 | bgWidth: ['100%', '100%', '100%'],
335 | bgPosX: ['0%', '0%', '0%', '20px'],
336 | bgPosY: ['56px', '8px', '56px', '0%'],
337 | bgFit: ['cover', 'cover', 'none', 'none'],
338 | bgClip: 'node',
339 | padding: '8px',
340 | borderWidth: 2
341 | };
342 | }
343 | };
344 |
345 | module.exports = entityPoolNodes;
346 |
--------------------------------------------------------------------------------
/src/sbgnStyle/glyph/index.js:
--------------------------------------------------------------------------------
1 | const memoize = require('lodash.memoize');
2 |
3 | const containerNodes = require('./containerNodes.js');
4 | const entityPoolNodes = require('./entityPoolNodes.js');
5 | const processNodes = require('./processNodes.js');
6 |
7 | const sbgnData = require('../util/sbgn.js');
8 |
9 | const cacheKeyFn = (node) => '' + JSON.stringify(node.id());
10 |
11 | const sbgnNodeShapeMap = new Map()
12 | // process nodes
13 | .set('dissociation', memoize(processNodes.dissociation, cacheKeyFn))
14 | .set('phenotype', memoize(processNodes.phenotype, cacheKeyFn))
15 |
16 | // entity pool nodes
17 | .set('source and sink', memoize(entityPoolNodes.sourceAndSink, cacheKeyFn))
18 | .set('unspecified entity', memoize(entityPoolNodes.unspecifiedEntity, cacheKeyFn))
19 | .set('simple chemical', memoize(entityPoolNodes.simpleChemical, cacheKeyFn))
20 | .set('macromolecule', memoize(entityPoolNodes.macromolecule, cacheKeyFn))
21 | .set('nucleic acid feature', memoize(entityPoolNodes.nucleicAcidFeature, cacheKeyFn))
22 | .set('complex', memoize(entityPoolNodes.complex, cacheKeyFn))
23 | .set('perturbing agent', memoize(entityPoolNodes.perturbingAgent, cacheKeyFn))
24 |
25 | // container nodes
26 | .set('compartment', memoize(containerNodes.compartment, cacheKeyFn));
27 |
28 |
29 | const draw = (node) => {
30 | const sbgnClass = sbgnData.sbgnClass(node).replace(' multimer', '');
31 | let shapeFn = sbgnNodeShapeMap.get(sbgnClass);
32 | if (shapeFn == null) {
33 | throw new TypeError(`${sbgnClass} does not have a shape implementation`);
34 | }
35 | return shapeFn(node);
36 | };
37 |
38 | module.exports = {
39 | draw: draw
40 | };
41 |
--------------------------------------------------------------------------------
/src/sbgnStyle/glyph/processNodes.js:
--------------------------------------------------------------------------------
1 | const baseShapes = require('./baseShapes');
2 | const auxiliaryItems = require('./auxiliaryItems');
3 |
4 | const svgStr = require('../util/svg').svgStr;
5 | const hasClonemarker = require('../util/sbgn').hasClonemarker;
6 |
7 | const element = require('../element');
8 |
9 | const processNodes = {
10 |
11 | dissociation (node) {
12 | const {w: nw, h: nh} = element.dimensions(node);
13 |
14 | const centerX = nw / 2;
15 | const centerY = nh / 2;
16 | const outerRadius = (Math.min(nw, nh) - 2) / 2;
17 | const innerRadius = (Math.min(nw, nh) - 2) / 3;
18 |
19 | const styleMap = new Map()
20 | .set('stroke', '#6A6A6A')
21 | .set('stroke-width', '2')
22 | .set('fill', 'none');
23 |
24 | const dissociationSvg =
25 | `
26 | ${baseShapes.circle(centerX, centerY, outerRadius, styleMap)}
27 | ${baseShapes.circle(centerX, centerY, innerRadius, styleMap)}
28 | `;
29 | return svgStr(dissociationSvg, nw, nh);
30 | },
31 |
32 | phenotype (node) {
33 | const auxItemWidth = 100;
34 | const auxItemHeight = 20;
35 |
36 | const style = new Map()
37 | .set('stroke', '#6A6A6A')
38 | .set('stroke-width', '1');
39 |
40 | const cloneMarkerSvg = svgStr(
41 | hasClonemarker(node) ? auxiliaryItems.multiImgCloneMarker(0, 2, auxItemWidth, auxItemHeight - 3) : '',
42 | auxItemWidth, auxItemHeight, 0, 0, auxItemWidth, auxItemHeight
43 | );
44 |
45 | const bottomLine = svgStr(
46 | hasClonemarker(node) ? baseShapes.line(0, 0, auxItemWidth, 0, style) : '',
47 | auxItemWidth, auxItemHeight, 0, 0, auxItemWidth, auxItemHeight
48 | );
49 |
50 | return {
51 | bgImage: [bottomLine, cloneMarkerSvg],
52 | bgWidth: ['100%', '100%'],
53 | bgPosX: ['0%', '0%'],
54 | bgPosY: ['56px', '56px'],
55 | bgFit: ['cover', 'none'],
56 | bgClip: 'node',
57 | padding: '8px',
58 | borderWidth: 2
59 | };
60 | }
61 | };
62 |
63 | module.exports = processNodes;
64 |
--------------------------------------------------------------------------------
/src/sbgnStyle/index.js:
--------------------------------------------------------------------------------
1 | const elementStyle = require('./element');
2 | const sbgnsvg = require('./glyph');
3 |
4 | const sbgnStyleSheet = function (cytoscape) {
5 |
6 | return cytoscape.stylesheet()
7 | // general node style
8 | .selector('node')
9 | .css({
10 | 'shape': (node) => elementStyle.sbgnShape(node),
11 | 'content': (node) => elementStyle.sbgnContent(node),
12 | 'font-size': 20,
13 | 'width': (node) => elementStyle.width(node),
14 | 'height': (node) => elementStyle.height(node),
15 | 'text-valign': 'center',
16 | 'text-halign': 'center',
17 | 'border-width': 1.5,
18 | 'border-color': '#555',
19 | 'background-color': '#f6f6f6',
20 | 'text-opacity': 1,
21 | 'opacity': 1,
22 | 'text-outline-color': 'white',
23 | 'text-outline-opacity': 1,
24 | 'text-outline-width': 0.75
25 | })
26 | .selector('node:selected')
27 | .css({
28 | 'background-color': '#d67614',
29 | 'target-arrow-color': '#000',
30 | 'text-outline-color': '#000'
31 | })
32 | .selector('node:active')
33 | .css({
34 | 'overlay-color': '#d67614',
35 | 'overlay-padding': '14'
36 | })
37 |
38 | // draw sbgn specific styling (auxiliary items, clonemarker, etc.)
39 | .selector(`
40 | node[class="unspecified entity"],
41 | node[class="simple chemical"], node[class="simple chemical multimer"],
42 | node[class="macromolecule"], node[class="macromolecule multimer"],
43 | node[class="nucleic acid feature"], node[class="nucleic acid feature multimer"],
44 | node[class="perturbing agent"],
45 | node[class="phenotype"],
46 | node[class="complex"], node[class="complex multimer"], node[class="compartment"]
47 | `)
48 | .css({
49 | 'background-image': (node) => sbgnsvg.draw(node).bgImage,
50 | 'background-width': (node) => sbgnsvg.draw(node).bgWidth,
51 | 'background-position-x': (node) => sbgnsvg.draw(node).bgPosX,
52 | 'background-position-y': (node) => sbgnsvg.draw(node).bgPosY,
53 | 'background-fit': (node) => sbgnsvg.draw(node).bgFit,
54 | 'background-clip': (node) => sbgnsvg.draw(node).bgClip,
55 | 'padding': (node) => sbgnsvg.draw(node).padding,
56 | 'border-width': (node) => sbgnsvg.draw(node).borderWidth
57 | })
58 |
59 | .selector(`
60 | node[class="simple chemical multimer"],
61 | node[class="macromolecule multimer"],
62 | node[class="nucleic acid feature multimer"],
63 | node[class="complex multimer"]
64 | `)
65 | .css({
66 | 'ghost': 'yes',
67 | 'ghost-opacity': 1
68 | })
69 |
70 | .selector(`
71 | node[class="macromolecule multimer"],
72 | node[class="nucleic acid feature multimer"]
73 | `)
74 | .css({
75 | 'ghost-offset-x': 12,
76 | 'ghost-offset-y': 12
77 | })
78 |
79 | .selector(`
80 | node[class="simple chemical multimer"]
81 | `)
82 | .css({
83 | 'ghost-offset-x': 5,
84 | 'ghost-offset-y': 5
85 | })
86 |
87 | .selector(`
88 | node[class="complex multimer"]
89 | `)
90 | .css({
91 | 'ghost-offset-x': 16,
92 | 'ghost-offset-y': 16
93 | })
94 |
95 | // compound node specific style
96 | .selector('node[class="complex"], node[class="complex multimer"], node[class="compartment"]')
97 | .css({
98 | 'compound-sizing-wrt-labels': 'exclude',
99 | 'text-valign': 'bottom',
100 | 'text-halign': 'center',
101 | })
102 |
103 | // process node specific style
104 | .selector('node[class="association"], node[class="dissociation"]')
105 | .css({
106 | 'background-opacity': 1
107 | })
108 | .selector('node[class="association"]')
109 | .css({
110 | 'background-color': '#6B6B6B'
111 | })
112 |
113 | // source and sink and dissociation are drawn differently because
114 | // of their unique shape
115 | .selector('node[class="source and sink"]')
116 | .css({
117 | 'background-image': (node) => sbgnsvg.draw(node),
118 | 'background-fit': 'none',
119 | 'background-width': '100%',
120 | 'background-height': '100%',
121 | 'background-clip': 'none',
122 | 'background-repeat': 'no-repeat',
123 | 'border-width': 0,
124 | 'shape-polygon-points': '-0.86, 0.5, -0.75, 0.65, -1, 0.95, -0.95, 1, -0.65, 0.75, -0.5, 0.86, 0, 1, 0.5, 0.86, 0.71, 0.71, 0.86, 0.5, 1, 0, 0.86, -0.5, 0.75, -0.65, 1, -0.95, 0.95, -1, 0.65, -0.75, 0.5, -0.86, 0, -1, -0.5, -0.86, -0.71, -0.71, -0.86, -0.5, -1, 0',
125 | })
126 |
127 | // source and sink and dissociation are drawn differently because
128 | // of their unique shape
129 | .selector('node[class="dissociation"]')
130 | .css({
131 | 'background-image': (node) => sbgnsvg.draw(node),
132 | 'background-fit': 'none',
133 | 'background-width': '100%',
134 | 'background-height': '100%',
135 | 'background-clip': 'none',
136 | 'background-repeat': 'no-repeat',
137 | 'border-width': 0,
138 | })
139 |
140 | // edge styling
141 | .selector('edge')
142 | .css({
143 | 'arrow-scale': 1.75,
144 | 'curve-style': 'bezier',
145 | 'line-color': '#555',
146 | 'target-arrow-fill': 'hollow',
147 | 'source-arrow-fill': 'hollow',
148 | 'width': 1.5,
149 | 'target-arrow-color': '#555',
150 | 'source-arrow-color': '#555',
151 | 'text-border-color': '#555',
152 | 'color': '#555'
153 | })
154 | .selector('edge:selected')
155 | .css({
156 | 'color': '#d67614',
157 | 'line-color': '#d67614',
158 | 'text-border-color': '#d67614',
159 | 'source-arrow-color': '#d67614',
160 | 'target-arrow-color': '#d67614'
161 | })
162 | .selector('edge:active')
163 | .css({
164 | 'background-opacity': 0.7, 'overlay-color': '#d67614',
165 | 'overlay-padding': '8'
166 | })
167 | .selector('edge[cardinality > 0]')
168 | .css({
169 | 'text-background-shape': 'rectangle',
170 | 'text-border-opacity': '1',
171 | 'text-border-width': '1',
172 | 'text-background-color': 'white',
173 | 'text-background-opacity': '1'
174 | })
175 | .selector('edge[class="consumption"][cardinality > 0], edge[class="production"][cardinality > 0]')
176 | .css({
177 | 'source-label': (edge) => '' + edge.data('cardinality'),
178 | 'source-text-offset': 10
179 | })
180 | .selector('edge[class]')
181 | .css({
182 | 'target-arrow-shape': (edge) => elementStyle.sbgnArrowShape(edge),
183 | 'source-arrow-shape': 'none'
184 | })
185 | .selector('edge[class="inhibition"]')
186 | .css({
187 | 'target-arrow-fill': 'filled'
188 | })
189 | .selector('edge[class="production"]')
190 | .css({
191 | 'target-arrow-fill': 'filled'
192 | })
193 |
194 |
195 | // core
196 | .selector('core')
197 | .css({
198 | 'selection-box-color': '#d67614',
199 | 'selection-box-opacity': '0.2', 'selection-box-border-color': '#d67614'
200 | });
201 | };
202 |
203 | module.exports = sbgnStyleSheet;
204 |
--------------------------------------------------------------------------------
/src/sbgnStyle/util/sbgn.js:
--------------------------------------------------------------------------------
1 | const sbgnDataHandler = {
2 | isMultimer (node) {
3 | return node.data('class').includes('multimer');
4 | },
5 | hasClonemarker (node) {
6 | return node.data('clonemarker');
7 | },
8 | getStateVars (node) {
9 | return node.data('stateVariables');
10 | },
11 | getUnitInfos (node) {
12 | return node.data('unitsOfInformation');
13 | },
14 | hasAuxItems (node) {
15 | return (node.data('stateVariables').length + node.data('unitsOfInformation').length > 0);
16 | },
17 | sbgnClass (element) {
18 | return element.data('class');
19 | },
20 | sbgnLabel (element) {
21 | return element.data('label');
22 | },
23 | stateVarLabel (stateVar) {
24 | const variable = stateVar.state.variable;
25 | const value = stateVar.state.value;
26 | if (value && variable) {
27 | return `${value}@${variable}`;
28 | }
29 | if (value) {
30 | return value;
31 | }
32 |
33 | if (variable) {
34 | return variable;
35 | }
36 | return '';
37 | }
38 | };
39 |
40 | module.exports = sbgnDataHandler;
41 |
--------------------------------------------------------------------------------
/src/sbgnStyle/util/svg.js:
--------------------------------------------------------------------------------
1 | const styleMap2Str = (styleMap) => {
2 | if( !styleMap ){
3 | return '';
4 | }
5 |
6 | let s = '';
7 |
8 | for( let [k, v] of styleMap ){
9 | s += k + '=' + '"' + v + '"' + ' ';
10 | }
11 |
12 | return s;
13 | };
14 |
15 | const svg = (svgStr, width = 100, height = 100) => {
16 | const parser = new DOMParser();
17 | let svgText =
18 | ``;
19 | return parser.parseFromString(svgText, 'text/xml').documentElement;
20 | };
21 |
22 | const svgStr = (svgText, viewPortWidth, viewPortHeight, viewBoxX, viewBoxY, viewBoxWidth, viewBoxHeight) => {
23 | let s = svg(svgText, viewPortWidth, viewPortHeight, viewBoxX, viewBoxY, viewBoxWidth, viewBoxHeight);
24 |
25 | // base64
26 | // let data = 'data:image/svg+xml;base64,' + btoa(s.outerHTML);
27 |
28 | // uri component string
29 | let data = 'data:image/svg+xml;utf8,' + encodeURIComponent(s.outerHTML);
30 |
31 | return data;
32 | };
33 |
34 | module.exports = {
35 | svgStr: svgStr,
36 | styleMap2Str: styleMap2Str
37 | };
38 |
--------------------------------------------------------------------------------
/test/shapeTest.js:
--------------------------------------------------------------------------------
1 | /* global describe, it */
2 |
3 | const expect = require('chai').expect;
4 |
5 | const svgUtil = require('../src/sbgnStyle/util/svg.js');
6 | const s = require('../src/sbgnStyle/glyph/baseShapes.js');
7 |
8 | const sbgnShapes = require('../src/sbgnStyle/glyph/');
9 |
10 | const browser = !(typeof window === 'undefined');
11 |
12 | describe('shape style', () => {
13 | it('should convert style maps to a svg style string', () => {
14 | const styleMap = new Map()
15 | .set('stroke-width', '3')
16 | .set('fill', 'none')
17 | .set('stroke', '#6A6A6A');
18 |
19 | const styleString = `stroke-width="3" fill="none" stroke="#6A6A6A" `;
20 | expect(svgUtil.styleMap2Str(styleMap)).to.equal(styleString);
21 | });
22 | it('should produce an empty string for an empty map', () => {
23 | const styleMap = new Map();
24 |
25 | const styleString = '';
26 |
27 | expect(svgUtil.styleMap2Str(styleMap)).to.equal(styleString);
28 | });
29 | });
30 |
31 | describe('shape svg', function () {
32 | it('(browser only) should produce valid svg when parsed', function () {
33 |
34 | if (browser) {
35 |
36 | const validSvg = (svg) => {
37 | const parser = new DOMParser();
38 | let doc = parser.parseFromString(svg, 'text/xml');
39 | let parseError = doc.getElementsByTagName('parsererror');
40 | return parseError.length === 0;
41 | };
42 |
43 | const styleMap = new Map()
44 | .set('stroke-width', '3')
45 | .set('fill', 'none')
46 | .set('stroke', '#6A6A6A');
47 |
48 | const x = 0;
49 | const y = 0;
50 | const w = 100;
51 | const h = 100;
52 |
53 | expect(validSvg(s.rectangle(x, y, w, h, styleMap))).to.equal(true);
54 | expect(validSvg(s.roundBottomRectangle(x, y, w, h, styleMap))).to.equal(true);
55 | expect(validSvg(s.roundRectangle(x, y, w, h, styleMap))).to.equal(true);
56 | expect(validSvg(s.square(x, y, w, styleMap))).to.equal(true);
57 | expect(validSvg(s.barrel(x, y, w, h, styleMap))).to.equal(true);
58 | expect(validSvg(s.circle(x, y, w, styleMap))).to.equal(true);
59 | expect(validSvg(s.concaveHexagon(x, y, w, h, styleMap))).to.equal(true);
60 | expect(validSvg(s.cutRectangle(x, y, w, h, 10, styleMap))).to.equal(true);
61 | expect(validSvg(s.ellipse(x, y, w, h, styleMap))).to.equal(true);
62 | expect(validSvg(s.hexagon(x, y, w, h, styleMap))).to.equal(true);
63 | expect(validSvg(s.line(x, y, w, h, styleMap))).to.equal(true);
64 | expect(validSvg(s.text('blah', x, y, styleMap))).to.equal(true);
65 | } else {
66 | this.skip();
67 | }
68 | });
69 | });
70 |
71 | describe('sbgn shape svg', function () {
72 | it('should throw an error when a incorrect node class is specified', function () {
73 | let dummyNode = {
74 | data() {
75 | return 'not a sbgn class';
76 | }
77 | };
78 | expect(sbgnShapes.draw.bind(dummyNode)).to.throw(TypeError);
79 | });
80 | });
81 |
--------------------------------------------------------------------------------
/test/test.js:
--------------------------------------------------------------------------------
1 | /* global describe, it */
2 | const expect = require('chai').expect;
3 |
4 | describe('dummy test', () => {
5 | it('should run and not crash and not fail', () => {
6 | const a = 1;
7 |
8 | expect(a + a).to.equal(2);
9 | });
10 | });
--------------------------------------------------------------------------------
/test/testenv/tests.html:
--------------------------------------------------------------------------------
1 | Mocha Tests
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
14 |
--------------------------------------------------------------------------------
/webpack.config.js:
--------------------------------------------------------------------------------
1 | const webpack = require('webpack');
2 | const { env } = require('process');
3 | const isProd = env.NODE_ENV === 'production';
4 | const UglifyJSPlugin = require('uglifyjs-webpack-plugin');
5 | const isNonNil = x => x != null;
6 | const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
7 | const isProfile = env.PROFILE == 'true';
8 | const minify = env.MINIFY == 'true';
9 | const package = require('./package.json');
10 | const camelcase = require('camelcase');
11 |
12 | let conf = {
13 | entry: './src/index.js',
14 |
15 | devtool: isProd ? false : 'inline-source-map',
16 |
17 | output: {
18 | filename: './build/bundle.js',
19 | library: camelcase( package.name ),
20 | libraryTarget: 'umd'
21 | },
22 |
23 | externals: isProd ? Object.keys( package.dependencies || {} ) : [],
24 |
25 | module: {
26 | rules: [
27 | { test: /\.js$/, exclude: /node_modules/, loader: 'babel-loader' }
28 | ]
29 | },
30 |
31 | plugins: [
32 | new webpack.EnvironmentPlugin(['NODE_ENV']),
33 |
34 | minify ? new UglifyJSPlugin() : null
35 | ].filter( isNonNil )
36 | };
37 |
38 | module.exports = conf;
39 |
--------------------------------------------------------------------------------