2016-07-06 3 views
0

Ich bin ein Neuling zu D3 und muss ein Diagramm von zwei Datensätzen erstellen.Hinzufügen von Punkten zu D3.js Graph

Ich konnte this erstellen, nach der Anpassung von Code, den ich here gefunden habe, und war in der Lage, Dinge mit meinen JSON-Daten arbeiten, aber nicht Punkte oder den Strich in meine Version integrieren konnte.

Ich versuchte, einen „Punkt“ Variable in der gleichen Weise wie das „Linien“ variabel zu machen:

var dots = canvas.selectAll(".dot") 
    .data(dataArray, function(d){ return line(d.values);}) 
    .enter() 
    .append("circle") 
    .attr("class", "dot") 
    .attr("cx", line.x()) 
    .attr("cy", line.y()) 
    .attr("r", 3.5); 

aber lief in Probleme mit dem, was erscheint, die einzelne Datenfelder in meinem Code zugreifen.

Jede Hilfe ist willkommen, meine gesamte Code ist unten:

<!DOCTYPE html> 
    <html> 
    <head> 
    <style> 
     body { 
     font: 10px sans-serif; 
     } 

     .axis path, .axis line { 
     fill: none; 

     shape-rendering: crispEdges; 
     } 

     .line { 

     } 

     .area { 
     fill: steelblue; 
     opacity: 0.5; 
     } 


     .dot { 
     fill: steelblue; 
     stroke: steelblue; 
     stroke-width: 1.5px; 
     } 
    </style> 
    </head> 
    <body> 
    <div id="disp"></div> 
    <script src="https://d3js.org/d3.v3.min.js"></script> 
    <script> 

     var dataArray = [ 
      { 
      category: 'red', 
      values: [0, 4, 9, 4, 4, 7] 
      }, 

     { 
      category: 'blue', 
      values: [0, 10, 7, 1, 1, 11] 
     } 
     ]; 

     var canvas = d3.select('#disp') 
     .append('svg') 
     .attr('width', 400) 
     .attr('height', 200); 

     var x = d3.scale.linear() 
       .domain([0, 8]) 
       .range([0, 700]); 

     var y = d3.scale.linear() 
       .domain([0, 20]) 
       .range([200, 0]); 

     var line = d3.svg.line() 
      .interpolate("cardinal") 
      .x(function(d, i) { return x(i); }) 
      .y(function(d, i) { return y(d); }); 

     var area = d3.svg.area() 
     .interpolate("cardinal") 
     .x(line.x()) 
     .y1(line.y()) 
     .y0(y(0)); 

     var lines = canvas.selectAll('.line') 
      .data(dataArray, function(d) { return d.category; }); 

      lines.enter() 
      .append('path') 
      .attr('class', 'line') 
      .attr("d", function(d) { return line(d.values);}) 
      .style("stroke", function(d) {return d.category;}) 
      .attr("class", "area") 
      .style("fill", function(d) {return d.category;}) 
      .attr("d", function(d) { return area(d.values);}); 

    </script> 
    </body> 
    </html> 

Antwort

3

Ihr Diagramm Break up in die drei Dinge, die Sie wollen, ein gefüllter Bereich, eine Linie auf der Oberseite (unterschiedlicher Opazität) und dann eine Sammlung von Kreisen. Hier einige kommentiert und Lauf der Lage Code:

<!DOCTYPE html> 
 
<html> 
 

 
<head> 
 
    <style> 
 
    body { 
 
     font: 10px sans-serif; 
 
    } 
 
    
 
    .axis path, 
 
    .axis line { 
 
     fill: none; 
 
     shape-rendering: crispEdges; 
 
    } 
 
    
 
    .line { 
 
     fill: none; 
 
     stroke-width: 3px; 
 
     
 
    } 
 
    
 
    .area { 
 
     fill: steelblue; 
 
     opacity: 0.5; 
 
    } 
 
    
 
    .dot { 
 
     fill: steelblue; 
 
     stroke: steelblue; 
 
     stroke-width: 1.5px; 
 
    } 
 
    </style> 
 
</head> 
 

 
<body> 
 
    <div id="disp"></div> 
 
    <script src="//d3js.org/d3.v3.min.js"></script> 
 
    <script> 
 
    var dataArray = [{ 
 
     category: 'red', 
 
     values: [0, 4, 9, 4, 4, 7] 
 
     }, 
 

 
     { 
 
     category: 'blue', 
 
     values: [0, 10, 7, 1, 1, 11] 
 
     } 
 
    ]; 
 

 
    var canvas = d3.select('#disp') 
 
     .append('svg') 
 
     .attr('width', 400) 
 
     .attr('height', 200); 
 

 
    var x = d3.scale.linear() 
 
     .domain([0, 8]) 
 
     .range([0, 700]); 
 

 
    var y = d3.scale.linear() 
 
     .domain([0, 20]) 
 
     .range([200, 0]); 
 

 
    var line = d3.svg.line() 
 
     .interpolate("cardinal") 
 
     .x(function(d, i) { 
 
     return x(i); 
 
     }) 
 
     .y(function(d, i) { 
 
     return y(d); 
 
     }); 
 

 
    var area = d3.svg.area() 
 
     .interpolate("cardinal") 
 
     .x(line.x()) 
 
     .y1(line.y()) 
 
     .y0(y(0)); 
 

 
    var lines = canvas.selectAll('.category') 
 
     .data(dataArray, function(d) { 
 
     return d.category; 
 
     }); 
 

 
    // on enter append a g to hold our 3 parts 
 
    var lE = lines.enter() 
 
     .append('g') 
 
     .attr('class', 'category') 
 
    
 
    // append a path that's our solid line on top of the area 
 
    lE.append("path") 
 
     .attr('class', 'line') 
 
     .attr("d", function(d) { 
 
     return line(d.values); 
 
     }) 
 
     .style("stroke", function(d) { 
 
     return d.category; 
 
     }) 
 
     
 
    //apend a path that's our filled area 
 
    lE.append("path") 
 
     .attr("class", "area") 
 
     .style("fill", function(d) { 
 
     return d.category; 
 
     }) 
 
     .attr("d", function(d) { 
 
     return area(d.values); 
 
     }); 
 
    
 
    // create a subselection for our "dots" 
 
    // and on enter append a bunch of circles 
 
    lE.selectAll(".dot") 
 
     .data(function(d){ 
 
     return d.values 
 
     }) 
 
     .enter() 
 
     .append("circle") 
 
     .attr("r", 3) 
 
     .attr("cx", function(d,i){ 
 
     return x(i); 
 
     }) 
 
     .attr("cy", function(d){ 
 
     return y(d); 
 
     }) 
 
     .attr("fill", function(d){ 
 
     return d3.select(this.parentNode).datum().category; 
 
     }); 
 

 
    </script> 
 
</body> 
 

+0

Ok, danke für die Hilfe. Ich kann sehen, wie es in drei Phasen der Anhaftung an die Leinwand unterteilt ist. Ich bin mir immer noch nicht sicher, wofür die Zeilenvariable verwendet wird, aber wahrscheinlich muss ich über Gruppen in d3 nachlesen. – oraz

+0

'line' ist eine Funktion, die bei Angabe eines Datenfeldes das' d'-Attribut eines SVG-Pfads zurückgibt (Anweisungen zum Zeichnen der Linie). Es weiß, wie man basierend auf den 'accessor' Funktionen, die man mit' .x (function (d, i) {return x (i)} 'erstellt, zeichnet, dies sagt loop my array und benutzt meine x-Skala für die x-Koordinate an jedem Index, '.y (Funktion (d, i) {return y (d);}', sagt mein Array loop und benutze meine y-Skala für die y-Koordinate bei jedem Datenwert. – Mark

+0

Das 'g' Element ist eine SVG-Gruppe, die es einfach erlaubt, mehrere Zeichnungselemente miteinander zu kombinieren. @oraz – Mark