如何在D3中的水平条形图上的X轴上添加一条线 [英] How to add a line on x-axis on a horizontal bar chart in d3
问题描述
我想在水平条形图上添加一条类似于图像的线,在这种情况下,该线应在x轴上代表270,但出现错误无效的路径属性.这是
此处不需要 d3.svg.line()
.只需创建一条简单的线:
var lineEnd = 270;var line = svg.append("line").attr("x1",lineEnd).attr("x2",lineEnd).attr("y1",0).attr("y2",高度).attr("stroke-width",8).attr("stroke","black").attr("stroke-dasharray","8,8");
这是个笨蛋: http://plnkr.co/edit/dOhZjRvBHzFqWFByerKH?p=preview
PS:在x轴上不是270,在SVG上仅为270px.现在,您无法使用 x
作为比例,因为没有域.为 x
设置一个域,并使用它来设置条形的宽度.
首先,摆脱这一点:
var max_n = 0;var category = []为(信息中的var d){max_n = Math.max(info [d] .value,max_n);category.push(info [d] .name)}var dx = width/max_n;var dy =高度/信息长度;
现在,设置比例尺:
var y = d3.scale.ordinal().domain(info.map(function(d){return d.name})).rangeRoundBands([0,height],.1);var x = d3.scale.linear().range([0,宽度]).domain([0,d3.max(info,function(d){return d.value})])
然后将这些比例尺用于您的酒吧:
.attr("x",0).attr("y",function(d){return y(d.name)}).attr("width",function(d){return x(d.value)}).attr("height",y.rangeBand())
所有这些纠正后,现在,我们可以在刻度中使用270:
var line = svg.append("line").attr("x1",function(){return x(lineEnd)}).attr("x2",function(){return x(lineEnd)}).attr("y1",0).attr("y2",高度).attr("stroke-width",6).attr("stroke","black").attr("stroke-dasharray","8,8")
以下是更新的插件: http://plnkr.co/edit/gtPA12qSf9mBoAY6MeDd?p=预览
I would like to add a line on my horizontal bar chart something like the image, the line should represent 270 on x-axis in this case, but I get the error invalid path attribute. Here is the plunker code:
var info = [
{name: "Walnuts", value:206},
{name: "Almonds", value:332}
];
/* Set chart dimensions */
var width = 960,
height = 500,
margin = {top:10, right:10, bottom:20, left:60};
//subtract margins
width = width - margin.left - margin.right;
height = height - margin.top - margin.bottom;
//sort data from highest to lowest
info = info.sort(function(a, b){ return b.value - a.value; });
//Sets the y scale from 0 to the maximum data element
var max_n = 0;
var category = []
for (var d in info) {
max_n = Math.max(info[d].value, max_n);
category.push(info[d].name)
}
var dx = width / max_n;
var dy = height / info.length;
var y = d3.scale.ordinal()
.domain(category)
.rangeRoundBands([0, height], .1);
var x = d3.scale.linear()
.range([0, width]);
var yAxis = d3.svg.axis()
.scale(y)
.orient('left')
var svg = d3.select("#chart")
.append("svg")
.attr("width", "100%")
.attr("height", "100%")
.attr('preserveAspectRatio', 'xMidYMin')
.attr("viewBox", '0 0 ' + parseInt(width + margin.left + margin.right) + ' ' + parseInt(height + margin.top + margin.bottom))
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
svg.selectAll(".bar")
.data(info)
.enter()
.append("rect")
.attr("class", function(d, i) {return "bar" + d.name;})
.attr("x", function(d, i) {return 0;})
.attr("y", function(d, i) {return dy*i;})
.attr("width", function(d, i) {return dx*d.value})
.attr("height", dy)
.attr("fill", function(d, i){
if(d.name == 'Walnuts') {return 'red'} else {return 'green'}
});
var y_xis = svg.append('g')
.attr('id','yaxis')
.call(yAxis);
var lineEnd = 270;
var line = d3.svg.line()
line
.x(function(d, i) {
return x(d.value) + i; })
.y(function(d, i) { return lineEnd; });
svg.append("path")
.datum(info)
.attr("class", "line")
.attr("d", line);
You don't need d3.svg.line()
here. Just create a simple line:
var lineEnd = 270;
var line = svg.append("line")
.attr("x1", lineEnd)
.attr("x2", lineEnd)
.attr("y1", 0)
.attr("y2", height)
.attr("stroke-width", 8)
.attr("stroke", "black")
.attr("stroke-dasharray", "8,8");
This is the plunker: http://plnkr.co/edit/dOhZjRvBHzFqWFByerKH?p=preview
PS: This is not 270 on x-axis, this is simply 270px on the SVG. Right now you cannot use x
as a scale because there is no domain. Set a domain for x
and use it to set the width of your bars.
First, get rid of this:
var max_n = 0;
var category = []
for (var d in info) {
max_n = Math.max(info[d].value, max_n);
category.push(info[d].name)
}
var dx = width / max_n;
var dy = height / info.length;
Now, set the scales:
var y = d3.scale.ordinal()
.domain(info.map(function(d){ return d.name}))
.rangeRoundBands([0, height], .1);
var x = d3.scale.linear()
.range([0, width])
.domain([0, d3.max(info, function(d){return d.value})])
And then use these scales for your bars:
.attr("x", 0)
.attr("y", function(d){ return y(d.name)})
.attr("width", function(d) {return x(d.value)})
.attr("height", y.rangeBand())
With all these corrected, now we can use 270 in the scale:
var line = svg.append("line")
.attr("x1", function(){ return x(lineEnd)})
.attr("x2", function(){ return x(lineEnd)})
.attr("y1", 0)
.attr("y2", height)
.attr("stroke-width", 6)
.attr("stroke", "black")
.attr("stroke-dasharray", "8,8")
Here is the updated plunker: http://plnkr.co/edit/gtPA12qSf9mBoAY6MeDd?p=preview
这篇关于如何在D3中的水平条形图上的X轴上添加一条线的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!