d3 axis tick alignment - d3.js

I have a d3 bar chart with, and the axis tick marks are centered below the bars (as I would expect). In this case, I would actually like to left align the axis ticks and have the ticks under the left edge of the bar. Is that possible?
EDIT: Javascript for constructing the axis
// note width is just the width of the chart
var xScale = d3.scale.ordinal().rangeRoundBands([0,width], .1);
var xAxis = d3.svg.axis().scale(xScale).orient("bottom");

here is an example of left aligning the ticks.
http://bl.ocks.org/mbostock/6186172
the idea is that after you create the ticks you collect them and aligne them:
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis)
.selectAll("text")
.attr("y", 6)
.attr("x", 6)
.style("text-anchor", "start");

Why not just create a new scale?
var padding = .1;
var axisScale = d3.scale.linear()
.domain([0, n])
.range([0 + padding, WIDTH + padding]);
Where n is the number of bars in your histogram.

I think that this should be adjusted when you add the axis to your graph.
Try (assuming your graph is called svg):
var bandSize = xScale.rangeBand();
svg.append("svg:g")
.attr("transform", "translate(-" + bandSize + "," + h + ")")
.call(xAxis)
.selectAll("text")
.style("text-anchor", "start")
.attr("transform", "translate(" + bandSize + ", 0)");
In my experiments, this shifts the ticks to the start of each band, and retains the text centered under each band.

Related

D3 Pie Chart rotate only the arcs

My chart needs a label in the center of the donut that should not rotate when clicked.
https://codepen.io/scratchy303/pen/dyXMzrz
Can I append the label in a sibling "g"roup and rotate the arcs group?
Can I translate just the arcs rather than rotating the entire SVG?
What's the simplest solution?
var svg = d3.select("#pieChart").append("svg")
.attr("width", '100%')
.attr("height", '100%')
.attr('viewBox', '0 0 ' + Math.min(width, height) + ' ' + Math.min(width, height))
.attr('preserveAspectRatio', 'xMinYMin')
.append("g")
.attr("transform", "translate(" + radius + "," + height / 2 + ")")
.style("filter", "url(#drop-shadow)");
svg.append("g")
.append("text")
.attr("text-anchor", "middle")
.text("Donut Name");
I found a solution by counter-rotating my text. My biggest hurdle was simply traversing my SVG in D3.
//start by selecting the parent "g"roup and then you can select the text
d3.select(i.parentNode).select(".donut-label")
.transition()
.duration(1000)
.attr("transform", "rotate(" + (-angle) + ")");

D3JS: unable to set only 5 ticks in x Axis

I've been unable to set only 5 ticks on my x Axis, by default it set 10 ticks, multiples of 5, I tried to use ´.ticks(5)´ but it's not working for me. If if visualize the chart on mobile, 10 ticks becomes almost unreadable. But as I mentioned ´.ticks(5)´ it's not working
this is the snippet which draws the x axis:
var xAxis = svg.append("g")
.style("font-size", textSetter())
.attr("class", "xAxis", "axis")
.attr("transform", "translate(" + 0 + "," + heightTwo + ")")
.call(d3.axisBottom(xScale).ticks(5)
.tickPadding(5).tickFormat(d => d + "%"))
How can I solve this? Thanks
You could set all the text in the axis to a particular class and then hide the ticks based on the number for example.
//Create the xAxis and assign x-axisticks class to the tick text
var xAxis = svg.append("g")
.style("font-size", textSetter())
.attr("class", "xAxis", "axis")
.attr("transform", "translate(" + 0 + "," + heightTwo + ")")
.call(d3.axisBottom(xScale)
.selectAll('text')
.attr('class', 'x-axisticks');
//remove the ticks which based on the multiples
var xticks = d3.selectAll('.x-axisticks');
xticks.attr('class', function (d, i) {
i = i + 1;
if (i % 5 !== 0) d3.select(this).remove();
});
Hope this helps. A more specific use-case answer would probably require some more code to be posted from your end so that I can tailor an answer, but this should work.

D3 - Position second x axis labels

I have a stackblitz here - https://stackblitz.com/edit/d3-stacked-trend-bar-positioned-months-1b93nz?file=src%2Fapp%2Fbar-chart.ts
I have a stacked bar chart using D3 in Angular.
I'm trying to position a second axis of labels on the x axis.
Currently I'm using the with of the graph but this means the labels dont line up correctly with the bars.
Is there a better D3 way to add these labels and positino them.
Use the x-position of the bars and position the text in the middle of it.
private drawBarTitle(data:any){
this.chart.append('g')
.attr("transform", "translate(" + 10 + "," + (this.height+10) + ")")
.selectAll('g')
.data(data)
.enter()
.append('g')
.attr('transform', (d:any, i:any)=>{
var x = this.x(d.date) + (i%2) * 0.525 * this.x.bandwidth();
return "translate(" + (x + this.x.bandwidth()*0.95*0.25) + "," + 0 + ")"
})
.append('text')
.text((d:any, i:any)=>{ return d.type; })
.attr("dy", "-0.3em")
.classed('trend-type', true)
.style("text-anchor", "end")
.attr("transform", "rotate(-90)");
}

Cut off gridline at the end in d3.js

I'd like to cut off the grid line at the end of the graph. If I remove the padding in xScale, then the end tick "2016"'s "16" will be cut off.
Which part should I fix, yScale, xScale, or the gridline?
//Define X axis
xAxis = d3.axisBottom()
.scale(xScale)
.ticks(10)
.tickFormat(formatTime);
//Define Y axis
yAxis = d3.axisLeft()
.scale(yScale)
.ticks(5);
//Define Y axis gridlines
function make_y_gridlines() {
return d3.axisLeft(yScale)
}
//Create axes
svg.append("g")
.attr("class", "axis x")
.attr("transform", "translate(0," + (h - padding) + ")")
.call(xAxis);
svg.append("g")
.attr("class", "axis y")
.attr("transform", "translate(" + padding + ",0)")
.call(yAxis);
// add the Y gridlines
svg.append("g")
.attr("class", "grid")
.attr("transform", "translate(" + padding + ",0)")
.call(make_y_gridlines()
.tickSize(-w)
.tickFormat("")
)
As the x-axis is defined with:
.range([padding, w - padding * 2])
This means, the graph begins at 1 * padding from the left of the svg container and ends at width - 2 * padding from the left. Which means the width of the graph (as opposed to the width of the svg container) is width - 3 * padding.
Thus the actual size of the y grid lines should be width - 3 * padding.
In the code, this means that you can just replace the ticksize in the definition of the y gridlines:
.tickSize(-w)
with:
.tickSize(-w + 3*padding)
It's -(w-3*padding) since the ticks by default are going to the left of the y axis and here we want them to the right.

Yaxis and xAxis position [duplicate]

I am using d3.js for scatter plot,I want to plot x and y axis such that they intersect at point(100,75).how to do this?
I am using
svg.append("g")
.attr("class", "axis")
.attr("transform", "translate(0," + (padding+223) + ")")
.call(xAxis2);
//Create Y2 axis
svg.append("g")
.attr("class", "axis")
.attr("transform", "translate(" + (padding+200) + ",0)")
.call(yAxis2);
But this will not change according to the scale,and I have used variable for scale.
Please let me know if you need more information.
You would need to offset the axes by the respective amount, which you can determine using the scales of the axes, i.e.
svg.append("g")
.attr("class", "axis")
.attr("transform", "translate(0," + yScale(75) + ")")
.call(xAxis2);
and similarly for the y axis. You may have to tweak the offset slightly to account for other offsets, labels etc.

Resources