根据算术级数动态分配高度

时间:2019-07-08 04:06:22

标签: javascript d3.js

我正在用d3制作时间轴,我注意到时间轴上是否有一些事件(彼此之间相隔几天)即将结束,因此易读性受到很大影响。到目前为止,我最好的想法是尝试为高度分配一些逻辑。例如,下面我基于偶/奇。

graphGroup.selectAll('text')
    .data(data)
    .enter()
    .append('text')
    .attr('x', function(d) {return timeScale(d.date)-125})
    .attr('y', function(d,i) {
      if (i%2) {
        return 50-5;
      } else {
        return height/2-5;
      }
      })
    .text(function(d) {return formatTime(d.date)})
    //.attr('text-anchor','middle')
    .attr('class', 'date');

这工作到一定程度,但是使用我的最新数据集,我有3-4个背靠背的事件,因此我想弄清楚如何垂直交错文本以形成一种重复的阶梯样式:1 ,2,3,1,2,3,1,2,3 ...

我尝试将%2替换为%3,但结果相同。然后它突然降临在我身上-我必须以某种方式绘制高度图。

为简单起见,假设:

var myHeightLogic: {
    h1:100,
    h2:300,
    h3:400
};

问题

对于重复的楼梯图案,如何使用我的myHeightLogic变量计算文本.attr('y', function(d,i) { })的正确高度?如果我想增加4个步骤,方法是否会一样?我想找到最可扩展的方法。由于可分数字之间存在重叠,因此数学上似乎很复杂(例如6被2和3均分)。

1 个答案:

答案 0 :(得分:2)

正如您在问题中所推理的那样,可以将数组和第二个参数提供的索引与其余运算符一起使用。 6和2被3和3整除的事实不是问题。

但是,由于要使用“最可扩展的方法” ,因此可以利用以下事实:如果未指定,则D3序数标度中的域是根据使用情况推断的。

因此,您可以执行此操作(使用新的scale构造函数语法):

const scale = d3.scaleOrdinal([100, 300, 400]) 

然后将刻度与索引一起使用。

这是一个演示:

const scale = d3.scaleOrdinal([100, 300, 400]);
d3.range(20).forEach(d => {
  console.log("index: " + d + " --- position: " + scale(d))
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.8.0/d3.min.js"></script>

而且,为什么不这样呢?

const svg = d3.select("svg");
const scale = d3.scaleOrdinal([0, 20, 40]);
const data = d3.range(20);
svg.selectAll(null)
  .data(data)
  .enter()
  .append("rect")
  .attr("x", d => d * 30)
  .attr("width", 30)
  .attr("height", 10)
  .attr("y", d => scale(d))
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.8.0/d3.min.js"></script>
<svg height="50" width="600"></svg>