2016-08-08 204 views
1

我使用d3.js绘制条形图。我想在两个输入值之间显示条形图,但以字符串值的形式显示,而不是x轴上的整数值。使用d3的水平条形图js

[![什么我想才达到] [1]的一个例子] [1]

变种y轴= [ '配件', '发烧', '相机&照片',“细胞电话','电脑','电子书阅读器'];

var x-axis = ['development','design','testing','UAT','LiveDeployment'];

我所使用

参考URL是[D3 JS简单水平条形图] [2]下面

代码家道设有: 1)使用单杠D3 JS和自定义x轴标签 2)显示X - 轴行文本换行:(2016年1月1日生产开始日) 3)显示y轴行文本换行(类别1Category 1Category 1Category 1)

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

data = [ 
    {label:"Category 1Category 1Category 1", value:25}, 
    {label:"Category 2", value:50}, 
    {label:"Category 3", value:100}, 
    {label:"Category 4", value:75}, 
    {label:"Category 5", value:40}, 
    {label:"Category 6", value:20} 
]; 

var axisMargin = 10, 
margin = 20, 
valueMargin = 2, 
width = parseInt(d3.select('#barchart').style('width'), 9), 
height = parseInt(d3.select('body').style('height'), 9), 
barHeight = (height-axisMargin-margin*2)* 0.6/data.length, 
barPadding = (height-axisMargin-margin*2)*0.4/data.length, 
data, bar, svg, scale, scale2, xAxis, labelWidth = 0; 

max = d3.max(data, function(d) { return d.value; }); 

svg = d3.select('#barchart') 
     .append("svg") 
     .attr("width", width) 
     .attr("height", height); 


bar = svg.selectAll("g") 
     .data(data) 
     .enter() 
     .append("g"); 

bar.attr("class", "bar") 
     .attr("cx",0) 
     .attr("transform", function(d, i) { 
      return "translate(" + margin + "," + (i * (barHeight + barPadding) + barPadding) + ")"; 
     }); 

bar.append("text") 
     .attr("class", "label") 
     .attr("y", barHeight/2) 
     .attr("dy", ".35em") //vertical align middle 
     .text(function(d){ 
      return d.label; 
     }).each(function() { 
      labelWidth = 150; //Math.ceil(Math.max(labelWidth, this.getBBox().width)); 
     }) 
     .call(wrap, 150); 


scale = d3.scale.linear() 
     .domain([0, max]) 
     .range([0, width - margin*2 - labelWidth]); 

/*scale = d3.scale.linear() 
     .domain([0, max]) 
     .range([0, width - margin*2 - labelWidth]); 

xAxis = d3.svg.axis() 
     .scale(scale) 
     .tickSize(-height + 2*margin + axisMargin); 
     .orient("bottom");*/ 

var scale2 = d3.scale.ordinal() 
     .domain(["01/01/2016 Production Start Date", "01/01/2016 Production End Date", "Transcoding", "Encryption", "Published", "Published Release Date"]) 
     .rangePoints([0, width - margin*2 - labelWidth]); 

var xAxis = d3.svg.axis() 
     .scale(scale2) 
     .tickSize(-height + 2*margin + axisMargin) 
     .orient("bottom");   

bar.append("rect") 
    .attr("transform", "translate("+labelWidth+", 0)") 
    .attr("height", barHeight) 
    .attr("width", function(d){ 
     return scale(d.value); 
}); 

bar.append("text") 
    .attr("class", "value") 
    .attr("y", barHeight/2) 
    .attr("dx", -valueMargin + labelWidth) //margin right 
    .attr("dy", ".35em") //vertical align middle 
    .attr("text-anchor", "end") 
    .text(function(d){ 
      return (d.value+"%"); 
     }) 
    .attr("x", function(d){ 
     var width = this.getBBox().width; 
     return Math.max(width + valueMargin, scale(d.value)); 
}); 

svg.insert("g",":first-child") 
     .attr("class", "axisHorizontal") 
     .attr("transform", "translate(" + (margin + labelWidth) + ","+ (height - axisMargin - margin)+")") 
     .call(xAxis) 
     .selectAll(".tick text") 
     .call(wrap, 100); 
+1

我可以推荐c3.js.它使用D3,但更容易处理。 –

回答

2

你当然可以格式化蜱,但有一个简单的解决方法:创建另一个规模只是为蜱,并称之为替代规模为你的x轴:

var xScaleString = d3.scale.ordinal() 
     .domain(["design", "development", "testing", "UAT"]) 
     .rangePoints([0, width]); 

使用这种非同寻常做法的好处是,你可以传播琴弦沿x轴你想要的方式。缺点是你可能没有完全匹配你的原始比例值(10,20,30等)。

请记住保留您的原始比例(这是用于矩形的比例)。

+0

是的,我已经尝试过使用它,现在似乎工作。这里要求的功能更多。你能否相应更新代码 1)显示x轴线。 2)X轴文本的大小很大,所以我需要把它分成两行。 请参考问题中给出的代码。 –

+0

为了显示轴,就像你称之为原始的一样。为了包装长文本,你需要一个像这样的函数:https://bl.ocks.org/mbostock/7555321 –

+1

谢谢,我已经完成了这个帮助给定的链接。工作代码在帖子中更新,以便其他需要或有问题的成员可以参考。非常感谢您的支持。 –