堆积条形图D3js

时间:2015-05-11 13:48:35

标签: javascript d3.js

我正在尝试使用d3js开发堆积条形图。但是我在x轴上的位置上遇到了麻烦的问题......有人可以帮忙吗?上面是我的代码和一些使用的数据...... 如果有必要,我会改变数据的来源...... 感谢的!

var dadosAcessos = [{
  _id: {
    fullname: 'Vis. Curso 13',
    recurso_id: 149,
    day: 17,
    month: 07,
    year: 2014,
    fulldata: '2014/07/17'
  },
  acessos: 7
}, {
  _id: {
    fullname: 'Vis. Curso 13',
    recurso_id: 149,
    day: 18,
    month: 07,
    year: 2014,
    fulldata: '2014/07/18'
  },
  acessos: 3
}, {
  _id: {
    fullname: 'Recurso',
    recurso_id: 150,
    day: 18,
    month: 07,
    year: 2014,
    fulldata: '2014/07/18'
  },
  acessos: 1
}, {
  _id: {
    fullname: 'Vis. Curso 13',
    recurso_id: 149,
    day: 14,
    month: 11,
    year: 2014,
    fulldata: '2014/11/14'
  },
  acessos: 1
}];

var color = d3.scale.category20();


// Chart dimensions
var margin = {
    top: 20,
    right: 80,
    bottom: 100,
    left: 40
  },
  width = 1000 - margin.right - margin.left,
  height = 300 - margin.top - margin.bottom;

// Define main svg element in #graph
var svg = d3.select("#acessos").append("svg")
  .attr("width", width + margin.left + margin.right)
  .attr("height", height + margin.top + margin.bottom);

var graph = svg.append("g")
  .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

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

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

var len = 0;

dadosAcessos.forEach(function(d) {
  d.fullname = d._id.fullname
  d.date = new Date(d._id.year + "/" + d._id.month + "/" + d._id.day);
  len++;
});

var nestByDate = d3.nest()
  .key(function(d) {
    return d.date;
  })
  .sortValues(function(a, b) {
    return ((a.acessos < b.acessos) ? -1 : 1);
    return 0;
  })
  .entries(dadosAcessos);

nestByDate.forEach(function(d) {
  var y0 = 0;
  var y1 = 0;
  d.vis = "1";
  d.values.forEach(function(d) {

    // y0 is the y axis start of the bar
    d.y0 = y0 + y1;

    // y1 is the y axis end of the bar
    d.y1 = y1 = d.acessos;

    // d.vis controls whether bars are visible or not
    d.vis = "1";
  });
});

var x = d3.time.scale().range([0, width], .1);
x.domain([
  d3.min(dadosAcessos, function(d) {
    return d.date.setDate(d.date.getDate() - 1);
  }),
  d3.max(dadosAcessos, function(d) {
    return d.date.setDate(d.date.getDate() + 2);
  })
]);

// y axis domain (ie: time)
y.domain([0, d3.max(dadosAcessos, function(d) {
  return d.acessos;
})]);

// Create brush for mini graph
var brush = d3.svg.brush()
  .x(x)
  .on("brush", brushed);

// Define the X axis
var xAxis = d3.svg.axis()
  .scale(x)
  .ticks(d3.time.months)
  .orient("bottom");

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

// Add the brush
graph.append("g")
  .attr("class", "x brush")
  .call(brush)
  .selectAll("rect")
  .attr("y", -10)
  .attr("height", height + 15);

// Add the Y axis
graph.append("g")
  .attr("class", "y axis")
  .attr("transform", "translate(0,0)")
  .call(yAxis)
  .append("text")
  .attr("transform", "rotate(-90)")
  .attr("y", 6)
  .attr("dy", ".71em")
  .style("text-anchor", "end")
  .text("Acessos")
  .attr("class", "y_label");

var bar = graph.selectAll(".bars")
  .data(nestByDate)
  .enter()
  .append("g");

bar.selectAll("rect")
  .data(function(d) {
    return d.values;
  })
  .enter().append("rect")
  .attr("width", function(d) {
    return width / (len * 2);
  })
  .attr("x", function(d) {
    return x(d.date.setDate(d.date.getDate() + 1)) - (width / len) / 2;
  })
  .attr("y", function(d) {
    return y(d.y1);
  })
  .attr("fill", function(d) {
    return color(d.fullname);
  })
  .attr("height", function(d) {
    return y(d.y0) - y(d.y1);
  });

function brushed() {
  var dataIni = new Date(brush.extent()[0]);
  var dataFim = new Date(brush.extent()[1]);
  console.log("BRUSH");
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>


<div id="acessos"></div>

2 个答案:

答案 0 :(得分:1)

矩形彼此重叠。要将每个条形正好放在x轴刻度附近,必须改变rect的x属性。修改.attr处的代码(“x”,函数(d,i){return i * width / 4;}) D3.JS提供了进入匿名函数的参数。 d 是数据值本身, i 用作数据项的索引

bar.selectAll("rect")
  .data(function(d) {
    return d.values;
  })
  .enter().append("rect")
  .attr("width", function(d) {
    return width / (len * 2);
  })
  .attr("x", function(d,i) {
    return i*width/4;
  .attr("y", function(d) {
    return y(d.y1);
  })
  .attr("fill", function(d) {
    return color(d.fullname);
  })
  .attr("height", function(d) {
    return y(d.y0) - y(d.y1);
  });

答案 1 :(得分:0)

<强>分辨

我改变了这些行来解决问题...

var x = d3.scale.ordinal().rangeRoundBands([0, width], .05);
x.domain(dadosAcessos.map(function(d){ return d.date; }));

bar.selectAll("rect")
.data(function(d) {
  return d.values;
})
.enter().append("rect")
.attr("width", function(d) {
  return x.rangeBand();
})
.attr("x", function(d,i) {
  d.x = x(d.date);
  return x(d.date);
})
.attr("y", function(d) {
  return y(d.y1);
})
.attr("fill", function(d) {
  return color(d.fullname);
})
.attr("height", function(d) {
    return y(d.y0) - y(d.y1);
})

非常感谢!!