2016-07-28 16 views
0

Ich verwende crossfilter.js und d3.js v4 mit ES6-Stil Reagieren in einem Versuch, dimensionale Diagramme mit Kontext-putzen zu machen. Im Wesentlichen nahm ich this example und konvertierte es zu ES6.d3 v4 + reagieren + es6 + crossfilter: Selection.exit(). Remove() funktioniert nicht

Das Problem, das ich habe, ist selection.exit().remove() funktioniert nicht so, dass auf jedem Neuzeichnen, mehr und mehr Kreise an die Svg g-Element angefügt werden. Neuzeichnungen werden ausgelöst, wenn ein Pinsel erstellt wird. Ich überprüfte

selection.exit() 
    .attr('class', d => { 
    console.log('anything'); 
    return 'anything'; 
    }) 
    .remove(); 

aber nichts wurde ausgegeben, also denke ich, dass meine Datenauswahl nicht gültig ist.

Hier ist der Kontext:

componentDidMount() { 
    const el = ReactDOM.findDOMNode(this); // the mounted svg element 

    const svg = d3.select(el) 
    .attr('width', 300) 
    .attr('height', 500); 

    const g = svg.append('g') 
    .attr('transform', 'translate(32,32)'); 

    let circles = g.append('g') 
    .selectAll('circle'); 

    const brushGroup = g.append('g') 
    .attr('class', 'brush') 
    .call(brush); 

    function redraw() { 
    const all = group.all(); // crossfilter group returns an array 

    xAxisGroup.call(xAxis); 
    yAxisGroup.call(yAxis); 

    circles = circles.data(all, d => d); // keyFn for data constancy 

    circles.enter().append('circle') 
     .attr('r', radius) 
     .attr('cx', plotX) // radius + plotX/Y are simple curry functions 
     .attr('cy', plotY); 

    circles.exit().remove(); // not working!! 
    } 

    redraw(); 
} 

ich auch von dieser Änderung in v4 in d3-selection bewusst bin, aber ich bin nicht super sicher, welche Linien sind meine update und welche meine update + enter sind.

Jede Hilfe würde sehr geschätzt werden. Vielen Dank!

+1

Eine 'exit' Auswahl ist, nachdem Sie die Daten auf eine Auswahl binden, all jene Elemente, die mit keinen Daten, die sich auf sie verlassen wurden . Schauen Sie sich nun Ihre "Leet Circles" genau an: Sie sind an keine Daten gebunden. Sie müssen Ihre Auswahl korrekt eingeben, aktualisieren und beenden. Im Moment sind sie nicht richtig definiert. –

+0

Wie sieht es aus, wenn ich 'circles = circles.data (all, d => d)' festlege? Ist das nicht eine richtige Join-Auswahl, also 'circles.enter()' und 'circles.exit()'? –

+0

haben Sie einzigartige IDs für Ihre Kreise Daten so etwas wie diese 'circles = circles.data (alle, d => d.id)' – Cyril

Antwort

1

Ich vermute, das Problem ist eines von 2 Dingen. Wahrscheinlich # 1 unten. Es ist ein bisschen schwer mit ein funktionierendes Beispiel zu sagen, die Dinge in testen, aber hier geht:

  1. Ich glaube, dass die selectAll und die data sollten zusammen in der redraw Funktion geschehen verbinden. Da Sie die selectAll in der Neuzeichnungsfunktion nie wiederholen, enthält Ihre Auswahl niemals Elemente. Wenn Sie Ihre enter und 10 Auswahlen in Ihrer redraw Funktion überprüfen, enthält Ihre enter Auswahl immer alle Ihre Datenpunkte, da die zugrunde liegende Auswahl leer ist.

  2. Das Ihre Datenschlüsselfunktion gibt ein Objekt zurück. Da das Objekt das Ergebnis von Crossfilters group.all ist, sollten sie durch Bezugnahme vergleichbar sein, aber es wäre sicherer, circles.data(all, d => d.key) zu tun.

Die Lösung sollte so etwas zu tun:

componentDidMount() { 
    const el = ReactDOM.findDOMNode(this); // the mounted svg element 

    const svg = d3.select(el) 
    .attr('width', 300) 
    .attr('height', 500); 

    const g = svg.append('g') 
    .attr('transform', 'translate(32,32)'); 

    let circlesGroup = g.append('g'); // Just hang on to the group 

    const brushGroup = g.append('g') 
    .attr('class', 'brush') 
    .call(brush); 

    function redraw() { 
    const all = group.all(); // crossfilter group returns an array 

    xAxisGroup.call(xAxis); 
    yAxisGroup.call(yAxis); 

    let circles = circlesGroup // Do the selection and data join here 
     .selectAll('circle') 
     .data(all, d => d.key); // Have the key function return a key, not an object 

    circles.enter().append('circle') 
     .attr('r', radius) 
     .attr('cx', plotX) // radius + plotX/Y are simple curry functions 
     .attr('cy', plotY); 

    circles.exit().remove(); 
    } 

    redraw(); 
} 
+0

Ich habe das Gefühl, dass ich jedes Muster außer dem einen ausprobiert habe!Es war hauptsächlich, weil ich nach dem manuellen Aufruf von 'redraw()' Kreise mit dem Diagramm exportiert habe (siehe den codepen), aber es stellt sich heraus, dass ich das exportierte Diagramm nur für 'redraw()' benutze Perfekter Sinn! Jetzt, wenn ich nur mein d3 v4-Histogramm zum arbeiten bekomme. Danke vielmals! –