简体   繁体   中英

d3.js Stacked Area chart - not appearing

I am constructing a stacked area graph (following this tutorial ) and am having issues with the graph rendering. The axes render correctly, but the area elements do not appear. When using just one column of the data it works fine, but after stacking the data, no luck.

I feel that the issue is with my use of scaleLinear() .

I've tried two methods: putting y values from the d3.stack function I get negative values out (commented in code below). Secondly, to debug, I set the maximum to the maximum of stackedData (set to default in code below). This gives all positive values out when I use console.log , but no graph renders.

Here's the code:

var margin = {top: 10, right: 30, bottom: 30, left: 70},
  width = 460 - margin.left - margin.right,
  height = 400 - margin.top - margin.bottom;

var svg = d3.select("#chart")
  .append("svg")
    .attr("width",width + margin.left + margin.right)
    .attr("height",height + margin.top + margin.bottom)
  .append("g")
    .attr("transform","translate("+margin.left+","+margin.top+")");
let data = []
var group_names = []
//Assumes first line of data is table header, otherwise will not work properly
model.output_energy_demand.map(function(x,i){
  if(i==0) {
    group_names = x
  }else{
    let line = {}
    x.map(function(y,j){
      line[group_names[j]]=y
    });
    data.push(line)
  }
});

data.forEach((d,i)=>{
    var keys = Object.keys(d)
    console.log(model.year[i])
    d["year"] = d3.timeParse("%Y")(model.year[i])
    for(var j=0;j<keys.length;j++){
      d[keys[i]] = +d[keys[j]]
    }
  });
if(typeof(data)!="undefined") {
  console.log("Data loaded")
  console.log(model.year)

  //Stacking data
  var sumstat = d3.nest()
    .key(function(d) { return d.year;})
    .entries(data);

  var stackedData = d3.stack()
  .keys(group_names)
  .value(function(d,key){
    return d.values[0][key]
  })(sumstat);

  //Set up axes
  var x = d3.scaleTime()
    .domain(d3.extent(model.year.map((d,i)=>{return d3.timeParse("%Y")(d)})))
    .range([0,width]);
  svg.append("g")
    .attr("transform","translate(0,"+height+")")
    .call(d3.axisBottom(x));
  svg.append("text")
    .attr("x",width*.5)
    .attr("y",height+margin.bottom)
    .style("text-anchor","middle")
    .attr("font-family","Tahoma")
    .text("Year")

  var y = d3.scaleLinear()
  // Finds maximum of stackedData, which avoids negative values (but gives incorrect values on the y-axis) 
  .domain([0,d3.max(stackedData,
    function(d){
      //Find maximum value of data
      var max = 0;
      d.forEach(function(e,i){
        console.log(e);
        if(d3.max(e)>max) max=d3.max(e)
    })
    return max
    })
  ])
 // Finds maximum of stackedData, which gives correct values on the y-axis, but causes negative values to come out of y(d[0])
// .domain([0,d3.max(data,
  //   function(d){
  //     //Find maximum value of data
  //     var max = 0;
  //     group_names.forEach(function(key,i){
  //       console.log(key);
  //       if(d[key]>max) max=d[key]
  //   })
  //   return max
  //   })
  // ])
  .range([ height,0])

  svg.append("g")
  .call(d3.axisLeft(y));

  svg.append("text")
    .attr("y",-margin.left)
    .attr("x",-height*.5)
    .attr("dy","1em")
    .style("text-anchor","middle")
    .attr("font-family","Tahoma")
    .attr("transform","rotate(-90)")
    .text("Energy Demand (TWh /year)")

  console.log("About to plot data ")
  svg
    .selectAll("layers")
    .data(stackedData)
    .enter()
    .append("path")
      .attr("fill",function(d){return color()})
      .attr("d", d3.area()
        .x(function(d,i){ console.log("Data on line", d.data); return x(d3.timeParse("%Y")(d.data.key)) })
        .y0(function(d) {console.log(d[0] +"-> y0: "+y(d[0])); return y(d[0])})
        .y1(function(d){ console.log(d[1] + "-> y1: "+y(d[1])); return y(d[1])})
        )
}else{
  d3.select("#chart").append("Error loading data")
}

Here's the structure of data :

在此处输入图片说明

(33) […]
​
0: {…}
​​
"Electricity by CSP": 0
​​
"Electricity by PV": 0
​​
"Electricity by geothermal": 0
​​
"Electricity by hydropower": 300.89983280022
​​
"Electricity by marine power": 0
​​
"Electricity by offshore wind": 0
​​
"Electricity by onshore wind": 0
​​
"Renewable energy": 258.219863514757
​​
"Solid bioenergy": 254.640155086192
​​
"Total demand for coal": 3711.42425220673
​​
"Total demand for crude oil": 7523.960117178
​​
"Total demand for natural gas": 254.640155086192
​​
"Total demand for nuclear fuel": 2449.95477156234
​​
year: Date Mon Jan 01 1990 00:00:00 GMT+0000 (Greenwich Mean Time)
​​
<prototype>: Object { … }
​
1: Object { "Total demand for natural gas": 3220.14298481777, "Total demand for crude oil": 277.599399485849, "Total demand for coal": 3662.11547993736, … }
​
2: Object { "Total demand for natural gas": 3200.81379949803, "Total demand for crude oil": 7756.9933670896, "Total demand for coal": 273.508068071529, … }

...

Any ideas?

EDIT: 2020-02-21 I've posted a live version here: https://jsfiddle.net/turium/ywrbkzm9/

I have checked your code and there were couple of errors. I have replaced them with correct one, you can do your R&D on top of it.

  • color function was not getting called from where you were appending path.
  • there was unnecessary nesting of data.
  • created a empty model object so jsfiddle was giving an error
  • removed the time scale as it was adding overhead

Code to show x axis with years without commas.

svg.append("g")
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(x).tickFormat(function(d) {
  return d;
}));

 model = {} model.year = [ 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2020, 2025, 2030, 2035, 2040, 2045, 2050 ] model.output_energy_demand = [ [ "Total demand for natural gas", "Total demand for crude oil", "Total demand for coal", "Electricity by geothermal", "Electricity by hydropower", "Electricity by marine power", "Electricity by CSP", "Electricity by PV", "Electricity by offshore wind", "Electricity by onshore wind", "Total demand for nuclear fuel", "Renewable energy", "Solid bioenergy" ], [ 3102.40524991691, 7523.960117178, 3711.42425220673, 0, 300.89983280022, 0, 0, 0, 0, 0, 2449.95477156234, 258.219863514757, 254.640155086192 ], [ 3220.14298481777, 7805.34286934201, 3662.11547993736, 0, 314.08215981732, 0, 0, 0, 0, 0, 2392.85347025885, 281.174663414415, 277.599399485849 ], [ 3200.81379949803, 7756.9933670896, 3445.10585509343, 0, 340.4890868346, 0, 0, 0, 0, 0, 2512.86260946551, 277.266526000094, 273.508068071529 ], [ 3305.31292778359, 7783.82326263428, 3472.68950574908, 0, 353.62925132022, 0, 0, 0, 0, 0, 2666.91820506714, 305.773519651316, 302.045477722751 ], [ 3367.00236478057, 7565.09225038114, 3413.93067723008, 0, 367.522212360599, 0, 0, 0, 0, 0, 2657.48508853596, 292.303360572476, 288.50963564391 ], [ 3487.48732706185, 7615.43451245472, 3406.94135763491, 0, 362.74326344874, 0, 0, 0, 0, 0, 2720.41544041992, 297.511985344959, 293.709384916393 ], [ 3744.9593399799, 7826.17851688842, 3449.136453147, 0, 355.3673026203, 0, 0, 0, 0, 0, 2871.17913811302, 323.48891655571, 319.711924627145 ], [ 3734.32219482531, 7545.58234604822, 3285.22078771847, 0, 367.27291222956, 0, 0, 0, 0, 0, 2895.07611993084, 333.778821035599, 329.987640607034 ], [ 3834.40132308377, 7645.80240057448, 3258.37777947803, 0, 377.0867016027, 0, 0, 0, 0, 0, 2889.95225758379, 334.216219338001, 330.408223409436 ], [ 3934.10235529276, 7393.72102051037, 3147.43143379234, 0, 383.18690200752, 0, 0, 0, 0, 0, 2914.35741090846, 327.381123667362, 323.534358238797 ], [ 4087.04502061623, 7247.4110570115, 3353.99479917852, 4.82547708666, 393.52232123964, 0.5071937472, 0, 0.203524605, 0, 26.81745703056, 2931.59347644636, 332.014849186351, 326.489968757786 ], [ 4187.85080191466, 7646.26147968543, 3384.51199334096, 4.64857517429999, 420.262811562959, 0.4852086192, 0, 0.30943918638, 0, 33.45917086152, 3022.71240680316, 336.487547234091, 330.881864107789 ], [ 4205.18925700953, 7579.67080593577, 3385.97805263338, 4.79569679315999, 353.99917660788, 0.494507592, 0, 0.4051566306, 0, 46.3006537083, 3067.10289195713, 337.738844971462, 332.131957416555 ], [ 4428.70123473367, 7834.71813308874, 3524.45624865725, 5.4612635832, 343.52520531084, 0.4898581056, 0, 0.72565105788, 0, 50.9478361405199, 3069.27182555567, 374.37075694017, 368.147127662413 ], [ 4551.82743034029, 8009.62808231553, 3449.96219341097, 5.564770758, 362.514048853499, 0.470082009599999, 0, 1.46273236614, 0, 67.69761449058, 3119.33911585662, 366.098265091526, 359.153478032005 ], [ 4604.74358239693, 8096.18416223813, 3381.05306785008, 5.44094040114, 344.3848462566, 0.4813375536, 0, 2.64236395716, 0, 78.3154704733199, 3066.35144843448, 386.969328558568, 379.391483494566 ], [ 4560.10999341729, 8203.04705336058, 3469.86003803626, 5.61711543678, 346.81026188232, 0.4642543728, 0, 3.73148887734, 0, 91.38316529736, 3050.45111617217, 394.148276719482, 385.458486662152 ], [ 4519.7188056018, 7948.7483718475, 3463.98671155763, 5.82834632004, 349.48220898564, 0.4654325232, 0.00484251372, 6.14455873164, 0, 118.81064914452, 2896.72897237308, 411.77345085889, 401.790597859782 ], [ 4642.45980752563, 8095.41788904162, 3208.68777524172, 5.78038393997999, 368.10858903516, 0.4654325232, 0.0094111776, 12.7615925908799, 2.60895690648, 132.13721227626, 2918.12383597752, 446.017117805582, 433.655553095456 ], [ 4300.19124830045, 7719.81278137145, 2876.38739207936, 5.58780088086, 371.310269112539, 0.44894025846, 0.11373727212, 20.3917959088199, 5.744841114762, 145.29539623914, 2921.42403037908, 467.905545984921, 453.394070650256 ], [ 4692.03986900568, 7797.53751476991, 2959.25747160129, 5.6382101145, 412.797954991499, 0.477972636839999, 0.8062598628, 35.0866669474799, 8.22484405134, 157.81866688674, 2856.24810989478, 498.364549610955, 481.466736916603 ], [ 4235.58374324098, 7538.66495957225, 3005.00134812211, 5.91160946975999, 344.426769476279, 0.478098341279999, 1.3839112116, 66.1100621738399, 11.72086686054, 179.46124283664, 2799.25195982939, 442.390139292031, 425.641578089282 ], [ 4107.70809841702, 7399.30695265121, 3137.64857648784, 5.80847765508, 374.23402394886, 0.46268411922, 3.98578825818, 86.04398912724, 16.05857548068, 204.94524478734, 2736.84193438788, 495.32616138678, 475.76987559724 ], [ 4043.0896536257, 7415.72476474021, 3039.06605229034, 5.97630596849999, 409.64636857176, 0.420999422399999, 5.21086402044, 94.70094727536, 21.5588025313199, 227.79819933624, 2708.12027152385, 505.670520272608, 483.316979888301 ], [ 3598.13284429141, 7317.86276802473, 2846.1651910181, 6.26113715202, 412.580152851659, 0.48353974812, 5.89504961916, 102.0072482082, 25.42716943056, 240.05775513006, 2711.96611313418, 454.88706631646, 432.892324258519 ], [ 3754.93540354624, 7511.65923877049, 2800.70818111911, 6.6793685346, 380.261269231019, 0.495524623319999, 6.07585064832, 114.06062251008, 39.85985729862, 276.41099985318, 2645.38509787332, 495.328376085096, 465.28909250104 ], [ 4043.59078735007, 8017.18489716505, 2338.95806864845, 6.7875256341, 394.603505735554, 0.51747170688, 6.07585064832, 145.892562054913, 83.1198330814429, 408.732059173849, 2480.44614477944, 427.441506546882, 409.905742992792 ], [ 3291.51973731274, 4997.05071692697, 452.188235416201, 63.9709506160571, 446.050495741098, 11.6326046301965, 85.869709014152, 220.181406509467, 609.256812048776, 529.707140310043, 2717.66461431481, 593.564950874224, 388.443809434111 ], [ 2885.96717926539, 2676.62515437839, 293.191002866746, 121.154375598014, 498.701133634033, 22.747737553513, 165.663567379984, 293.862964912845, 1131.43400447885, 649.689673274539, 2893.87542604889, 676.605125561303, 339.139457453926 ], [ 2664.88017244303, 1096.4584151475, 233.59485578412, 178.337800579971, 543.439537600747, 33.8628704768296, 245.457425745816, 367.884313156941, 1650.85948123489, 769.503145366082, 2732.03449314671, 636.789912347858, 258.105935984877 ], [ 2546.12143825256, 383.69776070687, 144.591148980276, 235.521225561928, 587.785639945705, 44.9780034001461, 325.251284111648, 441.672179518208, 2167.12983644434, 889.008654837177, 2379.90569231828, 511.758583755248, 174.052538556381 ], [ 2597.56379334278, 275.045700399492, 98.1839204037293, 292.704650543886, 631.738388993547, 56.0931363234626, 405.04514247748, 515.225029663832, 2680.25396805022, 1007.80883971052, 1913.52680335554, 530.552643420933, 153.689961713093 ], [ 2749.62249643278, 192.082054109743, 61.7232837841147, 349.888075525843, 681.054211190302, 67.2082692467792, 484.839000843312, 587.790589413631, 3189.00909148252, 1125.32442426428, 1779.67241790878, 550.847796398766, 135.833335875956 ] ] //Draw graph var margin = { top: 10, right: 30, bottom: 30, left: 70 }, width = 960 - margin.left - margin.right, height = 400 - margin.top - margin.bottom; var svg = d3.select("#chart") .append("svg") .attr("width", width + margin.left + margin.right) .attr("height", height + margin.top + margin.bottom) .append("g") .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); let data = [] var group_names = [] //Assumes first line of data is table header, otherwise will not work properly debugger; model.output_energy_demand.map(function(x, i) { if (i == 0) { group_names = x } else { let line = {} x.map(function(y, j) { line[group_names[j]] = y }); data.push(line) } }); /* data.forEach((d, i) => { var keys = Object.keys(d) d.year = model.year[i]; for (var j = 0; j < keys.length; j++) { d[keys[i]] = +d[keys[j]] } }); */ data.forEach((d, i) => { d['year'] = model.year[i]; }); if (typeof(data) != "undefined") { var stackedData = d3.stack() .keys(group_names) (data); debugger; //Set up axes var x = d3.scaleLinear() .domain(d3.extent(model.year.map((d, i) => { return d }))) .range([0, width]) svg.append("g") .attr("transform", "translate(0," + height + ")") .call(d3.axisBottom(x).tickFormat(function(d) { return d; })); svg.append("text") .attr("x", width * 0.5) .attr("y", height + margin.bottom) .style("text-anchor", "middle") .attr("font-family", "Tahoma") .text("Year") var y = d3.scaleLinear() .domain([0, d3.max(stackedData, function(d) { //Find maximum value of data var max = 0; d.forEach(function(e, i) { if (d3.max(e) > max) max = d3.max(e) }) return max })]) .range([height, 0]) svg.append("g") .call(d3.axisLeft(y)); svg.append("text") .attr("y", -margin.left) .attr("x", -height * 0.5) .attr("dy", "1em") .style("text-anchor", "middle") .attr("font-family", "Tahoma") .attr("transform", "rotate(-90)") .text("Energy Demand (TWh /year)") svg .selectAll("layers") .data(stackedData) .enter() .append("path") .style("fill", function(d) { var n = Math.random() * (16 ** 7 - 1) let val = (n.toString(16)).slice(0, 6) return `#${val}`; }) .attr("d", d3.area() .x(function(d, i) { return x(d.data.year) }) .y0(function(d) { return y(d[0]) }) .y1(function(d) { return y(d[1]) }) ) } else { d3.select("#chart").append("Error loading data") }
 body { border: 0; margin: 0; min-height: 100%; width: 100%; } h2 { font-family: sans-serif; font-weight: bold; font-size: 28px; } #header { height: 56px; position: relative; top: 0; left: 0; width: 100%; background-color: #666666; } #header div { padding: 5px 0 0 10px; } #header span { color: #ffffff; font-family: sans-serif; font-weight: bold; font-size: 36px; text-shadow: #000000 1px } #content { margin: 50px; }
 <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.3.0/d3.min.js"></script> <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta http-equiv="content-type" content="text/html; charset=utf-8"> <!--<link href="css/index.css" rel="stylesheet"/>--> <title>Stacked Area Chart</title> </head> <body> <div id="header"> <div> <span>Stacked Area Chart</span> </div> </div> <div id="content"> <h2>Demo 1: Basic Graph</h2> <div id="chart"></div> </div> <!--<script type="text/javascript" src="javascripts/stacked_graph1.js"></script>--> </body> </html>

The below code was messing the data, so replaced it with much easier code to add years to dataset.

// Commented below code as it was distorting current dataset
/* data.forEach((d, i) => {
  var keys = Object.keys(d)
  d.year = model.year[i];
  for (var j = 0; j < keys.length; j++) {
d[keys[i]] = +d[keys[j]
  }
}); */

// Use below code.
data.forEach((d, i) => {
    d['year'] = model.year[i];
});

Tested the data with excel and getting the same output在此处输入图片说明

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM