Logarithmic Scale

by Richard Hunter

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.1/Chart.bundle.min.js"></script>
<canvas id="canvas" width="1241" height="620" class="chartjs-render-monitor" style="display: block; width: 1241px; height: 620px;"></canvas>
<input id="rangeSlider" type="range" min="1" max="2" step="any" list="tickmarks" />
<datalist id="tickmarks">
  <option value="1">
    <option value="1.5">
      <option value="2">
</datalist>
<div>X is: <div id="baseEl"></div></div>

JavaScript

class Mapper {

  constructor(A, B) {
    this.A = A;
    this.B = B;

    let rangeA = this.A[1] - this.A[0];
    let rangeB = this.B[1] - this.B[0];

    this.AToBRatio = rangeA / rangeB;
    this.BToARatio = rangeB / rangeA;
  }

  atob(a) {

    let lowerBoundB = this.B[0];
    let lowerBoundA = this.A[0];
    let ratio = this.BToARatio;

    return ((a - lowerBoundA) * ratio) + lowerBoundB;
  }

  btoa(b) {

    let lowerBoundB = this.B[0];
    let lowerBoundA = this.A[0];
    let ratio = this.AToBRatio;

    return ((b - lowerBoundB) * ratio) + lowerBoundA;
  }

}

function createConfig(domain, mappingFunction) {
  const data = domain.map(mappingFunction);
  return {
    type: 'line',
    data: {
      labels: domain,
      datasets: [{
        borderColor: 'blue',
        data: data,
      }]
    },
    options: {
    	animation: false,
      legend: {
        display: false
      },
      responsive: true,
      title: {
        display: true,
        text: 'Logarithmic scale experiment'
      },
      hover: {
        mode: 'nearest',
        intersect: true
      },
      scales: {
        xAxes: [{
          display: true,
          scaleLabel: {
            display: true,
            labelString: 'n'
          }
        }],
        yAxes: [{
          display: true,
          scaleLabel: {
            display: true,
            labelString: 'x to the power n'
          }
        }]
      }
    }
  };

}
function update() {
  var ctx = document.getElementById("canvas").getContext("2d");
  let value = rangeSlider.value;
  window.myLine = new Chart(ctx, createConfig([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10], mappingFunction(value)));
  baseEl.innerHTML = value;
}

rangeSlider.addEventListener('change', update)


function mappingFunction(value) {
	let A = [Math.pow(value, 0), Math.pow(value, 10)];
  let B = [5000, 1000000];
	let mapper = new Mapper(A, B);
  return function (x) {
    return mapper.atob(Math.pow(value, x))
  }
}
update();