如何停止屏幕外的文本转换 [英] How to stop text transitioning off the screen

查看:60
本文介绍了如何停止屏幕外的文本转换的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我看到了两个环形的饼图. 我正在构建以下内容: -如果扇区的弧度对于指定的文本而言太小,则该文本将被隐藏.这样就完成了,看起来还可以 -如果隐藏了文本,则标签应该出现在饼图的外部.当视觉初始呈现时,也会执行此操作.

I have a visual of a two ringed pie chart. What I'm building is the following: - if a sector's radians are too small for the specified text then the text is hidden. This is done and seems to work ok - if text is hidden then a label should appear outside the pie. This is also done when the visual is initially rendered.

按下单选按钮时,饼图外部的标签应相应地过渡.我尝试了转换,并将其减慢到了3500,而这些标签正缓慢地移出屏幕.

When the radio button is pressed the labels outside the pie should transition accordingly. I've attempted the transition and slowed it to 3500 and these labels are just slowly transitioning off the screen.

如何解决此过渡?

我添加来尝试创建过渡的代码段始于第241行:

The snippet I've added to try to create the transition starts at line 241:

var arcs2 = svg.data([json]).selectAll(".arcG");

arcs2.data(partition.nodes)
  .transition()
  .duration(3500)
  .attr("transform", function(d) {

    var c = arc.centroid(d),
      x = c[0],
      y = c[1],
      // pythagorean theorem for hypotenuse
      h = Math.sqrt(x * x + y * y);
    return "translate(" + (x / h * labelr) + ',' +
      (y / h * labelr) + ")";
  })
  .attr("text-anchor", "middle");


svg.selectAll(".theTxtsOuter")
  .text(function(d, i) {
    if (d.name === 'root') {
      return;
    } else if ((d.depth === 1) && (d.dx < (d.name.length * 0.15))) {
      return d.name;
    } else if ((d.depth === 2) && (d.dx < (d.name.length * 0.1))) {
      return d.name;
    } else {
      return;
    }
  });

这是工作中的视觉效果!

This is a plunk of the working(!) visual:

https://plnkr.co/edit/jYVPCL?p=preview

这是饼所使用的完整javascript:

Here is the complete javascript used by the pie:

function pieChart(dataFile) {

  var plot;
  var vis;

  var width = 400,
    height = 400,
    radius = Math.min(width, height) / 2.1,
    color = d3.scale.ordinal()
    .range(["#338ABA", "#016da9", "#4c96d5"])
    .domain([0, 2]);

  var labelr = radius + 5 // radius for label anchor

  var div = d3.select("body")
    .append("div")
    .attr("class", "toolTip");



  var arc = d3.svg.arc()
    .startAngle(function(d) {
      return d.x;
    })
    .endAngle(function(d) {
      return d.x + d.dx;
    })
    .outerRadius(function(d) {
      return (d.y + d.dy) / (radius);
    })
    .innerRadius(function(d) {
      return d.y / (radius);
    });


  //check if the svg already exists
  plot = d3.select("#svgPIEChart");
  if (plot.empty()) {
    vis = d3.select("#pieChart")
      .append("svg")
      .attr({
        id: "svgPIEChart"
      });
  } else {
    vis = d3.select("#svgPIEChart");
    vis.selectAll("*").remove();
  }

  //group of the svg element
  var svg = vis
    .append("g")
    .attr({
      'transform': "translate(" + width / 2 + "," + height * .52 + ")"
    });


  //svg element
  vis.attr({
    //set the width and height of our visualization (these will be attributes of the <svg> tag
    width: width,
    height: height
  });



  d3.text(dataFile, function(text) {
    var csv = d3.csv.parseRows(text);
    var json = buildHierarchy(csv);

    // it seems d3.layout.partition() can be either squares or arcs
    var partition = d3.layout.partition()
      .sort(null)
      .size([2 * Math.PI, radius * radius])
      .value(function(d) {
        return d.SalesRev;
      });

    var path = svg.data([json]).selectAll(".theArc")
      .data(partition.nodes)
      .enter()
      .append("path")
      .attr("class", "theArc")
      .attr("id", function(d, i) {
        return "theArc_" + i;
      }) //Give each slice a unique ID 
      .attr("display", function(d) {
        return d.depth ? null : "none";
      })
      .attr("d", arc)
      .style("stroke", "#fff")
      .style("fill", function(d) {
        return color((d.children ? d : d.parent).name);
      })
      .attr("fill-rule", "evenodd")
      .style("opacity", 0.01)
      .style("stroke-opacity", 0.01)
      .each(stash);


    path.transition()
      .duration(PIEOBJ.transTime)
      .style("opacity", 1)
      .style("stroke-opacity", 1)

    path
      .on("mouseout", mouseout)
      .on("mousemove", function(d) {
        div.style("left", d3.event.pageX + 10 + "px");
        div.style("top", d3.event.pageY - 25 + "px");
        div.style("display", "inline-block");
        div.html(d.name + "<br>" + PIEOBJ.formatShrtInt(d.SalesRev));
      })



    var txts = svg.data([json]).selectAll(".theTxts")
      .data(partition.nodes)
      .enter()
      .append("text");
    txts
      .attr("class", "theTxts")
      .attr("dx", 10) //Move the text from the start angle of the arc
      .attr("dy", 15) //Move the text down
      .style("opacity", 0)
    txts
      .transition()
      .duration(PIEOBJ.transTime)
      .style("opacity", 1);



    var txtPths = txts.append("textPath")
      // .attr("xlink:href", function(d, i) {
      .attr("href", function(d, i) {
        return "#theArc_" + i;
      })
      .text(function(d) {
        if (d.name === 'root') {
          return;
        } else if ((d.depth === 1) && (d.dx < (d.name.length * 0.15))) {
          return;
        } else if ((d.depth === 2) && (d.dx < (d.name.length * 0.1))) {
          return;
        } else {
          return d.name;
        }
      });




    /* ------- TEXT LABELS OUTSIDE THE PIE-------*/
    //var arcs = svg.selectAll(".theArc");
    var arcs = svg.data([json]).selectAll(".arcG")
      .data(partition.nodes)
      .enter()
      .append("g")
      .attr("class", "arcG");

    arcs.append("text")
      .attr("transform", function(d) {

        var c = arc.centroid(d),
          x = c[0],
          y = c[1],
          // pythagorean theorem for hypotenuse
          h = Math.sqrt(x * x + y * y);
        console.log(c, h);
        return "translate(" + (x / h * labelr) + ',' +
          (y / h * labelr) + ")";
      })
      .attr("text-anchor", "middle")
      .text(function(d, i) {
        if (d.name === 'root') {
          return;
        } else if ((d.depth === 1) && (d.dx < (d.name.length * 0.15))) {
          return d.name;
        } else if ((d.depth === 2) && (d.dx < (d.name.length * 0.1))) {
          return d.name;
        } else {
          return;
        }
      })
      .attr("class", "theTxtsOuter");
    /* ----------------------------------------*/





    d3.selectAll("input").on("change", function change() {


      function createValueFunc(val) {
        // currentMeasure = val;
        return function(d) {
          return d[val];
        };
      }

      value = createValueFunc(this.value);

      PIEOBJ.currentMeasure = this.value;

      var path2 = svg.data([json]).selectAll(".theArc");
      path2
        .data(partition.value(value).nodes)
        .transition()
        .duration(1500)
        .attrTween("d", arcTween)
        .each("start", function() {
          d3.select(this)
            .on("mouseout", null) //CLEARING the listeners
            .on("mousemove", null);
        })
        .each("end", function() {
          d3.select(this)
            .on("mouseout", mouseout) //attaching the listeners
            .on("mousemove", function(d) {
              div.style("left", d3.event.pageX + 10 + "px");
              div.style("top", d3.event.pageY - 25 + "px");
              div.style("display", "inline-block");
              div.html(d.name + "<br>" + PIEOBJ.formatShrtInt(value(d)));
            });
        });

      svg.selectAll("textPath")
        .text(function(d) {
          if (d.name === 'root') {
            return;
          } else if ((d.depth === 1) && (d.dx < (d.name.length * 0.15))) {
            return;
          } else if ((d.depth === 2) && (d.dx < (d.name.length * 0.1))) {
            return;
          } else {
            return d.name;
          }
        });


      var arcs2 = svg.data([json]).selectAll(".arcG");

      arcs2.data(partition.nodes)
        .transition()
        .duration(3500)
        .attr("transform", function(d) {

          var c = arc.centroid(d),
            x = c[0],
            y = c[1],
            // pythagorean theorem for hypotenuse
            h = Math.sqrt(x * x + y * y);
          return "translate(" + (x / h * labelr) + ',' +
            (y / h * labelr) + ")";
        })
        .attr("text-anchor", "middle");


      svg.selectAll(".theTxtsOuter")
        .text(function(d, i) {
          if (d.name === 'root') {
            return;
          } else if ((d.depth === 1) && (d.dx < (d.name.length * 0.15))) {
            return d.name;
          } else if ((d.depth === 2) && (d.dx < (d.name.length * 0.1))) {
            return d.name;
          } else {
            return;
          }
        });

      // the following deletes what was originally created and then recreates the text
      // svg.selectAll("#titleX").remove();

    });



    function mouseout() {
      div.style("display", "none"); //<< gets rid of the tooltip <<
    }

    // Stash the old values for transition.
    function stash(d) {
      d.x0 = d.x;
      d.dx0 = d.dx;
    }

    // Interpolate the arcs in data space.
    function arcTween(a) {
      var i = d3.interpolate({
        x: a.x0,
        dx: a.dx0
      }, a);
      return function(t) {
        var b = i(t);
        a.x0 = b.x;
        a.dx0 = b.dx;
        return arc(b);
      };
    }

  });


}

// // Take a 2-column CSV and transform it into a hierarchical structure suitable
// // for a partition layout. 
function buildHierarchy(csv) {
  var root = {
    "name": "root",
    "children": []
  };
  for (var i = 0; i < csv.length; i++) {

    var sequence = csv[i][0];

    // var APD = +csv[i][1];
    var SalesRev = +csv[i][1];
    var Amount = +csv[i][2];

    if (isNaN(SalesRev)) { // e.g. if this is a header row
      continue;
    }
    var parts = sequence.split("-");
    var currentNode = root;
    for (var j = 0; j < parts.length; j++) {
      var children = currentNode.children;
      var nodeName = parts[j];
      var childNode;
      if (j + 1 < parts.length) {
        // Not yet at the end of the sequence; move down the tree.
        var foundChild = false;
        for (var k = 0; k < children.length; k++) {
          if (children[k].name == nodeName) {
            childNode = children[k];
            foundChild = true;
            break;
          }
        }
        // If we don't already have a child node for this branch, create it.
        if (!foundChild) {
          childNode = {
            "name": nodeName,
            "children": []
          };
          children.push(childNode);
        }
        currentNode = childNode;
      } else {
        // Reached the end of the sequence; create a leaf node.
        childNode = {
          "name": nodeName,
          // "APD": APD,
          "SalesRev": SalesRev,
          "Amount": Amount
        };
        children.push(childNode);
      }
    }
  }

  root.children.forEach(function(v) {
    v.SalesRev = 0;
    v.Amount = 0;

    v.children.forEach(function(a) {
      v.SalesRev += a.SalesRev;
      v.Amount += a.Amount;
    });
  });

  return root;
}

推荐答案

最初放置它们时,您正在转换text元素.过渡它们时,将放置外部g元素.这些导致冲突的转换.使用:

When you initially position them you are transforming the text elements. When you transition them you are positioning the outer g elements. These causes conflicting transforms. Use:

arcs2.data(partition.nodes)
  .select('text') //<-- apply on child text
  .transition()
  .duration(3500)
  .attr("transform", function(d) {
    ...
  });

更新了朋克车.

这篇关于如何停止屏幕外的文本转换的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆