2017-03-13 35 views
1

如何使用commonly used word wrap function將我的圓環圖標籤包裝成一行中的一個單詞?或者還有其他方法可以做到這一點嗎?在d3中包裝單詞以在一行中獲取一個單詞

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

var w = 650; 
var h = 400; 
var r = 100; 
var ir = 75; 
var textOffset = 24; 
var tweenDuration = 1050; 

//OBJECTS TO BE POPULATED WITH DATA LATER 
var lines, valueLabels, nameLabels; 
var pieData = [];  
var oldPieData = []; 
var filteredPieData = []; 

//D3 helper function to populate pie slice parameters from array data 
var donut = d3.layout.pie() 
.value(function(d){ 
    return d.itemValue; 
}); 

//D3 helper function to draw arcs, populates parameter "d" in path object 
var arc = d3.svg.arc() 
    .startAngle(function(d){ return d.startAngle; }) 
    .endAngle(function(d){ return d.endAngle; }) 
    .padAngle(.02) 
    .innerRadius(ir) 
    .outerRadius(r); 

// data 
var data; 
var dataStructure = [{ 
    "data":[{ 
     "itemLabel":"no patients", 
     "itemValue":27, 
     "color": "#2FB9A1" 
    },{ 
     "itemLabel":"1 patient", 
     "itemValue":11, 
     "color": "#F3B4B5" 
    },{ 
     "itemLabel":"2 patients", 
     "itemValue":33, 
     "color": "#EC8E8F" 
    },{ 
     "itemLabel":"3 or more patients", 
     "itemValue": 21, 
     "color": "#DA7C36" 
    }], 
    "label":"Patients" 
}]; 

// CREATE VIS & GROUPS 
var vis = d3.select("#pie-chart").append("svg:svg") 
    .attr("width", w) 
    .attr("height", h); 

//GROUP FOR ARCS/PATHS 
var arc_group = vis.append("svg:g") 
    .attr("class", "arc") 
    .attr("transform", "translate(" + (w/2) + "," + (h/2) + ")"); 

//GROUP FOR LABELS 
var label_group = vis.append("svg:g") 
    .attr("class", "label_group") 
    .attr("transform", "translate(" + (w/2) + "," + (h/2) + ")"); 

//GROUP FOR CENTER TEXT 
var center_group = vis.append("svg:g") 
    .attr("class", "center_group") 
    .attr("transform", "translate(" + (w/2) + "," + (h/2) + ")"); 

var centerText=''; 

// to run each time data is generated 
function update(number) { 
    data = dataStructure[number].data; 
    oldPieData = filteredPieData; 
    pieData = donut(data); 

    var sliceProportion = 0; //size of this slice 
    filteredPieData = pieData.filter(filterData); 
    function filterData(element, index, array) { 
     element.name = data[index].itemLabel; 
     element.value = data[index].itemValue; 
     element.color = data[index].color; 
     sliceProportion += element.value; 
     return (element.value > 0); 
    } 

    //DRAW ARC PATHS 
    paths = arc_group.selectAll("path") 
     .data(filteredPieData); 
    paths.enter() 
     .append("svg:path") 
     .attr("stroke", "transparent") 
     .attr("stroke-width", 0.5) 
     .attr("fill", function(d, i) { return d.color; }) 
     .transition() 
     .duration(tweenDuration) 
     .attrTween("d", pieTween); 

    paths.transition() 
     .duration(tweenDuration) 
     .attrTween("d", pieTween); 

    paths.exit() 
     .transition() 
     .duration(tweenDuration) 
     .attrTween("d", removePieTween) 
     .remove(); 

    paths.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.data.itemLabel)+"<br>"+(d.data.itemValue)); 
    }); 

    paths.on("mouseout", function(d){ 
     div.style("display", "none"); 
    }); 

    //DRAW LABELS WITH ENTITY NAMES 
    nameLabels = label_group.selectAll("text.units") 
     .data(filteredPieData) 
     .attr("dy", function(d) { 
      if ((d.startAngle+d.endAngle)/2 > Math.PI/2 && (d.startAngle+d.endAngle)/2 < Math.PI*1.5) { 
       return 17; 
      } else { 
       return 5; 
      } 
     }) 
     .attr("text-anchor", function(d) { 
      if ((d.startAngle+d.endAngle)/2 < Math.PI) { 
       return "beginning"; 
      } else { 
       return "end"; 
      } 
     }) 
     .text(function(d) { 
      return d.name; 
     }); 

    nameLabels.enter() 
     .append("svg:text") 
     .attr("class", "units") 
     .attr("transform", function(d) { 
      return "translate(" + Math.cos(((d.startAngle+d.endAngle - Math.PI)/2)) * (r+textOffset) + "," + Math.sin((d.startAngle+d.endAngle - Math.PI)/2) * (r+textOffset) + ")"; 
     }) 
     .attr("dy", function(d) { 
      if ((d.startAngle+d.endAngle)/2 > Math.PI/2 && (d.startAngle+d.endAngle)/2 < Math.PI*1.5) { 
       return 18; 
      } else { 
       return 5; 
      } 
     }) 
     .attr("text-anchor", function(d){ 
      if ((d.startAngle+d.endAngle)/2 < Math.PI) { 
       return "beginning"; 
      } else { 
       return "end"; 
      } 
     }).text(function(d){ 
      return d.name; 
     }); 

    nameLabels.transition() 
     .duration(tweenDuration) 
     .attrTween("transform", textTween); 

    nameLabels.exit().remove(); 

    var total = 0; 
    pieData.forEach(function(d) { total+=(d.value*1); }); 
    center_group.selectAll('text') 
     .data([total]) 
     .enter() 
     .append('text') 
     .text(function(d) { 
      return d; 
     }) 
     .attr('class','value') 
     .attr('dy', 8) 
     .attr('text-anchor', 'end') 
     .attr('transform', 'translate(20, 0)'); 
} 

Fiddle

如果標籤

3 or more patients 

我試圖讓排列單獨的行中心的每個字。

3 
or 
more 
patients 

回答

2

這是wrap function的一個快速重構。你可以使它更簡單一些,因爲你想分割每個單詞(而不是寬度)。 它變得更復雜一些圍繞更新fiddle

function wrap(text) { 
    text.each(function(d) { 
    var text = d3.select(this), 
     words = text.text().split(/\s+/).reverse(), 
     lineNumber = 0, 
     lineHeight = 1.1; 
    // null out text 
    text.text(null); 
    // loop the words 
    while (word = words.pop()) { 
     // build tspan 
     var tspan = text.append("tspan").attr("dy", ++lineNumber * lineHeight + "em").text(word); 
     // adjust position based on angle 
     if ((d.startAngle+d.endAngle)/2 < Math.PI) { 
     tspan.attr('x', 5) 
     } else { 
     tspan.attr('x', -25) 
     } 
     if ((d.startAngle+d.endAngle)/2 < Math.PI) { 
     tspan.attr('y', 0) 
     } else { 
     tspan.attr('y', -20) 
     } 
    } 
    }); 
} 

安排。

+0

最好使用'text-anchor'' middle'來對齊詞的中心位置嗎? – devo

+1

@devo,在'text-anchor:end'中右對齊:updated [fiddle](https://jsfiddle.net/zrdean6f/15/) – Mark

相關問題