Merge pull request #39 from CartoDB/expose-filtered-field

Expose filtered field
dev
IagoLast 7 years ago committed by GitHub
commit daafa9fbf2

@ -229,6 +229,8 @@ CartoCSS.prototype = {
// serach the max index to know rendering order
lyr.index = _.max(props[v].map(function(a) { return a.index; }).concat(lyr.index));
lyr.constant = !_.any(props[v].map(function(a) { return !a.constant; }));
// True when the property is filtered.
lyr.filtered = props[v][0].filtered;
}
}

@ -210,48 +210,37 @@ tree.Definition.prototype.toXML = function(env, existing) {
tree.Definition.prototype.toJS = function(env) {
var shaderAttrs = {};
// merge conditions from filters with zoom condition of the
// definition
var zoom = "(" + this.zoom + " & (1 << ctx.zoom))";
var frame_offset = this.frame_offset;
var _if = this.filters.toJS(env);
var filters = [zoom];
if(_if) filters.push(_if);
if(frame_offset) filters.push('ctx["frame-offset"] === ' + frame_offset);
_if = filters.join(" && ");
_.each(this.rules, function(rule) {
if(rule instanceof tree.Rule) {
shaderAttrs[rule.name] = shaderAttrs[rule.name] || [];
var r = {
index: rule.index,
symbolizer: rule.symbolizer
};
if (_if) {
r.js = "if(" + _if + "){" + rule.value.toJS(env) + "}"
} else {
r.js = rule.value.toJS(env);
}
var zoomFilter = "(" + this.zoom + " & (1 << ctx.zoom))";
var filters = [zoomFilter];
var originalFilters = this.filters.toJS(env);
if (originalFilters) {
filters.push(originalFilters);
}
if (frame_offset) {
filters.push('ctx["frame-offset"] === ' + frame_offset);
}
r.constant = rule.value.ev(env).is !== 'field';
r.filtered = !!_if;
shaderAttrs[rule.name].push(r);
} else {
throw new Error("Ruleset not supported");
//if (rule instanceof tree.Ruleset) {
//var sh = rule.toJS(env);
//for(var v in sh) {
//shaderAttrs[v] = shaderAttrs[v] || [];
//for(var attr in sh[v]) {
//shaderAttrs[v].push(sh[v][attr]);
//}
//}
//}
_.each(this.rules, function (rule) {
var exportedRule = {};
if (!rule instanceof tree.Rule) {
throw new Error("Ruleset not supported");
}
exportedRule.index = rule.index;
exportedRule.symbolizer = rule.symbolizer;
exportedRule.js = "if(" + filters.join(" && ") + "){" + rule.value.toJS(env) + "}";
exportedRule.constant = rule.value.ev(env).is !== 'field';
exportedRule.filtered = originalFilters !== '';
shaderAttrs[rule.name] = shaderAttrs[rule.name] || [];
shaderAttrs[rule.name].push(exportedRule);
});
return shaderAttrs;
};

@ -0,0 +1,88 @@
/**
* Test the filtered field.
*
* When compiled, a rule provides metainformation fields like index, constant...etc
* one of this fields is the "filtered field".
*
* This field gives information about whether a property is filtered or not.
*
* A property is filtered if it was activated inside a filter. In the following cartocss
* code marker-color.filtered will be true because is inside a population filter.
*
* #layer {
* maker-width: 20;
* [population > 100] {
* marker-color: red; //
* }
* }
*/
var assert = require('assert');
var Carto = require('../lib/carto/index.js');
var renderer = new Carto.RendererJS({ strict: true });
describe('Field:filtered propery', function () {
it('should be false when the property is not filtered', function () {
var style = [
'#layer {',
' marker-fill: red;',
'}'
].join('\n');
var layers = renderer.render(style).layers[0].shader;
assert(!layers['marker-fill'].filtered);
});
it('should be true when the property is filtered', function () {
var style = [
'#layer {',
' [foo > 30] {',
' marker-fill: red;',
' }',
'}'
].join('\n');
var layers = renderer.render(style).layers[0].shader;
assert(layers['marker-fill'].filtered);
});
it('should be true when the property is filtered at first level', function () {
var style = [
'#layer [foo > 30] {',
' marker-fill: red;',
'}`'
].join('\n');
var layers = renderer.render(style).layers[0].shader;
assert(layers['marker-fill'].filtered);
});
it('should be false when the property is not filterd but there is another filtered properties', function () {
var style = [
'#layer {',
' marker-fill: red;',
' [bar < 200]{',
' marker-allow-overlap: false;',
' }',
'}`'
].join('\n');
var layers = renderer.render(style).layers[0].shader;
assert(!layers['marker-fill'].filtered);
assert(layers['marker-allow-overlap'].filtered);
});
it('should be true when the property is filtered and have a default value', function () {
var style = [
'#layer {',
' marker-fill: red;',
' [bar < 200]{',
' marker-fill: blue;',
' }',
'}`'
].join('\n');
var layers = renderer.render(style).layers[0].shader;
assert(layers['marker-fill'].filtered);
});
});
Loading…
Cancel
Save