carto-vl icon indicating copy to clipboard operation
carto-vl copied to clipboard

viewportFeatures returns null values

Open Captain-Oski opened this issue 5 years ago • 7 comments

Hi ! version : "@carto/carto-vl": "^1.2.3"

In our test case, we would like to get all the viewport features and make some on the fly data normalization WITH category values aggregation such as :

$ / population with aggregated categories

Which is not possible with the viewportHistogram method if I am right.

viewportFeatures returns some null values when we try to make some operations between e.g.

feature.properties.variableName1 / feature.properties.variableName2

The described method return some random null values that will return an error because of the division by null or zero.

This seems only to happen when value is set with an mathematical operation, it behave well when called alone.

See attached the jsfiddle with quite explicite code.

https://jsfiddle.net/captainOski/z47yqovm/ Thank you very much for the good work !

Captain-Oski avatar May 02 '19 15:05 Captain-Oski

Has you said, there's no way to do with the current viewportHistogram and it has to be done "manually". I'm adding here the solution that I think solves your issue. It uses the viewportFeatures expression to go through all the features and calculate the values, which then uses to build the histogram:

Viz:

const viz = new carto.Viz(`
    @v_features: viewportFeatures($here_city, $total_spent, $r1_rta)
`);

Update function:

function histogramFactory () {
       const histogram = new Map();
       const features = layer.viz.variables.v_features.value;
       const defaultValue =  { total: 0, rta: 0 };

       features.forEach(feature => {
          const city = feature.properties.here_city;
          const total = feature.properties.total_spent;
          const rta = feature.properties.r1_rta;
          const currentValue = histogram.has(city) ? histogram.get(city) : defaultValue;
          const value = {
              total: currentValue.total + total,
              rta: currentValue.rta + rta
          }
          
          histogram.set(city, value);
        });
        
     const categories = [];
     histogram.forEach((value, key) => {
        const ratio = (value.total / value.rta) * 100;
        categories.push({ name: key, value: ratio })
      });
        
     $categoryWidget.categories = categories.sort((a, b) => b.value - a.value);
}

Live example here

elenatorro avatar May 03 '19 08:05 elenatorro

Hola !

With the exact same example you gave me I am able to reproduce the issue as described.

Note that the issue is not on the way to achieve the way of creating a proper histogram, but that the layer.viz.variables.v_features.value return null values

Just changed a few variables details but it is self explanatory. I commented where the issue is // ISSUE HERE // console.log(features.filter(a=>a.properties.r1_rta==null)) // ISSUE HERE // See issue as reproduced : https://jsfiddle.net/captainOski/s5jpLzc1/7

Captain-Oski avatar May 03 '19 18:05 Captain-Oski

InfinityG is caused by null values image

Captain-Oski avatar May 03 '19 18:05 Captain-Oski

@elenatorro are you able to reproduce and debug this ? Thank you very much.

Captain-Oski avatar May 13 '19 14:05 Captain-Oski

Hi 👋

Sorry we didn't answer this sooner. We're working on an issue related with null values, but also how can we style these values as 'others', for instance.

Meanwhile, there's a solution to avoid these InfinityG values. We can use the filter expression to filter the values that aren't null, in this case it would be:

const viz = new carto.Viz(`
    @v_features: viewportFeatures($here_city, $total_spent, $r1_rta)
    filter: not(isNull($r1_rta))
`);

Do you think this solution solves your current problem? Thanks!

elenatorro avatar May 13 '19 14:05 elenatorro

I've prioritized the issue to take a deeper look at it 👍

elenatorro avatar May 13 '19 15:05 elenatorro

Thank you for prioritizing this ! 🙏 Unfortunatly this is not solving our issue, we had to make some conditionals , if null => return statistical extrapolation. We can't afford losing data by filtering, this would mean rendering inaccurate information in the widgets. Thank you again.

Captain-Oski avatar May 13 '19 15:05 Captain-Oski