在D3图形y轴标签中添加换行符

时间:2022-02-15 14:59:50

I am trying to add a line break to the y-axis labels on my D3 graph, which displays bandwidth moved. At the moment it displays inline 5 GB, I would like it to display like so,

我试图在我的D3图表上的y轴标签上添加换行符,显示带宽移动。目前它显示内联5 GB,我希望它显示如此,

5
GB

So, since there is no easy way of adding a line break to a svg text element, I opted for selecting all of the text elements after they have been rendered, I split them at the space and positioned them in <tspan> elements inside of the text element, with the GB positioned slightly lower than the value, which seemed to work, except for the labels not displaying at all, even though they did exist on the page.

因此,由于没有简单的方法可以为svg文本元素添加换行符,所以我选择在渲染后选择所有文本元素,我将它们拆分到空间并将它们放在 元素中。文本元素,GB的位置略低于值,这似乎有效,除了标签根本不显示,即使它们确实存在于页面上。

Here is a snippet of the code,

这是一段代码,

    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'];
    }
}

Basically I would like to add a line break to a svg text element. I've tried a few methods, but to no avail.

基本上我想在svg文本元素中添加换行符。我尝试过几种方法,但无济于事。

1 个解决方案

#1


4  

The problem is that you're adding the tspan elements as text without a namespace. This way they get interpreted as HTML. If you add them using D3 or explicitly create the elements with a namespace, it should work, i.e.

问题是您将tspan元素添加为没有命名空间的文本。这样它们就被解释为HTML。如果使用D3添加它们或使用命名空间显式创建元素,它应该可以工作,即

el.text('');
d3.select(el).append("tspan").text(sections[0]);
...

#1


4  

The problem is that you're adding the tspan elements as text without a namespace. This way they get interpreted as HTML. If you add them using D3 or explicitly create the elements with a namespace, it should work, i.e.

问题是您将tspan元素添加为没有命名空间的文本。这样它们就被解释为HTML。如果使用D3添加它们或使用命名空间显式创建元素,它应该可以工作,即

el.text('');
d3.select(el).append("tspan").text(sections[0]);
...