2016-06-21 136 views
0

我的要求是生成分组类别条形图。我能够生成该图形,但问题是如果x轴标签名称大于条形区域范围,则标签名称重叠,因为这样无法获得理想的外观和感觉。我发现了一些我们可以将文本换行的位置标签,但我不知道如何实现这一点。x轴标签重叠分组类别条形图d3

相关分组生成图表类的js在这里和HTML代码

var margin = { 
 
    top: 20, 
 
    right: 20, 
 
    bottom: 130, 
 
    left: 40 
 
    }, 
 
    width = 2360 - margin.left - margin.right, 
 
    height = 560 - margin.top - margin.bottom; 
 
var color = { 
 
    Mechanical: '#4A7B9D', 
 
    Electrical: '#54577C', 
 
    Hydraulic: '#ED6A5A' 
 
}; 
 
var barPadding = 40; 
 
var data = [ 
 
    { 
 
    "key" : "portFolio1", 
 
    "values" :[ 
 
       { 
 
       "key" : "project1", 
 
       "values" :[ 
 
         { 
 
          "key" : "config1", 
 
          "values" :[ 
 
            { 
 
            "key" :"date1", 
 
            "value": 12 
 
            }, 
 
            { 
 
            "key" : "date2", 
 
            "value": 10 
 
            }, 
 
            { 
 
            "key" : "date3", 
 
            "value": 2 
 
            } 
 
           ], 
 
          
 
          }, 
 

 
\t \t \t { 
 
          "key" : "configurationwithvalue", 
 
          "values" :[ 
 
            { 
 
            "key" :"date1asa", 
 
            "value": 10 
 
            }, 
 
            { 
 
            "key" : "date2", 
 
            "value": 10 
 
            }, 
 
            { 
 
            "key" : "date3", 
 
            "value": 2 
 
            } 
 
           ], 
 
          
 
          }, 
 
          { 
 
          "key" : "config2", 
 
          "values" :[ 
 
            { 
 
             "key" : "date1", 
 
             "value": 1 
 
            }, 
 
            { 
 
             "key" : "date3", 
 
             "value": 14 
 
            } 
 
            ], 
 
           
 
          } 
 
          ], 
 
          
 
        }, 
 
        { 
 
        "key" : "projct2", 
 
        "values" :[ 
 
           { 
 
           "key" : "congi1", 
 
           "values" :[ 
 
              { 
 
              "key" : "date2", 
 
              "value" :1 
 
              }, 
 
              { 
 
              "key" : "date3", 
 
              "value": 10 
 
              } 
 
             ], 
 
           
 
           } 
 
           ], 
 
          
 
         } 
 
         ] , 
 
     
 
     }, 
 
     { 
 
     "key" : "portfolio2", 
 
     "values" :[ 
 
        { 
 
        "key" : "portfolio2_project1", 
 
        "values" :[ 
 
           { 
 
           "key" : "congie1", 
 
           "values" : [ 
 
             { 
 
              "key" : "date12", 
 
              "value": 23 
 
             }, 
 
             { 
 
             "key" : "date1", 
 
             "value" : 1 
 
             } 
 
            ], 
 
           
 
           } 
 
           ], 
 
          
 
         } 
 
        ], 
 
        
 
       }, 
 
    { 
 
    "key" : "portFolio3", 
 
    "values" :[ 
 
       { 
 
       "key" : "project_portfolio3", 
 
       "values" :[ 
 
         { 
 
          "key" : "congi1", 
 
          "values" :[ 
 
            { 
 
            "key" :"date1", 
 
            "value": 12 
 
            } 
 
           ], 
 
          
 
          }, 
 
          { 
 
          "key" : "congi2", 
 
          "values" :[ 
 
            { 
 
             "key" : "date1", 
 
             "value": 1 
 
            }, 
 
            { 
 
             "key" : "date3", 
 
             "value": 14 
 
            } 
 
            ], 
 
           
 
          } 
 
          ], 
 
          
 
        }, 
 
        { 
 
        "key" : "projct2_prortfolio_23", 
 
        "values" :[ 
 
           { 
 
           "key" : "congi1", 
 
           "values" :[ 
 
              { 
 
              "key" : "date2", 
 
              "value" :1 
 
              }, 
 
              { 
 
              "key" : "date3", 
 
              "value": 10 
 
              } 
 
             ], 
 
           
 
           } 
 
           ], 
 
          
 
         } 
 
         ] , 
 
     
 
     } 
 
      ] 
 

 
var rangeBands = []; 
 
var cummulative = 0; // to get transform position of categories 'portfolio1,portfolio2,portfolio3 on x axis scale 
 
data.forEach(function(val, i) { 
 
    var valLength = 0; // to get position of x axis for categories 'portfolio1,portfolo2,portfolio3 on x axis scale 
 
    val.cummulative = cummulative; 
 
    var cum = 0; // to get trnsfrom position of categories 'projct1,project2,project3' on x axis scale 
 
    val.values.forEach(function(values) { 
 
    var valLe = 0;  // to get position of x axis for categories 'projct1,project2,project3' on x axis scale 
 
    values.cummulative2 = cum; 
 
    values.parentKey = val.key; 
 
    var cum3 = 0; // to get trnsfrom position of categories 'config1,config2...etc on x axis scale 
 
    values.values.forEach(function(values) { // config level 
 
    \t values.cummulative3 = cum3; 
 
    \t values.parentKey = values.key; 
 
    \t values.values.forEach(function(values) { 
 
     \t \t cum3 = cum3 +1; 
 
     \t \t valLe = valLe + 1; 
 
     \t \t cum = cum+1; 
 
     \t \t valLength = valLength +1 ; 
 
     \t \t cummulative = cummulative+1; 
 
     \t \t values.parentKey = values.key; 
 
    \t \t rangeBands.push(i); 
 
    \t }) 
 
    }) 
 
    values.valueLength2 = valLe; 
 
    }) 
 
val.valueLength = valLength; 
 
}); 
 

 

 

 
// set x axis domain adn range 
 
var x_category = d3.scale.linear() 
 
    .range([0, width]); 
 
var x_defect = d3.scale.ordinal().domain(rangeBands).rangeRoundBands([0, width], .1); 
 
var x_category_domain = x_defect.rangeBand() * rangeBands.length*3; 
 
x_category.domain([0, x_category_domain]); 
 

 

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

 
y.domain([0, d3.max(data, function(cat) { 
 
    return d3.max(cat.values, function(def) { 
 
    return d3.max(def.values, function(def) { 
 
    \t return d3.max(def.values, function(def) { 
 
    \t \t return def.value; 
 
    \t }); 
 
    }); 
 
    }); 
 
})]); 
 

 

 

 
// x axis scale 
 
var category_axis = d3.svg.axis() 
 
    .scale(x_category) 
 
    .orient("bottom"); 
 

 

 
// y axis scale 
 
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) 
 
    .style('background-color', 'EFEFEF') 
 
    .append("g") 
 
    .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); 
 

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

 

 
//add all category groups of 'profolio1,portfolio2,portfolio3 ..etc for svg 
 
var category_g = svg.selectAll(".category") 
 
    .data(data) 
 
    .enter().append("g") 
 
    .attr("class", function(d) { 
 
    return 'category category-' + d.key; 
 
    }) 
 
    .attr("transform", function(d) { 
 
    return "translate(" + x_category((d.cummulative * x_defect.rangeBand())) + ",0)"; 
 
    }); 
 

 

 
//add all category groups of projct1,project2 etc for every category group of category_g 
 
var category_g1 = category_g.selectAll(".category1") 
 
    .data(function(d) { 
 
    return d.values; 
 
    }) 
 
    .enter().append("g") 
 
    .attr("class", function(d) { 
 
    return 'category category1-' + d.key; 
 
    }) 
 
    .attr("transform", function(d) { 
 
    return "translate(" + x_category((d.cummulative2 * x_defect.rangeBand())) + ",0)"; 
 
    }) 
 

 
//add all category groups of 'congif1,config2' etc for every category group of category_g1 
 
var category_g2 = category_g1.selectAll(".category2") 
 
    .data(function(d) { 
 
    return d.values; 
 
    }) 
 
    .enter().append("g") 
 
    .attr("class", function(d) { 
 
    return 'category category2-' + d.key; 
 
    }) 
 
    .attr("transform", function(d) { 
 
    return "translate(" + x_category((d.cummulative3 * x_defect.rangeBand())) + ",0)"; 
 
    }) 
 
    
 

 

 
// lables for category_g 
 
var category_label = category_g.selectAll(".category-label") 
 
    .data(function(d) { 
 
    return [d]; 
 
    }) 
 
    .enter().append("text") 
 
    .attr("class", function(d) { 
 
    return 'category-label category-label-' + d.key; 
 
    }) 
 
    .attr("transform", function(d) { 
 
    var x_label = x_category((d.valueLength * x_defect.rangeBand() + barPadding)/2); 
 
    var y_label = height + 120; 
 
    return "translate(" + x_label + "," + y_label + ")"; 
 
    }) 
 
    .text(function(d) { 
 
    return d.key; 
 
    }) 
 
    .attr('text-anchor', 'middle'); 
 

 

 
// lines to separate each category_g labels 
 
category_g.append("line") 
 
.attr("x1", function(d) { 
 
    return x_category((d.valueLength * x_defect.rangeBand()+ barPadding)); 
 
}) 
 
.attr("y1", 0) 
 
.attr("x2", function(d) { 
 
    return x_category((d.valueLength * x_defect.rangeBand()+ barPadding)); 
 
}) 
 
.attr("y2", 120) 
 
.attr("transform", function(d) { 
 
    var x_label = 0; 
 
    var y_label = height; 
 
    return "translate(" + x_label + "," + y_label + ")"; 
 
    }) 
 
.style("stroke-width", 1) 
 
.style("stroke", "red") 
 
.style("fill", "none"); 
 

 

 

 
// lables for category_g1 
 
var category_label1 = category_g1.selectAll(".category-label1") 
 
    .data(function(d) { 
 
    return [d]; 
 
    }) 
 
    .enter().append("text") 
 
    .attr("class", function(d) { 
 
    return 'category-label category-label-' + d.key; 
 
    }) 
 
    .attr("transform", function(d) { 
 
    var x_label = x_category((d.values.length * x_defect.rangeBand()+ barPadding)/2); 
 
    var y_label = height + 80; 
 
    return "translate(" + x_label + "," + y_label + ")"; 
 
    }) 
 
    .text(function(d) { 
 
    return d.key; 
 
    }) 
 
    .attr('text-anchor', 'middle'); 
 

 
// lines to separate each category_g1 labels 
 

 
category_g1.append("line") 
 
.attr("x1", function(d) { 
 
    return x_category((d.valueLength2* x_defect.rangeBand()+ barPadding)); 
 
}) 
 
.attr("y1", 0) 
 
.attr("x2", function(d) { 
 
    return x_category((d.valueLength2 * x_defect.rangeBand()+ barPadding)); 
 
}) 
 
.attr("y2", 80) 
 
.attr("transform", function(d) { 
 
    var x_label = 0; 
 
    var y_label = height; 
 
    return "translate(" + x_label + "," + y_label + ")"; 
 
    }) 
 
.style("stroke-width", 1) 
 
.style("stroke", "blue") 
 
.style("fill", "none"); 
 

 

 
// lables for category_g2 
 
var category_label2 = category_g2.selectAll(".category-label2") 
 
    .data(function(d) { 
 
    return [d]; 
 
    }) 
 
    .enter().append("text") 
 
    .attr("class", function(d) { 
 
    return 'category-label category-label2-' + d.key; 
 
    }) 
 
    .attr("transform", function(d) { 
 
    var x_label = x_category((d.values.length * x_defect.rangeBand())/2); 
 
    var y_label = height + 50; 
 
    return "translate(" + x_label + "," + y_label + ")"; 
 
    }) 
 
    .text(function(d) { 
 
    return d.key; 
 
    }) 
 
    .attr('text-anchor', 'middle'); 
 

 

 
// lines to separate each category_g2 labels 
 

 
category_g2.append("line") 
 
.attr("x1", function(d) { 
 
    return x_category((d.values.length* x_defect.rangeBand()+ barPadding)); 
 
}) 
 
.attr("y1", 0) 
 
.attr("x2", function(d) { 
 
    return x_category((d.values.length * x_defect.rangeBand()+ barPadding)); 
 
}) 
 
.attr("y2", 60) 
 
.attr("transform", function(d) { 
 
    var x_label = 0; 
 
    var y_label = height; 
 
    return "translate(" + x_label + "," + y_label + ")"; 
 
    }) 
 
.style("stroke-width", 1) 
 
.style("stroke", "black") 
 
.style("fill", "none"); 
 

 

 
// lables for defect_g 
 
var defect_g = category_g2.selectAll(".defect") 
 
    .data(function(d) { 
 
    return d.values; 
 
    }) 
 
    .enter().append("g") 
 
    .attr("class", function(d) { 
 
    return 'defect defect-' + d.key; 
 
    }) 
 
    .attr("transform", function(d, i) { 
 
    return "translate(" + x_category((i * x_defect.rangeBand())) + ",0)"; 
 
    }); 
 

 
var defect_label = defect_g.selectAll(".defect-label") 
 
    .data(function(d) { 
 
    return [d]; 
 
    }) 
 
    .enter().append("text") 
 
    .attr("class", function(d) { 
 
    
 
    return 'defect-label defect-label-' + d.key; 
 
    }) 
 
    .attr("transform", function(d) { 
 
    var x_label = x_category((x_defect.rangeBand() + barPadding)/2); 
 
    var y_label = height + 10; 
 
    return "translate(" + x_label + "," + y_label + "),rotate(-90)"; 
 
    }) 
 
    .text(function(d) { 
 
    return d.key; 
 
    }) 
 
    .attr('text-anchor', 'middle'); 
 

 

 
var rects = defect_g.selectAll('.rect') 
 
    .data(function(d) { 
 
    return [d]; 
 
    }) 
 
    .enter().append("rect") 
 
    .attr("class", "rect") 
 
    .attr("width", x_category(x_defect.rangeBand() - barPadding)) 
 
    .attr("x", function(d) { 
 
    return x_category(barPadding); 
 
    }) 
 
    .attr("y", function(d) { 
 
    return y(d.value); 
 
    }) 
 
    .attr("height", function(d) { 
 
    return height - y(d.value); 
 
    }); 
 

 

 
// to display values on top of bar chart 
 
    defect_g.selectAll("text.bar") 
 
     .data(function(d) { 
 
    
 
    return [d]; 
 
    }) 
 
    .enter().append("text") 
 
     .attr("class", "rect1") 
 
     .attr("text-anchor", "middle") 
 
     .attr("x", function(d) { return x_category(x_defect.rangeBand()-barPadding)/2; }) 
 
     .attr("y", function(d) { return y(d.value); }) 
 
     .text(function(d) { return d.value+"%"; });
<!DOCTYPE html> 
 
<html> 
 

 
    <head> 
 
    <script data-require="[email protected]" data-semver="3.5.3" src="https://d3js.org/d3.v3.min.js"></script> 
 
    <link rel="stylesheet" href="style.css" /> 
 
    
 
    </head> 
 

 
    <body> 
 
    <script src="script2.js"></script> 
 
    </body> 
 

 
</html>

回答

1

我想rotating labels将做好与区域不重叠。

svg.append("g") 
    .attr("class", "x axis") 
    .attr("transform", "translate(0," + height + ")") 
    .call(xAxis) 
    .selectAll("text") 
    .attr("y", 0) 
    .attr("x", 9) 
    .attr("dy", ".35em") 
    .attr("transform", "rotate(90)") 
    .style("text-anchor", "start"); 

,或者为了wrap text

svg.append("g") 
     .attr("class", "x axis") 
     .attr("transform", "translate(0," + height + ")") 
     .call(xAxis) 
    .selectAll(".tick text") 
     .call(wrap, x.rangeBand()); 

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

下面是示例:

  1. 旋转轴标签:http://bl.ocks.org/mbostock/4403522
  2. 包装轴标签:https://bl.ocks.org/mbostock/7555321
+0

如果我们旋转每个级别的标签,图形看起来不太好。如果我们旋转每个级别的标签,我们很难理解哪个组属于哪一个。 – Mounika

+0

好吧,我也回答了如何在上面的答案 – SiddP

+0

中包装轴标签换行符将标签名称作为以空格分隔的单词组合 – Mounika