2017-08-12 5 views
0

Ich arbeite gerade an einem mehrzeiligen Liniendiagramm in D3 (Version 4) und habe einige Probleme. Hier ist, was ich mit meinem aktuellen Code bin immer:D3 Stack Liniendiagramm

Ich denke, es hat etwas mit meiner x-Skala zu tun, aber ich kann nicht herausfinden, was falsch ist. Ich habe das Tutorial here mit leichten Änderungen verfolgt, weil ich mit V4 arbeite. Jede Hilfe würde sehr geschätzt werden.

var parseDate = d3.timeParse("%Y"); 

var color = d3.scaleOrdinal(["#969FFD","#7173BF","#4B4C7F","#262640", "red"]); 

var mySvg = d3.select("#chart8").append('svg') 
    .attr('width', width + margin.right + margin.left) 
    .attr('height', height + margin.bottom + margin.top) 

var chartGroup = mySvg.append("g") 
    .attr("class","fullGroup") 
    .attr("transform", "translate("+margin.left+","+margin.top+")"); 

var parseDate = d3.timeParse("%Y"); 

d3.csv("../Assets/datasets/allDrugs3.csv", function(error, data){ 
if (error) throw error; 

// FORMAT THE DATA // 
var labelVar = "year"; 
var varNames = d3.keys(data[0]).slice(1); 
    // Alternatively --> .filter(function(key){ return key !== labelVar;}) 
console.log(varNames); // <-- Names of drugs, used for color array 

// Add color domain of names 
color.domain(varNames); 

var seriesData = varNames.map(function(name){ 
    return { 
     name: name, 
     values: data.map(function(d) { 
      return { name: name, label: parseDate(d[labelVar]), value: +d[name]}; 
     }) 
    }; 
}); 

console.log(seriesData); 

// Y-SCALE // 

var yScale = d3.scaleLinear() 
    .domain([ 
     d3.min(seriesData, function(c){ 
     return d3.min(c.values, function(d){ return d.value; }); 
     }), 
     d3.max(seriesData, function(c){ 
      return d3.max(c.values, function(d){ return d.value;}); 
     }) 
    ]) 
    .range([height, 0]); 

console.log(
    "The y domain is", 
    d3.min(seriesData, function(c){ 
     return d3.min(c.values, function(d){ return d.value; })}), 
    "to", 
    d3.max(seriesData, function(c){ 
      return d3.max(c.values, function(d){ return d.value;}); 
     })); 

// X-SCALE // 

var xYears = data.map(function(d){return parseDate(d.year);});  
var xScale = d3.scaleTime() 
    .domain(xYears) 
    .range([0, width]); 

console.log(
    "The x domain is", 
    xYears 
) 

var series = chartGroup.selectAll(".series") 
    .data(seriesData) 
    .enter().append("g") 
     .attr("class","series"); 

var line = d3.line() 
    .x(function(d){return xScale(d.label)}) 
    .y(function(d){return yScale(d.value); }) 
    .curve(d3.curveCardinal); 

series.append("path") 
    .attr("d", function(d){ return line(d.values); }) 
    .style("stroke", function (d) { return color(d.name); }) 
    .style("stroke-width", "4px") 
    .style("fill", "none"); 

// Axes 

var yAxis = d3.axisLeft(yScale).ticks(5).tickPadding(5); 
var xAxis = d3.axisBottom(xScale).ticks(10); 

chartGroup.append("g") 
    .attr("class","Xaxis") 
    .call(xAxis) 
    .attr("transform","translate(0,"+height+")") 
.selectAll("text") 
    .style("text-anchor", "end") 
    .attr("dx", "-.8em") 
    .attr("dy", ".15em") 
    .attr("transform", "rotate(-65)"); 

chartGroup.append("g") 
    .attr("class","Yaxis") 
    .call(yAxis) 
    .selectAll("text") 
    .style("text-anchor", "middle") 
    .attr("dy", "-1em") 
    .attr("transform", "rotate(-90)"); 
}); 

Hier die Daten:

key,deaths,year 
heroin,289,2007 
heroin,360,2008 
heroin,238,2009 
heroin,247,2010 
heroin,392,2011 
heroin,399,2012 
heroin,464,2013 
heroin,578,2014 
heroin,748,2015 
heroin,1212,2016 
opiods,280,2007 
opiods,251,2008 
opiods,311,2009 
opiods,342,2010 
opiods,311,2011 
opiods,302,2012 
opiods,316,2013 
opiods,330,2014 
opiods,351,2015 
opiods,418,2016 
alchohol,175,2007 
alchohol,162,2008 
alchohol,160,2009 
alchohol,161,2010 
alchohol,195,2011 
alchohol,187,2012 
alchohol,238,2013 
alchohol,270,2014 
alchohol,310,2015 
alchohol,582,2016 
benzodiazepine,48,2007 
benzodiazepine,52,2008 
benzodiazepine,58,2009 
benzodiazepine,68,2010 
benzodiazepine,73,2011 
benzodiazepine,37,2012 
benzodiazepine,69,2013 
benzodiazepine,103,2014 
benzodiazepine,91,2015 
benzodiazepine,126,2016 
cocaine,157,2007 
cocaine,162,2008 
cocaine,135,2009 
cocaine,148,2010 
cocaine,153,2011 
cocaine,248,2012 
cocaine,154,2013 
cocaine,198,2014 
cocaine,221,2015 
cocaine,463,2016 

Antwort

0

Hier gibt es eine Menge ist, könnte es einfacher sein, nur einige Arbeits Code zu schreiben. Sie Idee ist gut, aber es gibt ein paar Orte, es bricht:

var varNames = d3.keys(data[0]).slice(1); 
// Alternatively --> .filter(function(key){ return key !== labelVar;}) 
console.log(varNames); // <-- Names of drugs, used for color array 

Wenn Sie an der Konsole anschauen, werden Sie sehen dies nicht, dass Sie die Medikamentennamen schenkt; Es gibt Ihnen einen Teil der ersten Datenzeile, was nicht wirklich nützlich ist.

Für Daten in dem Format, das Sie haben, ist eine Option d3.nest() zu verwenden. Dies nimmt Ihr Array und geben Sie ein neues Array nach dem Schlüssel Ihrer Wahl gruppiert. In diesem Fall können wir Gruppe von Drogen wie folgt aus:

var nested = d3.nest() 
    .key(d => d.key) 
    .map(data) 

nun ein Array von Objekten wie sein nested wird:

[{alchohol: [{key: "alchohol", deaths: "175", year: "2007"},...}, 
{benzodiazepine: [{key: "benzodiazepine", deaths: "48", year: "2007"}... 
] 

der Rest sehr natürlich Dies macht. Sie können mit .entries()

Einer Sache, die Schlüssel mit nested.keys() und der Arrays erhalten im Auge zu behalten mit Schuppen ist, dass d3.max() gibt den max in natürlicher Ordnung - Sie die numerische Reihenfolge in der Skala zwingen müssen, um mit .domain([0 , d3.max(data, d => +d.deaths) ])

Sobald das alles geglättet ist, können Sie einfach nested in die data() Funktion und .entries() in Ihrem Liniengenerator übergeben und alles funktioniert ziemlich gut.

Hier ist ein funktionierendes Beispiel, das helfen soll:

<html> 
<head> 
    <script src="d3/d3.min.js"></script> 
    <script src="d3-selection-multi/d3-selection-multi.min.js"></script> 
    <style> 
    #chart div { 
      background-color: steelblue; 
      color: white; 
      padding: 8px; 
      text-align: right; 
      margin:1px; 
      font: 10px sans-serf 
     } 
     div#graphic { 
      display: inline-block; 
     /* border: 1px solid #333;*/ 
     } 
     .title { 
      fill: #666; 
      font-family: Arial, Helvetica, sans-serif; 
      text-anchor: middle; 
      font-size: 24px; 
     } 
     .axis .domain, .axis .tick{ 
      stroke: #000; 
      fill: none; 
     } 
     .bar { 
      fill:steelblue; 
      stroke: #444; 
     } 
    </style> 
</head> 
<body> 
<div id ="chart"></div> 
<div id="chart8"></div> 
<button onclick="refresh()">refresh</button> 
<script> 
data = [{"key":"heroin","deaths":"289","year":"2007"},{"key":"heroin","deaths":"360","year":"2008"},{"key":"heroin","deaths":"238","year":"2009"},{"key":"heroin","deaths":"247","year":"2010"},{"key":"heroin","deaths":"392","year":"2011"},{"key":"heroin","deaths":"399","year":"2012"},{"key":"heroin","deaths":"464","year":"2013"},{"key":"heroin","deaths":"578","year":"2014"},{"key":"heroin","deaths":"748","year":"2015"},{"key":"heroin","deaths":"1212","year":"2016"},{"key":"opiods","deaths":"280","year":"2007"},{"key":"opiods","deaths":"251","year":"2008"},{"key":"opiods","deaths":"311","year":"2009"},{"key":"opiods","deaths":"342","year":"2010"},{"key":"opiods","deaths":"311","year":"2011"},{"key":"opiods","deaths":"302","year":"2012"},{"key":"opiods","deaths":"316","year":"2013"},{"key":"opiods","deaths":"330","year":"2014"},{"key":"opiods","deaths":"351","year":"2015"},{"key":"opiods","deaths":"418","year":"2016"},{"key":"alchohol","deaths":"175","year":"2007"},{"key":"alchohol","deaths":"162","year":"2008"},{"key":"alchohol","deaths":"160","year":"2009"},{"key":"alchohol","deaths":"161","year":"2010"},{"key":"alchohol","deaths":"195","year":"2011"},{"key":"alchohol","deaths":"187","year":"2012"},{"key":"alchohol","deaths":"238","year":"2013"},{"key":"alchohol","deaths":"270","year":"2014"},{"key":"alchohol","deaths":"310","year":"2015"},{"key":"alchohol","deaths":"582","year":"2016"},{"key":"benzodiazepine","deaths":"48","year":"2007"},{"key":"benzodiazepine","deaths":"52","year":"2008"},{"key":"benzodiazepine","deaths":"58","year":"2009"},{"key":"benzodiazepine","deaths":"68","year":"2010"},{"key":"benzodiazepine","deaths":"73","year":"2011"},{"key":"benzodiazepine","deaths":"37","year":"2012"},{"key":"benzodiazepine","deaths":"69","year":"2013"},{"key":"benzodiazepine","deaths":"103","year":"2014"},{"key":"benzodiazepine","deaths":"91","year":"2015"},{"key":"benzodiazepine","deaths":"126","year":"2016"},{"key":"cocaine","deaths":"157","year":"2007"},{"key":"cocaine","deaths":"162","year":"2008"},{"key":"cocaine","deaths":"135","year":"2009"},{"key":"cocaine","deaths":"148","year":"2010"},{"key":"cocaine","deaths":"153","year":"2011"},{"key":"cocaine","deaths":"248","year":"2012"},{"key":"cocaine","deaths":"154","year":"2013"},{"key":"cocaine","deaths":"198","year":"2014"},{"key":"cocaine","deaths":"221","year":"2015"},{"key":"cocaine","deaths":"463","year":"2016"}] 

var margin = { 
    top: 20, 
    bottom: 20, 
    left: 20, 
    right: 20 
} 
var width = 800 - margin.left - margin.right, 
    height = 600 - margin.top - margin.bottom 

var parseDate = d3.timeParse("%Y"); 

var color = d3.scaleOrdinal(["#969FFD","#7173BF","#4B4C7F","#262640", "red"]); 

var mySvg = d3.select("#chart8").append('svg') 
.attr('width', width + margin.right + margin.left) 
.attr('height', height + margin.bottom + margin.top) 

var chartGroup = mySvg.append("g") 
.attr("class","fullGroup") 
.attr("transform", "translate("+margin.left+","+margin.top+")"); 

var parseDate = d3.timeParse("%Y"); 

d3.csv("./allDrugs3.csv", function(error, data){ 
    console.log(JSON.stringify(data)) 
    if (error) throw error; 

    // FORMAT THE DATA // 
    var nested = d3.nest() 
     .key(d => d.key) 
     .map(data) 
    console.log("nest", nested.keys()) // <-- Names of drugs, used for color array 
    console.log(nested) // <-- the actual data 

    color.domain(nested); 

    // Y-SCALE // 
    var yScale = d3.scaleLinear() 
     .domain([0 , d3.max(data, d => +d.deaths) ]) 
     .range([height, 0]); 

    // X-SCALE // 
    var xScale = d3.scaleTime() 
     .domain(d3.extent(data, d => d.year)) 
     .range([0, width]) 

    var line = d3.line() 
     .x(d => xScale(d.year)) 
     .y(d => yScale(d.deaths)) 
     .curve(d3.curveCardinal); 


    var series = chartGroup.selectAll(".series") 
     .data(nested.entries()) 
     .enter().append("g") 
      .attr("class","series") 
     .append("path") 
     .attr("d", d => {console.log(d); return line(d.value)}) 
     .style("stroke", function (d) { return color(d.key); }) 
     .style("stroke-width", "4px") 
     .style("fill", "none"); 

    // Axes 

    var yAxis = d3.axisLeft(yScale).ticks(5).tickPadding(5); 
    var xAxis = d3.axisBottom(xScale).ticks(10); 

    chartGroup.append("g") 
    .attr("class","Xaxis") 
    .call(xAxis) 
    .attr("transform","translate(0,"+height+")") 
    .selectAll("text") 
     .style("text-anchor", "end") 
     .attr("dx", "-.8em") 
     .attr("dy", ".15em") 
     .attr("transform", "rotate(-65)"); 

    chartGroup.append("g") 
     .attr("class","Yaxis") 
     .call(yAxis) 
     .selectAll("text") 
     .style("text-anchor", "middle") 
     .attr("dy", "-1em") 
     .attr("transform", "rotate(-90)"); 
}); 

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