我正在尝试使用D3创建一个条形图上的文字。
https://jsfiddle.net/4j27311q/2/
我有一个相同的小提琴,但由于一些错误,文字没有包装。因为我的标签没有空格而不是' _'所以我试图将它们用作分隔符。 我正在使用' https://bl.ocks.org/mbostock/7555321'
建议的同样的策略如何正确对齐它们??
这是我试图与之合作的小提琴:
var wrap = function(text, width) {
text.each(function() {
var text = d3.select(this),
words = text.text().split(/_/).reverse(),
word,
line = [],
lineNumber = 0,
lineHeight = 1.1, // ems
y = text.attr("y"),
dy = parseFloat(text.attr("dy")),
tspan = text.text(null).append("tspan").attr("x", 0).attr("y", y).attr("dy", dy + "em");
while (word = words.pop()) {
line.push(word);
tspan.text(line.join(" "));
if (tspan.node().getComputedTextLength() > width) {
line.pop();
tspan.text(line.join("_"));
line = [word];
tspan = text.append("tspan").attr("x", 0).attr("y", y).attr("dy", ++lineNumber * lineHeight + dy + "em").text(word);
}
}
});
}
答案 0 :(得分:0)
问题不在于wrap
功能,这显然有效(正如您只需删除其call
所示)。
这里的问题更为平庸:rotate
将围绕坐标系的原点旋转元素。有几种方法可以解决这个问题,最简单的方法就是使用transform
在同一个translate
函数中设置x和y位置:
.attr('transform', function(d) {
return "translate(-40,30) rotate(-60)"
})
我在这里使用魔术数字,因为你的代码充满了它们!
以下是演示:
var wrap = function(text, width) {
text.each(function() {
var text = d3.select(this),
words = text.text().split("_").reverse(),
word,
line = [],
lineNumber = 0,
lineHeight = 1.1, // ems
y = text.attr("y"),
dy = parseFloat(text.attr("dy")),
tspan = text.text(null).append("tspan").attr("x", 0).attr("y", y).attr("dy", dy + "em");
while (word = words.pop()) {
line.push(word);
tspan.text(line.join(" "));
if (tspan.node().getComputedTextLength() > width) {
line.pop();
tspan.text(line.join("_"));
line = [word];
tspan = text.append("tspan").attr("x", 0).attr("y", y).attr("dy", ++lineNumber * lineHeight + dy + "em").text(word);
}
}
});
}
var tempData = [];
for (var i = 1; i < 30; i++) {
var obj = {
"Id": 1,
"Type": 'Apple_Orange_Swiss_Some_Things_' + i,
"Count": 5
};
tempData.push(obj);
}
var barWidth = 30,
paddingFactor = 2.2,
padding = 20,
responsiveDIVHeight = 300,
responsiveDIVWidth = tempData.length * barWidth * paddingFactor;
var x = d3.scale.ordinal().rangeRoundBands([0, responsiveDIVWidth], 0.5)
.domain(tempData.map(function(d) {
return d.Type
})),
y = d3.scale.linear().rangeRound([responsiveDIVHeight - padding, padding])
.domain([0, d3.max(tempData, function(d) {
return (d.Count + 10);
})]),
xAxis = d3.svg.axis().scale(x).orient('bottom'),
yAxis = d3.svg.axis().scale(y).orient('left');
var svgY = d3.select('#verticalSVG')
.append('svg')
.attr('height', responsiveDIVHeight)
.attr("width", 50);
svgY.append('g')
.attr('class', 'y axis')
.call(yAxis)
.attr('dx', '-0.3em')
.attr('transform', "translate(50, 0)");;
var svgX = d3.select('#horizontalSVG')
.append('svg')
.attr('width', responsiveDIVWidth)
.attr('height', responsiveDIVHeight + 300);
svgX.append('g')
.attr('class', 'x axis')
.attr('transform', "translate(0," + (responsiveDIVHeight - padding) + ")")
.call(xAxis)
.selectAll('text')
.attr('transform', function(d) {
return "translate(-40,30) rotate(-60)"
}).call(wrap, 90);
var startPoint = 0;
var bar = svgX.selectAll('.bar')
.data(tempData)
.enter()
.append('rect')
.attr('y', function(d) {
return y(d.Count)
})
.attr('x', function(d) {
return x(d.Type)
})
.attr('width', barWidth)
.attr('height', function(d) {
return responsiveDIVHeight - y(d.Count) - padding
})
.axis line,
.axis path {
fill: none;
stroke: black;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<div class="row">
<div class="col-md-12">
<div id="verticalSVG" style="float:left">
</div>
<div id="horizontalSVG" style="overflow-x:scroll">
</div>
</div>
</div>