我目前在图表上有一系列事件。在这种情况下,事件有持续时间,并用rectagles表示:
天真地,每个矩形都会被数组中事件的索引删除:
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值来制作这个图像):
关于我如何做到这一点的任何建议?可以在https://github.com/bosun-monitor/bosun/blob/master/cmd/bosun/web/static/js/directives.ts#L486
找到完整的D3代码答案 0 :(得分:0)
结束以下操作:
代码:
$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) })
如下所示: