Javascript 通过在d3中的条上方保持顶部记号来限制Y轴记号的数量
在我的d3条形图中,如果在最后一个刻度线上方,我应该在最高的条形图上方有一个顶部Y轴刻度线(带有水平网格线)。这是通过计算最后一个勾号来实现的,然后使用Javascript 通过在d3中的条上方保持顶部记号来限制Y轴记号的数量,javascript,html,css,d3.js,svg,Javascript,Html,Css,D3.js,Svg,在我的d3条形图中,如果在最后一个刻度线上方,我应该在最高的条形图上方有一个顶部Y轴刻度线(带有水平网格线)。这是通过计算最后一个勾号来实现的,然后使用tickValues()应用 此外,包括x轴域(0)在内,最多应有5个记号和网格线。我使用了ticks()尝试了这一点,但它不适用于tickValues()。有什么解决办法吗 // container size var margin = {top: 10, right: 10, bottom: 30, left: 30}, width = 400
tickValues()
应用
此外,包括x轴域(0)在内,最多应有5个记号和网格线。我使用了ticks()
尝试了这一点,但它不适用于tickValues()
。有什么解决办法吗
// container size
var margin = {top: 10, right: 10, bottom: 30, left: 30},
width = 400,
height = 300;
var data = [
{"month":"DEC","setup":{"count":26,"id":1,"label":"Set Up","year":"2016","graphType":"setup"}},
{"month":"JAN","setup":{"count":30,"id":1,"label":"Set Up","year":"2017","graphType":"setup"}},
{"month":"FEB","setup":{"count":30,"id":1,"label":"Set Up","year":"2017","graphType":"setup"}}];
var name = 'dashboard';
// x scale
var xScale = d3.scale.ordinal()
.rangeRoundBands([0, width], 0.2);
// set x and y scales
xScale.domain(data.map(function(d) { return d.month; }));
// x axis
var xAxis = d3.svg.axis()
.scale(xScale)
.orient('bottom')
.outerTickSize(0);
var yScale = d3.scale.linear()
.domain([0, d3.max(data, function(d) {
return d.setup.count;
})])
.range([height, 0]);
var ticks = yScale.ticks(),
lastTick = ticks[ticks.length-1];
var newLastTick = lastTick + (ticks[1] - ticks[0]);
if (lastTick < yScale.domain()[1]){
ticks.push(lastTick + (ticks[1] - ticks[0]));
}
// adjust domain for further value
yScale.domain([yScale.domain()[0], newLastTick]);
// y axis
var yAxis = d3.svg.axis()
.scale(yScale)
.orient('left')
.tickSize(-width, 0, 0)
.tickFormat(d3.format('d'))
.tickValues(ticks);
// create svg container
var svg = d3.select('#chart')
.append('svg')
.attr('class','d3-setup-barchart')
.attr('width', width + margin.left + margin.right)
.attr('height', height + margin.top + margin.bottom)
.append('g')
.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');
//.on('mouseout', tip.hide);
// apply tooltip
//svg.call(tip);
// Horizontal grid (y axis gridline)
svg.append('g')
.attr('class', 'grid horizontal')
.call(d3.svg.axis()
.scale(yScale)
.orient('left')
.tickSize(-width, 0, 0)
.tickFormat('')
.tickValues(ticks)
);
// create bars
var bars = svg.selectAll('.bar')
.data(data)
.enter()
.append('g');
bars.append('rect')
.attr('class', function(d,i) {
return 'bar';
})
.attr('id', function(d, i) {
return name+'-bar-'+i;
})
.attr('x', function(d) { return xScale(d.month); })
.attr('width', xScale.rangeBand())
.attr('y', function(d) { return yScale(d.setup.count); })
.attr('height', function(d) { return height - yScale(d.setup.count); })
.on('click', function(d, i) {
d3.select(this.nextSibling)
.classed('label-text selected', true);
d3.select(this)
.classed('bar selected', true);
d3.select('#'+name+'-axis-text-'+i)
.classed('axis-text selected', true);
});
//.on('mouseover', tip.show)
//.on('mouseout', tip.hide);
// apply text at the top
bars.append('text')
.attr('class',function(d,i) {
return 'label-text';
})
.attr('x', function(d) { return xScale(d.month) + (xScale.rangeBand()/2) - 10; })
.attr('y', function(d) { return yScale(d.setup.count) + 2 ; })
.attr('transform', function() { return 'translate(10, -10)'; })
.text(function(d) { return d.setup.count; });
// draw x axis
svg.append('g')
.attr('id', name+'-x-axis')
.attr('class', 'x axis')
.attr('transform', 'translate(0,' + height + ')')
.call(xAxis);
// apply class & id to x-axis texts
d3.select('#'+name+'-x-axis')
.selectAll('text')
.attr('class', function(d,i) {
return 'axis-text';
})
.attr('id', function(d,i) { return name+'-axis-text-' + i; });
// draw y axis
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');
// remove 0 in y axis
svg.select('.y')
.selectAll('.tick')
.filter(function (d) {
return d === 0 || d % 1 !== 0;
}).remove();
svg
.select('.horizontal')
.selectAll('.tick')
.filter(function (d) {
return d === 0 || d % 1 !== 0;
}).remove();
//容器大小
var margin={顶部:10,右侧:10,底部:30,左侧:30},
宽度=400,
高度=300;
风险值数据=[
{“月份”:“十二月”,“设置”:{“计数”:26,“id”:1,“标签”:“设置”,“年份”:“2016”,“图形类型”:“设置”},
{“月”:“一月”,“设置”:{“计数”:30,“id”:1,“标签”:“设置”,“年份”:“2017”,“图形类型”:“设置”},
{“月份”:“二月”,“设置”:{“计数”:30,“id”:1,“标签”:“设置”,“年份”:“2017”,“图形类型”:“设置”}];
变量名称='仪表板';
//x刻度
var xScale=d3.scale.ordinal()
.rangeRoundBands([0,宽度],0.2);
//设置x和y刻度
domain(data.map(函数(d){returnd.month;}));
//x轴
var xAxis=d3.svg.axis()
.scale(xScale)
.orient('底部')
.outerTickSize(0);
var yScale=d3.scale.linear()
.domain([0,d3.max(数据,函数(d){
返回d.setup.count;
})])
.范围([高度,0]);
var ticks=yScale.ticks(),
lastTick=ticks[ticks.length-1];
var newLastTick=lastTick+(ticks[1]-ticks[0]);
if(lastTick
正如我在我的中告诉您的,如果您使用D3 v4.x,这将非常容易:您可以简单地使用D3.ticks
或D3.range
设置tickValues
但是如果你想坚持使用D3V3,有一个解决方案
在您的情况下,默认方法是使用scale.ticks
设置滴答数。然而,正如API所说
如果count是一个数字,那么将返回大约count个记号。如果未指定计数,则默认为10。指定的计数只是一个提示;比例可能返回更多或更少的值,具体取决于输入域。(强调矿山)
因此,您不能在此处使用scale.ticks
来设置5个刻度的固定数字
因此,我的解决方案包括创建自己的函数来计算滴答声。一点也不复杂。就是这样:
function createTicks(start, stop, count) {
var difference = stop - start;
var steps = difference / (count - 1);
var arr = [start];
for (var i = 1; i < count; i++) {
arr.push(~~(start + steps * i))
}
return arr;
}
(如果您愿意,您可以保留您的数学以获得新的最后一个刻度,我只是展示了一种不同的方法来设置域的最大值,它不同于数据中的最大值)
然后,我们定义y轴的记号:
var axisTicks = createTicks(yScale.domain()[0], yScale.domain()[1], 5);
在您的域中使用我们的自定义函数,它将返回以下数组:
[0, 8, 16, 24, 33]
然后,只需在axis.tickValues
中使用该数组即可
这是你最新的小提琴:
这里是堆栈片段中的相同代码:
//容器大小
var保证金={
前10名,
右:10,,
底数:30,
左:30
},
宽度=400,
高度=300;
风险值数据=[{
“月”:“十二月”,
“设置”:{
“计数”:26,
“id”:1,
“标签”:“设置”,
“年份”:“2016年”,
“图形类型”:“设置”
}
}, {
“月”:“一月”,
“设置”:{
“计数”:30,
“id”:1,
[0, 8, 16, 24, 33]