Javascript 如何停止屏幕外的文本转换

Javascript 如何停止屏幕外的文本转换,javascript,d3.js,svg,Javascript,D3.js,Svg,我看到了一个双环饼图。 我正在构建的是以下内容: -如果某个扇区的弧度对于指定的文本来说太小,则该文本将被隐藏。这是做了,似乎工作正常 -如果文本被隐藏,则应在饼图外部显示标签。最初渲染视觉效果时也会执行此操作 当按下单选按钮时,饼图外的标签应相应转换。我已经尝试过转换,并将其减慢到3500,而这些标签只是在屏幕上慢慢转换 如何修复此转换 我为尝试创建转换而添加的代码段从第241行开始: var arcs2 = svg.data([json]).selectAll(".arcG"); arcs

我看到了一个双环饼图。 我正在构建的是以下内容: -如果某个扇区的弧度对于指定的文本来说太小,则该文本将被隐藏。这是做了,似乎工作正常 -如果文本被隐藏,则应在饼图外部显示标签。最初渲染视觉效果时也会执行此操作

当按下单选按钮时,饼图外的标签应相应转换。我已经尝试过转换,并将其减慢到3500,而这些标签只是在屏幕上慢慢转换

如何修复此转换

我为尝试创建转换而添加的代码段从第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;
    }
  });
var arcs2=svg.data([json])。选择all(“.arcG”);
arcs2.数据(分区.节点)
.transition()
.持续时间(3500)
.attr(“转换”,函数(d){
var c=弧形心(d),
x=c[0],
y=c[1],
//斜边勾股定理
h=数学sqrt(x*x+y*y);
返回“translate(“+(x/h*labelr)+',”+
(y/h*标签+”;
})
.attr(“文本锚定”、“中间”);
svg.selectAll(“.theTxtsOuter”)
.文本(功能(d,i){
如果(d.name=='root'){
返回;
}否则如果((d.depth==1)和&(d.dx<(d.name.length*0.15))){
返回d.name;
}否则如果((d.depth==2)和&(d.dx<(d.name.length*0.1))){
返回d.name;
}否则{
返回;
}
});
这是一个正在工作的(!)视觉:

以下是饼图使用的完整javascript:

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;
}
功能图表(数据文件){
var图;
var-vis;
可变宽度=400,
高度=400,
半径=数学最小值(宽度、高度)/2.1,
颜色=d3.scale.ordinal()
.范围([“#338ABA”、“#016da9”、“#4c96d5”])
.域([0,2]);
var labelr=半径+5//标签锚定的半径
var div=d3。选择(“主体”)
.附加(“div”)
.attr(“类”、“工具提示”);
var arc=d3.svg.arc()
.startAngle(功能(d){
返回d.x;
})
.端角(功能(d){
返回d.x+d.dx;
})
.外层(功能(d){
返回(d.y+d.dy)/(半径);
})
.内半径(功能(d){
返回d.y/(半径);
});
//检查svg是否已经存在
绘图=d3。选择(“svgPIEChart”);
if(plot.empty()){
vis=d3。选择(“pieChart”)
.append(“svg”)
艾特先生({
id:“svgPIEChart”
});
}否则{
vis=d3。选择(“svgPIEChart”);
vis.selectAll(“*”).remove();
}
//svg元素的组
var svg=vis
.附加(“g”)
艾特先生({
“转换”:“转换(“+width/2+”,“+height*.52+”)
});
//svg元素
vis.attr({
//设置可视化的宽度和高度(这些将是标签的属性)
宽度:宽度,
高度:高度
});
d3.文本(数据文件、函数(文本){
var csv=d3.csv.parseRows(文本);
var json=buildHierarchy(csv);
//看起来d3.layout.partition()可以是正方形,也可以是圆弧
var partition=d3.layout.partition()
.sort(空)
.size([2*Math.PI,半径*半径])
.价值(功能(d){
返回d.SalesRev;
});
var path=svg.data([json])。选择all(“.theArc”)
.数据(分区.节点)
.输入()
.append(“路径”)
.attr(“类”、“theArc”)
.attr(“id”,函数(d,i){
返回“theArc_”+i;
})//给每个片一个唯一的ID
.attr(“显示”,功能(d){
返回d.depth?空:“无”;
})
.attr(“d”,弧)
.style(“笔划”、“fff”)
.样式(“填充”,功能(d){
返回颜色((d.children?d:d.parent).name);
})
.attr(“填充规则”、“偶数”)
.style(“不透明度”,0.01)
.style(“笔划不透明度”,0.01)
.每个(储藏);
path.transition()
.持续时间(PIEOBJ.传输时间)
.style(“不透明度”,1)
.style(“笔划不透明度”,1)
路径
.on(“mouseout”,mouseout)
.on(“mousemove”,函数(d){
div.style(“左”,d3.event.pageX+10+“px”);
div.style(“top”,d3.event.pageY-25+“px”);
div.style(“显示”、“内联块”);
div.html(d.name+“
”+PIEOBJ.formatShrtInt(d.SalesRev)); }) var txts=svg.data([json])。选择All(“.theTxts”) .数据(分区.节点) .输入() .附加(“文本”); txts .attr(“类”、“theTxts”) .attr(“dx”,10)//从弧的起始角度移动文本 .attr(“dy”,15)//向下移动文本 .style(“不透明度”,0) txts .transition() .持续时间(PIEOBJ.传输时间) .样式(“不透明”,1); var txtPths=txts.append(“textPath”) //.attr(“xlink:href”,函数(d,i){ .attr(“href”,函数(d,i){ 返回“#the arc#”+i; }) .文本(功能(d){ 如果(d.name=='root'){ 返回; }否则如果((d.depth==1)和&(d.dx<(d.name.length*0.15))){ 返回; }否则如果((d.depth==2)和&(d.dx<(d.name.length*0.1))){ 返回; }否则{ 返回d.name; } }); /*----饼图外的文本标签-------*/ //var arcs=svg.selectAll(“.theArc”); var arcs=svg.data([json])。选择全部(“.arcG”) .数据(分区.节点) .输入() .附加(“g”) .attr(“类别”、“arcG”); arcs.append(“文本”) .attr(“转换”,函数(d){ var c=弧形心(d), x=c[0], y=c[1], //斜边勾股定理 h=数学sqrt(x*x+y*y); 控制台日志(c,h); 返回“translate(“+(x/h*labelr)+',”+ (y/h*标签+”; }) .attr(“文本锚定”、“中间”) .文本(功能(d,i){ 如果(d.name=='root'){ 返回; }否则如果((d.depth==1)和&(d.dx<(d.name.length*0.15))){ 返回d.name; }否则如果((d.depth==2)和&(d.dx<(d.name.length*0.1))){ 返回d.name; }否则{
arcs2.data(partition.nodes)
  .select('text') //<-- apply on child text
  .transition()
  .duration(3500)
  .attr("transform", function(d) {
    ...
  });