diff --git a/.eslintrc b/.eslintrc
index 090d93088..6fdb6ec65 100644
--- a/.eslintrc
+++ b/.eslintrc
@@ -16,10 +16,10 @@
"complexity": [2, 55],
"max-statements": [2, 115],
"no-unreachable": 1,
- "no-useless-escape": 0,
+ "no-console": 0,
+ "no-useless-escape": 0
/*
// some disabled options which might be useful
- "no-console": 0,
"no-empty": 0,
"no-extra-semi": 0,
"no-fallthrough": 0,
diff --git a/docs/graph3d/index.html b/docs/graph3d/index.html
index 902cd4eb9..19e63b9bd 100644
--- a/docs/graph3d/index.html
+++ b/docs/graph3d/index.html
@@ -441,6 +441,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 |
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..bd3eb5bbe 100644
--- a/examples/graph3d/10_styling.html
+++ b/examples/graph3d/10_styling.html
@@ -58,7 +58,7 @@
keepAspectRatio: true,
verticalRatio: 0.5
};
-
+
var camera = graph ? graph.getCameraPosition() : null;
// create our graph
diff --git a/examples/graph3d/playground/playground.js b/examples/graph3d/playground/playground.js
index 6b2ee04f3..8cdb07292 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,8 @@ function getOptions() {
xBarWidth: Number(document.getElementById("xBarWidth").value) || undefined,
yBarWidth: Number(document.getElementById("yBarWidth").value) || undefined
};
+
+ return options;
}
/**
diff --git a/lib/graph3d/Graph3d.js b/lib/graph3d/Graph3d.js
index 7c8209304..acfb7a285 100755
--- a/lib/graph3d/Graph3d.js
+++ b/lib/graph3d/Graph3d.js
@@ -5,6 +5,9 @@ var Point2d = require('./Point2d');
var Slider = require('./Slider');
var StepNumber = require('./StepNumber');
var Settings = require('./Settings');
+var Validator = require("./../shared/Validator").default;
+var {printStyle} = require('./../shared/Validator');
+var {allOptions} = require('./options.js');
var DataGroup = require('./DataGroup');
@@ -31,7 +34,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',
@@ -90,8 +93,6 @@ var DEFAULTS = {
}
},
- showLegend : autoByDefault, // determined by graph style
- backgroundColor : autoByDefault,
dataColor : {
fill : '#7DC1FF',
@@ -105,6 +106,13 @@ var DEFAULTS = {
distance : 1.7
},
+
+/*
+ The following fields are 'auto by default', see above.
+ */
+ showLegend : autoByDefault, // determined by graph style
+ backgroundColor : autoByDefault,
+
xBarWidth : autoByDefault,
yBarWidth : autoByDefault,
valueMin : autoByDefault,
@@ -151,7 +159,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;
@@ -628,6 +636,13 @@ 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);
+ }
+
this.animationStop();
Settings.setOptions(options, this);
diff --git a/lib/graph3d/options.js b/lib/graph3d/options.js
new file mode 100644
index 000000000..95ff370c7
--- /dev/null
+++ b/lib/graph3d/options.js
@@ -0,0 +1,132 @@
+/**
+ * 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 object = 'object'; // should only be in a __type__ property
+// Following not used here, but useful for reference
+//let array = 'array';
+//let dom = 'dom';
+//let any = 'any';
+
+
+let colorOptions = {
+ fill : { string },
+ stroke : { string },
+ strokeWidth: { number },
+ __type__ : { string, object, 'undefined': 'undefined' }
+};
+
+
+/**
+ * Order attempted to be alphabetical.
+ * - x/y/z-prefixes ignored in sorting
+ * - __type__ always at end
+ * - globals at end
+ */
+let allOptions = {
+ animationAutoStart: { boolean: bool, 'undefined': 'undefined' },
+ animationInterval : { number },
+ animationPreload : { boolean: bool },
+ axisColor : { string },
+ backgroundColor : colorOptions,
+ xBarWidth : { number, 'undefined': 'undefined' },
+ yBarWidth : { number, 'undefined': 'undefined' },
+ 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 },
+ onclick : { 'function': 'function' },
+ keepAspectRatio : { boolean: bool },
+ xLabel : { string },
+ yLabel : { string },
+ zLabel : { string },
+ legendLabel : { string },
+ 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, 'undefined': 'undefined' },
+ showPerspective : { boolean: bool },
+ showShadow : { boolean: bool },
+ showXAxis : { boolean: bool },
+ showYAxis : { boolean: bool },
+ showZAxis : { boolean: bool },
+ 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: [
+ '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, 'undefined': 'undefined' },
+ valueMin : { number, 'undefined': 'undefined' },
+ verticalRatio : { number },
+
+ //globals :
+ height: { string },
+ width: { string },
+ __type__: { object }
+};
+
+
+export {allOptions};
diff --git a/test/Graph3d.test.js b/test/Graph3d.test.js
index 1da5c856c..c6fa5bf0c 100644
--- a/test/Graph3d.test.js
+++ b/test/Graph3d.test.js
@@ -1,11 +1,15 @@
var assert = require('assert');
-var jsdom_global = require('jsdom-global');
var vis = require('../dist/vis');
var Graph3d = vis.Graph3d;
+var jsdom_global = require('jsdom-global');
+var stdout = require('test-console').stdout;
+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 () {
-
before(function() {
//console.log('before!');
this.jsdom_global = jsdom_global(
@@ -15,6 +19,24 @@ describe('Graph3d', function () {
this.container = document.getElementById('mynetwork');
});
+
+ it('should pass validation for the default options', function () {
+ assert(Graph3d.DEFAULTS !== undefined);
+
+ let errorFound;
+ let output;
+ output = stdout.inspectSync(function() {
+ errorFound = Validator.validate(Graph3d.DEFAULTS, allOptions);
+ });
+
+ // Useful during debugging:
+ //if (errorFound === true) {
+ // console.log(JSON.stringify(output, null, 2));
+ //}
+ assert(!errorFound, 'DEFAULTS options object does not pass validation');
+ });
+
+
it('accepts new option values on defined instance', function () {
assert(this.container !== null, 'Container div not found');