Skip to content

Commit b5ec01e

Browse files
committed
add support for transform in plot schema and Plotly.validate
1 parent 1752d30 commit b5ec01e

File tree

4 files changed

+137
-5
lines changed

4 files changed

+137
-5
lines changed

src/plot_api/plot_schema.js

+17
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ var UNDERSCORE_ATTRS = [IS_SUBPLOT_OBJ, IS_LINKED_TO_ARRAY, DEPRECATED];
2929
var plotSchema = {
3030
traces: {},
3131
layout: {},
32+
transforms: {},
3233
defs: {}
3334
};
3435

@@ -45,7 +46,11 @@ PlotSchema.get = function() {
4546
.forEach(getTraceAttributes);
4647

4748
getLayoutAttributes();
49+
50+
Object.keys(Plots.transformsRegistry).forEach(getTransformAttributes);
51+
4852
getDefs();
53+
4954
return plotSchema;
5055
};
5156

@@ -136,6 +141,18 @@ function getLayoutAttributes() {
136141
plotSchema.layout = { layoutAttributes: layoutAttributes };
137142
}
138143

144+
function getTransformAttributes(name) {
145+
var _module = Plots.transformsRegistry[name],
146+
_schema = {};
147+
148+
_schema = coupleAttrs(_schema, _module.attributes || {}, 'attributes', '*');
149+
_schema = removeUnderscoreAttrs(_schema);
150+
mergeValTypeAndRole(_schema);
151+
handleLinkedToArray(_schema);
152+
153+
plotSchema.transforms[name] = { attributes: _schema };
154+
}
155+
139156
function getDefs() {
140157
plotSchema.defs = {
141158
valObjects: Lib.valObjects,

src/plot_api/validate.js

+37-1
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,39 @@ module.exports = function valiate(data, layout) {
102102
}
103103

104104
crawl(traceIn, traceOut, traceSchema, errorList, base);
105+
106+
var transformsIn = traceIn.transforms,
107+
transformsOut = traceOut.transforms;
108+
109+
if(transformsIn) {
110+
if(!isArray(transformsIn)) {
111+
errorList.push(format('array', base, ['transforms']));
112+
}
113+
114+
base.push('transforms');
115+
116+
for(var j = 0; j < transformsIn.length; j++) {
117+
var path = ['transforms', j],
118+
transformType = transformsIn[j].type;
119+
120+
if(!isPlainObject(transformsIn[j])) {
121+
errorList.push(format('object', base, path));
122+
continue;
123+
}
124+
125+
var transformSchema = schema.transforms[transformType] ?
126+
schema.transforms[transformType].attributes :
127+
{};
128+
129+
// add 'type' to transform schema to validate the transform type
130+
transformSchema.type = {
131+
valType: 'enumerated',
132+
values: Object.keys(schema.transforms)
133+
};
134+
135+
crawl(transformsIn[j], transformsOut[j], transformSchema, errorList, base, path);
136+
}
137+
}
105138
}
106139

107140
var layoutOut = gd._fullLayout,
@@ -121,6 +154,9 @@ function crawl(objIn, objOut, schema, list, base, path) {
121154
for(var i = 0; i < keys.length; i++) {
122155
var k = keys[i];
123156

157+
// transforms are handled separately
158+
if(k === 'transforms') continue;
159+
124160
var p = path.slice();
125161
p.push(k);
126162

@@ -184,7 +220,7 @@ var code2msgFunc = {
184220
var prefix;
185221

186222
if(base === 'layout' && astr === '') prefix = 'The layout argument';
187-
else if(base[0] === 'data') {
223+
else if(base[0] === 'data' && astr === '') {
188224
prefix = 'Trace ' + base[1] + ' in the data argument';
189225
}
190226
else prefix = inBase(base) + 'key ' + astr;

test/jasmine/tests/plotschema_test.js

+13-4
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
var Plotly = require('@lib/index');
22
var Lib = require('@src/lib');
33

4-
// until it is part of the main plotly.js bundle
5-
Plotly.register(
6-
require('@lib/scattermapbox')
7-
);
4+
Plotly.register([
5+
// until it is part of the main plotly.js bundle
6+
require('@lib/scattermapbox'),
7+
8+
// until they become official
9+
require('@assets/transforms/filter')
10+
]);
811

912
describe('plot schema', function() {
1013
'use strict';
@@ -180,4 +183,10 @@ describe('plot schema', function() {
180183
);
181184
});
182185

186+
it('should work with registered transforms', function() {
187+
var valObjects = plotSchema.transforms.filter.attributes,
188+
attrNames = Object.keys(valObjects);
189+
190+
expect(attrNames).toEqual(['operation', 'value', 'filtersrc']);
191+
});
183192
});

test/jasmine/tests/validate_test.js

+70
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,10 @@
11
var Plotly = require('@lib/index');
2+
var Lib = require('@src/lib');
3+
4+
Plotly.register([
5+
// until they become official
6+
require('@assets/transforms/filter')
7+
]);
28

39

410
describe('Plotly.validate', function() {
@@ -248,4 +254,68 @@ describe('Plotly.validate', function() {
248254
'In layout, key yaxis5 must be linked to an object container'
249255
);
250256
});
257+
258+
it('should work with attributes in registered transforms', function() {
259+
var base = {
260+
x: [-2, -1, -2, 0, 1, 2, 3],
261+
y: [1, 2, 3, 1, 2, 3, 1],
262+
};
263+
264+
var out = Plotly.validate([
265+
Lib.extendFlat({}, base, {
266+
transforms: [{
267+
type: 'filter',
268+
operation: '='
269+
}, {
270+
type: 'filter',
271+
operation: '=',
272+
wrongKey: 'sup?'
273+
}, {
274+
type: 'filter',
275+
operation: 'wrongVal'
276+
},
277+
'wont-work'
278+
]
279+
}),
280+
Lib.extendFlat({}, base, {
281+
transforms: {
282+
type: 'filter'
283+
}
284+
}),
285+
Lib.extendFlat({}, base, {
286+
transforms: [{
287+
type: 'no gonna work'
288+
}]
289+
}),
290+
], {
291+
title: 'my transformed graph'
292+
});
293+
294+
expect(out.length).toEqual(5);
295+
assertErrorContent(
296+
out[0], 'schema', 'data', 0,
297+
['transforms', 1, 'wrongKey'], 'transforms[1].wrongKey',
298+
'In data trace 0, key transforms[1].wrongKey is not part of the schema'
299+
);
300+
assertErrorContent(
301+
out[1], 'value', 'data', 0,
302+
['transforms', 2, 'operation'], 'transforms[2].operation',
303+
'In data trace 0, key transforms[2].operation is set to an invalid value (wrongVal)'
304+
);
305+
assertErrorContent(
306+
out[2], 'object', 'data', 0,
307+
['transforms', 3], 'transforms[3]',
308+
'In data trace 0, key transforms[3] must be linked to an object container'
309+
);
310+
assertErrorContent(
311+
out[3], 'array', 'data', 1,
312+
['transforms'], 'transforms',
313+
'In data trace 1, key transforms must be linked to an array container'
314+
);
315+
assertErrorContent(
316+
out[4], 'value', 'data', 2,
317+
['transforms', 0, 'type'], 'transforms[0].type',
318+
'In data trace 2, key transforms[0].type is set to an invalid value (no gonna work)'
319+
);
320+
});
251321
});

0 commit comments

Comments
 (0)