title: D3.js v5 - Creating a relative, zoomable timeline-like axis on a linear scale
body: <p>I need to create a relative timeline-like axis in D3 (v5) that is zoomable and changes units and tick intervals on zoom change.
  It will be used for planning certain activities in time relative to the baseline - value 0.</p>
  <p>Example Timepoints: at -8 days, 2 hrs, 10 &amp; 20 days, 2 &amp; 4 &amp; 6 weeks, 4 months and so on (stored in millisecond offsets).</p>
  <p>When zoomed out, the ticks would be formatted as years, and as the user begins to zoom in, these turn to months, then weeks, days, hours, down to the minutes.</p>
  <p><a href="https://i.stack.imgur.com/DF9Kg.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/DF9Kg.png" alt="Axis example screenshot" /></a>
  <a href="https://codepen.io/el-sa-mu-el/pen/PoWJPbW" rel="nofollow noreferrer">CodePen Example</a></p>
  <p>The example shows the approximate effect that I am going for (use the mousewheel scroll to zoom in or out on the axis).</p>
  <p>I decided to use a linear scale with integer units - representing milliseconds.
  I am using <code>tickFormat()</code> where I find the distance among the ticks and calculate different tick formats based on that.<br />
  I probably cannot use D3’s <code>scaleTime()</code> because that’s based on real calendar dates (with variable months, gap years, etc). I need a fixed scale of offsets - 24-hour days, 7-day weeks, 30-day months, 365-days years.</p>
  <p>The scale in the example is wrong - D3 generates the ticks automatically in nicely rounded values - and I need the tick intervals to be variable based on the zoom level. Meaning, when showing ticks in the format of months, the distance between 2 ticks should be one month (in ms) and when zooming down to hours, the distance between 2 ticks should be exactly one hour (in ms) and so on.</p>
  <p>I guess I will need to create some algorithm that generates the variable ticks but I am not sure how would it look like, and what are the limitations of the D3 API because I haven't found any methods that would allow for something like this.
  I couldn't find any examples of this effect anywhere and I was hoping that someone here could point me in the right direction or give some tips on how to achieve it.</p>