我试图打破长轴的y轴标签。我的条形图如下所示:http://bl.ocks.org/erikvullings/51cc5332439939f1f292但标签较长(通常超过10个单词,带空格)。这是我的代码(它可以工作,我看到图表,唯一的错误'是文本,我加载JSON dinamically,这个数据仅用于SO):
HTML:
<svg id='table1'></svg>
<script>
var window_width = $(window).width();
var main_width = (window_width / 100 ) * 80;
var w = main_width - 400;
var data = {
labels: [
'the text to be splitted 1', 'the text to be splitted 2'
],
series: [
{
label: '2012',
values: [4, 8]
},
{
label: '2013',
values: [12, 43]
}
]
};
var chartWidth = w,
barHeight = 25,
groupHeight = barHeight * data.series.length,
gapBetweenGroups = 10,
spaceForLabels = 175,
spaceForLegend = 0;
// Zip the series data together (first values, second values, etc.)
var zippedData = [];
for (var i=0; i<data.labels.length; i++) {
for (var j=0; j<data.series.length; j++) {
zippedData.push(data.series[j].values[i]);
}
}
var chartHeight = barHeight * zippedData.length + gapBetweenGroups * data.labels.length;
var x = d3.scale.linear()
.domain([0, d3.max(zippedData)])
.range([0, chartWidth]);
var y = d3.scale.linear()
.range([chartHeight + gapBetweenGroups, 0]);
var yAxis = d3.svg.axis()
.scale(y)
.tickFormat('')
.tickSize(0)
.orient("left");
// Specify the chart area and dimensions
var chart = d3.select("#table"+ambit)
.attr("width", spaceForLabels + chartWidth + spaceForLegend)
.attr("height", chartHeight);
// Create bars
var bar = chart.selectAll("g")
.data(zippedData)
.enter().append("g")
.attr("transform", function(d, i) {
return "translate(" + spaceForLabels + "," + (i * barHeight + gapBetweenGroups * (0.5 + Math.floor(i/data.series.length))) + ")";
});
// Create rectangles of the correct width
bar.append("rect")
.attr("fill", function(d,i) { return color(i % data.series.length); })
.attr("class", "bar")
.attr("width", x)
.attr("height", barHeight - 1);
// Add text label in bar
bar.append("text")
.attr("class", "label_txt1")
.attr("x", function(d) { return x(d) - 3; })
.attr("y", barHeight / 2)
.attr("fill", "red")
.attr("dy", ".35em")
.text(function(d) { return d; });
// Draw labels
bar.append("text")
.attr("class", "label_txt")
.attr("x", function(d) { return - 10; })
.attr("y", groupHeight / 2)
.attr("dy", ".35em")
.text(function(d,i) {
if (i % data.series.length === 0)
return data.labels[Math.floor(i/data.series.length)];
else
return ""});
chart.append("g")
.attr("class", "y axis")
.attr("transform", "translate(" + spaceForLabels + ", " + -gapBetweenGroups/2 + ")")
.call(yAxis);
</script>
我按照多个例子来解决这个问题,例如: How do I include newlines in labels in D3 charts? 和Adding a line break to D3 graph y-axis labels和https://bl.ocks.org/mbostock/7555321
首次尝试:
var insertLinebreaks = function (d) {
var el = d3.select(this);
var words = d.split(' ');
el.text('');
for (var i = 0; i < words.length; i++) {
var tspan = el.append('tspan').text(words[i]);
if (i > 0)
tspan.attr('x', 0).attr('dy', '15');
}
};
chart.selectAll('g.y.axis text').each(insertLinebreaks);
和:
bar.selectAll('.label_txt1').each(insertLinebreaks);
我也试过了:
bar.append("text")
.attr("class", "label_txt1")
.attr("x", function(d) { return x(d) - 3; })
.attr("y", barHeight / 2)
.attr("fill", "red")
.attr("dy", ".35em")
.text(function(d) { return d; });
chart.selectAll(".label_txt1").call(wrap, 40)
function wrap(text, width) {
alert(JSON.stringify(text));
text.each(function() {
var text = d3.select(this),
words = text.text().split(/\s+/).reverse(),
word,
line = [],
lineNumber = 0,
y = text.attr("y"),
dy = parseFloat(text.attr("dy")),
lineHeight = 1.1, // ems
tspan = text.text(null).append("tspan").attr("x", function(d) { return d.children || d._children ? -10 : 10; }).attr("y", y).attr("dy", dy + "em");
while (word = words.pop()) {
line.push(word);
tspan.text(line.join(" "));
var textWidth = tspan.node().getComputedTextLength();
if (tspan.node().getComputedTextLength() > width) {
line.pop();
tspan.text(line.join(" "));
line = [word];
++lineNumber;
tspan = text.append("tspan").attr("x", function(d) { return d.children || d._children ? -10 : 10; }).attr("y", 0).attr("dy", lineNumber * lineHeight + dy + "em").text(word);
}
}
});
}
我在How do I include newlines in labels in D3 charts?
阅读时将text()
更改为html()
在浏览器中,我看到使用类<text>
创建的label_txt1
。当我尝试用selectAll(".label_txt1")
选择文本时,我得到的是行的值,而不是文本。
有人能帮助我吗?谢谢!
答案 0 :(得分:1)
您引用的此example是在使用svg文本节点时执行文本换行的规范方法。你只是称错了(在错误的班级,你正在包装数字)。将其简化为:
// Draw labels
bar.append("text")
.attr("class", "label_txt")
.attr("x", function(d) {
return -10;
})
.attr("y", groupHeight / 2) //<-- not sure you need this
.attr("dy", ".35em")
.text(function(d, i) {
if (i % data.series.length === 0)
return data.labels[Math.floor(i / data.series.length)];
else
return ""
})
.call(wrap, 40);
完整代码:
<!DOCTYPE html>
<html>
<head>
<script data-require="d3@3.5.3" data-semver="3.5.3" src="//cdnjs.cloudflare.com/ajax/libs/d3/3.5.3/d3.js"></script>
</head>
<body>
<svg id="table1"></svg>
<script>
var window_width = 1000;
var main_width = 400;
var w = 400;
var data = {
labels: [
'the text to be splitted 1', 'the text to be splitted 2'
],
series: [{
label: '2012',
values: [4, 8]
}, {
label: '2013',
values: [12, 43]
}]
};
var chartWidth = w,
barHeight = 25,
groupHeight = barHeight * data.series.length,
gapBetweenGroups = 10,
spaceForLabels = 175,
spaceForLegend = 0;
var color = d3.scale.category10();
// Zip the series data together (first values, second values, etc.)
var zippedData = [];
for (var i = 0; i < data.labels.length; i++) {
for (var j = 0; j < data.series.length; j++) {
zippedData.push(data.series[j].values[i]);
}
}
var chartHeight = barHeight * zippedData.length + gapBetweenGroups * data.labels.length;
var x = d3.scale.linear()
.domain([0, d3.max(zippedData)])
.range([0, chartWidth]);
var y = d3.scale.linear()
.range([chartHeight + gapBetweenGroups, 0]);
var yAxis = d3.svg.axis()
.scale(y)
.tickFormat('')
.tickSize(0)
.orient("left");
// Specify the chart area and dimensions
var chart = d3.select("#table1")
.attr("width", spaceForLabels + chartWidth + spaceForLegend)
.attr("height", chartHeight);
// Create bars
var bar = chart.selectAll("g")
.data(zippedData)
.enter().append("g")
.attr("transform", function(d, i) {
return "translate(" + spaceForLabels + "," + (i * barHeight + gapBetweenGroups * (0.5 + Math.floor(i / data.series.length))) + ")";
});
// Create rectangles of the correct width
bar.append("rect")
.attr("fill", function(d, i) {
return color(i % data.series.length);
})
.attr("class", "bar")
.attr("width", x)
.attr("height", barHeight - 1);
// Add text label in bar
bar.append("text")
.attr("class", "label_txt1")
.attr("x", function(d) {
return x(d) - 3;
})
.attr("y", barHeight / 2)
.attr("fill", "red")
.attr("dy", ".35em")
.text(function(d) {
return d;
});
// Draw labels
bar.append("text")
.attr("class", "label_txt")
.attr("x", function(d) {
return -10;
})
//.attr("y", groupHeight / 2) //<-- you don't need this...
.attr("dy", ".35em")
.text(function(d, i) {
if (i % data.series.length === 0)
return data.labels[Math.floor(i / data.series.length)];
else
return ""
})
.call(wrap, 40);
function wrap(text, width) {
text.each(function() {
var text = d3.select(this),
words = text.text().split(/\s+/).reverse(),
word,
line = [],
lineNumber = 0,
y = text.attr("y"),
dy = parseFloat(text.attr("dy")),
lineHeight = 1.1, // ems
tspan = text.text(null).append("tspan").attr("x", function(d) {
return d.children || d._children ? -10 : 10;
}).attr("y", y).attr("dy", dy + "em");
while (word = words.pop()) {
line.push(word);
tspan.text(line.join(" "));
var textWidth = tspan.node().getComputedTextLength();
if (tspan.node().getComputedTextLength() > width) {
line.pop();
tspan.text(line.join(" "));
line = [word];
++lineNumber;
tspan = text.append("tspan").attr("x", function(d) {
return d.children || d._children ? -10 : 10;
}).attr("y", 0).attr("dy", lineNumber * lineHeight + dy + "em").text(word);
}
}
});
}
chart.append("g")
.attr("class", "y axis")
.attr("transform", "translate(" + spaceForLabels + ", " + -gapBetweenGroups / 2 + ")")
.call(yAxis);
</script>
</body>
</html>