CartoDB / carto-vl

CARTO VL: a Javascript library to create vector-based visualizations
BSD 3-Clause "New" or "Revised" License
129 stars 26 forks source link

Not honouring duration in blendTo with variable #864

Open rochoa opened 6 years ago

rochoa commented 6 years ago

The following example doesn't animate when invoking viz.variables.val.blendTo(s.prop('nanprop'), 5000); and inmideately transition to the new style.

const map = new mapboxgl.Map({
    container: 'map',
    style: 'https://basemaps.cartocdn.com/gl/voyager-gl-style/style.json',
    center: [0, 0],
    zoom: 2,
    dragRotate: false,
    touchZoomRotate: false,
});

const s = carto.expressions;

const mapconfig = {
    layers: [
        {
            options: {
                sql: `
                    WITH geoms AS (
                        SELECT
                            1 as cartodb_id,
                            st_makeenvelope(-90, -45, 0, 0, 4326) as the_geom,
                            null::numeric as nanprop,
                            10 as numprop

                        UNION ALL

                        SELECT
                            2 as cartodb_id,
                            st_makeenvelope(0, 0, 90, 45, 4326) as the_geom,
                            null::numeric as nanprop,
                            20 as numprop
                    )
                    SELECT *, ST_Transform(the_geom, 3857) as the_geom_webmercator
                    FROM geoms
                `
            }
        }
    ]
}

const viz = new carto.Viz(`
    @val: $numprop
    color: blend(ramp(linear(@val, 0, 50), temps), grey, isnan(@val))
`);

fetch(`https://cartovl.carto.com/api/v1/map?api_key=default_public&config=${encodeURIComponent(JSON.stringify(mapconfig))}`)
    .then(response => response.json())
    .then(layergroup => {
        const source = new carto.source.MVT(layergroup.metadata.tilejson.vector.tiles, {
            idProperty: 'cartodb_id',
            properties: {
                nanprop: {
                    type: 'number',
                    min: 0,
                    max: 50
                },
                numprop: {
                    type: 'number',
                    min: 0,
                    max: 50
                }
            }
        });

        const layer = new carto.Layer('layer', source, viz);

        layer.addTo(map);

        layer.on('loaded', () => {
            viz.variables.val.blendTo(s.prop('nanprop'), 5000);
        });
    });
davidmanzanares commented 6 years ago

This is not a bug, it's a feature!

No kidding, actually, see https://github.com/CartoDB/carto-vl/blob/master/src/Layer.js#L242 We don't honor blendTo when it is known to cause a re-instantiation because the only way to do it would be to wait for the first instantiation with both properties then the blend, and finally another instantiation without the first property.

The latency of the first instantiation is not really good and we considered that the experience is better if we ignore those blendings.

rochoa commented 6 years ago

But in this case, this doesn't require a new instantiation: the data and the metadata are already in the client.

Actually, if instead of having null values in the nanprop property, I have valid numeric values, the transition works.

You can try it yourself by changing the query as in:

@@ -2,7 +2,7 @@ WITH geoms AS (
     SELECT
         1 as cartodb_id,
         st_makeenvelope(-90, -45, 0, 0, 4326) as the_geom,
-        null::numeric as nanprop,
+        30::numeric as nanprop,
         10 as numprop

     UNION ALL
@@ -10,7 +10,7 @@ WITH geoms AS (
     SELECT
         2 as cartodb_id,
         st_makeenvelope(0, 0, 90, 45, 4326) as the_geom,
-        null::numeric as nanprop,
+        60::numeric as nanprop,
         20 as numprop
 )
 SELECT *, ST_Transform(the_geom, 3857) as the_geom_webmercator