D3 Stacked Chart with array or JSON data

2019-03-21 13:46发布

I want to create a Stacked bar chart like http://bl.ocks.org/mbostock/3886208 . But I don't want to use CSV file.

How can I create Stacked chart using array or JSON data?

In csv we are using like this :

State,Post,Comment    
AL,310504,552339
AK,52083,85640

How can I define data in array or json like

var data = []

标签: d3.js stacked
3条回答
地球回转人心会变
2楼-- · 2019-03-21 14:31

do it like this

<!DOCTYPE html>
<meta charset="utf-8">
<style>

body {
  font: 10px sans-serif;
}

.axis path,
.axis line {
  fill: none;
  stroke: #000;
  shape-rendering: crispEdges;
}

.bar {
  fill: steelblue;
}

.x.axis path {
  display: none;
}

</style>
<body>
<script src="//d3js.org/d3.v3.min.js"></script>
<script>

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

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

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

var color = d3.scale.ordinal()
    .range(["#98abc5", "#8a89a6", "#7b6888", "#6b486b", "#a05d56", "#d0743c", "#ff8c00"]);

var xAxis = d3.svg.axis()
    .scale(x)
    .orient("bottom");

var yAxis = d3.svg.axis()
    .scale(y)
    .orient("left")
    .tickFormat(d3.format(".2s"));

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 data = [
    {
    "State": "AL",
    "Under 5 Years": 10,
    "5 to 13 Years": 20,
    "14 to 17 Years": 30,
    "18 to 24 Years": 40,
    "25 to 44 Years": 50,
    "45 to 64 Years": 60,
    "65 Years and Over": 70
  },{
    "State": "AK",
    "Under 5 Years": 15,
    "5 to 13 Years": 25,
    "14 to 17 Years": 35,
    "18 to 24 Years": 45,
    "25 to 44 Years": 55,
    "45 to 64 Years": 65,
    "65 Years and Over": 75
  }];
  color.domain(d3.keys(data[0]).filter(function(key) { return key !== "State"; }));

  data.forEach(function(d) {
    var y0 = 0;
    d.ages = color.domain().map(function(name) { return {name: name, y0: y0, y1: y0 += +d[name]}; });
    d.total = d.ages[d.ages.length - 1].y1;
  });

  data.sort(function(a, b) { return b.total - a.total; });

  x.domain(data.map(function(d) { return d.State; }));
  y.domain([0, d3.max(data, function(d) { return d.total; })]);

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

  svg.append("g")
      .attr("class", "y axis")
      .call(yAxis)
    .append("text")
      .attr("transform", "rotate(-90)")
      .attr("y", 6)
      .attr("dy", ".71em")
      .style("text-anchor", "end")
      .text("Population");

  var state = svg.selectAll(".state")
      .data(data)
    .enter().append("g")
      .attr("class", "g")
      .attr("transform", function(d) { return "translate(" + x(d.State) + ",0)"; });

  state.selectAll("rect")
      .data(function(d) { return d.ages; })
    .enter().append("rect")
      .attr("width", x.rangeBand())
      .attr("y", function(d) { return y(d.y1); })
      .attr("height", function(d) { return y(d.y0) - y(d.y1); })
      .style("fill", function(d) { return color(d.name); });

  var legend = svg.selectAll(".legend")
      .data(color.domain().slice().reverse())
    .enter().append("g")
      .attr("class", "legend")
      .attr("transform", function(d, i) { return "translate(0," + i * 20 + ")"; });

  legend.append("rect")
      .attr("x", width - 18)
      .attr("width", 18)
      .attr("height", 18)
      .style("fill", color);

  legend.append("text")
      .attr("x", width - 24)
      .attr("y", 9)
      .attr("dy", ".35em")
      .style("text-anchor", "end")
      .text(function(d) { return d; });


</script>
查看更多
对你真心纯属浪费
3楼-- · 2019-03-21 14:31

If you have an array, data, you can use that just like the parameter data in the csv function in the example you linked. The code within that function will work as expected, provided that your data is in the same format.

If you can set breakpoints with your browser, you can have a look at what that format is fairly easily, set one just inside the csv function call in the js and look at the data variable.

查看更多
趁早两清
4楼-- · 2019-03-21 14:43

I know late for replying to this one. I modified @heshjse's code for D3 version 4. When I tried the above code with d3 v3, it's working fine. But we had limitation to use version 4, I was getting problem bcoz of some changes in d3 v4. So adding the code which worked for me. I hope it helps.

This should work fine for Json format in d3 v4.

<!DOCTYPE html>
<html>
<head>
    <title></title>
    <meta charset="utf-8" />
</head>
<body>
    <div id="Dash"></div>
</body>
</html>

<script src="https://d3js.org/d3.v4.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script>
    $(document).ready(function () {
        drawStackChart();
    });


    //Draw Stack Chart
    var marginStackChart = { top: 20, right: 20, bottom: 30, left: 40 },
            widthStackChart = 500 - marginStackChart.left - marginStackChart.right,
            heightStackChart = 300 - marginStackChart.top - marginStackChart.bottom;

    var xStackChart = d3.scaleBand()
            .range([0, widthStackChart])
            .padding(0.1);
    var yStackChart = d3.scaleLinear()
                .range([heightStackChart, 0]);


    var colorStackChart = d3.scaleOrdinal(["#98abc5", "#8a89a6", "#7b6888", "#6b486b", "#a05d56", "#d0743c", "#ff8c00"])


    var canvasStackChart = d3.select("#Dash").append("svg")
        .attr("width", widthStackChart + marginStackChart.left + marginStackChart.right)
        .attr("height", heightStackChart + marginStackChart.top + marginStackChart.bottom)
        .append("g")
        .attr("transform", "translate(" + marginStackChart.left + "," + marginStackChart.top + ")");

    function drawStackChart() {


        var data = [
             {
                 "Year": "2012",
                 "Category1": "20",
                 "Category2": "5",
                 "Category3": "5",
                 "Category4": "5",
                 "Category5": "5",
                 "Category6": "5",
                 "Category7": "5",
                 "Category8": "5",
                 "Category9": "5"
             },
             {
                 "Year": "2013",
                 "Category1": "30",
                 "Category2": "10",
                 "Category3": "10",
                 "Category4": "10",
                 "Category5": "10",
                 "Category6": "10",
                 "Category7": "10",
                 "Category8": "10",
                 "Category9": "10"
             },
             {
                 "Year": "2014",
                 "Category1": "35",
                 "Category2": "15",
                 "Category3": "15",
                 "Category4": "15",
                 "Category5": "15",
                 "Category6": "15",
                 "Category7": "15",
                 "Category8": "15",
                 "Category9": "15"
             },
             {
                 "Year": "2015",
                 "Category1": "60",
                 "Category2": "20",
                 "Category3": "20",
                 "Category4": "20",
                 "Category5": "20",
                 "Category6": "20",
                 "Category7": "20",
                 "Category8": "20",
                 "Category9": "20"
             },
             {
                 "Year": "2016",
                 "Category1": "70",
                 "Category2": "40",
                 "Category3": "40",
                 "Category4": "40",
                 "Category5": "40",
                 "Category6": "40",
                 "Category7": "40",
                 "Category8": "40",
                 "Category9": "40"
             }
        ];



            colorStackChart.domain(d3.keys(data[0]).filter(function (key) { return key !== "Year"; }));

            data.forEach(function (d) {
                var y0 = 0;
                d.ages = colorStackChart.domain().map(function (name) { return { name: name, y0: y0, y1: y0 += +d[name] }; });
                d.total = d.ages[d.ages.length - 1].y1;
            });

            data.sort(function (a, b) { return b.total - a.total; });

            xStackChart.domain(data.map(function (d) { return d.Year; }));
            yStackChart.domain([0, d3.max(data, function (d) { return d.total; })]);

            canvasStackChart.append("g")
            .attr("class", "x axis")
            .attr("transform", "translate(0," + heightStackChart + ")")
            .call(d3.axisBottom(xStackChart));

            canvasStackChart.append("g")
            .attr("class", "y axis")
            .call(d3.axisLeft(yStackChart))
            .append("text")
            .attr("transform", "rotate(-90)")
            .attr("y", 6)
            .attr("dy", ".71em")
            .style("text-anchor", "end")
            .text("No Of Buildings");

            var state = canvasStackChart.selectAll(".Year")
            .data(data)
            .enter().append("g")
            .attr("class", "g")
            .attr("transform", function (d) { return "translate(" + xStackChart(d.Year) + ",0)"; });

            state.selectAll("rect")
            .data(function (d) { return d.ages; })
            .enter().append("rect")
            .attr("width", xStackChart.bandwidth())
            .attr("y", function (d) { return yStackChart(d.y1); })
            .attr("height", function (d) { return yStackChart(d.y0) - yStackChart(d.y1); })
            .style("fill", function (d) { return colorStackChart(d.name); });

            var legend = canvasStackChart.selectAll(".legend")
            .data(colorStackChart.domain().slice().reverse())
            .enter().append("g")
            .attr("class", "legend")
            .attr("transform", function (d, i) { return "translate(0," + i * 20 + ")"; });

            legend.append("rect")
            .attr("x", widthStackChart - 18)
            .attr("width", 18)
            .attr("height", 18)
            .style("fill", colorStackChart);

            legend.append("text")
            .attr("x", widthStackChart - 24)
            .attr("y", 9)
            .attr("dy", ".35em")
            .style("text-anchor", "end")
            .text(function (d) { return d; });


    }



</script>
查看更多
登录 后发表回答