2014-09-16 3 views
0

J'essaie d'obtenir un graphique à bulles fonctionnant avec crossfilter et dc.js. Mais j'ai un problème pour faire apparaître mes points sur mon tableau. Je l'ai construit un jsFiddle ici:dc.js graphique à bulles ne parvient pas à afficher les points

http://jsfiddle.net/4asmb7h1/

var data = [ 
    {date: "12/27/2012", label: "a1", x: 2, y: 190, bubble: 5}, 
    {date: "12/28/2012", label: "a2", x: 2, y: 10, bubble: 5}, 
    {date: "12/29/2012", label: "a3", x: 95, y: 300, bubble: 10} 
]; 
var ndx = crossfilter(data); 
var parseDate = d3.time.format("%m/%d/%Y").parse; 
data.forEach(function(d) { 
    d.date = parseDate(d.date); 
}); 
var dateDim = ndx.dimension(function(d) {return d.date;}); 
var xDim = ndx.dimension(function(d) {return d.x;}); 
var bubbleChart = dc.bubbleChart("#bubble-chart"); 
bubbleChart 
    .dimension(dateDim) 
    .group(xDim) 
    .x(d3.scale.linear().domain([0, 100])) 
    .y(d3.scale.linear().domain([0, 100])) 
    .width(400) 
    .height(400) 
    .yAxisPadding(50) 
    .xAxisPadding(50) 
    .xAxisLabel('X') // (optional) render an axis label below the x axis 
    .yAxisLabel('Y') // (optional) render a vertical axis lable left of the y axis 
    .label(function (p) { 
     return p.label; 
    }) 
    .renderLabel(true) 
    .title(function (p) { 
     return [ 
       "x: " + p.x, 
       "y: " + p.y, 
       "Bubble: " + p.bubble, 
       ] 
       .join("\n"); 
    }) 
    .renderTitle(true) 
    .renderHorizontalGridLines(true) // (optional) render horizontal grid lines, :default=false 
    .renderVerticalGridLines(true) 
    .maxBubbleRelativeSize(0.3) 
    .keyAccessor(function (p) { 
     return p.y; 
    }) 
    .valueAccessor(function (p) { 
     return p.x; 
    }) 
    .radiusValueAccessor(function (p) { 
     return p.bubble; 
    }) 
; 

pouvez afficher les données via la table de données en bas, donc je sais que les données sont visibles. Ma meilleure idée à ce stade est que je ne suis pas en train de mettre en œuvre mes groupes ou mes dimensions correctement, mais rien que je semble essayer de travailler pour moi.

Quelqu'un peut-il voir ce que je fais mal ici? Je cherche les points à afficher comme data.x, data.y avec une taille de bulle de data.bubble.

EDIT: mise à jour de la question pour inclure plus de configuration JS. (Tout le code est sur mon violon)

+1

Je suis désolé, mais simplement demander aux autres de déboguer votre code ne fait pas une grande question SO. En particulier, vous voudrez 1. Regardez la console de débogage pour toutes les erreurs 2. https://github.com/dc-js/dc.js/wiki/FAQ#tell-whether-my-groups-are- function-correctement - if-my-input-data-is-good 3. Le débogueur dans votre navigateur est votre ami. – Gordon

+0

Je n'essaie pas de vous faire déboguer mon code. Comme je l'ai dit, je pense avoir compris où était mon problème (groupes/dimensions). Ce n'est pas vraiment mon "code" autant qu'un violon pour essayer de reproduire le problème. J'ai grandement simplifié le code pour essayer de le rendre plus facile. Il n'y a pas d'erreurs de console. Je pense qu'il est clair que j'ai des problèmes avec le regroupement, car c'est la partie du code que je comprends le moins. – awildeep

+0

Wow, on dirait que vous avez trouvé un cas étrange de dc.js. Il ne devrait pas être possible de transmettre une dimension en tant que groupe. Il arrive juste qu'ils aient tous les deux une fonction '.top', c'est pourquoi ils n'ont généré aucune erreur. Pouah. – Gordon

Répondre

4

Je peux voir quelques mauvaises choses:

  1. Dans le graphique à bulles, vous passez une dimension en tant que paramètre de groupe. dc.js s'attend à ce que vous transmettiez un groupe précédemment déclaré à ce paramètre.

  2. Il ne semble pas que vous utilisiez les avantages de crossfilter ici. L'idée est de regrouper et de résumer vos données. Vos dimensions résultent en une valeur unique étant créée pour chaque valeur de la dimension, ce qui est OK, mais il manque en quelque sorte le point de crossfilter. Lorsque vous référencez les propriétés de l'objet groupé, vous ne les référencez pas correctement. Lorsque crossfilter groupe des éléments, il créera de nouveaux objets avec key et value propriétés contenant la clé (correspond à une valeur dimension) et une valeur (calculée à partir de la fonction reduce). Vous n'utilisez pas ces propriétés à partir de l'objet groupé.

Ceci étant dit, voici un jsfiddle qui peut vous aider: http://jsfiddle.net/0w3xnbu0/5/

Je pense que j'ai produit ce que vous êtes après.

Les changements que j'ai créés sont:

  1. créé un objet qui dateGroup groupes et réduit vos données afin que le bubbleChart peut charger. Ceci est potentiellement incorrect, en particulier si vos données réelles incluent plusieurs enregistrements avec la même date. Pour l'adapter à d'autres ensembles de données, vous aurez certainement besoin de changer les fonctions dans la partie reduce de cet objet.

    var dateGroup = dateDim.group().reduce(
        function(p, v) { 
         ++p.count; 
         p.label = v.label; 
         p.bubble = v.bubble; 
         p.x = v.x; 
         p.y = v.y; 
    
         return p; 
        }, 
        function(p, v) { 
         --p.count; 
         p.bubble = 0; 
         p.label = ""; 
         p.x = 0; 
         p.y = 0; 
    
         return p; 
        }, function() { 
         return { count: 0, x: 0, y:0, label: "" }; 
        }); 
    
  2. Création d'un xRange et yRange objet qui définit correctement les min et max valeurs de vos x et y valeurs, plutôt que hardcoding à [0, 100].

    var xRange = [-10, d3.max(dateGroup.all(), function(d) { return d.value.x + d.value.bubble*2; }) ], 
        yRange = [-10, d3.max(dateGroup.all(), function(d) { return d.value.y + d.value.bubble*2; }) ]; 
    
  3. Mis à jour l'objet BubbleChart utiliser la nouvelle dateGroup et x et échelles y sur l'appel BubbleChart à utiliser les nouvelles gammes ci-dessus

    bubbleChart 
        .dimension(dateDim) 
        .group(dateGroup) 
        .x(d3.scale.linear().domain(xRange)) 
        .y(d3.scale.linear().domain(yRange)) 
    
  4. changé les title, keyAccessor, valueAccessor et radiusValueAccessor fonctions bubbleChart pour référencer correctement les valeurs appropriées de l'objet groupé.

    .title(function (p) { 
         return [ 
          "x: " + p.value.x, 
          "y: " + p.value.y, 
          "Bubble: " + p.value.bubble, 
          ] 
          .join("\n"); 
        }) 
    ... 
        .keyAccessor(function (p) { 
         return p.value.x; 
        }) 
        .valueAccessor(function (p) { 
         return p.value.y; 
        }) 
        .radiusValueAccessor(function (p) { 
         return p.value.bubble; 
        }) 
    
+0

Ben, merci beaucoup pour cet article. Vous avez raison de dire que je n'utilise pas de crossfilter dans mon exemple, mais cela est principalement dû au fait que j'essaie de simplifier mon code pour plus de lisibilité et que j'ai besoin de crossfilter dans mon code pour filtrer les autres méta-données associées. Dates, etc). – awildeep

Questions connexes