3 votes

Comportement étrange pour la fonction de groupe Crossfilter

Je rencontre un problème étrange en utilisant dc.js et Crossfilter. Imaginez les données et le code suivants

test_data = [{date: d3.time.format("%Y-%m-%dT%H:%M:%S+0100").parse("2014-11-24T12:00:00+0100"), cnt: 1}, 
             {date: d3.time.format("%Y-%m-%dT%H:%M:%S+0100").parse("2014-11-24T11:00:00+0100"), cnt: 2},
             {date: d3.time.format("%Y-%m-%dT%H:%M:%S+0100").parse("2014-11-24T12:00:00+0100"), cnt: 3}],
test_ndx = crossfilter(test_data),
test_dim = test_ndx.dimension(function(d) { return d.date; }),
test_grp = test_dim.group(function(d) { return d.getHours(); });

test_grp.all() renvoie à [{key: 11, value: 1}, {key: 12, value: 2}] comme je m'y attendais.

Si je change la dernière ligne en

test_grp = test_dim.group(function(d) { return -d.getHours(); });

test_grp.all() renvoie à [{key: -11, value: 3}] .

Pourquoi cela ne revient-il pas [{key: -11, value: 1}, {key: -12, value: 2}] ?

5voto

Gordon Points 12563

Je ne pense pas que ce soit un problème dans crossfilter ; je pense que c'est que vous désobéissez à l'API de crossfilter, qui stipule :

Comme la fonction de valeur, Valeur du groupe doit retourner une valeur naturellement ordonnée ; de plus, cet ordre doit être cohérent avec l'ordre des dimensions. valor fonction !

https://github.com/crossfilter/crossfilter/wiki/API-Reference#dimension_group

Plus précisément

L'ordre des valeurs votre Valeur du groupe sont inversés par rapport à l'ordre des valeurs de vos dimensions. valor en raison du signe moins.

Je simplifie à l'extrême, mais au fond, le groupe de filtrage croisé tente de conserver un index des bacs dans le même ordre que la dimension a son propre index de toutes les valeurs. Si les valeurs ne sont pas dans l'ordre dans l'index du groupe, celui-ci ne sera pas en mesure de déterminer correctement les limites des bacs. De telles hypothèses simples font partie de ce qui rend crossfilter si rapide.

Voici un exemple plus simple qui n'utilise pas de dates et qui a le même comportement :

test_data = [{date: 12, cnt: 1}, 
             {date: 11, cnt: 2},
             {date: 12, cnt: 3}],
test_ndx = crossfilter(test_data),
test_dim = test_ndx.dimension(function(d) { return d.date; }),
test_grp = test_dim.group(function(d) { return -d; });

Ce site test_grp contient également [{"key":-11,"value":3}]

Généralement

En fait, tout date.getAnything() ne fonctionnera généralement pas dans une fonction de valeur de groupe (avec des dates pour la fonction de valeur de dimension), à moins que les observations ne couvrent exactement la même chose.

Par exemple, disons que vous utilisez date.getMonth() - si tous les jours sont d'un même mois, tout va bien car l'ordre de la dimension correspond à celui du groupe. Mais si les dates sont le 29 mars, le 31 mars, le 1er avril, le 2 avril, le filtre croisé peut décider qu'il peut créer une limite de groupe à la fin du 29 mars, et mettre les trois dernières dates dans le deuxième bac, ou une limite de groupe à la fin du 1er avril avec les trois premières dates dedans.

Encore une fois, je simplifie et ce n'est pas exactement ce que fait crossfilter. Mais son algorithme s'appuie sur < y <= fonctionne de la même manière pour les valeurs de dimension que pour les valeurs de groupe. Si ce n'est pas le cas, il ne détectera pas le problème (car cela serait lent) - il créera simplement en silence la mauvaise agrégation.

Comme pour la plainte commune selon laquelle NaN ne fonctionne pas parce qu'il n'est pas correctement ordonné, il y a de la place pour une bibliothèque de validation en plus de crossfilter. Mais vous aurez toujours besoin de configurer crossfilter selon ses hypothèses, qui le rendent très efficace pour ce qu'il fait.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X