I'm trying to have the tick marks show up on both sides of the y axis. As the code is shown below, I'm able to extend the tick marks based on length -width which draws the tick mark from a starting point from left to right.
Is it possible to move the starting point of the tick mark further to the left?
My intent is aesthetics, but to have the tick values be directly over a length of the tick marks.
I have a grid set up, made up of container-length tick marks:
// Axis
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom")
.tickSize(-height);
var yAxis = d3.svg.axis()
.scale(y)
.orient("left")
.tickSize(-width)
.tickFormat(d3.format("s"));
Based on these scales:
// Scale
var x = d3.time.scale()
.range([0, width]);
var y = d3.scale.linear()
.range([height, 0]);
My axis are appended to the svg like this:
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis)
.call(adjustXLabels);
svg.append("g")
.attr("class", "y axis")
.call(yAxis)
.call(adjustYLabels);
I'm a little confused about what you're after. Do you want the tick labels to overlap with the ticks themselves? If so you can select the text after the axis is drawn and then translate the ticks.
See the fiddle here: https://jsfiddle.net/6q3rpw6j/
The key bit is:
svg.append("g")
.attr("class", "y axis")
.call(yAxis)
.selectAll(".tick text")
.attr("transform", "translate(15,0)");
EDIT
To move the ticks themselves:
svg.append("g")
.attr("class", "y axis")
.call(yAxis)
.selectAll(".tick line")
.attr("transform", "translate(15,0)");
And to remove the top and bottom end ticks, make sure you set the .outerTickSize(0)
Related
I am new to D3 and currently trying to create a line graph. The axis are created with the right dimensions, however the label for the axes are not showing up. They are there, as when I highlight where they are supposed to be, they show up. They must be hidden or being displaying with a white fill but I'm not sure as to why that is happening. Below is my code for adding axes to the chart.
var xScale = d3.scaleTime()
.domain(d3.extent(data[0].values, d => d.date))
.range([0, width1-margin1]);
var yScale = d3.scaleLinear()
.domain([0, 40])
.range([height1-margin1, 0]);
/* Add Axis into SVG */
var xAxis = d3.axisBottom(xScale).ticks(10);
var yAxis = d3.axisLeft(yScale).ticks(10);
svg1.append("g")
.attr("class", "x axis")
.attr("transform", `translate(0, ${height1-margin1})`)
.call(xAxis);
svg1.append("g")
.attr("class", "y axis")
.call(yAxis)
}
The values are there, they are just not displayed for some reason
I have a bar chart with the X axis, which have ticks that include the month and year. The month and year are in the single row now.
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom")
.tickFormat(RU.timeFormat("%b %Y"));
I need to leave the month in the first line and move the year in the second one.
svg.append("g")
.attr("class", "axis")
.attr("transform", "translate(0," + (h - padding) + ")")
.call(xAxis);
Here is my jsfiddle: https://jsfiddle.net/anton9ov/uaygrmLo/
There is this nice "wrap text function", written by Bostock: https://bl.ocks.org/mbostock/7555321
Using this function, I just modified your axis:
svg.append("g")
.attr("class", "axis")
.attr("transform", "translate(0," + (h - padding) + ")")
.call(xAxis)
.selectAll(".tick text")
.call(wrap, 40);
Check the fiddle: https://jsfiddle.net/gerardofurtado/aLc8t6yq/
PS: I used 40 here as a magic number, change it according to your needs.
I have two axes in my graph right now, that are stuck at the very left and bottom of the graph. I want to make the axes line up with the (0,0) coordinate, or in other words I want the axes to be at x=0 and y=0
Here's my axes code:
//setup x
var xAxis = d3.svg.axis()
.scale(xRange)
.tickSize(5)
.tickSubdivide(true),
//setup y
yAxis = d3.svg.axis()
.scale(yRange)
.tickSize(5)
.orient("left")
.tickSubdivide(true);
I was thinking that the way to do it might just be to make a smaller svg underneath the one that I have, that starts at zero, and put the axes there, and remove them from the one I have right now.
Here's the full code: http://jsfiddle.net/v92q26L8/
The key part of your code is the bit where you attach the axes
vis.append("svg:g")
.attr("class", "x axis")
.attr("transform", "translate(0," + (HEIGHT - MARGINS.bottom) + ")")
.call(xAxis);
vis.append("svg:g")
.attr("class", "y axis")
.attr("transform", "translate(" + (MARGINS.left) + ",0)")
.call(yAxis);
At the moment you are positioning the axes bottom and left using transforms on the groups (svg:g nodes) which contain them.
To reposition the axes you simply need to adjust these transforms using your defined scales.
For your x axis
.attr("transform", "translate(0," + (HEIGHT - MARGINS.bottom) + ")")
becomes
.attr("transform", "translate(0," + yRange(0) + ")")
for your y axis
.attr("transform", "translate(" + (MARGINS.left) + ",0)")
becomes
.attr("transform", "translate(" + xRange(0) + ",0)")
Additionally, it may be sensible to change the names of your scales. The term 'range' has a very particular meaning in D3, I'd suggest xScale and yScale.
JS Fiddle
I have a stacked bar chart similar to this link, graph is plotted correctly but the problem is y axis line is invisible. But if you increase the browser page size in the example chart, you can see like at some resolution x, y axis lines and horizontal tick lines will appear. So x, y axis lines and horizontal tick lines are appearing and disappearing subjected to resolution of the page. How to solve this?
I am defining x and y axis like below
var yAxis = d3.svg.axis()
.scale(y)
.orient("left")
.ticks(5)
.tickSize(-width - 180, 0, 0)
.tickFormat(d3.format("$"));
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom")
.tickFormat(d3.time.format("%b"));
svg.append("g")
.attr("class", "y axis")
.attr("transform", "translate(0,0)")
.call(yAxis);
svg.selectAll('.axis line, .axis path')
.style({ 'stroke': '#ddd', 'fill': 'none', 'stroke-width': '1px' });
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
Problem was solved after setting
shape-rendering: geometricPrecision;
in the place of
shape-rendering: crispEdges;
I hope it helps somebody in future.
It might be helpful to see it in action but its possible that you are drawing the axis at the end of the svg. You could try adding the style "overflow: visible" to the svg element to make sure that there is enough space to show your axis. If thats the problem you need to position your axis away from the edges.
Working with one bar chart with d3.js I am unable to align ticks in x axis with bars.
In left and right verges the ticks are ok, but not in the middle.
Here is the code:
var formatDate = d3.time.format("%e %b");
var height = 325;
var xTimeScale = d3.time.scale()
.domain([new Date(data[0].date), d3.time.day.offset(new Date(data[data.length - 2].date), 1)])
.range([30, width]);
var xAxis = d3.svg.axis()
.scale(xTimeScale)
.orient("bottom")
.ticks(d3.time.days, .1)
.tickFormat(formatDate);
chart.append("g")
.attr("class", "xaxis axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
chart.selectAll(".xaxis text")
.attr("transform", function(d) {return "translate(" + this.getBBox().height * -2 + "," + this.getBBox().height + ")rotate(-45)";});
What am I missing?
Thanks in advance.
Update: Here is the jsFiddle updated with chrtan suggestions.
My problem now is to align text with the center of bar and not in left.
From the looks of your graph, you lost a bar's worth of space. If all the bars are supposed to be left-aligned against a tick, that final bar you have should be to the right of the January 31st tick.
You might need to add the February 1st tick by perhaps changing the [data.length - 2] to [data.length - 1] in the domain() for your xTimeScale.
Then for display purposes, you could probably remove the last tick axis text with:
d3.select(chart.selectAll(".xaxis text")[0].pop()).remove();
The inner selectAll should get the array containing your xAxis tick texts and then pop the very last tick. This last tick should then be removed by the outer select.
An example with an auto time ticks with d3.js
// set domain for axis
var x_domain = d3.extent(data, function(d) { return new Date(d.date); });
//format date
var date_format = d3.time.format('%Y %B');
var vis = d3.select("#graph")
.append("svg:svg")
.attr('class', 'chart')
.attr("width", width)
.attr("height", height);
var yScale = d3.scale.linear()
.domain([0, d3.max(data, function(d) { return d.data; })]).nice()
.range([height - padding, padding]);
var xScale = d3.time.scale()
.domain(x_domain)
.range([padding, width - padding]);
// define the y axis
var yAxis = d3.svg.axis()
.orient("left")
.scale(yScale);
// define the x axis
var xAxis = d3.svg.axis()
.orient("bottom")
.scale(xScale)
.tickFormat(date_format);
// draw y axis with labels and move in from the size by the amount of padding
vis.append("g")
.attr("class", "axis")
.attr("transform", "translate("+padding+",0)")
.call(yAxis);
// draw x axis with labels and move to the bottom of the chart area
vis.append("g")
.attr("class", "xaxis axis")
.attr("transform", "translate(0," + (height - padding) + ")")
.call(xAxis);
// and set data in graph...
a great example : http://bl.ocks.org/phoebebright/3061203