如何处理d3js中的数据遮挡?

时间:2015-07-01 03:39:21

标签: javascript d3.js

我正在尝试使用以下方法创建一种原始数据分发:

  • X轴:人(a或b)
  • Y轴:强度(0到4的等级)

有什么方法可以防止数据点互相遮挡?例如,当存在现有数据点时,具有相同值(不同日期)的下一个数据点位于与其偏移的位置,如下图所示。

情节的当前状态 Current status of plot

情节的期望状态 Desired status of plot

我愿意改变数据格式以获得最终结果。

Dataset:

    condition   intensity   date
    a   2   1
    a   3   2
    a   0   3
    a   1   4
    b   3   5
    b   3   6
    b   4   7
    b   4   8

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()
  .range([height, 0]);

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

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

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 + ")");

d3.csv("data.csv", type, function(error, data) {
  if (error) throw error;

  x.domain(data.map(function(d) {
    return d.condition;
  }));
  y.domain([0, 4]);

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

  svg.append("g")
    .attr("class", "y axis")
    .call(yAxis);

  svg.selectAll(".point")
    .data(data)
    .enter().append("path")
    .attr("class", "point")
    .attr("d", d3.svg.symbol().type("square").size([500]))
    .attr("transform", function(d) {
      return "translate(" + x(d.condition) + "," + y(d.intensity) + ")";
    });
});


function type(d) {
  d.severity = +d.severity;
  return d;
}
.bar {
  fill: steelblue;
}
.bar:hover {
  fill: brown;
}
.axis {
  font: 10px sans-serif;
}
.axis path,
.axis line {
  fill: none;
  stroke: #000;
  shape-rendering: crispEdges;
}
<body>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"></script>
  </body>

1 个答案:

答案 0 :(得分:0)

想出办法。

将所有数据点存储在数组中并检查重复项。如果遇到重复,则沿X轴偏移40个像素。

var arr = []; // array for holding all the datapoints
var tally = []; // array for storing the duplicates

// Change the squares
    svg.selectAll(".point")
      .attr("d", d3.svg.symbol().type("square").size([500]))
      .attr("transform", function(d) {
    var current = (d.condition + "," + d.severity); // current data point
    var index = arr.indexOf(current); // get the index of current data point in array arr

if (index == -1) { // if index is -1, then no match found. unique data point
  arr.push(current); // push point onto array
  position = "translate(" + x(d.condition) + "," + y(d.severity) + ")";

} else {
  tally.push(current);
  var tallylen = tally.length;
  var tindex = tally.indexOf(current);
  for (var i = 0; i < tallylen; i++) {
    var c = 0;
    if (c == tindex) {
      position = "translate(" + (x(d.condition) + (40 * (i + 1))) + "," + y(d.severity) + ")";
    } else {
      c = tindex;
      position = "translate(" + (x(d.condition) + (40 * (i + 1 - tindex))) + "," + y(d.severity) + ")";
    };

  }
};
return position;
})

如果有人有更好的解决方案,请发布。