条形图条形之间的 d3js 网格线
d3js gridlines between bars for bar charts
我创建了一个简单的 d3js 垂直条形图。我知道通常情况下,要创建网格线,我会使用“tickSize”调用,并给它们一个类似于轴的高度或宽度。
var yGridLine = d3.svg.axis()
.scale(yScale)
.tickSize(-width, 0 ,0)
.tickFormat("")
.orient("left");
以上代码将创建水平网格线。所以如果我想创建垂直网格线,那么我会修改方向和参考轴(类似于以下未经测试但假设正确的代码)
var xGridLine = d3.svg.axis()
.scale(xScale)
.tickSize(-height, 0 ,0)
.tickFormat("");
现在,问题是,当使用这种方法时,垂直网格线是在垂直条的中间创建的(或者在水平条形图的情况下,水平网格线是在水平条的中间创建的)酒吧),这在视觉上并不令人愉快并且不符合要求。我想要的是让垂直网格线出现在 之间 垂直条(即,在刻度线之间的中心点)。我该怎么做?
例子
In this link,您会发现许多图表,其中垂直网格线位于刻度之间,而不是中心。这就是我想要实现的目标,我的问题是如何实现它?
谢谢。
全部代码:
var data = [{
name: "Hemant",
age: 20
}, {
name: "Vinay",
age: 55
}, {
name: "Vikas",
age: 56
}, {
name: "Arun",
age: 88
}, {
name: "Varun",
age: 34
}, {
name: "Ajay",
age: 77
}],
w = 600,
h = 300,
margin = {
top: 20,
right: 20,
bottom: 30,
left: 40
},
width = w - margin.left - margin.right,
height = h - margin.top - margin.bottom;
var mySvg = d3.select("body").append("svg").attr({
width: w,
height: h
}).append("g")
.attr("transform", 'translate(' + margin.left + ',' + margin.top + ')');
var xScale = d3.scale.ordinal()
.domain(data.map(function(d) {
return d.name;
}))
.rangeBands([0, width]);
var yScale = d3.scale.linear()
.domain([0, d3.max(data, function(d) {
return d.age;
})])
.range([height, 0]);
var linearColorScale = d3.scale.linear()
.domain([0, data.length])
.range(["#e74c3c", "#8e44ad"]);
var xAxis = d3.svg.axis()
.scale(xScale)
.orient("bottom");
var yAxis = d3.svg.axis()
.scale(yScale)
.orient("left");
var yGridLine = d3.svg.axis()
.scale(yScale)
.tickSize(-width, 0, 0)
.tickFormat("")
.orient("left");
var ordinalColorScale = d3.scale.category20();
mySvg.append("g")
.classed("gridLine", true)
.attr("transform", "translate(0,0)")
.call(yGridLine);
mySvg.selectAll("rect").data(data).enter()
.append("rect")
.attr("x", function(d) {
return xScale(d.name);
})
.attr("y", function(d, i) {
return yScale(d.age);
})
.attr("width", function(d) {
return xScale.rangeBand();
})
.attr("height", function(d) {
return height - yScale(d.age)
})
.style("fill", function(d, i) {
return ordinalColorScale(i);
})
mySvg.selectAll("text").data(data)
.enter()
.append("text")
.classed("bar", true)
.attr("x", function(d) {
return xScale(d.name) + xScale.rangeBand() / 2;
})
.attr("dx", 0)
.attr("y", function(d, i) {
return yScale(d.age);
})
.attr("dy", -6)
.text(function(d, i) {
return d.age;
});
mySvg.append("g")
.classed("axis", true)
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
mySvg.append("g")
.classed("axis", true)
.attr("transform", "translate(0,0)")
.call(yAxis);
svg {
border: 1px solid #ccc;
}
svg rect {
shape-rendering: crispedges;
}
.bar {
fill: #000;
text-anchor: middle;
font-size: 20px;
}
.axis path,
.axis line {
fill: none;
shape-rendering: crispedges;
stroke: #666;
}
.gridLine path,
.gridLine line {
fill: none;
shape-rendering: crispedges;
stroke: #e4e4e4;
}
<script src="http://d3js.org/d3.v3.min.js"></script>
您可以通过简单地将 .gridLines
翻译成 xScale.rangeBand() / 2
来实现此目的 - 即,一个条形宽度的一半。
var data = [{
name: "Hemant",
age: 20
}, {
name: "Vinay",
age: 55
}, {
name: "Vikas",
age: 56
}, {
name: "Arun",
age: 88
}, {
name: "Varun",
age: 34
}, {
name: "Ajay",
age: 77
}],
w = 600,
h = 300,
margin = {
top: 20,
right: 20,
bottom: 30,
left: 40
},
width = w - margin.left - margin.right,
height = h - margin.top - margin.bottom;
var mySvg = d3.select("body").append("svg").attr({
width: w,
height: h
}).append("g")
.attr("transform", 'translate(' + margin.left + ',' + margin.top + ')');
var xScale = d3.scale.ordinal()
.domain(data.map(function(d) {
return d.name;
}))
.rangeBands([0, width]);
var yScale = d3.scale.linear()
.domain([0, d3.max(data, function(d) {
return d.age;
})])
.range([height, 0]);
var linearColorScale = d3.scale.linear()
.domain([0, data.length])
.range(["#e74c3c", "#8e44ad"]);
var xAxis = d3.svg.axis()
.scale(xScale)
.orient("bottom");
var yAxis = d3.svg.axis()
.scale(yScale)
.orient("left");
var yGridLine = d3.svg.axis()
.scale(xScale)
.tickSize(-height, 0, 0)
.tickFormat("");
var ordinalColorScale = d3.scale.category20();
mySvg.append("g")
.classed("gridLine", true)
.attr("transform", "translate(" + [xScale.rangeBand() / 2, height] + ")")
.call(yGridLine);
mySvg.selectAll("rect").data(data).enter()
.append("rect")
.attr("x", function(d) {
return xScale(d.name);
})
.attr("y", function(d, i) {
return yScale(d.age);
})
.attr("width", function(d) {
return xScale.rangeBand();
})
.attr("height", function(d) {
return height - yScale(d.age)
})
.style("fill", function(d, i) {
return ordinalColorScale(i);
})
mySvg.selectAll("text").data(data)
.enter()
.append("text")
.classed("bar", true)
.attr("x", function(d) {
return xScale(d.name) + xScale.rangeBand() / 2;
})
.attr("dx", 0)
.attr("y", function(d, i) {
return yScale(d.age);
})
.attr("dy", -6)
.text(function(d, i) {
return d.age;
});
mySvg.append("g")
.classed("axis", true)
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
mySvg.append("g")
.classed("axis", true)
.attr("transform", "translate(0,0)")
.call(yAxis);
svg {
border: 1px solid #ccc;
}
svg rect {
shape-rendering: crispedges;
}
.bar {
fill: #000;
text-anchor: middle;
font-size: 20px;
}
.axis path,
.axis line {
fill: none;
shape-rendering: crispedges;
stroke: #666;
}
.gridLine path,
.gridLine line {
fill: none;
shape-rendering: crispedges;
stroke: #e4e4e4;
}
<script src="http://d3js.org/d3.v3.min.js"></script>
我创建了一个简单的 d3js 垂直条形图。我知道通常情况下,要创建网格线,我会使用“tickSize”调用,并给它们一个类似于轴的高度或宽度。
var yGridLine = d3.svg.axis()
.scale(yScale)
.tickSize(-width, 0 ,0)
.tickFormat("")
.orient("left");
以上代码将创建水平网格线。所以如果我想创建垂直网格线,那么我会修改方向和参考轴(类似于以下未经测试但假设正确的代码)
var xGridLine = d3.svg.axis()
.scale(xScale)
.tickSize(-height, 0 ,0)
.tickFormat("");
现在,问题是,当使用这种方法时,垂直网格线是在垂直条的中间创建的(或者在水平条形图的情况下,水平网格线是在水平条的中间创建的)酒吧),这在视觉上并不令人愉快并且不符合要求。我想要的是让垂直网格线出现在 之间 垂直条(即,在刻度线之间的中心点)。我该怎么做?
例子
In this link,您会发现许多图表,其中垂直网格线位于刻度之间,而不是中心。这就是我想要实现的目标,我的问题是如何实现它?
谢谢。
全部代码:
var data = [{
name: "Hemant",
age: 20
}, {
name: "Vinay",
age: 55
}, {
name: "Vikas",
age: 56
}, {
name: "Arun",
age: 88
}, {
name: "Varun",
age: 34
}, {
name: "Ajay",
age: 77
}],
w = 600,
h = 300,
margin = {
top: 20,
right: 20,
bottom: 30,
left: 40
},
width = w - margin.left - margin.right,
height = h - margin.top - margin.bottom;
var mySvg = d3.select("body").append("svg").attr({
width: w,
height: h
}).append("g")
.attr("transform", 'translate(' + margin.left + ',' + margin.top + ')');
var xScale = d3.scale.ordinal()
.domain(data.map(function(d) {
return d.name;
}))
.rangeBands([0, width]);
var yScale = d3.scale.linear()
.domain([0, d3.max(data, function(d) {
return d.age;
})])
.range([height, 0]);
var linearColorScale = d3.scale.linear()
.domain([0, data.length])
.range(["#e74c3c", "#8e44ad"]);
var xAxis = d3.svg.axis()
.scale(xScale)
.orient("bottom");
var yAxis = d3.svg.axis()
.scale(yScale)
.orient("left");
var yGridLine = d3.svg.axis()
.scale(yScale)
.tickSize(-width, 0, 0)
.tickFormat("")
.orient("left");
var ordinalColorScale = d3.scale.category20();
mySvg.append("g")
.classed("gridLine", true)
.attr("transform", "translate(0,0)")
.call(yGridLine);
mySvg.selectAll("rect").data(data).enter()
.append("rect")
.attr("x", function(d) {
return xScale(d.name);
})
.attr("y", function(d, i) {
return yScale(d.age);
})
.attr("width", function(d) {
return xScale.rangeBand();
})
.attr("height", function(d) {
return height - yScale(d.age)
})
.style("fill", function(d, i) {
return ordinalColorScale(i);
})
mySvg.selectAll("text").data(data)
.enter()
.append("text")
.classed("bar", true)
.attr("x", function(d) {
return xScale(d.name) + xScale.rangeBand() / 2;
})
.attr("dx", 0)
.attr("y", function(d, i) {
return yScale(d.age);
})
.attr("dy", -6)
.text(function(d, i) {
return d.age;
});
mySvg.append("g")
.classed("axis", true)
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
mySvg.append("g")
.classed("axis", true)
.attr("transform", "translate(0,0)")
.call(yAxis);
svg {
border: 1px solid #ccc;
}
svg rect {
shape-rendering: crispedges;
}
.bar {
fill: #000;
text-anchor: middle;
font-size: 20px;
}
.axis path,
.axis line {
fill: none;
shape-rendering: crispedges;
stroke: #666;
}
.gridLine path,
.gridLine line {
fill: none;
shape-rendering: crispedges;
stroke: #e4e4e4;
}
<script src="http://d3js.org/d3.v3.min.js"></script>
您可以通过简单地将 .gridLines
翻译成 xScale.rangeBand() / 2
来实现此目的 - 即,一个条形宽度的一半。
var data = [{
name: "Hemant",
age: 20
}, {
name: "Vinay",
age: 55
}, {
name: "Vikas",
age: 56
}, {
name: "Arun",
age: 88
}, {
name: "Varun",
age: 34
}, {
name: "Ajay",
age: 77
}],
w = 600,
h = 300,
margin = {
top: 20,
right: 20,
bottom: 30,
left: 40
},
width = w - margin.left - margin.right,
height = h - margin.top - margin.bottom;
var mySvg = d3.select("body").append("svg").attr({
width: w,
height: h
}).append("g")
.attr("transform", 'translate(' + margin.left + ',' + margin.top + ')');
var xScale = d3.scale.ordinal()
.domain(data.map(function(d) {
return d.name;
}))
.rangeBands([0, width]);
var yScale = d3.scale.linear()
.domain([0, d3.max(data, function(d) {
return d.age;
})])
.range([height, 0]);
var linearColorScale = d3.scale.linear()
.domain([0, data.length])
.range(["#e74c3c", "#8e44ad"]);
var xAxis = d3.svg.axis()
.scale(xScale)
.orient("bottom");
var yAxis = d3.svg.axis()
.scale(yScale)
.orient("left");
var yGridLine = d3.svg.axis()
.scale(xScale)
.tickSize(-height, 0, 0)
.tickFormat("");
var ordinalColorScale = d3.scale.category20();
mySvg.append("g")
.classed("gridLine", true)
.attr("transform", "translate(" + [xScale.rangeBand() / 2, height] + ")")
.call(yGridLine);
mySvg.selectAll("rect").data(data).enter()
.append("rect")
.attr("x", function(d) {
return xScale(d.name);
})
.attr("y", function(d, i) {
return yScale(d.age);
})
.attr("width", function(d) {
return xScale.rangeBand();
})
.attr("height", function(d) {
return height - yScale(d.age)
})
.style("fill", function(d, i) {
return ordinalColorScale(i);
})
mySvg.selectAll("text").data(data)
.enter()
.append("text")
.classed("bar", true)
.attr("x", function(d) {
return xScale(d.name) + xScale.rangeBand() / 2;
})
.attr("dx", 0)
.attr("y", function(d, i) {
return yScale(d.age);
})
.attr("dy", -6)
.text(function(d, i) {
return d.age;
});
mySvg.append("g")
.classed("axis", true)
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
mySvg.append("g")
.classed("axis", true)
.attr("transform", "translate(0,0)")
.call(yAxis);
svg {
border: 1px solid #ccc;
}
svg rect {
shape-rendering: crispedges;
}
.bar {
fill: #000;
text-anchor: middle;
font-size: 20px;
}
.axis path,
.axis line {
fill: none;
shape-rendering: crispedges;
stroke: #666;
}
.gridLine path,
.gridLine line {
fill: none;
shape-rendering: crispedges;
stroke: #e4e4e4;
}
<script src="http://d3js.org/d3.v3.min.js"></script>