2016-04-10 3 views
0

Erstellen eines D3-Kreisdiagramms, das den Spieler anzeigen und als Prozentsatz der insgesamt erzielten Punktzahl einstufen soll. Die Daten werden auf Klicks gebaut und aktualisiert ein Array namens playersObj die wie folgt aussieht ...D3 Aktualisierung der lokalen Daten und Neuzeichnen der Torte, so wie sie aktualisiert wird

var playersObj = [ 
    {"playerName":"Jessica Jones","playerID":157,"playerScore":2}, 
    {"playerName":"Luke Cage","playerID":158,"playerScore":0}, 
    {"playerName":"Matt Murdock","playerID":159,"playerScore":6} 
] 

Während mein Skript ich die playerScore erhöhen und bin versucht, das Diagramm entsprechend zu aktualisieren. Hier ist der Code Ich habe so weit, wo ich die Besonderheiten einrichten und dann versuchen, sie zu zeichnen, wie Daten aktualisiert ...

/* 
---------------------------------------------------------------------- 
DONUT CHART 
---------------------------------------------------------------------- 
*/ 

//Set color range 
var color = d3.scale.ordinal() 
    .range(["red", "green", "blue", "purple", "orange"]); 

//Set stage dimensions 
var width = 300; 
var height = 300; 
var radius = Math.min(width, height)/2; 

//Select div and add svg into it 
var svg = d3.select("#donut").append("svg") 
    .attr("width", width) 
    .attr("height", height); 

var group = svg.append("g") 
    .attr("transform", "translate(" + radius + "," + radius + ")") 

//Set inner and outer radius of chart 
var arc = d3.svg.arc() 
    .outerRadius(radius - 10) 
    .innerRadius(radius - 75); 


//UPDATE THE DONUT 

function updateDonut(){ 
    console.log("Updating donut..."); 
    //console.log(donutData); 

    //Create pie chart 
    var pie = d3.layout.pie() 
     .value(function(d) { 
     return d.playersScore; 
     }); 

    var arcs = group.selectAll(".arc") 
     .data(pie(playersObj)) 
     .enter() 
     .append("g") 
     .attr("class", "arc"); 

    console.log(pie(playersObj)); 

    arcs.append("path") 
     .attr("d", arc) 
     .attr("fill", function(d) { 
     //console.log(d); 
     return color(d.data.playerName); 
     }); 

    arcs.append("text") 
     .attr("transform", function(d) { 
     return "translate(" + arc.centroid(d) + ")"; 
     }) 
     .text(function(d) { 
     return d.data.firstName+": "+d.data.playersScore 
     }); 

} 

Als ein Ergebnis dieser, ich ein Diagramm mit zwei Probleme bekommen. Zunächst fügt das Diagramm Text an Einträge an, die einen playerScore von 0 haben. Da jeder mit 0 beginnt, wird eine große Anzahl von Namen übereinander gestapelt, da ihre Teile des Kuchens keinen Wert haben. Das zweite Problem ist, dass der Kuchen nach dem zweiten Update nie aktualisiert wird. playersObj aktualisiert und console.log(pie(playersObj)); zeigt die richtigen Werte, aber die Diagrammanzeige ändert sich nie.

Ich habe die Bostock-Beispiele mit den Äpfeln gesehen, aber das ändert Daten und ich muss einfach aktualisieren und neu zeichnen. Andere Beiträge scheinen unterschiedliche Ansätze zu verfolgen, so dass es für mich verwirrend ist, wie ihre Lösungen funktionieren.

Antwort

0

So war das größte Problem falsch geschriebene Variablennamen. Ich habe die meisten der Probleme behoben, die ich gefunden habe, obwohl einige eigensinnig sind. Ich hoffe das hilft.

var playersObj = [{ 
 
    "playerName": "Jessica Jones", 
 
    "playerID": 157, 
 
    "playerScore": 3 
 
}, { 
 
    "playerName": "Luke Cage", 
 
    "playerID": 158, 
 
    "playerScore": 2 
 
}, { 
 
    "playerName": "Matt Murdock", 
 
    "playerID": 159, 
 
    "playerScore": 6 
 
}, { 
 
    "playerName": "Oliver Queen", 
 
    "playerID": 160, 
 
    "playerScore": 10 
 
}, { 
 
    "playerName": "Barry Allen", 
 
    "playerID": 161, 
 
    "playerScore": 3 
 
}]; 
 

 
var domain = playersObj.map(function(m) { 
 
    return m.playerID; 
 
}); 
 

 
//Set color range 
 
var color = d3.scale.category10(); 
 
// var color = d3.scale.ordinal() 
 
// .range(["red", "green", "blue", "purple", "orange"]); 
 

 
//Set stage dimensions 
 
var width = 300; 
 
var height = 300; 
 
var radius = Math.min(width, height)/2; 
 

 
//Select div and add svg into it 
 
var svg = d3.select("#donut").append("svg") 
 
    .attr("width", width) 
 
    .attr("height", height); 
 

 
var group = svg.append("g") 
 
    .attr("transform", "translate(" + radius + "," + radius + ")") 
 

 
//Set inner and outer radius of chart 
 
var arc = d3.svg.arc() 
 
    .outerRadius(radius - 10) 
 
    .innerRadius(radius - 75); 
 

 
function updateDonut() { 
 
    console.log("Updating donut..."); 
 
    //console.log(donutData); 
 

 
    //Create pie chart 
 
    var pie = d3.layout.pie() 
 
    .value(function(d) { 
 
     return d.playerScore; 
 
    }); 
 

 
    var enter = group.selectAll(".arc") 
 
    .data(pie(playersObj)) 
 
    .enter(); 
 
    var arcs = enter.append("g") 
 
    .attr("class", "arc"); 
 
    var text = enter.append("g") 
 
    .attr("class", "text"); 
 

 
    console.log(pie(playersObj)); 
 

 
    arcs.append("path") 
 
    .attr("d", arc) 
 
    .attr("fill", function(d) { 
 
     return color(d.data.playerID); 
 
    }); 
 

 
    text.append("text") 
 
    .attr("style", "text-anchor:middle") 
 
    .attr("transform", function(d) { 
 
     return "translate(" + arc.centroid(d) + ")"; 
 
    }) 
 
    .text(function(d) { 
 
     return d.data.playerName + ": " + d.data.playerScore 
 
    }); 
 

 
} 
 

 
updateDonut();
body { 
 
    background-color: #404040; 
 
} 
 
li, 
 
text { 
 
    font-family: arial; 
 
    font-size: 0.8rem; 
 
    color: white; 
 
    fill: white; 
 
} 
 
#donut { 
 
    padding: 2rem; 
 
} 
 
svg { 
 
    overflow: visible; 
 
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script> 
 

 
<ul> 
 
    <li>Your `playersObj` shows `playerScore` (singular) while you text elements value assignment references `playersScore` (plural). 
 
    </li> 
 
    <li>You also referenced `firstName` in the text element, which doesn't exist in `playersObj`. 
 
    </li> 
 
    <li> 
 
    `Luke Cage` could not be seen because his `playerScore` was 0. 
 
    </li> 
 
    <li> 
 
    Add some padding to the svg container and let the overflow be visible. Lots of different ways to handle that... 
 
    </li> 
 
    <li> 
 
    Color scheme was a bit difficult to read too and the text elements should/could be centered. 
 
    </li> 
 
    <li> 
 
    After fixing the above, text was hidden behind each arc because the text was attached to the same g object as the arc. Attachment order makes the text below the next arc added to the pie. Attaching to separate g 'layers' from the enter selection solves 
 
    this. 
 
    </li> 
 
</ul> 
 
<div id='donut'></div>

+0

Dank Will, fügte ich eine Geige mit Ihrem Code besser zu veranschaulichen, was passiert ist und was ich versuche zu erreichen. Grundsätzlich beginnt der Kuchen bei 0, die Punktzahl des Spielers wird erhöht, die Aktualisierung des Kreisdiagramms. Fiddle hier verfügbar: https://jsfiddle.net/johnlayne/e2wyd1fr/ – Layne

+0

Verwaltet, um den Cluster von überlappenden Etiketten mit einer einfachen if-Anweisung zu verbergen. Trotzdem kann der Kuchen nicht aktualisiert werden. https://jsfiddle.net/johnlayne/e2wyd1fr/1/ – Layne

Verwandte Themen