2017-11-16 1 views
1

Ich folgte zunächst einem einfachen Linienbeispiel, um eine Linie in d3.js (https://bl.ocks.org/d3noob/402dd382a51a4f6eea487f9a35566de0) zu zeichnen.d3v4.js - d3.line zeichnet nicht die richtigen Werte

Meine reale Welt erfordert, ein wenig die ursprünglichen Daten zu manipulieren, und so fügte ich ein Nest() und ein Rollup() hinzu, um die Schließungen pro Tag zu addieren. I.e. am 07. Mai, sollte die Diagrammlinie 400 zeigt statt 100

Basierend auf dem Codes und tsv-Datei unter:

  • ich die richtigen Informationen in der Konsole, also 400 am 07. Mai
  • Ich kann diese 400-Nummer nicht in der Grafik finden. Stattdessen bekomme ich 100 immer

Auf der Grundlage meiner Forschung, mein Gefühl ist, die d3.line Funktion der „Daten“ info anstelle der verschachtelt/rolledup „groupByDate“ Informationen liest (nicht „Werte“ zu lesen, aber "schließt"). Wenn ich versuche, die Dinge zu ändern, erhalte ich die Meldung: d3.v4.min.js:2 Error: <path> attribute d: Expected number, "MNaN,450LNaN,447L…"

ich durch viele Antworten auf dieser Website gesucht haben und änderte meine d3.line Funktion die groupByDate Informationen enthalten, aber es scheint, der falsche Weg. Ich brauche nur diese Zeile, um am Tag 07, wie in der Konsole, auf 400 zu springen.

<!DOCTYPE html> 
<svg width="960" height="500"></svg> 
<script src="https://d3js.org/d3.v4.min.js"></script> 
<script> 

var svg = d3.select("svg"), 
    margin = {top: 20, right: 20, bottom: 30, left: 50}, 
    width = +svg.attr("width") - margin.left - margin.right, 
    height = +svg.attr("height") - margin.top - margin.bottom, 
    g = svg.append("g").attr("transform", "translate(" + margin.left + "," + margin.top + ")"); 

var parseTime = d3.timeParse("%d-%b-%y"); 

var x = d3.scaleTime() 
    .rangeRound([0, width]); 

var y = d3.scaleLinear() 
    .rangeRound([height, 0]); 

var vline = d3.line() 
    .x(function(d) { return x(d.date); }) 
    .y(function(d) { return y(+d.close); }); 

d3.tsv("data.tsv", function(d) { 
    d.date = parseTime(d.date); 
    d.close = +d.close; 
    return d; 
}, function(data) { 
    var groupByDate = d3.nest() 
    .key(function(d) { return d.date; }) 
    .rollup(function(d) { return d3.sum(d, function(g) { return +g.close; }); }) 
    .entries(data); 

    groupByDate.forEach(function(d) { 
     d.date = d.key; 
     d.close = +d.close; 
     d.close = d.value; 
     }); 

    console.log(groupByDate); 


    x.domain(d3.extent(data, function(d) { return d.date; })); 
    y.domain(d3.extent(groupByDate, function(d) { return d.value; })); 

    g.append("g") 
     .attr("transform", "translate(0," + height + ")") 
     .call(d3.axisBottom(x)) 
    .select(".domain") 
     .remove(); 

    g.append("g") 
     .call(d3.axisLeft(y)) 
    .append("text") 
     .attr("fill", "#000") 
     .attr("transform", "rotate(-90)") 
     .attr("y", 6) 
     .attr("dy", "0.71em") 
     .attr("text-anchor", "end") 
     .text("Price ($)"); 

    g.append("path") 
     .datum(data) 
     .attr("fill", "none") 
     .attr("stroke", "steelblue") 
     .attr("stroke-linejoin", "round") 
     .attr("stroke-linecap", "round") 
     .attr("stroke-width", 1.5) 
     .attr("d", vline); 
}); 

</script> 

data.tsv

date close 
24-Apr-07 93.24 
25-Apr-07 95.35 
26-Apr-07 98.84 
27-Apr-07 99.92 
30-Apr-07 99.80 
1-May-07 99.47 
2-May-07 100.39 
3-May-07 100.40 
4-May-07 100.81 
7-May-07 100.00 
7-May-07 100.00 
7-May-07 100.00 
7-May-07 100.00 
8-May-07 105.06 
9-May-07 106.88 
10-May-07 107.34 
11-May-07 108.74 
14-May-07 109.36 
15-May-07 107.52 
16-May-07 107.34 
+0

Sie vorbei 'data' anstatt' groupByData' in Ihrem Datum für die Pfad. –

+0

Vielen Dank Emma und Ryan! Beide Änderungen haben dazu geführt, dass die Zeile auf 400 springt. :) – Vinicenzo

Antwort

1

sollten Sie groupByData statt data auf Ihrem Weg werden vorbei. Aber der Grund, dass dies dann nicht funktioniert, ist, dass die nest.key eine Zeichenkette sein muss, so dass es Ihre Zeit zurück zu einer Zeichenkette analysiert, die dann nicht mit Ihrer x-Skala funktioniert. Ich würde vorschlagen, parseTime aus der Zeilenkonvertierung zu entfernen und stattdessen zu Ihrer x-Skalierungsdomäne und zur vline x-Funktion hinzuzufügen (obwohl dies bedeutet, dass Sie es an zwei Stellen platzieren, damit es vielleicht einen besseren Weg gibt ...).

Ihre x Skala Domain würde:

x.domain(d3.extent(data, function(d) { return parseTime(d.date); }));

Und vline würde:

var vline = d3.line() .x(function(d) { return x(parseTime(d.date)); })...

+0

Vielen Dank Emma und Ryan! Beide Änderungen haben dazu geführt, dass die Zeile auf 400 springt. :) – Vinicenzo