D3.js - Stacked Chart

D3.js - Stacked Chart

by Rajesh Danabal

HTML

<html>

  <head>
    <meta charset="utf-8">
    <script src="https://d3js.org/d3.v4.min.js"></script>
  </head>

  <body>
    <!-- Create a div where the graph will take place -->
    <div id="my_dataviz" class='resizable'>
      <div class='resizers'>
        <div class='resizer top-left'></div>
        <div class='resizer top-right'></div>
        <div class='resizer bottom-left'></div>
        <div class='resizer bottom-right'></div>
      </div>
    </div>
  </body>

</html>

CSS

svg {
  font-family: Sans-Serif, Arial;
}

.Actuals {
  stroke-width: 2px;
  stroke: black;
  fill: none;

}

.Forecast {
  stroke: black;
  stroke-width: 2px;
  fill: none;

}

.Planned {
  stroke: black;
  stroke-width: 3px;
  fill: none;

}

.PriorYear {
  stroke: grey;
  stroke-width: 2px;
  fill: none;
}

circle: {
  fill: none;
  stroke-dasharray: 3, 3
}

circle .selected {
  stroke: red !important;
}

.text {
  font-size: 12px;
}

.title-text {
  font-size: 12px;
}

.belowarea {
  fill: red;
}

.abovearea {
  fill: green;
}

body,
html {
  background: black;
}

.resizable {
  background: white;
  width: 100px;
  height: 100px;
  position: absolute;
  top: 100px;
  left: 100px;
}

.resizable .resizers {
  width: 100%;
  height: 100%;
  border: 3px solid #4286f4;
  box-sizing: border-box;
}

.resizable .resizers .resizer {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  /*magic to turn square into circle*/
  background: white;
  border: 3px solid #4286f4;
  position: absolute;
}

.resizable .resizers .resizer.top-left {
  left: -5px;
  top: -5px;
  cursor: nwse-resize;
  /*resizer cursor*/
}

.resizable .resizers .resizer.top-right {
  right: -5px;
  top: -5px;
  cursor: nesw-resize;
}

.resizable .resizers .resizer.bottom-left {
  left: -5px;
  bottom: -5px;
  cursor: nesw-resize;
}

.resizable .resizers .resizer.bottom-right {
  right: -5px;
  bottom: -5px;
  cursor: nwse-resize;
}

#my_dataviz {
  height: 420px;
  width: 460px;
  margin: 15px;
}

JavaScript

function render() {
  // set the dimensions and margins of the graph
  const rect = document.getElementById('my_dataviz').getBoundingClientRect();
  console.log(rect)
  var margin = {
      top: 10,
      right: 30,
      bottom: 20,
      left: 50
    },
    width = rect.width - margin.left - margin.right,
    height = rect.height - margin.top - margin.bottom;

  // append the svg object to the body of the page
  var svg = d3.select(".resizers")
    .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 + ")");

  // Parse the Data
  d3.csv("https://raw.githubusercontent.com/holtzy/D3-graph-gallery/master/DATA/data_stacked.csv", function(data) {

    // List of subgroups = header of the csv files = soil condition here
    var subgroups = data.columns.slice(1)

    console.log("data", data)

    // List of groups = species here = value of the first column called group -> I show them on the X axis
    var groups = d3.map(data, function(d) {
      return (d.group)
    }).keys()

    // Add X axis
    var x = d3.scaleBand()
      .domain(groups)
      .range([0, width])
      .padding([0.2])
    svg.append("g")
      .attr("transform", "translate(0," + height + ")")
      .call(d3.axisBottom(x).tickSizeOuter(0));

    // Add Y axis
    var y = d3.scaleLinear()
      .domain([0, 60])
      .range([height, 0]);
    svg.append("g")
      .call(d3.axisLeft(y));

    // color palette = one color per subgroup
    var color = d3.scaleOrdinal()
      .domain(subgroups)
      .range(['#e41a1c', '#377eb8', '#4daf4a'])

    //stack the data? --> stack per subgroup
    var stackedData = d3.stack()
      .keys(subgroups)
      (data);

    console.log("stackedData", stackedData);
    // Show the bars
    svg.append("g")
      .selectAll("g")
      // Enter in the stack data = loop key per key = group per group
     ...