2017-08-12 34 views
0

我正在D3中使用多行折線圖(版本4),並且遇到了一些麻煩。以下是我與我當前的代碼獲得:D3 Stack Line Chart

我認爲這是與我的X規模,但我無法弄清楚什麼是錯的。我一直在遵循教程here,稍作修改,因爲我正在使用V4。任何幫助將不勝感激。

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)"); 
}); 

這裏的數據:

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 

回答

0

這裏有很多,這可能是更容易只是張貼一些工作代碼。你的想法是好的,但有幾個地方它打破:

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 

如果你看一下控制檯,你會看到,這是不是給你的藥品名稱;它會給你第一行數據的一部分,這不是很有用。

對於您使用的格式的數據,一個選項是使用d3.nest()。這將採取你的陣列,並給你一個新的陣列按您選擇的關鍵。在這種情況下,我們可以通過組藥物是這樣的:

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

現在nested將物體的像一個數組:

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

這使得剩下的很自然。你可以用nested.keys()鍵和陣列與.entries()

有一點要記住的鱗片是d3.max()回報最大的自然秩序 - 你需要與.domain([0 , d3.max(data, d => +d.deaths) ])

迫使規模的數字順序

一旦完全解決問題,您只需將nested傳入data()函數,然後將.entries()傳入您的線生成器,並且一切正常。

這裏的工作的例子,應該幫助:

<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>