From 0a3374172563617da1d9dd4da2d08dc9d72f341b Mon Sep 17 00:00:00 2001 From: Wim Rijnders Date: Wed, 24 May 2017 07:20:05 +0200 Subject: [PATCH 1/9] Proof of concept with copied options + handling from network --- lib/graph3d/Graph3d.js | 9 + lib/graph3d/options.js | 636 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 645 insertions(+) create mode 100644 lib/graph3d/options.js diff --git a/lib/graph3d/Graph3d.js b/lib/graph3d/Graph3d.js index 29371ff7f..bde90c903 100755 --- a/lib/graph3d/Graph3d.js +++ b/lib/graph3d/Graph3d.js @@ -9,6 +9,9 @@ var Slider = require('./Slider'); var StepNumber = require('./StepNumber'); var Range = require('./Range'); var Settings = require('./Settings'); +var Validator = require("./../shared/Validator").default; +var {printStyle} = require('./../shared/Validator'); +var {allOptions, configureOptions} = require('./options.js'); /// enumerate the available styles @@ -891,6 +894,12 @@ Graph3d.prototype.setData = function (data) { * @param {Object} options */ Graph3d.prototype.setOptions = function (options) { + if (options === undefined) return + let errorFound = Validator.validate(options, allOptions); + if (errorFound === true) { + console.log('%cErrors have been found in the supplied options object.', printStyle); + } + var cameraPosition = undefined; this.animationStop(); diff --git a/lib/graph3d/options.js b/lib/graph3d/options.js new file mode 100644 index 000000000..76522546d --- /dev/null +++ b/lib/graph3d/options.js @@ -0,0 +1,636 @@ +/** + * This object contains all possible options. It will check if the types are correct, if required if the option is one + * of the allowed values. + * + * __any__ means that the name of the property does not matter. + * __type__ is a required field for all objects and contains the allowed types of all objects + */ +let string = 'string'; +let bool = 'boolean'; +let number = 'number'; +let array = 'array'; +let object = 'object'; // should only be in a __type__ property +let dom = 'dom'; +let any = 'any'; + + +let allOptions = { + filterLabel: { string }, + verticalRatio: { number }, + keepAspectRatio: { boolean: bool }, + showGrid: { boolean: bool }, + showPerspective: { boolean: bool }, + showShadow: { boolean: bool }, + style: { string: [ + 'bar', + 'bar-color', + 'bar-size', + 'dot', + 'dot-line', + 'dot-color', + 'dot-size', + 'line', + 'grid', + 'surface' + ] }, + + //globals : + height: { string }, + width: { string }, + __type__: { object }, // TODO this should be the final item in options; remove the comma when done + +// Options copied from 'network' - TODO remove these! + configure: { + enabled: { boolean: bool }, + filter: { boolean: bool, string, array, 'function': 'function' }, + container: { dom }, + showButton: { boolean: bool }, + __type__: { object, boolean: bool, string, array, 'function': 'function' } + }, + edges: { + arrows: { + to: { enabled: { boolean: bool }, scaleFactor: { number }, type: { string: ['arrow', 'circle'] }, __type__: { object, boolean: bool } }, + middle: { enabled: { boolean: bool }, scaleFactor: { number }, type: { string: ['arrow', 'circle'] }, __type__: { object, boolean: bool } }, + from: { enabled: { boolean: bool }, scaleFactor: { number }, type: { string: ['arrow', 'circle'] }, __type__: { object, boolean: bool } }, + __type__: { string: ['from', 'to', 'middle'], object } + }, + arrowStrikethrough: { boolean: bool }, + chosen: { + label: { boolean: bool, 'function': 'function' }, + edge: { boolean: bool, 'function': 'function' }, + __type__: { object, boolean: bool } + }, + color: { + color: { string }, + highlight: { string }, + hover: { string }, + inherit: { string: ['from', 'to', 'both'], boolean: bool }, + opacity: { number }, + __type__: { object, string } + }, + dashes: { boolean: bool, array }, + font: { + color: { string }, + size: { number }, // px + face: { string }, + background: { string }, + strokeWidth: { number }, // px + strokeColor: { string }, + align: { string: ['horizontal', 'top', 'middle', 'bottom'] }, + vadjust: { number }, + multi: { boolean: bool, string }, + bold: { + color: { string }, + size: { number }, // px + face: { string }, + mod: { string }, + vadjust: { number }, + __type__: { object, string } + }, + boldital: { + color: { string }, + size: { number }, // px + face: { string }, + mod: { string }, + vadjust: { number }, + __type__: { object, string } + }, + ital: { + color: { string }, + size: { number }, // px + face: { string }, + mod: { string }, + vadjust: { number }, + __type__: { object, string } + }, + mono: { + color: { string }, + size: { number }, // px + face: { string }, + mod: { string }, + vadjust: { number }, + __type__: { object, string } + }, + __type__: { object, string } + }, + hidden: { boolean: bool }, + hoverWidth: { 'function': 'function', number }, + label: { string, 'undefined': 'undefined' }, + labelHighlightBold: { boolean: bool }, + length: { number, 'undefined': 'undefined' }, + physics: { boolean: bool }, + scaling: { + min: { number }, + max: { number }, + label: { + enabled: { boolean: bool }, + min: { number }, + max: { number }, + maxVisible: { number }, + drawThreshold: { number }, + __type__: { object, boolean: bool } + }, + customScalingFunction: { 'function': 'function' }, + __type__: { object } + }, + selectionWidth: { 'function': 'function', number }, + selfReferenceSize: { number }, + shadow: { + enabled: { boolean: bool }, + color: { string }, + size: { number }, + x: { number }, + y: { number }, + __type__: { object, boolean: bool } + }, + smooth: { + enabled: { boolean: bool }, + type: { string: ['dynamic', 'continuous', 'discrete', 'diagonalCross', 'straightCross', 'horizontal', 'vertical', 'curvedCW', 'curvedCCW', 'cubicBezier'] }, + roundness: { number }, + forceDirection: { string: ['horizontal', 'vertical', 'none'], boolean: bool }, + __type__: { object, boolean: bool } + }, + title: { string, 'undefined': 'undefined' }, + width: { number }, + widthConstraint: { + maximum: { number }, + __type__: { object, boolean: bool, number } + }, + value: { number, 'undefined': 'undefined' }, + __type__: { object } + }, + groups: { + useDefaultGroups: { boolean: bool }, + __any__: 'get from nodes, will be overwritten below', + __type__: { object } + }, + interaction: { + dragNodes: { boolean: bool }, + dragView: { boolean: bool }, + hideEdgesOnDrag: { boolean: bool }, + hideNodesOnDrag: { boolean: bool }, + hover: { boolean: bool }, + keyboard: { + enabled: { boolean: bool }, + speed: { x: { number }, y: { number }, zoom: { number }, __type__: { object } }, + bindToWindow: { boolean: bool }, + __type__: { object, boolean: bool } + }, + multiselect: { boolean: bool }, + navigationButtons: { boolean: bool }, + selectable: { boolean: bool }, + selectConnectedEdges: { boolean: bool }, + hoverConnectedEdges: { boolean: bool }, + tooltipDelay: { number }, + zoomView: { boolean: bool }, + __type__: { object } + }, + layout: { + randomSeed: { 'undefined': 'undefined', number }, + improvedLayout: { boolean: bool }, + hierarchical: { + enabled: { boolean: bool }, + levelSeparation: { number }, + nodeSpacing: { number }, + treeSpacing: { number }, + blockShifting: { boolean: bool }, + edgeMinimization: { boolean: bool }, + parentCentralization: { boolean: bool }, + direction: { string: ['UD', 'DU', 'LR', 'RL'] }, // UD, DU, LR, RL + sortMethod: { string: ['hubsize', 'directed'] }, // hubsize, directed + __type__: { object, boolean: bool } + }, + __type__: { object } + }, + manipulation: { + enabled: { boolean: bool }, + initiallyActive: { boolean: bool }, + addNode: { boolean: bool, 'function': 'function' }, + addEdge: { boolean: bool, 'function': 'function' }, + editNode: { 'function': 'function' }, + editEdge: { + editWithoutDrag: { 'function' : 'function' }, + __type__: {object, boolean: bool, 'function': 'function' } + }, + deleteNode: { boolean: bool, 'function': 'function' }, + deleteEdge: { boolean: bool, 'function': 'function' }, + controlNodeStyle: 'get from nodes, will be overwritten below', + __type__: { object, boolean: bool } + }, + nodes: { + borderWidth: { number }, + borderWidthSelected: { number, 'undefined': 'undefined' }, + brokenImage: { string, 'undefined': 'undefined' }, + chosen: { + label: { boolean: bool, 'function': 'function' }, + node: { boolean: bool, 'function': 'function' }, + __type__: { object, boolean: bool } + }, + color: { + border: { string }, + background: { string }, + highlight: { + border: { string }, + background: { string }, + __type__: { object, string } + }, + hover: { + border: { string }, + background: { string }, + __type__: { object, string } + }, + __type__: { object, string } + }, + fixed: { + x: { boolean: bool }, + y: { boolean: bool }, + __type__: { object, boolean: bool } + }, + font: { + align: { string }, + color: { string }, + size: { number }, // px + face: { string }, + background: { string }, + strokeWidth: { number }, // px + strokeColor: { string }, + vadjust: { number }, + multi: { boolean: bool, string }, + bold: { + color: { string }, + size: { number }, // px + face: { string }, + mod: { string }, + vadjust: { number }, + __type__: { object, string } + }, + boldital: { + color: { string }, + size: { number }, // px + face: { string }, + mod: { string }, + vadjust: { number }, + __type__: { object, string } + }, + ital: { + color: { string }, + size: { number }, // px + face: { string }, + mod: { string }, + vadjust: { number }, + __type__: { object, string } + }, + mono: { + color: { string }, + size: { number }, // px + face: { string }, + mod: { string }, + vadjust: { number }, + __type__: { object, string } + }, + __type__: { object, string } + }, + group: { string, number, 'undefined': 'undefined' }, + heightConstraint: { + minimum: { number }, + valign: { string }, + __type__: { object, boolean: bool, number } + }, + hidden: { boolean: bool }, + icon: { + face: { string }, + code: { string }, //'\uf007', + size: { number }, //50, + color: { string }, + __type__: { object } + }, + id: { string, number }, + image: { + selected: { string, 'undefined': 'undefined' }, // --> URL + unselected: { string, 'undefined': 'undefined' }, // --> URL + __type__: { object, string } + }, + label: { string, 'undefined': 'undefined' }, + labelHighlightBold: { boolean: bool }, + level: { number, 'undefined': 'undefined' }, + margin: { + top: { number }, + right: { number }, + bottom: { number }, + left: { number }, + __type__: { object, number } + }, + mass: { number }, + physics: { boolean: bool }, + scaling: { + min: { number }, + max: { number }, + label: { + enabled: { boolean: bool }, + min: { number }, + max: { number }, + maxVisible: { number }, + drawThreshold: { number }, + __type__: { object, boolean: bool } + }, + customScalingFunction: { 'function': 'function' }, + __type__: { object } + }, + shadow: { + enabled: { boolean: bool }, + color: { string }, + size: { number }, + x: { number }, + y: { number }, + __type__: { object, boolean: bool } + }, + shape: { string: ['ellipse', 'circle', 'database', 'box', 'text', 'image', 'circularImage', 'diamond', 'dot', 'star', 'triangle', 'triangleDown', 'square', 'icon'] }, + shapeProperties: { + borderDashes: { boolean: bool, array }, + borderRadius: { number }, + interpolation: { boolean: bool }, + useImageSize: { boolean: bool }, + useBorderWithImage: { boolean: bool }, + __type__: { object } + }, + size: { number }, + title: { string, 'undefined': 'undefined' }, + value: { number, 'undefined': 'undefined' }, + widthConstraint: { + minimum: { number }, + maximum: { number }, + __type__: { object, boolean: bool, number } + }, + x: { number }, + y: { number }, + __type__: { object } + }, + physics: { + enabled: { boolean: bool }, + barnesHut: { + gravitationalConstant: { number }, + centralGravity: { number }, + springLength: { number }, + springConstant: { number }, + damping: { number }, + avoidOverlap: { number }, + __type__: { object } + }, + forceAtlas2Based: { + gravitationalConstant: { number }, + centralGravity: { number }, + springLength: { number }, + springConstant: { number }, + damping: { number }, + avoidOverlap: { number }, + __type__: { object } + }, + repulsion: { + centralGravity: { number }, + springLength: { number }, + springConstant: { number }, + nodeDistance: { number }, + damping: { number }, + __type__: { object } + }, + hierarchicalRepulsion: { + centralGravity: { number }, + springLength: { number }, + springConstant: { number }, + nodeDistance: { number }, + damping: { number }, + __type__: { object } + }, + maxVelocity: { number }, + minVelocity: { number }, // px/s + solver: { string: ['barnesHut', 'repulsion', 'hierarchicalRepulsion', 'forceAtlas2Based'] }, + stabilization: { + enabled: { boolean: bool }, + iterations: { number }, // maximum number of iteration to stabilize + updateInterval: { number }, + onlyDynamicEdges: { boolean: bool }, + fit: { boolean: bool }, + __type__: { object, boolean: bool } + }, + timestep: { number }, + adaptiveTimestep: { boolean: bool }, + __type__: { object, boolean: bool } + }, + + //globals : + autoResize: { boolean: bool }, + clickToUse: { boolean: bool }, + locale: { string }, + locales: { + __any__: { any }, + __type__: { object } + }, +}; + +allOptions.groups.__any__ = allOptions.nodes; +allOptions.manipulation.controlNodeStyle = allOptions.nodes; + + +let configureOptions = { + nodes: { + borderWidth: [1, 0, 10, 1], + borderWidthSelected: [2, 0, 10, 1], + color: { + border: ['color', '#2B7CE9'], + background: ['color', '#97C2FC'], + highlight: { + border: ['color', '#2B7CE9'], + background: ['color', '#D2E5FF'] + }, + hover: { + border: ['color', '#2B7CE9'], + background: ['color', '#D2E5FF'] + } + }, + fixed: { + x: false, + y: false + }, + font: { + color: ['color', '#343434'], + size: [14, 0, 100, 1], // px + face: ['arial', 'verdana', 'tahoma'], + background: ['color', 'none'], + strokeWidth: [0, 0, 50, 1], // px + strokeColor: ['color', '#ffffff'] + }, + //group: 'string', + hidden: false, + labelHighlightBold: true, + //icon: { + // face: 'string', //'FontAwesome', + // code: 'string', //'\uf007', + // size: [50, 0, 200, 1], //50, + // color: ['color','#2B7CE9'] //'#aa00ff' + //}, + //image: 'string', // --> URL + physics: true, + scaling: { + min: [10, 0, 200, 1], + max: [30, 0, 200, 1], + label: { + enabled: false, + min: [14, 0, 200, 1], + max: [30, 0, 200, 1], + maxVisible: [30, 0, 200, 1], + drawThreshold: [5, 0, 20, 1] + } + }, + shadow: { + enabled: false, + color: 'rgba(0,0,0,0.5)', + size: [10, 0, 20, 1], + x: [5, -30, 30, 1], + y: [5, -30, 30, 1] + }, + shape: ['ellipse', 'box', 'circle', 'database', 'diamond', 'dot', 'square', 'star', 'text', 'triangle', 'triangleDown'], + shapeProperties: { + borderDashes: false, + borderRadius: [6, 0, 20, 1], + interpolation: true, + useImageSize: false + }, + size: [25, 0, 200, 1] + }, + edges: { + arrows: { + to: { enabled: false, scaleFactor: [1, 0, 3, 0.05], type: 'arrow' }, + middle: { enabled: false, scaleFactor: [1, 0, 3, 0.05], type: 'arrow' }, + from: { enabled: false, scaleFactor: [1, 0, 3, 0.05], type: 'arrow' } + }, + arrowStrikethrough: true, + color: { + color: ['color', '#848484'], + highlight: ['color', '#848484'], + hover: ['color', '#848484'], + inherit: ['from', 'to', 'both', true, false], + opacity: [1, 0, 1, 0.05] + }, + dashes: false, + font: { + color: ['color', '#343434'], + size: [14, 0, 100, 1], // px + face: ['arial', 'verdana', 'tahoma'], + background: ['color', 'none'], + strokeWidth: [2, 0, 50, 1], // px + strokeColor: ['color', '#ffffff'], + align: ['horizontal', 'top', 'middle', 'bottom'] + }, + hidden: false, + hoverWidth: [1.5, 0, 5, 0.1], + labelHighlightBold: true, + physics: true, + scaling: { + min: [1, 0, 100, 1], + max: [15, 0, 100, 1], + label: { + enabled: true, + min: [14, 0, 200, 1], + max: [30, 0, 200, 1], + maxVisible: [30, 0, 200, 1], + drawThreshold: [5, 0, 20, 1] + } + }, + selectionWidth: [1.5, 0, 5, 0.1], + selfReferenceSize: [20, 0, 200, 1], + shadow: { + enabled: false, + color: 'rgba(0,0,0,0.5)', + size: [10, 0, 20, 1], + x: [5, -30, 30, 1], + y: [5, -30, 30, 1] + }, + smooth: { + enabled: true, + type: ['dynamic', 'continuous', 'discrete', 'diagonalCross', 'straightCross', 'horizontal', 'vertical', 'curvedCW', 'curvedCCW', 'cubicBezier'], + forceDirection: ['horizontal', 'vertical', 'none'], + roundness: [0.5, 0, 1, 0.05] + }, + width: [1, 0, 30, 1] + }, + layout: { + //randomSeed: [0, 0, 500, 1], + //improvedLayout: true, + hierarchical: { + enabled: false, + levelSeparation: [150, 20, 500, 5], + nodeSpacing: [100, 20, 500, 5], + treeSpacing: [200, 20, 500, 5], + blockShifting: true, + edgeMinimization: true, + parentCentralization: true, + direction: ['UD', 'DU', 'LR', 'RL'], // UD, DU, LR, RL + sortMethod: ['hubsize', 'directed'] // hubsize, directed + } + }, + interaction: { + dragNodes: true, + dragView: true, + hideEdgesOnDrag: false, + hideNodesOnDrag: false, + hover: false, + keyboard: { + enabled: false, + speed: { x: [10, 0, 40, 1], y: [10, 0, 40, 1], zoom: [0.02, 0, 0.1, 0.005] }, + bindToWindow: true + }, + multiselect: false, + navigationButtons: false, + selectable: true, + selectConnectedEdges: true, + hoverConnectedEdges: true, + tooltipDelay: [300, 0, 1000, 25], + zoomView: true + }, + manipulation: { + enabled: false, + initiallyActive: false + }, + physics: { + enabled: true, + barnesHut: { + //theta: [0.5, 0.1, 1, 0.05], + gravitationalConstant: [-2000, -30000, 0, 50], + centralGravity: [0.3, 0, 10, 0.05], + springLength: [95, 0, 500, 5], + springConstant: [0.04, 0, 1.2, 0.005], + damping: [0.09, 0, 1, 0.01], + avoidOverlap: [0, 0, 1, 0.01] + }, + forceAtlas2Based: { + //theta: [0.5, 0.1, 1, 0.05], + gravitationalConstant: [-50, -500, 0, 1], + centralGravity: [0.01, 0, 1, 0.005], + springLength: [95, 0, 500, 5], + springConstant: [0.08, 0, 1.2, 0.005], + damping: [0.4, 0, 1, 0.01], + avoidOverlap: [0, 0, 1, 0.01] + }, + repulsion: { + centralGravity: [0.2, 0, 10, 0.05], + springLength: [200, 0, 500, 5], + springConstant: [0.05, 0, 1.2, 0.005], + nodeDistance: [100, 0, 500, 5], + damping: [0.09, 0, 1, 0.01] + }, + hierarchicalRepulsion: { + centralGravity: [0.2, 0, 10, 0.05], + springLength: [100, 0, 500, 5], + springConstant: [0.01, 0, 1.2, 0.005], + nodeDistance: [120, 0, 500, 5], + damping: [0.09, 0, 1, 0.01] + }, + maxVelocity: [50, 0, 150, 1], + minVelocity: [0.1, 0.01, 0.5, 0.01], + solver: ['barnesHut', 'forceAtlas2Based', 'repulsion', 'hierarchicalRepulsion'], + timestep: [0.5, 0.01, 1, 0.01], + //adaptiveTimestep: true + } +}; + +export {allOptions, configureOptions}; From e07d68fe8108685a5480b33b7f82224c17221b04 Mon Sep 17 00:00:00 2001 From: Wim Rijnders Date: Wed, 24 May 2017 16:01:35 +0200 Subject: [PATCH 2/9] Added unit test for Graph3d, for checking default syntax; completed def's of all options, autoByDefault not handled yet. --- lib/graph3d/Graph3d.js | 7 ++- lib/graph3d/options.js | 138 +++++++++++++++++++++++++++++++++-------- test/Graph3d.test.js | 21 +++++++ 3 files changed, 138 insertions(+), 28 deletions(-) create mode 100644 test/Graph3d.test.js diff --git a/lib/graph3d/Graph3d.js b/lib/graph3d/Graph3d.js index bde90c903..815eac452 100755 --- a/lib/graph3d/Graph3d.js +++ b/lib/graph3d/Graph3d.js @@ -37,7 +37,7 @@ var autoByDefault = undefined; * If a field is not in this list, a default value of 'autoByDefault' is assumed, * which is just an alias for 'undefined'. */ -var DEFAULTS = { +Graph3d.DEFAULTS = { width : '400px', height : '400px', filterLabel : 'time', @@ -157,7 +157,7 @@ function Graph3d(container, data, options) { // create a frame and canvas this.create(); - Settings.setDefaults(DEFAULTS, this); + Settings.setDefaults(Graph3d.DEFAULTS, this); // the column indexes this.colX = undefined; @@ -894,7 +894,8 @@ Graph3d.prototype.setData = function (data) { * @param {Object} options */ Graph3d.prototype.setOptions = function (options) { - if (options === undefined) return + if (options === undefined) return; + let errorFound = Validator.validate(options, allOptions); if (errorFound === true) { console.log('%cErrors have been found in the supplied options object.', printStyle); diff --git a/lib/graph3d/options.js b/lib/graph3d/options.js index 76522546d..e9d10f363 100644 --- a/lib/graph3d/options.js +++ b/lib/graph3d/options.js @@ -5,41 +5,129 @@ * __any__ means that the name of the property does not matter. * __type__ is a required field for all objects and contains the allowed types of all objects */ -let string = 'string'; -let bool = 'boolean'; -let number = 'number'; -let array = 'array'; -let object = 'object'; // should only be in a __type__ property -let dom = 'dom'; -let any = 'any'; +let string = 'string'; +let bool = 'boolean'; +let number = 'number'; +let array = 'array'; +let object = 'object'; // should only be in a __type__ property +let dom = 'dom'; +let any = 'any'; +let colorOptions = { + fill : { string }, + stroke : { string }, + strokeWidth: { number }, + __type__ : { string, object } +}; + + +/** + * Order attempted to be alphabetical. + * - x/y/z-prefixes ignored in sorting + * - __type__ always at end + * - globals at end + */ let allOptions = { - filterLabel: { string }, - verticalRatio: { number }, - keepAspectRatio: { boolean: bool }, - showGrid: { boolean: bool }, - showPerspective: { boolean: bool }, - showShadow: { boolean: bool }, - style: { string: [ - 'bar', - 'bar-color', - 'bar-size', - 'dot', - 'dot-line', - 'dot-color', - 'dot-size', - 'line', - 'grid', - 'surface' - ] }, + animationAutoStart: { boolean: bool }, + animationInterval : { number }, + animationPreload : { boolean: bool }, + axisColor : { string }, + backgroundColor : { __type__: { string, object} }, + xBarWidth : { number }, + yBarWidth : { number }, + cameraPosition : { + distance : { number }, + horizontal: { number }, + vertical : { number }, + __type__ : { object } + }, + xCenter : { string }, + yCenter : { string }, + dataColor : colorOptions, + dotSizeMinFraction: { number }, + dotSizeMaxFraction: { number }, + dotSizeRatio : { number }, + filterLabel : { string }, + gridColor : { string }, + keepAspectRatio : { boolean: bool }, + xLabel : { string }, + yLabel : { string }, + zLabel : { string }, + legendLabel : { string }, + xMin : { number }, + yMin : { number }, + zMin : { number }, + xMax : { number }, + yMax : { number }, + zMax : { number }, + showAnimationControls: { boolean: bool }, + showGrid : { boolean: bool }, + showLegend : { boolean: bool }, + showPerspective : { boolean: bool }, + showShadow : { boolean: bool }, + showXAxis : { boolean: bool }, + showYAxis : { boolean: bool }, + showZAxis : { boolean: bool }, + xStep : { number }, + yStep : { number }, + zStep : { number }, + style: { + number, // TODO: either Graph3d.DEFAULT has string, or number allowed in documentation + string: [ + 'bar', + 'bar-color', + 'bar-size', + 'dot', + 'dot-line', + 'dot-color', + 'dot-size', + 'line', + 'grid', + 'surface' + ] + }, + tooltip : { boolean: bool, 'function': 'function' }, + tooltipStyle : { + content: { + color : { string }, + background : { string }, + border : { string }, + borderRadius: { string }, + boxShadow : { string }, + padding : { string }, + __type__ : { object } + }, + line: { + borderLeft: { string }, + height : { string }, + width : { string }, + __type__ : { object } + }, + dot: { + border : { string }, + borderRadius: { string }, + height : { string }, + width : { string }, + __type__ : { object}, + }, + __type__: { object} + }, + xValueLabel : { 'function': 'function' }, + yValueLabel : { 'function': 'function' }, + zValueLabel : { 'function': 'function' }, + valueMax : { number }, + valueMin : { number }, + verticalRatio : { number }, //globals : height: { string }, width: { string }, __type__: { object }, // TODO this should be the final item in options; remove the comma when done +// // Options copied from 'network' - TODO remove these! +// configure: { enabled: { boolean: bool }, filter: { boolean: bool, string, array, 'function': 'function' }, diff --git a/test/Graph3d.test.js b/test/Graph3d.test.js new file mode 100644 index 000000000..d9cca6730 --- /dev/null +++ b/test/Graph3d.test.js @@ -0,0 +1,21 @@ +var assert = require('assert'); +var vis = require('../dist/vis'); +var Graph3d = vis.Graph3d; +var Validator = require("./../lib/shared/Validator").default; +var {printStyle} = require('./../lib/shared/Validator'); +var {allOptions, configureOptions} = require('./../lib/graph3d/options.js'); + +var now = new Date(); + +describe('Graph3d', function () { + it('should pass validation for the default options', function () { + assert(Graph3d.DEFAULTS !== undefined); + + let errorFound = Validator.validate(Graph3d.DEFAULTS, allOptions); + assert(!errorFound); + if (errorFound === true) { + console.log('%cErrors have been found in the DEFAULTS options object.', printStyle); + } + }); + +}); From 95ef79bbc690b783b19ceff850e7b0404acaecbb Mon Sep 17 00:00:00 2001 From: Wim Rijnders Date: Thu, 25 May 2017 08:36:52 +0200 Subject: [PATCH 3/9] Fixes for options in playground example --- examples/graph3d/playground/playground.js | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/examples/graph3d/playground/playground.js b/examples/graph3d/playground/playground.js index 6b2ee04f3..04c1b0cdc 100644 --- a/examples/graph3d/playground/playground.js +++ b/examples/graph3d/playground/playground.js @@ -400,7 +400,7 @@ function getDataDatasource() { * Retrieve a JSON object with all options */ function getOptions() { - return { + var options = { width: document.getElementById("width").value, height: document.getElementById("height").value, style: document.getElementById("style").value, @@ -413,8 +413,8 @@ function getOptions() { showLegend: (document.getElementById("showLegend").checked != false), showShadow: (document.getElementById("showShadow").checked != false), keepAspectRatio: (document.getElementById("keepAspectRatio").checked != false), - verticalRatio: document.getElementById("verticalRatio").value, - animationInterval: document.getElementById("animationInterval").value, + verticalRatio: Number(document.getElementById("verticalRatio").value) || undefined, + animationInterval: Number(document.getElementById("animationInterval").value) || undefined, xLabel: document.getElementById("xLabel").value, yLabel: document.getElementById("yLabel").value, zLabel: document.getElementById("zLabel").value, @@ -423,8 +423,8 @@ function getOptions() { animationPreload: (document.getElementById("animationPreload").checked != false), animationAutoStart:(document.getElementById("animationAutoStart").checked != false), - xCenter: Number(document.getElementById("xCenter").value) || undefined, - yCenter: Number(document.getElementById("yCenter").value) || undefined, + xCenter: document.getElementById("xCenter").value, + yCenter: document.getElementById("yCenter").value, xMin: Number(document.getElementById("xMin").value) || undefined, xMax: Number(document.getElementById("xMax").value) || undefined, @@ -442,6 +442,15 @@ function getOptions() { xBarWidth: Number(document.getElementById("xBarWidth").value) || undefined, yBarWidth: Number(document.getElementById("yBarWidth").value) || undefined }; + + // Remove all options explicitly set to undefined + for (let opt in options) { + if (options.hasOwnProperty(opt) && options[opt] === undefined) { + delete options[opt]; + } + } + + return options; } /** From 8df2388f9f6aaef9ab3ab3bde4d4251a27879007 Mon Sep 17 00:00:00 2001 From: Wim Rijnders Date: Thu, 25 May 2017 09:42:21 +0200 Subject: [PATCH 4/9] Added onclick options to graph3d documentation --- docs/graph3d/index.html | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/docs/graph3d/index.html b/docs/graph3d/index.html index 69d28ad62..282a23799 100644 --- a/docs/graph3d/index.html +++ b/docs/graph3d/index.html @@ -427,6 +427,24 @@

Configuration Options

both have the same, maximum with. + + onclick + function + none + Event handler for a click event with signature function onclick(point).
+ Parameter point contains data for the nearest graph element relative to the click in + the line of sight. It is an object with the fields: +
    +
  • id - id of nearest node to the click
  • +
  • x - x-coordinate in graph units
  • +
  • y - y-coordinate in graph units
  • +
  • z - z-coordinate in graph units
  • +
  • style - if present, the data value for this point
  • +
+ + + + showAnimationControls boolean From 80a3a09b3dd82d46409709c534de02175a8bca2c Mon Sep 17 00:00:00 2001 From: Wim Rijnders Date: Thu, 25 May 2017 09:52:46 +0200 Subject: [PATCH 5/9] Fixes in graph3d examples --- examples/graph3d/04_animation.html | 3 +-- examples/graph3d/10_styling.html | 7 +++++++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/examples/graph3d/04_animation.html b/examples/graph3d/04_animation.html index b9c81515f..ec4c46296 100644 --- a/examples/graph3d/04_animation.html +++ b/examples/graph3d/04_animation.html @@ -51,8 +51,7 @@ keepAspectRatio: true, verticalRatio: 0.5, animationInterval: 100, // milliseconds - animationPreload: true, - filterValue: 'time' + animationPreload: true }; // create our graph diff --git a/examples/graph3d/10_styling.html b/examples/graph3d/10_styling.html index 23b08c44e..62a993a57 100644 --- a/examples/graph3d/10_styling.html +++ b/examples/graph3d/10_styling.html @@ -58,6 +58,13 @@ keepAspectRatio: true, verticalRatio: 0.5 }; + + // Remove all options explicitly set to undefined + for (let opt in options) { + if (options.hasOwnProperty(opt) && options[opt] === undefined) { + delete options[opt]; + } + } var camera = graph ? graph.getCameraPosition() : null; From 6aa3492cf6038bfe690cd6d4b43e4d35ae8e3cb4 Mon Sep 17 00:00:00 2001 From: Wim Rijnders Date: Thu, 25 May 2017 09:53:12 +0200 Subject: [PATCH 6/9] Final fixes for option definitions in Graph3d --- lib/graph3d/Graph3d.js | 25 +- lib/graph3d/options.js | 601 +---------------------------------------- 2 files changed, 23 insertions(+), 603 deletions(-) diff --git a/lib/graph3d/Graph3d.js b/lib/graph3d/Graph3d.js index 815eac452..4b7dbcafe 100755 --- a/lib/graph3d/Graph3d.js +++ b/lib/graph3d/Graph3d.js @@ -11,7 +11,7 @@ var Range = require('./Range'); var Settings = require('./Settings'); var Validator = require("./../shared/Validator").default; var {printStyle} = require('./../shared/Validator'); -var {allOptions, configureOptions} = require('./options.js'); +var {allOptions} = require('./options.js'); /// enumerate the available styles @@ -24,9 +24,13 @@ Graph3d.STYLE = Settings.STYLE; * * Using 'undefined' directly achieves the same thing, but this is more * descriptive by describing the intent. - */ + * + * Value not used any more in code; this comment block now serves as reference. + var autoByDefault = undefined; + */ + /** * Default values for option settings. @@ -61,10 +65,8 @@ Graph3d.DEFAULTS = { dotSizeMinFraction: 0.5, // size of min-value dot as a fraction of dotSizeRatio dotSizeMaxFraction: 2.5, // size of max-value dot as a fraction of dotSizeRatio - showAnimationControls: autoByDefault, animationInterval : 1000, // milliseconds animationPreload : false, - animationAutoStart : autoByDefault, axisColor : '#4D4D4D', gridColor : '#D3D3D3', @@ -96,8 +98,6 @@ Graph3d.DEFAULTS = { } }, - showLegend : autoByDefault, // determined by graph style - backgroundColor : autoByDefault, dataColor : { fill : '#7DC1FF', @@ -111,6 +111,18 @@ Graph3d.DEFAULTS = { distance : 1.7 }, + +/* + The following fields are 'auto by default', see above. + The explicit setting of the fields has been disabled, because the + Validator module can't handle 'undefined' as set value. + + showAnimationControls: autoByDefault, + animationAutoStart : autoByDefault, + + showLegend : autoByDefault, // determined by graph style + backgroundColor : autoByDefault, + xBarWidth : autoByDefault, yBarWidth : autoByDefault, valueMin : autoByDefault, @@ -124,6 +136,7 @@ Graph3d.DEFAULTS = { zMin : autoByDefault, zMax : autoByDefault, zStep : autoByDefault +*/ }; diff --git a/lib/graph3d/options.js b/lib/graph3d/options.js index e9d10f363..fe19be5ad 100644 --- a/lib/graph3d/options.js +++ b/lib/graph3d/options.js @@ -33,7 +33,7 @@ let allOptions = { animationInterval : { number }, animationPreload : { boolean: bool }, axisColor : { string }, - backgroundColor : { __type__: { string, object} }, + backgroundColor : colorOptions, xBarWidth : { number }, yBarWidth : { number }, cameraPosition : { @@ -50,6 +50,7 @@ let allOptions = { dotSizeRatio : { number }, filterLabel : { string }, gridColor : { string }, + onclick : { 'function': 'function' }, keepAspectRatio : { boolean: bool }, xLabel : { string }, yLabel : { string }, @@ -123,602 +124,8 @@ let allOptions = { //globals : height: { string }, width: { string }, - __type__: { object }, // TODO this should be the final item in options; remove the comma when done - -// -// Options copied from 'network' - TODO remove these! -// - configure: { - enabled: { boolean: bool }, - filter: { boolean: bool, string, array, 'function': 'function' }, - container: { dom }, - showButton: { boolean: bool }, - __type__: { object, boolean: bool, string, array, 'function': 'function' } - }, - edges: { - arrows: { - to: { enabled: { boolean: bool }, scaleFactor: { number }, type: { string: ['arrow', 'circle'] }, __type__: { object, boolean: bool } }, - middle: { enabled: { boolean: bool }, scaleFactor: { number }, type: { string: ['arrow', 'circle'] }, __type__: { object, boolean: bool } }, - from: { enabled: { boolean: bool }, scaleFactor: { number }, type: { string: ['arrow', 'circle'] }, __type__: { object, boolean: bool } }, - __type__: { string: ['from', 'to', 'middle'], object } - }, - arrowStrikethrough: { boolean: bool }, - chosen: { - label: { boolean: bool, 'function': 'function' }, - edge: { boolean: bool, 'function': 'function' }, - __type__: { object, boolean: bool } - }, - color: { - color: { string }, - highlight: { string }, - hover: { string }, - inherit: { string: ['from', 'to', 'both'], boolean: bool }, - opacity: { number }, - __type__: { object, string } - }, - dashes: { boolean: bool, array }, - font: { - color: { string }, - size: { number }, // px - face: { string }, - background: { string }, - strokeWidth: { number }, // px - strokeColor: { string }, - align: { string: ['horizontal', 'top', 'middle', 'bottom'] }, - vadjust: { number }, - multi: { boolean: bool, string }, - bold: { - color: { string }, - size: { number }, // px - face: { string }, - mod: { string }, - vadjust: { number }, - __type__: { object, string } - }, - boldital: { - color: { string }, - size: { number }, // px - face: { string }, - mod: { string }, - vadjust: { number }, - __type__: { object, string } - }, - ital: { - color: { string }, - size: { number }, // px - face: { string }, - mod: { string }, - vadjust: { number }, - __type__: { object, string } - }, - mono: { - color: { string }, - size: { number }, // px - face: { string }, - mod: { string }, - vadjust: { number }, - __type__: { object, string } - }, - __type__: { object, string } - }, - hidden: { boolean: bool }, - hoverWidth: { 'function': 'function', number }, - label: { string, 'undefined': 'undefined' }, - labelHighlightBold: { boolean: bool }, - length: { number, 'undefined': 'undefined' }, - physics: { boolean: bool }, - scaling: { - min: { number }, - max: { number }, - label: { - enabled: { boolean: bool }, - min: { number }, - max: { number }, - maxVisible: { number }, - drawThreshold: { number }, - __type__: { object, boolean: bool } - }, - customScalingFunction: { 'function': 'function' }, - __type__: { object } - }, - selectionWidth: { 'function': 'function', number }, - selfReferenceSize: { number }, - shadow: { - enabled: { boolean: bool }, - color: { string }, - size: { number }, - x: { number }, - y: { number }, - __type__: { object, boolean: bool } - }, - smooth: { - enabled: { boolean: bool }, - type: { string: ['dynamic', 'continuous', 'discrete', 'diagonalCross', 'straightCross', 'horizontal', 'vertical', 'curvedCW', 'curvedCCW', 'cubicBezier'] }, - roundness: { number }, - forceDirection: { string: ['horizontal', 'vertical', 'none'], boolean: bool }, - __type__: { object, boolean: bool } - }, - title: { string, 'undefined': 'undefined' }, - width: { number }, - widthConstraint: { - maximum: { number }, - __type__: { object, boolean: bool, number } - }, - value: { number, 'undefined': 'undefined' }, - __type__: { object } - }, - groups: { - useDefaultGroups: { boolean: bool }, - __any__: 'get from nodes, will be overwritten below', - __type__: { object } - }, - interaction: { - dragNodes: { boolean: bool }, - dragView: { boolean: bool }, - hideEdgesOnDrag: { boolean: bool }, - hideNodesOnDrag: { boolean: bool }, - hover: { boolean: bool }, - keyboard: { - enabled: { boolean: bool }, - speed: { x: { number }, y: { number }, zoom: { number }, __type__: { object } }, - bindToWindow: { boolean: bool }, - __type__: { object, boolean: bool } - }, - multiselect: { boolean: bool }, - navigationButtons: { boolean: bool }, - selectable: { boolean: bool }, - selectConnectedEdges: { boolean: bool }, - hoverConnectedEdges: { boolean: bool }, - tooltipDelay: { number }, - zoomView: { boolean: bool }, - __type__: { object } - }, - layout: { - randomSeed: { 'undefined': 'undefined', number }, - improvedLayout: { boolean: bool }, - hierarchical: { - enabled: { boolean: bool }, - levelSeparation: { number }, - nodeSpacing: { number }, - treeSpacing: { number }, - blockShifting: { boolean: bool }, - edgeMinimization: { boolean: bool }, - parentCentralization: { boolean: bool }, - direction: { string: ['UD', 'DU', 'LR', 'RL'] }, // UD, DU, LR, RL - sortMethod: { string: ['hubsize', 'directed'] }, // hubsize, directed - __type__: { object, boolean: bool } - }, - __type__: { object } - }, - manipulation: { - enabled: { boolean: bool }, - initiallyActive: { boolean: bool }, - addNode: { boolean: bool, 'function': 'function' }, - addEdge: { boolean: bool, 'function': 'function' }, - editNode: { 'function': 'function' }, - editEdge: { - editWithoutDrag: { 'function' : 'function' }, - __type__: {object, boolean: bool, 'function': 'function' } - }, - deleteNode: { boolean: bool, 'function': 'function' }, - deleteEdge: { boolean: bool, 'function': 'function' }, - controlNodeStyle: 'get from nodes, will be overwritten below', - __type__: { object, boolean: bool } - }, - nodes: { - borderWidth: { number }, - borderWidthSelected: { number, 'undefined': 'undefined' }, - brokenImage: { string, 'undefined': 'undefined' }, - chosen: { - label: { boolean: bool, 'function': 'function' }, - node: { boolean: bool, 'function': 'function' }, - __type__: { object, boolean: bool } - }, - color: { - border: { string }, - background: { string }, - highlight: { - border: { string }, - background: { string }, - __type__: { object, string } - }, - hover: { - border: { string }, - background: { string }, - __type__: { object, string } - }, - __type__: { object, string } - }, - fixed: { - x: { boolean: bool }, - y: { boolean: bool }, - __type__: { object, boolean: bool } - }, - font: { - align: { string }, - color: { string }, - size: { number }, // px - face: { string }, - background: { string }, - strokeWidth: { number }, // px - strokeColor: { string }, - vadjust: { number }, - multi: { boolean: bool, string }, - bold: { - color: { string }, - size: { number }, // px - face: { string }, - mod: { string }, - vadjust: { number }, - __type__: { object, string } - }, - boldital: { - color: { string }, - size: { number }, // px - face: { string }, - mod: { string }, - vadjust: { number }, - __type__: { object, string } - }, - ital: { - color: { string }, - size: { number }, // px - face: { string }, - mod: { string }, - vadjust: { number }, - __type__: { object, string } - }, - mono: { - color: { string }, - size: { number }, // px - face: { string }, - mod: { string }, - vadjust: { number }, - __type__: { object, string } - }, - __type__: { object, string } - }, - group: { string, number, 'undefined': 'undefined' }, - heightConstraint: { - minimum: { number }, - valign: { string }, - __type__: { object, boolean: bool, number } - }, - hidden: { boolean: bool }, - icon: { - face: { string }, - code: { string }, //'\uf007', - size: { number }, //50, - color: { string }, - __type__: { object } - }, - id: { string, number }, - image: { - selected: { string, 'undefined': 'undefined' }, // --> URL - unselected: { string, 'undefined': 'undefined' }, // --> URL - __type__: { object, string } - }, - label: { string, 'undefined': 'undefined' }, - labelHighlightBold: { boolean: bool }, - level: { number, 'undefined': 'undefined' }, - margin: { - top: { number }, - right: { number }, - bottom: { number }, - left: { number }, - __type__: { object, number } - }, - mass: { number }, - physics: { boolean: bool }, - scaling: { - min: { number }, - max: { number }, - label: { - enabled: { boolean: bool }, - min: { number }, - max: { number }, - maxVisible: { number }, - drawThreshold: { number }, - __type__: { object, boolean: bool } - }, - customScalingFunction: { 'function': 'function' }, - __type__: { object } - }, - shadow: { - enabled: { boolean: bool }, - color: { string }, - size: { number }, - x: { number }, - y: { number }, - __type__: { object, boolean: bool } - }, - shape: { string: ['ellipse', 'circle', 'database', 'box', 'text', 'image', 'circularImage', 'diamond', 'dot', 'star', 'triangle', 'triangleDown', 'square', 'icon'] }, - shapeProperties: { - borderDashes: { boolean: bool, array }, - borderRadius: { number }, - interpolation: { boolean: bool }, - useImageSize: { boolean: bool }, - useBorderWithImage: { boolean: bool }, - __type__: { object } - }, - size: { number }, - title: { string, 'undefined': 'undefined' }, - value: { number, 'undefined': 'undefined' }, - widthConstraint: { - minimum: { number }, - maximum: { number }, - __type__: { object, boolean: bool, number } - }, - x: { number }, - y: { number }, - __type__: { object } - }, - physics: { - enabled: { boolean: bool }, - barnesHut: { - gravitationalConstant: { number }, - centralGravity: { number }, - springLength: { number }, - springConstant: { number }, - damping: { number }, - avoidOverlap: { number }, - __type__: { object } - }, - forceAtlas2Based: { - gravitationalConstant: { number }, - centralGravity: { number }, - springLength: { number }, - springConstant: { number }, - damping: { number }, - avoidOverlap: { number }, - __type__: { object } - }, - repulsion: { - centralGravity: { number }, - springLength: { number }, - springConstant: { number }, - nodeDistance: { number }, - damping: { number }, - __type__: { object } - }, - hierarchicalRepulsion: { - centralGravity: { number }, - springLength: { number }, - springConstant: { number }, - nodeDistance: { number }, - damping: { number }, - __type__: { object } - }, - maxVelocity: { number }, - minVelocity: { number }, // px/s - solver: { string: ['barnesHut', 'repulsion', 'hierarchicalRepulsion', 'forceAtlas2Based'] }, - stabilization: { - enabled: { boolean: bool }, - iterations: { number }, // maximum number of iteration to stabilize - updateInterval: { number }, - onlyDynamicEdges: { boolean: bool }, - fit: { boolean: bool }, - __type__: { object, boolean: bool } - }, - timestep: { number }, - adaptiveTimestep: { boolean: bool }, - __type__: { object, boolean: bool } - }, - - //globals : - autoResize: { boolean: bool }, - clickToUse: { boolean: bool }, - locale: { string }, - locales: { - __any__: { any }, - __type__: { object } - }, + __type__: { object } }; -allOptions.groups.__any__ = allOptions.nodes; -allOptions.manipulation.controlNodeStyle = allOptions.nodes; - - -let configureOptions = { - nodes: { - borderWidth: [1, 0, 10, 1], - borderWidthSelected: [2, 0, 10, 1], - color: { - border: ['color', '#2B7CE9'], - background: ['color', '#97C2FC'], - highlight: { - border: ['color', '#2B7CE9'], - background: ['color', '#D2E5FF'] - }, - hover: { - border: ['color', '#2B7CE9'], - background: ['color', '#D2E5FF'] - } - }, - fixed: { - x: false, - y: false - }, - font: { - color: ['color', '#343434'], - size: [14, 0, 100, 1], // px - face: ['arial', 'verdana', 'tahoma'], - background: ['color', 'none'], - strokeWidth: [0, 0, 50, 1], // px - strokeColor: ['color', '#ffffff'] - }, - //group: 'string', - hidden: false, - labelHighlightBold: true, - //icon: { - // face: 'string', //'FontAwesome', - // code: 'string', //'\uf007', - // size: [50, 0, 200, 1], //50, - // color: ['color','#2B7CE9'] //'#aa00ff' - //}, - //image: 'string', // --> URL - physics: true, - scaling: { - min: [10, 0, 200, 1], - max: [30, 0, 200, 1], - label: { - enabled: false, - min: [14, 0, 200, 1], - max: [30, 0, 200, 1], - maxVisible: [30, 0, 200, 1], - drawThreshold: [5, 0, 20, 1] - } - }, - shadow: { - enabled: false, - color: 'rgba(0,0,0,0.5)', - size: [10, 0, 20, 1], - x: [5, -30, 30, 1], - y: [5, -30, 30, 1] - }, - shape: ['ellipse', 'box', 'circle', 'database', 'diamond', 'dot', 'square', 'star', 'text', 'triangle', 'triangleDown'], - shapeProperties: { - borderDashes: false, - borderRadius: [6, 0, 20, 1], - interpolation: true, - useImageSize: false - }, - size: [25, 0, 200, 1] - }, - edges: { - arrows: { - to: { enabled: false, scaleFactor: [1, 0, 3, 0.05], type: 'arrow' }, - middle: { enabled: false, scaleFactor: [1, 0, 3, 0.05], type: 'arrow' }, - from: { enabled: false, scaleFactor: [1, 0, 3, 0.05], type: 'arrow' } - }, - arrowStrikethrough: true, - color: { - color: ['color', '#848484'], - highlight: ['color', '#848484'], - hover: ['color', '#848484'], - inherit: ['from', 'to', 'both', true, false], - opacity: [1, 0, 1, 0.05] - }, - dashes: false, - font: { - color: ['color', '#343434'], - size: [14, 0, 100, 1], // px - face: ['arial', 'verdana', 'tahoma'], - background: ['color', 'none'], - strokeWidth: [2, 0, 50, 1], // px - strokeColor: ['color', '#ffffff'], - align: ['horizontal', 'top', 'middle', 'bottom'] - }, - hidden: false, - hoverWidth: [1.5, 0, 5, 0.1], - labelHighlightBold: true, - physics: true, - scaling: { - min: [1, 0, 100, 1], - max: [15, 0, 100, 1], - label: { - enabled: true, - min: [14, 0, 200, 1], - max: [30, 0, 200, 1], - maxVisible: [30, 0, 200, 1], - drawThreshold: [5, 0, 20, 1] - } - }, - selectionWidth: [1.5, 0, 5, 0.1], - selfReferenceSize: [20, 0, 200, 1], - shadow: { - enabled: false, - color: 'rgba(0,0,0,0.5)', - size: [10, 0, 20, 1], - x: [5, -30, 30, 1], - y: [5, -30, 30, 1] - }, - smooth: { - enabled: true, - type: ['dynamic', 'continuous', 'discrete', 'diagonalCross', 'straightCross', 'horizontal', 'vertical', 'curvedCW', 'curvedCCW', 'cubicBezier'], - forceDirection: ['horizontal', 'vertical', 'none'], - roundness: [0.5, 0, 1, 0.05] - }, - width: [1, 0, 30, 1] - }, - layout: { - //randomSeed: [0, 0, 500, 1], - //improvedLayout: true, - hierarchical: { - enabled: false, - levelSeparation: [150, 20, 500, 5], - nodeSpacing: [100, 20, 500, 5], - treeSpacing: [200, 20, 500, 5], - blockShifting: true, - edgeMinimization: true, - parentCentralization: true, - direction: ['UD', 'DU', 'LR', 'RL'], // UD, DU, LR, RL - sortMethod: ['hubsize', 'directed'] // hubsize, directed - } - }, - interaction: { - dragNodes: true, - dragView: true, - hideEdgesOnDrag: false, - hideNodesOnDrag: false, - hover: false, - keyboard: { - enabled: false, - speed: { x: [10, 0, 40, 1], y: [10, 0, 40, 1], zoom: [0.02, 0, 0.1, 0.005] }, - bindToWindow: true - }, - multiselect: false, - navigationButtons: false, - selectable: true, - selectConnectedEdges: true, - hoverConnectedEdges: true, - tooltipDelay: [300, 0, 1000, 25], - zoomView: true - }, - manipulation: { - enabled: false, - initiallyActive: false - }, - physics: { - enabled: true, - barnesHut: { - //theta: [0.5, 0.1, 1, 0.05], - gravitationalConstant: [-2000, -30000, 0, 50], - centralGravity: [0.3, 0, 10, 0.05], - springLength: [95, 0, 500, 5], - springConstant: [0.04, 0, 1.2, 0.005], - damping: [0.09, 0, 1, 0.01], - avoidOverlap: [0, 0, 1, 0.01] - }, - forceAtlas2Based: { - //theta: [0.5, 0.1, 1, 0.05], - gravitationalConstant: [-50, -500, 0, 1], - centralGravity: [0.01, 0, 1, 0.005], - springLength: [95, 0, 500, 5], - springConstant: [0.08, 0, 1.2, 0.005], - damping: [0.4, 0, 1, 0.01], - avoidOverlap: [0, 0, 1, 0.01] - }, - repulsion: { - centralGravity: [0.2, 0, 10, 0.05], - springLength: [200, 0, 500, 5], - springConstant: [0.05, 0, 1.2, 0.005], - nodeDistance: [100, 0, 500, 5], - damping: [0.09, 0, 1, 0.01] - }, - hierarchicalRepulsion: { - centralGravity: [0.2, 0, 10, 0.05], - springLength: [100, 0, 500, 5], - springConstant: [0.01, 0, 1.2, 0.005], - nodeDistance: [120, 0, 500, 5], - damping: [0.09, 0, 1, 0.01] - }, - maxVelocity: [50, 0, 150, 1], - minVelocity: [0.1, 0.01, 0.5, 0.01], - solver: ['barnesHut', 'forceAtlas2Based', 'repulsion', 'hierarchicalRepulsion'], - timestep: [0.5, 0.01, 1, 0.01], - //adaptiveTimestep: true - } -}; -export {allOptions, configureOptions}; +export {allOptions}; From 49c4476d92aefcc5d74e4a0036ca45d6452349ea Mon Sep 17 00:00:00 2001 From: Wim Rijnders Date: Sun, 4 Jun 2017 08:43:56 +0200 Subject: [PATCH 7/9] Fixed handling of 'undefined' in options, enhanced graph3d unit test --- examples/graph3d/10_styling.html | 7 ----- examples/graph3d/playground/playground.js | 7 ----- lib/graph3d/Graph3d.js | 16 +++-------- lib/graph3d/options.js | 34 +++++++++++------------ package.json | 3 +- test/Graph3d.test.js | 19 ++++++++----- 6 files changed, 35 insertions(+), 51 deletions(-) diff --git a/examples/graph3d/10_styling.html b/examples/graph3d/10_styling.html index 62a993a57..bd3eb5bbe 100644 --- a/examples/graph3d/10_styling.html +++ b/examples/graph3d/10_styling.html @@ -59,13 +59,6 @@ verticalRatio: 0.5 }; - // Remove all options explicitly set to undefined - for (let opt in options) { - if (options.hasOwnProperty(opt) && options[opt] === undefined) { - delete options[opt]; - } - } - var camera = graph ? graph.getCameraPosition() : null; // create our graph diff --git a/examples/graph3d/playground/playground.js b/examples/graph3d/playground/playground.js index 04c1b0cdc..8cdb07292 100644 --- a/examples/graph3d/playground/playground.js +++ b/examples/graph3d/playground/playground.js @@ -443,13 +443,6 @@ function getOptions() { yBarWidth: Number(document.getElementById("yBarWidth").value) || undefined }; - // Remove all options explicitly set to undefined - for (let opt in options) { - if (options.hasOwnProperty(opt) && options[opt] === undefined) { - delete options[opt]; - } - } - return options; } diff --git a/lib/graph3d/Graph3d.js b/lib/graph3d/Graph3d.js index 4b7dbcafe..9348ae586 100755 --- a/lib/graph3d/Graph3d.js +++ b/lib/graph3d/Graph3d.js @@ -24,12 +24,8 @@ Graph3d.STYLE = Settings.STYLE; * * Using 'undefined' directly achieves the same thing, but this is more * descriptive by describing the intent. - * - * Value not used any more in code; this comment block now serves as reference. - -var autoByDefault = undefined; - */ +var autoByDefault = undefined; /** @@ -65,8 +61,10 @@ Graph3d.DEFAULTS = { dotSizeMinFraction: 0.5, // size of min-value dot as a fraction of dotSizeRatio dotSizeMaxFraction: 2.5, // size of max-value dot as a fraction of dotSizeRatio + showAnimationControls: autoByDefault, animationInterval : 1000, // milliseconds animationPreload : false, + animationAutoStart : autoByDefault, axisColor : '#4D4D4D', gridColor : '#D3D3D3', @@ -114,12 +112,7 @@ Graph3d.DEFAULTS = { /* The following fields are 'auto by default', see above. - The explicit setting of the fields has been disabled, because the - Validator module can't handle 'undefined' as set value. - - showAnimationControls: autoByDefault, - animationAutoStart : autoByDefault, - + */ showLegend : autoByDefault, // determined by graph style backgroundColor : autoByDefault, @@ -136,7 +129,6 @@ Graph3d.DEFAULTS = { zMin : autoByDefault, zMax : autoByDefault, zStep : autoByDefault -*/ }; diff --git a/lib/graph3d/options.js b/lib/graph3d/options.js index fe19be5ad..6c3f7ccfb 100644 --- a/lib/graph3d/options.js +++ b/lib/graph3d/options.js @@ -18,7 +18,7 @@ let colorOptions = { fill : { string }, stroke : { string }, strokeWidth: { number }, - __type__ : { string, object } + __type__ : { string, object, 'undefined': 'undefined' } }; @@ -29,13 +29,13 @@ let colorOptions = { * - globals at end */ let allOptions = { - animationAutoStart: { boolean: bool }, + animationAutoStart: { boolean: bool, 'undefined': 'undefined' }, animationInterval : { number }, animationPreload : { boolean: bool }, axisColor : { string }, backgroundColor : colorOptions, - xBarWidth : { number }, - yBarWidth : { number }, + xBarWidth : { number, 'undefined': 'undefined' }, + yBarWidth : { number, 'undefined': 'undefined' }, cameraPosition : { distance : { number }, horizontal: { number }, @@ -56,23 +56,23 @@ let allOptions = { yLabel : { string }, zLabel : { string }, legendLabel : { string }, - xMin : { number }, - yMin : { number }, - zMin : { number }, - xMax : { number }, - yMax : { number }, - zMax : { number }, - showAnimationControls: { boolean: bool }, + xMin : { number, 'undefined': 'undefined' }, + yMin : { number, 'undefined': 'undefined' }, + zMin : { number, 'undefined': 'undefined' }, + xMax : { number, 'undefined': 'undefined' }, + yMax : { number, 'undefined': 'undefined' }, + zMax : { number, 'undefined': 'undefined' }, + showAnimationControls: { boolean: bool, 'undefined': 'undefined' }, showGrid : { boolean: bool }, - showLegend : { boolean: bool }, + showLegend : { boolean: bool, 'undefined': 'undefined' }, showPerspective : { boolean: bool }, showShadow : { boolean: bool }, showXAxis : { boolean: bool }, showYAxis : { boolean: bool }, showZAxis : { boolean: bool }, - xStep : { number }, - yStep : { number }, - zStep : { number }, + xStep : { number, 'undefined': 'undefined' }, + yStep : { number, 'undefined': 'undefined' }, + zStep : { number, 'undefined': 'undefined' }, style: { number, // TODO: either Graph3d.DEFAULT has string, or number allowed in documentation string: [ @@ -117,8 +117,8 @@ let allOptions = { xValueLabel : { 'function': 'function' }, yValueLabel : { 'function': 'function' }, zValueLabel : { 'function': 'function' }, - valueMax : { number }, - valueMin : { number }, + valueMax : { number, 'undefined': 'undefined' }, + valueMin : { number, 'undefined': 'undefined' }, verticalRatio : { number }, //globals : diff --git a/package.json b/package.json index e1d285ee7..fb07a3609 100644 --- a/package.json +++ b/package.json @@ -63,6 +63,7 @@ "uglify-js": "^2.7.5", "uuid": "^3.0.1", "webpack": "^1.14.0", - "yargs": "^6.6.0" + "yargs": "^6.6.0", + "test-console": "^1.0.0" } } diff --git a/test/Graph3d.test.js b/test/Graph3d.test.js index d9cca6730..a15aaa60e 100644 --- a/test/Graph3d.test.js +++ b/test/Graph3d.test.js @@ -1,21 +1,26 @@ var assert = require('assert'); var vis = require('../dist/vis'); var Graph3d = vis.Graph3d; +var stdout = require('test-console').stdout; var Validator = require("./../lib/shared/Validator").default; -var {printStyle} = require('./../lib/shared/Validator'); +//var {printStyle} = require('./../lib/shared/Validator'); var {allOptions, configureOptions} = require('./../lib/graph3d/options.js'); var now = new Date(); describe('Graph3d', function () { it('should pass validation for the default options', function () { - assert(Graph3d.DEFAULTS !== undefined); + assert(Graph3d.DEFAULTS !== undefined); - let errorFound = Validator.validate(Graph3d.DEFAULTS, allOptions); - assert(!errorFound); - if (errorFound === true) { - console.log('%cErrors have been found in the DEFAULTS options object.', printStyle); - } + let errorFound; + let output; + output = stdout.inspectSync(function() { + errorFound = Validator.validate(Graph3d.DEFAULTS, allOptions); + }); + if (errorFound === true) { + console.log(JSON.stringify(output, null, 2)); + } + assert(!errorFound, 'DEFAULTS options object does not pass validation'); }); }); From cd1c203267dc560ea9cc991fba35af63d3e4c7e0 Mon Sep 17 00:00:00 2001 From: Wim Rijnders Date: Sun, 4 Jun 2017 08:50:14 +0200 Subject: [PATCH 8/9] Disabled console output in graph3d unit test --- test/Graph3d.test.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/test/Graph3d.test.js b/test/Graph3d.test.js index a15aaa60e..335fe61bf 100644 --- a/test/Graph3d.test.js +++ b/test/Graph3d.test.js @@ -17,9 +17,11 @@ describe('Graph3d', function () { output = stdout.inspectSync(function() { errorFound = Validator.validate(Graph3d.DEFAULTS, allOptions); }); - if (errorFound === true) { - console.log(JSON.stringify(output, null, 2)); - } + + // Useful during debugging: + //if (errorFound === true) { + // console.log(JSON.stringify(output, null, 2)); + //} assert(!errorFound, 'DEFAULTS options object does not pass validation'); }); From ef2b339bdb150081dfc021db5d21b8456cee6fed Mon Sep 17 00:00:00 2001 From: Wim Rijnders Date: Mon, 17 Jul 2017 09:00:06 +0200 Subject: [PATCH 9/9] Upgrade webpack module --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index c9e92a450..dcad9ccfe 100644 --- a/package.json +++ b/package.json @@ -68,7 +68,7 @@ "test-console": "^1.0.0", "uglify-js": "^2.7.5", "uuid": "^3.0.1", - "webpack": "^1.14.0", + "webpack": "^2.0.0", "yargs": "^6.6.0" } }