【问题标题】:Stacked Bar Chart D3js堆积条形图 D3js
【发布时间】:2015-05-11 13:48:34
【问题描述】:

我正在尝试使用 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>

【问题讨论】:

    标签: javascript d3.js


    【解决方案1】:

    矩形相互重叠。要将每个条形图精确地放置在 x 轴刻度附近,必须改变 rect 的 x 属性。修改 .attr("x",function(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);
      });
    

    【讨论】:

    • 比@tejesh95 好不了多少... :( 看看这个小提琴:fiddle
    • 数据需要正确结构化@Augusto
    • 你能举个例子吗?
    • 你能展示你想要的理想数据格式的格式样本吗?另外,请提及您想要的条形高度数据。
    • 是的,当然。我需要在 Y 轴(条形的高度)、访问次数(我的数据集中的“accessos”)和 X 轴上日复一日地显示(我使用的是“fulldata”或 javascript 新日期(年、月、日) ) 成为我的数据集)。酒吧听起来像这些these
    【解决方案2】:

    已解决

    我已更改这些行以解决问题...

    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);
    })
    

    非常感谢!!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-06-01
      • 1970-01-01
      • 2017-02-26
      • 2014-02-09
      相关资源
      最近更新 更多