title: Best d3 scale for mapping integers range
body: <p>I want to construct a scale that maps a range of successive integers (indexes of characters in a string) to regular intervals in another range of integers (pixels, say 0-600). That is, I would like to assign characters to pixels and conversely as regularly as possible, the length of one not being necessarily a multiple of the other.</p>
  
  <p>For instance, mapping [0,1,2,3] to 400 pixels, I would expect</p>
  
  <pre><code>0 -&gt; 0-99
  1 -&gt; 100-199
  2 -&gt; 200-299
  3 -&gt; 300-399
  </code></pre>
  
  <p>and conversely </p>
  
  <pre><code>0-99 -&gt; 0
  100-199 -&gt; 1
  200-299 -&gt; 2
  300-399 -&gt; 3
  </code></pre>
  
  <p>while for mapping 0-4000 to 400 pixels, I would expect</p>
  
  <pre><code>0-9 -&gt; 0
  10-19 -&gt; 1
  etc.
  </code></pre>
  
  <p>What is the best scale to use for this in d3 ?</p>
  
  <p>On one hand I am afraid that discrete scales will not use the fact that the domain is equally separated and generate a huge switch statement if the number of elements is big. Since I will use the scale on every element to draw an image, I am worried about performance.</p>
  
  <p>On the other hand, a linear scale such as </p>
  
  <pre><code>d3.scaleLinear()
      .domain([0,399])   // 400 pixels
      .rangeRound([0,3])  // 4 elements
  </code></pre>
  
  <p>gives me </p>
  
  <pre><code>0 0
  66 0  // 1st interval has 66 pixels
  67 1
  199 1 // other intervals have 132 pixels
  200 2 
  332 2
  333 3 // last interval has 66 pixels
  400 3
  </code></pre>
  
  <p>(<a href="https://fiddle.jshell.net/6q1s488L/1/" rel="nofollow">fiddle</a>)</p>
  
  <p>so the interpolator returns unequal intervals (shorter at the ends).</p>
  
  <p><strong>Edit:</strong> not using d3, it is not hard to implement:</p>
  
  <pre><code>function coordinateFromSeqIndex(index, seqlength, canvasSize) {
       return Math.floor(index * (canvasSize / seqlength));
  }
  function seqIndexFromCoordinate(px, seqlength, canvasSize) {
      return Math.floor((seqlength/canvasSize) * px);
  }
  </code></pre>
  
  <p>Too bad only if it does not come with d3 scales, since it would become much more readable.</p>