transition of x-axis results in overflow - javascript

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.

Related

PlotlyJS rescale yaxis when xaxis range is updated (via rangeslider)

I have the sample chart with range slider created with PlotlyJS:
It uses API endpoint to fetch data. Now, the slider can be used to change xaxis range like:
but then the chart looks strange as yaxis has this fixed range and visible data covers only small vertical part of the whole chart.
Is it possible to scale (change range of) yaxis when xaxis range is updated?
I tried listening to plotly_replot event and then rescaling yaxis, but really couldn't make it work properly.

How can I implement 2 x axis in D3 version 4

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

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.

Highcharts.js combined bar/line chart with timespan bars

What I am trying to achieve is to develop a graph that combines line series with bars. The x axis should be a simple timeline (dates) and the 2 y axes should be linear or logarithmic values. I have no problem creating the line series and the timeline axis.
My problem is when I am trying to implement the "time span bars". It's sort of a gantt chart combined with a line chart I guess. The bars represent data where each bar has a start date, and optionally an end date. I want each bar to start at the start date (aligned with the x axis) and end at the end date if available. If no end date is available, the bar should fill the entire chart until the right edge. I cannot figure out how to combine these time span bars with the line series. I have checked out the jsfiddle /8JhXv/1/ which is pretty close to what I am trying to achieve, except in that example, they are not on top of each other. Anyone who could give me some hints on how to put these on top of each other?
Look at some of the options here:
http://highcharts.uservoice.com/forums/55896-general/suggestions/804783-gantt-chart
Best option is not to use actual bars, but to use line series with lineWidth set to a high enough value to mimic bars visually.
You can try to use line series and columnrange (http://www.highcharts.com/demo/columnrange)

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