diff --git a/.eslintrc b/.eslintrc index 090d9308..6fdb6ec6 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 902cd4eb..19e63b9b 100644 --- a/docs/graph3d/index.html +++ b/docs/graph3d/index.html @@ -441,6 +441,24 @@ var 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: + + + + + showAnimationControls boolean diff --git a/examples/graph3d/04_animation.html b/examples/graph3d/04_animation.html index b9c81515..ec4c4629 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 23b08c44..bd3eb5bb 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 6b2ee04f..8cdb0729 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 7c820930..acfb7a28 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 00000000..95ff370c --- /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 1da5c856..c6fa5bf0 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');