d3.js ticks for axis displayed wrong - javascript

I have a problem regarding ticks for the axis label using d3.js
This is my code:
const svg = d3.select('svg').attr('width', 1000).attr('height', 600);
const layer = svg.append('g').attr('transform', `translate(30, 30)`);
const scale = d3.scaleLinear().range([0, 750]).domain([0, 350]);
const axis = d3.axisTop(scale).ticks(14);
layer.call(axis);
So what i want to do is, have 14 labels regarding the data. So by dividing 350/14 a step should be of size 25.
If you take a look at the result, the ticks are rounded somehow to 20, which I do not know why.
Does anyone know what d3 is doing here? What am I doing wrong?
Thanks in advance!
Output

The number of ticks you pass is only a hint to d3. According to the observable documentation here:
For linear and power scales, pass axis.ticks the desired tick count. This is just a hint: these scales only generate ticks at 1-, 2-, and 5-multiples of powers of ten, so the actual number of ticks may be different.
If you want to use labels on the axis, you should consider using the scaleBand which is demonstrated here

Related

How to set unequal intervals on Y axis in D3.js?

I am trying to create a chart that will have a custom tick range. Having an issue on how to set up the axis though, tried using logscale too but it didn't work properly. Any help is appreciated, attaching a pic for reference.
How I want the axis to be
var y = d3.scaleLinear()
.domain(d3.extent(props.dailyDataAll, function (d) { return d.confirmed }))
.range([height, 0])
I know this really does not answer your question, but I think it may be just a common XY problem.
As such I would suggest instead of struggling to plot ticks properly, you could simply replace Y values with Math.log10(Y) which would make ticks work exactly as you wanted (100 being 2 on the Y scale, 1000 being 3, 10000 being 4 and so on, effectively one tick per order of magnitude just like in your requirements)

Highcharts Y-Axis Limits

I am having problems controlling the Y-Axis range of a highcharts graph. It seems like highcharts likes nice round numbers. When my data passes or is close to certain thresholds, the Y-Axis range can expand a lot which effectively compresses all the plot points downward.
Here is a jsfiddle that illustrates the problem I am having:
https://jsfiddle.net/shannonwrege/z8h5eork
The relevant code for this post is this:
chart.yAxis[0].setExtremes(0, max, true, false);
Keep in mind that I don't know what the data will look like in advance, so I must dynamically modify the Y-Axis range. Right now I am using the setExtremes because of other suggestions I've read on stackoverflow.
The maximum y-value of the data in the first two charts is 99. You'll notice that the y-axis is set at 150 in the first chart where the range is automatically calculated and 100 in the second chart where I specifically set the extreme values. The look of the 2nd chart is what I want. So it seems like setExtremes(0,99,true,false) should do the trick, but it actually doesn't.
In the 3rd chart I changed the data so that the maximum y-value of the data is 101, and I called setExtremes(0,101,true,false). You'll note that the y-axis is now back to 150.
Ideally I want the scale of the graph to be capped on the maximum value to limit the about of extra white space. I want to see all of the data, but I don't necessarily care about the y-axis displaying a maximum band that is greater than the max data value. In this case, I would be happy with the y-axis displaying 100 on the axis and some points over but still visible.
Does anyone know how to make this work?
I ended up using the endOnTick parameter to solve this problem. Adding the following line to the yAxis configuration parameters did exactly what I wanted:
endOnTick: false,
Here's the updated Fiddle showing the results.
https://jsfiddle.net/shannonwrege/z8h5eork/3/
All of the charts look pretty good in my opinion (even the one where the yAxis range was auto calculated).
You will need to read the data and then round up to set the idealMax
var chart,
idealMax = 0; // init the max value
// Read the data to find the highest value
for (i=0;i < (options.series[0].data).length; i++ ){
if (options.series[0].data[i][1] > idealMax) {
idealMax = options.series[0].data[i][1];
}
}
// Round the max to the nearest 10
idealMax = Math.round(idealMax / 10) * 10;
options.yAxis.tickPixelInterval = idealMax/10;
Highcharts.chart('container1', options);
chart = $('#container1').highcharts();
chart.yAxis[0].setExtremes(0, idealMax, true, false);
Updated Fiddle

Automatic Date Labeling for NVD3 Graphs

I want the date labels to automatically be calculated, appear, and disappear when I change the focus range so that they don't overlap.
I am using a MultiBar graph with a focus chart with the default ordinal scale for nv.models.multiBar(). When I use .ticks(availableWidth / 100 ) on the xAxis, it seems to generate a tick label for EVERY date, or at least a very large number of them:
On nv.models.lineWithFocusChart(), the labels are automatically reduced to fit in a space. This could be because it uses the scale for nv.models.scatter() which is a d3.scale.linear(), but I'm not sure. I tried creating my own scale with the following:
x = d3.scale.ordinal() //as well as x = d3.scale.linear()
.domain(d3.extent(data.map(function(d) {
return d.values.map(function(d,i) {
var X = getX(d,i);
return X.getTime();
});
})))
.range([0, availableWidth]);
I get the following for an ordinal scale:
and no labels for a linear scale. Will this approach work? If so, what am I doing wrong?
On nv.models.multiBarChart(), there is a .reduceXTicks(BOOLEAN) option but this only applies to multiBarChart and there doesn't seem to be an easy way to add it to nv.models.multiBar(). Can I somehow use this?
If there is anything I haven't tried please let me know. I don't want to calculate the labels myself and specify them using .tickValues()
The solution was in fact to use d3.scale.linear() for the x axis. What I tried above didn't work because I was specifying the whole domain of the context chart, when I needed to specify the min and max of the current selection.
In chart(selection) {...}, I put
x = d3.scale.linear()
.range([0, availableWidth]);
and in onBrush(), I put x.domain([new Date(extent[0]), new Date(extent[1])]);, where extent contains the min and max dates of the selection in milliseconds.

How can I get the tick values of a '.nice()'ed scale?

I've created a chart in D3 which contains grid lines. I'm placing my gridlines at every tick on my axis using the axis' scale:
y0Scale.ticks()
The problem I'm having is that the value of .ticks() doesn't seem to take into account the face that the scale has had .nice() called. The result of this is that sometimes my chart is missing gridlines at the extents of the axes.
I know I could combine y0Scale.domain[0] and y0Scale.domain[1] with the tick marks I know about, but doesn't always work, as in some cases the .nice() algorithm does more than just adding a tick value on the min and the max of the scale.
You need to call .ticks() after having called .nice() on the scale.

Creating a histogram with distribution curve, where the curve series is larger than the bin series

I want to create a histogram in Highcharts. The bin series has about 8 elements. The series for the the distribution curve has about 200 elements. Since Highcharts infers the xAxis from the number of elements in the series, the xAxis stretches out to 200. How do I get the curve series to fit to the bin series on the xAxis?
I would suggest using 2 x axes for this. It is far easier than trying to make the points match on a single axis.
See my example here:
http://jsfiddle.net/FnhRV/19/
Well, first I advice to get familiar with Highcharts docs/tutorials. Like this one.
In general, you can manage distance between points, it's called pointInterval, for example: http://jsfiddle.net/Dd9Py/1/
When you have 8 columns, on xAxis you should have scale - according to pair [x,y] of values.
Another solution is to use two different xAxis, one for column and one for spline. Example: http://jsfiddle.net/Dd9Py/2/
Looking at this jsFiddle. Things I notice is that your xAxis is linear - meaning that each point is plotted consecutively. So, since your bar series only has 8 points they are plotted int he first 8 positions. Your curve contains 200 points and are also plotted first come first served. You need to link up your xAxis so that each series is linked. What are your xAxis increments/categories?

Categories

Resources