I need to align x-axis labels as shown in the snapshot below:
I tried:
.attr("transform", function(d) {
return "rotate(-90)"
})
But it rotated the whole axis/scale.
How do I fix this?
jsFiddle
EDIT:
I updated my code:
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis)
.selectAll("text")
.style("text-anchor", "end")
.attr("dx", "0em")
.attr("dy", "0em")
.attr("transform", function(d) {
return "rotate(-90)"
});
Now the labels are rotated to -90 degrees. How do I get it onto the bars?
jsFiddle
You need to rotate only text, and then translate it properly. See the updated fiddle:
svg.selectAll('.tick')
.select('text')
.attr('transform', 'rotate(-90) translate(50, -12)');
http://jsfiddle.net/MjFgK/18/
I'm not that good in using translate. But this fiddle just works fine.
Reason why the whole axis/scale got rotated is because when the text being created with x and y position, the origin point of it becomes (0,0).
So to rotate your text labels you need to position those text using translate instead of x and y.
In the fiddle I've added the below code at the bottom where it text labels are being rotated.
If you wanted to rotate it more. You can just change the degree of rotation.
svg.selectAll(".text")
.data(data)
.enter()
.append("text")
.attr("transform", function(d, i) {
return "translate(" + (35 + x(d.age)) + ", 250)" + "rotate(-90)"
})
.text(function(d) { return d.age; })
Hope this helps for you.
Related
I'm trying to rotate x-axis text with the code below :
focus.append("g")
.attr("class", "axis axis--x")
.attr("transform", "translate(0," + height + ")")
.call(xAxis)
.selectAll("text")
.attr("class", "x-axistext")
.style("text-anchor", "end")
.attr("dx", "-.8em")
.attr("dy", ".15em")
.attr("font-family", textfontfamily)
.attr("font-weight",textfontweight)
.attr("font-size", textfontsize)
.attr("transform", function (d) {
return "rotate(-65)"
});
Texts are rotating but only when the graph is not zooming. On zooming graph, texts are not rotating. Once you start zooming graph, new texts will be not in rotate position.
Next Problem i'm facing is related to the DateTime Format. Below line of code i'm using to format the text.
var parseDate = d3.timeParse("%H:%M:%S");
But it is also not working properly. Time are showing along with 'AM' 'PM'.
JSFiddle: Here is the complete code
Problem 1
Time are showing along with 'AM' 'PM'.
If you want the time on the ticks to come in a format please provide timeFormat:
xAxis = d3.axisBottom(x).tickFormat(d3.timeFormat("%H:%M:%S"))
Problem 2
On zooming graph, texts are not rotating
On zoom/brush you need to select all ticks and give rotation.
focus.selectAll(".axis--x")
.selectAll("text")
.attr("class", "x-axistext")
.style("text-anchor", "end")
.attr("dx", "-.8em")
.attr("dy", ".15em")
.attr("font-family", textfontfamily)
.attr("font-weight",textfontweight)
.attr("font-size", textfontsize)
.attr("transform", function (d) {
return "rotate(-65)"
});
working code here
I'm create a line chart using D3 v4 and the labels X are overlapping.
// Add the X Axis
var xAxis = svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(x)
.tickValues(data.map(d=>d.date))
.tickFormat(d3.timeFormat("%d/%m %H:%M")))
.selectAll("text")
.attr("transform", "rotate(90)")
.attr("dy", ".35em")
.attr("y", 0)
.attr("x", 9)
.style("text-anchor", "start");
The full code is here: JSFiddle
Do not use given tick values. The data points near the right end of the chart are too close to each other for doing this. Just remove this line
.tickValues(data.map(d=>d.date))
Show the exact times in a tooltip if they are important.
I am doing a dot plot in D3 and I want to add the values along a right Y axis. I have done this before in many charts, adding labels is straightforward, but for some reason this particular chart is giving a lot of problems.
I cant get the values of the dots to show on the right axis.
jsfiddle:
The chart appears on click.
The relevant code for the value labels attached to the right axis:
svg.append("g")
.attr("class", "y axis")
.attr("transform", "translate(" + (width + 10) + " ,0)")
.call(yAxis1)
.selectAll('text')
.text(function(d){ return xScale(d.value); });
With an ordinal axis you are binding your domain values to the axis ticks. So, the scale domain should be:
var yScale1 = d3.scale.ordinal()
.domain(data.map(function(d) { return d.value; })) //<-- use '.value'
.rangeRoundPoints([0, height]);
Then your y-axis call just becomes:
svg.append("g")
.attr("class", "y axis")
.attr("transform", "translate(" + (width + 10) + " ,0)")
.call(yAxis1);
Updated fiddle.
See: http://jsfiddle.net/bQHjj/
Following the green line, the circles should be vertically aligned with my x axis, but all of them are moved a few pixels to the right.
The X axis isn't showing it's first tick, which should be 01.05.2013.
My x axis settings:
var xAxis = d3.svg.axis().scale(x).ticks(d3.time.days, 1).tickFormat(d3.time.format("%d.%m.%Y"));
graph.append("svg:g")
.attr("class", "x axis")
.attr("transform", "translate(0," + h + ")")
.call(xAxis)
.selectAll("text")
.style("text-anchor", "end")
.attr("dx", "-.8em")
.attr("dy", ".15em")
.attr("transform", function (d) {
return "rotate(-65)"
});
Can anybody tell me what's wrong?
Your date parsing function is not correct, it seems to mess up time zones, since new Date(string) apparently assumes UTC.
This will work:
var format = d3.time.format("%Y-%m-%d");
function getDate(d) {
return format.parse(d.date);
}
cf the updated fiddle.
How do I add text labels to axes in d3?
For instance, I have a simple line graph with an x and y axis.
On my x-axis, I have ticks from 1 to 10. I want the word "days" to appear underneath it so people know the x axis is counting days.
Similarly, on the y-axis, I have the numbers 1-10 as ticks, and I want the words "sandwiches eaten" to appear sideways.
Is there a simple way to do this?
Axis labels aren't built-in to D3's axis component, but you can add labels yourself simply by adding an SVG text element. A good example of this is my recreation of Gapminderās animated bubble chart, The Wealth & Health of Nations. The x-axis label looks like this:
svg.append("text")
.attr("class", "x label")
.attr("text-anchor", "end")
.attr("x", width)
.attr("y", height - 6)
.text("income per capita, inflation-adjusted (dollars)");
And the y-axis label like this:
svg.append("text")
.attr("class", "y label")
.attr("text-anchor", "end")
.attr("y", 6)
.attr("dy", ".75em")
.attr("transform", "rotate(-90)")
.text("life expectancy (years)");
You can also use a stylesheet to style these labels as you like, either together (.label) or individually (.x.label, .y.label).
In the new D3js version (version 3 onwards), when you create a chart axis via d3.svg.axis() function you have access to two methods called tickValues and tickFormat which are built-in inside the function so that you can specifies which values you need the ticks for and in what format you want the text to appear:
var formatAxis = d3.format(" 0");
var axis = d3.svg.axis()
.scale(xScale)
.tickFormat(formatAxis)
.ticks(3)
.tickValues([100, 200, 300]) //specify an array here for values
.orient("bottom");
If you want the y-axis label in the middle of the y-axis like I did:
Rotate text 90 degrees with text-anchor middle
Translate the text by its midpoint
x position: to prevent overlap of y-axis tick labels (-50)
y position: to match the midpoint of the y-axis (chartHeight / 2)
Code sample:
var axisLabelX = -50;
var axisLabelY = chartHeight / 2;
chartArea
.append('g')
.attr('transform', 'translate(' + axisLabelX + ', ' + axisLabelY + ')')
.append('text')
.attr('text-anchor', 'middle')
.attr('transform', 'rotate(-90)')
.text('Y Axis Label')
;
This prevents rotating the whole coordinate system as mentioned by lubar above.
If you work in d3.v4, as suggested, you can use this instance offering everything you need.
You might just want to replace the X-axis data by your "days" but remember to parse string values correctly and not apply concatenate.
parseTime might as well do the trick for days scaling with a date format ?
d3.json("data.json", function(error, data) {
if (error) throw error;
data.forEach(function(d) {
d.year = parseTime(d.year);
d.value = +d.value;
});
x.domain(d3.extent(data, function(d) { return d.year; }));
y.domain([d3.min(data, function(d) { return d.value; }) / 1.005, d3.max(data, function(d) { return d.value; }) * 1.005]);
g.append("g")
.attr("class", "axis axis--x")
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(x));
g.append("g")
.attr("class", "axis axis--y")
.call(d3.axisLeft(y).ticks(6).tickFormat(function(d) { return parseInt(d / 1000) + "k"; }))
.append("text")
.attr("class", "axis-title")
.attr("transform", "rotate(-90)")
.attr("y", 6)
.attr("dy", ".71em")
.style("text-anchor", "end")
.attr("fill", "#5D6971")
.text("Population)");
fiddle with global css / js
D3 provides a pretty low-level set of components that you can use to assemble charts. You are given the building blocks, an axis component, data join, selection and SVG. It's your job to put them together to form a chart!
If you want a conventional chart, i.e. a pair of axes, axis labels, a chart title and a plot area, why not have a look at d3fc? it is an open source set of more high-level D3 components. It includes a cartesian chart component that might be what you need:
var chart = fc.chartSvgCartesian(
d3.scaleLinear(),
d3.scaleLinear()
)
.xLabel('Value')
.yLabel('Sine / Cosine')
.chartLabel('Sine and Cosine')
.yDomain(yExtent(data))
.xDomain(xExtent(data))
.plotArea(multi);
// render
d3.select('#sine')
.datum(data)
.call(chart);
You can see a more complete example here: https://d3fc.io/examples/simple/index.html
chart.xAxis.axisLabel('Label here');
or
xAxis: {
axisLabel: 'Label here'
},