I'm trying to find a good example to get my xAxis ticks to be equally spread based on Date Time values.
I have been trying to accomplish this using http://nivo.rocks/guides/axes documentation. However so far no success. As my data collection is not always on the same interval my graph does not equally draw the visual representation but shows every data point with same distance.
Over here my chart code can be found. https://github.com/marcofranssen/gothermostat/blob/master/web/src/components/TemperaturesChart/TemperaturesChart.js
I would like the data to be shown where x axis represent equally spread during the start and end time.
Is there some documentation available to achieve this, or is this a missing feature?
You can use axis tickValues property and set a number which will tell the corresponding d3 axis to use this number of ticks, but it's just a hint, d3 will adapt this count to have sensible ticks, if you really want to keep the number of ticks consistent, then you can compute the values by yourself and pass an array containing those values to tickValues.
I just saw that you're using an older version of the package, please upgrade to 0.49.0, there are changes on the way min/max values are defined though, please have a look at http://nivo.rocks/line.
You can now use a time scale (example).
The source code for the time x scale demo is available here.
@marcofranssen did you succeed in achieving what you wanted?
@plouc still need to give it a shot in my repo. Recently been very busy in personal life. Will report back results asap. Thanks so far.
hi @plouc ! First of all thanks for the awesome plotting library. I think I have a relatively simple question related to this discussion. I'm trying to just set an axis to use time, but not sure how to tell it what format my data is in (preferably I would pass it a JS Date object, or integer representing UNIX timestamp in ms).
I saw this code from your example, but wasn't sure how to adapt it to UNIX timestamp or Date object?
xScale={{
type: 'time',
format: '%Y-%m-%d',
precision: 'day',
}}
axisBottom={{
format: '%b %d',
}}
Thanks so much for the help!!!!
@uclanate, you can set format to native to use js date objects.
on the xScale I mean.
thanks @plouc ! next question, sorry if very basic. For axis labels, the code you used doesn't seem to work:
axisBottom={{format: '%b %d'}}
do I have to do anything special when specifying the format on the axis? I tried playing with both format and labelFormat and neither seemed to work. Thanks again!
which version are you using?
Ah I'm an idiot. ok it works now!! (I was back on version 0.33). Thanks dude!!!! Great work here and thanks again for getting back so quickly :)
@plouc first off, great library, thank you so much. Wondering if its possible to do hours rather than days?
I've got an API returning data in 15 min increments, and I want to set the xScale to say 2 or 4 hour increments.
Is this possible?
I figured it out... for anyone coming to look for something similar, I created an xScale that looks like this:
xScale={{
"type": "time",
"format": "%Y-%m-%d %H:%M:%S",
"precision": "minute"
}}
then in axisBottom I set tickValues: 6 which gets me ticks every 4 hours.
Which is perfectly what I was looking for. Hope this helps anyone else out there.
Desperately trying to figure this out, maybe I'm reading the documentation wrong? Trying to get "ticksValues:5" working for ResponsiveBar but I'm getting every single date.
This is my config:
<ResponsiveBar
data={this.props.stats}
keys={['words']}
indexBy="date"
margin={{
top: 50,
right: 0,
bottom: 50,
left: 0
}}
padding={0.3}
colors="nivo"
borderColor="inherit:darker(1.6)"
xScale={{
type: 'time',
format: '%Y-%m-%d',
precision: 'day'
}}
axisBottom={{
tickValues: 5,
orient: 'bottom',
tickSize: 5,
tickPadding: 5,
tickRotation: 90
}}
axisLeft={{
orient: 'left',
tickSize: 5,
tickPadding: 5,
tickRotation: 0
}}
labelSkipWidth={12}
labelSkipHeight={12}
labelTextColor="inherit:darker(1.6)"
animate={true}
motionStiffness={90}
motionDamping={15}
enableGridY={false}
legends={[
{
dataFrom: 'keys',
anchor: 'bottom-right',
direction: 'column',
justify: false,
translateX: 120,
translateY: 0,
itemsSpacing: 2,
itemWidth: 100,
itemHeight: 20,
itemDirection: 'left-to-right',
itemOpacity: 0.85,
symbolSize: 20,
effects: [
{
on: 'hover',
style: {
itemOpacity: 1
}
}
]
}
]}
/>
my data looks like this:
[
{
date: '2018-09-28',
words: 5
}
]
And I'm on version "@nivo/bar": "^0.49.1",
@raelmiu can we see more of the dataset? how many dates are there?
In my solution, it still renders each 15 min increment, but setting the tickValues:6, shows a tick every 4 hours, but in between each tick mark there are still all the 15 min increments... thats how it can properly render the chart.
I might suggest jumping over to the discord channel where we can discuss a bit more, instead of here.
As soon I add the following to my chart it crashes with following exception.
xScale={{
type: 'time',
format: '%Y-%m-%dT%H:%M:%S',
precision: 'minute'
}}
I get following exception:
Uncaught TypeError: Cannot read property 'setMilliseconds' of null
at push../node_modules/@nivo/scales/cjs/nivo-scales.js.precisionCutOffs (nivo-scales.js:86)
at nivo-scales.js:103
at Array.forEach (<anonymous>)
at nivo-scales.js:102
at nivo-scales.js:120
at nivo-scales.js:262
at Array.forEach (<anonymous>)
at nivo-scales.js:261
at Array.forEach (<anonymous>)
at generateSeriesAxis (nivo-scales.js:260)
at generateSeriesXY (nivo-scales.js:241)
at Object.computeXYScalesForSeries (nivo-scales.js:204)
at nivo-line.js:715
at new WithPropsOnChange (withPropsOnChange.js:92)
at constructClassInstance (react-dom.development.js:12221)
at updateClassComponent (react-dom.development.js:14058)
at beginWork (react-dom.development.js:14687)
at performUnitOfWork (react-dom.development.js:17242)
at workLoop (react-dom.development.js:17281)
at renderRoot (react-dom.development.js:17359)
at performWorkOnRoot (react-dom.development.js:18252)
at performWork (react-dom.development.js:18159)
at performSyncWork (react-dom.development.js:18132)
at requestWork (react-dom.development.js:18009)
at scheduleWork (react-dom.development.js:17802)
at Object.enqueueSetState (react-dom.development.js:12076)
at ResponsiveWrapper.push../node_modules/react/cjs/react.development.js.Component.setState (react.development.js:404)
at Object.onResize (nivo-core.js:258)
at ResizeObserver.WithContentRect._this.measure (with-content-rect.js:146)
I'm also on version 0.49.1. It would really help if there would be some working example.
My current chart can be found over here. Would be great if someone can help me make this work.
@marcofranssen perhaps you don't have a need for the time portion... by this I mean the H:M:S. I had the need in my code because my data was coming to me in that format. If you only need YYYY-MM-DD you can just use Y-m-d. And you would want to change the format from minute to day.
Or maybe you need to format using native as suggested to someone else.
Maybe you can have a look at the storybook source
@marcofranssen, are you sure the dates are all valid ones?
can we see more of the dataset? how many dates are there?
I'm afraid not, it's for a client. But it's 30 dates, all formatted as 'YYYY-MM-DD'.
I've checked all the examples but the result is the same:

I've tried to customize the xScale on a Stream component but with no luck, this method is something specific to the Bar component?
It's available on several component which use @nivo/scales package, @nivo/stream doesn't use it yet
Any hints about my responsiveBar problem above?
@raelmiu, it's difficult to help without having the code, if you can reproduce it on https://codesandbox.io for example, I can have a look, I understand it's for a client and you cannot use real data, but maybe you can use fake one.
@plouc Here you go, faked Data and all:
https://codesandbox.io/s/6yq5o903v3
Still can't make this work. Tried all sorts of variants.
Thank you @raelmiu, sorry, I missed that you're using a bar chart as the issue was initially about a line chart, the bar chart only support point scales (for x axis) and point scales don't support setting tickValues… I should had support for time scales as it's fairly common
I found the issue. After I stripped the milliseconds from my datetime strings it works. So I think there is still a bug with regards to millis. But for now I'm good as I don't need milli precision.
Thank you @raelmiu, sorry, I missed that you're using a bar chart as the issue was initially about a line chart, the bar chart only support point scales (for x axis) and point scales don't support setting
tickValues… I should had support for time scales this as it's fairly common
Thanks for the explanation! That makes sense. This is the documentation that confused me: http://nivo.rocks/guides/axes
Does anyone have an example of how to use native as an option for the format in axis?
this works: axisBottom={{format: '%b %d'}} but axisBottom={{format: 'native'}} produces this chart:

I'm trying to implement the dynamic date axis that D3 supports eg:

native can only be used to define the format of input data, not the way it's displayed
You'll have to implement a custom function for this
I'm planning to add support for d3 intervals though, but haven't yet decided how it should be defined, maybe something like interval:month
I would greatly appreciate time scale on bar charts, it's often used in our application and I'd like to switch us over to Nivo
sounds cool. is this being worked on?
@lucas-wade, yes, this PR will add support for intervals, you'll be able to define tick values like this tickValues="every 15 minutes" or tickValues="every month. only for @nivo/line and @nivo/scatterplot for now.
@plingampally, this means you'll be able to use tickValues="every month" for your use case instead of implementing it by yourself.
It doesn't seem to work for Stream
@vintg, as I previously mentioned it only works for @nivo/line and @nivo/scatterplot for now.
@plouc How would I set the min start date in an example for @nivo/line where I use the every month tick value? Currently, this property defaults to the last day of every month. I'm thinking about altering it with the min property, but a little unsure what the min property would be.
Thank you @raelmiu, sorry, I missed that you're using a bar chart as the issue was initially about a line chart, the bar chart only support point scales (for x axis) and point scales don't support setting
tickValues… I should had support for time scales as it's fairly common
@plouc any chance that time scales will be supported on bar charts in the near future? I'd like to use your library but having a histogram-like bar chart is a high priority feature for our product.
If this isn't a feature on your radar, is there any room for customization to make this work?
Thank you!
I'm trying to use a timestamp for the x value on my graph but I'm also running into the Cannot read property 'setMilliseconds' of null problem. Not on a bar chart, on a ResponsiveLine chart. :( This thread was what came up when I googled the issue.
Reproduced here: https://codesandbox.io/s/lucid-night-h2pk5
Notably, if I set precision to "week" instead of "day" then I get a different error: Cannot read property 'forEach' of undefined
As it stands, I don't think I'll be able to use the time formatting feature; I'll have to DIY it with moment or something...
@aldeka-humu try setting the xScale format to 'native'. You should be good to go after that.
@dhruv4 I have the same issue. If you change xScale to "native" you get a v.getTime is not a function error.
https://codesandbox.io/s/hungry-water-vt4yx
Ah, my bad. What I’m actually doing is creating a JavaScript Date object that’s parsing the datetime string itself and then passing that Date object as the x value. That way the time is already a native Date object, hence why we can use format: “native”.
If I had to guess, somewhere either nivo or D3 is concerting the string we’re passing to a Date object but is unable to set its milliseconds correctly, maybe because the Date object isn’t being created successfully.
Is it possible to use date in x axis using stream chart ? If yes can anybody tell me the properties that I have to deal with or any sort of example available for it
Thank you very much to all, this issue helped me so much with dates and tickValues, I managed to finish my chart
any updates for scale time on bar chart @plouc ?
You'll have to implement a custom function for this
What do you mean exactly? Where should I use this function? in case Im using {format: native}
Update:
Found the solution inside the storybook code:
stories.add('formatting values', () => (
<Line
{...commonProperties}
curve="monotoneX"
yScale={{
type: 'linear',
stacked: boolean('stacked', true),
}}
yFormat={value =>
`${Number(value).toLocaleString('ru-RU', {
minimumFractionDigits: 2,
})} â‚˝`
}
/>
))
In our case support for scale time in the bar chart is the only thing preventing us from adopting nivo generally.
We ran into the milliseconds bug with ISO format and the solution was to add the Z to our format string
// our data x format for time
x: 2020-07-31T16:50:00Z
xScale={{
type: 'time',
format: '%Y-%m-%dT%H:%M:%SZ', // before we forgot the Z which broke the formatter
}}
Without the Z it was not formatting correctly.
I agree with others, scale time for the bar chart is a big pain point.
Don't think this approach will work for everyone (maybe not even for myself once we're using real data) but, for now, I've fixed this issue by transforming the <g> that includes the tickValues.
We need to use a unit-less transform so everything is relative to the SVG's viewBox. Adding that to the group with the tickValues after Nivo has updated its responsive styles should be enough to fix the alignment.
handleResize () {
this.$nextTick(() => {
if (!process.client) { return this.handleResize() }
const colsGroup = document.querySelector('svg > g > g:first-of-type')
if (!colsGroup) { return this.handleResize() }
const val = colsGroup.querySelector('line').getAttribute('x1')
colsGroup.setAttribute('transform', `translate(-${val}, 0)`)
})
}
I'm using this on Vue/Nuxt so you'll probably need to change some things to make it work in React-land but maybe someone will find this workaround useful.
Does anyone know if this transform is the only thing missing in core to fix this issue or there's a bunch of more complex scenarios where this breaks differently?
We ran into the milliseconds bug with ISO format and the solution was to add the
Zto our format string// our data x format for time x: 2020-07-31T16:50:00ZxScale={{ type: 'time', format: '%Y-%m-%dT%H:%M:%SZ', // before we forgot the Z which broke the formatter }}Without the
Zit was not formatting correctly.
This fixed the issue I was having with milliseconds as well :-)
I don't want to pile on by creating another issue but I just thought I'd add that the confusion around time axis config is why I'm not going to use nivo. I just want the ticks and tick formatting on my line chart to be dynamic like d3-axis automatically does by default, but I can't figure out how to do it. For example notice how the Victory time axis dynamically changes tick format precision based on the size of the domain. (You can mess around with the domain on this page to see it in action). https://formidable.com/open-source/victory/gallery/brush-and-zoom
Most helpful comment
I figured it out... for anyone coming to look for something similar, I created an xScale that looks like this:
xScale={{ "type": "time", "format": "%Y-%m-%d %H:%M:%S", "precision": "minute" }}then in axisBottom I set
tickValues: 6which gets me ticks every 4 hours.Which is perfectly what I was looking for. Hope this helps anyone else out there.