How can I implement 2 x axis in D3 version 4 - javascript

I'm trying to implement two x axis (Major and minor axis) using D3.
I already have both of them been displayed, but my second axis is not displayng the domain properly.
Here's the code on codepen: http://codepen.io/wendelcosta/pen/QpzzgJ
g.append("g")
.attr("class", "axis axis--x2")
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(x2));
I need to display the days for the months as minor ticks in between the major ticks (Months), it should looks like the following image.
Click Here for Image Preview

You should use two time scales for the x axis.
In the "day" axis, you can set the axis generator using d3.timeDay:
call(d3.axisBottom(x2)
.ticks(d3.timeDay.every(6))
.tickFormat(d => d3.timeFormat("%d")(d)));
And in the "month" axis, you increase the tick size:
call(d3.axisBottom(x)
.tickSizeInner(20)
.tickFormat(d3.timeFormat("%b %y")));
Here is your updated codepen: http://codepen.io/anon/pen/bqOPRg?editors=0010
I'm printing just one on every 6 days, still the "day" axis is terribly crowded. Now it's up to you reducing the text size or reducing the number of ticks.
EDIT: Since OP asked in the comments to show only values present in the data array, here is another CodePen: http://codepen.io/anon/pen/qrvdWq?editors=0010

Related

D3 adding interval on X axis

Trying to get intervals on the X axis. The X axis should display the 1st of every month(1st Jan, 1st Feb, etc). Also looking at how to zoom in the chart to show the days (1-31 Jan). So far i've got a brush only to work as i'm still new to creating bar charts in D3.
var brush = d3.svg.brush()
.x(x)
.on('brush', bListener);
var gBrush = svg.select('g.brush').call(brush);
gBrush.selectAll('rect')
.attr('height', height - margin.top - margin.bottom)
.style("opacity", 0.5)
.style("fill", ""grey");
Looking to create something like this but as a bar chart in D3, http://www.highcharts.com/demo/line-time-series.
Here's https://jsfiddle.net/noobiecode/wck4ur9d/4/
Any help would be appreciated.
Partial answer:
How to display the 1st of every month(1st Jan, 1st Feb, etc):
In your xAxis instead of this:
.ticks(d3.time.days, 1)
do this:
.ticks(d3.time.months)
working fiddle here
Regarding brushing i didn't see any examples, may be you need to write it on your own :(

Chart bars not aligning with x axis values in d3.js

Trying to learn and implement d3.js for the first time.
In the fiddle, we needed to reduce the width of each bar from
.attr('width', xScale.rangeBand()) line 46
to
.attr('width', '10') line 50
When doing so, the horizontal x axis labels are getting dis-aligned with vertical bars which is not needed.
Tried to see a few solutions:
We're unable to see tickValues anywhere in my code.
Unable to understand where to put SVG-Text
We do not wish to hide the x axis labels
Ours is numeric, they're discussing about date time kind of axis
Any suggestions, kind folks?
Try this code:
.rangeBands([0, width], someValue)

transition of x-axis results in overflow

First of all, no: this question is not about the (yet) ugly transition of the lines (I might open another one for that, though..).
I'm displaying data in line charts and the user can select the time horizon. The x-axis then correspondingly transitions so as to fit to the changed time horizon. In attached image, e.g., the time horizon was 1 week and then I switched to 4 weeks. The number of ticks on the x-axis increases from 7 to 28, correspondingly.
Question: How can I prevent the x-axis animation to display outside the svg container? As you can see, the additional dates fly in from the left and they are being animated far far outside the container.
Any ideas?
Right now, the transition works probably in the most simple way it could:
// format for x-axis
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom")
.tickFormat(d3.time.format("%d.%m"))
.ticks(d3.time.days, 1)
.tickSubdivide(0);
// Update x-axis
svg.select(".x")
.transition()
.duration(500)
.call(xAxis);
It could work if you set CSS rule
overflow:hidden
for part of page which contains the chart.

D3 time axis - why do tick marks seem to be invisible by default?

I'm working on a pretty regular graph using an X time axis.
The axis code is pretty standard:
var xScale = d3.time.scale()
.domain([tlState.startdate.getTime(), tlState.enddate.getTime()])
.range([0, width]);
var xHourAxis = d3.svg.axis()
.scale(xScale)
.ticks(d3.time.hours, 6)
.tickFormat(d3.time.format("%_Hh"))
.tickSize(5,1)
.orient('bottom');
root.append('g')
.attr('class', 'axis')
.attr("transform", "translate(" + 0 + "," + height + ")")
.call(xHourAxis);
The tsState.* functions simply return starting/ending dates for the axis.
My problem: the axis tick label are visible, but I can't see the tick marks. They are clearly there in the DOM tree (<line y2="5" x2="0"></line>), but they only become invisible when I explicitly set their "stroke" attribute to something non-white.
I could easily solve this using CSS to set the stroke on tickmarks... But why are they invisible in the first place? I've googled around, but have found nothing indicating a default stroke color for tick marks...
Thanks a lot for any hints,
wwwald
According to the SVG spec, the default value for stroke is none. Since d3 uses a path for the ticks, which only show a stroke and no fill, nothing shows up until you style them.
I'm not sure why they decided on that; maybe to make adding a border to shapes a little simpler. Since stroke-width defaults to 1, adding a border only requires changing one attribute. If stroke was any other value besides none, stroke-width would have to default to 0 (don't want to give text a stroke by default!), and it would be a little counter intuitive to set up strokes for the first time: you'd have to know to change stroke-width to a positive number before seeing any strokes.
Why doesn't d3 fix this problem for us? d3's axis is built on top of SVGs and in general d3 lets you work very closely with the standards it is built on top of (css/html/svg). This makes it possible to push the medium to its limits, but also means you run into these issues occasionally.

Wrong number of lines/ticks on d3 bar chart

I have a simple d3 bar chart and I'm trying to draw horizontal lines in the background.
The bars on the chart represent percentages, with a full-height bar being 100%. I want to show 4 bars, at 25%, 50%, 75% and 100% levels. But if I do this:
svg.selectAll('.rule')
.data(y.ticks(4))
.enter().append('line')
.attr('class', 'rule')
.attr('x1', 0)
.attr('x2', width)
.attr('y1', y)
.attr('y2', y);
then the y.ticks(4) shows 5 lines. If I change it to 3 I get 2 lines. If I change it to 5 then I still get 5 lines. Here's an example on JSFiddle.
Also, at the end of that script, I tried adding a y-axis, but it only displays horizontally - how do I get it to appear vertically? This seems to Just Work in all the examples I've seen.
The param of the ticks() method of d3.scale.linear() is just a hint. The method uses this as an approximation, but it will pick "pretty" values. (see here: https://github.com/mbostock/d3/wiki/Quantitative-Scales#wiki-linear_ticks)
If you want to set the values explicitly, you need to instantiate a d3.svg.axis() and use axis.tickValues() (like you did further down).
Regarding your 2nd question. The axis has a default orientation (which you're seeing), for using as a horizontal, X axis. You need to call .orient("left") or .orient("right") to get a vertical axis. Note, if you use "left" orientation, you won't actually see an axis, bc its numbers will run off the left edge of the SVG and get cropped. So it's a good idea in general to add some padding to the SVG and shift all your graphics within it. If you use "right" orientation you'll see the numbers, but typically in this case you'd translate the axis to the right side of the graph.

Categories