JSFiddle - React, Tailwind, and code Playground
CSS
.pt {
position: absolute;
width: 1px;
height: 4px;
top: 10px;
border: 1px solid red;
border-width: 0 0 0 1px;
}
.num {
position: absolute;
width: 1px;
height: 4px;
top: 10px;
border: 1px solid blue;
border-width: 0 0 0 1px;
padding-top: 10px
}
JavaScript
function sigLog(n) {
return Math.log(Math.abs(n) + 1) / Math.log(10) * sig(n);
}
function sig(n) {
return n == 0 ? 0 : Math.abs(n) / n;
}
function sigExp(n) {
return (Math.pow(10, Math.abs(n)) - 1) * sig(n);
}
function value2px(value, valueMin, valueMax, pxMin, pxMax) {
var valueWidth = sigLog(valueMax) - sigLog(valueMin);
var pixelWidth = pxMax - pxMin;
var ratio = pixelWidth / valueWidth;
return ratio * (sigLog(value) - sigLog(valueMin)) + pxMin;
}
function px2value(px, valueMin, valueMax, pxMin, pxMax) {
var valueWidth = sigLog(valueMax) - sigLog(valueMin);
var pixelWidth = pxMax - pxMin;
var ratio = pixelWidth / valueWidth;
return sigExp((px - pxMin) / ratio + sigLog(valueMin));
}
function prettify(n) {
var exp = Math.round(Math.pow(10, Math.log(Math.abs(n)) / Math.log(10)));
return exp == 0 ? 0 : Math.round(n / exp) * exp;
}
var valueMin = -20,
valueMax = 6,
pxMin = 10,
pxMax = 210;
for (var i = valueMin; i <= valueMax; i++) {
document.body.innerHTML += '<div class="pt" style="left: ' + Math.round(value2px(i, valueMin, valueMax, pxMin, pxMax)) + 'px"></div>';
}
var parts = 6;
for (var i = 0; i <= parts; i++) {
var px = pxMin + (pxMax - pxMin) / parts * i;
var exactValue = px2value(px, valueMin, valueMax, pxMin, pxMax);
var prettyValue = prettify(exactValue);
document.body.innerHTML += '<div class="num" style="left: ' + Math.round(value2px(prettyValue, valueMin, valueMax, pxMin, pxMax)) + 'px">' + prettyValue + '</div>';
}