D3 Stacked Chart with array or JSON data

寵の児 提交于 2019-12-09 07:18:19

问题


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 = []

回答1:


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>



回答2:


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>



回答3:


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.



来源:https://stackoverflow.com/questions/31981299/d3-stacked-chart-with-array-or-json-data

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!