D3 차트의 레이블에 줄 바꿈을 어떻게 포함합니까?
저는 D3를 사용하여 막대 차트를 생성하고 있습니다 ( 이 예제 의 코드를 수정했습니다 ). x 축 에서 사용하는 레이블 은 각각 두 단어 길이이며 모든 레이블이 겹치므로이 레이블을 여러 줄로 나누어야합니다. (각 레이블의 모든 공백을 줄 바꿈으로 바꿀 수 있으면 괜찮습니다.)
원래 공백을 리터럴 줄 바꿈 ( 

) 으로 바꾸고 xml:space="preserve"
레이블 <text>
요소를 설정 하여 시도했습니다 . 불행히도 SVG는이 속성을 존중하지 않는다는 것이 밝혀졌습니다. 다음으로 <tspan>
나중에 스타일을 지정할 수 있도록 각 단어를 a로 감싸려고했습니다 . 이 함수를 통해 각 레이블을 전달했습니다.
function (text) {
return '<tspan>' + text.replace(/ /g, '</tspan><tspan>') + '</tspan>';
}
그러나 이것은 리터럴 <tspan>
s를 출력에 넣습니다. tspan
내 레이블이 겹치지 않도록 텍스트 레이블을 s로 감싸 거나 다른 작업을 수행하려면 어떻게해야합니까?
다음 코드를 사용하여 각 x 축 레이블을 여러 줄로 나누었습니다.
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');
}
};
svg.selectAll('g.x.axis g text').each(insertLinebreaks);
이것은 레이블이 이미 생성되었다고 가정합니다. ( 표준 히스토그램 예제 를 따르면 레이블이 필요한 방식으로 설정됩니다.) 또한 실제 줄 바꿈 논리가 존재하지 않습니다. 이 함수는 모든 공백을 개행 문자로 변환합니다. 이것은 내 목적에 잘 맞지만 split()
문자열의 일부를 줄로 분할하는 방법에 대해 더 현명하게 줄을 편집해야 할 수도 있습니다 .
SVG 텍스트 요소는 텍스트 줄 바꿈을 지원하지 않으므로 두 가지 옵션이 있습니다.
- 텍스트를 여러 SVG 텍스트 요소로 분할
- SVG 위에 오버레이 HTML div 사용
여기 에서 Mike Bostock의 의견을 참조 하십시오 .
내가 유용한 것으로 밝혀진 것은 text 또는 tspan 요소 대신 'foreignObject'태그를 사용하는 것입니다. 이렇게하면 HTML을 간단하게 포함 할 수 있으므로 단어가 자연스럽게 분리됩니다. 주의 사항은 특정 요구 사항을 충족하는 개체의 전체 치수입니다.
var myLabel = svg.append('foreignObject')
.attr({
height: 50,
width: 100, // dimensions determined based on need
transform: 'translate(0,0)' // put it where you want it...
})
.html('<div class"style-me"><p>My label or other text</p></div>');
이 객체 안에 어떤 요소를 배치하든 나중에 d3.select/selectAll을 사용하여 텍스트 값을 동적으로 업데이트 할 수 있습니다.
주위를 둘러 본 결과 Mike Bostock이 텍스트를 줄 바꿈 할 수있는 솔루션을 제공했음을 알았습니다.
http://bl.ocks.org/mbostock/7555321
내 코드에서 구현하려면 (축소 된 트리 다이어그램을 사용하고 있습니다). 나는 단순히 "wrap"방법을 복사했다.
그런 다음 다음을 추가했습니다.
// Standard code for a node
nodeEnter.append("text")
.attr("x", function(d) { return d.children || d._children ? -10 : 10; })
.attr("dy", ".35em")
.text(function(d) { return d.text; })
// New added line to call the function to wrap after a given width
.call(wrap, 40);
나는 이것이 강제 지시, 바 또는 다른 패턴에 대해 작동하지 않아야하는 이유를 보지 못합니다.
수정 :
이것을 읽고 접을 수있는 그래프를 사용하는 사람을 위해 랩 기능을 다음과 같이 수정했습니다. "x"속성의 변경은 할당을 올바르게 설정합니다. 원래 코드에서 문제가 기록되고 "y"가 0으로 하드 설정되었으므로 줄 번호를 별도의 줄에서 수행했습니다. 그렇지 않으면 줄 간격이 증가하는 문제가 발생합니다. 각 줄.
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);
}
}
});
}
도 있습니다 이 긴 라벨을 포장에 대한 대답은.
<!DOCTYPE html>
<meta charset="utf-8">
<style>
.bar {
fill: steelblue;
}
.bar:hover {
fill: brown;
}
.title {
font: bold 14px "Helvetica Neue", Helvetica, Arial, sans-serif;
}
.axis {
font: 10px sans-serif;
}
.axis path,
.axis line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
.x.axis path {
display: none;
}
</style>
<body>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script>
var margin = {top: 80, right: 180, bottom: 80, left: 180},
width = 960 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
var x = d3.scale.ordinal()
.rangeRoundBands([0, width], .1, .3);
var y = d3.scale.linear()
.range([height, 0]);
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom");
var yAxis = d3.svg.axis()
.scale(y)
.orient("left")
.ticks(8, "%");
var svg = d3.select("body").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
d3.tsv("data.tsv", type, function(error, data) {
x.domain(data.map(function(d) { return d.name; }));
y.domain([0, d3.max(data, function(d) { return d.value; })]);
svg.append("text")
.attr("class", "title")
.attr("x", x(data[0].name))
.attr("y", -26)
.text("Why Are We Leaving Facebook?");
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis)
.selectAll(".tick text")
.call(wrap, x.rangeBand());
svg.append("g")
.attr("class", "y axis")
.call(yAxis);
svg.selectAll(".bar")
.data(data)
.enter().append("rect")
.attr("class", "bar")
.attr("x", function(d) { return x(d.name); })
.attr("width", x.rangeBand())
.attr("y", function(d) { return y(d.value); })
.attr("height", function(d) { return height - y(d.value); });
});
function wrap(text, width) {
text.each(function() {
var text = d3.select(this),
words = text.text().split(/\s+/).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);
}
}
});
}
function type(d) {
d.value = +d.value;
return d;
}
</script>
및 데이터 파일 "data.tsv":
name value
Family in feud with Zuckerbergs .17
Committed 671 birthdays to memory .19
Ex is doing too well .10
High school friends all dead now .15
Discovered how to “like” things mentally .27
Not enough politics .12
사용하다 <tspan>
및 nv.d3
nv.models.axis = function () {
...
.select('text')
.attr('dy', '0em')
.attr('y', -axis.tickPadding())
.attr('text-anchor', 'middle')
.text(function(d,i) {
var v = fmt(d);
return ('' + v).match('NaN') ? '' : v;
});
모든 .text (를 .html (으로 변경)
참고 URL : https://stackoverflow.com/questions/13241475/how-do-i-include-newlines-in-labels-in-d3-charts
'Programing' 카테고리의 다른 글
Rails Asset Pipeline 사전 컴파일 프로세스의 속도를 높이려면 어떻게해야합니까? (0) | 2020.11.28 |
---|---|
Go에 람다 식이나 비슷한 것이 있습니까? (0) | 2020.11.28 |
C 대 C ++ 구조체 정렬 (0) | 2020.11.28 |
dotnet cli와 새로운 vs2017 msbuild 간의 관계 (0) | 2020.11.28 |
ELMAH를 사용하는 WCF 서비스에 대한 예외 로깅 (0) | 2020.11.28 |