0

I'm trying to update some dataviews' operation by a select item. The operation has been changed but the data didn't (so it doesn't trigger a 'dataChanged'). I've tried without boundingBoxFiltering but with no results. So is there a way to force the dataview to recalculate the data from the new operation?

enter image description here

  <div id="widgets">
    <div class="widget-container" id="menu"></div>
    <select id="operation" class="select">
       <option value="sum">SUM</option>
       <option value="count">COUNT</option>
       <option value="avg">AVG</option>
       <option value="max">MAX</option>
       <option value="min">MIN</option>
     </select>
    <button onclick="applyDataviewChanges()" class="button">Apply</button>
   <div class="widget-container" id="widget1"></div>

     <div class="widget-container" id="widget2"><div class="info" id="content"></div></div>

   </div>
 </div>


</div>
<script>



  console.log(carto.version)





const map = L.map('map').setView([48, 2], 8);
  // Adding Voyager Basemap
L.tileLayer('https://api.mapbox.com/styles/v1/sducournau/cjfmqj0r517kr2snx3htweipo/tiles/256/{z}/{x}/{y}@2x?access_token=pk.eyJ1Ijoic2R1Y291cm5hdSIsImEiOiJjajk5dDRiamQxMTVsMzB0NGw4ZmVtZWVrIn0.xdXP6dldSqtgXbk-SR3lOw', {
  maxZoom: 24
  }).addTo(map);
const client = new carto.Client({
    apiKey: 'xxxxxx',
    username: 'xxxxxx'
});


const entreprisesSource = new carto.source.Dataset(`
  teset
`);

const source = new carto.source.Dataset(`
  teset
`);
const entreprisesStyle = new carto.style.CartoCSS(`
  #layer {
    marker-width: ramp([tca], range(5, 20), jenks(5));
    marker-fill: ramp([secteur], ( '#ffaf40','#17c0eb', '#ff3838', '#38ada9', '#b8e994', '#7158e2'), category);
    marker-fill-opacity: 0.8;
    marker-allow-overlap: false;
    marker-line-width: 0;
    marker-line-color: #FFFFFF;
    marker-line-opacity: 1;}
`);





const entreprises = new carto.layer.Layer(entreprisesSource, entreprisesStyle, {
  featureOverColumns: ['denomination','secteur'], featureClickColumns: ['lien_google','libelle_ape___activite','ca_2012','ca_2013','ca_2014','ca_2015','ca_2016','denomination','ville', 'ca_moyen']
});

console.log(entreprises);

const popup = L.popup({ closeButton: false });

client.addLayers([entreprises]);
client.getLeafletLayer().addTo(map);


let data_ca2012 = null,
    data_ca2013 = null,
    data_ca2014 = null,
    data_ca2015 = null,
    data_ca2016 = null,
    data_camoyen = null;


const dataview_ca2012 = new carto.dataview.Category(entreprisesSource, 'secteur', { limit: 7, operation: 'sum', operationColumn: 'ca_2012' });
const dataview_ca2013 = new carto.dataview.Category(entreprisesSource, 'secteur', { limit: 7, operation: 'sum', operationColumn: 'ca_2013' });
const dataview_ca2014 = new carto.dataview.Category(entreprisesSource, 'secteur', { limit: 7, operation: 'sum', operationColumn: 'ca_2014' });
const dataview_ca2015 = new carto.dataview.Category(entreprisesSource, 'secteur', { limit: 7, operation: 'sum', operationColumn: 'ca_2015' });
const dataview_ca2016 = new carto.dataview.Category(entreprisesSource, 'secteur', { limit: 7, operation: 'sum', operationColumn: 'ca_2016' });
const dataview_camoyen = new carto.dataview.Category(source, 'secteur', {
        limit: 7,
        operation: carto.operation.SUM,
        operationColumn: 'ca_moyen'
      });



dataview_ca2012.on('error', error => {
        alert(error.message);
        });

dataview_ca2012.on('dataChanged', newData => {
        data_ca2012 = newData;
        onDataChanged();
      });

dataview_ca2013.on('dataChanged', newData => {
        data_ca2013 = newData;
        onDataChanged();
      });

dataview_ca2014.on('dataChanged', newData => {
        data_ca2014 = newData;
        onDataChanged();
      });

dataview_ca2015.on('dataChanged', newData => {
        data_ca2015 = newData;
        onDataChanged();
      });

dataview_ca2016.on('dataChanged', newData => {
        data_ca2016 = newData;
        onDataChanged();
      });

dataview_camoyen.on('dataChanged', newData => {
        data_camoyen = newData;
        console.log(data_camoyen);
      });



function onDataChanged() {
        if (!data_ca2012 || !data_ca2013 || !data_ca2014 || !data_ca2015 || !data_ca2016) {
          return;
        }
        d3.select("#infofiche").remove();
        var chart = initVizu ();



        data_ca2012 = data_ca2012.categories
        .map(category => {
          return {
            secteur: category.name,
            ca: category.value
          }
        })


        data_ca2013 = data_ca2013.categories
        .map(category => {
          return {
            secteur: category.name,
            ca: category.value
          }
        })

        data_ca2014 = data_ca2014.categories
        .map(category => {
          return {
            secteur: category.name,
            ca: category.value
          }
        })

        data_ca2015 = data_ca2015.categories
        .map(category => {
          return {
            secteur: category.name,
            ca: category.value
          }
        })

        data_ca2016 = data_ca2016.categories
        .map(category => {
          return {
            secteur: category.name,
            ca: category.value
          }
        })

        var data = data_ca2012.map((category, i) => {
            return {

              secteur: data_ca2012[i].secteur,
              ca2012: data_ca2012[i].ca,
              ca2013: data_ca2013[i].ca,
              ca2014: data_ca2014[i].ca,
              ca2015: data_ca2015[i].ca,
              ca2016: data_ca2016[i].ca

            }
          })

          data_ca2012 = data_ca2013 = data_ca2014 = data_ca2015 = data_ca2016 = null;
      vizu(data, chart);
    }


entreprises.on('featureOver', featureEvent => {
  popup.setLatLng(featureEvent.latLng);

  if (!popup.isOpen()) {
      popup.setContent(featureEvent.data.denomination);
      popup.openOn(map);
    }
  });

entreprises.on('featureOut', featureEvent => {
popup.removeFrom(map);
      });

entreprises.on('featureClicked', featureEvent => {

  var chart = initVizu ();
  let content = '';
  content += `<div id="infofiche">`;
  content += `<h5>${featureEvent.data.denomination}</h5>`;
  content += `<h5>${featureEvent.data.ville}</h5>`;
  content += `<p>${featureEvent.data.libelle_ape___activite}</p>`;

  content += `<p>${featureEvent.data.ca_moyen} <small> € CA moyen</small></p>`;

  content += `<a class="lien_google" target="_blank" style="font-size:140%;" href="${featureEvent.data.lien_google}"><img src="https://www.google.fr/images/branding/googlelogo/2x/googlelogo_color_120x44dp.png" style="width:30%;height:30%;border:0;"></a>`;
  content += `</div>`;
  document.getElementById('content').innerHTML = content;
  var data =
    [{
    secteur: featureEvent.data.secteur,
    ca2012: featureEvent.data.ca_2012,
    ca2013: featureEvent.data.ca_2013,
    ca2014: featureEvent.data.ca_2014,
    ca2015: featureEvent.data.ca_2015,
    ca2016: featureEvent.data.ca_2016,
    caMoyen: featureEvent.data.ca_moyen

    }];

    vizu(data, chart);



      });



const bboxFilter = new carto.filter.BoundingBoxLeaflet(map);


client.addDataviews([dataview_ca2012, dataview_ca2013, dataview_ca2014, dataview_ca2015, dataview_ca2016]);

client.addDataview(dataview_camoyen);


dataview_ca2012.addFilter(bboxFilter);
dataview_ca2013.addFilter(bboxFilter);
dataview_ca2014.addFilter(bboxFilter);
dataview_ca2015.addFilter(bboxFilter);
dataview_ca2016.addFilter(bboxFilter);
dataview_camoyen.addFilter(bboxFilter);



function applyDataviewChanges() {

                const operation = document.getElementById('operation').value;
              dataview_ca2012.setOperation(operation);
              dataview_ca2013.setOperation(operation);
              dataview_ca2014.setOperation(operation);
              dataview_ca2015.setOperation(operation);
              dataview_ca2016.setOperation(operation);
              dataview_camoyen.setOperation(operation);



              }



</script>

  • It should change, but you should add the bbox-filtering. Can you share the code? – ramiroaznar Apr 12 '18 at 6:11
2

Disclaimer: I work at CARTO

I guess that you're using a Category dataview. Am I right? In that case, I've tried the example on CARTO.js documentation and a change on the operation triggers the dataChanged event.

In that example, we call categoryDataview.setOperation('AVG') and the categoryDataview.on('dataChanged'... handler is being called.

In that example no Bounding Box filter is used.

Can you share a code snippet of the dataview related operations?

UPDATE:

Now that I can access your map I see that the problem is that the map is running into limit errors. The problem is that you're changing 6 dataviews at the same time. At this time there's no bulk operations so they're instantiating the map 6 times and the server can't deal with that throughput.

A possible workaround is to space the dataviews setOperation.

``` function applyDataviewChanges() { const operation = document.getElementById('operation').value; const dataviews = [dataview_ca2012, dataview_ca2013, dataview_ca2014, dataview_ca2015, dataview_ca2016, dataview_camoyen];

let index = 0;
const intervalId = setInterval(() => {
  const dataview = dataviews[index];
  dataview.setOperation(operation);
  index++;
  if (index === dataviews.length) {
    clearInterval(intervalId);
  }
}, 2000);

} ```

This has two disadvantages: 1.- The change takes a lot more of time to be reflected. I've tried with different intervals and the best one was 2 seconds between setOperations. 2.- Because of that, you'd need a visual clue for showing the user that the app is working. A spinner, for instance.

Thanks for your map because we were not sure if allowing bulk operations was worth it but now we see that there are cases for it. We'll do a quick test to allow them and I'll ping you when it's ready. In the meantime you can try with the "hack" above.

  • Yes i use Bounding Box Filter for my chart and it works but changing the operation doesn't. I've tried comparing the category example which is working and my code but did not succeed. Some tries the operation change works and my data is updated but it's random and only one time by charging the app. – Simon Ducournau Apr 12 '18 at 15:52
  • I've been trying to change the operation via the console by typping this : dataview_ca2012._changeProperty('operation', 'avg', 'aggregation') equivalent to : dataview_ca2012.setOperation('avg') This did work. I think that when i perform multiple dataviews' operation changes, there are multiple calls and the engine is lost. So one solution could be to update dataviews' operation separately. (Sorry i'm not very fluent in english) – Simon Ducournau Apr 12 '18 at 19:55
  • If you switch from COUNT to MAX and back, do you get data change events? If that's the case, what it's likely happening is that you have one row per secteur. In that case, having only one row, SUM, AVG, MAX and MIN returns the same data, so no dataChanged event is triggered. – Ivan Malagon Apr 12 '18 at 20:31
  • No there is no data change when switching but if i change manually in the command prompt the operation of a third dataview like "dataview_camoyen" which not appears on the chart it triggers a data change for all. youtu.be/rAU6lEqdP14 – Simon Ducournau Apr 12 '18 at 22:21
  • You can reproduce it here – Simon Ducournau Apr 12 '18 at 22:27

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.