Skip to content

Commit 7ed38ea

Browse files
wimrijndersPrimoz Susa
authored andcommitted
Add option definitions and validation to Graph3d (visjs#3099)
* Proof of concept with copied options + handling from network * Added unit test for Graph3d, for checking default syntax; completed def's of all options, autoByDefault not handled yet. * Fixes for options in playground example * Added onclick options to graph3d documentation * Fixes in graph3d examples * Final fixes for option definitions in Graph3d * Fixed handling of 'undefined' in options, enhanced graph3d unit test * Disabled console output in graph3d unit test * Upgrade webpack module
1 parent 5d8b656 commit 7ed38ea

File tree

8 files changed

+204
-16
lines changed

8 files changed

+204
-16
lines changed

.eslintrc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,10 @@
1616
"complexity": [2, 55],
1717
"max-statements": [2, 115],
1818
"no-unreachable": 1,
19-
"no-useless-escape": 0,
19+
"no-console": 0,
20+
"no-useless-escape": 0
2021
/*
2122
// some disabled options which might be useful
22-
"no-console": 0,
2323
"no-empty": 0,
2424
"no-extra-semi": 0,
2525
"no-fallthrough": 0,

docs/graph3d/index.html

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -441,6 +441,24 @@ <h2 id="Configuration_Options">Configuration Options</h2>
441441
both have the same, maximum with.</td>
442442
</tr>
443443

444+
<tr>
445+
<td>onclick</td>
446+
<td>function</td>
447+
<td>none</td>
448+
<td>Event handler for a click event with signature <code>function onclick(point)</code>.<br>
449+
Parameter <code>point</code> contains data for the nearest graph element relative to the click in
450+
the line of sight. It is an object with the fields:
451+
<ul>
452+
<li><code>id </code> - id of nearest node to the click</li>
453+
<li><code>x </code> - x-coordinate in graph units</li>
454+
<li><code>y </code> - y-coordinate in graph units</li>
455+
<li><code>z </code> - z-coordinate in graph units</li>
456+
<li><code>style</code> - if present, the data value for this point</li>
457+
</ul>
458+
459+
</td>
460+
</tr>
461+
444462
<tr>
445463
<td>showAnimationControls</td>
446464
<td>boolean</td>

examples/graph3d/04_animation.html

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,7 @@
5151
keepAspectRatio: true,
5252
verticalRatio: 0.5,
5353
animationInterval: 100, // milliseconds
54-
animationPreload: true,
55-
filterValue: 'time'
54+
animationPreload: true
5655
};
5756

5857
// create our graph

examples/graph3d/10_styling.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@
5858
keepAspectRatio: true,
5959
verticalRatio: 0.5
6060
};
61-
61+
6262
var camera = graph ? graph.getCameraPosition() : null;
6363

6464
// create our graph

examples/graph3d/playground/playground.js

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -400,7 +400,7 @@ function getDataDatasource() {
400400
* Retrieve a JSON object with all options
401401
*/
402402
function getOptions() {
403-
return {
403+
var options = {
404404
width: document.getElementById("width").value,
405405
height: document.getElementById("height").value,
406406
style: document.getElementById("style").value,
@@ -413,8 +413,8 @@ function getOptions() {
413413
showLegend: (document.getElementById("showLegend").checked != false),
414414
showShadow: (document.getElementById("showShadow").checked != false),
415415
keepAspectRatio: (document.getElementById("keepAspectRatio").checked != false),
416-
verticalRatio: document.getElementById("verticalRatio").value,
417-
animationInterval: document.getElementById("animationInterval").value,
416+
verticalRatio: Number(document.getElementById("verticalRatio").value) || undefined,
417+
animationInterval: Number(document.getElementById("animationInterval").value) || undefined,
418418
xLabel: document.getElementById("xLabel").value,
419419
yLabel: document.getElementById("yLabel").value,
420420
zLabel: document.getElementById("zLabel").value,
@@ -423,8 +423,8 @@ function getOptions() {
423423
animationPreload: (document.getElementById("animationPreload").checked != false),
424424
animationAutoStart:(document.getElementById("animationAutoStart").checked != false),
425425

426-
xCenter: Number(document.getElementById("xCenter").value) || undefined,
427-
yCenter: Number(document.getElementById("yCenter").value) || undefined,
426+
xCenter: document.getElementById("xCenter").value,
427+
yCenter: document.getElementById("yCenter").value,
428428

429429
xMin: Number(document.getElementById("xMin").value) || undefined,
430430
xMax: Number(document.getElementById("xMax").value) || undefined,
@@ -442,6 +442,8 @@ function getOptions() {
442442
xBarWidth: Number(document.getElementById("xBarWidth").value) || undefined,
443443
yBarWidth: Number(document.getElementById("yBarWidth").value) || undefined
444444
};
445+
446+
return options;
445447
}
446448

447449
/**

lib/graph3d/Graph3d.js

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@ var Point2d = require('./Point2d');
55
var Slider = require('./Slider');
66
var StepNumber = require('./StepNumber');
77
var Settings = require('./Settings');
8+
var Validator = require("./../shared/Validator").default;
9+
var {printStyle} = require('./../shared/Validator');
10+
var {allOptions} = require('./options.js');
811
var DataGroup = require('./DataGroup');
912

1013

@@ -31,7 +34,7 @@ var autoByDefault = undefined;
3134
* If a field is not in this list, a default value of 'autoByDefault' is assumed,
3235
* which is just an alias for 'undefined'.
3336
*/
34-
var DEFAULTS = {
37+
Graph3d.DEFAULTS = {
3538
width : '400px',
3639
height : '400px',
3740
filterLabel : 'time',
@@ -90,8 +93,6 @@ var DEFAULTS = {
9093
}
9194
},
9295

93-
showLegend : autoByDefault, // determined by graph style
94-
backgroundColor : autoByDefault,
9596

9697
dataColor : {
9798
fill : '#7DC1FF',
@@ -105,6 +106,13 @@ var DEFAULTS = {
105106
distance : 1.7
106107
},
107108

109+
110+
/*
111+
The following fields are 'auto by default', see above.
112+
*/
113+
showLegend : autoByDefault, // determined by graph style
114+
backgroundColor : autoByDefault,
115+
108116
xBarWidth : autoByDefault,
109117
yBarWidth : autoByDefault,
110118
valueMin : autoByDefault,
@@ -151,7 +159,7 @@ function Graph3d(container, data, options) {
151159
// create a frame and canvas
152160
this.create();
153161

154-
Settings.setDefaults(DEFAULTS, this);
162+
Settings.setDefaults(Graph3d.DEFAULTS, this);
155163

156164
// the column indexes
157165
this.colX = undefined;
@@ -628,6 +636,13 @@ Graph3d.prototype.setData = function (data) {
628636
* @param {Object} options
629637
*/
630638
Graph3d.prototype.setOptions = function (options) {
639+
if (options === undefined) return;
640+
641+
let errorFound = Validator.validate(options, allOptions);
642+
if (errorFound === true) {
643+
console.log('%cErrors have been found in the supplied options object.', printStyle);
644+
}
645+
631646
this.animationStop();
632647

633648
Settings.setOptions(options, this);

lib/graph3d/options.js

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
/**
2+
* This object contains all possible options. It will check if the types are correct, if required if the option is one
3+
* of the allowed values.
4+
*
5+
* __any__ means that the name of the property does not matter.
6+
* __type__ is a required field for all objects and contains the allowed types of all objects
7+
*/
8+
let string = 'string';
9+
let bool = 'boolean';
10+
let number = 'number';
11+
let object = 'object'; // should only be in a __type__ property
12+
// Following not used here, but useful for reference
13+
//let array = 'array';
14+
//let dom = 'dom';
15+
//let any = 'any';
16+
17+
18+
let colorOptions = {
19+
fill : { string },
20+
stroke : { string },
21+
strokeWidth: { number },
22+
__type__ : { string, object, 'undefined': 'undefined' }
23+
};
24+
25+
26+
/**
27+
* Order attempted to be alphabetical.
28+
* - x/y/z-prefixes ignored in sorting
29+
* - __type__ always at end
30+
* - globals at end
31+
*/
32+
let allOptions = {
33+
animationAutoStart: { boolean: bool, 'undefined': 'undefined' },
34+
animationInterval : { number },
35+
animationPreload : { boolean: bool },
36+
axisColor : { string },
37+
backgroundColor : colorOptions,
38+
xBarWidth : { number, 'undefined': 'undefined' },
39+
yBarWidth : { number, 'undefined': 'undefined' },
40+
cameraPosition : {
41+
distance : { number },
42+
horizontal: { number },
43+
vertical : { number },
44+
__type__ : { object }
45+
},
46+
xCenter : { string },
47+
yCenter : { string },
48+
dataColor : colorOptions,
49+
dotSizeMinFraction: { number },
50+
dotSizeMaxFraction: { number },
51+
dotSizeRatio : { number },
52+
filterLabel : { string },
53+
gridColor : { string },
54+
onclick : { 'function': 'function' },
55+
keepAspectRatio : { boolean: bool },
56+
xLabel : { string },
57+
yLabel : { string },
58+
zLabel : { string },
59+
legendLabel : { string },
60+
xMin : { number, 'undefined': 'undefined' },
61+
yMin : { number, 'undefined': 'undefined' },
62+
zMin : { number, 'undefined': 'undefined' },
63+
xMax : { number, 'undefined': 'undefined' },
64+
yMax : { number, 'undefined': 'undefined' },
65+
zMax : { number, 'undefined': 'undefined' },
66+
showAnimationControls: { boolean: bool, 'undefined': 'undefined' },
67+
showGrid : { boolean: bool },
68+
showLegend : { boolean: bool, 'undefined': 'undefined' },
69+
showPerspective : { boolean: bool },
70+
showShadow : { boolean: bool },
71+
showXAxis : { boolean: bool },
72+
showYAxis : { boolean: bool },
73+
showZAxis : { boolean: bool },
74+
xStep : { number, 'undefined': 'undefined' },
75+
yStep : { number, 'undefined': 'undefined' },
76+
zStep : { number, 'undefined': 'undefined' },
77+
style: {
78+
number, // TODO: either Graph3d.DEFAULT has string, or number allowed in documentation
79+
string: [
80+
'bar',
81+
'bar-color',
82+
'bar-size',
83+
'dot',
84+
'dot-line',
85+
'dot-color',
86+
'dot-size',
87+
'line',
88+
'grid',
89+
'surface'
90+
]
91+
},
92+
tooltip : { boolean: bool, 'function': 'function' },
93+
tooltipStyle : {
94+
content: {
95+
color : { string },
96+
background : { string },
97+
border : { string },
98+
borderRadius: { string },
99+
boxShadow : { string },
100+
padding : { string },
101+
__type__ : { object }
102+
},
103+
line: {
104+
borderLeft: { string },
105+
height : { string },
106+
width : { string },
107+
__type__ : { object }
108+
},
109+
dot: {
110+
border : { string },
111+
borderRadius: { string },
112+
height : { string },
113+
width : { string },
114+
__type__ : { object},
115+
},
116+
__type__: { object}
117+
},
118+
xValueLabel : { 'function': 'function' },
119+
yValueLabel : { 'function': 'function' },
120+
zValueLabel : { 'function': 'function' },
121+
valueMax : { number, 'undefined': 'undefined' },
122+
valueMin : { number, 'undefined': 'undefined' },
123+
verticalRatio : { number },
124+
125+
//globals :
126+
height: { string },
127+
width: { string },
128+
__type__: { object }
129+
};
130+
131+
132+
export {allOptions};

test/Graph3d.test.js

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,15 @@
11
var assert = require('assert');
2-
var jsdom_global = require('jsdom-global');
32
var vis = require('../dist/vis');
43
var Graph3d = vis.Graph3d;
4+
var jsdom_global = require('jsdom-global');
5+
var stdout = require('test-console').stdout;
6+
var Validator = require("./../lib/shared/Validator").default;
7+
//var {printStyle} = require('./../lib/shared/Validator');
8+
var {allOptions, configureOptions} = require('./../lib/graph3d/options.js');
59

10+
var now = new Date();
611

712
describe('Graph3d', function () {
8-
913
before(function() {
1014
//console.log('before!');
1115
this.jsdom_global = jsdom_global(
@@ -15,6 +19,24 @@ describe('Graph3d', function () {
1519
this.container = document.getElementById('mynetwork');
1620
});
1721

22+
23+
it('should pass validation for the default options', function () {
24+
assert(Graph3d.DEFAULTS !== undefined);
25+
26+
let errorFound;
27+
let output;
28+
output = stdout.inspectSync(function() {
29+
errorFound = Validator.validate(Graph3d.DEFAULTS, allOptions);
30+
});
31+
32+
// Useful during debugging:
33+
//if (errorFound === true) {
34+
// console.log(JSON.stringify(output, null, 2));
35+
//}
36+
assert(!errorFound, 'DEFAULTS options object does not pass validation');
37+
});
38+
39+
1840
it('accepts new option values on defined instance', function () {
1941
assert(this.container !== null, 'Container div not found');
2042

0 commit comments

Comments
 (0)