I'm currently using the following code to set the number of ticks on my time-based x-axis to 5; however, every single tick continues to display regardless of what number I insert within "ticks()".
The code I'm using to set the number of ticks to 5
let xAxisLower = d3.axisBottom(x)
.ticks(5)
.tickFormat(d3.timeFormat("%m-%d"))
.tickPadding(15);
How do I set the number of ticks on the x-axis to 5 and why can't I do so with .ticks(5)?
The JavaScript code (refer to JSFiddle for further detail)
tradeArr = [
{date: "2017-06-15" , bps: 0},
{date: "2017-06-14" , bps: 0},
{date: "2017-06-13" , bps: 0},
{date: "2017-06-12" , bps: 0},
{date: "2017-06-09" , bps: 0},
{date: "2017-06-08" , bps: 0},
{date: "2017-06-07" , bps: 0},
{date: "2017-06-06" , bps: 0},
{date: "2017-06-05" , bps: 0},
{date: "2017-06-02" , bps: 0},
{date: "2017-06-01" , bps: 13.9},
{date: "2017-05-31" , bps: 0},
{date: "2017-05-30" , bps: 0},
{date: "2017-05-29" , bps: 0},
{date: "2017-05-26" , bps: 0},
{date: "2017-05-25" , bps: 0},
{date: "2017-05-24" , bps: 0},
{date: "2017-05-23" , bps: 0},
{date: "2017-05-22" , bps: 0},
{date: "2017-05-19" , bps: 0},
{date: "2017-05-18" , bps: 0},
{date: "2017-05-17" , bps: 0},
{date: "2017-05-16" , bps: 1.95},
{date: "2017-05-15" , bps: 0},
{date: "2017-05-12" , bps: 0}
];
tradeArr.forEach(obj => {
obj.date = d3.timeParse("%Y-%m-%d")(obj.date);
})
generateBarChart(tradeArr);
function generateBarChart(data) {
console.log(data);
// chart configuration
let margin = {
top: 20,
right: 20,
bottom: 30,
left: 50
};
let width;
let height;
let x = d3.scaleBand()
.domain(data.map(function(d) { return d.date; }));
let y = d3.scaleLinear()
.domain([d3.min(data, function(d) { return d.bps; }), d3.max(data, function(d) { return d.bps; })])
let xAxisLower = d3.axisBottom(x)
.ticks(5)
.tickFormat(d3.timeFormat("%m-%d"))
.tickPadding(15);
let yAxis = d3.axisLeft(y)
.ticks(2)
.tickSize(0)
.tickPadding(15);
let svg = d3
.select("#price-chart-graph")
.style("position", "relative") // strictly for the tooltip
.append("svg") // append an svg to the div
.style("overflow", "hidden")
.style("position", "relative");
let artboard = svg
.append("g")
.attr("transform", "translate(" + margin.left + ", " + margin.right + ")");
let xAxisLowerEl = artboard.append("g") // x-axis
.attr("class", "x-axis")
.style("font-size", "14px");
let yAxisEl = artboard.append("g") // y-axis
.attr("class", "y-axis")
.style("font-size", "14px");
let bars = artboard.selectAll(".bar")
.data(data)
.enter().append("rect")
.style("fill", "black")
function drawChart() {
width = parseInt(d3.select("#price-chart-graph").style("width")) - margin.left - margin.right;
height = parseInt(d3.select("#price-chart-graph").style("height")) - margin.top - margin.bottom;
svg.attr("width", width + margin.left + margin.right) // give it width
svg.attr("height", height + margin.top + margin.bottom) // give it height
x.rangeRound([0, width], .05).padding(0.1);
y.range([height, 0]);
// call new x axis
xAxisLowerEl.attr("transform", "translate(0," + height + ")").call(xAxisLower);
yAxisEl.call(yAxis);
bars
.attr("x", function(d) { return x(d.date); })
.attr("width", function(d) { return x.bandwidth()})
.attr("y", function(d) { return y(d.bps); })
.attr("height", function(d) { return height - y(d.bps); })
}
drawChart();
window.addEventListener('resize', drawChart);
}
Your x-axis is of type scaleBand
, and ticks()
doesn't work on banded axes. From the documentation:
This method has no effect if the scale does not implement scale.ticks, as with band and point scales
You can however explicitly set the values with tickValues()
, so you can try filtering the domain down to five values and setting manually. This may get you in the right direction:
let tickInterval = 5;
let tickValues = data.map(function(d) { return d.date; }).filter(function(d, i) { return i % tickInterval === 0 });
let xAxisLower = d3.axisBottom(x)
.tickFormat(d3.timeFormat("%m-%d"))
.tickValues(tickValues)
.tickPadding(15);
You might need to tweak tickInterval
to fit the length of your data, but that should be a start.