2017-01-24 1 views
1

Je suis un novice dc.js travaillant sur un tableau de bord affichant des informations sur les cartes et une carte.Dc.js leaflet marker popup montrant les champs à partir des données d'entrée

Je suis actuellement incapable d'afficher des informations sur la fenêtre contextuelle du marqueur en dehors de la valeur par défaut, qui semble être les coordonnées d'un point (geo) et le nombre d'occurrences. Code actuel est:

var facilities = xf.dimension(function(d) { return d.geo; }); 
var facilitiesGroup = facilities.group().reduceCount(); 

dc.leafletMarkerChart("#test .map",groupname) 
    .dimension(facilities) 
    .group(facilitiesGroup) 
    .width(540) 
    .height(440) 
    .center([0,0]) 
    .zoom(7) 
    .cluster(true) 
    .filterByArea(true) 
    .renderPopup(true) 
    .popup(); 

J'ai essayé de changer la fenêtre comme suit:

.popup(function(d,feature) { return feature.name +" : "+feature.items; }); 

Pour inclure le nom de l'emplacement et le nombre d'éléments là-bas. Cependant, les fenêtres pop-up mentionnent juste "undefined: undefined".

Je suis sûr qu'il y a une solution facile que j'ignore simplement en raison de mon expérience limitée. Quelqu'un peut-il aider?

+0

Qu'est-ce qu'une fonctionnalité? Et que sont 'feature.name' et' feature.items'? Sont-ils dans vos données que vous avez passées à crossfilter? – Gordon

+0

Excuses, cela vient du code précédent. J'ai essayé la même chose en utilisant 'd.name' et' d.items'. "Nom" et "Articles" sont d'autres colonnes dans le même fichier CSV contenant les données géographiques. – zanmatt

Répondre

2

Le cœur de dc.js et crossfilter est une sorte de carte et de réduire, où les bacs sont trouvés pour chaque valeur, puis les lignes qui atterrissent dans chaque bac sont agrégées.

Mais il semble que vous essayez d'afficher directement vos données dans la carte de brochure sans aucune agrégation. Si vous voulez agréger, vous devrez décider comment agréger items (vous n'avez pas montré vos données donc je ne sais pas de quoi il s'agit), et devrez probablement quitter le name parce que les noms ne le font généralement pas agrégat. Donc, je suggère de dire crossfilter à bin par son nom (en supposant que c'est unique) au lieu de l'emplacement, puis de conserver l'emplacement et les éléments, ainsi que de garder un compte. Malheureusement, cela est un peu à contre-courant à l'objectif principal de crossfilter, de sorte que le code est un peu maladroit:

var facilities = xf.dimension(function(d) { return d.name; }); 
var facilitiesGroup = facilities.group().reduce(
    function(p, v) { // add 
     p.items = v.items; 
     p.geo = v.geo; 
     ++p.count; 
     return p; 
    }, 
    function(p, v) { // remove 
     --p.count; 
     return p; 
    }, 
    function() { // init 
     return {count: 0}; 
    } 
); 

Nous sommes juste partons du principe que les noms sont uniques et saisir les champs du premier enregistrement que nous voyons. Maintenant, le groupe crossfilter retourne un tableau de paires clé-valeur, où le nom sera le key et la {count, items, geo} sera la valeur, afin que nous puissions dire-feuillet dc comment les lire:

dc.leafletMarkerChart("#test .map",groupname) 
    // ... 
    .valueAccessor(function(kv) { 
     return kv.value.count; 
    }) 
    .locationAccessor(function(kv) { 
     return kv.value.geo; 
    }) 
    .popup(function(kv) { 
     return kv.key + " : " + kv.value.items; 
    }) 

kv est un convention que j'aime utiliser pour me rappeler que les données d vont presque toujours être une paire valeur/clé. (Dans certains diagrammes cc, il s'agit d'un objet qui contient un membre data qui est la paire valeur/clé.)

Notez que cela est différent du comportement par défaut de la feuille de calcul dynamique, à regrouper par emplacement et à définir le emplacement comme la clé. Si vos emplacements sont garantis uniques, vous pouvez aussi le faire de cette façon, mais cela me semble risqué (des données pourraient être perdues). Je pense qu'il est préférable d'utiliser une clé vraiment unique si vous voulez afficher les données d'origine sans agrégation.

+0

Merci beaucoup pour votre réponse et mes excuses pour mon commentaire très tardif.J'ai essayé ceci et le tableau de bord ne chargera pas. Les 'items' sont en effet quantitatifs, et le' nom' est unique. Toutefois, lorsque j'ajoute ce code, le tableau de bord ne se charge pas. Firebug me dit que c'est un 'SyntaxError: expression attendue, got '-''. Des idées? J'ai encore beaucoup à apprendre avec dc.js et crossfilter, mais cela m'a beaucoup aidé. – zanmatt

+0

Hmm, je n'ai pas testé cela, et je vois qu'il y avait une incompatibilité de support, que j'ai corrigée. Est ce que ça aide? – Gordon

+0

En fait, je suis un idiot! J'avais fait une faute de frappe dans une ligne et seulement maintenant réussi à le trouver. Ça a marché! Merci beaucoup :) Je publierai bientôt le tableau de bord en ligne et serai heureux de vous envoyer un lien. – zanmatt

0

La leafletMarkerChart ne fonctionnait pas dans mon cas. Il n'a montré aucune erreur ni popups. En utilisant la même approche sur la fonction standard dc-leaflet.js, vous pouvez effectuer les opérations suivantes:

var restaurantsGroup = restaurantNames.group().reduce(
        function(p, v) { // add 
        p.name = v.name; 
        p.price_range = v.price_range; 
        p.stars = v.stars; 
        p.latitude = v.latitude; 
        p.longitude = v.longitude; 
      ++p.count; 
      return p; 
       }, 
       function(p, v) { // remove 
       --p.count; 
       return p; 
       }, 
       function() { // init 
       return {count: 0}; 
       } 
      ); 


var marker = dc_leaflet.markerChart("#demo1 .map", groupname) //map formatting 
     .dimension(restaurantNames) 
     .group(restaurantsGroup) 
     .width(700) 
     .height(500) 
     .center([43.733372, -79.354782]) 
     .zoom(11) 
     .cluster(true) 
    .valueAccessor(function(kv) { 
      return kv.value.count; 
    }) 
    .locationAccessor(function(kv) { 
      return [kv.value.latitude,kv.value.longitude] ; 
    }) 
    .popup(function(kv,marker) { 
      return kv.value.name + " - " + kv.value.stars + " * - " + 
      kv.value.price_range + "$"; 
     });