NextGIS Frontend
    Preparing search index...

    Module @nextgis/expression

    Expression

    size version

    @nextgis/expression is a versatile library designed for executing actions on objects based on expressions inspired by the syntax of Maplibre Style expressions. These expressions are JSON-serializable, making them perfect for configurations, data processing, or any other kind of object manipulation.

    • JSON-serializable Expressions: Represent complex logic and operations in a portable and easily shareable format.
    • Zero Dependencies: Built to be completely standalone without relying on external packages.
    • Versatility: Ability to perform various operations on objects directly in JavaScript, from simple retrieval to complex computations.
    • Easy Integration: Designed with a simple API for hassle-free integration into any project.
    # latest stable
    npm install @nextgis/expression

    Expressions are like little command lists inside arrays. The first item in this list tells you what action to do, like "add" or "multiply". The items after that are the things you're acting on.

    For example, to multiply 5 by 3:

    const myExpression = ["*", 5, 3];
    

    To find out what this equals, use the evaluate function:

    import { evaluate } from '@nextgis/expression';

    const answer = evaluate(["*", 5, 3]);
    console.log(answer); // This will show: 15

    You can even put expressions inside other expressions:

    const biggerExpression = ["+", ["*", 5, 3], 4]; // This is like saying (5 times 3) plus 4
    const biggerAnswer = evaluate(biggerExpression);
    console.log(biggerAnswer); // This will show: 19

    When we need to retrieve data stored in an object, the second argument in evaluate becomes invaluable.

    Imagine you have some data:

    const lakeData = {
    name: "Baikal",
    depth: 1642, // in meters
    volume: "23,600 km³", // in cubic kilometers
    islands: ["Olkhon", "Big Ushkany", "Small Ushkany"]
    };

    You can use expressions to access or manipulate parts of this data.

    To fetch the name of the lake:

    const nameExpression = ["get", "name"];
    

    Execute this with evaluate, passing in both the expression and the data:

    const lakeName = evaluate(["get", "name"], lakeData);
    console.log(lakeName); // Outputs: "Baikal"

    Want the first island from the "islands" array? Do this:

    const islandExpression = ["at", 0, ["get", "islands"]];
    const firstIsland = evaluate(islandExpression, lakeData);
    console.log(firstIsland); // Outputs: "Olkhon"

    To visually represent data, sometimes we might want to assign colors based on numerical values. For instance, we can use interpolation to determine a color for Lake Baikal based on its depth.

    Let's decide on a simple color gradient:

    Up to 500 meters: Light Blue (#ADD8E6) At 1642 meters (Baikal's maximum depth): Deep Blue (#00008B)

    const colorExpression = [
    "interpolate", ["linear"], ["get", "depth"],
    500, "#ADD8E6", // Light Blue up to 500 meters
    1642, "#00008B" // Deep Blue at Baikal's max depth
    ];

    const derivedColor = evaluate(colorExpression, lakeData);
    console.log(derivedColor); // Assuming the depth of `lakeData` is at its max, outputs: "#00008B", which corresponds to the Deep Blue color

    Let's move on to exploring all possible expression types and examples of their use.

    Expressions under the "Types" category are designed to work with and convert data types. Here are some of the available types expressions:

    API

    The literal expression provides a way to explicitly label a value as a raw constant, ensuring that it's interpreted as a literal instead of an expression. This can be especially useful in scenarios where there might be ambiguity.

    import { evaluate } from '@nextgis/expression';
    // Without 'literal', the array might be interpreted as an expression.
    const literalExpression = ['literal', [10, 20, 30]];
    console.log(evaluate(literalExpression)); // [10, 20, 30]

    API

    For defining arrays and specifying types within arrays.

    Basic Array

    import { evaluate } from '@nextgis/expression';
    const obj = { array: [1,2,3] }
    console.log(evaluate(['array', ['get', 'array']], obj)); // [1, 2, 3]

    Typed Array

    import { evaluate } from '@nextgis/expression';
    console.log(evaluate(['array', 'number', ['get', 'array']])); // [1, 2, 3] as number[]

    Fixed Length Typed Array

    import { evaluate } from '@nextgis/expression';
    console.log(evaluate(['array', 'string', 2, ["literal", ["Hello", "World"]]])); // ["Hello", "World"] as string[2]

    These are basic type expressions to directly specify a particular type of data.

    Example:

    import { evaluate } from '@nextgis/expression';

    console.log(evaluate(['boolean', true])); // true
    console.log(evaluate(['number', 42])); // 42
    console.log(evaluate(['object', ['literal', { key: "value" }]], obj)); // { key: "value" }
    console.log(evaluate(['string', "Hello World"])); // "Hello World"

    If multiple values are provided for type expressions like 'boolean', each one is evaluated in order until a result of the specified type is obtained. If none of the provided values match the specified type, the expression results in an error.

    // Fallback until a boolean is found
    console.log(evaluate(['boolean', "not a boolean", "still not a boolean", true])); // true

    // Results in an error since none of the values are booleans
    try {
    console.log(evaluate(['boolean', "not a boolean", "still not a boolean", 42]));
    } catch (error) {
    console.error(error.message); // Error: received a mismatched type
    }

    These expressions allow for type conversions.

    const obj = {
    value1: "true",
    value2: "hello", // Not a number
    value3: 100
    };

    console.log(evaluate(['to-boolean', ["get", "value1"], true], obj)); // true
    console.log(evaluate(['to-number', ["get", "value2"], ["get", "value3"]], obj)); // 100 (because "hello" isn't a number, so it takes value3)
    console.log(evaluate(['to-string', ["get", "value3"]], obj)); // "100"

    This expression returns the type of the given value.

    const obj = {
    value: [1, 2, 3]
    };

    console.log(evaluate(['typeof', ["get", "value"]], obj)); // "array"

    The Lookup category of expressions allows users to access and modify specific parts of the data. This category includes methods to extract a value by its key or index, determine if an object has a certain property, find out the length of a string or array, and many others.

    API

    Fetches a value from an array using an index.

    import { evaluate } from '@nextgis/expression';

    const obj = {
    values: [10, 20, 30, 40]
    };

    console.log(evaluate(['at', 2, ['get', 'values']], obj)); // 30

    API

    Retrieves the value of a property from an object.

    const obj = {
    foo: 'bar',
    key: 'foo',
    nested: { key: 'value' },
    };

    // should get value from obj using key
    console.log(evaluate(['get', 'foo'], obj)) // bar
    console.log(evaluate(['get', 'nested'], obj)) // { key: 'value' }

    // should get value from evaluated object using key
    console.log(evaluate(['get', 'key', ['get', 'nested']], obj)) // 'value'

    // should return null for nonexistent keys
    console.log(evaluate(['get', 'nonexistent'], obj)) // null

    API

    console.log(evaluate(['has', 'width'], { type: 'River', width: 30 })); // true
    console.log(evaluate(['has', 'width', ['literal', { type: 'River', width: 30 }]])); // true

    API

    Returns the length of a string or an array.

    console.log(evaluate(['length', ['get', 'name']], { name: 'NextGIS' })); // 7
    

    API

    Checks if an element exists in an array.

    console.log(evaluate(['in', 'blue', ['get', 'colors']], {
    colors: ['red', 'blue', 'green']
    })); // true

    API

    Returns the index of the first occurrence of a substring or an array element.

    const obj = {
    colors: ['red', 'blue', 'green']
    };

    console.log(evaluate(['index-of', 'blue', ['get', 'colors']], obj)); // 1

    API

    Returns a subsection of a string or an array.

    const obj = {
    animals: ['dog', 'cat', 'bird', 'fish']
    };

    console.log(evaluate(['slice', ['get', 'animals'], 1, 3], obj)); // ['cat', 'bird']

    The Decision category provides simple tools to make comparisons and decisions based on your data. These expressions help you check equality, make logic-based choices, and more.

    API

    Returns the logical negation of the input.

    import { evaluate } from '@nextgis/expression';

    console.log(evaluate(['!', true])); // false

    API

    Checks if two values are not equal.

    import { evaluate } from '@nextgis/expression';

    console.log(evaluate(['!=', ['get', 'type'], 'River'], { type: 'Stream' })); // true

    API

    Checks if the first value is less than the second.

    import { evaluate } from '@nextgis/expression';

    console.log(evaluate(['<', ['get', 'length'], 100], { length: 80 })); // true

    API

    Checks if the first value is less than or equal to the second.

    import { evaluate } from '@nextgis/expression';

    console.log(evaluate(['<=', ['get', 'length'], 100], { length: 100 })); // true

    API

    Checks if two values are equal.

    import { evaluate } from '@nextgis/expression';

    console.log(evaluate(['==', ['get', 'type'], 'River'], { type: 'River' })); // true

    API

    Checks if the first value is greater than or equal to the second.

    import { evaluate } from '@nextgis/expression';

    console.log(evaluate(['>=', ['get', 'width'], 50], { width: 60 })); // true

    API

    Checks if the first value is greater than the second.

    import { evaluate } from '@nextgis/expression';

    console.log(evaluate(['>', ['get', 'width'], 50], { width: 40 })); // false

    API

    Evaluates multiple conditions and returns true if all of them are true.

    import { evaluate } from '@nextgis/expression';

    console.log(evaluate(['all', ['>', ['get', 'width'], 50], ['==', ['get', 'type'], 'River']], { width: 60, type: 'River' })); // true

    API

    Evaluates multiple conditions and returns true if at least one of them is true.

    import { evaluate } from '@nextgis/expression';

    console.log(evaluate([
    'any',
    ['>', ['get', 'width'], 100],
    ['==', ['get', 'type'], 'Stream']
    ], { width: 80, type: 'Stream' })); // true

    API

    Evaluates each pair of conditions and values sequentially and returns the output of the first true condition. If none are true, it returns the value of the optional default case.

    import { evaluate } from '@nextgis/expression';

    const obj = {
    two: 2,
    str: 'Foo Bar',
    };

    evaluate([
    'case',
    ['==', ['get', 'two'], 2],
    'matches two',
    ['==', ['get', 'str'], 'Not Foo Bar'],
    'matches string',
    'fallback',
    ],
    obj,
    ) // 'matches two'

    API

    Matches an input with a series of cases, returning the output associated with the first matching case. If there's no match, a default value is returned.

    import { evaluate } from '@nextgis/expression';

    const obj = { shape: 'circle' };
    console.log(evaluate([
    'match',
    ['get', 'shape'],
    'square', 'It is a square',
    'circle', 'It is a circle',
    'Unknown shape'],
    obj)); // 'It is a circle'

    Interpolation expressions allow you to create smooth transitions between values based on your input data. They can be especially useful when visualizing data gradients or when you want to transition between two values.

    API

    The step expression creates a stepped, piecewise-constant function. It's mainly used when you want to categorize your data into specific bins.

    import { evaluate } from '@nextgis/expression';

    const prop = { five: 5, one: 1 };

    console.log(evaluate(['step', ['get', 'five'], 0, 4, 'low', 6, 'medium', 8, 'high'], prop)); // 'low'
    console.log(evaluate(['step', 6, 0, 4, 'low', 6, 'medium', 8, 'high'], prop)); // 'medium'
    console.log(evaluate(['step', 9, 0, 4, 'low', 6, 'medium', 8, 'high'], prop)); // 'high'
    console.log(evaluate(['step', ['get', 'one'], 'low', 6, 'medium', 8, 'high'], prop)); // 'low'

    API

    The interpolate expression provides smooth transitions between pairs of input and output values.

    Currently, only linear interpolation is supported.

    import { evaluate } from '@nextgis/expression';

    const prop = { value: 5 };

    // Interpolating numbers:
    console.log(evaluate([
    'interpolate',
    ['linear'],
    ['get', 'value'],
    0, 10,
    10, 20
    ], prop)); // 15

    // Interpolating HEX colors:
    console.log(evaluate([
    'interpolate',
    ['linear'],
    ['get', 'value'],
    0, '#000000',
    10, '#ffffff'
    ], prop
    )); // 'rgb(128,128,128)'

    // Interpolating Named colors:
    console.log(evaluate([
    'interpolate',
    ['linear'],
    ['get', 'value'],
    0, 'black',
    10, 'white'
    ], prop
    )); // 'rgb(128,128,128)'

    // Interpolating RGB colors:
    console.log(evaluate([
    'interpolate',
    ['linear'],
    ['get', 'value'],
    0, 'rgb(0,0,0)',
    10, 'rgb(255,255,255)'
    ], prop)); // 'rgb(128,128,128)'

    // Interpolating with multiple stops
    console.log(evaluate([
    'interpolate',
    ['linear'],
    14,
    0, 10,
    5, 20,
    10, 30,
    15, 40
    ])); // 38

    API

    The Math category includes a comprehensive set of mathematical operations to perform arithmetic, trigonometric, logarithmic, and other related calculations.

    Supported Operations:

    • Arithmetic: +, -, *, /, %, ^, abs, ceil, floor, round, max, min, sqrt
    • Trigonometric: acos, asin, atan, cos, sin, tan
    • Logarithmic and Exponential: ln, ln2, log10, log2, e
    import { evaluate } from '@nextgis/expression';

    // Summation (multiple arguments):
    evaluate(['+', 1, 2, 3, 4]); // Outputs: 10

    // Subtraction (two arguments):
    evaluate(['+', 1, 2, 3, 4]); // Outputs: 10

    // Sine function (single argument):
    evaluate(['sin', ['/', 'pi', 2]]); // Outputs: 1

    Need to fix a bug or add a feature to @nextgis/expression? We provide custom development and support for this software. Contact us to discuss options!

    http://nextgis.com

    Type Aliases

    Data
    DecisionExpressionName
    Expression
    ExpressionCbFunc
    ExpressionFunc
    ExpressionName
    InterpolationExpressionName
    LookupExpressionName
    MapToCallback
    MathExpressionName
    SimpleType
    StringExpressionName
    TypeExpressionName

    Functions

    evaluate
    isExpression