Is there a way to justify the text in the X axis to the left? I've tried with .attr("text-anchor", "middle") .attr("text-anchor", "end") .attr("text-anchor", "start") but nothing works, I also tried with css but nothing works.
this is how my X axis looks like
and this is the part of the code that ads the x labels
// Add X axis
var x = d3.scaleBand()
.domain(groups)
.range([0, width])
.padding([0.5]);
svg.append("g")
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(x))
.selectAll("text")
.attr("text-anchor", "middle")
.attr("font-size", "55px")
.attr("y", "-7")
.attr("x", "-45")
.attr("transform", "rotate(-90)");
I don't know if I understood your question properly but it seems you want the x axis text closest to the axis itself am I right?
If that's the question I think your problem is related to the text-anchor atribute.
I would sugest writing .style instead of .attr so the code would look something like this:
.style("text-anchor", "end")
I'll provide this link for you to read so you can understand a bit more how to fix the axis problem and I hope it helps.
If it doesn't work, please let me know.
Related
I'm studying the code made by D3noob for a line chart with mousetracker and tooltip.
This tooltips appear very close to the selected data points.
I am not sure how to do in order to have the tooltip always positionned on the top-left corner of my chart.
The problem here is that the tooltip's coordinates are relative the selected data point's position.
Here is the original link from D3noob:
http://bl.ocks.org/d3noob/6eb506b129f585ce5c8a
I believe that the portion of the code which needs to be changed is:
focus.append("text")
.attr("class", "y2")
.attr("dx", 8)
.attr("dy", "-.3em");
focus.append("text")
.attr("class", "y4")
.attr("dx", 8)
.attr("dy", "1em");
Just create two selections, one for each text element:
var text1 = svg.append("text")
.attr("class", "y1")
.style("opacity", 0.8)
.attr("x", 10)
.attr("y", 30);
var text2 = svg.append("text")
.attr("class", "y3")
.style("opacity", 0.8)
.attr("x", 10)
.attr("y", 40);
And use that in the mousemove function:
text1.text(d.close);
text2.text(formatDate(d.date));
Here is the updated bl.ocks: http://bl.ocks.org/anonymous/64fd748d63f2a0754afbc5dfc62b75e7
I want to append x-axis text label and rotate the x axis labels.
Both works individually but I cant figure out how to use them both together.Can someone please help.
g.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(x))
.selectAll("text") // either this
.style("text-anchor", "end")
.attr("dx", "-.8em")
.attr("dy", ".1em")
.attr("transform", "rotate(-65)")
.append("text")// or this
.attr("x", width)
.attr("y", -6)
.style("text-anchor", "end")
.style("font-weight", "bold")
.style("fill", "black")
.text(tooltipTxt);
In this axis label example, which uses D3 v4, it adds the x axis and the text label as separate nodes under svg.
// Add the x Axis
svg.append("g")
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(x));
// text label for the x axis
svg.append("text")
.attr("transform",
"translate(" + (width/2) + " ," +
(height + margin.top + 20) + ")")
.style("text-anchor", "middle")
.text("Date");
When I chain the code above (hence moving the text element under the x axis group):
// Add the x Axis
svg.append("g")
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(x))
.append("text")
.style("text-anchor", "middle")
.text("Date");
Then my axis title is not visible any more (see screenshot below). I can still find my text element in DOM, under the x axis group, but it's not there in the rendered HTML.
I want to know:
Is it by design that D3 wants me to add axis and its label separately (i.e., not chaining)?
Why is my text element not visible after I move it under the x axis group?
D3 axis label has to be added separately?
No, it doesn't. You can chain, that's not the problem. The problem here is the fill of the text element.
As you can see in the screenshot you linked, the container group has "none" as fill. Since the text inherits the parent's attributes/styles, you'll have to change its fill from "none" to any color you want:
var svg = d3.select("svg");
var xScale = d3.scaleLinear()
.domain([1, 10])
.range([10,390]);
var xAxis = d3.axisBottom(xScale);
var gX = svg.append("g")
.attr('class', 'axis')
.attr("transform","translate(0,40)")
.call(xAxis)
.append("text")
.attr("fill", "black")//set the fill here
.attr("transform","translate(120, 40)")
.text("Hello World!!!");
<script src="https://d3js.org/d3.v4.min.js"></script>
<svg width="400" height="80"></svg>
PS: this problem wouldn't happen in D3 v3.x.
I am drawing a simple horizontal bar graph in D3.
I'm breaking the bars into smaller rectangles with long, white tick marks.
But my tick marks are slicing through some text.
I suspect I am drawing elements in the wrong order, somehow.
What do you think?
How to make gridlines slice only the bars, not the text?
You can see how it looks tacky, whole thing is here:
http://bl.ocks.org/greencracker/4378b817d4d5393c4e37
Here's the key part, I think:
...
var bar = svg.selectAll("g.bar") // create the bars
.data(data)
.enter().append("g")
.attr("class", "bar")
.attr("transform", function(d) { return "translate(0," + y(d.name) + ")"; });
bar.append("rect") // draw the bars
.attr("width", function(d) { return x(d.value); })
.attr("height", y.rangeBand())
.style("opacity", 0.5);
svg.append("g") // draw my x axis, which includes the white tickmarks
.attr("class", "x axis")
.call(xAxis);
bar.append("text") // then attach text to each bar
.attr("class", "value")
.attr("x", function(d) { return x(d.value); })
.attr("y", y.rangeBand() / 2)
.attr("dy", ".35em")
.attr("text-anchor", function (d) {
if (d.name === "Business, Management, Marketing") {return "end"}
else {return "start"} ;}) // correct for "business" being very long
.attr("dx", function (d) {
if (d.name === "Business, Management, Marketing") {return -3}
else {return 3} ;}) // correct for "business" being very long
.text(function(d) { return (d.name); });
(Yes, I asked a similar question before, but this one's a little different and I can't figure it out. Transition on axis -- losing grid lines (ticksize), how to transition in correct order?)
your suspicions about drawing elements in the proper order are correct.
What's currently happening is:
1) Append <g class="bar"> for new data.
var bar = svg.selectAll("g.bar")
.data(data)
.enter().append("g")
2) Append a rectangle to the above group.
bar.append("rect")
3) Draw the x-axis, which is placed after (i.e. over) of (1).
svg.append("g")
.attr("class", "x axis")
.call(xAxis);
4) Append/nest text to the group defined in (1).
bar.append("text")
Since the text is nested with the group and the group is inserted into the DOM before the x-axis, the tickmarks are showing up over the text.
However if we do something as simple as say moving the x-axis call before the bar call, the ticks won't show up because they'll be drawn underneath the bars. So unfortunately you'll need to split up the grouping of rectangle and text.
This also means you'll need define a transform/translate for the text labels:
svg.selectAll("text.value")
.data(data)
.enter().append("text")
.attr("class", "value")
.attr("transform", function(d) {
return "translate("+ x(d.value)+5 + "," + (12+y(d.name)) + ")";
})
.attr("text-anchor", function (d) {
if (d.name === "Business, Management, Marketing") {return "end"}
else {return "start"} ;}) // correct for "business" being very long
.attr("dx", function (d) {
if (d.name === "Business, Management, Marketing") {return -3}
else {return 3} ;}) // correct for "business" being very long
.text(function(d) { return (d.name); });
The above should work for all labels except for Business, Management, Marketing, because its translate is at 5800.
Hope this helps!
I have this code:
y.domain([-arr2, arr2]).nice();
svg.append("g")
.attr("class", "y axis")
.call(yAxis)
.append("text")
.attr("class", "label")
.attr("transform", "rotate(-90)")
.attr("x", 150)
.attr("y", -10)
.attr("dy", ".71em")
.style("text-anchor", "end")
.attr("font-family", "sans-serif")
.attr("font-size", "34px")
.text("log(Lev)");
This is the graph with Y axis created by this code:
As you can see, Y axis have a negative portion (0 <--> -25) bellow X axis,
i whould like to change negative Y axis domain to be positive.
So i get something like:
You can use:
yAxis = Math.abs(yAxis);
You want to use a custom render for the axis labels. You can do it with yAxis.tickFormat(function(v){ return String(Math.abs(v)); }) (github.com/mbostock/d3/wiki/SVG-Axes#wiki-tickFormat) – Prusse 10 mins ago