d3.js中的文本换行不以图表栏为中心

时间:2016-11-23 22:53:42

标签: javascript d3.js svg

有人可以帮助我,将包装好的文字值集中在栏上。现在第一行是居中的,但所有新的附加行都在它下面。它们被包裹后有没有办法重新定位?

http://jsbin.com/qajejahiqi/edit?js,output

谢谢!

1 个答案:

答案 0 :(得分:1)

使用三元运算符,根据文本的长度更改标签的y位置:

.attr("y", function(d){
    return d.month.length > 50 ? y(d.month) + 8 : y(d.month) + (y.rangeBand() / 2);
})

我不想使用魔术数字,这只是只是一个例子,让您了解如何创建您的实际功能,您可以在其中更改我的幻数。 m在这里用于计算位置。

这个三元运算符的逻辑非常简单。首先,我们得到文本的长度:

d.month.length > 50

您可以根据左边距和字体大小更改任何计算值的50。如果文字大于该值,则设置y位置:

y(d.month) + 8

同样,8在这里只是一个幻数,你必须创建一个函数来根据条的宽度,文本的大小等来计算足够的数量......

另外,如果你有不同的行数,你可以连接几个三元运算符:

condition1 ? actionA : condition2 ? actionB : condition3? actionC : actionD;

如果condition1为真,则actionA完成。如果它为假,则评估condition2。如果确实如此,则actionB完成,如果错误,则评估condition3,依此类推......

查看演示:



var temperatures = [
  {temp: 32, month: 'January is really a long month.', color: 0},
  {temp: 38, month: 'February is really a cold month.', color: 1},
  {temp: 47, month: 'March, i dont know what to think', color: 1},
  {temp: 59, month: 'April. What if I wanted to test a really long string here that will span.', color: 2},
  {temp: 70, month: 'May', color: 2},
  {temp: 80, month: 'June', color: 2},
  {temp: 90, month: 'July', color: 2},
  {temp: 83, month: 'Auguest', color: 0},
  {temp: 76, month: 'September', color: 3},
  {temp: 64, month: 'October', color: 4},
  {temp: 49, month: 'November', color: 4},
  {temp: 37, month: 'December', color: 4}
];

var margin = {top: 5, right: 60, bottom: 50, left: 150},
    width = 700 - margin.left - margin.right,
    height = 600 - margin.top - margin.bottom;

var y = d3.scale.ordinal()
    .domain(temperatures.map(function (d) { return d.month; }))
    .rangeBands([0, height], 0.1, 0.35);

var x = d3.scale.linear()
    .domain([0, d3.max(temperatures, function(d){return d.temp;})])
    .range([0, width]);

var color = d3.scale.category20c();

var xAxis = d3.svg.axis()
    .scale(x)
    .orient("bottom")
    .innerTickSize(-(height-5))

var barChart = 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 + ")");

barChart.selectAll("#bar")
    .data(temperatures)
    .enter().append("rect")
    .attr("id", "bar")
    .attr("x", 0)
    .attr("width", function(d){return x(d.temp);})
    .attr("y", function (d) { return y(d.month); })
    .attr("fill", function(d){ return color(d.color); })
    .attr("height", y.rangeBand())
    .on("mouseover", function(){
        d3.select(this).attr("fill", "red");
    })
    .on("mouseout", function(){
        d3.select(this).attr("fill", function(d) { return color(d.color); });             
    });

barChart.append("g")
    .attr("class", "x axisHorizontal")
    .attr("transform", "translate(0," + height + ")")
    .call(xAxis)
    .append("text")
    .style("text-anchor", "end")
    .attr("x", width - 3)
    .attr("y", -5)
    .text("Label")

barChart.append("g")
    .selectAll("axisLabels")
    .data(temperatures)
    .enter()
    .append("text")
    .attr("x", 0)
    .attr("y", function(d){return d.month.length > 50 ? y(d.month) + 8 : y(d.month) + (y.rangeBand() / 2);})
    .attr("text-anchor", "end")
    .attr("dy", ".35em")
    .attr("dx", -5)
    .text(function(d){return d.month;})
    .call(wrap, margin.left);

barChart.append("g")
    .selectAll("valueLabels")
    .data(temperatures)
    .enter()
    .append("text")
    .attr("x", function(d){return x(d.temp);})
    .attr("y", function(d){return y(d.month) + (y.rangeBand() / 2);})
    .attr("dx", 5)
    .attr("dy", ".35em")
    .text(function(d){return d.temp;})

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("dx", -5).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("dx", -5).attr("dy", ++lineNumber * lineHeight + dy + "em").text(word);
      }
    }
  });
}

body { 
    font: 10px Arial;
}
.axis path {
    fill: none;
    stroke: grey;
    shape-rendering: crispEdges;
}
.axis text {
    font-family: Arial;
    font-size: 10px;
}
.axis line {
    fill: none;
    stroke: grey;
    stroke-width: 1;
    shape-rendering: crispEdges;
}
svg{
    display: block;
    margin: auto;
}

<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
&#13;
&#13;
&#13;