简体   繁体   中英

Adding a line break to D3 graph y-axis labels

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,

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.

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.

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, ie

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM