D3将数据添加到setInterval()内的数组元素中以绘制分组条形图

时间:2015-09-23 09:22:30

标签: javascript jquery arrays d3.js

我是D3.js的新手。我需要使用数据集数组设计分组条形图。为此,我按照这个链接。 Grouped Bar ChartD3js take data from an array instead of a file

这是我的代码。

<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>
<!DOCTYPE html>
<meta charset="utf-8">
<html>
<head> 
<script src="http://d3js.org/d3.v3.min.js"  charset="utf-8"></script>    

</head>
    
<body>
     
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"></script>
<script>
    
 var interval = setInterval(function() {
                      
                }, 1000);    

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

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

var x1 = d3.scale.ordinal();

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

var color = d3.scale.ordinal()
    .range(["#98abc5", "#8a89a6"]);

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

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

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 = [
    {TestSuite:"TestSuite1",True:2,False:5},
    {TestSuite:"TestSuite2",True:6,False:3},
    {TestSuite:"TestSuite3",True:1,False:7},
    {TestSuite:"TestSuite4",True:5,False:2},
    {TestSuite:"TestSuite5",True:2,False:2},
    {TestSuite:"TestSuite6",True:9,False:4}
];    
 //x.domain(data.map(function(d) { return d.letter; }));
  for(var i=0;i<data.length;i++){  
  var ageNames = d3.keys(data[i]).filter(function(key) { return key !== "TestSuite"; });
  
  }
      
  data.forEach(function(d) {
    d.ages = ageNames.map(function(name) { return {name: name, value: +d[name]}; });
      
  });

  x0.domain(data.map(function(d) { return d.TestSuite; }));
  x1.domain(ageNames).rangeRoundBands([0, x0.rangeBand()]);
  y.domain([0, d3.max(data, function(d) { return d3.max(d.ages, function(d) { return d.value; }); })]);

  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("Count");

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

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

  var legend = svg.selectAll(".legend")
      .data(ageNames.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>
    
</body> 
    
</html>

但是我需要将数据添加到setInterval()函数中的data []作为

var data = [];
var i=0;
var interval = setInterval(function() {
  // data must be add for each index in each second until i=6(something like this   condition)
  //I tried like this
  if(i<6){
    
     data[i] = {letter:"A",frequency:i};//frequency=i value
  
     /*
     x.domain(data.map(function(d) { return d.letter; }));
     y.domain([0, d3.max(data, function(d) { return d.frequency; })]);
     .
     .
     .
     .
     function type(d) {
            d.frequency = +d.frequency;
            return d;
     }
     */
    
   } 
  i++;
},1000);
这不起作用,谁能告诉我如何解决这个难题?如何将数据添加到数组以及如何分别创建每个条形图? 谢谢...

1 个答案:

答案 0 :(得分:1)

您可以在更新块中移动生成条形图或rect DOM的代码。

像小提琴中的代码

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

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

 var x1 = d3.scale.ordinal();

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

 var color = d3.scale.ordinal()
     .range(["#98abc5", "#8a89a6"]);

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

 var yAxis = d3.svg.axis()
     .scale(y)
     .orient("left")
     .tickFormat(d3.format(""));
 var w = width + margin.left + margin.right;
 var h = height + margin.top + margin.bottom;
 var svg = d3.select("body").append("svg")
     .attr("width", w)
     .attr("height", h)
     .append("g")
     .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

 var data = [{
     TestSuite: "TestSuite1",
     True: 2,
     False: 5
 }, {
     TestSuite: "TestSuite2",
     True: 6,
     False: 3
 }, {
     TestSuite: "TestSuite3",
     True: 1,
     False: 7
 }, {
     TestSuite: "TestSuite4",
     True: 5,
     False: 2
 }, {
     TestSuite: "TestSuite5",
     True: 2,
     False: 2
 }, {
     TestSuite: "TestSuite6",
     True: 9,
     False: 4
 }];
 var interval = setInterval(function () {
     //add your new fresh data here
     data.push({
         TestSuite: "TestSuite"+Math.round(Math.random()*100) + 1,
         True: Math.round(Math.random()*9) + 1,
         False: Math.round(Math.random()*9) + 1
     });
     update();
 }, 10000);
 //x.domain(data.map(function(d) { return d.letter; }));


 var xg = svg.append("g")
     .attr("class", "x axis")
     .attr("transform", "translate(0," + height + ")");

 var yg = svg.append("g")
     .attr("class", "y axis");

 yg.append("text")
     .attr("transform", "rotate(-90)")
     .attr("y", 6)
     .attr("dy", ".71em")
     .style("text-anchor", "end")
     .text("Count");



 update();
//this function will make the bar charts
 function update() {
     for (var i = 0; i < data.length; i++) {
         var ageNames = d3.keys(data[i]).filter(function (key) {
             return key !== "TestSuite";
         });

     }

     data.forEach(function (d) {
         d.ages = ageNames.map(function (name) {
             return {
                 name: name,
                 value: +d[name]
             };
         });

     });

     x0.domain(data.map(function (d) {
         return d.TestSuite;
     }));
     x1.domain(ageNames).rangeRoundBands([0, x0.rangeBand()]);
     y.domain([0, d3.max(data, function (d) {
         return d3.max(d.ages, function (d) {
             return d.value;
         });
     })]);
     //making the x axis/y axis
     xg.call(xAxis);
     yg.call(yAxis);
     //removing all the rectangles
     svg.selectAll(".TestSuite").remove();
     
     var state = svg.selectAll(".TestSuite")
         .data(data)
         .enter().append("g")
         .attr("class", "TestSuite")
         .attr("transform", function (d) {
         return "translate(" + x0(d.TestSuite) + ",0)";
     });
     
     state.selectAll("rect")
         .data(function (d) {
         return d.ages;
     })
         .enter().append("rect")
         .attr("width", x1.rangeBand())
         .attr("x", function (d) {
         return x1(d.name);
     })
         .attr("y", function (d) {
         return y(d.value);
     })
         .attr("height", function (d) {
         return height - y(d.value);
     })
         .style("fill", function (d) {
         return color(d.name);
     });
 }
&#13;
body {
    font: 10px sans-serif;
}
.axis path, .axis line {
    fill: none;
    stroke: #000;
    shape-rendering: crispEdges;
}
.bar {
    fill: steelblue;
}
.x.axis path {
    display: none;
}
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
&#13;
&#13;
&#13;