在D3图表的y轴标签中添加换行

4

我正在尝试在我的D3图表上为y轴标签添加换行符,该图表显示带宽移动情况。目前它以行内方式显示5 GB,我希望它显示如下:

5
GB

因为svg文本元素没有简单的添加换行的方式,所以在它们被渲染后我选择了选择所有文本元素,并将它们在空格处分割成 <tspan> 元素内部的文本元素位置,其中 GB 的位置略低于值,这似乎是有效的,但标签根本没有显示出来,即使它们存在于页面上。
以下是代码片段:
    function init(svg,data,width,height,margin){

      var x = d3.scale.linear()
        .domain([0,data[0].length-1])
        .range([margin.left, width-margin.right]),

      y = d3.scale.linear()
        .domain([0,d3.max(data[0])])
        .range([height-margin.bottom, margin.top]),

      /* Define stock x and y axis */
      xAxis = d3.svg
                .axis()
                .ticks(data[0].length)
                .tickFormat(function(d) { return d+1; })
                .scale(x)
                .orient('bottom'),

      yAxis = d3.svg
                .axis()
                .scale(y)
                .tickFormat(function(d) { return bytesToSize(d,0); })
                .orient('right'),

      /* line path generator */
      line = d3.svg.line().interpolate('monotone')
        .x(function(d,i) { return x(i); })
        .y(function(d) { return y(d); }),

      /* area path generator */
      area = d3.svg.area().interpolate('monotone')
        .x(line.x())
        .y1(line.y())
        .y0(y(0)),

      /* add the groups */
      groups = svg.selectAll("g")
        .data(data)
        .enter()
        .append("g");

      /* add the circles */
      svg.select("g")
        .selectAll("circle")
      .data(data[0])
      .enter()
        .append("circle")
        .attr("class","dot")
        .attr("cx", line.x())
        .attr("cy", line.y())
        .attr("r", 3.5)
        .style("fill","#008cc2")
        .style("stroke","#008cc2")
        .style("stroke-width","1.5px");

        /* add the axes */
        svg.append('g')
                .attr("class", "x axis")
                .attr("transform", "translate(0,"+(height - 20)+")")
                .call(xAxis)
                .selectAll("text")
                .style("text-anchor", "end")
                .attr("dx", "-.3em")
                .attr("dy", "-.3em")
                .attr("transform", function(d) {
                    return "rotate(-90)"
                });

        svg.append('g')
                .attr("class", "y axis")
                .call(yAxis);

      /* add the areas */
      area = groups.append("path")
        .attr("class", "area")
        .attr("d",area)
        .style("opacity",0.3)
        .style("fill", function(d,i) {
            return (i == 0 ? "#008cc2" : "#7500c6" );
        });

      /* add the lines */
      groups.append("path")
        .attr("class", "line")
        .attr("d", line)
        .style("fill","none")
        .style("stroke-width", "1.5px")
        .style("stroke", function(d,i) {
            return (i == 0 ? "#008cc2" : "#7500c6" );
        });

    var insertLinebreaks = function (d) {
        var el = $(d3.select(this).node());
        var sections = bytesToSize(d,0);

        console.log(sections[0]);
        console.log(sections[1]);

        el.text('');
        el.append('<tspan>'+sections[0]+'</tspan>');
        el.append('<tspan x="0" dy="3">'+sections[1]+'</tspan>');

    };

    svg.selectAll('g.y.axis g text').each(insertLinebreaks);

    }

function bytesToSize(bytes, precision)
{
    var kilobyte    = 1024;
    var megabyte    = kilobyte * 1024;
    var gigabyte    = megabyte * 1024;
    var terabyte    = gigabyte * 1024;

    if ((bytes >= 0) && (bytes < kilobyte)) {
        return [bytes,'B'];

    }
    else if ((bytes >= kilobyte) && (bytes < megabyte))
    {
        return [(bytes / kilobyte).toFixed(precision),'KB'];

    }
    else if ((bytes >= megabyte) && (bytes < gigabyte))
    {
        return [(bytes / megabyte).toFixed(precision),'MB'];

    }
    else if ((bytes >= gigabyte) && (bytes < terabyte))
    {
        return [(bytes / gigabyte).toFixed(precision),'GB'];

    }
    else if (bytes >= terabyte)
    {
        return [(bytes / terabyte).toFixed(precision),'TB'];

    }
    else
    {
        return [bytes,'B'];
    }
}

基本上,我想在SVG文本元素中添加一个换行符。我尝试了几种方法,但都没有成功。


你检查了相关的tspan元素是否按照你的预期创建了吗? - Lars Kotthoff
是的,我做了。HTML代码已经存在,但是没有显示任何内容。 - Odyss3us
1
问题可能是新元素添加在HTML而不是SVG命名空间中。您是否尝试使用D3附加tspan元素或显式创建具有正确命名空间的元素? - Lars Kotthoff
搞定了,加了命名空间就解决了。谢谢! :) - Odyss3us
好的,我会将其添加为答案以供日后参考。 - Lars Kotthoff
1个回答

4
问题在于你正在添加没有命名空间的tspan元素作为文本。这样它们会被解释为HTML。如果你使用D3添加它们或者显式地创建带有命名空间的元素,它应该可以正常工作,即:
el.text('');
d3.select(el).append("tspan").text(sections[0]);
...

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接