How to place legends for stacked bar chart underneath in d3.js$location not working in AngularJS using d3.jshow to format time on xAxis use d3.jsDraw the line use the same y values, plots line at the bottomd3js - TypeError: string is undefinedHow to apply a pattern for a D3 bar chart?d3 - trigger event on second clickX Y Co-ordinates of Stacked BarX & Y Co-ordinates of selective bars in a stack graphD3 Y Scale, y vs height?D3 Bar Chart - Reverse Bars from Right to Left

WordPress 5.2.1 deactivated my jQuery

Why haven't we yet tried accelerating a space station with people inside to a near light speed?

How do I superimpose two math symbols?

Operators in C++ what does (::Type*)0 mean

WAS IT A CAT I SAW? Do Some Detective Work & Catch The Imposters

Mercedes C180 (W204) dash symbol

Take elements from a list based on two criteria

What weight should be given to writers groups critiques?

Where is Jon going?

ESTA validity after a visa denial

Is it legal to meet with potential future employers in the UK, whilst visiting from the USA

How to cut a climbing rope?

My players want to grind XP but we're using landmark advancement

How to melt snow without fire or body heat?

Is it truly impossible to tell what a CPU is doing?

Non-containing subsets of two sizes

Natural Armour and Weapons

When playing Edgar Markov, what is the definition of a "Vampire spell"?

Security vulnerabilities of POST over SSL

Parallel fifths in the orchestra

Public transport tickets in UK for two weeks

USPS Back Room - Trespassing?

Did this character show any indication of wanting to rule before S8E6?

Are runways booked by airlines to land their planes?



How to place legends for stacked bar chart underneath in d3.js


$location not working in AngularJS using d3.jshow to format time on xAxis use d3.jsDraw the line use the same y values, plots line at the bottomd3js - TypeError: string is undefinedHow to apply a pattern for a D3 bar chart?d3 - trigger event on second clickX Y Co-ordinates of Stacked BarX & Y Co-ordinates of selective bars in a stack graphD3 Y Scale, y vs height?D3 Bar Chart - Reverse Bars from Right to Left






.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty height:90px;width:728px;box-sizing:border-box;








0















I am trying to place the legends underneath the stacked bar chart aligned block. Can not transition it properly. Below is the code i have, at this moment the legends appear on the left top corner, what i am trying to do is the tranistion it properly underneath the stacked bar, is there any suggestion of how can i transition it so it fits the svg as well. Any suggestion will be appriciated



<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>D3 Example</title>
<script src="https://d3js.org/d3.v4.min.js"></script>
<link href='https://fonts.googleapis.com/css?family=Open+Sans' rel='stylesheet' type='text/css'>
<style>
</style>
</head>
<style>

</style>
<body>

<div class="canvas">

</div>

<script>

var data = [
month: "Q1-2016", apples: 3840, bananas: 1920, cherries: -1960,
month: "Q2-2016", apples: 1600, bananas: 1440, cherries: -960,
month: "Q3-2016", apples: 640, bananas: 960, cherries: -640,
month: "Q4-2016", apples: 320, bananas: 480, cherries: -640,
month: "Q5-2016", apples: 3840, bananas: 1920, cherries: -1960,
month: "Q6-2016", apples: 1600, bananas: 1440, cherries: -960,
month: "Q7-2016", apples: 640, bananas: 960, cherries: -640,
month: "Q8-2016", apples: 320, bananas: 480, cherries: -640,
month: "Q9-2016", apples: 3840, bananas: 1920, cherries: -1960,
month: "Q10-2016", apples: 1600, bananas: 1440, cherries: 960,
month: "Q11-2016", apples: 640, bananas: 960, cherries: -640,
month: "Q12-2016", apples: 320, bananas: 480, cherries: -640,
];

var series = d3.stack()
.keys(["apples", "bananas", "cherries"])
.offset(d3.stackOffsetDiverging)
(data);

var margin = top: 20, right: 30, bottom: 30, left: 60,
width = 900,
height = 600,
padding = 40,
svg = d3.select(".canvas").append('svg').attr('height', height).attr('width',width);

var x = d3.scaleBand()
.domain(data.map(function(d)return d.month;))
.rangeRound([margin.left, width-margin.right])
.padding(0.1);

var y = d3.scaleLinear()
.domain([d3.min(series, stackMin), d3.max(series, stackMax)])
.rangeRound([height - margin.bottom, margin.top]);

var colors = ["#66b3ff", "#b3d9ff", "#99ddff", "#99ffdd"];
var z = d3.scaleOrdinal(colors);

//create and call the axes
const xAxis = d3.axisBottom(x);
const yAxis = d3.axisLeft(y);
console.log(series);

svg.append('g')
.selectAll('g')
.data(series)
.enter().append('g')
.attr('fill', function (d)
return z(d.key);
)
.selectAll('rect')
.data(function(d) return d; )
.enter().append('rect')
.attr('width', x.bandwidth)
.attr('x', function(d) return x(d.data.month))
.attr("y", function(d) return y(d[1]); )
.attr("height", function(d) return y(d[0]) - y(d[1]); )


svg.append("g")
.attr("transform", "translate(0," + y(0) + ")")
.call(d3.axisBottom(x));

svg.append("g")
.attr("transform", "translate(" + margin.left + ",0)")
.call(d3.axisLeft(y));

var legend = svg.append('g')
.attr('class', 'legend')
.attr('transform', 'translate(' + (padding + 12) + ',0)');

legend.selectAll('rect')
.data(series)
.enter()
.append('rect')
.attr('x', 0)
.attr('y', function(d,i)
return i * 18;
)
.attr('width', 12)
.attr('height', 12)
.attr('fill', function(d,i)
return z(i);
);

legend.selectAll('text')
.data(series)
.enter()
.append('text')
.text(function(d)
return d.key;
)
.attr('x', -18)
.attr('y', function(d, i)
return i * 18;
)
.attr('text-anchor', 'start')
.attr('alignment-baseline', 'hanging');



function stackMin(serie)
return d3.min(serie, function(d) return d[0]; );


function stackMax(serie)
return d3.max(serie, function(d) return d[1]; );





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









share|improve this question




























    0















    I am trying to place the legends underneath the stacked bar chart aligned block. Can not transition it properly. Below is the code i have, at this moment the legends appear on the left top corner, what i am trying to do is the tranistion it properly underneath the stacked bar, is there any suggestion of how can i transition it so it fits the svg as well. Any suggestion will be appriciated



    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="utf-8">
    <title>D3 Example</title>
    <script src="https://d3js.org/d3.v4.min.js"></script>
    <link href='https://fonts.googleapis.com/css?family=Open+Sans' rel='stylesheet' type='text/css'>
    <style>
    </style>
    </head>
    <style>

    </style>
    <body>

    <div class="canvas">

    </div>

    <script>

    var data = [
    month: "Q1-2016", apples: 3840, bananas: 1920, cherries: -1960,
    month: "Q2-2016", apples: 1600, bananas: 1440, cherries: -960,
    month: "Q3-2016", apples: 640, bananas: 960, cherries: -640,
    month: "Q4-2016", apples: 320, bananas: 480, cherries: -640,
    month: "Q5-2016", apples: 3840, bananas: 1920, cherries: -1960,
    month: "Q6-2016", apples: 1600, bananas: 1440, cherries: -960,
    month: "Q7-2016", apples: 640, bananas: 960, cherries: -640,
    month: "Q8-2016", apples: 320, bananas: 480, cherries: -640,
    month: "Q9-2016", apples: 3840, bananas: 1920, cherries: -1960,
    month: "Q10-2016", apples: 1600, bananas: 1440, cherries: 960,
    month: "Q11-2016", apples: 640, bananas: 960, cherries: -640,
    month: "Q12-2016", apples: 320, bananas: 480, cherries: -640,
    ];

    var series = d3.stack()
    .keys(["apples", "bananas", "cherries"])
    .offset(d3.stackOffsetDiverging)
    (data);

    var margin = top: 20, right: 30, bottom: 30, left: 60,
    width = 900,
    height = 600,
    padding = 40,
    svg = d3.select(".canvas").append('svg').attr('height', height).attr('width',width);

    var x = d3.scaleBand()
    .domain(data.map(function(d)return d.month;))
    .rangeRound([margin.left, width-margin.right])
    .padding(0.1);

    var y = d3.scaleLinear()
    .domain([d3.min(series, stackMin), d3.max(series, stackMax)])
    .rangeRound([height - margin.bottom, margin.top]);

    var colors = ["#66b3ff", "#b3d9ff", "#99ddff", "#99ffdd"];
    var z = d3.scaleOrdinal(colors);

    //create and call the axes
    const xAxis = d3.axisBottom(x);
    const yAxis = d3.axisLeft(y);
    console.log(series);

    svg.append('g')
    .selectAll('g')
    .data(series)
    .enter().append('g')
    .attr('fill', function (d)
    return z(d.key);
    )
    .selectAll('rect')
    .data(function(d) return d; )
    .enter().append('rect')
    .attr('width', x.bandwidth)
    .attr('x', function(d) return x(d.data.month))
    .attr("y", function(d) return y(d[1]); )
    .attr("height", function(d) return y(d[0]) - y(d[1]); )


    svg.append("g")
    .attr("transform", "translate(0," + y(0) + ")")
    .call(d3.axisBottom(x));

    svg.append("g")
    .attr("transform", "translate(" + margin.left + ",0)")
    .call(d3.axisLeft(y));

    var legend = svg.append('g')
    .attr('class', 'legend')
    .attr('transform', 'translate(' + (padding + 12) + ',0)');

    legend.selectAll('rect')
    .data(series)
    .enter()
    .append('rect')
    .attr('x', 0)
    .attr('y', function(d,i)
    return i * 18;
    )
    .attr('width', 12)
    .attr('height', 12)
    .attr('fill', function(d,i)
    return z(i);
    );

    legend.selectAll('text')
    .data(series)
    .enter()
    .append('text')
    .text(function(d)
    return d.key;
    )
    .attr('x', -18)
    .attr('y', function(d, i)
    return i * 18;
    )
    .attr('text-anchor', 'start')
    .attr('alignment-baseline', 'hanging');



    function stackMin(serie)
    return d3.min(serie, function(d) return d[0]; );


    function stackMax(serie)
    return d3.max(serie, function(d) return d[1]; );





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









    share|improve this question
























      0












      0








      0








      I am trying to place the legends underneath the stacked bar chart aligned block. Can not transition it properly. Below is the code i have, at this moment the legends appear on the left top corner, what i am trying to do is the tranistion it properly underneath the stacked bar, is there any suggestion of how can i transition it so it fits the svg as well. Any suggestion will be appriciated



      <!DOCTYPE html>
      <html>
      <head>
      <meta charset="utf-8">
      <title>D3 Example</title>
      <script src="https://d3js.org/d3.v4.min.js"></script>
      <link href='https://fonts.googleapis.com/css?family=Open+Sans' rel='stylesheet' type='text/css'>
      <style>
      </style>
      </head>
      <style>

      </style>
      <body>

      <div class="canvas">

      </div>

      <script>

      var data = [
      month: "Q1-2016", apples: 3840, bananas: 1920, cherries: -1960,
      month: "Q2-2016", apples: 1600, bananas: 1440, cherries: -960,
      month: "Q3-2016", apples: 640, bananas: 960, cherries: -640,
      month: "Q4-2016", apples: 320, bananas: 480, cherries: -640,
      month: "Q5-2016", apples: 3840, bananas: 1920, cherries: -1960,
      month: "Q6-2016", apples: 1600, bananas: 1440, cherries: -960,
      month: "Q7-2016", apples: 640, bananas: 960, cherries: -640,
      month: "Q8-2016", apples: 320, bananas: 480, cherries: -640,
      month: "Q9-2016", apples: 3840, bananas: 1920, cherries: -1960,
      month: "Q10-2016", apples: 1600, bananas: 1440, cherries: 960,
      month: "Q11-2016", apples: 640, bananas: 960, cherries: -640,
      month: "Q12-2016", apples: 320, bananas: 480, cherries: -640,
      ];

      var series = d3.stack()
      .keys(["apples", "bananas", "cherries"])
      .offset(d3.stackOffsetDiverging)
      (data);

      var margin = top: 20, right: 30, bottom: 30, left: 60,
      width = 900,
      height = 600,
      padding = 40,
      svg = d3.select(".canvas").append('svg').attr('height', height).attr('width',width);

      var x = d3.scaleBand()
      .domain(data.map(function(d)return d.month;))
      .rangeRound([margin.left, width-margin.right])
      .padding(0.1);

      var y = d3.scaleLinear()
      .domain([d3.min(series, stackMin), d3.max(series, stackMax)])
      .rangeRound([height - margin.bottom, margin.top]);

      var colors = ["#66b3ff", "#b3d9ff", "#99ddff", "#99ffdd"];
      var z = d3.scaleOrdinal(colors);

      //create and call the axes
      const xAxis = d3.axisBottom(x);
      const yAxis = d3.axisLeft(y);
      console.log(series);

      svg.append('g')
      .selectAll('g')
      .data(series)
      .enter().append('g')
      .attr('fill', function (d)
      return z(d.key);
      )
      .selectAll('rect')
      .data(function(d) return d; )
      .enter().append('rect')
      .attr('width', x.bandwidth)
      .attr('x', function(d) return x(d.data.month))
      .attr("y", function(d) return y(d[1]); )
      .attr("height", function(d) return y(d[0]) - y(d[1]); )


      svg.append("g")
      .attr("transform", "translate(0," + y(0) + ")")
      .call(d3.axisBottom(x));

      svg.append("g")
      .attr("transform", "translate(" + margin.left + ",0)")
      .call(d3.axisLeft(y));

      var legend = svg.append('g')
      .attr('class', 'legend')
      .attr('transform', 'translate(' + (padding + 12) + ',0)');

      legend.selectAll('rect')
      .data(series)
      .enter()
      .append('rect')
      .attr('x', 0)
      .attr('y', function(d,i)
      return i * 18;
      )
      .attr('width', 12)
      .attr('height', 12)
      .attr('fill', function(d,i)
      return z(i);
      );

      legend.selectAll('text')
      .data(series)
      .enter()
      .append('text')
      .text(function(d)
      return d.key;
      )
      .attr('x', -18)
      .attr('y', function(d, i)
      return i * 18;
      )
      .attr('text-anchor', 'start')
      .attr('alignment-baseline', 'hanging');



      function stackMin(serie)
      return d3.min(serie, function(d) return d[0]; );


      function stackMax(serie)
      return d3.max(serie, function(d) return d[1]; );





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









      share|improve this question














      I am trying to place the legends underneath the stacked bar chart aligned block. Can not transition it properly. Below is the code i have, at this moment the legends appear on the left top corner, what i am trying to do is the tranistion it properly underneath the stacked bar, is there any suggestion of how can i transition it so it fits the svg as well. Any suggestion will be appriciated



      <!DOCTYPE html>
      <html>
      <head>
      <meta charset="utf-8">
      <title>D3 Example</title>
      <script src="https://d3js.org/d3.v4.min.js"></script>
      <link href='https://fonts.googleapis.com/css?family=Open+Sans' rel='stylesheet' type='text/css'>
      <style>
      </style>
      </head>
      <style>

      </style>
      <body>

      <div class="canvas">

      </div>

      <script>

      var data = [
      month: "Q1-2016", apples: 3840, bananas: 1920, cherries: -1960,
      month: "Q2-2016", apples: 1600, bananas: 1440, cherries: -960,
      month: "Q3-2016", apples: 640, bananas: 960, cherries: -640,
      month: "Q4-2016", apples: 320, bananas: 480, cherries: -640,
      month: "Q5-2016", apples: 3840, bananas: 1920, cherries: -1960,
      month: "Q6-2016", apples: 1600, bananas: 1440, cherries: -960,
      month: "Q7-2016", apples: 640, bananas: 960, cherries: -640,
      month: "Q8-2016", apples: 320, bananas: 480, cherries: -640,
      month: "Q9-2016", apples: 3840, bananas: 1920, cherries: -1960,
      month: "Q10-2016", apples: 1600, bananas: 1440, cherries: 960,
      month: "Q11-2016", apples: 640, bananas: 960, cherries: -640,
      month: "Q12-2016", apples: 320, bananas: 480, cherries: -640,
      ];

      var series = d3.stack()
      .keys(["apples", "bananas", "cherries"])
      .offset(d3.stackOffsetDiverging)
      (data);

      var margin = top: 20, right: 30, bottom: 30, left: 60,
      width = 900,
      height = 600,
      padding = 40,
      svg = d3.select(".canvas").append('svg').attr('height', height).attr('width',width);

      var x = d3.scaleBand()
      .domain(data.map(function(d)return d.month;))
      .rangeRound([margin.left, width-margin.right])
      .padding(0.1);

      var y = d3.scaleLinear()
      .domain([d3.min(series, stackMin), d3.max(series, stackMax)])
      .rangeRound([height - margin.bottom, margin.top]);

      var colors = ["#66b3ff", "#b3d9ff", "#99ddff", "#99ffdd"];
      var z = d3.scaleOrdinal(colors);

      //create and call the axes
      const xAxis = d3.axisBottom(x);
      const yAxis = d3.axisLeft(y);
      console.log(series);

      svg.append('g')
      .selectAll('g')
      .data(series)
      .enter().append('g')
      .attr('fill', function (d)
      return z(d.key);
      )
      .selectAll('rect')
      .data(function(d) return d; )
      .enter().append('rect')
      .attr('width', x.bandwidth)
      .attr('x', function(d) return x(d.data.month))
      .attr("y", function(d) return y(d[1]); )
      .attr("height", function(d) return y(d[0]) - y(d[1]); )


      svg.append("g")
      .attr("transform", "translate(0," + y(0) + ")")
      .call(d3.axisBottom(x));

      svg.append("g")
      .attr("transform", "translate(" + margin.left + ",0)")
      .call(d3.axisLeft(y));

      var legend = svg.append('g')
      .attr('class', 'legend')
      .attr('transform', 'translate(' + (padding + 12) + ',0)');

      legend.selectAll('rect')
      .data(series)
      .enter()
      .append('rect')
      .attr('x', 0)
      .attr('y', function(d,i)
      return i * 18;
      )
      .attr('width', 12)
      .attr('height', 12)
      .attr('fill', function(d,i)
      return z(i);
      );

      legend.selectAll('text')
      .data(series)
      .enter()
      .append('text')
      .text(function(d)
      return d.key;
      )
      .attr('x', -18)
      .attr('y', function(d, i)
      return i * 18;
      )
      .attr('text-anchor', 'start')
      .attr('alignment-baseline', 'hanging');



      function stackMin(serie)
      return d3.min(serie, function(d) return d[0]; );


      function stackMax(serie)
      return d3.max(serie, function(d) return d[1]; );





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






      d3.js






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Mar 24 at 0:52









      bisamovbisamov

      9418




      9418






















          1 Answer
          1






          active

          oldest

          votes


















          1














          There were a few things going wrong in your code, so I tried to fix some of it.



          1. Your chart elements (i.e. the bars and axis) should be added to a group. This will allow it to be moved/translated appropriately as needed. I create a chart variable and assigned these elements to it, rather than directly to the svg. This makes the structure easier to see when you view in the console too.


          2. The height of the legend area should be declared and accounted for in the chart. I declared this as a variable legendh and account for it in the y axis range.


          3. If you want your legend group to appear below the chart it needs to be translated below the chart. Your earlier transform on the group mentioned .attr('transform', 'translate(' + (padding + 12) + ',0)'); making the y coordinates 0. I changed it to .attr('transform', 'translate(' + (padding + 12) + ','+ (height - legendh) + ')');. This tells the legend group to move down from the top by the height - legendh amount, thus placing it below the chart.


          4. Lastly, the colors in the legend were not matching the colors in the chart/bars. This was because your bar fill was goverened by d.key but your legend fill was based on i. I chose to make it uniform and get the color using z(i).


          Here is the working block: https://bl.ocks.org/akulmehta/80153b35ab7498d30408f92cfa50f356



          Here is the working code:



          <!DOCTYPE html>
          <html>
          <head>
          <meta charset="utf-8">
          <title>D3 Example</title>
          <script src="https://d3js.org/d3.v4.min.js"></script>
          <link href='https://fonts.googleapis.com/css?family=Open+Sans' rel='stylesheet' type='text/css'>
          <style>
          </style>
          </head>
          <style>

          </style>
          <body>

          <div class="canvas">

          </div>

          <script>

          var data = [
          month: "Q1-2016", apples: 3840, bananas: 1920, cherries: -1960,
          month: "Q2-2016", apples: 1600, bananas: 1440, cherries: -960,
          month: "Q3-2016", apples: 640, bananas: 960, cherries: -640,
          month: "Q4-2016", apples: 320, bananas: 480, cherries: -640,
          month: "Q5-2016", apples: 3840, bananas: 1920, cherries: -1960,
          month: "Q6-2016", apples: 1600, bananas: 1440, cherries: -960,
          month: "Q7-2016", apples: 640, bananas: 960, cherries: -640,
          month: "Q8-2016", apples: 320, bananas: 480, cherries: -640,
          month: "Q9-2016", apples: 3840, bananas: 1920, cherries: -1960,
          month: "Q10-2016", apples: 1600, bananas: 1440, cherries: 960,
          month: "Q11-2016", apples: 640, bananas: 960, cherries: -640,
          month: "Q12-2016", apples: 320, bananas: 480, cherries: -640,
          ];

          var series = d3.stack()
          .keys(["apples", "bananas", "cherries"])
          .offset(d3.stackOffsetDiverging)
          (data);

          var margin = top: 20, right: 30, bottom: 30, left: 60,
          width = 900,
          height = 500,
          legendh = 100, //determines the height of the legend below the chart
          padding = 40,
          svg = d3.select(".canvas").append('svg').attr('height', height).attr('width',width);

          var x = d3.scaleBand()
          .domain(data.map(function(d)return d.month;))
          .rangeRound([margin.left, width-margin.right])
          .padding(0.1);

          var y = d3.scaleLinear()
          .domain([d3.min(series, stackMin), d3.max(series, stackMax)])
          .rangeRound([height - margin.bottom - legendh, margin.top]);

          var colors = ["#66b3ff", "#b3d9ff", "#99ddff", "#99ffdd"];
          var z = d3.scaleOrdinal(colors);

          //create and call the axes
          const xAxis = d3.axisBottom(x);
          const yAxis = d3.axisLeft(y);


          var chart = svg.append('g').attr('id','chart'); //make a chart group inside the svg

          chart.append('g')
          .selectAll('g')
          .data(series)
          .enter().append('g')
          .attr('fill', function (d,i) //because the legend is based on i this should also be based on i
          return z(i);
          )
          .selectAll('rect')
          .data(function(d) return d; )
          .enter().append('rect')
          .attr('width', x.bandwidth)
          .attr('x', function(d) return x(d.data.month))
          .attr("y", function(d) return y(d[1]); )
          .attr("height", function(d) return y(d[0]) - y(d[1]); )


          chart.append("g")
          .attr("transform", "translate(0," + y(0) + ")")
          .call(d3.axisBottom(x));

          chart.append("g")
          .attr("transform", "translate(" + margin.left + ",0)")
          .call(d3.axisLeft(y));

          var legend = svg.append('g')
          .attr('class', 'legend')
          .attr('transform', 'translate(' + (padding + 12) + ','+ (height - legendh) + ')');

          legend.selectAll('rect')
          .data(series)
          .enter()
          .append('rect')
          .attr('x', 0)
          .attr('y', function(d,i)
          return i * 18;
          )
          .attr('width', 12)
          .attr('height', 12)
          .attr('fill', function(d,i)
          console.log(z(i));
          return z(i);
          );

          legend.selectAll('text')
          .data(series)
          .enter()
          .append('text')
          .text(function(d)
          return d.key;
          )
          .attr('x', 15)
          .attr('y', function(d, i)
          return i * 18;
          )
          .attr('text-anchor', 'start')
          .attr('alignment-baseline', 'hanging');



          function stackMin(serie)
          return d3.min(serie, function(d) return d[0]; );


          function stackMax(serie)
          return d3.max(serie, function(d) return d[1]; );





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





          share|improve this answer























            Your Answer






            StackExchange.ifUsing("editor", function ()
            StackExchange.using("externalEditor", function ()
            StackExchange.using("snippets", function ()
            StackExchange.snippets.init();
            );
            );
            , "code-snippets");

            StackExchange.ready(function()
            var channelOptions =
            tags: "".split(" "),
            id: "1"
            ;
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function()
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled)
            StackExchange.using("snippets", function()
            createEditor();
            );

            else
            createEditor();

            );

            function createEditor()
            StackExchange.prepareEditor(
            heartbeatType: 'answer',
            autoActivateHeartbeat: false,
            convertImagesToLinks: true,
            noModals: true,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: 10,
            bindNavPrevention: true,
            postfix: "",
            imageUploader:
            brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
            contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
            allowUrls: true
            ,
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            );



            );













            draft saved

            draft discarded


















            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55319777%2fhow-to-place-legends-for-stacked-bar-chart-underneath-in-d3-js%23new-answer', 'question_page');

            );

            Post as a guest















            Required, but never shown

























            1 Answer
            1






            active

            oldest

            votes








            1 Answer
            1






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes









            1














            There were a few things going wrong in your code, so I tried to fix some of it.



            1. Your chart elements (i.e. the bars and axis) should be added to a group. This will allow it to be moved/translated appropriately as needed. I create a chart variable and assigned these elements to it, rather than directly to the svg. This makes the structure easier to see when you view in the console too.


            2. The height of the legend area should be declared and accounted for in the chart. I declared this as a variable legendh and account for it in the y axis range.


            3. If you want your legend group to appear below the chart it needs to be translated below the chart. Your earlier transform on the group mentioned .attr('transform', 'translate(' + (padding + 12) + ',0)'); making the y coordinates 0. I changed it to .attr('transform', 'translate(' + (padding + 12) + ','+ (height - legendh) + ')');. This tells the legend group to move down from the top by the height - legendh amount, thus placing it below the chart.


            4. Lastly, the colors in the legend were not matching the colors in the chart/bars. This was because your bar fill was goverened by d.key but your legend fill was based on i. I chose to make it uniform and get the color using z(i).


            Here is the working block: https://bl.ocks.org/akulmehta/80153b35ab7498d30408f92cfa50f356



            Here is the working code:



            <!DOCTYPE html>
            <html>
            <head>
            <meta charset="utf-8">
            <title>D3 Example</title>
            <script src="https://d3js.org/d3.v4.min.js"></script>
            <link href='https://fonts.googleapis.com/css?family=Open+Sans' rel='stylesheet' type='text/css'>
            <style>
            </style>
            </head>
            <style>

            </style>
            <body>

            <div class="canvas">

            </div>

            <script>

            var data = [
            month: "Q1-2016", apples: 3840, bananas: 1920, cherries: -1960,
            month: "Q2-2016", apples: 1600, bananas: 1440, cherries: -960,
            month: "Q3-2016", apples: 640, bananas: 960, cherries: -640,
            month: "Q4-2016", apples: 320, bananas: 480, cherries: -640,
            month: "Q5-2016", apples: 3840, bananas: 1920, cherries: -1960,
            month: "Q6-2016", apples: 1600, bananas: 1440, cherries: -960,
            month: "Q7-2016", apples: 640, bananas: 960, cherries: -640,
            month: "Q8-2016", apples: 320, bananas: 480, cherries: -640,
            month: "Q9-2016", apples: 3840, bananas: 1920, cherries: -1960,
            month: "Q10-2016", apples: 1600, bananas: 1440, cherries: 960,
            month: "Q11-2016", apples: 640, bananas: 960, cherries: -640,
            month: "Q12-2016", apples: 320, bananas: 480, cherries: -640,
            ];

            var series = d3.stack()
            .keys(["apples", "bananas", "cherries"])
            .offset(d3.stackOffsetDiverging)
            (data);

            var margin = top: 20, right: 30, bottom: 30, left: 60,
            width = 900,
            height = 500,
            legendh = 100, //determines the height of the legend below the chart
            padding = 40,
            svg = d3.select(".canvas").append('svg').attr('height', height).attr('width',width);

            var x = d3.scaleBand()
            .domain(data.map(function(d)return d.month;))
            .rangeRound([margin.left, width-margin.right])
            .padding(0.1);

            var y = d3.scaleLinear()
            .domain([d3.min(series, stackMin), d3.max(series, stackMax)])
            .rangeRound([height - margin.bottom - legendh, margin.top]);

            var colors = ["#66b3ff", "#b3d9ff", "#99ddff", "#99ffdd"];
            var z = d3.scaleOrdinal(colors);

            //create and call the axes
            const xAxis = d3.axisBottom(x);
            const yAxis = d3.axisLeft(y);


            var chart = svg.append('g').attr('id','chart'); //make a chart group inside the svg

            chart.append('g')
            .selectAll('g')
            .data(series)
            .enter().append('g')
            .attr('fill', function (d,i) //because the legend is based on i this should also be based on i
            return z(i);
            )
            .selectAll('rect')
            .data(function(d) return d; )
            .enter().append('rect')
            .attr('width', x.bandwidth)
            .attr('x', function(d) return x(d.data.month))
            .attr("y", function(d) return y(d[1]); )
            .attr("height", function(d) return y(d[0]) - y(d[1]); )


            chart.append("g")
            .attr("transform", "translate(0," + y(0) + ")")
            .call(d3.axisBottom(x));

            chart.append("g")
            .attr("transform", "translate(" + margin.left + ",0)")
            .call(d3.axisLeft(y));

            var legend = svg.append('g')
            .attr('class', 'legend')
            .attr('transform', 'translate(' + (padding + 12) + ','+ (height - legendh) + ')');

            legend.selectAll('rect')
            .data(series)
            .enter()
            .append('rect')
            .attr('x', 0)
            .attr('y', function(d,i)
            return i * 18;
            )
            .attr('width', 12)
            .attr('height', 12)
            .attr('fill', function(d,i)
            console.log(z(i));
            return z(i);
            );

            legend.selectAll('text')
            .data(series)
            .enter()
            .append('text')
            .text(function(d)
            return d.key;
            )
            .attr('x', 15)
            .attr('y', function(d, i)
            return i * 18;
            )
            .attr('text-anchor', 'start')
            .attr('alignment-baseline', 'hanging');



            function stackMin(serie)
            return d3.min(serie, function(d) return d[0]; );


            function stackMax(serie)
            return d3.max(serie, function(d) return d[1]; );





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





            share|improve this answer



























              1














              There were a few things going wrong in your code, so I tried to fix some of it.



              1. Your chart elements (i.e. the bars and axis) should be added to a group. This will allow it to be moved/translated appropriately as needed. I create a chart variable and assigned these elements to it, rather than directly to the svg. This makes the structure easier to see when you view in the console too.


              2. The height of the legend area should be declared and accounted for in the chart. I declared this as a variable legendh and account for it in the y axis range.


              3. If you want your legend group to appear below the chart it needs to be translated below the chart. Your earlier transform on the group mentioned .attr('transform', 'translate(' + (padding + 12) + ',0)'); making the y coordinates 0. I changed it to .attr('transform', 'translate(' + (padding + 12) + ','+ (height - legendh) + ')');. This tells the legend group to move down from the top by the height - legendh amount, thus placing it below the chart.


              4. Lastly, the colors in the legend were not matching the colors in the chart/bars. This was because your bar fill was goverened by d.key but your legend fill was based on i. I chose to make it uniform and get the color using z(i).


              Here is the working block: https://bl.ocks.org/akulmehta/80153b35ab7498d30408f92cfa50f356



              Here is the working code:



              <!DOCTYPE html>
              <html>
              <head>
              <meta charset="utf-8">
              <title>D3 Example</title>
              <script src="https://d3js.org/d3.v4.min.js"></script>
              <link href='https://fonts.googleapis.com/css?family=Open+Sans' rel='stylesheet' type='text/css'>
              <style>
              </style>
              </head>
              <style>

              </style>
              <body>

              <div class="canvas">

              </div>

              <script>

              var data = [
              month: "Q1-2016", apples: 3840, bananas: 1920, cherries: -1960,
              month: "Q2-2016", apples: 1600, bananas: 1440, cherries: -960,
              month: "Q3-2016", apples: 640, bananas: 960, cherries: -640,
              month: "Q4-2016", apples: 320, bananas: 480, cherries: -640,
              month: "Q5-2016", apples: 3840, bananas: 1920, cherries: -1960,
              month: "Q6-2016", apples: 1600, bananas: 1440, cherries: -960,
              month: "Q7-2016", apples: 640, bananas: 960, cherries: -640,
              month: "Q8-2016", apples: 320, bananas: 480, cherries: -640,
              month: "Q9-2016", apples: 3840, bananas: 1920, cherries: -1960,
              month: "Q10-2016", apples: 1600, bananas: 1440, cherries: 960,
              month: "Q11-2016", apples: 640, bananas: 960, cherries: -640,
              month: "Q12-2016", apples: 320, bananas: 480, cherries: -640,
              ];

              var series = d3.stack()
              .keys(["apples", "bananas", "cherries"])
              .offset(d3.stackOffsetDiverging)
              (data);

              var margin = top: 20, right: 30, bottom: 30, left: 60,
              width = 900,
              height = 500,
              legendh = 100, //determines the height of the legend below the chart
              padding = 40,
              svg = d3.select(".canvas").append('svg').attr('height', height).attr('width',width);

              var x = d3.scaleBand()
              .domain(data.map(function(d)return d.month;))
              .rangeRound([margin.left, width-margin.right])
              .padding(0.1);

              var y = d3.scaleLinear()
              .domain([d3.min(series, stackMin), d3.max(series, stackMax)])
              .rangeRound([height - margin.bottom - legendh, margin.top]);

              var colors = ["#66b3ff", "#b3d9ff", "#99ddff", "#99ffdd"];
              var z = d3.scaleOrdinal(colors);

              //create and call the axes
              const xAxis = d3.axisBottom(x);
              const yAxis = d3.axisLeft(y);


              var chart = svg.append('g').attr('id','chart'); //make a chart group inside the svg

              chart.append('g')
              .selectAll('g')
              .data(series)
              .enter().append('g')
              .attr('fill', function (d,i) //because the legend is based on i this should also be based on i
              return z(i);
              )
              .selectAll('rect')
              .data(function(d) return d; )
              .enter().append('rect')
              .attr('width', x.bandwidth)
              .attr('x', function(d) return x(d.data.month))
              .attr("y", function(d) return y(d[1]); )
              .attr("height", function(d) return y(d[0]) - y(d[1]); )


              chart.append("g")
              .attr("transform", "translate(0," + y(0) + ")")
              .call(d3.axisBottom(x));

              chart.append("g")
              .attr("transform", "translate(" + margin.left + ",0)")
              .call(d3.axisLeft(y));

              var legend = svg.append('g')
              .attr('class', 'legend')
              .attr('transform', 'translate(' + (padding + 12) + ','+ (height - legendh) + ')');

              legend.selectAll('rect')
              .data(series)
              .enter()
              .append('rect')
              .attr('x', 0)
              .attr('y', function(d,i)
              return i * 18;
              )
              .attr('width', 12)
              .attr('height', 12)
              .attr('fill', function(d,i)
              console.log(z(i));
              return z(i);
              );

              legend.selectAll('text')
              .data(series)
              .enter()
              .append('text')
              .text(function(d)
              return d.key;
              )
              .attr('x', 15)
              .attr('y', function(d, i)
              return i * 18;
              )
              .attr('text-anchor', 'start')
              .attr('alignment-baseline', 'hanging');



              function stackMin(serie)
              return d3.min(serie, function(d) return d[0]; );


              function stackMax(serie)
              return d3.max(serie, function(d) return d[1]; );





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





              share|improve this answer

























                1












                1








                1







                There were a few things going wrong in your code, so I tried to fix some of it.



                1. Your chart elements (i.e. the bars and axis) should be added to a group. This will allow it to be moved/translated appropriately as needed. I create a chart variable and assigned these elements to it, rather than directly to the svg. This makes the structure easier to see when you view in the console too.


                2. The height of the legend area should be declared and accounted for in the chart. I declared this as a variable legendh and account for it in the y axis range.


                3. If you want your legend group to appear below the chart it needs to be translated below the chart. Your earlier transform on the group mentioned .attr('transform', 'translate(' + (padding + 12) + ',0)'); making the y coordinates 0. I changed it to .attr('transform', 'translate(' + (padding + 12) + ','+ (height - legendh) + ')');. This tells the legend group to move down from the top by the height - legendh amount, thus placing it below the chart.


                4. Lastly, the colors in the legend were not matching the colors in the chart/bars. This was because your bar fill was goverened by d.key but your legend fill was based on i. I chose to make it uniform and get the color using z(i).


                Here is the working block: https://bl.ocks.org/akulmehta/80153b35ab7498d30408f92cfa50f356



                Here is the working code:



                <!DOCTYPE html>
                <html>
                <head>
                <meta charset="utf-8">
                <title>D3 Example</title>
                <script src="https://d3js.org/d3.v4.min.js"></script>
                <link href='https://fonts.googleapis.com/css?family=Open+Sans' rel='stylesheet' type='text/css'>
                <style>
                </style>
                </head>
                <style>

                </style>
                <body>

                <div class="canvas">

                </div>

                <script>

                var data = [
                month: "Q1-2016", apples: 3840, bananas: 1920, cherries: -1960,
                month: "Q2-2016", apples: 1600, bananas: 1440, cherries: -960,
                month: "Q3-2016", apples: 640, bananas: 960, cherries: -640,
                month: "Q4-2016", apples: 320, bananas: 480, cherries: -640,
                month: "Q5-2016", apples: 3840, bananas: 1920, cherries: -1960,
                month: "Q6-2016", apples: 1600, bananas: 1440, cherries: -960,
                month: "Q7-2016", apples: 640, bananas: 960, cherries: -640,
                month: "Q8-2016", apples: 320, bananas: 480, cherries: -640,
                month: "Q9-2016", apples: 3840, bananas: 1920, cherries: -1960,
                month: "Q10-2016", apples: 1600, bananas: 1440, cherries: 960,
                month: "Q11-2016", apples: 640, bananas: 960, cherries: -640,
                month: "Q12-2016", apples: 320, bananas: 480, cherries: -640,
                ];

                var series = d3.stack()
                .keys(["apples", "bananas", "cherries"])
                .offset(d3.stackOffsetDiverging)
                (data);

                var margin = top: 20, right: 30, bottom: 30, left: 60,
                width = 900,
                height = 500,
                legendh = 100, //determines the height of the legend below the chart
                padding = 40,
                svg = d3.select(".canvas").append('svg').attr('height', height).attr('width',width);

                var x = d3.scaleBand()
                .domain(data.map(function(d)return d.month;))
                .rangeRound([margin.left, width-margin.right])
                .padding(0.1);

                var y = d3.scaleLinear()
                .domain([d3.min(series, stackMin), d3.max(series, stackMax)])
                .rangeRound([height - margin.bottom - legendh, margin.top]);

                var colors = ["#66b3ff", "#b3d9ff", "#99ddff", "#99ffdd"];
                var z = d3.scaleOrdinal(colors);

                //create and call the axes
                const xAxis = d3.axisBottom(x);
                const yAxis = d3.axisLeft(y);


                var chart = svg.append('g').attr('id','chart'); //make a chart group inside the svg

                chart.append('g')
                .selectAll('g')
                .data(series)
                .enter().append('g')
                .attr('fill', function (d,i) //because the legend is based on i this should also be based on i
                return z(i);
                )
                .selectAll('rect')
                .data(function(d) return d; )
                .enter().append('rect')
                .attr('width', x.bandwidth)
                .attr('x', function(d) return x(d.data.month))
                .attr("y", function(d) return y(d[1]); )
                .attr("height", function(d) return y(d[0]) - y(d[1]); )


                chart.append("g")
                .attr("transform", "translate(0," + y(0) + ")")
                .call(d3.axisBottom(x));

                chart.append("g")
                .attr("transform", "translate(" + margin.left + ",0)")
                .call(d3.axisLeft(y));

                var legend = svg.append('g')
                .attr('class', 'legend')
                .attr('transform', 'translate(' + (padding + 12) + ','+ (height - legendh) + ')');

                legend.selectAll('rect')
                .data(series)
                .enter()
                .append('rect')
                .attr('x', 0)
                .attr('y', function(d,i)
                return i * 18;
                )
                .attr('width', 12)
                .attr('height', 12)
                .attr('fill', function(d,i)
                console.log(z(i));
                return z(i);
                );

                legend.selectAll('text')
                .data(series)
                .enter()
                .append('text')
                .text(function(d)
                return d.key;
                )
                .attr('x', 15)
                .attr('y', function(d, i)
                return i * 18;
                )
                .attr('text-anchor', 'start')
                .attr('alignment-baseline', 'hanging');



                function stackMin(serie)
                return d3.min(serie, function(d) return d[0]; );


                function stackMax(serie)
                return d3.max(serie, function(d) return d[1]; );





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





                share|improve this answer













                There were a few things going wrong in your code, so I tried to fix some of it.



                1. Your chart elements (i.e. the bars and axis) should be added to a group. This will allow it to be moved/translated appropriately as needed. I create a chart variable and assigned these elements to it, rather than directly to the svg. This makes the structure easier to see when you view in the console too.


                2. The height of the legend area should be declared and accounted for in the chart. I declared this as a variable legendh and account for it in the y axis range.


                3. If you want your legend group to appear below the chart it needs to be translated below the chart. Your earlier transform on the group mentioned .attr('transform', 'translate(' + (padding + 12) + ',0)'); making the y coordinates 0. I changed it to .attr('transform', 'translate(' + (padding + 12) + ','+ (height - legendh) + ')');. This tells the legend group to move down from the top by the height - legendh amount, thus placing it below the chart.


                4. Lastly, the colors in the legend were not matching the colors in the chart/bars. This was because your bar fill was goverened by d.key but your legend fill was based on i. I chose to make it uniform and get the color using z(i).


                Here is the working block: https://bl.ocks.org/akulmehta/80153b35ab7498d30408f92cfa50f356



                Here is the working code:



                <!DOCTYPE html>
                <html>
                <head>
                <meta charset="utf-8">
                <title>D3 Example</title>
                <script src="https://d3js.org/d3.v4.min.js"></script>
                <link href='https://fonts.googleapis.com/css?family=Open+Sans' rel='stylesheet' type='text/css'>
                <style>
                </style>
                </head>
                <style>

                </style>
                <body>

                <div class="canvas">

                </div>

                <script>

                var data = [
                month: "Q1-2016", apples: 3840, bananas: 1920, cherries: -1960,
                month: "Q2-2016", apples: 1600, bananas: 1440, cherries: -960,
                month: "Q3-2016", apples: 640, bananas: 960, cherries: -640,
                month: "Q4-2016", apples: 320, bananas: 480, cherries: -640,
                month: "Q5-2016", apples: 3840, bananas: 1920, cherries: -1960,
                month: "Q6-2016", apples: 1600, bananas: 1440, cherries: -960,
                month: "Q7-2016", apples: 640, bananas: 960, cherries: -640,
                month: "Q8-2016", apples: 320, bananas: 480, cherries: -640,
                month: "Q9-2016", apples: 3840, bananas: 1920, cherries: -1960,
                month: "Q10-2016", apples: 1600, bananas: 1440, cherries: 960,
                month: "Q11-2016", apples: 640, bananas: 960, cherries: -640,
                month: "Q12-2016", apples: 320, bananas: 480, cherries: -640,
                ];

                var series = d3.stack()
                .keys(["apples", "bananas", "cherries"])
                .offset(d3.stackOffsetDiverging)
                (data);

                var margin = top: 20, right: 30, bottom: 30, left: 60,
                width = 900,
                height = 500,
                legendh = 100, //determines the height of the legend below the chart
                padding = 40,
                svg = d3.select(".canvas").append('svg').attr('height', height).attr('width',width);

                var x = d3.scaleBand()
                .domain(data.map(function(d)return d.month;))
                .rangeRound([margin.left, width-margin.right])
                .padding(0.1);

                var y = d3.scaleLinear()
                .domain([d3.min(series, stackMin), d3.max(series, stackMax)])
                .rangeRound([height - margin.bottom - legendh, margin.top]);

                var colors = ["#66b3ff", "#b3d9ff", "#99ddff", "#99ffdd"];
                var z = d3.scaleOrdinal(colors);

                //create and call the axes
                const xAxis = d3.axisBottom(x);
                const yAxis = d3.axisLeft(y);


                var chart = svg.append('g').attr('id','chart'); //make a chart group inside the svg

                chart.append('g')
                .selectAll('g')
                .data(series)
                .enter().append('g')
                .attr('fill', function (d,i) //because the legend is based on i this should also be based on i
                return z(i);
                )
                .selectAll('rect')
                .data(function(d) return d; )
                .enter().append('rect')
                .attr('width', x.bandwidth)
                .attr('x', function(d) return x(d.data.month))
                .attr("y", function(d) return y(d[1]); )
                .attr("height", function(d) return y(d[0]) - y(d[1]); )


                chart.append("g")
                .attr("transform", "translate(0," + y(0) + ")")
                .call(d3.axisBottom(x));

                chart.append("g")
                .attr("transform", "translate(" + margin.left + ",0)")
                .call(d3.axisLeft(y));

                var legend = svg.append('g')
                .attr('class', 'legend')
                .attr('transform', 'translate(' + (padding + 12) + ','+ (height - legendh) + ')');

                legend.selectAll('rect')
                .data(series)
                .enter()
                .append('rect')
                .attr('x', 0)
                .attr('y', function(d,i)
                return i * 18;
                )
                .attr('width', 12)
                .attr('height', 12)
                .attr('fill', function(d,i)
                console.log(z(i));
                return z(i);
                );

                legend.selectAll('text')
                .data(series)
                .enter()
                .append('text')
                .text(function(d)
                return d.key;
                )
                .attr('x', 15)
                .attr('y', function(d, i)
                return i * 18;
                )
                .attr('text-anchor', 'start')
                .attr('alignment-baseline', 'hanging');



                function stackMin(serie)
                return d3.min(serie, function(d) return d[0]; );


                function stackMax(serie)
                return d3.max(serie, function(d) return d[1]; );





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






                share|improve this answer












                share|improve this answer



                share|improve this answer










                answered Mar 24 at 17:37









                CoolaCoola

                411514




                411514



























                    draft saved

                    draft discarded
















































                    Thanks for contributing an answer to Stack Overflow!


                    • Please be sure to answer the question. Provide details and share your research!

                    But avoid


                    • Asking for help, clarification, or responding to other answers.

                    • Making statements based on opinion; back them up with references or personal experience.

                    To learn more, see our tips on writing great answers.




                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function ()
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55319777%2fhow-to-place-legends-for-stacked-bar-chart-underneath-in-d3-js%23new-answer', 'question_page');

                    );

                    Post as a guest















                    Required, but never shown





















































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown

































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown







                    Popular posts from this blog

                    Kamusi Yaliyomo Aina za kamusi | Muundo wa kamusi | Faida za kamusi | Dhima ya picha katika kamusi | Marejeo | Tazama pia | Viungo vya nje | UrambazajiKuhusu kamusiGo-SwahiliWiki-KamusiKamusi ya Kiswahili na Kiingerezakuihariri na kuongeza habari

                    Swift 4 - func physicsWorld not invoked on collision? The Next CEO of Stack OverflowHow to call Objective-C code from Swift#ifdef replacement in the Swift language@selector() in Swift?#pragma mark in Swift?Swift for loop: for index, element in array?dispatch_after - GCD in Swift?Swift Beta performance: sorting arraysSplit a String into an array in Swift?The use of Swift 3 @objc inference in Swift 4 mode is deprecated?How to optimize UITableViewCell, because my UITableView lags

                    Access current req object everywhere in Node.js ExpressWhy are global variables considered bad practice? (node.js)Using req & res across functionsHow do I get the path to the current script with Node.js?What is Node.js' Connect, Express and “middleware”?Node.js w/ express error handling in callbackHow to access the GET parameters after “?” in Express?Modify Node.js req object parametersAccess “app” variable inside of ExpressJS/ConnectJS middleware?Node.js Express app - request objectAngular Http Module considered middleware?Session variables in ExpressJSAdd properties to the req object in expressjs with Typescript