1

I try to create stacked bar chart like https://bl.ocks.org/mbostock/1134768. But I don't want to use .tsv file

How can I create the stacked bar chart with an array like below?

var data=[
    {date:'Jan',total:100, disease:20, wounds: 5,  other: 10},
    {date:'Feb',total:200, disease:25, wounds: 10, other: 20}   
];

Any suggestion should be appreciated.

2

1 Answer 1

3

These are the steps for the bl.ocks you linked (have in mind that, since you didn't provide your code, I'll write the answer to that bl.ocks specifically):

  1. Hardcode your data:

    var crimea = [{
        date: "4/1854",
        total: "8571",
        disease: "1",
        wounds: "0",
        other: "5"
    }, {
        date: "5/1854",
        total: "23333",
        disease: "12",
        wounds: "0",
        other: "9"
    },
    etc...
    ]
    
  2. Move the row function to a forEach loop:

    crimea.forEach(function(d) {
        d.date = parseDate(d.date);
        causes.forEach(function(c) {
            d[c] = +d[c];
        });
    })
    
  3. Get rid of the TSV.

This is the code with those changes:

<style>
  .axis text {
    font: 10px sans-serif;
  }
  
  .axis line,
  .axis path {
    fill: none;
    stroke: #000;
    shape-rendering: crispEdges;
  }
  
  .axis--x path {
    display: none;
  }
</style>

<body>
  <script src="//d3js.org/d3.v3.min.js"></script>
  <script>
    var causes = ["wounds", "other", "disease"];

    var parseDate = d3.time.format("%m/%Y").parse;

    var margin = {
        top: 20,
        right: 50,
        bottom: 30,
        left: 20
      },
      width = 960 - margin.left - margin.right,
      height = 500 - margin.top - margin.bottom;

    var x = d3.scale.ordinal()
      .rangeRoundBands([0, width]);

    var y = d3.scale.linear()
      .rangeRound([height, 0]);

    var z = d3.scale.category10();

    var xAxis = d3.svg.axis()
      .scale(x)
      .orient("bottom")
      .tickFormat(d3.time.format("%b"));

    var yAxis = d3.svg.axis()
      .scale(y)
      .orient("right");

    var svg = d3.select("body").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 + ")");

    var crimea = [{
        date: "4/1854",
        total: "8571",
        disease: "1",
        wounds: "0",
        other: "5"
      },
      {
        date: "5/1854",
        total: "23333",
        disease: "12",
        wounds: "0",
        other: "9"
      },
      {
        date: "6/1854",
        total: "28333",
        disease: "11",
        wounds: "0",
        other: "6"
      },
      {
        date: "7/1854",
        total: "28772",
        disease: "359",
        wounds: "0",
        other: "23"
      },
      {
        date: "8/1854",
        total: "30246",
        disease: "828",
        wounds: "1",
        other: "30"
      },
      {
        date: "9/1854",
        total: "30290",
        disease: "788",
        wounds: "81",
        other: "70"
      },
      {
        date: "10/1854",
        total: "30643",
        disease: "503",
        wounds: "132",
        other: "128"
      },
      {
        date: "11/1854",
        total: "29736",
        disease: "844",
        wounds: "287",
        other: "106"
      },
      {
        date: "12/1854",
        total: "32779",
        disease: "1725",
        wounds: "114",
        other: "131"
      },
      {
        date: "1/1855",
        total: "32393",
        disease: "2761",
        wounds: "83",
        other: "324"
      },
      {
        date: "2/1855",
        total: "30919",
        disease: "2120",
        wounds: "42",
        other: "361"
      },
      {
        date: "3/1855",
        total: "30107",
        disease: "1205",
        wounds: "32",
        other: "172"
      },
      {
        date: "4/1855",
        total: "32252",
        disease: "477",
        wounds: "48",
        other: "57"
      },
      {
        date: "5/1855",
        total: "35473",
        disease: "508",
        wounds: "49",
        other: "37"
      },
      {
        date: "6/1855",
        total: "38863",
        disease: "802",
        wounds: "209",
        other: "31"
      },
      {
        date: "7/1855",
        total: "42647",
        disease: "382",
        wounds: "134",
        other: "33"
      },
      {
        date: "8/1855",
        total: "44614",
        disease: "483",
        wounds: "164",
        other: "25"
      },
      {
        date: "9/1855",
        total: "47751",
        disease: "189",
        wounds: "276",
        other: "20"
      },
      {
        date: "10/1855",
        total: "46852",
        disease: "128",
        wounds: "53",
        other: "18"
      },
      {
        date: "11/1855",
        total: "37853",
        disease: "178",
        wounds: "33",
        other: "32"
      },
      {
        date: "12/1855",
        total: "43217",
        disease: "91",
        wounds: "18",
        other: "28"
      },
      {
        date: "1/1856",
        total: "44212",
        disease: "42",
        wounds: "2",
        other: "48"
      },
      {
        date: "2/1856",
        total: "43485",
        disease: "24",
        wounds: "0",
        other: "19"
      },
      {
        date: "3/1856",
        total: "46140",
        disease: "15",
        wounds: "0",
        other: "35"
      }
    ];

    crimea.forEach(function(d) {
      d.date = parseDate(d.date);
      causes.forEach(function(c) {
        d[c] = +d[c];
      });
    })

    var layers = d3.layout.stack()(causes.map(function(c) {
      return crimea.map(function(d) {
        return {
          x: d.date,
          y: d[c]
        };
      });
    }));

    x.domain(layers[0].map(function(d) {
      return d.x;
    }));
    y.domain([0, d3.max(layers[layers.length - 1], function(d) {
      return d.y0 + d.y;
    })]).nice();

    var layer = svg.selectAll(".layer")
      .data(layers)
      .enter().append("g")
      .attr("class", "layer")
      .style("fill", function(d, i) {
        return z(i);
      });

    layer.selectAll("rect")
      .data(function(d) {
        return d;
      })
      .enter().append("rect")
      .attr("x", function(d) {
        return x(d.x);
      })
      .attr("y", function(d) {
        return y(d.y + d.y0);
      })
      .attr("height", function(d) {
        return y(d.y0) - y(d.y + d.y0);
      })
      .attr("width", x.rangeBand() - 1);

    svg.append("g")
      .attr("class", "axis axis--x")
      .attr("transform", "translate(0," + height + ")")
      .call(xAxis);

    svg.append("g")
      .attr("class", "axis axis--y")
      .attr("transform", "translate(" + width + ",0)")
      .call(yAxis);
  </script>

Sign up to request clarification or add additional context in comments.

3 Comments

@Greardo when i try to change 'orient' of y axis from 'right' to 'left' then it's y axis position doesn't change , only label position is changing.
@kunal please, don't ask further questions in the comments. As this is a different issue, please post another question. However, just to let you know, you have to change the transform here: .attr("transform", "translate(" + width + ",0)"). Change width for the value you want.
@Greardo Check my another question link related to existing query

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.