创建具有最小值、最大值和离散"steps"的对数刻度



我正在构建一个用于为地图生成颜色的比例,其中不同范围的数字对应于颜色。在下面的刻度中,abc值(连同最小值和最大值(形成"0";步骤";或";桶";对应于颜色。在本例中,-1min之间的任何内容都将被着色为"#ffeda0,而mina之间的任何对象都将被不同地着色:

return [
"#e7e9e9",
-1,
"#ffeda0",
min,
"#fed976",
a
"#feb24c",
b
"#fd8d3c",
c
"#fc4e2a",
max
"#e31a1c"
];

这个标度总是从一个最小值开始,称为min,并以一个最大值结束。我目前有一个简单的线性标度,如下所示:

const min = Math.min(data);
const range = Math.max(data) - min;
const step = range / 4;
return [
"#e7e9e9",
-1,
"#ffeda0",
min,
"#fed976",
min + step,
"#feb24c",
min + step * 2,
"#fd8d3c",
min + step * 3,
"#fc4e2a",
max,
"#e31a1c"
];

如何编写一个函数,在给定刻度中的最小值、最大值和步数(在本例中为三步(的情况下,输出对数刻度的正确数字?

对数刻度的对数是线性的。因此:

const min = Math.min(data);
const max = Math.max(data);
const logmin = Math.log(min);
const logmax = Math.log(max);
const logrange = logmax - logmin;
const logstep = logrange / 4;

现在线性标尺有

value = min + n * step;

对数刻度有:

value = Math.exp(logmin + n * logstep);

只有当minmax都是正数时,这才会起作用,因为你不能取零或负数的对数,因为在对数刻度中,每个值都有一个与前一个值相同的常数。您可以通过调整符号使负minmax起作用。

您可以在其他基础上进行计算,例如10:

const logmin = Math.log10(min);
const logmax = Math.log10(max);
value = Math.pow(10, logmin + n * logstep);

或者,您可以通过取最小值和最大值的商的第n根来找到从一步到下一步的公共因子:

const min = Math.min(data);
const max = Math.max(data);
const fact = Math.pow(max / min, 1.0 / 4.0);

然后通过重复乘法找到这些值:

value = prev_value * fact

value = xmin * Math.pow(fact, n);

两种方法都可能产生";不整洁";数字,即使刻度应该有很好的整数,因为对数和nth根可能会产生不准确的浮点结果。如果你选择一个舍入因子并调整你的最小/最大值,你可能会得到更好的结果。

最新更新