时间轴:在D3中有机会堆叠矩形?

时间:2016-02-23 16:57:30

标签: javascript d3.js

我目前在图表上有一系列事件。在这种情况下,事件有持续时间,并用rectagles表示:

enter image description here

天真地,每个矩形都会被数组中事件的索引删除:

annotations.enter()
    .append("svg:a")
    .append('rect')
    .attr("y", (d, i) => { return i * ((height * .05) + 2) })
    .attr("height", height * .05)
    .attr("x", (d: any) => { return xScale(moment(d.StartDate).utc().unix() * 1000); })
    .attr("width", (d: any) => {
         var startT = moment(d.StartDate).utc().unix() * 1000
         var endT = moment(d.EndDate).utc().unix() * 1000
         if (startT == endT) {
             return 3
         }
         return xScale(endT) - xScale(startT)
    })

我想做的是,如果矩形有空间,则将事件向上移动。但是,如果没有空间,我仍然希望将它们向下堆叠。

所以上面的内容最终会像下面这样(我只是编辑了chrome检查器中的y值来制作这个图像): enter image description here

关于我如何做到这一点的任何建议?可以在https://github.com/bosun-monitor/bosun/blob/master/cmd/bosun/web/static/js/directives.ts#L486

找到完整的D3代码

1 个答案:

答案 0 :(得分:0)

结束以下操作:

  1. 按开始日期排序
  2. 跟踪每行的最后结束日期
  3. 如果当前StartDate大于Row的结束日期,则插入,如果它不是转到下一行。
  4. 代码:

    $scope.annotations = _.sortBy(data.Annotations, (d: Annotation) => { return d.StartDate; });
    ...
    if (scope.annotateEnabled && scope.annotations.length != 0) {
        var rowId = {}; // annotation Id -> rowId
        var rowEndDate = {}; // rowId -> EndDate
        var maxRow = 0;    
        for (var i = 0; i < scope.annotations.length; i++) {
            if (i == 0) {
                rowId[scope.annotations[i].Id] = 0;
                rowEndDate[0] = scope.annotations[0].EndDate;
                continue;
            }
            for (var row = 0; row <= maxRow+1; row++) {
                if (row == maxRow+1) {
                    rowId[scope.annotations[i].Id] = row;
                    rowEndDate[row] = scope.annotations[i].EndDate;
                    maxRow+=1
                    break;
                }
                if (rowEndDate[row] < scope.annotations[i].StartDate) {
                    rowId[scope.annotations[i].Id] = row;
                    rowEndDate[row] = scope.annotations[i].EndDate;
                    break;
                }
            }   
        }
    ...
    .attr("y", (d) => { return rowId[d.Id] * ((height * .05) + 2) })
    

    如下所示:

    enter image description here