Map X-values to a Date in d3.time.scale() - javascript

I have a d3 chart that draws out a number of rectangles over an x-axis.
The x-axis represents a timeline and I currently use d3.time.scale in order to map the dates of each datapoint to a point on the x-axis. This is all straight forward.
var xAxis = d3.time.scale();
data.forEach(function(d){
d.xValue = xAxis(d.startDate);
});
Then drawing it out using that specific xValue in a css transform.
Now, if I would like to get the date based on a given x-value (say for instance when a user clicks on the graph I want to check which date that x-value corresponds to) I have not found how to do this using the xAxis variable that I have created.
How can I achieve this? Would I have to use the xAxis.domain() and the width of the element to calculate the chosen date?

Taking the answer from Lars Kotthoff in the comments;
d3.time.scale().invert() was the answer to this.

Related

d3.js ticks for axis displayed wrong

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

Custom D3 `tickValue` on x axis -- horizontal bar chart

I am trying to create custom tick values on X axis.
Chart is generated from data.csv file. There are 144 data points. Each data value represent 10 minutes cycle, so first tick should appear on 6th tick representing 1 hour.
If I use .domain([new Date('2014-03-08T12:00:00'), new Date('2014-03-9T00:00:00')]) for example, I will get X axis right, but my chart would be gone.
I can't use tickValues([]) in this case either.
What I should see on X axis is something like this 00:00 AM...(6 tick values)...1:00 AM...(6 tick values)...2:00 AM etc. Or it could be 00:00 AM...(12 tick values)...2:00 AM...(12 tick values)...3:00 AM etc. Just to be able to customize it.
Not sure if this is even possible. I tried following this simple example http://bl.ocks.org/phoebebright/3059392, but again, I get X axis right, but my chart is gone.
This would be the code: https://plnkr.co/edit/kc4E43Bgo4bNMB9hKX2j?p=preview
Thank you in advance!
Since your data doesn't contain actual date values, this is my solution:
You want to show one tick out of 6, since each tick represents 10 minutes and you want to show only the "hourly" tick. So, define the tick values using your x scale domain:
.tickValues(d3.range(x.domain()[0], x.domain()[1]).filter(function(d) {
return d % 6 === 0;
}))
And then, format the ticks to add a :00 to each one:
.tickFormat(function(d) {
return d/6 + ":00";
});
Here is your updated plunker: https://plnkr.co/edit/8EOGt8UvYq1J8qpIdArN?p=preview
Edit: As discussed in the comments, here is the solution with "am" and "pm": https://plnkr.co/edit/OvtVlgT4I6Y19hgoMKIK?p=preview

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.

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?

D3 time series heatmap

I am trying to make a heatmap using d3 which on x axis a time series, on y a number and the color is the value for the cell. The data is loaded based on the input and the domain and range can change on different input. I was not able to find such example. Does anyone have an idea how I can create that?
Thanks
So I finally got the time to write this piece of code that I was looking for. My main problem was that I had understood the scales well. So after reading a bit I could define a time scale and map it to my data with the following code:
var xscale = d3.time.scale()
.domain([startDate, endDate])
.range([padding, w - padding]);
var xAxis = d3.svg.axis()
.scale(xscale)
.orient("bottom")
.ticks(d3.time.days, 5);
You can find a working demo of my code in the following jsfiddle:
http://jsfiddle.net/TD5Sk/1/
Explore around the d3 gallery of examples, mixing and matching you should be able to find a good starting point. The co-occurrence matrix has many of the properties you describe. Even the calendar example probably has some useful pointers.

Categories

Resources