在D3.js中将标签正确放置在轴上

时间:2018-04-17 15:26:47

标签: javascript d3.js data-visualization

我有一张显示一些数据的热图。如果用户点击标签(xy轴),则数据会正确排序。 我的问题是在分类数据之前和之后标签的正确定位。

这是 PLUNKER

如您所见,最初图表是这样的:

enter image description here

y轴上的标签是正确的,x轴上的标签不是,因为它们应该都在同一高度。相反,他们下来了。

当我点击ddd时,它变为:

enter image description here

同样的问题。

当我点击2001时,它变为:

enter image description here

现在一团糟。

控制标签定位的代码是:

var rowLabels = svg.append('g')
    .attr('class', 'rowLabels')
    .selectAll('.rowLabels')
    .data(regionsName)
    .enter().append('text')
    .text(function(d) {
        return d;
    })
    .attr('x', 0)
    .attr('y', function(d, i) {
        return i * cellSize;
    })
    .attr('transform', function(d, i) {
        return 'translate(-25, 11)';
    })
    .attr('class', 'rowLabel mono')
    .attr('id', function(d) {
        return 'rowLabel_' + regionsName.indexOf(d);            
    })
    .attr('font-weight', 'normal')
    .on('mouseover', function(d) {
        d3.select(this).attr('font-weight', 'bold').style('fill', 'red');
    })
    .on('mouseout', function(d) {
        d3.select(this).attr('font-weight', 'normal').style('fill', 'black');
    })
    .on('click', function(d, i) {
        rowSortOrder = !rowSortOrder;
        sortByValues('r', i, rowSortOrder);
    });

var colLabels = svg.append('g')
    .attr('class', 'colLabels')
    .selectAll('.colLabels')
    .data(yearsName)
    .enter().append('text')
    .text(function(d) {
        return d;
    })
    .attr('x', 0)
    .attr('y', function(d, i) {
        return i * cellSize;
    })
    .attr('transform', function(d, i) {
        return 'translate(0, -3) rotate(-65)';
    })
    .attr('class', 'colLabel mono')
    .attr('id', function(d) {
        return 'colLabel_' + yearsName.indexOf(d);          
    })
    .attr('font-weight', 'normal')
    .style('text-anchor', 'left')
    .attr('dx', '.8em')
    .attr('dy', '.5em')
    .on('mouseover', function(d) {
        d3.select(this).attr('font-weight', 'bold').style('fill', 'red');
    })
    .on('mouseout', function(d) {
        d3.select(this).attr('font-weight', 'normal').style('fill', 'black');
    })
    .on('click', function(d, i) {
        colSortOrder = !colSortOrder;
        sortByValues('c', i, colSortOrder);
    });

t.selectAll('.colLabel')
    .attr('y', function(d, i) {
        return sorted.indexOf(i) * cellSize;
    })
    .attr('transform', function(d, i) {
        return 'translate(-10, 2) rotate(-65) rotate(0, 0, ' + (sorted.indexOf(i) * cellSize) + ')';
    });

t.selectAll('.rowLabel')
    .attr('y', function(d, i) {
        return sorted.indexOf(i) * cellSize;
    })
    .attr('transform', function(d, i) {
        return 'translate(-5, 0)';
    });

我改变了一千次,思考它,但没有。 有谁知道如何帮助我?

1 个答案:

答案 0 :(得分:1)

您的轴标签设置过于复杂。旋转标签时,标签从坐标系原点旋转 - 而不是文本锚点。如果我们按原样比较标签,如果我们删除变换并只使用您指定的x,y属性,我们可以更好地看到这一点:

.attr('x', 0)
.attr('y', function(d, i) {
    return i * cellSize;
})
//.attr('transform', function(d, i) {
//    return 'translate(-25, 11)';
//})

enter image description here

我们可以看到所有标签围绕公共点一起旋转。标签放置中可能出现错误的提示也来自动态设置y值和固定x值的代码,以便放置仅在x值中有所不同的值。

我们可以简化这个,而不是设置x,y和变换,让我们设置变换。首先,我们将修改坐标系,以便每个标签坐标系的原点都是锚定的位置。然后我们将轮换:

.attr('transform', function(d, i) {
    return 'translate('+(i*cellSize)+',2) rotate(-65)';
})

我们还想更新更新功能:

t.selectAll('.colLabel')
  .attr('transform', function(d, i) {
    return 'translate('+(sorted.indexOf(i)*cellSize)+',2) rotate(-65)';
  })

给我们:

enter image description here

另一个问题是y轴标签的间距,您在排序时更新标签的x位置。这是不必要的,标签只需要垂直移动,我们可以删除转换更改并使用:

t.selectAll('.rowLabel')
  .attr('y', function(d, i) {
     return sorted.indexOf(i) * cellSize;
   })

这是一个updated plunkr