2013-06-24 23 views
0

我試圖用數據驅動的文檔創建條形圖。但是我遇到了一個我自己無法解決的問題。在條形圖中包裝文本標籤3d.js

enter image description here

正如您在圖片中看到的第3條的文字重疊其他文本標籤。我想創建一個最大寬度,因此它可以放在一個盒子裏面,所以它不會與其他標籤重疊。這可能嗎?這裏是我的代碼:

var margin = {top: 20, right: 90, bottom: 30, left: 40}, 
    width = 670 - margin.left - margin.right, 
    height = 250 - margin.top - margin.bottom; 

var x0 = d3.scale.ordinal() 
    .rangeRoundBands([0, width], .1); 

var x1 = d3.scale.ordinal(); 

var y = d3.scale.linear() 
    .range([height, 0]); 

var color = d3.scale.ordinal() 
    .range([ "#4a4a82", "#6b54b2", "#9269e1", "#b99fe3", "#d3d3d3"]); 

var xAxis = d3.svg.axis() 
    .scale(x0) 
    .orient("bottom"); 

var yAxis = d3.svg.axis() 
    .scale(y) 
    .orient("left") 
    .tickFormat(d3.format(".2s")); 

var svg = d3.select("body").append("svg") 
    .attr("width", width + margin.left + margin.right) 
    .attr("height", height + margin.top + margin.bottom) 
    .append("g") 
    .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); 

var dataset = [ 
       {"State": "Vraag 1", "Helemaal eens": 20, "Eens": 10, "Niet eens, niet oneens": 20, "Oneens": 10, "Helemaal oneens": 10}, 
       {"State": "Vraag 2", "Helemaal eens": 20, "Eens": 10, "Niet eens, niet oneens": 20, "Oneens": 10, "Helemaal oneens": 10}, 
       {"State": "Zeer lange vraag om te kijken of het wordt afgehakt of niet", "Helemaal eens": 20, "Eens": 10, "Niet eens, niet oneens": 20, "Oneens": 10, "Helemaal oneens": 10}, 
       {"State": "Vraag 4", "Helemaal eens": 20, "Eens": 10, "Niet eens, niet oneens": 20, "Oneens": 10, "Helemaal oneens": 10}, 
       {"State": "Vraag 5", "Helemaal eens": 40, "Eens": 5, "Niet eens, niet oneens": 20, "Oneens": 10, "Helemaal oneens": 10} 
      ]; 
    var ageNames = d3.keys(dataset[0]).filter(function(key) { return key !== "State"; }); 

    dataset.forEach(function(d) { 
    d.ages = ageNames.map(function(name) { return {name: name, value: +d[name]}; }); 
    }); 

    x0.domain(dataset.map(function(d) { return d.State; })); 
    x1.domain(ageNames).rangeRoundBands([0, x0.rangeBand()]); 
    y.domain([0, d3.max(dataset, function(d) { return d3.max(d.ages, function(d) { return d.value; }); })]); 

    svg.append("foreignObject:g") 
     .attr("class", "x axis") 
     .attr("transform", "translate(0," + height + ")") 
     .call(xAxis) 
     .attr("width", 20) 
     .append("xhtml:graphmatrixtext") 
     .append("h5") 
     .style("text-anchor", "begin"); 

    svg.append("g") 
     .attr("class", "y axis") 
     .call(yAxis) 
    .append("text") 
     .attr("transform", "rotate(-90)") 
     .attr("y", 6) 
     .attr("dy", ".41em") 
     .style("text-anchor", "end") 
     .text("% Percentage"); 

    var state = svg.selectAll(".state") 
     .data(dataset) 
    .enter().append("g") 
     .attr("class", "g") 
     .attr("transform", function(d) { return "translate(" + x0(d.State) + ",0)"; }); 

    state.selectAll("rect") 
     .data(function(d) { return d.ages; }) 
    .enter().append("rect") 
     .attr("width", x1.rangeBand()) 
     .attr("x", function(d) { return x1(d.name); }) 
     .attr("y", function(d) { return y(d.value); }) 
     .attr("height", function(d) { return height - y(d.value); }) 
     .style("fill", function(d) { return color(d.name); }); 

    var legend = svg.selectAll(".legend") 
     .data(ageNames.slice()) 
    .enter().append("g") 
     .attr("class", "legend") 
     .attr("transform", function(d, i) { return "translate(0," + i * 20 + ")"; }); 

    legend.append("rect") 
     .attr("x", width + 50) 
     .attr("width", 18) 
     .attr("height", 18) 
     .style("fill", color); 

    legend.append("text") 
     .attr("x", width + 44) 
     .attr("y", 9) 
     .attr("dy", ".35em") 
     .style("text-anchor", "end") 
     .text(function(d) { return d; }); 

     var subject = svg.selectAll(".subject") 
      .data(dataset) 
      .enter().append("g") 
      .attr("class", "x axis"); 

修復該標籤上的JavaScript是這一部分:

d3.svg.axis = function() { 
    var scale = d3.scale.linear(), orient = d3_svg_axisDefaultOrient, tickMajorSize = 6, tickMinorSize = 6, tickEndSize = 6, tickPadding = 3, tickArguments_ = [ 10 ], tickValues = null, tickFormat_, tickSubdivide = 0; 
    function axis(g) { 
     g.each(function() { 
     var g = d3.select(this); 
     var ticks = tickValues == null ? scale.ticks ? scale.ticks.apply(scale, tickArguments_) : scale.domain() : tickValues, tickFormat = tickFormat_ == null ? scale.tickFormat ? scale.tickFormat.apply(scale, tickArguments_) : String : tickFormat_; 
     var subticks = d3_svg_axisSubdivide(scale, ticks, tickSubdivide), subtick = g.selectAll(".tick.minor").data(subticks, String), subtickEnter = subtick.enter().insert("line", ".tick").attr("class", "tick minor").style("opacity", 1e-6), subtickExit = d3.transition(subtick.exit()).style("opacity", 1e-6).remove(), subtickUpdate = d3.transition(subtick).style("opacity", 1); 
     var tick = g.selectAll(".tick.major").data(ticks, String), tickEnter = tick.enter().insert("g", "path").attr("class", "tick major").style("opacity", 1e-6), tickExit = d3.transition(tick.exit()).style("opacity", 1e-6).remove(), tickUpdate = d3.transition(tick).style("opacity", 1), tickTransform; 
     var range = d3_scaleRange(scale), path = g.selectAll(".domain").data([ 0 ]), pathUpdate = (path.enter().append("path").attr("class", "domain"), 
     d3.transition(path)); 
     var scale1 = scale.copy(), scale0 = this.__chart__ || scale1; 
     this.__chart__ = scale1; 
     tickEnter.append("line"); 
     tickEnter.append("text"); 
     var lineEnter = tickEnter.select("line"), lineUpdate = tickUpdate.select("line"), text = tick.select("text").text(tickFormat), textEnter = tickEnter.select("text"), textUpdate = tickUpdate.select("text"); 
     switch (orient) { 
     case "bottom": 
      { 
      tickTransform = d3_svg_axisX; 
      subtickEnter.attr("y2", tickMinorSize); 
      subtickUpdate.attr("x2", 0).attr("y2", tickMinorSize); 
      lineEnter.attr("y2", tickMajorSize); 
      textEnter.attr("y", Math.max(tickMajorSize, 0) + tickPadding); 
      lineUpdate.attr("x2", 0).attr("y2", tickMajorSize); 
      textUpdate.attr("x", 0).attr("y", Math.max(tickMajorSize, 0) + tickPadding); 
      text.attr("dy", ".71em").style("text-anchor", "middle"); 
      pathUpdate.attr("d", "M" + range[0] + "," + tickEndSize + "V0H" + range[1] + "V" + tickEndSize); 

      break; 
      } 

我真的很感激,如果有人可以幫助我走出這個!

回答

1

Mike Bostock himself has addressed this issue.

function wrap(text, width) { 
    text.each(function() { 
    var text = d3.select(this), 
     words = text.text().split(/\s+/).reverse(), 
     word, 
     line = [], 
     lineNumber = 0, 
     lineHeight = 1.1, // ems 
     y = text.attr("y"), 
     dy = parseFloat(text.attr("dy")), 
     tspan = text.text(null).append("tspan").attr("x", 0).attr("y", y).attr("dy", dy + "em"); 
    while (word = words.pop()) { 
     line.push(word); 
     tspan.text(line.join(" ")); 
     if (tspan.node().getComputedTextLength() > width) { 
     line.pop(); 
     tspan.text(line.join(" ")); 
     line = [word]; 
     tspan = text.append("tspan").attr("x", 0).attr("y", y).attr("dy", ++lineNumber * lineHeight + dy + "em").text(word); 
     } 
    } 
    }); 
} 

vis.selectAll(".tick text") 
    .call(wrap, 100);