Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

turbo-carto

Package Overview
Dependencies
Maintainers
2
Versions
32
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

turbo-carto - npm Package Compare versions

Comparing version 0.14.0 to 0.15.0

examples/readme/example-0.css

11

CHANGELOG.md
# Changelog
## Version 0.15.0
Released 2016-07-19
- New API: `property: ramp([attribute], (...values), (...filters), mapping);`.
- It's backwards compatible with previous signatures.
- New `range(min, max)` function.
- High level functions for quantifications: `category()`, `equal()`, `headtails()`, `jenks()`, and `quantiles()`.
- Improved documentation and examples.
- Removes `colors` and `buckets` function.
## Version 0.14.0

@@ -4,0 +15,0 @@ Released 2016-07-06

117

docs/quickstart.md

@@ -1,116 +0,3 @@

# Quickstart
# DEPRECATED
## Color ramps: *-fill
### Basic usage
```css
marker-fill: ramp([column_name], (red, green, blue));
| |
v |
column to calculate ramp |
v
it will use a 3 buckets color ramp as provided
```
### Basic usage with colorbrewer or cartocolor
```css
marker-fill: ramp([column_name], colorbrewer(Greens));
| |
v |
column to calculate ramp |
v
it will use a color ramp from http://colorbrewer2.org/
```
### Change number of color brewer data classes
```css
marker-fill: ramp([column_name], colorbrewer(YlGnBu, 7));
|
v
force number of classes
default: 5 classes
```
### Change quantification method
```css
marker-fill: ramp([column_name], colorbrewer(Reds), jenks);
|
v
force quantification method
default: quantiles
```
## Numeric ramps: *-width, *-opacity
### Basic usage
```css
marker-width: ramp([column_name], (4, 8, 16, 32));
| |
v |
column to calculate ramp |
|
|
|
v
provide the steps for the symbol sizes
```
### Basic usage with interpolation for symbol size
```css
marker-width: ramp([column_name], 4, 18);
| | |
v | |
column to calculate ramp | |
v |
start value for the ramp |
|
v
end value for the ramp
```
### Change quantification method
```css
marker-width: ramp([column_name], 4, 18, equal);
|
v
force quantification method
default: quantiles
```
### Change number of buckets
```css
marker-width: ramp([column_name], 4, 18, 6);
|
v
force number of buckets
default: 5
```
### Change both: number of buckets and quantification method
```css
marker-width: ramp([column_name], 4, 18, 6, jenks);
| |
v |
force number of classes |
v
force quantification method
```
## Options
### Quantification methods
- quantiles: as per [`CDB_QuantileBins`](https://github.com/CartoDB/cartodb-postgresql/blob/master/scripts-available/CDB_QuantileBins.sql).
- equal: as per [`CDB_EqualIntervalBins`](https://github.com/CartoDB/cartodb-postgresql/blob/master/scripts-available/CDB_EqualIntervalBins.sql).
- jenks: as per [`CDB_JenksBins`](https://github.com/CartoDB/cartodb-postgresql/blob/master/scripts-available/CDB_JenksBins.sql).
- headtails: as per [`CDB_HeadsTailsBins`](https://github.com/CartoDB/cartodb-postgresql/blob/master/scripts-available/CDB_HeadsTailsBins.sql).
Check [README.md](../README.md) for API and examples.
{
"name": "turbo-carto",
"version": "0.14.0",
"version": "0.15.0",
"description": "CartoCSS preprocessor",

@@ -5,0 +5,0 @@ "main": "src/index.js",

@@ -1,4 +0,4 @@

# Turbo Carto
# Turbo-Carto
AKA CartoCSS preprocessor
Next-Gen Styling for Data-Driven Maps, AKA CartoCSS preprocessor

@@ -9,8 +9,166 @@ tl;dr Enables adding functions to CartoCSS that can be evaluated asynchronously.

TBC.
## Ramps
## Limitations
It's all about ramps.
- TBA
You can create color and symbol size ramps with just a single line of code. You no longer need to worry about
calculating the bins for your thematic map, if your data changes your CartoCSS changes.
### Very basic introduction to CartoCSS
In CartoCSS you usually assign values to properties, and apply filters in order to change those values based on some
data attributes.
The general form for properties and filters is:
```css
#selector {
property: value;
[filter] {
property: value;
}
}
```
An example for a filter based on price attribute:
```css
#selector {
marker-width: 10;
[price > 100] {
marker-width: 20;
}
}
```
### Turbo-Carto ramps
Turbo-Carto high level API for ramps is as follows:
```css
#selector {
property: ramp([attribute], (...values), (...filters), mapping);
}
```
Where:
- `property` is the CartoCSS property you want to create.
- `[attribute]` usually is a column/key name from your dataset.
- `(...values)` is **what** `property` is gonna get for different filters.
- `(...filters)` is **how** `property` is gonna get the different values.
- `mapping` is the type of filter that will be applied: <, >, =.
So for the previous example you could write (see [examples/readme/example-0.css](./examples/readme/example-0.css)):
```css
#selector {
marker-width: ramp([price], (10, 20), (100));
}
```
In this case the first value is the default value.
If you want to have a category map, to generate a CartoCSS like:
```css
#selector {
marker-fill: red;
[room_type = "Private Room"] {
marker-fill: green;
}
}
```
You can use the same approach but specifying the mapping type to be an equality (see [examples/readme/example-1.css](./examples/readme/example-1.css)):
```css
#selector {
marker-width: ramp([room_type], (green, red), ("Private room"), =);
}
```
See that in this case the last value is the default value, and if the number of values is equal to the number of filters
it won't have a default value, like in (see [examples/readme/example-2.css](./examples/readme/example-2.css)):
```css
#selector {
marker-width: ramp([room_type], (green, red), ("Private room"), =);
}
```
That's nice, but it is still unlinked from the actual data/attributes.
#### Associate ramp filters to your data
To generate ramps based on actual data you have to say what kind of quantification you want to use, for that purpose
Turbo-Carto provides some shorthand methods that will delegate the filters computation to different collaborators.
Let's say you want to compute the ramp using jenks as quantification function (see [examples/readme/example-3.css](./examples/readme/example-3.css)):
```css
#selector {
marker-width: ramp([price], (10, 20, 30), jenks());
}
```
Or generate a category map depending on the room_type property (see [examples/readme/example-4.css](./examples/readme/example-4.css)):
```css
#selector {
marker-fill: ramp([room_type], (red, green, blue), category(2));
}
```
You can override the mapping if you know your data requires an more strict filter (see [examples/readme/example-5.css](./examples/readme/example-5.css)):
```css
#selector {
marker-width: ramp([price], (10, 20, 30), jenks(), >=);
}
```
Shorthand methods include:
- `category()`: default mapping is `=`.
- `equal()`: default mapping is `>`.
- `headtails()`: default mapping is `<`.
- `jenks()`: default mapping is `>`.
- `quantiles()`: default mapping is `>`.
#### Color ramps
For color ramps there are a couple of handy functions to retrieve color palettes: `cartocolor` and `colorbrewer`.
You can create a choropleth map using Reds color palette from colorbrewer (see [examples/readme/example-6.css](./examples/readme/example-6.css)):
```css
#selector {
polygon-fill: ramp([avg_price], colorbrewer(Reds), jenks());
}
```
Or a category map using Bold color palette from cartocolor (see [examples/readme/example-7.css](./examples/readme/example-7.css)):
```css
#selector {
polygon-fill: ramp([room_type], cartocolor(Bold), category(4));
}
```
#### Numeric ramps
Sometimes is really useful to have a continuous range that can be split in as many bins as desired, so you don't have to
worry about how many values you have to provide for your calculated filters. You only specify the start and the end, and
the values are computed linearly (see [examples/readme/example-8.css](./examples/readme/example-8.css)):
```css
#selector {
marker-width: ramp([price], range(4, 40), equal(5));
}
```
It is kind of similar to color palettes where depending on your number of filters you get the correct number of values.
## Dependencies

@@ -41,3 +199,3 @@

Visit `examples/index.html`, it also .
Visit `examples/index.html`, to test different styles using CartoDB's SQL API as datasource.

@@ -44,0 +202,0 @@ ## Tests

@@ -5,3 +5,4 @@ 'use strict';

var debug = require('../helper/debug')('fn-factory');
var debug = require('../helper/debug')('fn-anonymous-tuple');
var ValuesResult = require('../model/values-result');

@@ -14,3 +15,3 @@ module.exports = function () {

var tupleValues = Object.keys(args).map(function (k) { return args[k]; });
resolve(tupleValues);
resolve(new ValuesResult(tupleValues));
});

@@ -17,0 +18,0 @@ };

@@ -5,54 +5,34 @@ 'use strict';

var debug = require('../helper/debug')('fn-buckets');
var columnName = require('../helper/column-name');
var debug = require('../helper/debug')('fn-factory');
var postcss = require('postcss');
var TurboCartoError = require('../helper/turbo-carto-error');
var FiltersResult = require('../model/filters-result');
module.exports = function (datasource, decl) {
return function fn$buckets (column, scheme) {
module.exports = function (datasource) {
return function fn$buckets (column, quantificationMethod, numBuckets) {
debug('fn$buckets(%j)', arguments);
debug('Using "%s" datasource to calculate buckets', datasource.getName());
return getRamp(datasource, column)
.then(function (ramp) {
var i;
var rampResult = [];
rampResult.push(scheme[0]);
for (i = 0; i < 5; i++) {
rampResult.push(ramp[i]);
rampResult.push(scheme[i]);
return new Promise(function (resolve, reject) {
if (!quantificationMethod) {
return reject(new TurboCartoError('Missing quantification method in buckets function'));
}
numBuckets = Number.isFinite(+numBuckets) ? +numBuckets : 5;
datasource.getRamp(columnName(column), numBuckets, quantificationMethod, function (err, filters) {
if (err) {
return reject(
new TurboCartoError('unable to compute ramp,', err)
);
}
var parent = decl.parent;
var start = rampResult.shift();
column = columnName(column);
rampResult = rampResult.reverse();
parent.append(postcss.decl({ prop: decl.prop, value: start }));
for (i = 0; i < rampResult.length; i += 2) {
var rule = postcss.rule({
selector: '[ ' + column + ' < ' + rampResult[i + 1] + ' ]'
});
rule.append(postcss.decl({prop: decl.prop, value: rampResult[i]}));
parent.append(rule);
var strategy = 'max';
if (!Array.isArray(filters)) {
strategy = filters.strategy || 'max';
filters = filters.ramp;
}
decl.remove();
resolve(new FiltersResult(filters, strategy));
});
});
};
};
function getRamp (datasource, column, method) {
return new Promise(function (resolve, reject) {
datasource.getRamp(columnName(column), method || 'quantiles', function (err, ramp) {
if (err) {
return reject(err);
}
resolve(ramp);
});
});
}
module.exports.fnName = 'buckets';

@@ -6,3 +6,5 @@ 'use strict';

var cartocolor = require('cartocolor');
var debug = require('../helper/debug')('fn-factory');
var ValuesResult = require('../model/values-result');
var minMaxKeys = require('../helper/min-max-keys');
var debug = require('../helper/debug')('fn-cartocolor');

@@ -12,10 +14,10 @@ module.exports = function () {

debug('fn$cartocolor(%j)', arguments);
numberDataClasses = Math.min(7, Math.max(3, numberDataClasses || 5));
return new Promise(function (resolve) {
var result = cartocolor.BluGrn[numberDataClasses];
var def = cartocolor[scheme];
if (def) {
result = def[numberDataClasses];
return new Promise(function (resolve, reject) {
if (!cartocolor.hasOwnProperty(scheme)) {
return reject(new Error('Invalid cartocolor scheme: "' + scheme + '"'));
}
resolve(result);
var result = cartocolor[scheme];
var minMax = minMaxKeys(result);
numberDataClasses = Math.min(minMax.max, Math.max(minMax.min, numberDataClasses || 5));
resolve(new ValuesResult(result, numberDataClasses, null, minMax.max));
});

@@ -22,0 +24,0 @@ };

@@ -5,3 +5,3 @@ 'use strict';

var debug = require('../helper/debug')('fn-factory');
var debug = require('../helper/debug')('fn-identity');

@@ -8,0 +8,0 @@ module.exports = function (fnName) {

@@ -5,6 +5,11 @@ 'use strict';

var debug = require('../helper/debug')('fn-factory');
var debug = require('../helper/debug')('fn-ramp');
var columnName = require('../helper/column-name');
var TurboCartoError = require('../helper/turbo-carto-error');
var buckets = require('../helper/linear-buckets');
var isResult = require('../model/is-result');
var linearBuckets = require('../helper/linear-buckets');
var ValuesResult = require('../model/values-result');
var FiltersResult = require('../model/filters-result');
var LazyFiltersResult = require('../model/lazy-filters-result');
var RampResult = require('../model/ramp/ramp-result');
var postcss = require('postcss');

@@ -58,3 +63,3 @@

exact: createSplitStrategy(function exactSelector (column, value) {
return '[ ' + column + ' = "' + value + '" ]';
return Number.isFinite(value) ? '[ ' + column + ' = ' + value + ' ]' : '[ ' + column + ' = "' + value + '" ]';
})

@@ -72,2 +77,5 @@ };

.then(function (rampResult) {
if (rampResult.constructor === RampResult) {
return rampResult.process(columnName(column), decl);
}
var strategyFn = strategy.hasOwnProperty(rampResult.strategy) ? strategy[rampResult.strategy] : strategy.max;

@@ -124,6 +132,2 @@ return strategyFn(columnName(column), rampResult.ramp, decl);

function ramp (datasource, column, args) {
var method;
var tuple = [];
if (args.length === 0) {

@@ -135,27 +139,128 @@ return Promise.reject(

if (Array.isArray(args[0])) {
tuple = args[0];
method = args[1];
/**
* Overload scenarios to support
* marker-width: ramp([price], 4, 100);
* marker-width: ramp([price], 4, 100, method);
* marker-width: ramp([price], 4, 100, 5, method);
* marker-width: ramp([price], 4, 100, 3, (100, 200, 1000));
* marker-width: ramp([price], 4, 100, (100, 150, 250, 200, 1000));
*/
if (Number.isFinite(args[0])) {
return compatibilityNumericRamp(datasource, column, args);
}
/**
* Overload methods to support
* marker-fill: ramp([price], colorbrewer(Reds));
* marker-fill: ramp([price], colorbrewer(Reds), jenks);
*/
if (!isResult(args[1])) {
return compatibilityValuesRamp(datasource, column, args);
}
/**
* Overload methods to support from here
* marker-fill: ramp([price], colorbrewer(Reds), (100, 200, 300, 400, 500));
* marker-fill: ramp([price], colorbrewer(Reds), (100, 200, 300, 400, 500), =);
* marker-fill: ramp([price], (...values), (...filters), [mapping]);
*/
var values = args[0];
var filters = args[1];
var mapping = args[2];
var strategy = strategyFromMapping(mapping);
filters = filters.is(ValuesResult) ? new FiltersResult(filters.get(), strategy) : filters;
if (filters.is(LazyFiltersResult)) {
return filters.get(column, strategy).then(createRampFn(values));
} else {
if (args.length < 2) {
return Promise.reject(
new TurboCartoError('invalid number of arguments')
);
}
return Promise.resolve(filters).then(createRampFn(values));
}
}
var min = +args[0];
var max = +args[1];
var oldMappings2Strategies = {
quantiles: 'max',
equal: 'max',
jenks: 'max',
headtails: 'split',
category: 'exact'
};
var numBuckets = 5;
method = args[2];
function strategyFromMapping (mapping) {
if (oldMappings2Strategies.hasOwnProperty(mapping)) {
return oldMappings2Strategies[mapping];
}
return mapping;
}
if (Number.isFinite(+args[2])) {
numBuckets = +args[2];
/**
* Overload methods to support
* marker-fill: ramp([price], colorbrewer(Reds));
* marker-fill: ramp([price], colorbrewer(Reds), jenks);
*/
function compatibilityValuesRamp (datasource, column, args) {
var values = args[0];
var method = (args[1] || 'quantiles').toLowerCase();
var numBuckets = values.getLength();
return getRamp(datasource, column, numBuckets, method).then(compatibilityCreateRampFn(values));
}
/**
* Overload scenarios to support
* marker-width: ramp([price], 4, 100);
* marker-width: ramp([price], 4, 100, method);
* marker-width: ramp([price], 4, 100, 5, method); √
* marker-width: ramp([price], 4, 100, 3, (100, 200, 1000)); √
* marker-width: ramp([price], 4, 100, (100, 150, 250, 200, 1000)); √
*/
function compatibilityNumericRamp (datasource, column, args) {
// jshint maxcomplexity:9
if (args.length < 2) {
return Promise.reject(
new TurboCartoError('invalid number of arguments')
);
}
var min = +args[0];
var max = +args[1];
var numBuckets;
var filters = null;
var method;
if (Number.isFinite(args[2])) {
numBuckets = args[2];
if (isResult(args[3])) {
filters = args[3];
method = null;
if (filters.getLength() !== numBuckets) {
return Promise.reject(
new TurboCartoError(
'invalid ramp length, got ' + filters.getLength() + ' values, expected ' + numBuckets
)
);
}
} else {
filters = null;
method = args[3];
}
} else if (isResult(args[2])) {
filters = args[2];
numBuckets = filters.getLength();
method = null;
} else {
filters = null;
numBuckets = 5;
method = args[2];
}
tuple = buckets(min, max, numBuckets);
var values = new ValuesResult([min, max], numBuckets, linearBuckets, Number.POSITIVE_INFINITY);
if (filters === null) {
// normalize method
method = (method || 'quantiles').toLowerCase();
return getRamp(datasource, column, numBuckets, method).then(compatibilityCreateRampFn(values));
}
return tupleRamp(datasource, column, tuple, method);
filters = filters.is(FiltersResult) ? filters : new FiltersResult(filters.get(), 'max');
return Promise.resolve(filters).then(compatibilityCreateRampFn(values));
}

@@ -165,3 +270,3 @@

return new Promise(function (resolve, reject) {
datasource.getRamp(columnName(column), buckets, method, function (err, ramp) {
datasource.getRamp(columnName(column), buckets, method, function (err, filters) {
if (err) {

@@ -172,3 +277,8 @@ return reject(

}
resolve(ramp);
var strategy = 'max';
if (!Array.isArray(filters)) {
strategy = filters.strategy || 'max';
filters = filters.ramp;
}
resolve(new FiltersResult(filters, strategy));
});

@@ -178,31 +288,32 @@ });

function tupleRamp (datasource, column, tuple, method) {
if (Array.isArray(method)) {
var ramp = method;
if (tuple.length !== ramp.length) {
return Promise.reject(
new TurboCartoError('invalid ramp length, got ' + ramp.length + ' values, expected ' + tuple.length)
);
function compatibilityCreateRampFn (valuesResult) {
return function prepareRamp (filtersResult) {
var buckets = Math.min(valuesResult.getLength(), filtersResult.getLength());
var i;
var rampResult = [];
var filters = filtersResult.get();
var values = valuesResult.get();
if (buckets > 0) {
for (i = 0; i < buckets; i++) {
rampResult.push(filters[i]);
rampResult.push(values[i]);
}
} else {
rampResult.push(null, values[0]);
}
var strategy = ramp.map(function numberMapper (n) { return +n; }).every(Number.isFinite) ? 'split' : 'exact';
return Promise.resolve({ramp: ramp, strategy: strategy}).then(createRampFn(tuple));
}
// normalize method
if (method) {
method = method.toLowerCase();
}
return getRamp(datasource, column, tuple.length, method).then(createRampFn(tuple));
return { ramp: rampResult, strategy: filtersResult.getStrategy() };
};
}
function createRampFn (tuple) {
return function prepareRamp (ramp) {
var strategy = 'max';
if (!Array.isArray(ramp)) {
strategy = ramp.strategy || 'max';
ramp = ramp.ramp;
function createRampFn (valuesResult) {
return function prepareRamp (filtersResult) {
if (RampResult.supports(filtersResult.getStrategy())) {
return new RampResult(valuesResult, filtersResult, filtersResult.getStrategy());
}
var buckets = Math.min(tuple.length, ramp.length);
var buckets = Math.min(valuesResult.getMaxSize(), filtersResult.getMaxSize());

@@ -212,12 +323,15 @@ var i;

var filters = filtersResult.get();
var values = valuesResult.get(buckets);
if (buckets > 0) {
for (i = 0; i < buckets; i++) {
rampResult.push(ramp[i]);
rampResult.push(tuple[i]);
rampResult.push(filters[i]);
rampResult.push(values[i]);
}
} else {
rampResult.push(null, tuple[0]);
rampResult.push(null, values[0]);
}
return { ramp: rampResult, strategy: strategy };
return { ramp: rampResult, strategy: filtersResult.getStrategy() };
};

@@ -224,0 +338,0 @@ }

'use strict';
module.exports = function (min, max, numBuckets) {
if (Array.isArray(min)) {
numBuckets = max;
max = min[1];
min = min[0];
}
var buckets = [];
var range = max - min;
var width = range / (numBuckets - 1);
if (width === Number.POSITIVE_INFINITY || width === Number.NEGATIVE_INFINITY) {
width = 0;
}
for (var i = 0; i < numBuckets; i++) {

@@ -8,0 +16,0 @@ buckets.push(min + i * width);

@@ -7,3 +7,3 @@ 'use strict';

var postcss = require('postcss');
var FnBuilder = require('./fn/fn-builder');
var FnBuilder = require('./fn/builder');

@@ -10,0 +10,0 @@ function PostcssTurboCarto (datasource) {

'use strict';
var assert = require('assert');
var postcss = require('postcss');
var PostcssTurboCarto = require('../../src/postcss-turbo-carto');
var turbocarto = require('../../src/index');
var DummyDatasource = require('../support/dummy-datasource');

@@ -20,16 +19,5 @@ var DummyStrategyDatasource = require('../support/dummy-strategy-datasource');

});
var numericExactStrategyDatasource = new DummyStrategyDatasource('exact');
describe('ramp-strategy', function () {
function getCartoCss (datasource, cartocss, callback) {
var postcssTurboCarto = new PostcssTurboCarto(datasource);
postcss([postcssTurboCarto.getPlugin()])
.process(cartocss)
.then(function (result) {
return callback(null, result.css);
})
.catch(function (err) {
return callback(err);
});
}
var cartocss = [

@@ -113,2 +101,151 @@ '#layer{',

].join('\n')
},
{
desc: 'result with exact strategy generates uses numeric values',
datasource: numericExactStrategyDatasource,
cartocss: [
'#layer{',
' marker-width: ramp([population], (10, 20, 30, 40));',
'}'
].join('\n'),
expectedCartocss: [
'#layer{',
' marker-width: 10;',
' [ population = 1 ]{',
' marker-width: 20',
' }',
' [ population = 2 ]{',
' marker-width: 30',
' }',
' [ population = 3 ]{',
' marker-width: 40',
' }',
'}'
].join('\n')
},
{
desc: 'result with exact strategy is generated from buckets fn',
datasource: numericExactStrategyDatasource,
cartocss: [
'#layer{',
' marker-width: ramp([population], range(10, 50), buckets([population], category));',
'}'
].join('\n'),
expectedCartocss: [
'#layer{',
' marker-width: 10;',
' [ population = 1 ]{',
' marker-width: 20',
' }',
' [ population = 2 ]{',
' marker-width: 30',
' }',
' [ population = 3 ]{',
' marker-width: 40',
' }',
' [ population = 4 ]{',
' marker-width: 50',
' }',
'}'
].join('\n')
},
{
desc: 'result with exact strategy is generated from buckets fn, force number of buckets',
datasource: numericExactStrategyDatasource,
cartocss: [
'#layer{',
' marker-width: ramp([population], range(10, 40), buckets([population], category, 4));',
'}'
].join('\n'),
expectedCartocss: [
'#layer{',
' marker-width: 10;',
' [ population = 1 ]{',
' marker-width: 20',
' }',
' [ population = 2 ]{',
' marker-width: 30',
' }',
' [ population = 3 ]{',
' marker-width: 40',
' }',
'}'
].join('\n')
},
{
desc: 'result with exact strategy is generated from category fn',
datasource: numericExactStrategyDatasource,
cartocss: [
'#layer{',
' marker-width: ramp([population], range(10, 50), category());',
'}'
].join('\n'),
expectedCartocss: [
'#layer{',
' marker-width: 50;',
' [ population = 0 ]{',
' marker-width: 10',
' }',
' [ population = 1 ]{',
' marker-width: 18',
' }',
' [ population = 2 ]{',
' marker-width: 26',
' }',
' [ population = 3 ]{',
' marker-width: 34',
' }',
' [ population = 4 ]{',
' marker-width: 42',
' }',
'}'
].join('\n')
},
{
desc: 'result with exact strategy is generated from category fn, force number of buckets',
datasource: numericExactStrategyDatasource,
cartocss: [
'#layer{',
' marker-width: ramp([population], range(10, 40), category(3));',
'}'
].join('\n'),
expectedCartocss: [
'#layer{',
' marker-width: 40;',
' [ population = 0 ]{',
' marker-width: 10',
' }',
' [ population = 1 ]{',
' marker-width: 20',
' }',
' [ population = 2 ]{',
' marker-width: 30',
' }',
'}'
].join('\n')
},
{
desc: 'should not set default value for equal mapping when values and filters are same size',
datasource: numericExactStrategyDatasource,
cartocss: [
'#layer{',
' marker-width: ramp([population], (10, 20, 30, 40), (0, 1, 2, 3), =);',
'}'
].join('\n'),
expectedCartocss: [
'#layer{',
' [ population = 0 ]{',
' marker-width: 10',
' }',
' [ population = 1 ]{',
' marker-width: 20',
' }',
' [ population = 2 ]{',
' marker-width: 30',
' }',
' [ population = 3 ]{',
' marker-width: 40',
' }',
'}'
].join('\n')
}

@@ -118,4 +255,5 @@ ];

scenarios.forEach(function (scenario) {
it(scenario.desc, function (done) {
getCartoCss(scenario.datasource, scenario.cartocss || cartocss, function (err, cartocssResult) {
var itFn = scenario.only ? it.only : it;
itFn(scenario.desc, function (done) {
turbocarto(scenario.cartocss || cartocss, scenario.datasource, function (err, cartocssResult) {
if (err) {

@@ -122,0 +260,0 @@ return done(err);

@@ -5,4 +5,3 @@ 'use strict';

var assert = require('assert');
var postcss = require('postcss');
var PostcssTurboCarto = require('../../src/postcss-turbo-carto');
var turbocarto = require('../../src/index');
var DummyDatasource = require('../support/dummy-datasource');

@@ -12,4 +11,2 @@

var postcssTurboCarto = new PostcssTurboCarto(datasource);
var scenariosPath = __dirname + '/scenarios';

@@ -35,16 +32,5 @@ var scenarios = fs.readdirSync(scenariosPath)

describe('ramp', function () {
function getCartoCss (cartocss, callback) {
postcss([postcssTurboCarto.getPlugin()])
.process(cartocss)
.then(function (result) {
return callback(null, result.css);
})
.catch(function (err) {
return callback(err);
});
}
scenarios.forEach(function (scenario) {
it(scenario.desc, function (done) {
getCartoCss(scenario.cartocss, function (err, cartocssResult) {
turbocarto(scenario.cartocss, datasource, function (err, cartocssResult) {
if (err) {

@@ -51,0 +37,0 @@ return done(err);

'use strict';
var assert = require('assert');
var postcss = require('postcss');
var PostcssTurboCarto = require('../../src/postcss-turbo-carto');
var turbocarto = require('../../src/index');
var DummyDatasource = require('../support/dummy-datasource');

@@ -10,26 +9,30 @@ var DummyStrategyDatasource = require('../support/dummy-strategy-datasource');

describe('regressions', function () {
function getCartoCss (cartocss, datasource, callback) {
if (!callback) {
callback = datasource;
datasource = new DummyDatasource();
}
datasource = datasource || new DummyDatasource();
var postcssTurboCarto = new PostcssTurboCarto(datasource);
postcss([postcssTurboCarto.getPlugin()])
.process(cartocss)
.then(function (result) {
return callback(null, result.css);
})
.catch(function (err) {
return callback(err);
});
}
var scenarios = [
{
desc: 'should keep working with category quantification',
cartocss: [
'#layer{',
' marker-width: ramp([population], (10, 20, 30, 40), (_, Spain, Portugal, France), category);',
'}'
].join('\n'),
expectedCartocss: [
'#layer{',
' marker-width: 10;',
' [ population = "Spain" ]{',
' marker-width: 20',
' }',
' [ population = "Portugal" ]{',
' marker-width: 30',
' }',
' [ population = "France" ]{',
' marker-width: 40',
' }',
'}'
].join('\n')
},
{
desc: 'should use strings for filters',
cartocss: [
'#layer{',
' marker-width: ramp([population], (10, 20, 30, 40), (_, Spain, Portugal, France));',
' marker-width: ramp([population], (10, 20, 30, 40), (_, Spain, Portugal, France), category);',
'}'

@@ -56,3 +59,3 @@ ].join('\n'),

'#layer{',
' marker-width: ramp([population], (10, 20, 30, 40), (_, "Spain\'s", Portugal, France));',
' marker-width: ramp([population], (10, 20, 30, 40), (_, "Spain\'s", Portugal, France), category);',
'}'

@@ -136,3 +139,3 @@ ].join('\n'),

' marker-fill: #fee5d9;',
' [ population = "2" ]{',
' [ population = 2 ]{',
' marker-fill: #fcbba1',

@@ -142,2 +145,21 @@ ' }',

].join('\n')
},
{
desc: 'should work with less values than filters',
cartocss: [
'#layer{',
' marker-width: ramp([population], (8, 24, 96), (8, 24, 96, 128));',
'}'
].join('\n'),
expectedCartocss: [
'#layer{',
' marker-width: 8;',
' [ population > 8 ]{',
' marker-width: 24',
' }',
' [ population > 24 ]{',
' marker-width: 96',
' }',
'}'
].join('\n')
}

@@ -147,4 +169,6 @@ ];

scenarios.forEach(function (scenario) {
it(scenario.desc, function (done) {
getCartoCss(scenario.cartocss, scenario.datasource, function (err, cartocssResult) {
var itFn = scenario.only ? it.only : it;
itFn(scenario.desc, function (done) {
var datasource = scenario.datasource || new DummyDatasource();
turbocarto(scenario.cartocss, datasource, function (err, cartocssResult) {
if (err) {

@@ -151,0 +175,0 @@ return done(err);

'use strict';
var assert = require('assert');
var FnExecutor = require('../../src/fn/fn-executor');
var FnExecutor = require('../../src/fn/executor');
var DummyDatasource = require('../support/dummy-datasource');

@@ -6,0 +6,0 @@ var postcss = require('postcss');

'use strict';
function DummyDatasource () {
function DummyDatasource (getter) {
this.getter = getter || null;
}

@@ -13,2 +14,6 @@

DummyDatasource.prototype.getRamp = function (column, buckets, method, callback) {
if (this.getter) {
var result = this.getter(column, buckets, method);
return callback(null, result);
}
var ramp = [];

@@ -15,0 +20,0 @@ for (var i = 0; i < buckets; i++) {

@@ -10,3 +10,3 @@ 'use strict';

fn('red', 'green', 'blue').then(function (result) {
assert.deepEqual(result, [ 'red', 'green', 'blue' ]);
assert.deepEqual(result.get(), [ 'red', 'green', 'blue' ]);
done();

@@ -18,3 +18,3 @@ });

fn(9, 8, 7).then(function (result) {
assert.deepEqual(result, [ 9, 8, 7 ]);
assert.deepEqual(result.get(), [ 9, 8, 7 ]);
done();

@@ -21,0 +21,0 @@ });

@@ -10,4 +10,4 @@ 'use strict';

it('should return by default 5 data classes', function (done) {
fn('Green2').then(function (result) {
assert.equal(result.length, 5);
fn('BluGrn').then(function (result) {
assert.equal(result.get().length, 5);
done();

@@ -18,4 +18,4 @@ });

it('should return at least 3 data classes', function (done) {
fn('Green2', 1).then(function (result) {
assert.equal(result.length, 3);
fn('Peach', 1).then(function (result) {
assert.equal(result.get().length, 3);
done();

@@ -26,4 +26,4 @@ });

it('should return at most 7 data classes', function (done) {
fn('Green2', 9).then(function (result) {
assert.equal(result.length, 7);
fn('RedOr', 9).then(function (result) {
assert.equal(result.get().length, 7);
done();

@@ -35,4 +35,4 @@ });

it('should return the correct number of data classes for param=' + numberDataClasses, function (done) {
fn('Green2', numberDataClasses).then(function (result) {
assert.equal(result.length, numberDataClasses);
fn('ArmyRose', numberDataClasses).then(function (result) {
assert.equal(result.get().length, numberDataClasses);
done();

@@ -39,0 +39,0 @@ });

'use strict';
var assert = require('assert');
var fnColorbrewer = require('../../src/fn/fn-colorbrew');
var fnColorbrewer = require('../../src/fn/fn-colorbrewer');

@@ -11,3 +11,3 @@ describe('fn-colorbrewer', function () {

fn('Reds').then(function (result) {
assert.equal(result.length, 5);
assert.equal(result.get().length, 5);
done();

@@ -19,3 +19,3 @@ });

fn('Reds', 1).then(function (result) {
assert.equal(result.length, 3);
assert.equal(result.get().length, 3);
done();

@@ -25,5 +25,5 @@ });

it('should return at most 7 data classes', function (done) {
fn('Reds', 9).then(function (result) {
assert.equal(result.length, 7);
it('should return at most 8 data classes', function (done) {
fn('Dark2', 9).then(function (result) {
assert.equal(result.get().length, 8);
done();

@@ -36,3 +36,3 @@ });

fn('Reds', numberDataClasses).then(function (result) {
assert.equal(result.length, numberDataClasses);
assert.equal(result.get().length, numberDataClasses);
done();

@@ -39,0 +39,0 @@ });

@@ -16,2 +16,6 @@ 'use strict';

});
it('should work with array range as first argument', function () {
assert.deepEqual(interpolate([0, 10], 3), [0, 5, 10]);
});
});

@@ -19,4 +19,3 @@ #!/usr/bin/env node

var postcss = require('postcss');
var PostcssTurboCarto = require('../src/postcss-turbo-carto');
var turbocarto = require('../src/index');
var SqlApiDatasource = require('../examples/sql-api-datasource');

@@ -31,3 +30,6 @@

getRamp: function (column, buckets, method, callback) {
return callback(null, [100000, 250000, 500000, 1e6, 1.5e6, 2e6, 1e7]);
if (method === 'category') {
return callback(null, ['Private Room', 'Entire House', 'Other', 'Complete floor'].slice(0, buckets));
}
return callback(null, [100000, 250000, 500000, 1e6, 1.5e6, 2e6, 1e7].slice(0, buckets));
}

@@ -44,10 +46,8 @@ };

var postCssTurboCarto = new PostcssTurboCarto(datasource);
postcss([postCssTurboCarto.getPlugin()])
.process(cartocss)
.then(function (result) {
console.log(result.css);
})
.catch(function (err) {
turbocarto(cartocss, datasource, function (err, result) {
if (err) {
console.error(err);
});
process.exit(1);
}
console.log(result);
});

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc