2016-07-18 11 views
0

Ich arbeite an ein paar einfache DC, D3 und Crossfilter Daten Visualisierung Charts. Nach viel Basteln und Betrachten verschiedener Beispiele kann ich immer noch nicht herausfinden, warum die Balken auf dem Balkendiagramm verschwinden, wenn ich den Pinsel darüber bewege.DC.js barchart Balken verschwinden auf Pinsel und Gesamtbetrag für Datumsbereich Probleme

Eine andere Sache, mit der ich Probleme habe, ist der Versuch, ein zweites Diagramm zu erstellen und es mit den Datumsbereichen zu verknüpfen, die im ersten ausgewählt wurden. Das erste Problem muss offensichtlich behoben werden, damit es funktioniert, aber ich weiß, dass es auch andere Probleme mit meinem Code gibt. Ich möchte, dass dieses zweite Diagramm ein Balkendiagramm mit einem einzelnen Balken ist, der die Summe des Felds "h" für die ausgewählten Daten im ersten Diagramm anzeigt. Noch bevor der Pinsel bewegt wird, zeigt er nur drei für die Summe, also füttert er nur die h-Dimension und eine Gruppe, die ich erstellt habe, ist nicht ausreichend.

JSFiddle: https://jsfiddle.net/schins02/bLkgLuhg/

rData.forEach(function(d, i) { 
    d.date = d3.time.format("%Y-%m-%d").parse(d.date); 
    }); 

var playerData = crossfilter(rData); 

//dimensions and groups 
var dateDim = playerData.dimension(function(d) { 
    return d.date; 
}); 

var abDim = playerData.dimension(function(d) { 
    return d.ab 
}); 

var hitDim = playerData.dimension(function(d) { 
    return d.h 
}); 

var absGroupByDate = dateDim.group().reduceSum(function(d) { 
    return d.ab 
}); 

var hitsGroupByDate = dateDim.group().reduceSum(function(d) { 
    return d.h 
}); 

var x_domain = d3.extent(rData, function(d) { 
    return d.date; 
}); 

var x_scale = d3.time.scale(); 
x_scale.domain(x_domain); 

var abChart = dc.barChart("#ab-bar-chart"); 

abChart 
    .width(WIDTH) 
    .height(HEIGHT + 30) 
    .x(x_scale) 
    .y(d3.scale.linear().domain([0, d3.max(rData, function(d) { 
    return d.ab 
    })])) 
    .yAxisLabel("") 
    .centerBar(true) 
    .dimension(abDim) 
    .alwaysUseRounding(true) 
    .xUnits(function() { 
    return 15; 
    }) 
    .group(absGroupByDate); 

abChart.elasticX(true); 
abChart.xAxisPadding(1); 
abChart.xAxis().tickFormat(d3.time.format("%b %d")).ticks(d3.time.days, 3); 
abChart.yAxis().tickFormat(d3.format("d")); 
abChart.render(); 

abChart.on("filtered", function(chart) { 
    //??? 
    //console.log(chart); 
    //console.log(dateDim); 
    //dc.redrawAll(chart.chartGroup()); 
    //hitDim.filterRange(newDate(?) , new Date(?)); 
}); 

var hitChart = dc.barChart("#hit-bar-chart"); 

var totalHits = playerData.groupAll().reduceSum(function(d) { 
    return d.h; 
}).value(); 

hitChart 
    .width(200) 
    .height(HEIGHT + 30) 
    .x(d3.scale.ordinal().domain(["Hits"])) 
    .xUnits(dc.units.ordinal) 
    .y(d3.scale.linear().domain([0, totalHits])) 
    .yAxisLabel("") 
    .centerBar(true) 
    .dimension(hitDim) 
    .brushOn(false) 
    .alwaysUseRounding(true) 
    .group(hitsGroupByDate) 

    hitChart.render(); 

Jede Hilfe wäre sehr geschätzt.

Antwort

0

In der Tat ist das Crossfilter-Modell der Welt gewöhnungsbedürftig. Der Name "dimension" kann etwas irreführend sein - es ist wirklich "eine Sache, die Sie filtern möchten", und alle Gruppen, die aus dieser Dimension heraus gebaut werden, werden ihre Filter nicht beobachten, nur andere Dimensionen.

So bedeutet, dass

  1. Sie wollen normalerweise die Gruppe und Dimension für ein einzelnes Diagramm anzupassen, so dass die eigenen Daten nicht entfernt wird erhalten, wenn Sie es filtern. Da das erste Diagramm Daten anzeigt, gehen Sie voran und verwenden Sie dafür die dateDim. Wenn ein Datumsbereich vom Filter angewendet wird (basierend auf den Schlüsseln in der Gruppe), stimmen die Typen überein. Und es wird sich auch nicht filtern.

  2. Um einen einzelnen Balken zu erhalten, der die Summe aller Daten aufrollt, können Sie den Trick in this recent answer verwenden, um einen crossfilter groupAll wie eine normale Gruppe zu verhalten. Hier ist es egal, was die Dimension ist, denn es gibt nichts zu filtern.

Der zweite Teil wird wie folgt aussehen:

function regularize_groupAll(groupAll) { 
    return { 
     all: function() { 
      return [{key: 'all', value: groupAll.value()}]; 
     } 
    }; 
} 
var allHits = playerData.groupAll().reduceSum(function(d) { 
    return d.h; 
}); 
var totalHits = allHits.value(); 
var regAllHits = regularize_groupAll(allHits); 

Gabel Ihrer Geige: https://jsfiddle.net/gordonwoodhull/sfLnoxdr/7/