diff --git a/.gitignore b/.gitignore index d9a5e809..b56f5ddd 100644 --- a/.gitignore +++ b/.gitignore @@ -16,3 +16,4 @@ npm-debug.log # temporary files .*.sw[op] .commits.tmp +gen/ diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 00000000..d64a0332 --- /dev/null +++ b/docs/README.md @@ -0,0 +1,231 @@ +# Command line usage example + +``` +jsdoc -c jsdoc.json -r -t docs -d gen/docs lib +``` + +- `-c`: use this config file for `jsdoc` +- `-r`: Recurse into subdirectories of the specified source directories +- `-t`: Use template in path `docs` +- `-d`: Generated html files put in `gen/docs` +- Source files to parse are taken from directory `lib` + + +## Notes + +The template generation is set up so that: + + - Files ending in `.tmpl` are skipped + - All non-html files are plain copied + - html-files *can* contain `` tags, but this is not required + + +## Intention + +The `docs` directory is treated as a `jsdoc` template, in which the html-files are the template files. This allows for a gradual adaptation of the html-files to templates; unchanged html-files will pass through `jsdoc` unchanged. + +The added value of using `jsdoc` for documentation generation, is that the complete documentation information, as collected by `jsdoc` from the source, is available for usage. This way, it's possible to insert technical notes from the source code into the documentation. + +---- + +# Usage of and Notes on Source Code + +This section contains notes on the usage of `jsdoc` functionality, to aid with the handling of its generated data. + + +## Parameters of `publish()` + +### Parameter `taffyData` + + A table containing *all* data collected from the source code, related to jsdoc generation. See below for more info and example outputs. + +### Parameter `opt` + +Example of `opt` variable: + +```js +{ + "_":["../github/vis/lib/network/"], + "configure":"jsdoc.json", + "recurse":true, + "template":"/home/wim/projects/jsdoc/default", + "destination":"./out/", + "encoding":"utf8" +} +``` + +### Parameter `tutorial` + +This does not appear to be of use for the generation of `vis.js` documentation. + +Example of `tutorial` variable: + +```js +{ + "longname":"", + "name":"", + "title":"", + "content":"", + "parent":null, + "children":[], + "_tutorials":{} +} +``` + +## Global variable `env` + +This contains addition info for the current execution of `jsdoc`. Example of `env` variable: + +```js +{ + "run":{"start":"2017-09-16T05:06:45.621Z","finish":null}, + "args":["-c","jsdoc.json","-r","-t","default","../github/vis/lib/network/"], + "conf":{ + "plugins":["/usr/lib/node_modules/jsdoc/plugins/markdown.js"], + "recurseDepth":10, + "source":{"includePattern":".+\\.js(doc|x)?$","excludePattern":""}, + "sourceType":"module", + "tags":{"allowUnknownTags":true,"dictionaries":["jsdoc","closure"]}, + "templates":{"monospaceLinks":false,"cleverLinks":false} + }, + "dirname":"/usr/lib/node_modules/jsdoc", + "pwd":"/home/wim/projects/jsdoc", + "opts":{ <> }, + "sourceFiles":[ <> ], + "version":{"number":"3.5.4","revision":"Fri, 04 Aug 2017 22:05:27 GMT"} +} +``` + + +## taffyData + +This is a parameter to `publish()`. It's a table containing *all* data collected from the source code, related to jsdoc generation. + +I can't find any way to return a list of fields for the data items in the taffyDB docs, therefore below there are examples of items, for better understanding of usage. + +Example usage: + +```js + var data = taffyData; + var tmp = data().filter({name:'Label'}).get(); +``` + +Returns an array with all items with `name === 'Label'`. Example output of one of these items, for a class: + +*In these examples, block comment endings are redacted to ' * /'* + +```js +{ + "comment":"/**\n * A Label to be used for Nodes or Edges.\n * /", + "meta":{ + "range":[3770,41303], + "filename":"Label.js", + "lineno":167, + "columnno":0, + "path":"/home/wim/projects/github/vis/lib/network/modules/components/shared", + "code":{ + "id":"astnode100065034", + "name":"Label", + "type":"ClassDeclaration", + "paramnames":["body","options","edgelabel"] + } + }, + "classdesc":" +A Label to be used for Nodes or Edges. + +", + "name":"Label", + "longname":"Label", + "kind":"class", + "scope":"global", + "params":[ + {"type":{"names":["Object"]},"name":"body"}, + {"type":{"names":["Object"]},"name":"options"}, + {"type":{"names":["boolean"]},"optional":true,"defaultvalue":false,"name":"edgelabel"} + ], + "___id":"T000002R005289", + "___s":true +} +``` + +Example of item for an instance method: + +```js + var tmp = data().filter({name:'_drawText'}).get(); +``` + +Full output returned: + +```js +[{ + "comment":"/**\n *\n * @param {CanvasRenderingContext2D} ctx\n * @param {boolean} selected\n * @param {boolean} hover\n * @param {number} x\n * @param {number} y\n * @param {string} [baseline='middle']\n * @private\n * /", + "meta":{ + "range":[20060,22269], + "filename":"Label.js", + "lineno":652, + "columnno":2, + "path":"/home/wim/projects/github/vis/lib/network/modules/components/shared", + "code":{ + "id":"astnode100066427", + "name":"Label#_drawText", + "type":"MethodDefinition", + "paramnames":["ctx","selected","hover","x","y","baseline"] + }, + "vars":{"":null} + }, + "params":[ + {"type":{"names":["CanvasRenderingContext2D"]},"name":"ctx"}, + {"type":{"names":["boolean"]},"name":"selected"}, + {"type":{"names":["boolean"]},"name":"hover"}, + {"type":{"names":["number"]},"name":"x"}, + {"type":{"names":["number"]},"name":"y"}, + {"type":{"names":["string"]},"optional":true,"defaultvalue":"'middle'","name":"baseline"} + ], + "access":"private", + "name":"_drawText", + "longname":"Label#_drawText", + "kind":"function", + "memberof":"Label", + "scope":"instance", + "___id":"T000002R005388", + "___s":true +}] +``` + +## `jsdoc` template rendering + +See `function createRenderer(fromDir, data)` in code for usage. + +There are two calls for rendering templates: + + - `var html = renderer.render(inFile, docData);` + - `var html = renderer.partial(inFile, docData);` + +The difference is that `render()` will use a default layout template, if present, which will encapsulate all html. This can be set by: + +```js + renderer.layout = 'path/to/default/layout.tmpl'; +``` + +Parameter `docData` is a hash which is used to pass parameters into a template. The standard way of using this appear to be: + +``` + +``` + +But it also appear to be possible to use the elements of docData directly: + +```js +var docData = { + myTitle: 'Hello, pussycat!' +}; +``` + +Within the template: + +``` + +``` diff --git a/docs/data/dataset.html b/docs/data/dataset.html index 4c8a958c..b78fb2fe 100644 --- a/docs/data/dataset.html +++ b/docs/data/dataset.html @@ -1,86 +1,11 @@ - - - - - - - - - DataSet - vis.js - A dynamic, browser based visualization library. - - - - - - - - - - - - - - - - - - - - - + + - - - - +

DataSet

diff --git a/docs/network/index.html b/docs/network/index.html index 2ade8795..23ce1cfb 100644 --- a/docs/network/index.html +++ b/docs/network/index.html @@ -1,3 +1,6 @@ + @@ -609,6 +612,21 @@ var locales = { The options object is explained in full below. + + + + + This comes from the source! + + + Returns: + + + + + findNode( String/Number nodeId) @@ -1487,7 +1505,7 @@ Thus, to get the topmost item, get the value at index 0. stabilized Object - Fired when the network has stabilized or when the stopSimulation() has been called. The amount of iterations it took could be used to tweak the maximum amount of iterations needed to stabilize the network. Passes an object with properties structured as: + Fired when the network has stabilized, when the amount of iterations defined in the options has been reached, or when the stopSimulation() has been called. The amount of iterations it took could be used to tweak the maximum amount of iterations needed to stabilize the network. Passes an object with properties structured as:
{
   iterations: Number // iterations it took
 }
diff --git a/docs/publish.js b/docs/publish.js new file mode 100644 index 00000000..f500e366 --- /dev/null +++ b/docs/publish.js @@ -0,0 +1,118 @@ +/*============================================================================== + Demo template, showing how documentation can be generated for `vis.js`. + + ------------------------------------------------------------------------------ + ## Notes on `jsdoc` code + + // claim some special filenames in advance, so the All-Powerful Overseer of Filename Uniqueness + // doesn't try to hand them out later + indexUrl = helper.getUniqueFilename('index'); + // don't call registerLink() on this one! 'index' is also a valid longname + + globalUrl = helper.getUniqueFilename('global'); + helper.registerLink('global', globalUrl); + + ============================================================================== */ +'use strict'; +//var taffy = require('taffydb').taffy; // not really required here, left for reference + +// Internal modules of `jsdoc` are available here. +// This is not the complete list, there may be more useful stuff in jsdoc +// For all modules scan in: '/usr/lib/node_modules/jsdoc/lib/jsdoc/' (or similar on your system) +var fs = require('jsdoc/fs'); +var path = require('jsdoc/path'); +var template = require('jsdoc/template'); + + +/** + * Set up the template rendering engine. + */ +function createRenderer(fromDir, data) { + var renderer = new template.Template(fromDir); // Param is the template source directory. + // All template files are relative to this directory! + /** + * Example helper method + * + * This can be called from within a template as follows: + * + * ``` + * + * ... + * + * ``` + * + * / + renderer.helper = function(val) { + return 'this is a helper! ' + val; + }; + */ + + /** + * Retrieves jsdoc info for the passed instance method. + */ + renderer.getComment = function(methodName) { + var tmp = data().filter({longname: methodName}).get()[0]; + //console.log(JSON.stringify(tmp)); + + // Some restructuring, to adapt it to the docs layout + // This needs some work to make it handle 0 and > 1 parameters + var param = tmp.params[0]; + var prototype = tmp.name + '(' + param.type.names.join('|') + ' ' + param.name + ')'; + var returns = tmp.returns[0].type.names; + + return { + prototype: prototype, + returns: returns, + description: tmp.description + } + }; + + return renderer; +} + + +/** + Entry point for the template. + + This is called from `jsdoc` during execution + + @param {TAFFY} taffyData See . + @param {object} opts + @param {Tutorial} tutorials + */ +exports.publish = function(taffyData, opts, tutorials) { + //console.log(JSON.stringify(opts, null, 2)); + + var fromDir = path.resolve(opts.template); + var toDir = path.join(opts.destination); + var renderer = createRenderer(fromDir, taffyData); + + var docFiles = fs.ls(fromDir, 3); + docFiles.forEach(function(fileName) { + // Template filenames need to be relative to template source dir + var relName = path.relative(fromDir, fileName); + var outFile = path.join(toDir, relName); + + if (/publish.js$/.test(fileName)) return; // Skip self + if (/README.md$/.test(fileName)) return; // Skip own README + if (/\.tmpl$/.test(fileName)) return; // Skip .tmpl files; these are used as partials only + + if (!/\.html$/.test(fileName)) { + // Just plain copy over non-html files + var tmpDir = fs.toDir(outFile); + fs.mkPath(tmpDir); + fs.copyFileSync(fileName, tmpDir); + return; + } + + // Render html files as templates + //console.log(relName); + var html = renderer.partial(relName, {}); + fs.mkPath(fs.toDir(outFile)); + fs.writeFileSync(outFile, html, 'utf8'); + }); + + //console.log(JSON.stringify(env, null, 2)); +}; diff --git a/docs/timeline/index.html b/docs/timeline/index.html index 0b6f46c0..03e53cfe 100644 --- a/docs/timeline/index.html +++ b/docs/timeline/index.html @@ -773,6 +773,13 @@ function (option, path) { If true, range of all items in the Timeline is draggable without being selected. If false, range is only draggable for the selected item(s). Only applicable when option itemsAlwaysDraggable.item is set true. + + loadingScreenTemplate + function + none + A template function used to generate the timeline initial loading screen. See section Templates for a detailed explanation. + + locale String diff --git a/docs/tmpl/html-head.tmpl b/docs/tmpl/html-head.tmpl new file mode 100644 index 00000000..7fd3adb8 --- /dev/null +++ b/docs/tmpl/html-head.tmpl @@ -0,0 +1,40 @@ + + + + + + + + + + <?js= title ?> + + + + + + + + + + + + + + + + + + + + + +' purposely missing here, so that more stuff can be added to header */ ?> \ No newline at end of file diff --git a/docs/tmpl/navbar.tmpl b/docs/tmpl/navbar.tmpl new file mode 100644 index 00000000..b1f8da08 --- /dev/null +++ b/docs/tmpl/navbar.tmpl @@ -0,0 +1,49 @@ + + + + \ No newline at end of file diff --git a/examples/network/nodeStyles/shapes.html b/examples/network/nodeStyles/shapes.html index d60901f6..bf1a5c85 100644 --- a/examples/network/nodeStyles/shapes.html +++ b/examples/network/nodeStyles/shapes.html @@ -32,6 +32,7 @@ {id: 9, label: 'triangleDown', shape: 'triangleDown'}, {id: 10, label: 'text', shape: 'text'}, {id: 11, label: 'star', shape: 'star'}, + {id: 12, label: 'hexagon', shape: 'hexagon'}, {id: 21, font:{size:30}, label: 'big circle', shape: 'circle' }, {id: 22, font:{size:30}, label: 'big ellipse', shape: 'ellipse'}, {id: 23, font:{size:30}, label: 'ellipse with a long label text', shape: 'ellipse'}, @@ -43,7 +44,8 @@ {id: 29, font:{size:30}, size:40, label: 'big triangle',shape: 'triangle'}, {id: 30, font:{size:30}, size:40, label: 'big triangleDown', shape: 'triangleDown'}, {id: 31, font:{size:30}, label: 'big text', shape: 'text'}, - {id: 32, font:{size:30}, size:40, label: 'big star', shape: 'star'} + {id: 32, font:{size:30}, size:40, label: 'big star', shape: 'star'}, + {id: 33, font:{size:30}, size:40, label: 'big hexagon', shape: 'hexagon'}, ]; edges = [ diff --git a/examples/network/nodeStyles/shapesWithDashedBorders.html b/examples/network/nodeStyles/shapesWithDashedBorders.html index a129782e..b0eb2de0 100644 --- a/examples/network/nodeStyles/shapesWithDashedBorders.html +++ b/examples/network/nodeStyles/shapesWithDashedBorders.html @@ -32,6 +32,7 @@ {id: 9, font:{size:30}, size:40, label: 'triangleDown', shape: 'triangleDown', shapeProperties:{borderDashes:[5,5]}}, {id: 10, font:{size:30}, size:40, label: 'star', shape: 'star', shapeProperties:{borderDashes:true}}, {id: 11, font:{size:30}, size:40, label: 'circularImage', shape: 'circularImage', image: '../img/indonesia/4.png', shapeProperties: {borderDashes:[15,5]}}, + {id: 12, font:{size:30}, size:40, label: 'hexagon', shape: 'hexagon', shapeProperties:{borderDashes:[5,5]}}, ]; edges = [ diff --git a/examples/timeline/other/loadingScreen.html b/examples/timeline/other/loadingScreen.html new file mode 100644 index 00000000..80ca4aa8 --- /dev/null +++ b/examples/timeline/other/loadingScreen.html @@ -0,0 +1,58 @@ + + + + + Timeline | Loading screen example + + + + + + +

Timeline with loading screen

+
+ + + + + \ No newline at end of file diff --git a/examples/timeline/other/stressPerformance.html b/examples/timeline/other/stressPerformance.html index 94906e06..d26f4117 100644 --- a/examples/timeline/other/stressPerformance.html +++ b/examples/timeline/other/stressPerformance.html @@ -49,18 +49,9 @@ // create visualization var container = document.getElementById('visualization'); - var options = { - width: '100%', - showCurrentTime: false, - stack: true, - selectable: true, - editable: true, - }; + var options = {}; - var timeline = new vis.Timeline(container); - timeline.setOptions(options); - timeline.setGroups(groups); - timeline.setItems(items); + var timeline = new vis.Timeline(container, items, groups, options); \ No newline at end of file diff --git a/examples/timeline/styling/weekStyling.html b/examples/timeline/styling/weekStyling.html index 9a3a919e..53663ac0 100644 --- a/examples/timeline/styling/weekStyling.html +++ b/examples/timeline/styling/weekStyling.html @@ -26,7 +26,21 @@ of moment.js including locales.

To set a locale for the timeline, specify the option {locale: STRING}.

-

To set the scale to use week numbers, use for example {scale: 'week', step: 1}.

+

+ To set the scale to use week numbers, use the following options: + + { + timeAxis: { + scale: 'week', + step: 1 + }, + format: { + minorLabels: {week: 'w'} + } + } + +

+

The following timeline is initialized with the 'de' locale and items are added with locally localized moment.js objects. The timeline locale can be switched to another locale at runtime. If you choose the 'en' locale, the week numbers will be calculated according to the US week calendar numbering scheme.

@@ -93,7 +107,16 @@ } // Configuration for the Timeline - var options = {timeAxis: {scale: 'week', step: 1}, locale: 'de'}; + var options = { + locale: 'de', + timeAxis: { + scale: 'week', + step: 1 + }, + format: { + minorLabels: {week: 'w'} + } + }; // Create a Timeline var timeline = new vis.Timeline(container, items, groups, options); @@ -108,4 +131,4 @@ select.onchange(); - \ No newline at end of file + diff --git a/gulpfile.js b/gulpfile.js index 5e87f423..4076d81c 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -10,6 +10,7 @@ var webpack = require('webpack'); var uglify = require('uglify-js'); var rimraf = require('rimraf'); var argv = require('yargs').argv; +var child_exec = require('child_process').exec; var ENTRY = './index.js'; var HEADER = './lib/header.js'; @@ -29,7 +30,12 @@ var INDIVIDUAL_CSS_BUNDLES = [ {entry: ['./lib/shared/**/*.css', './lib/network/**/*.css'], filename: 'vis-network.min.css'} ]; -// generate banner with today's date and correct version + +/** + * Generate banner with today's date and correct version + * + * @returns {string} banner text + */ function createBanner() { var today = gutil.date(new Date(), 'yyyy-mm-dd'); // today, formatted as yyyy-mm-dd var version = require('./package.json').version; @@ -39,6 +45,7 @@ function createBanner() { .replace('@@version', version); } + var bannerPlugin = new webpack.BannerPlugin({ banner: createBanner(), entryOnly: true, @@ -92,6 +99,12 @@ var uglifyConfig = { // create a single instance of the compiler to allow caching var compiler = webpack(webpackConfig); +/** + * Callback for handling errors for a compiler run + * + * @param {object} err + * @param {objects} stats + */ function handleCompilerCallback (err, stats) { if (err) { gutil.log(err.toString()); @@ -232,5 +245,27 @@ gulp.task('lint', function () { }); +// Generate the documentation files +gulp.task('docs', function(cb) { + var targetDir = 'gen/docs'; + + // Not sure if this is the best way to handle 'cb'; at least it works. + var hasError = false; + var onError = function(error) { + if (error !== undefined && error !== null) { + console.error('Error while running task: ' + error); + hasError = true; + cb(); + } + } + + rimraf(__dirname + '/' + targetDir, onError); // Clean up previous generation + + if (!hasError) { + var params = '-c ./jsdoc.json -r -t docs -d ' + targetDir; + child_exec('node ./node_modules/jsdoc/jsdoc.js ' + params + ' lib', undefined, cb); + } +}); + // The default task (called when you run `gulp`) gulp.task('default', ['clean', 'bundle', 'minify']); diff --git a/jsdoc.json b/jsdoc.json new file mode 100644 index 00000000..df0756c6 --- /dev/null +++ b/jsdoc.json @@ -0,0 +1,3 @@ +{ + "plugins": ["plugins/markdown"] +} diff --git a/lib/network/Network.js b/lib/network/Network.js index 486a8a21..b45baf0a 100644 --- a/lib/network/Network.js +++ b/lib/network/Network.js @@ -470,7 +470,27 @@ Network.prototype.isActive = function () { Network.prototype.setSize = function() {return this.canvas.setSize.apply(this.canvas,arguments);}; Network.prototype.canvasToDOM = function() {return this.canvas.canvasToDOM.apply(this.canvas,arguments);}; Network.prototype.DOMtoCanvas = function() {return this.canvas.DOMtoCanvas.apply(this.canvas,arguments);}; + + +/** + * Nodes can be in clusters. Clusters can also be in clusters. This function returns and array of + * nodeIds showing where the node is. + * + * If any nodeId in the chain, especially the first passed in as a parameter, is not present in + * the current nodes list, an empty array is returned. + * + * Example: + * cluster 'A' contains cluster 'B', + * cluster 'B' contains cluster 'C', + * cluster 'C' contains node 'fred'. + * `jsnetwork.clustering.findNode('fred')` will return `['A','B','C','fred']`. + * + * @param {string|number} nodeId + * @returns {Array} + */ Network.prototype.findNode = function() {return this.clustering.findNode.apply(this.clustering,arguments);}; + + Network.prototype.isCluster = function() {return this.clustering.isCluster.apply(this.clustering,arguments);}; Network.prototype.openCluster = function() {return this.clustering.openCluster.apply(this.clustering,arguments);}; Network.prototype.cluster = function() {return this.clustering.cluster.apply(this.clustering,arguments);}; diff --git a/lib/network/modules/LayoutEngine.js b/lib/network/modules/LayoutEngine.js index ccee1a43..ad907ebd 100644 --- a/lib/network/modules/LayoutEngine.js +++ b/lib/network/modules/LayoutEngine.js @@ -1,4 +1,3 @@ -'use strict'; /** * There's a mix-up with terms in the code. Following are the formal definitions: * @@ -30,6 +29,8 @@ * The layout is a way to arrange the nodes in the view; this can be done * on non-hierarchical networks as well. The converse is also possible. */ +'use strict'; +var TimSort = require('timsort'); let util = require('../../util'); var NetworkUtil = require('../NetworkUtil').default; var {HorizontalStrategy, VerticalStrategy} = require('./components/DirectionStrategy.js'); @@ -1422,7 +1423,7 @@ class LayoutEngine { result.push(Number(size)); }); - result.sort(function(a, b) { + TimSort.sort(result, function(a, b) { return b - a; }); diff --git a/lib/network/modules/components/DirectionStrategy.js b/lib/network/modules/components/DirectionStrategy.js index b72e127e..ac3151ce 100644 --- a/lib/network/modules/components/DirectionStrategy.js +++ b/lib/network/modules/components/DirectionStrategy.js @@ -3,6 +3,7 @@ * * Strategy pattern for usage of direction methods for hierarchical layouts. */ +var TimSort = require('timsort'); /** @@ -87,6 +88,15 @@ class DirectionInterface { /** * Sort array of nodes on the unfixed coordinates. * + * **Note:** chrome has non-stable sorting implementation, which + * has a tendency to change the order of the array items, + * even if the custom sort function returns 0. + * + * For this reason, an external sort implementation is used, + * which has the added benefit of being faster than the standard + * platforms implementation. This has been verified on `node.js`, + * `firefox` and `chrome` (all linux). + * * @param {Array.} nodeArray array of nodes to sort */ sort(nodeArray) { this.fake_use(nodeArray); this.abstract(); } @@ -156,9 +166,7 @@ class VerticalStrategy extends DirectionInterface { /** @inheritdoc */ sort(nodeArray) { - nodeArray.sort(function(a, b) { - // Test on 'undefined' takes care of divergent behaviour in chrome - if (a.x === undefined || b.x === undefined) return 0; // THIS HAPPENS + TimSort.sort(nodeArray, function(a, b) { return a.x - b.x; }); } @@ -221,9 +229,7 @@ class HorizontalStrategy extends DirectionInterface { /** @inheritdoc */ sort(nodeArray) { - nodeArray.sort(function(a, b) { - // Test on 'undefined' takes care of divergent behaviour in chrome - if (a.y === undefined || b.y === undefined) return 0; // THIS HAPPENS + TimSort.sort(nodeArray, function(a, b) { return a.y - b.y; }); } diff --git a/lib/network/modules/components/Edge.js b/lib/network/modules/components/Edge.js index 653eb9f6..7cc0f8f2 100644 --- a/lib/network/modules/components/Edge.js +++ b/lib/network/modules/components/Edge.js @@ -241,7 +241,7 @@ class Edge { /** * - * @returns {{toArrow: boolean, toArrowScale: (allOptions.edges.arrows.to.scaleFactor|{number}|allOptions.edges.arrows.middle.scaleFactor|allOptions.edges.arrows.from.scaleFactor|Array|number), toArrowType: *, middleArrow: boolean, middleArrowScale: (number|allOptions.edges.arrows.middle.scaleFactor|{number}|Array), middleArrowType: (allOptions.edges.arrows.middle.type|{string}|string|*), fromArrow: boolean, fromArrowScale: (allOptions.edges.arrows.to.scaleFactor|{number}|allOptions.edges.arrows.middle.scaleFactor|allOptions.edges.arrows.from.scaleFactor|Array|number), fromArrowType: *, arrowStrikethrough: (*|boolean|allOptions.edges.arrowStrikethrough|{boolean}), color: undefined, inheritsColor: (string|string|string|allOptions.edges.color.inherit|{string, boolean}|Array|*), opacity: *, hidden: *, length: *, shadow: *, shadowColor: *, shadowSize: *, shadowX: *, shadowY: *, dashes: (*|boolean|Array|allOptions.edges.dashes|{boolean, array}), width: *}} + * @returns {ArrowOptions} */ getFormattingValues() { let toArrow = (this.options.arrows.to === true) || (this.options.arrows.to.enabled === true) @@ -545,7 +545,7 @@ class Edge { * * @param {CanvasRenderingContext2D} ctx * @param {Object} arrowData - * @param {{toArrow: boolean, toArrowScale: (allOptions.edges.arrows.to.scaleFactor|{number}|allOptions.edges.arrows.middle.scaleFactor|allOptions.edges.arrows.from.scaleFactor|Array|number), toArrowType: *, middleArrow: boolean, middleArrowScale: (number|allOptions.edges.arrows.middle.scaleFactor|{number}|Array), middleArrowType: (allOptions.edges.arrows.middle.type|{string}|string|*), fromArrow: boolean, fromArrowScale: (allOptions.edges.arrows.to.scaleFactor|{number}|allOptions.edges.arrows.middle.scaleFactor|allOptions.edges.arrows.from.scaleFactor|Array|number), fromArrowType: *, arrowStrikethrough: (*|boolean|allOptions.edges.arrowStrikethrough|{boolean}), color: undefined, inheritsColor: (string|string|string|allOptions.edges.color.inherit|{string, boolean}|Array|*), opacity: *, hidden: *, length: *, shadow: *, shadowColor: *, shadowSize: *, shadowX: *, shadowY: *, dashes: (*|boolean|Array|allOptions.edges.dashes|{boolean, array}), width: *}} values + * @param {ArrowOptions} values */ drawArrows(ctx, arrowData, values) { if (values.fromArrow) { diff --git a/lib/network/modules/components/edges/BezierEdgeDynamic.js b/lib/network/modules/components/edges/BezierEdgeDynamic.js index 02640e8d..4a330094 100644 --- a/lib/network/modules/components/edges/BezierEdgeDynamic.js +++ b/lib/network/modules/components/edges/BezierEdgeDynamic.js @@ -122,7 +122,7 @@ class BezierEdgeDynamic extends BezierEdgeBase { /** * Draw a line between two nodes * @param {CanvasRenderingContext2D} ctx - * @param {{toArrow: boolean, toArrowScale: (allOptions.edges.arrows.to.scaleFactor|{number}|allOptions.edges.arrows.middle.scaleFactor|allOptions.edges.arrows.from.scaleFactor|Array|number), toArrowType: *, middleArrow: boolean, middleArrowScale: (number|allOptions.edges.arrows.middle.scaleFactor|{number}|Array), middleArrowType: (allOptions.edges.arrows.middle.type|{string}|string|*), fromArrow: boolean, fromArrowScale: (allOptions.edges.arrows.to.scaleFactor|{number}|allOptions.edges.arrows.middle.scaleFactor|allOptions.edges.arrows.from.scaleFactor|Array|number), fromArrowType: *, arrowStrikethrough: (*|boolean|allOptions.edges.arrowStrikethrough|{boolean}), color: undefined, inheritsColor: (string|string|string|allOptions.edges.color.inherit|{string, boolean}|Array|*), opacity: *, hidden: *, length: *, shadow: *, shadowColor: *, shadowSize: *, shadowX: *, shadowY: *, dashes: (*|boolean|Array|allOptions.edges.dashes|{boolean, array}), width: *}} values + * @param {ArrowOptions} values * @param {Node} viaNode * @private */ diff --git a/lib/network/modules/components/edges/BezierEdgeStatic.js b/lib/network/modules/components/edges/BezierEdgeStatic.js index 39cb9939..4f219c11 100644 --- a/lib/network/modules/components/edges/BezierEdgeStatic.js +++ b/lib/network/modules/components/edges/BezierEdgeStatic.js @@ -19,7 +19,7 @@ class BezierEdgeStatic extends BezierEdgeBase { /** * Draw a line between two nodes * @param {CanvasRenderingContext2D} ctx - * @param {{toArrow: boolean, toArrowScale: (allOptions.edges.arrows.to.scaleFactor|{number}|allOptions.edges.arrows.middle.scaleFactor|allOptions.edges.arrows.from.scaleFactor|Array|number), toArrowType: *, middleArrow: boolean, middleArrowScale: (number|allOptions.edges.arrows.middle.scaleFactor|{number}|Array), middleArrowType: (allOptions.edges.arrows.middle.type|{string}|string|*), fromArrow: boolean, fromArrowScale: (allOptions.edges.arrows.to.scaleFactor|{number}|allOptions.edges.arrows.middle.scaleFactor|allOptions.edges.arrows.from.scaleFactor|Array|number), fromArrowType: *, arrowStrikethrough: (*|boolean|allOptions.edges.arrowStrikethrough|{boolean}), color: undefined, inheritsColor: (string|string|string|allOptions.edges.color.inherit|{string, boolean}|Array|*), opacity: *, hidden: *, length: *, shadow: *, shadowColor: *, shadowSize: *, shadowX: *, shadowY: *, dashes: (*|boolean|Array|allOptions.edges.dashes|{boolean, array}), width: *}} values + * @param {ArrowOptions} values * @param {Node} viaNode * @private */ diff --git a/lib/network/modules/components/edges/CubicBezierEdge.js b/lib/network/modules/components/edges/CubicBezierEdge.js index 1ac243f5..ee362128 100644 --- a/lib/network/modules/components/edges/CubicBezierEdge.js +++ b/lib/network/modules/components/edges/CubicBezierEdge.js @@ -19,7 +19,7 @@ class CubicBezierEdge extends CubicBezierEdgeBase { /** * Draw a line between two nodes * @param {CanvasRenderingContext2D} ctx - * @param {{toArrow: boolean, toArrowScale: (allOptions.edges.arrows.to.scaleFactor|{number}|allOptions.edges.arrows.middle.scaleFactor|allOptions.edges.arrows.from.scaleFactor|Array|number), toArrowType: *, middleArrow: boolean, middleArrowScale: (number|allOptions.edges.arrows.middle.scaleFactor|{number}|Array), middleArrowType: (allOptions.edges.arrows.middle.type|{string}|string|*), fromArrow: boolean, fromArrowScale: (allOptions.edges.arrows.to.scaleFactor|{number}|allOptions.edges.arrows.middle.scaleFactor|allOptions.edges.arrows.from.scaleFactor|Array|number), fromArrowType: *, arrowStrikethrough: (*|boolean|allOptions.edges.arrowStrikethrough|{boolean}), color: undefined, inheritsColor: (string|string|string|allOptions.edges.color.inherit|{string, boolean}|Array|*), opacity: *, hidden: *, length: *, shadow: *, shadowColor: *, shadowSize: *, shadowX: *, shadowY: *, dashes: (*|boolean|Array|allOptions.edges.dashes|{boolean, array}), width: *}} values + * @param {ArrowOptions} values * @param {Array.} viaNodes * @private */ diff --git a/lib/network/modules/components/edges/StraightEdge.js b/lib/network/modules/components/edges/StraightEdge.js index 073a08ef..42368b3d 100644 --- a/lib/network/modules/components/edges/StraightEdge.js +++ b/lib/network/modules/components/edges/StraightEdge.js @@ -18,7 +18,7 @@ class StraightEdge extends EdgeBase { /** * Draw a line between two nodes * @param {CanvasRenderingContext2D} ctx - * @param {{toArrow: boolean, toArrowScale: (allOptions.edges.arrows.to.scaleFactor|{number}|allOptions.edges.arrows.middle.scaleFactor|allOptions.edges.arrows.from.scaleFactor|Array|number), toArrowType: *, middleArrow: boolean, middleArrowScale: (number|allOptions.edges.arrows.middle.scaleFactor|{number}|Array), middleArrowType: (allOptions.edges.arrows.middle.type|{string}|string|*), fromArrow: boolean, fromArrowScale: (allOptions.edges.arrows.to.scaleFactor|{number}|allOptions.edges.arrows.middle.scaleFactor|allOptions.edges.arrows.from.scaleFactor|Array|number), fromArrowType: *, arrowStrikethrough: (*|boolean|allOptions.edges.arrowStrikethrough|{boolean}), color: undefined, inheritsColor: (string|string|string|allOptions.edges.color.inherit|{string, boolean}|Array|*), opacity: *, hidden: *, length: *, shadow: *, shadowColor: *, shadowSize: *, shadowX: *, shadowY: *, dashes: (*|boolean|Array|allOptions.edges.dashes|{boolean, array}), width: *}} values + * @param {ArrowOptions} values * @private */ _line(ctx, values) { @@ -100,4 +100,4 @@ class StraightEdge extends EdgeBase { } -export default StraightEdge; \ No newline at end of file +export default StraightEdge; diff --git a/lib/network/modules/components/edges/util/EdgeBase.js b/lib/network/modules/components/edges/util/EdgeBase.js index 59b1e67a..8987c740 100644 --- a/lib/network/modules/components/edges/util/EdgeBase.js +++ b/lib/network/modules/components/edges/util/EdgeBase.js @@ -322,7 +322,7 @@ class EdgeBase { /** * * @param {CanvasRenderingContext2D} ctx - * @param {{toArrow: boolean, toArrowScale: (allOptions.edges.arrows.to.scaleFactor|{number}|allOptions.edges.arrows.middle.scaleFactor|allOptions.edges.arrows.from.scaleFactor|Array|number), toArrowType: *, middleArrow: boolean, middleArrowScale: (number|allOptions.edges.arrows.middle.scaleFactor|{number}|Array), middleArrowType: (allOptions.edges.arrows.middle.type|{string}|string|*), fromArrow: boolean, fromArrowScale: (allOptions.edges.arrows.to.scaleFactor|{number}|allOptions.edges.arrows.middle.scaleFactor|allOptions.edges.arrows.from.scaleFactor|Array|number), fromArrowType: *, arrowStrikethrough: (*|boolean|allOptions.edges.arrowStrikethrough|{boolean}), color: undefined, inheritsColor: (string|string|string|allOptions.edges.color.inherit|{string, boolean}|Array|*), opacity: *, hidden: *, length: *, shadow: *, shadowColor: *, shadowSize: *, shadowX: *, shadowY: *, dashes: (*|boolean|Array|allOptions.edges.dashes|{boolean, array}), width: *}} values + * @param {ArrowOptions} values * @param {boolean} selected - Unused * @param {boolean} hover - Unused * @returns {string} @@ -544,7 +544,7 @@ class EdgeBase { /** * * @param {CanvasRenderingContext2D} ctx - * @param {{toArrow: boolean, toArrowScale: (allOptions.edges.arrows.to.scaleFactor|{number}|allOptions.edges.arrows.middle.scaleFactor|allOptions.edges.arrows.from.scaleFactor|Array|number), toArrowType: *, middleArrow: boolean, middleArrowScale: (number|allOptions.edges.arrows.middle.scaleFactor|{number}|Array), middleArrowType: (allOptions.edges.arrows.middle.type|{string}|string|*), fromArrow: boolean, fromArrowScale: (allOptions.edges.arrows.to.scaleFactor|{number}|allOptions.edges.arrows.middle.scaleFactor|allOptions.edges.arrows.from.scaleFactor|Array|number), fromArrowType: *, arrowStrikethrough: (*|boolean|allOptions.edges.arrowStrikethrough|{boolean}), color: undefined, inheritsColor: (string|string|string|allOptions.edges.color.inherit|{string, boolean}|Array|*), opacity: *, hidden: *, length: *, shadow: *, shadowColor: *, shadowSize: *, shadowX: *, shadowY: *, dashes: (*|boolean|Array|allOptions.edges.dashes|{boolean, array}), width: *}} values + * @param {ArrowOptions} values * @param {boolean} selected * @param {boolean} hover * @param {Object} arrowData @@ -568,7 +568,7 @@ class EdgeBase { /** * * @param {CanvasRenderingContext2D} ctx - * @param {{toArrow: boolean, toArrowScale: (allOptions.edges.arrows.to.scaleFactor|{number}|allOptions.edges.arrows.middle.scaleFactor|allOptions.edges.arrows.from.scaleFactor|Array|number), toArrowType: *, middleArrow: boolean, middleArrowScale: (number|allOptions.edges.arrows.middle.scaleFactor|{number}|Array), middleArrowType: (allOptions.edges.arrows.middle.type|{string}|string|*), fromArrow: boolean, fromArrowScale: (allOptions.edges.arrows.to.scaleFactor|{number}|allOptions.edges.arrows.middle.scaleFactor|allOptions.edges.arrows.from.scaleFactor|Array|number), fromArrowType: *, arrowStrikethrough: (*|boolean|allOptions.edges.arrowStrikethrough|{boolean}), color: undefined, inheritsColor: (string|string|string|allOptions.edges.color.inherit|{string, boolean}|Array|*), opacity: *, hidden: *, length: *, shadow: *, shadowColor: *, shadowSize: *, shadowX: *, shadowY: *, dashes: (*|boolean|Array|allOptions.edges.dashes|{boolean, array}), width: *}} values + * @param {ArrowOptions} values */ enableShadow(ctx, values) { if (values.shadow === true) { @@ -582,7 +582,7 @@ class EdgeBase { /** * * @param {CanvasRenderingContext2D} ctx - * @param {{toArrow: boolean, toArrowScale: (allOptions.edges.arrows.to.scaleFactor|{number}|allOptions.edges.arrows.middle.scaleFactor|allOptions.edges.arrows.from.scaleFactor|Array|number), toArrowType: *, middleArrow: boolean, middleArrowScale: (number|allOptions.edges.arrows.middle.scaleFactor|{number}|Array), middleArrowType: (allOptions.edges.arrows.middle.type|{string}|string|*), fromArrow: boolean, fromArrowScale: (allOptions.edges.arrows.to.scaleFactor|{number}|allOptions.edges.arrows.middle.scaleFactor|allOptions.edges.arrows.from.scaleFactor|Array|number), fromArrowType: *, arrowStrikethrough: (*|boolean|allOptions.edges.arrowStrikethrough|{boolean}), color: undefined, inheritsColor: (string|string|string|allOptions.edges.color.inherit|{string, boolean}|Array|*), opacity: *, hidden: *, length: *, shadow: *, shadowColor: *, shadowSize: *, shadowX: *, shadowY: *, dashes: (*|boolean|Array|allOptions.edges.dashes|{boolean, array}), width: *}} values + * @param {ArrowOptions} values */ disableShadow(ctx, values) { if (values.shadow === true) { diff --git a/lib/network/modules/components/edges/util/EndPoints.js b/lib/network/modules/components/edges/util/EndPoints.js index 291d4067..9a7261d5 100644 --- a/lib/network/modules/components/edges/util/EndPoints.js +++ b/lib/network/modules/components/edges/util/EndPoints.js @@ -25,28 +25,6 @@ * `edgeStyles/arrowTypes`. * ============================================================================= */ -// NOTE: When a typedef is isolated in a separate comment block, an actual description is generated for it, -// using the rest of the commenting in the code block. Usage of typedef in other comments then -// link to there. TIL. -// -// Also noteworthy, all typedef's set up in this manner are collected in a single, global page 'global.html'. -// In other words, it doesn't matter *where* the typedef's are defined in the code. -// -// -// TODO: add descriptive commenting to given typedef's - -/** - * @typedef {{type:string, point:Point, angle:number, length:number}} ArrowData - * - * Object containing instantiation data for a given endpoint. - */ - -/** - * @typedef {{x:number, y:number}} Point - * - * A point in view-coordinates. - */ - /** * Common methods for endpoints * diff --git a/lib/network/modules/components/nodes/shapes/Box.js b/lib/network/modules/components/nodes/shapes/Box.js index 981fc93d..40d4375c 100644 --- a/lib/network/modules/components/nodes/shapes/Box.js +++ b/lib/network/modules/components/nodes/shapes/Box.js @@ -41,7 +41,7 @@ class Box extends NodeBase { * @param {number} y height * @param {boolean} selected * @param {boolean} hover - * @param {{toArrow: boolean, toArrowScale: (allOptions.edges.arrows.to.scaleFactor|{number}|allOptions.edges.arrows.middle.scaleFactor|allOptions.edges.arrows.from.scaleFactor|Array|number), toArrowType: *, middleArrow: boolean, middleArrowScale: (number|allOptions.edges.arrows.middle.scaleFactor|{number}|Array), middleArrowType: (allOptions.edges.arrows.middle.type|{string}|string|*), fromArrow: boolean, fromArrowScale: (allOptions.edges.arrows.to.scaleFactor|{number}|allOptions.edges.arrows.middle.scaleFactor|allOptions.edges.arrows.from.scaleFactor|Array|number), fromArrowType: *, arrowStrikethrough: (*|boolean|allOptions.edges.arrowStrikethrough|{boolean}), color: undefined, inheritsColor: (string|string|string|allOptions.edges.color.inherit|{string, boolean}|Array|*), opacity: *, hidden: *, length: *, shadow: *, shadowColor: *, shadowSize: *, shadowX: *, shadowY: *, dashes: (*|boolean|Array|allOptions.edges.dashes|{boolean, array}), width: *}} values + * @param {ArrowOptions} values */ draw(ctx, x, y, selected, hover, values) { this.resize(ctx, selected, hover); diff --git a/lib/network/modules/components/nodes/shapes/Circle.js b/lib/network/modules/components/nodes/shapes/Circle.js index 07c02174..643b57e4 100644 --- a/lib/network/modules/components/nodes/shapes/Circle.js +++ b/lib/network/modules/components/nodes/shapes/Circle.js @@ -45,7 +45,7 @@ class Circle extends CircleImageBase { * @param {number} y height * @param {boolean} selected * @param {boolean} hover - * @param {{toArrow: boolean, toArrowScale: (allOptions.edges.arrows.to.scaleFactor|{number}|allOptions.edges.arrows.middle.scaleFactor|allOptions.edges.arrows.from.scaleFactor|Array|number), toArrowType: *, middleArrow: boolean, middleArrowScale: (number|allOptions.edges.arrows.middle.scaleFactor|{number}|Array), middleArrowType: (allOptions.edges.arrows.middle.type|{string}|string|*), fromArrow: boolean, fromArrowScale: (allOptions.edges.arrows.to.scaleFactor|{number}|allOptions.edges.arrows.middle.scaleFactor|allOptions.edges.arrows.from.scaleFactor|Array|number), fromArrowType: *, arrowStrikethrough: (*|boolean|allOptions.edges.arrowStrikethrough|{boolean}), color: undefined, inheritsColor: (string|string|string|allOptions.edges.color.inherit|{string, boolean}|Array|*), opacity: *, hidden: *, length: *, shadow: *, shadowColor: *, shadowSize: *, shadowX: *, shadowY: *, dashes: (*|boolean|Array|allOptions.edges.dashes|{boolean, array}), width: *}} values + * @param {ArrowOptions} values */ draw(ctx, x, y, selected, hover, values) { this.resize(ctx, selected, hover); diff --git a/lib/network/modules/components/nodes/shapes/CircularImage.js b/lib/network/modules/components/nodes/shapes/CircularImage.js index c30c6512..04b719ca 100644 --- a/lib/network/modules/components/nodes/shapes/CircularImage.js +++ b/lib/network/modules/components/nodes/shapes/CircularImage.js @@ -53,7 +53,7 @@ class CircularImage extends CircleImageBase { * @param {number} y height * @param {boolean} selected * @param {boolean} hover - * @param {{toArrow: boolean, toArrowScale: (allOptions.edges.arrows.to.scaleFactor|{number}|allOptions.edges.arrows.middle.scaleFactor|allOptions.edges.arrows.from.scaleFactor|Array|number), toArrowType: *, middleArrow: boolean, middleArrowScale: (number|allOptions.edges.arrows.middle.scaleFactor|{number}|Array), middleArrowType: (allOptions.edges.arrows.middle.type|{string}|string|*), fromArrow: boolean, fromArrowScale: (allOptions.edges.arrows.to.scaleFactor|{number}|allOptions.edges.arrows.middle.scaleFactor|allOptions.edges.arrows.from.scaleFactor|Array|number), fromArrowType: *, arrowStrikethrough: (*|boolean|allOptions.edges.arrowStrikethrough|{boolean}), color: undefined, inheritsColor: (string|string|string|allOptions.edges.color.inherit|{string, boolean}|Array|*), opacity: *, hidden: *, length: *, shadow: *, shadowColor: *, shadowSize: *, shadowX: *, shadowY: *, dashes: (*|boolean|Array|allOptions.edges.dashes|{boolean, array}), width: *}} values + * @param {ArrowOptions} values */ draw(ctx, x, y, selected, hover, values) { this.switchImages(selected); diff --git a/lib/network/modules/components/nodes/shapes/Database.js b/lib/network/modules/components/nodes/shapes/Database.js index f9a17dab..b25bc3f3 100644 --- a/lib/network/modules/components/nodes/shapes/Database.js +++ b/lib/network/modules/components/nodes/shapes/Database.js @@ -42,7 +42,7 @@ class Database extends NodeBase { * @param {number} y height * @param {boolean} selected * @param {boolean} hover - * @param {{toArrow: boolean, toArrowScale: (allOptions.edges.arrows.to.scaleFactor|{number}|allOptions.edges.arrows.middle.scaleFactor|allOptions.edges.arrows.from.scaleFactor|Array|number), toArrowType: *, middleArrow: boolean, middleArrowScale: (number|allOptions.edges.arrows.middle.scaleFactor|{number}|Array), middleArrowType: (allOptions.edges.arrows.middle.type|{string}|string|*), fromArrow: boolean, fromArrowScale: (allOptions.edges.arrows.to.scaleFactor|{number}|allOptions.edges.arrows.middle.scaleFactor|allOptions.edges.arrows.from.scaleFactor|Array|number), fromArrowType: *, arrowStrikethrough: (*|boolean|allOptions.edges.arrowStrikethrough|{boolean}), color: undefined, inheritsColor: (string|string|string|allOptions.edges.color.inherit|{string, boolean}|Array|*), opacity: *, hidden: *, length: *, shadow: *, shadowColor: *, shadowSize: *, shadowX: *, shadowY: *, dashes: (*|boolean|Array|allOptions.edges.dashes|{boolean, array}), width: *}} values + * @param {ArrowOptions} values */ draw(ctx, x, y, selected, hover, values) { this.resize(ctx, selected, hover); diff --git a/lib/network/modules/components/nodes/shapes/Diamond.js b/lib/network/modules/components/nodes/shapes/Diamond.js index 8292e3bd..832afc70 100644 --- a/lib/network/modules/components/nodes/shapes/Diamond.js +++ b/lib/network/modules/components/nodes/shapes/Diamond.js @@ -24,7 +24,7 @@ class Diamond extends ShapeBase { * @param {number} y height * @param {boolean} selected * @param {boolean} hover - * @param {{toArrow: boolean, toArrowScale: (allOptions.edges.arrows.to.scaleFactor|{number}|allOptions.edges.arrows.middle.scaleFactor|allOptions.edges.arrows.from.scaleFactor|Array|number), toArrowType: *, middleArrow: boolean, middleArrowScale: (number|allOptions.edges.arrows.middle.scaleFactor|{number}|Array), middleArrowType: (allOptions.edges.arrows.middle.type|{string}|string|*), fromArrow: boolean, fromArrowScale: (allOptions.edges.arrows.to.scaleFactor|{number}|allOptions.edges.arrows.middle.scaleFactor|allOptions.edges.arrows.from.scaleFactor|Array|number), fromArrowType: *, arrowStrikethrough: (*|boolean|allOptions.edges.arrowStrikethrough|{boolean}), color: undefined, inheritsColor: (string|string|string|allOptions.edges.color.inherit|{string, boolean}|Array|*), opacity: *, hidden: *, length: *, shadow: *, shadowColor: *, shadowSize: *, shadowX: *, shadowY: *, dashes: (*|boolean|Array|allOptions.edges.dashes|{boolean, array}), width: *}} values + * @param {ArrowOptions} values */ draw(ctx, x, y, selected, hover, values) { this._drawShape(ctx, 'diamond', 4, x, y, selected, hover, values); diff --git a/lib/network/modules/components/nodes/shapes/Dot.js b/lib/network/modules/components/nodes/shapes/Dot.js index 9c4ac5ac..1cde7813 100644 --- a/lib/network/modules/components/nodes/shapes/Dot.js +++ b/lib/network/modules/components/nodes/shapes/Dot.js @@ -24,7 +24,7 @@ class Dot extends ShapeBase { * @param {number} y height * @param {boolean} selected * @param {boolean} hover - * @param {{toArrow: boolean, toArrowScale: (allOptions.edges.arrows.to.scaleFactor|{number}|allOptions.edges.arrows.middle.scaleFactor|allOptions.edges.arrows.from.scaleFactor|Array|number), toArrowType: *, middleArrow: boolean, middleArrowScale: (number|allOptions.edges.arrows.middle.scaleFactor|{number}|Array), middleArrowType: (allOptions.edges.arrows.middle.type|{string}|string|*), fromArrow: boolean, fromArrowScale: (allOptions.edges.arrows.to.scaleFactor|{number}|allOptions.edges.arrows.middle.scaleFactor|allOptions.edges.arrows.from.scaleFactor|Array|number), fromArrowType: *, arrowStrikethrough: (*|boolean|allOptions.edges.arrowStrikethrough|{boolean}), color: undefined, inheritsColor: (string|string|string|allOptions.edges.color.inherit|{string, boolean}|Array|*), opacity: *, hidden: *, length: *, shadow: *, shadowColor: *, shadowSize: *, shadowX: *, shadowY: *, dashes: (*|boolean|Array|allOptions.edges.dashes|{boolean, array}), width: *}} values + * @param {ArrowOptions} values */ draw(ctx, x, y, selected, hover, values) { this._drawShape(ctx, 'circle', 2, x, y, selected, hover, values); diff --git a/lib/network/modules/components/nodes/shapes/Ellipse.js b/lib/network/modules/components/nodes/shapes/Ellipse.js index b625ff68..feb934f7 100644 --- a/lib/network/modules/components/nodes/shapes/Ellipse.js +++ b/lib/network/modules/components/nodes/shapes/Ellipse.js @@ -40,7 +40,7 @@ class Ellipse extends NodeBase { * @param {number} y height * @param {boolean} selected * @param {boolean} hover - * @param {{toArrow: boolean, toArrowScale: (allOptions.edges.arrows.to.scaleFactor|{number}|allOptions.edges.arrows.middle.scaleFactor|allOptions.edges.arrows.from.scaleFactor|Array|number), toArrowType: *, middleArrow: boolean, middleArrowScale: (number|allOptions.edges.arrows.middle.scaleFactor|{number}|Array), middleArrowType: (allOptions.edges.arrows.middle.type|{string}|string|*), fromArrow: boolean, fromArrowScale: (allOptions.edges.arrows.to.scaleFactor|{number}|allOptions.edges.arrows.middle.scaleFactor|allOptions.edges.arrows.from.scaleFactor|Array|number), fromArrowType: *, arrowStrikethrough: (*|boolean|allOptions.edges.arrowStrikethrough|{boolean}), color: undefined, inheritsColor: (string|string|string|allOptions.edges.color.inherit|{string, boolean}|Array|*), opacity: *, hidden: *, length: *, shadow: *, shadowColor: *, shadowSize: *, shadowX: *, shadowY: *, dashes: (*|boolean|Array|allOptions.edges.dashes|{boolean, array}), width: *}} values + * @param {ArrowOptions} values */ draw(ctx, x, y, selected, hover, values) { this.resize(ctx, selected, hover); diff --git a/lib/network/modules/components/nodes/shapes/Hexagon.js b/lib/network/modules/components/nodes/shapes/Hexagon.js index 6f4618ff..e7359f4f 100644 --- a/lib/network/modules/components/nodes/shapes/Hexagon.js +++ b/lib/network/modules/components/nodes/shapes/Hexagon.js @@ -24,7 +24,7 @@ class Hexagon extends ShapeBase { * @param {number} y height * @param {boolean} selected * @param {boolean} hover - * @param {{toArrow: boolean, toArrowScale: (allOptions.edges.arrows.to.scaleFactor|{number}|allOptions.edges.arrows.middle.scaleFactor|allOptions.edges.arrows.from.scaleFactor|Array|number), toArrowType: *, middleArrow: boolean, middleArrowScale: (number|allOptions.edges.arrows.middle.scaleFactor|{number}|Array), middleArrowType: (allOptions.edges.arrows.middle.type|{string}|string|*), fromArrow: boolean, fromArrowScale: (allOptions.edges.arrows.to.scaleFactor|{number}|allOptions.edges.arrows.middle.scaleFactor|allOptions.edges.arrows.from.scaleFactor|Array|number), fromArrowType: *, arrowStrikethrough: (*|boolean|allOptions.edges.arrowStrikethrough|{boolean}), color: undefined, inheritsColor: (string|string|string|allOptions.edges.color.inherit|{string, boolean}|Array|*), opacity: *, hidden: *, length: *, shadow: *, shadowColor: *, shadowSize: *, shadowX: *, shadowY: *, dashes: (*|boolean|Array|allOptions.edges.dashes|{boolean, array}), width: *}} values + * @param {ArrowOptions} values */ draw(ctx, x, y, selected, hover, values) { this._drawShape(ctx, 'hexagon', 4, x, y, selected, hover, values); @@ -41,4 +41,4 @@ class Hexagon extends ShapeBase { } } -export default Hexagon; \ No newline at end of file +export default Hexagon; diff --git a/lib/network/modules/components/nodes/shapes/Icon.js b/lib/network/modules/components/nodes/shapes/Icon.js index e2a170df..ae74817a 100644 --- a/lib/network/modules/components/nodes/shapes/Icon.js +++ b/lib/network/modules/components/nodes/shapes/Icon.js @@ -43,7 +43,7 @@ class Icon extends NodeBase { * @param {number} y height * @param {boolean} selected * @param {boolean} hover - * @param {{toArrow: boolean, toArrowScale: (allOptions.edges.arrows.to.scaleFactor|{number}|allOptions.edges.arrows.middle.scaleFactor|allOptions.edges.arrows.from.scaleFactor|Array|number), toArrowType: *, middleArrow: boolean, middleArrowScale: (number|allOptions.edges.arrows.middle.scaleFactor|{number}|Array), middleArrowType: (allOptions.edges.arrows.middle.type|{string}|string|*), fromArrow: boolean, fromArrowScale: (allOptions.edges.arrows.to.scaleFactor|{number}|allOptions.edges.arrows.middle.scaleFactor|allOptions.edges.arrows.from.scaleFactor|Array|number), fromArrowType: *, arrowStrikethrough: (*|boolean|allOptions.edges.arrowStrikethrough|{boolean}), color: undefined, inheritsColor: (string|string|string|allOptions.edges.color.inherit|{string, boolean}|Array|*), opacity: *, hidden: *, length: *, shadow: *, shadowColor: *, shadowSize: *, shadowX: *, shadowY: *, dashes: (*|boolean|Array|allOptions.edges.dashes|{boolean, array}), width: *}} values + * @param {ArrowOptions} values */ draw(ctx, x, y, selected, hover, values) { this.resize(ctx, selected, hover); @@ -88,7 +88,7 @@ class Icon extends NodeBase { * @param {number} y height * @param {boolean} selected * @param {boolean} hover - Unused - * @param {{toArrow: boolean, toArrowScale: (allOptions.edges.arrows.to.scaleFactor|{number}|allOptions.edges.arrows.middle.scaleFactor|allOptions.edges.arrows.from.scaleFactor|Array|number), toArrowType: *, middleArrow: boolean, middleArrowScale: (number|allOptions.edges.arrows.middle.scaleFactor|{number}|Array), middleArrowType: (allOptions.edges.arrows.middle.type|{string}|string|*), fromArrow: boolean, fromArrowScale: (allOptions.edges.arrows.to.scaleFactor|{number}|allOptions.edges.arrows.middle.scaleFactor|allOptions.edges.arrows.from.scaleFactor|Array|number), fromArrowType: *, arrowStrikethrough: (*|boolean|allOptions.edges.arrowStrikethrough|{boolean}), color: undefined, inheritsColor: (string|string|string|allOptions.edges.color.inherit|{string, boolean}|Array|*), opacity: *, hidden: *, length: *, shadow: *, shadowColor: *, shadowSize: *, shadowX: *, shadowY: *, dashes: (*|boolean|Array|allOptions.edges.dashes|{boolean, array}), width: *}} values + * @param {ArrowOptions} values */ _icon(ctx, x, y, selected, hover, values) { let iconSize = Number(this.options.icon.size); diff --git a/lib/network/modules/components/nodes/shapes/Image.js b/lib/network/modules/components/nodes/shapes/Image.js index 5bb5607c..1aa2a958 100644 --- a/lib/network/modules/components/nodes/shapes/Image.js +++ b/lib/network/modules/components/nodes/shapes/Image.js @@ -52,7 +52,7 @@ class Image extends CircleImageBase { * @param {number} y height * @param {boolean} selected * @param {boolean} hover - * @param {{toArrow: boolean, toArrowScale: (allOptions.edges.arrows.to.scaleFactor|{number}|allOptions.edges.arrows.middle.scaleFactor|allOptions.edges.arrows.from.scaleFactor|Array|number), toArrowType: *, middleArrow: boolean, middleArrowScale: (number|allOptions.edges.arrows.middle.scaleFactor|{number}|Array), middleArrowType: (allOptions.edges.arrows.middle.type|{string}|string|*), fromArrow: boolean, fromArrowScale: (allOptions.edges.arrows.to.scaleFactor|{number}|allOptions.edges.arrows.middle.scaleFactor|allOptions.edges.arrows.from.scaleFactor|Array|number), fromArrowType: *, arrowStrikethrough: (*|boolean|allOptions.edges.arrowStrikethrough|{boolean}), color: undefined, inheritsColor: (string|string|string|allOptions.edges.color.inherit|{string, boolean}|Array|*), opacity: *, hidden: *, length: *, shadow: *, shadowColor: *, shadowSize: *, shadowX: *, shadowY: *, dashes: (*|boolean|Array|allOptions.edges.dashes|{boolean, array}), width: *}} values + * @param {ArrowOptions} values */ draw(ctx, x, y, selected, hover, values) { this.switchImages(selected); diff --git a/lib/network/modules/components/nodes/shapes/Square.js b/lib/network/modules/components/nodes/shapes/Square.js index c7d52c83..b61b7e5b 100644 --- a/lib/network/modules/components/nodes/shapes/Square.js +++ b/lib/network/modules/components/nodes/shapes/Square.js @@ -24,7 +24,7 @@ class Square extends ShapeBase { * @param {number} y height * @param {boolean} selected * @param {boolean} hover - * @param {{toArrow: boolean, toArrowScale: (allOptions.edges.arrows.to.scaleFactor|{number}|allOptions.edges.arrows.middle.scaleFactor|allOptions.edges.arrows.from.scaleFactor|Array|number), toArrowType: *, middleArrow: boolean, middleArrowScale: (number|allOptions.edges.arrows.middle.scaleFactor|{number}|Array), middleArrowType: (allOptions.edges.arrows.middle.type|{string}|string|*), fromArrow: boolean, fromArrowScale: (allOptions.edges.arrows.to.scaleFactor|{number}|allOptions.edges.arrows.middle.scaleFactor|allOptions.edges.arrows.from.scaleFactor|Array|number), fromArrowType: *, arrowStrikethrough: (*|boolean|allOptions.edges.arrowStrikethrough|{boolean}), color: undefined, inheritsColor: (string|string|string|allOptions.edges.color.inherit|{string, boolean}|Array|*), opacity: *, hidden: *, length: *, shadow: *, shadowColor: *, shadowSize: *, shadowX: *, shadowY: *, dashes: (*|boolean|Array|allOptions.edges.dashes|{boolean, array}), width: *}} values + * @param {ArrowOptions} values */ draw(ctx, x, y, selected, hover, values) { this._drawShape(ctx, 'square', 2, x, y, selected, hover, values); diff --git a/lib/network/modules/components/nodes/shapes/Star.js b/lib/network/modules/components/nodes/shapes/Star.js index 007f9330..d9bf4fb3 100644 --- a/lib/network/modules/components/nodes/shapes/Star.js +++ b/lib/network/modules/components/nodes/shapes/Star.js @@ -24,7 +24,7 @@ class Star extends ShapeBase { * @param {number} y height * @param {boolean} selected * @param {boolean} hover - * @param {{toArrow: boolean, toArrowScale: (allOptions.edges.arrows.to.scaleFactor|{number}|allOptions.edges.arrows.middle.scaleFactor|allOptions.edges.arrows.from.scaleFactor|Array|number), toArrowType: *, middleArrow: boolean, middleArrowScale: (number|allOptions.edges.arrows.middle.scaleFactor|{number}|Array), middleArrowType: (allOptions.edges.arrows.middle.type|{string}|string|*), fromArrow: boolean, fromArrowScale: (allOptions.edges.arrows.to.scaleFactor|{number}|allOptions.edges.arrows.middle.scaleFactor|allOptions.edges.arrows.from.scaleFactor|Array|number), fromArrowType: *, arrowStrikethrough: (*|boolean|allOptions.edges.arrowStrikethrough|{boolean}), color: undefined, inheritsColor: (string|string|string|allOptions.edges.color.inherit|{string, boolean}|Array|*), opacity: *, hidden: *, length: *, shadow: *, shadowColor: *, shadowSize: *, shadowX: *, shadowY: *, dashes: (*|boolean|Array|allOptions.edges.dashes|{boolean, array}), width: *}} values + * @param {ArrowOptions} values */ draw(ctx, x, y, selected, hover, values) { this._drawShape(ctx, 'star', 4, x, y, selected, hover, values); diff --git a/lib/network/modules/components/nodes/shapes/Text.js b/lib/network/modules/components/nodes/shapes/Text.js index 12c0f059..824bfcf3 100644 --- a/lib/network/modules/components/nodes/shapes/Text.js +++ b/lib/network/modules/components/nodes/shapes/Text.js @@ -40,7 +40,7 @@ class Text extends NodeBase { * @param {number} y height * @param {boolean} selected * @param {boolean} hover - * @param {{toArrow: boolean, toArrowScale: (allOptions.edges.arrows.to.scaleFactor|{number}|allOptions.edges.arrows.middle.scaleFactor|allOptions.edges.arrows.from.scaleFactor|Array|number), toArrowType: *, middleArrow: boolean, middleArrowScale: (number|allOptions.edges.arrows.middle.scaleFactor|{number}|Array), middleArrowType: (allOptions.edges.arrows.middle.type|{string}|string|*), fromArrow: boolean, fromArrowScale: (allOptions.edges.arrows.to.scaleFactor|{number}|allOptions.edges.arrows.middle.scaleFactor|allOptions.edges.arrows.from.scaleFactor|Array|number), fromArrowType: *, arrowStrikethrough: (*|boolean|allOptions.edges.arrowStrikethrough|{boolean}), color: undefined, inheritsColor: (string|string|string|allOptions.edges.color.inherit|{string, boolean}|Array|*), opacity: *, hidden: *, length: *, shadow: *, shadowColor: *, shadowSize: *, shadowX: *, shadowY: *, dashes: (*|boolean|Array|allOptions.edges.dashes|{boolean, array}), width: *}} values + * @param {ArrowOptions} values */ draw(ctx, x, y, selected, hover, values) { this.resize(ctx, selected, hover); diff --git a/lib/network/modules/components/nodes/shapes/Triangle.js b/lib/network/modules/components/nodes/shapes/Triangle.js index 4079ff5a..9c67b0da 100644 --- a/lib/network/modules/components/nodes/shapes/Triangle.js +++ b/lib/network/modules/components/nodes/shapes/Triangle.js @@ -24,7 +24,7 @@ class Triangle extends ShapeBase { * @param {number} y * @param {boolean} selected * @param {boolean} hover - * @param {{toArrow: boolean, toArrowScale: (allOptions.edges.arrows.to.scaleFactor|{number}|allOptions.edges.arrows.middle.scaleFactor|allOptions.edges.arrows.from.scaleFactor|Array|number), toArrowType: *, middleArrow: boolean, middleArrowScale: (number|allOptions.edges.arrows.middle.scaleFactor|{number}|Array), middleArrowType: (allOptions.edges.arrows.middle.type|{string}|string|*), fromArrow: boolean, fromArrowScale: (allOptions.edges.arrows.to.scaleFactor|{number}|allOptions.edges.arrows.middle.scaleFactor|allOptions.edges.arrows.from.scaleFactor|Array|number), fromArrowType: *, arrowStrikethrough: (*|boolean|allOptions.edges.arrowStrikethrough|{boolean}), color: undefined, inheritsColor: (string|string|string|allOptions.edges.color.inherit|{string, boolean}|Array|*), opacity: *, hidden: *, length: *, shadow: *, shadowColor: *, shadowSize: *, shadowX: *, shadowY: *, dashes: (*|boolean|Array|allOptions.edges.dashes|{boolean, array}), width: *}} values + * @param {ArrowOptions} values */ draw(ctx, x, y, selected, hover, values) { this._drawShape(ctx, 'triangle', 3, x, y, selected, hover, values); diff --git a/lib/network/modules/components/nodes/shapes/TriangleDown.js b/lib/network/modules/components/nodes/shapes/TriangleDown.js index 0f740d16..f87c3d07 100644 --- a/lib/network/modules/components/nodes/shapes/TriangleDown.js +++ b/lib/network/modules/components/nodes/shapes/TriangleDown.js @@ -24,7 +24,7 @@ class TriangleDown extends ShapeBase { * @param {number} y * @param {boolean} selected * @param {boolean} hover - * @param {{toArrow: boolean, toArrowScale: (allOptions.edges.arrows.to.scaleFactor|{number}|allOptions.edges.arrows.middle.scaleFactor|allOptions.edges.arrows.from.scaleFactor|Array|number), toArrowType: *, middleArrow: boolean, middleArrowScale: (number|allOptions.edges.arrows.middle.scaleFactor|{number}|Array), middleArrowType: (allOptions.edges.arrows.middle.type|{string}|string|*), fromArrow: boolean, fromArrowScale: (allOptions.edges.arrows.to.scaleFactor|{number}|allOptions.edges.arrows.middle.scaleFactor|allOptions.edges.arrows.from.scaleFactor|Array|number), fromArrowType: *, arrowStrikethrough: (*|boolean|allOptions.edges.arrowStrikethrough|{boolean}), color: undefined, inheritsColor: (string|string|string|allOptions.edges.color.inherit|{string, boolean}|Array|*), opacity: *, hidden: *, length: *, shadow: *, shadowColor: *, shadowSize: *, shadowX: *, shadowY: *, dashes: (*|boolean|Array|allOptions.edges.dashes|{boolean, array}), width: *}} values + * @param {ArrowOptions} values */ draw(ctx, x, y, selected, hover, values) { this._drawShape(ctx, 'triangleDown', 3, x, y, selected, hover, values); diff --git a/lib/network/modules/components/nodes/util/CircleImageBase.js b/lib/network/modules/components/nodes/util/CircleImageBase.js index 5393cce5..b70c419a 100644 --- a/lib/network/modules/components/nodes/util/CircleImageBase.js +++ b/lib/network/modules/components/nodes/util/CircleImageBase.js @@ -124,7 +124,7 @@ class CircleImageBase extends NodeBase { * @param {CanvasRenderingContext2D} ctx * @param {number} x width * @param {number} y height - * @param {{toArrow: boolean, toArrowScale: (allOptions.edges.arrows.to.scaleFactor|{number}|allOptions.edges.arrows.middle.scaleFactor|allOptions.edges.arrows.from.scaleFactor|Array|number), toArrowType: *, middleArrow: boolean, middleArrowScale: (number|allOptions.edges.arrows.middle.scaleFactor|{number}|Array), middleArrowType: (allOptions.edges.arrows.middle.type|{string}|string|*), fromArrow: boolean, fromArrowScale: (allOptions.edges.arrows.to.scaleFactor|{number}|allOptions.edges.arrows.middle.scaleFactor|allOptions.edges.arrows.from.scaleFactor|Array|number), fromArrowType: *, arrowStrikethrough: (*|boolean|allOptions.edges.arrowStrikethrough|{boolean}), color: undefined, inheritsColor: (string|string|string|allOptions.edges.color.inherit|{string, boolean}|Array|*), opacity: *, hidden: *, length: *, shadow: *, shadowColor: *, shadowSize: *, shadowX: *, shadowY: *, dashes: (*|boolean|Array|allOptions.edges.dashes|{boolean, array}), width: *}} values + * @param {ArrowOptions} values * @private */ _drawRawCircle(ctx, x, y, values) { @@ -136,7 +136,7 @@ class CircleImageBase extends NodeBase { /** * * @param {CanvasRenderingContext2D} ctx - * @param {{toArrow: boolean, toArrowScale: (allOptions.edges.arrows.to.scaleFactor|{number}|allOptions.edges.arrows.middle.scaleFactor|allOptions.edges.arrows.from.scaleFactor|Array|number), toArrowType: *, middleArrow: boolean, middleArrowScale: (number|allOptions.edges.arrows.middle.scaleFactor|{number}|Array), middleArrowType: (allOptions.edges.arrows.middle.type|{string}|string|*), fromArrow: boolean, fromArrowScale: (allOptions.edges.arrows.to.scaleFactor|{number}|allOptions.edges.arrows.middle.scaleFactor|allOptions.edges.arrows.from.scaleFactor|Array|number), fromArrowType: *, arrowStrikethrough: (*|boolean|allOptions.edges.arrowStrikethrough|{boolean}), color: undefined, inheritsColor: (string|string|string|allOptions.edges.color.inherit|{string, boolean}|Array|*), opacity: *, hidden: *, length: *, shadow: *, shadowColor: *, shadowSize: *, shadowX: *, shadowY: *, dashes: (*|boolean|Array|allOptions.edges.dashes|{boolean, array}), width: *}} values + * @param {ArrowOptions} values * @private */ _drawImageAtPosition(ctx, values) { diff --git a/lib/network/modules/components/nodes/util/NodeBase.js b/lib/network/modules/components/nodes/util/NodeBase.js index e2348517..4217c4f3 100644 --- a/lib/network/modules/components/nodes/util/NodeBase.js +++ b/lib/network/modules/components/nodes/util/NodeBase.js @@ -70,7 +70,7 @@ class NodeBase { /** * * @param {CanvasRenderingContext2D} ctx - * @param {{toArrow: boolean, toArrowScale: (allOptions.edges.arrows.to.scaleFactor|{number}|allOptions.edges.arrows.middle.scaleFactor|allOptions.edges.arrows.from.scaleFactor|Array|number), toArrowType: *, middleArrow: boolean, middleArrowScale: (number|allOptions.edges.arrows.middle.scaleFactor|{number}|Array), middleArrowType: (allOptions.edges.arrows.middle.type|{string}|string|*), fromArrow: boolean, fromArrowScale: (allOptions.edges.arrows.to.scaleFactor|{number}|allOptions.edges.arrows.middle.scaleFactor|allOptions.edges.arrows.from.scaleFactor|Array|number), fromArrowType: *, arrowStrikethrough: (*|boolean|allOptions.edges.arrowStrikethrough|{boolean}), color: undefined, inheritsColor: (string|string|string|allOptions.edges.color.inherit|{string, boolean}|Array|*), opacity: *, hidden: *, length: *, shadow: *, shadowColor: *, shadowSize: *, shadowX: *, shadowY: *, dashes: (*|boolean|Array|allOptions.edges.dashes|{boolean, array}), width: *}} values + * @param {ArrowOptions} values */ enableShadow(ctx, values) { if (values.shadow) { @@ -84,7 +84,7 @@ class NodeBase { /** * * @param {CanvasRenderingContext2D} ctx - * @param {{toArrow: boolean, toArrowScale: (allOptions.edges.arrows.to.scaleFactor|{number}|allOptions.edges.arrows.middle.scaleFactor|allOptions.edges.arrows.from.scaleFactor|Array|number), toArrowType: *, middleArrow: boolean, middleArrowScale: (number|allOptions.edges.arrows.middle.scaleFactor|{number}|Array), middleArrowType: (allOptions.edges.arrows.middle.type|{string}|string|*), fromArrow: boolean, fromArrowScale: (allOptions.edges.arrows.to.scaleFactor|{number}|allOptions.edges.arrows.middle.scaleFactor|allOptions.edges.arrows.from.scaleFactor|Array|number), fromArrowType: *, arrowStrikethrough: (*|boolean|allOptions.edges.arrowStrikethrough|{boolean}), color: undefined, inheritsColor: (string|string|string|allOptions.edges.color.inherit|{string, boolean}|Array|*), opacity: *, hidden: *, length: *, shadow: *, shadowColor: *, shadowSize: *, shadowX: *, shadowY: *, dashes: (*|boolean|Array|allOptions.edges.dashes|{boolean, array}), width: *}} values + * @param {ArrowOptions} values */ disableShadow(ctx, values) { if (values.shadow) { @@ -98,7 +98,7 @@ class NodeBase { /** * * @param {CanvasRenderingContext2D} ctx - * @param {{toArrow: boolean, toArrowScale: (allOptions.edges.arrows.to.scaleFactor|{number}|allOptions.edges.arrows.middle.scaleFactor|allOptions.edges.arrows.from.scaleFactor|Array|number), toArrowType: *, middleArrow: boolean, middleArrowScale: (number|allOptions.edges.arrows.middle.scaleFactor|{number}|Array), middleArrowType: (allOptions.edges.arrows.middle.type|{string}|string|*), fromArrow: boolean, fromArrowScale: (allOptions.edges.arrows.to.scaleFactor|{number}|allOptions.edges.arrows.middle.scaleFactor|allOptions.edges.arrows.from.scaleFactor|Array|number), fromArrowType: *, arrowStrikethrough: (*|boolean|allOptions.edges.arrowStrikethrough|{boolean}), color: undefined, inheritsColor: (string|string|string|allOptions.edges.color.inherit|{string, boolean}|Array|*), opacity: *, hidden: *, length: *, shadow: *, shadowColor: *, shadowSize: *, shadowX: *, shadowY: *, dashes: (*|boolean|Array|allOptions.edges.dashes|{boolean, array}), width: *}} values + * @param {ArrowOptions} values */ enableBorderDashes(ctx, values) { if (values.borderDashes !== false) { @@ -120,7 +120,7 @@ class NodeBase { /** * * @param {CanvasRenderingContext2D} ctx - * @param {{toArrow: boolean, toArrowScale: (allOptions.edges.arrows.to.scaleFactor|{number}|allOptions.edges.arrows.middle.scaleFactor|allOptions.edges.arrows.from.scaleFactor|Array|number), toArrowType: *, middleArrow: boolean, middleArrowScale: (number|allOptions.edges.arrows.middle.scaleFactor|{number}|Array), middleArrowType: (allOptions.edges.arrows.middle.type|{string}|string|*), fromArrow: boolean, fromArrowScale: (allOptions.edges.arrows.to.scaleFactor|{number}|allOptions.edges.arrows.middle.scaleFactor|allOptions.edges.arrows.from.scaleFactor|Array|number), fromArrowType: *, arrowStrikethrough: (*|boolean|allOptions.edges.arrowStrikethrough|{boolean}), color: undefined, inheritsColor: (string|string|string|allOptions.edges.color.inherit|{string, boolean}|Array|*), opacity: *, hidden: *, length: *, shadow: *, shadowColor: *, shadowSize: *, shadowX: *, shadowY: *, dashes: (*|boolean|Array|allOptions.edges.dashes|{boolean, array}), width: *}} values + * @param {ArrowOptions} values */ disableBorderDashes(ctx, values) { if (values.borderDashes !== false) { @@ -157,7 +157,7 @@ class NodeBase { /** * * @param {CanvasRenderingContext2D} ctx - * @param {{toArrow: boolean, toArrowScale: (allOptions.edges.arrows.to.scaleFactor|{number}|allOptions.edges.arrows.middle.scaleFactor|allOptions.edges.arrows.from.scaleFactor|Array|number), toArrowType: *, middleArrow: boolean, middleArrowScale: (number|allOptions.edges.arrows.middle.scaleFactor|{number}|Array), middleArrowType: (allOptions.edges.arrows.middle.type|{string}|string|*), fromArrow: boolean, fromArrowScale: (allOptions.edges.arrows.to.scaleFactor|{number}|allOptions.edges.arrows.middle.scaleFactor|allOptions.edges.arrows.from.scaleFactor|Array|number), fromArrowType: *, arrowStrikethrough: (*|boolean|allOptions.edges.arrowStrikethrough|{boolean}), color: undefined, inheritsColor: (string|string|string|allOptions.edges.color.inherit|{string, boolean}|Array|*), opacity: *, hidden: *, length: *, shadow: *, shadowColor: *, shadowSize: *, shadowX: *, shadowY: *, dashes: (*|boolean|Array|allOptions.edges.dashes|{boolean, array}), width: *}} values + * @param {ArrowOptions} values */ initContextForDraw(ctx, values) { var borderWidth = values.borderWidth / this.body.view.scale; @@ -170,7 +170,7 @@ class NodeBase { /** * * @param {CanvasRenderingContext2D} ctx - * @param {{toArrow: boolean, toArrowScale: (allOptions.edges.arrows.to.scaleFactor|{number}|allOptions.edges.arrows.middle.scaleFactor|allOptions.edges.arrows.from.scaleFactor|Array|number), toArrowType: *, middleArrow: boolean, middleArrowScale: (number|allOptions.edges.arrows.middle.scaleFactor|{number}|Array), middleArrowType: (allOptions.edges.arrows.middle.type|{string}|string|*), fromArrow: boolean, fromArrowScale: (allOptions.edges.arrows.to.scaleFactor|{number}|allOptions.edges.arrows.middle.scaleFactor|allOptions.edges.arrows.from.scaleFactor|Array|number), fromArrowType: *, arrowStrikethrough: (*|boolean|allOptions.edges.arrowStrikethrough|{boolean}), color: undefined, inheritsColor: (string|string|string|allOptions.edges.color.inherit|{string, boolean}|Array|*), opacity: *, hidden: *, length: *, shadow: *, shadowColor: *, shadowSize: *, shadowX: *, shadowY: *, dashes: (*|boolean|Array|allOptions.edges.dashes|{boolean, array}), width: *}} values + * @param {ArrowOptions} values */ performStroke(ctx, values) { var borderWidth = values.borderWidth / this.body.view.scale; @@ -191,7 +191,7 @@ class NodeBase { /** * * @param {CanvasRenderingContext2D} ctx - * @param {{toArrow: boolean, toArrowScale: (allOptions.edges.arrows.to.scaleFactor|{number}|allOptions.edges.arrows.middle.scaleFactor|allOptions.edges.arrows.from.scaleFactor|Array|number), toArrowType: *, middleArrow: boolean, middleArrowScale: (number|allOptions.edges.arrows.middle.scaleFactor|{number}|Array), middleArrowType: (allOptions.edges.arrows.middle.type|{string}|string|*), fromArrow: boolean, fromArrowScale: (allOptions.edges.arrows.to.scaleFactor|{number}|allOptions.edges.arrows.middle.scaleFactor|allOptions.edges.arrows.from.scaleFactor|Array|number), fromArrowType: *, arrowStrikethrough: (*|boolean|allOptions.edges.arrowStrikethrough|{boolean}), color: undefined, inheritsColor: (string|string|string|allOptions.edges.color.inherit|{string, boolean}|Array|*), opacity: *, hidden: *, length: *, shadow: *, shadowColor: *, shadowSize: *, shadowX: *, shadowY: *, dashes: (*|boolean|Array|allOptions.edges.dashes|{boolean, array}), width: *}} values + * @param {ArrowOptions} values */ performFill(ctx, values) { // draw shadow if enabled diff --git a/lib/network/modules/components/nodes/util/ShapeBase.js b/lib/network/modules/components/nodes/util/ShapeBase.js index 087e1bfd..d1d79e9c 100644 --- a/lib/network/modules/components/nodes/util/ShapeBase.js +++ b/lib/network/modules/components/nodes/util/ShapeBase.js @@ -41,7 +41,7 @@ class ShapeBase extends NodeBase { * @param {number} y * @param {boolean} selected * @param {boolean} hover - * @param {{toArrow: boolean, toArrowScale: (allOptions.edges.arrows.to.scaleFactor|{number}|allOptions.edges.arrows.middle.scaleFactor|allOptions.edges.arrows.from.scaleFactor|Array|number), toArrowType: *, middleArrow: boolean, middleArrowScale: (number|allOptions.edges.arrows.middle.scaleFactor|{number}|Array), middleArrowType: (allOptions.edges.arrows.middle.type|{string}|string|*), fromArrow: boolean, fromArrowScale: (allOptions.edges.arrows.to.scaleFactor|{number}|allOptions.edges.arrows.middle.scaleFactor|allOptions.edges.arrows.from.scaleFactor|Array|number), fromArrowType: *, arrowStrikethrough: (*|boolean|allOptions.edges.arrowStrikethrough|{boolean}), color: undefined, inheritsColor: (string|string|string|allOptions.edges.color.inherit|{string, boolean}|Array|*), opacity: *, hidden: *, length: *, shadow: *, shadowColor: *, shadowSize: *, shadowX: *, shadowY: *, dashes: (*|boolean|Array|allOptions.edges.dashes|{boolean, array}), width: *}} values + * @param {ArrowOptions} values * @private */ _drawShape(ctx, shape, sizeMultiplier, x, y, selected, hover, values) { diff --git a/lib/network/modules/components/shared/ComponentUtil.js b/lib/network/modules/components/shared/ComponentUtil.js index 9555920f..532c8a2c 100644 --- a/lib/network/modules/components/shared/ComponentUtil.js +++ b/lib/network/modules/components/shared/ComponentUtil.js @@ -1,23 +1,3 @@ -/** - * Definitions for param's in jsdoc. - * These are more or less global within Network. Putting them here until I can figure out - * where to really put them - * - * @typedef {string|number} Id - * @typedef {Id} NodeId - * @typedef {Id} EdgeId - * @typedef {Id} LabelId - * - * @typedef {{x: number, y: number}} point - * @typedef {{left: number, top: number, width: number, height: number}} rect - * @typedef {{x: number, y:number, angle: number}} rotationPoint - * - point to rotate around and the angle in radians to rotate. angle == 0 means no rotation - * @typedef {{nodeId:NodeId}} nodeClickItem - * @typedef {{nodeId:NodeId, labelId:LabelId}} nodeLabelClickItem - * @typedef {{edgeId:EdgeId}} edgeClickItem - * @typedef {{edgeId:EdgeId, labelId:LabelId}} edgeLabelClickItem - */ - let util = require("../../../../util"); /** diff --git a/lib/network/modules/components/shared/Label.js b/lib/network/modules/components/shared/Label.js index 1e400212..bf769a04 100644 --- a/lib/network/modules/components/shared/Label.js +++ b/lib/network/modules/components/shared/Label.js @@ -2,32 +2,6 @@ let util = require('../../../../util'); let ComponentUtil = require('./ComponentUtil').default; let LabelSplitter = require('./LabelSplitter').default; -/** - * @typedef {'bold'|'ital'|'boldital'|'mono'|'normal'} MultiFontStyle - * - * The allowed specifiers of multi-fonts. - */ - -/** - * @typedef {{color:string, size:number, face:string, mod:string, vadjust:number}} MultiFontOptions - * - * The full set of options of a given multi-font. - */ - -/** - * @typedef {Array.} Pile - * - * Sequence of option objects, the order is significant. - * The sequence is used to determine the value of a given option. - * - * Usage principles: - * - * - All search is done in the sequence of the pile. - * - As soon as a value is found, the searching stops. - * - prototypes are totally ignored. The idea is to add option objects used as prototypes - * to the pile, in the correct order. - */ - /** * List of special styles for multi-fonts @@ -35,6 +9,7 @@ let LabelSplitter = require('./LabelSplitter').default; */ const multiFontStyle = ['bold', 'ital', 'boldital', 'mono']; + /** * A Label to be used for Nodes or Edges. */ diff --git a/lib/network/modules/components/shared/LabelSplitter.js b/lib/network/modules/components/shared/LabelSplitter.js index 168d9966..75ad77b6 100644 --- a/lib/network/modules/components/shared/LabelSplitter.js +++ b/lib/network/modules/components/shared/LabelSplitter.js @@ -1,6 +1,274 @@ let LabelAccumulator = require('./LabelAccumulator').default; let ComponentUtil = require('./ComponentUtil').default; +// Hash of prepared regexp's for tags +var tagPattern = { + // HTML + '': //, + '': //, + '': //, + '': /<\/b>/, + '': /<\/i>/, + '': /<\/code>/, + // Markdown + '*': /\*/, // bold + '_': /\_/, // ital + '`': /`/, // mono + 'afterBold': /[^\*]/, + 'afterItal': /[^_]/, + 'afterMono': /[^`]/, +}; + + +/** + * Internal helper class for parsing the markup tags for HTML and Markdown. + * + * NOTE: Sequences of tabs and spaces are reduced to single space. + * Scan usage of `this.spacing` within method + */ +class MarkupAccumulator { + + /** + * Create an instance + * + * @param {string} text text to parse for markup + */ + constructor(text) { + this.text = text; + this.bold = false; + this.ital = false; + this.mono = false; + this.spacing = false; + this.position = 0; + this.buffer = ""; + this.modStack = []; + + this.blocks = []; + } + + + /** + * Return the mod label currently on the top of the stack + * + * @returns {string} label of topmost mod + * @private + */ + mod() { + return (this.modStack.length === 0) ? 'normal' : this.modStack[0]; + } + + + /** + * Return the mod label currently active + * + * @returns {string} label of active mod + * @private + */ + modName() { + if (this.modStack.length === 0) + return 'normal'; + else if (this.modStack[0] === 'mono') + return 'mono'; + else { + if (this.bold && this.ital) { + return 'boldital'; + } else if (this.bold) { + return 'bold'; + } else if (this.ital) { + return 'ital'; + } + } + } + + + /** + * @private + */ + emitBlock() { + if (this.spacing) { + this.add(" "); + this.spacing = false; + } + if (this.buffer.length > 0) { + this.blocks.push({ text: this.buffer, mod: this.modName() }); + this.buffer = ""; + } + } + + + /** + * Output text to buffer + * + * @param {string} text text to add + * @private + */ + add(text) { + if (text === " ") { + this.spacing = true; + } + if (this.spacing) { + this.buffer += " "; + this.spacing = false; + } + if (text != " ") { + this.buffer += text; + } + } + + + /** + * Handle parsing of whitespace + * + * @param {string} ch the character to check + * @returns {boolean} true if the character was processed as whitespace, false otherwise + */ + parseWS(ch) { + if (/[ \t]/.test(ch)) { + if (!this.mono) { + this.spacing = true; + } else { + this.add(ch); + } + return true; + } + + return false; + } + + + /** + * @param {string} tagName label for block type to set + * @private + */ + setTag(tagName) { + this.emitBlock(); + this[tagName] = true; + this.modStack.unshift(tagName); + } + + + /** + * @param {string} tagName label for block type to unset + * @private + */ + unsetTag(tagName) { + this.emitBlock(); + this[tagName] = false; + this.modStack.shift(); + } + + + /** + * @param {string} tagName label for block type we are currently processing + * @param {string|RegExp} tag string to match in text + * @returns {boolean} true if the tag was processed, false otherwise + */ + parseStartTag(tagName, tag) { + // Note: if 'mono' passed as tagName, there is a double check here. This is OK + if (!this.mono && !this[tagName] && this.match(tag)) { + this.setTag(tagName); + return true; + } + + return false; + } + + + /** + * @param {string|RegExp} tag + * @param {number} [advance=true] if set, advance current position in text + * @returns {boolean} true if match at given position, false otherwise + * @private + */ + match(tag, advance = true) { + let [regExp, length] = this.prepareRegExp(tag); + let matched = regExp.test(this.text.substr(this.position, length)); + + if (matched && advance) { + this.position += length - 1; + } + + return matched; + } + + + /** + * @param {string} tagName label for block type we are currently processing + * @param {string|RegExp} tag string to match in text + * @param {RegExp} [nextTag] regular expression to match for characters *following* the current tag + * @returns {boolean} true if the tag was processed, false otherwise + */ + parseEndTag(tagName, tag, nextTag) { + let checkTag = (this.mod() === tagName); + if (tagName === 'mono') { // special handling for 'mono' + checkTag = checkTag && this.mono; + } else { + checkTag = checkTag && !this.mono; + } + + if (checkTag && this.match(tag)) { + if (nextTag !== undefined) { + // Purpose of the following match is to prevent a direct unset/set of a given tag + // E.g. '*bold **still bold*' => '*bold still bold*' + if ((this.position === this.text.length-1) || this.match(nextTag, false)) { + this.unsetTag(tagName); + } + } else { + this.unsetTag(tagName); + } + + return true; + } + + return false; + } + + + /** + * @param {string|RegExp} tag string to match in text + * @param {value} value string to replace tag with, if found at current position + * @returns {boolean} true if the tag was processed, false otherwise + */ + replace(tag, value) { + if (this.match(tag)) { + this.add(value); + this.position += length - 1; + return true; + } + + return false; + } + + + /** + * Create a regular expression for the tag if it isn't already one. + * + * @param {string|RegExp} tag string to match in text + * @returns {[RegExp, number]} regular expression to use and length of input string to match + * @private + */ + prepareRegExp(tag) { + let length; + let regExp; + if (tag instanceof RegExp) { + regExp = tag; + length = 1; // ASSUMPTION: regexp only tests one character + } else { + // use prepared regexp if present + var prepared = tagPattern[tag]; + if (prepared !== undefined) { + regExp = prepared; + } else { + regExp = new RegExp(tag); + } + + length = tag.length; + } + + return [regExp, length]; + } +} + /** * Helper class for Label which explodes the label text into lines and blocks within lines @@ -159,123 +427,43 @@ class LabelSplitter { * @returns {Array} */ splitHtmlBlocks(text) { - let blocks = []; - - // TODO: consolidate following + methods/closures with splitMarkdownBlocks() - // NOTE: sequences of tabs and spaces are reduced to single space; scan usage of `this.spacing` within method - let s = { - bold: false, - ital: false, - mono: false, - spacing: false, - position: 0, - buffer: "", - modStack: [] - }; + let s = new MarkupAccumulator(text); - s.mod = function() { - return (this.modStack.length === 0) ? 'normal' : this.modStack[0]; - }; + let parseEntities = (ch) => { + if (/&/.test(ch)) { + let parsed = s.replace(s.text, '<', '<') + || s.replace(s.text, '&', '&'); - s.modName = function() { - if (this.modStack.length === 0) - return 'normal'; - else if (this.modStack[0] === 'mono') - return 'mono'; - else { - if (s.bold && s.ital) { - return 'boldital'; - } else if (s.bold) { - return 'bold'; - } else if (s.ital) { - return 'ital'; + if (!parsed) { + s.add("&"); } - } - }; - s.emitBlock = function(override=false) { // eslint-disable-line no-unused-vars - if (this.spacing) { - this.add(" "); - this.spacing = false; - } - if (this.buffer.length > 0) { - blocks.push({ text: this.buffer, mod: this.modName() }); - this.buffer = ""; + return true; } - }; - s.add = function(text) { - if (text === " ") { - s.spacing = true; - } - if (s.spacing) { - this.buffer += " "; - this.spacing = false; - } - if (text != " ") { - this.buffer += text; - } + return false; }; - while (s.position < text.length) { - let ch = text.charAt(s.position); - if (/[ \t]/.test(ch)) { - if (!s.mono) { - s.spacing = true; - } else { - s.add(ch); - } - } else if (//.test(text.substr(s.position,3))) { - s.emitBlock(); - s.bold = true; - s.modStack.unshift("bold"); - s.position += 2; - } else if (!s.mono && !s.ital && //.test(text.substr(s.position,3))) { - s.emitBlock(); - s.ital = true; - s.modStack.unshift("ital"); - s.position += 2; - } else if (!s.mono && //.test(text.substr(s.position,6))) { - s.emitBlock(); - s.mono = true; - s.modStack.unshift("mono"); - s.position += 5; - } else if (!s.mono && (s.mod() === 'bold') && /<\/b>/.test(text.substr(s.position,4))) { - s.emitBlock(); - s.bold = false; - s.modStack.shift(); - s.position += 3; - } else if (!s.mono && (s.mod() === 'ital') && /<\/i>/.test(text.substr(s.position,4))) { - s.emitBlock(); - s.ital = false; - s.modStack.shift(); - s.position += 3; - } else if ((s.mod() === 'mono') && /<\/code>/.test(text.substr(s.position,7))) { - s.emitBlock(); - s.mono = false; - s.modStack.shift(); - s.position += 6; - } else { - s.add(ch); - } - } else if (/&/.test(ch)) { - if (/</.test(text.substr(s.position,4))) { - s.add("<"); - s.position += 3; - } else if (/&/.test(text.substr(s.position,5))) { - s.add("&"); - s.position += 4; - } else { - s.add("&"); - } - } else { + while (s.position < s.text.length) { + let ch = s.text.charAt(s.position); + + let parsed = s.parseWS(ch) + || (/') + || s.parseStartTag('ital', '') + || s.parseStartTag('mono', '') + || s.parseEndTag('bold', '') + || s.parseEndTag('ital', '') + || s.parseEndTag('mono', ''))) + || parseEntities(ch); + + if (!parsed) { s.add(ch); } s.position++ } s.emitBlock(); - return blocks; + return s.blocks; } @@ -285,129 +473,49 @@ class LabelSplitter { * @returns {Array} */ splitMarkdownBlocks(text) { - let blocks = []; - - // TODO: consolidate following + methods/closures with splitHtmlBlocks() - // NOTE: sequences of tabs and spaces are reduced to single space; scan usage of `this.spacing` within method - let s = { - bold: false, - ital: false, - mono: false, - beginable: true, - spacing: false, - position: 0, - buffer: "", - modStack: [] - }; - - s.mod = function() { - return (this.modStack.length === 0) ? 'normal' : this.modStack[0]; - }; - - s.modName = function() { - if (this.modStack.length === 0) - return 'normal'; - else if (this.modStack[0] === 'mono') - return 'mono'; - else { - if (s.bold && s.ital) { - return 'boldital'; - } else if (s.bold) { - return 'bold'; - } else if (s.ital) { - return 'ital'; - } - } - }; - - s.emitBlock = function(override=false) { // eslint-disable-line no-unused-vars - if (this.spacing) { - this.add(" "); - this.spacing = false; - } - if (this.buffer.length > 0) { - blocks.push({ text: this.buffer, mod: this.modName() }); - this.buffer = ""; - } - }; + let s = new MarkupAccumulator(text); + let beginable = true; - s.add = function(text) { - if (text === " ") { - s.spacing = true; - } - if (s.spacing) { - this.buffer += " "; - this.spacing = false; - } - if (text != " ") { - this.buffer += text; - } - }; - - while (s.position < text.length) { - let ch = text.charAt(s.position); - if (/[ \t]/.test(ch)) { - if (!s.mono) { - s.spacing = true; - } else { - s.add(ch); - } - s.beginable = true - } else if (/\\/.test(ch)) { - if (s.position < text.length+1) { + let parseOverride = (ch) => { + if (/\\/.test(ch)) { + if (s.position < this.text.length + 1) { s.position++; - ch = text.charAt(s.position); + ch = this.text.charAt(s.position); if (/ \t/.test(ch)) { s.spacing = true; } else { s.add(ch); - s.beginable = false; + beginable = false; } } - } else if (!s.mono && !s.bold && (s.beginable || s.spacing) && /\*/.test(ch)) { - s.emitBlock(); - s.bold = true; - s.modStack.unshift("bold"); - } else if (!s.mono && !s.ital && (s.beginable || s.spacing) && /\_/.test(ch)) { - s.emitBlock(); - s.ital = true; - s.modStack.unshift("ital"); - } else if (!s.mono && (s.beginable || s.spacing) && /`/.test(ch)) { - s.emitBlock(); - s.mono = true; - s.modStack.unshift("mono"); - } else if (!s.mono && (s.mod() === "bold") && /\*/.test(ch)) { - if ((s.position === text.length-1) || /[.,_` \t\n]/.test(text.charAt(s.position+1))) { - s.emitBlock(); - s.bold = false; - s.modStack.shift(); - } else { - s.add(ch); - } - } else if (!s.mono && (s.mod() === "ital") && /\_/.test(ch)) { - if ((s.position === text.length-1) || /[.,*` \t\n]/.test(text.charAt(s.position+1))) { - s.emitBlock(); - s.ital = false; - s.modStack.shift(); - } else { - s.add(ch); - } - } else if (s.mono && (s.mod() === "mono") && /`/.test(ch)) { - if ((s.position === text.length-1) || (/[.,*_ \t\n]/.test(text.charAt(s.position+1)))) { - s.emitBlock(); - s.mono = false; - s.modStack.shift(); - } else { - s.add(ch); - } - } else { + + return true + } + + return false; + } + + while (s.position < s.text.length) { + let ch = s.text.charAt(s.position); + + let parsed = s.parseWS(ch) + || parseOverride(ch) + || ((beginable || s.spacing) && ( + s.parseStartTag('bold', '*') + || s.parseStartTag('ital', '_') + || s.parseStartTag('mono', '`'))) + || s.parseEndTag('bold', '*', 'afterBold') + || s.parseEndTag('ital', '_', 'afterItal') + || s.parseEndTag('mono', '`', 'afterMono'); + + if (!parsed) { s.add(ch); - s.beginable = false; + beginable = false; } s.position++ } s.emitBlock(); - return blocks; + return s.blocks; } diff --git a/lib/network/typedefs.js b/lib/network/typedefs.js new file mode 100644 index 00000000..ed6a3712 --- /dev/null +++ b/lib/network/typedefs.js @@ -0,0 +1,97 @@ +// NOTE: When a typedef is isolated in a separate comment block, an actual description is generated for it, +// using the rest of the commenting in the code block. Usage of typedef in other comments then +// link to there. TIL. +// +// Also noteworthy, all typedef's set up in this manner are collected in a single, global page 'global.html'. +// In other words, it doesn't matter *where* the typedef's are defined in the code. +// +// +// TODO: add descriptive commenting to given typedef's + +/** + * @typedef {{type:string, point:Point, angle:number, length:number}} ArrowData + * + * Object containing instantiation data for a given endpoint. + */ + +/** + * @typedef {{x:number, y:number}} Point + * + * A point in view-coordinates. + */ + +/** + * @typedef {{toArrow: boolean, toArrowScale: (allOptions.edges.arrows.to.scaleFactor|{number}|allOptions.edges.arrows.middle.scaleFactor|allOptions.edges.arrows.from.scaleFactor|Array|number), toArrowType: *, middleArrow: boolean, middleArrowScale: (number|allOptions.edges.arrows.middle.scaleFactor|{number}|Array), middleArrowType: (allOptions.edges.arrows.middle.type|{string}|string|*), fromArrow: boolean, fromArrowScale: (allOptions.edges.arrows.to.scaleFactor|{number}|allOptions.edges.arrows.middle.scaleFactor|allOptions.edges.arrows.from.scaleFactor|Array|number), fromArrowType: *, arrowStrikethrough: (*|boolean|allOptions.edges.arrowStrikethrough|{boolean}), color: undefined, inheritsColor: (string|string|string|allOptions.edges.color.inherit|{string, boolean}|Array|*), opacity: *, hidden: *, length: *, shadow: *, shadowColor: *, shadowSize: *, shadowX: *, shadowY: *, dashes: (*|boolean|Array|allOptions.edges.dashes|{boolean, array}), width: *}} ArrowOptions + */ + +/** + * @typedef {string|number} Id + */ + +/** + * @typedef {Id} NodeId + */ + +/** + * @typedef {Id} EdgeId + */ + +/** + * @typedef {Id} LabelId + */ + +/** + * @typedef {{x: number, y: number}} point + */ + +/** + * @typedef {{left: number, top: number, width: number, height: number}} rect + */ + +/** + * @typedef {{x: number, y:number, angle: number}} rotationPoint + * + * point to rotate around and the angle in radians to rotate. angle == 0 means no rotation + */ + +/** + * @typedef {{nodeId:NodeId}} nodeClickItem + */ + +/** + * @typedef {{nodeId:NodeId, labelId:LabelId}} nodeLabelClickItem + */ + +/** + * @typedef {{edgeId:EdgeId}} edgeClickItem + */ + +/** + * @typedef {{edgeId:EdgeId, labelId:LabelId}} edgeLabelClickItem + */ + +/** + * @typedef {'bold'|'ital'|'boldital'|'mono'|'normal'} MultiFontStyle + * + * The allowed specifiers of multi-fonts. + */ + +/** + * @typedef {{color:string, size:number, face:string, mod:string, vadjust:number}} MultiFontOptions + * + * The full set of options of a given multi-font. + */ + +/** + * @typedef {Array.} Pile + * + * Sequence of option objects, the order is significant. + * The sequence is used to determine the value of a given option. + * + * Usage principles: + * + * - All search is done in the sequence of the pile. + * - As soon as a value is found, the searching stops. + * - prototypes are totally ignored. The idea is to add option objects used as prototypes + * to the pile, in the correct order. + */ diff --git a/lib/timeline/Core.js b/lib/timeline/Core.js index 134c1580..376eacb7 100644 --- a/lib/timeline/Core.js +++ b/lib/timeline/Core.js @@ -27,6 +27,7 @@ Core.prototype._create = function (container) { this.dom = {}; this.dom.container = container; + this.dom.container.style.position = 'relative'; this.dom.root = document.createElement('div'); this.dom.background = document.createElement('div'); @@ -47,6 +48,7 @@ Core.prototype._create = function (container) { this.dom.shadowTopRight = document.createElement('div'); this.dom.shadowBottomRight = document.createElement('div'); this.dom.rollingModeBtn = document.createElement('div'); + this.dom.loadingScreen = document.createElement('div'); this.dom.root.className = 'vis-timeline'; this.dom.background.className = 'vis-panel vis-background'; @@ -67,6 +69,7 @@ Core.prototype._create = function (container) { this.dom.shadowTopRight.className = 'vis-shadow vis-top'; this.dom.shadowBottomRight.className = 'vis-shadow vis-bottom'; this.dom.rollingModeBtn.className = 'vis-rolling-mode-btn'; + this.dom.loadingScreen.className = 'vis-loading-screen'; this.dom.root.appendChild(this.dom.background); this.dom.root.appendChild(this.dom.backgroundVertical); @@ -76,7 +79,6 @@ Core.prototype._create = function (container) { this.dom.root.appendChild(this.dom.rightContainer); this.dom.root.appendChild(this.dom.top); this.dom.root.appendChild(this.dom.bottom); - this.dom.root.appendChild(this.dom.bottom); this.dom.root.appendChild(this.dom.rollingModeBtn); this.dom.centerContainer.appendChild(this.dom.center); @@ -88,7 +90,7 @@ Core.prototype._create = function (container) { this.dom.leftContainer.appendChild(this.dom.shadowBottomLeft); this.dom.rightContainer.appendChild(this.dom.shadowTopRight); this.dom.rightContainer.appendChild(this.dom.shadowBottomRight); - + // size properties of each of the panels this.props = { root: {}, @@ -334,6 +336,7 @@ Core.prototype._create = function (container) { // attach the root panel to the provided container if (!container) throw new Error('No container provided'); container.appendChild(this.dom.root); + container.appendChild(this.dom.loadingScreen); }; /** diff --git a/lib/timeline/TimeStep.js b/lib/timeline/TimeStep.js index f72fd1c0..1b3c1111 100644 --- a/lib/timeline/TimeStep.js +++ b/lib/timeline/TimeStep.js @@ -73,7 +73,7 @@ TimeStep.FORMAT = { hour: 'HH:mm', weekday: 'ddd D', day: 'D', - week: 'w', + week: 'D', month: 'MMM', year: 'YYYY' }, @@ -340,7 +340,7 @@ TimeStep.prototype.setMinimumStep = function(minimumStep) { if (stepYear > minimumStep) {this.scale = 'year'; this.step = 1;} if (stepMonth*3 > minimumStep) {this.scale = 'month'; this.step = 3;} if (stepMonth > minimumStep) {this.scale = 'month'; this.step = 1;} - if (stepDay*5 > minimumStep) {this.scale = 'day'; this.step = 5;} + if (stepDay*7 > minimumStep) {this.scale = 'week'; this.step = 1;} if (stepDay*2 > minimumStep) {this.scale = 'day'; this.step = 2;} if (stepDay > minimumStep) {this.scale = 'day'; this.step = 1;} if (stepDay/2 > minimumStep) {this.scale = 'weekday'; this.step = 1;} diff --git a/lib/timeline/Timeline.js b/lib/timeline/Timeline.js index 60974393..184c4891 100644 --- a/lib/timeline/Timeline.js +++ b/lib/timeline/Timeline.js @@ -78,6 +78,26 @@ function Timeline (container, items, groups, options) { this.options.rollingMode = options && options.rollingMode; this.options.onInitialDrawComplete = options && options.onInitialDrawComplete; + this.options.loadingScreenTemplate = options && options.loadingScreenTemplate; + + // Prepare loading screen + var loadingScreenFragment = document.createElement('div'); + if (this.options.loadingScreenTemplate) { + var templateFunction = this.options.loadingScreenTemplate.bind(this); + var loadingScreen = templateFunction(this.dom.loadingScreen); + if ((loadingScreen instanceof Object) && !(loadingScreen instanceof Element)) { + templateFunction(loadingScreenFragment) + } else { + if (loadingScreen instanceof Element) { + loadingScreenFragment.innerHTML = ''; + loadingScreenFragment.appendChild(loadingScreen); + } + else if (loadingScreen != undefined) { + loadingScreenFragment.innerHTML = loadingScreen; + } + } + } + this.dom.loadingScreen.appendChild(loadingScreenFragment); // all components listed here will be repainted automatically this.components = []; @@ -183,6 +203,7 @@ function Timeline (container, items, groups, options) { if (!me.initialDrawDone && me.initialRangeChangeDone) { me.initialDrawDone = true; me.dom.root.style.visibility = 'visible'; + me.dom.loadingScreen.parentNode.removeChild(me.dom.loadingScreen); if (me.options.onInitialDrawComplete) { setTimeout(() => { return me.options.onInitialDrawComplete(); @@ -438,7 +459,7 @@ Timeline.prototype.focus = function(id, options) { me._redraw(); } }; - + // Enforces the final vertical scroll position var setFinalVerticalPosition = function() { var finalVerticalScroll = getItemVerticalScroll(me, item); diff --git a/lib/timeline/component/css/timeline.css b/lib/timeline/component/css/timeline.css index a45d467c..e8ad0e5f 100644 --- a/lib/timeline/component/css/timeline.css +++ b/lib/timeline/component/css/timeline.css @@ -2,10 +2,16 @@ .vis-timeline { position: relative; border: 1px solid #bfbfbf; - overflow: hidden; padding: 0; margin: 0; - box-sizing: border-box; } + +.vis-loading-screen { + width: 100%; + height: 100%; + position: absolute; + top: 0; + left: 0; +} \ No newline at end of file diff --git a/lib/timeline/component/css/timeline.js b/lib/timeline/component/css/timeline.js new file mode 100644 index 00000000..fd3d3bd5 --- /dev/null +++ b/lib/timeline/component/css/timeline.js @@ -0,0 +1,19 @@ +import { StyleSheet } from 'react-native'; + +export default StyleSheet.create({ + 'vis-timeline': { + 'position': 'relative', + 'border': [{ 'unit': 'px', 'value': 1 }, { 'unit': 'string', 'value': 'solid' }, { 'unit': 'string', 'value': '#bfbfbf' }], + 'overflow': 'hidden', + 'padding': [{ 'unit': 'px', 'value': 0 }, { 'unit': 'px', 'value': 0 }, { 'unit': 'px', 'value': 0 }, { 'unit': 'px', 'value': 0 }], + 'margin': [{ 'unit': 'px', 'value': 0 }, { 'unit': 'px', 'value': 0 }, { 'unit': 'px', 'value': 0 }, { 'unit': 'px', 'value': 0 }], + 'boxSizing': 'border-box' + }, + 'vis-loading-screen': { + 'width': [{ 'unit': '%H', 'value': 1 }], + 'height': [{ 'unit': '%V', 'value': 1 }], + 'position': 'absolute', + 'top': [{ 'unit': 'px', 'value': 0 }], + 'left': [{ 'unit': 'px', 'value': 0 }] + } +}); diff --git a/lib/timeline/optionsTimeline.js b/lib/timeline/optionsTimeline.js index 820b6b3e..e13e6ae6 100644 --- a/lib/timeline/optionsTimeline.js +++ b/lib/timeline/optionsTimeline.js @@ -142,6 +142,7 @@ let allOptions = { snap: {'function': 'function', 'null': 'null'}, start: {date, number, string, moment}, template: {'function': 'function'}, + loadingScreenTemplate: {'function': 'function'}, groupTemplate: {'function': 'function'}, visibleFrameTemplate: {string, 'function': 'function'}, showTooltips: { 'boolean': bool}, diff --git a/package.json b/package.json index be72b0af..de2515f5 100644 --- a/package.json +++ b/package.json @@ -38,7 +38,8 @@ "hammerjs": "^2.0.8", "keycharm": "^0.2.0", "moment": "^2.18.1", - "propagating-hammerjs": "^1.4.6" + "propagating-hammerjs": "^1.4.6", + "timsort": "^0.3.0" }, "devDependencies": { "async": "^2.5.0", @@ -59,6 +60,7 @@ "gulp-eslint": "^4.0.0", "gulp-rename": "^1.2.2", "gulp-util": "^3.0.8", + "jsdoc": "^3.5.5", "jsdom": "9.12.0", "jsdom-global": "^2.1.1", "merge-stream": "^1.0.1", diff --git a/test/Label.test.js b/test/Label.test.js index f2dbe90a..8f2cf52a 100644 --- a/test/Label.test.js +++ b/test/Label.test.js @@ -2,6 +2,7 @@ * TODO - add tests for: * ==== * + * - html entities * - html unclosed or unopened tags * - html tag combinations with no font defined (e.g. bold within mono) * - Unit tests for bad font shorthands.