2017-04-07 165 views
0

我有一個視覺的雙環形餅圖。我已經添加了以下嘗試圖表外添加標籤:爲什麼這些標籤不可見

var arcs = svg.selectAll(".theArc") 

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 "hello" + d.name; 
     } 
    }) 
    .attr("class", "theTxtsOuter") 

我可以看到文本的檢查員,但不能在網頁上呈現 - 這是爲什麼文本不可見?

這裏是視覺的普拉克:http://plnkr.co/edit/cnump1mG0XRXxrCur0OT?p=preview

下面是該函數的填充代碼創建餅圖:

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") 

     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 "hello" + d.name; 
       } 
      }) 
      .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; 
        } 
       }); 

      // 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; 
} 

回答

2

沒有顯示,因爲它被添加作爲一個孩子的文本的path元素。下g標籤添加與path元素同級別的文本。做到這一點的方法之一是這樣的(它增加了g元素每個圓弧的一個級別組的弧線和文字一起):

var arcs = svg.data([json]).selectAll(".arcG") 
    .data(partition.nodes) 
    .enter() 
    .append("g") 
    .attr("class","arcG"); 

arcs.append("path") 
     .attr("class","theArc") 
     .attr("d", arc) 
     ... 

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) + ")"; 
    }) 
    .... 
+0

你做一些偉大的工作Tormi! https://twitter.com/TormiReinson – whytheq

+0

... UT我很新的D3和發現很難知道其中的代碼來實現你所建議的更改嗎? – whytheq

+0

爲什麼我們需要你的代碼的中間部分? 'arcs.append( 「路徑」) .attr( 「類」, 「theArc」) .attr( 「d」,ARC) ...'我知道,第一部分增加了'g'元素,然後加入他們對數據......第三部分添加文本,但是中間部分是什麼? – whytheq