我正在制作一个图表算法,它会给我一组y轴数值,我将在我的图表中使用。
主要问题是我还想计算要使用的步数,并使用不错的数字。它必须能够采用整数和双精度,并能够处理小范围(小于1)和大范围(超过10000等)。
例如,如果给出0.1到0.9的范围,理想情况下我会得到0,0.2,0.4,0.6,0.8,1的值,但如果给出0.3到0.7,我可以使用0.3,0.4,0.5 ,0.6,0.7
这是我到目前为止,它适用于小范围,但非常大范围,并没有给我很好的数字
-(double*)yAxisValues:(double)min (double):max {
double diff = max - min;
double divisor = 1.0;
if (diff > 1) {
while (diff > 1) {
diff /= 10;
divisor *= 10;
}
} else {
while (diff < 1) {
diff *= 10;
divisor *= 10;
}
}
double newMin = round(min * divisor) / divisor;
double newMax = round(max * divisor) / divisor;
if (newMin > min) {
newMin -= 1.0/divisor;
}
if (newMax < max) {
newMax += 1.0/divisor;
}
int test2 = round((newMax - newMin) * divisor);
if (test2 >= 7) {
while (test2 % 6 != 0 && test2 % 5 != 0 && test2 % 4 != 0 && test2 % 3 != 0) {
test2++;
newMax += 1.0/divisor;
}
}
if (test2 % 6 == 0) {
test2 = 6;
} else if (test2 % 5 == 0) {
test2 = 5;
} else if (test2 % 4 == 0 || test2 == 2) {
test2 = 4;
} else if (test2 % 3 == 0) {
test2 = 3;
}
double *values = malloc(sizeof(double) * (test2 + 1));
for (int i = 0; i < test2 + 1; i++) {
values[i] = newMin + (newMax - newMin) * i / test2;
}
return values;
}
有什么建议吗?
答案 0 :(得分:0)
这是一段代码,它做了类似的事情,虽然方法略有不同。 “单位”是指您在图表上绘制的内容。因此,如果您的比例使得图表上的一个单位在屏幕上应为20像素,则此函数将返回每个步骤应该有多少个单位。有了这些信息,您就可以轻松计算轴值是什么以及绘制它们的位置。
- (float)unitsPerMajorGridLine:(float)pixelsPerUnit {
float amountAtMinimum, orderOfMagnitude, fraction;
amountAtMinimum = [[self minimumPixelsPerMajorGridLine] floatValue]/pixelsPerUnit;
orderOfMagnitude = floor(log10(amountAtMinimum));
fraction = amountAtMinimum / pow(10.0, orderOfMagnitude);
if (fraction <= 2) {
return 2 * pow(10.0, orderOfMagnitude);
} else if (fraction <= 5) {
return 5 * pow(10.0, orderOfMagnitude);
} else {
return 10 * pow(10.0, orderOfMagnitude);
}
}
答案 1 :(得分:0)
对JavaScript的简单适应(非常感谢Johan Kool提供源代码)
const step = (() => {let pixelPerUnit = height / (end - size)
, amountAtMinimum = minimumPixelsPerMajorGridLine / pixelPerUnit
, orderOfMagnitude = Math.floor(Math.log10(amountAtMinimum))
, fraction = amountAtMinimum / Math.pow(10.0, orderOfMagnitude);
let result;
if (fraction <= 2) {
result = 2 * Math.pow(10.0, orderOfMagnitude);
} else if (fraction <= 5) {
result = 5 * Math.pow(10.0, orderOfMagnitude);
} else {
result = 10 * Math.pow(10.0, orderOfMagnitude);
}})();
let arr = [];
arr.push(start);
let curVal = start - start % step + step
, pxRatio = height / (end - start);
while (curVal < end) {
arr.push(curVal);
curVal += step;
}
arr.push(end);