Public
Edited
Nov 18, 2022
Fork of Simple D3
19 stars
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
screenDPIResolution = 166
Insert cell
pixelPhysicalSizeM = (25.4 / screenDPIResolution) * 0.001
Insert cell
Insert cell
pixelSizeM = scale * pixelPhysicalSizeM
Insert cell
Insert cell
maxLengthM = maxLengthPix * pixelSizeM
Insert cell
Insert cell
niceScaleBarLength = function (scaleBarLength) {
//compute the 'nice' power of ten
const pow10 = Math.pow(
10,
Math.floor(Math.log(scaleBarLength) / Math.log(10))
);

//check if 5 times this value fits
if (5 * pow10 <= scaleBarLength) return [5 * pow10, 5];

//check if 3 times this value fits
if (3 * pow10 <= scaleBarLength) return [3 * pow10, 3];

//check if 2 times this value fits
if (2 * pow10 <= scaleBarLength) return [2 * pow10, 2];

//returns the power of ten
return [pow10, 1];
}
Insert cell
Insert cell
niceLengthM = niceScaleBarLength(maxLengthM)
Insert cell
Insert cell
niceLengthPixel = niceLengthM[0] / pixelSizeM
Insert cell
Insert cell
Insert cell
scaleBarStartDigit = niceLengthM[1]
Insert cell
Insert cell
Insert cell
Insert cell
divisionNumber = {
//the scale bar is already too small to be divided
if (niceLengthPixel < divisionMinLengthPixel) return 1;

let subLP = 0;

//try dividing by the scaleBarStartDigit
subLP = niceLengthPixel / scaleBarStartDigit;
if (subLP < divisionMinLengthPixel) {
//try dividing by 2
if (niceLengthPixel / 2 < divisionMinLengthPixel) return 2;
return 1;
}

//try dividing by the scaleBarStartDigit * 2
subLP = niceLengthPixel / scaleBarStartDigit / 2;
if (subLP < divisionMinLengthPixel) return scaleBarStartDigit;

//try dividing by the scaleBarStartDigit * 4
subLP = niceLengthPixel / scaleBarStartDigit / 4;
if (subLP < divisionMinLengthPixel) return 2 * scaleBarStartDigit;

//try dividing by the scaleBarStartDigit * 5
subLP = niceLengthPixel / scaleBarStartDigit / 5;
if (subLP < divisionMinLengthPixel) return 4 * scaleBarStartDigit;

//TODO these three previous steps could be handled into a loop, with some recursion mechanism. It would however be good to limit the number of divisions, or to hierarchise them.

return 5 * scaleBarStartDigit;
}
Insert cell
Insert cell
Insert cell
getLabel = function (valueM, withUnit = true) {
//mm
if (valueM < 0.01)
return (valueM * 1000).toLocaleString() + (withUnit ? " mm" : "");
//cm
if (valueM < 1)
return (valueM * 100).toLocaleString() + (withUnit ? " cm" : "");
//m
if (valueM < 1000)
return (valueM * 1).toLocaleString() + (withUnit ? " m" : "");
//km
return (valueM / 1000).toLocaleString() + (withUnit ? " km" : "");
}
Insert cell

One platform to build and deploy the best data apps

Experiment and prototype by building visualizations in live JavaScript notebooks. Collaborate with your team and decide which concepts to build out.
Use Observable Framework to build data apps locally. Use data loaders to build in any language or library, including Python, SQL, and R.
Seamlessly deploy to Observable. Test before you ship, use automatic deploy-on-commit, and ensure your projects are always up-to-date.
Learn more