Skip to content

Commit

Permalink
Merge pull request #263 from jaimedp/fn-in-options
Browse files Browse the repository at this point in the history
Materialize configuration options parameters that are functions.
  • Loading branch information
narenranjit committed Dec 7, 2017
2 parents 63a16ed + cb04b37 commit 81b9840
Show file tree
Hide file tree
Showing 5 changed files with 53 additions and 13 deletions.
8 changes: 4 additions & 4 deletions src/documentation/config/config.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,11 @@ Each configuration option can be:

columnWidth: function() { return this.rangeBand/3 * 2; }

__Note__ Function parameters will be invoked just before each render happens or in the within the render cycle with the corresponding data point in the following cases:
* function expects a parameter (ie. `function (d) { return d.x; }`)
* parameter path is in the `options.skip`
* parameter path matches the RegExp `options.skipMatch`
__Note__ In general, function parameters will be invoked just before the render cycle happens except when:
* the function expects 1 or more parameters (ie. `function (d) { return d.x; }`) or
* the parameter path matches or is in the `options.skip` array. The `options.skip` array can have string with a full path to skip or a RegExp to match a path. For example `['line.marker.enable', /formatter/i]` would skip the options `line.marker.enable` and any options called `formatter`.

This allows functions to be used for things like formatters that need to be called for each point in the data set.

<% if(notes) { %><%= notes %><% } %>

Expand Down
26 changes: 20 additions & 6 deletions src/scripts/core/contour-utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -284,8 +284,19 @@
materialize: function (object, ctx, options, curPath) {
var isDom = function (obj) { return obj && typeof obj === 'object' && obj.nodeType === 1 && typeof obj.style === 'object' && typeof obj.ownerDocument === 'object'; };
var skipList = (options || {}).skip || [];
var skipMatch = (options || {}).skipMatch;
if ( object == null ) {

var shouldSkip = function (path) {
return skipList.some(function (e) {
if (!e) return false;
if (typeof e === 'object' && e instanceof RegExp) {
return e.test(path);
}

return e.toString() === path;
});
};

if (object == null) {
return object;
} else if (Array.isArray(object)) {
return object;
Expand All @@ -296,10 +307,13 @@
} else if (typeof object === 'object') {
return Object.keys(object).reduce(function (prev, key) {
var curKeyPath = curPath ? curPath + '.' + key : key;
var notInSkipList = skipList.indexOf(curKeyPath) === -1;
var notSkipMatch = (skipMatch && skipMatch.test ? !skipMatch.test(curKeyPath) : true);
var expectsParam = /(function)?\s?\(.+\)\s*({|=>)/.test((object[key] || '').toString());
var shouldMaterialize = notInSkipList && notSkipMatch && !expectsParam;
var expectsParam = (typeof object[key] === 'function' && !!object[key].length);
var shouldMaterialize = !shouldSkip(curKeyPath) && !expectsParam;

if (expectsParam && !shouldSkip(curKeyPath)) {
console.warn('The funciton "' + curKeyPath + '" expects parameters and will not be resolved to a value before the render starts. It is assumed to be used inside a visualization. Add this function to the "skip" list to remove this message.');
}

if (shouldMaterialize) {
prev[key] = generalHelpers.materialize(object[key], ctx, options, curKeyPath);
} else {
Expand Down
3 changes: 2 additions & 1 deletion src/scripts/core/contour.js
Original file line number Diff line number Diff line change
Expand Up @@ -315,7 +315,8 @@
this._extraOptions.forEach(mergeExtraOptions);
this._visualizations.forEach(mergeDefaults);

var opt = nwt.materialize(this.originalOptions, this, { skipMatch: /formatter/ });
var forceSkip = ['skip', /formatter/, 'el'];
var opt = nwt.materialize(this.originalOptions, this, { skip: forceSkip.concat(this.originalOptions.skip) });

// compose the final list of options right before start rendering
this.options = nwt.merge(opt, nwt.merge({}, allDefaults, opt));
Expand Down
3 changes: 1 addition & 2 deletions tests/specs/contour-utils-spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -478,8 +478,7 @@ describe('utils', function () {


res = mat(input, expectedContext, {
skip: ['x', 'd.x'],
skipMatch: /zzz/
skip: ['x', 'd.x', /zzz/],
});
});

Expand Down
26 changes: 26 additions & 0 deletions tests/specs/core-spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -373,4 +373,30 @@ describe('Contour', function () {
});
});

describe('composeOptions', function () {
var instance;
var formatter = function () { return 1; };
beforeEach(function () {
instance = createContour({
width: function () { return 80; },
skip: ['abc'],
formatter: formatter
});
});

it('should call options to materialzie', function () {
instance.composeOptions();
expect(instance.options).toEqual(jasmine.objectContaining({
width: 80,
}));
});
it('should not materialize skip list plus defaults', function () {
instance.composeOptions();
expect(instance.options).toEqual(jasmine.objectContaining({
skip: ['abc'],
formatter: formatter
}));
});
});

});

0 comments on commit 81b9840

Please sign in to comment.