I've begun learning D3, and many tutorials are written for v3. I read through a lot of v4's documentation, but I can't wrap my mind around how to format my axis labels. Right now I have a visualization that looks like this:
The months overlapping is not ideal. I know I can use d3's timeFormat and use "%b" to use an abbreviated month. But I'm not sure how syntactically it fits in. My code for the bottom axis is:
svg.append("g")
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(x)
.ticks(d3.timeMonth.every(4)));
I would've expected it to be something like
format = d3.time.format("%b")
svg.append("g")
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(x)
.ticks(format(d3.timeMonth.every(4))));
But that doesn't work. I know this is probably very simple, but I'm not getting it.
You should use tickFormat instead of ticks:
.tickFormat(d3.timeFormat("%b"))
Here is a demo:
var svg = d3.select("svg")
var scale = d3.scaleTime()
.range([20, 480])
.domain([new Date(), new Date().setYear(new Date().getFullYear() + 1)]);
var axis = d3.axisBottom(scale)
.tickFormat(d3.timeFormat("%b"))
.ticks(d3.timeMonth);
svg.append("g")
.attr("transform", "translate(0,50)")
.call(axis)
<script src="https://d3js.org/d3.v4.min.js"></script>
<svg width="500"></svg>
EDIT: For showing the year instead of January:
var svg = d3.select("svg")
var scale = d3.scaleTime()
.range([20, 480])
.domain([new Date(), new Date().setYear(new Date().getFullYear() + 1)]);
var axis = d3.axisBottom(scale)
.tickFormat(function(d) {
return d3.timeFormat("%b")(d) === "Jan" ?
d3.timeFormat("%Y")(d) : d3.timeFormat("%b")(d);
})
.ticks(d3.timeMonth);
svg.append("g")
.attr("transform", "translate(0,50)")
.call(axis)
<script src="https://d3js.org/d3.v4.min.js"></script>
<svg width="500"></svg>
Related
I'm trying to create a heat map.
The code is on Codepen: https://codepen.io/imestin/pen/qBOpodX?editors=1010
My problem is, that the axes are not showing on the SVG canvas.
Inspecting it with web developer tools, I can see the elements.
These are the lines that I think are important in drawing the axes (for the x-axis):
let minYear = d3.min(data, d => d.year );
let maxYear = d3.max(data, d => d.year );
let xScale = d3.scaleLinear()
.domain(minYear,maxYear)
.range(0,canvasX);
//xAxis - needs xScale
let xAxis = d3.axisBottom(xScale);
//X-axis draw
Canvas.append("g")
.attr("id","x-axis")
.attr("class","tick")
.attr("transform", "translate(" + (edge) + ", " + (canvasY) + ")")
.call(xAxis)
Other elements are drawing correctly, basic SVG drawing is working.
The xScale domain and range need an array of values, for example:
xScale = d3.scaleLinear()
.domain([minYear,maxYear])
.range([0,canvasX]);
And secondly, the axis is positioned off the bottom of canvas, so it needs to adjusted up, for example:
Canvas.append("g")
.attr("id","x-axis")
.attr("class","tick")
.attr("transform", "translate(" + (edge) + ", " + (canvasY - 20) + ")")
.call(xAxis)
Using d3 I have an xAxis defined as
var xScale = d3.scaleTime()
.domain([fromDate, toDate])
.range([0, width]);
var xAxis = d3.axisBottom(xScale);
function customXAxis(g) {
g.call(xAxis);
g.select(".domain").remove();
g.selectAll(".tick line").attr("stroke", "white");
g.selectAll(".tick text").attr("fill", "white");
}
g.append("g")
.attr("transform", "translate(0," + height + ")")
.call(customXAxis);
All is working very well indeed.
However, I would like the scale to show ticks at a minimum of a day. As it stands if fromData and toDate are only a few days difference it show ticks....
Mon-10___12PM___Tue-11___12PM___Wed-13___12PM___Thu-14___12PM
How can I get it to not show the time of day values?
Any help appreciated.
You can set the intervals in the axis generator:
Constructs a new custom interval given the specified floor and offset functions and an optional count function.
For instance, this is your code as it is (the domain here has just 3 days):
var svg = d3.select("svg");
var xScale = d3.scaleTime()
.domain([new Date("January 1, 2017 00:00:00"), new Date("January 4, 2017 00:00:00")])
.range([20, 480]);
var xAxis = d3.axisBottom(xScale);
svg.append("g")
.attr("transform", "translate(0,100)")
.call(xAxis);
<script src="https://d3js.org/d3.v4.min.js"></script>
<svg width="500"></svg>
Now the same code, with d3.timeDay:
var svg = d3.select("svg");
var xScale = d3.scaleTime()
.domain([new Date("January 1, 2017 00:00:00"), new Date("January 4, 2017 00:00:00")])
.range([20, 480]);
var xAxis = d3.axisBottom(xScale)
.ticks(d3.timeDay)
.tickFormat(d=>d3.timeFormat("%a %d")(d));
svg.append("g")
.attr("transform", "translate(0,100)")
.call(xAxis);
<script src="https://d3js.org/d3.v4.min.js"></script>
<svg width="500"></svg>
PS: the tickFormat is just to change the first tick, don't pay attention to it.
is it possible to have a line chart with a time-scaled y-Axis in D3.js?
I found the documentation:
https://github.com/mbostock/d3/wiki/Time-Scales
and there doesn't seem to be a limitation for the Y-Axis.
Do you have any examples?
Its pretty much the same as using a linear scale:
var svg = d3.select('#your_svg_id').select("svg")
.attr('width', 300)
.attr('height', 300)
.append("g");
var yScale = d3.time.scale()
.domain([new Date(1980, 0, 1), new Date() ])
.range([100, 0]);
// Domian being the from and to date and range the from to positioning of the axis
svg.append("svg:g")
.attr("class", "y axis")
.call(yAxisGen);
I work with D3JS and I want an axis in x with this kind of values : 125, 250, 500, 1000 ... So multiply by 2 my values each time.
So I tried a Quantize Scales like this:
var qScale = d3.scale.quantize(2)
.domain([0, 8000])
.range([0, 500]);
And I create my axis like that :
var xAxis = d3.svg.axis()
.scale(qScale);
But when I'm calling the axis with that code :
svg.append("g")
.attr("transform", "translate(" + padding + "," + (ChartHeight - padding) + ")")
.attr("class", "axis")
.call(xAxis);
I have the following error :
Object doesn't support property or method 'rangeBand' (I develop on Visual Studio 2012)
Any idea ?
EDIT: here the full code code
I am using D3.js to build this line chart.and its working fine . but i am not able to print the months on x-axis in abbreviated form (jan,feb....)
here how i am parsing the date.
var parseDate = d3.time.format("%m-%Y").parse;
the code for x-axis
var xAxis = d3.svg.axis().scale(x).orient("bottom");
and printing and appending
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
help me with this.
just use tickFormat with a d3.time.format inside
var xAxis = d3.svg.axis().scale(x).orient("bottom").tickFormat(d3.time.format("%H"))