Php 显示从最小值到最大值的轴-计算比例和标签
编写一个在水平轴上显示数据的例程(使用PHPGD2,但这不是重点) 轴从Php 显示从最小值到最大值的轴-计算比例和标签,php,algorithm,php-gd,axis-labels,Php,Algorithm,Php Gd,Axis Labels,编写一个在水平轴上显示数据的例程(使用PHPGD2,但这不是重点) 轴从$min到$max开始,并在$result处显示一个菱形,这样的图像宽约300px,高约30px,如下所示: (来源:) 在上面的示例中,$min=0,$max=3,$result=0.6。 现在,我需要计算一个刻度和有意义的标签,在上面的例子中,例如0.25.50.75 1 1.25处的虚线。。。最多3个,数字标签位于0 1 2 3 如果$min=-200和$max=600,虚线应位于-200-150-100-50 10
$min
到$max
开始,并在$result
处显示一个菱形,这样的图像宽约300px,高约30px,如下所示:
(来源:) 在上面的示例中,
$min=0
,$max=3
,$result=0.6
。
现在,我需要计算一个刻度和有意义的标签,在上面的例子中,例如0.25.50.75 1 1.25处的虚线。。。最多3个,数字标签位于0 1 2 3
如果$min=-200
和$max=600
,虚线应位于-200-150-100-50 100。。。最多600个,数字标签位于-200-100 100。。。最多600个
使用$min=.02
和$max=5.80
,点线位于.02.511.522.5。。。5.5.8
和.02 1 2 3 4 5.8处的数字
我试图明确地告诉函数在哪里按数组放置虚线和数字,但是嘿,应该是计算机在工作,不是我,对吗
那么,如何计算呢?我知道这并不是你想要的,但希望它能让你朝着正确的方向开始
$min = -200;
$max = 600;
$difference = $max - $min;
$labels = 10;
$picture_width = 300;
/* Get units per label */
$difference_between = $difference / ($labels - 1);
$width_between = $picture_width / $labels;
/* Make the label array */
$label_arr = array();
$label_arr[] = array('label' => $min, 'x_pos' => 0);
/* Loop through the number of labels */
for($i = 1, $l = $labels; $i < $l; $i++) {
$label = $min + ($difference_between * $i);
$label_arr[] = array('label' => $label, 'x_pos' => $width_between * $i);
}
$min=-200;
$max=600;
$difference=$max-$min;
$labels=10;
$picture_width=300;
/*获取每个标签的单位*/
$difference_between=$difference/($labels-1);
$width\u between=$picture\u width/$labels;
/*创建标签数组*/
$label_arr=array();
$label\u arr[]=数组('label'=>$min,'x\u pos'=>0);
/*循环浏览标签的数量*/
对于($i=1,$l=$labels;$i<$l;$i++){
$label=$min+(*$i之间的$difference_);
$label\u arr[]=数组('label'=>$label,'x\u pos'=>$width\u在*i之间);
}
提供了三个简单的函数来生成良好的轴刻度,输出刻度上最小值和最大值的xminp、xmaxp和dist,以及刻度上刻度线之间的距离,给出了包含数据点xmin
和xmax
的n
间隔的请求:
Scale1()
Scale2()
给出了一个精确间隔为n
的线性标度(xminp和xmaxp之间的间隙往往大于Scale1()
产生的间隙)
Scale3()
给出对数刻度
1973年的原始论文是在线的,它提供了比上面链接的代码更多的解释
代码是用Fortran编写的,但它只是一组算术计算,因此解释和转换为其他语言非常简单。我自己没有写过任何PHP,但它看起来很像C,所以您可能希望从运行代码开始,通过这些代码,您可以在PHP中获得接近可运行的功能
还有一些更复杂的函数可以提供更漂亮的比例(例如gnuplot
中的函数),但是Scale1()
可能会用最少的代码为您完成这项工作
(此答案基于我对上一个问题的回答)
(编辑——我发现了我在Perl中实现的Scale1()
):
使用严格;
子标度1($$){
#来自Toms463
#使用调用时,返回合适的比例($xMinp、$xMaxp、$dist)
#最小和最大x值,以及近似的间隔数
#除以。$dist是每个结果间隔的大小。
#@vInt是$dist的可接受值数组。
#@sqr是@vInt相邻值的几何平均值数组,它
#用作断点以确定要使用的@vInt值。
#
我的($xMin,$xMax,$n)=@;
@vInt={1,2,5,10};
@sqr={1.414214,3.162278,7.071068}
如果($xMin>$xMax){
my($tmp)=$xMin;
$xMin=$xMax;
$xMax=$tmp;
}
我的($del)=0.0002;#计算机四舍五入帐户
my($fn)=$n;
#查找近似的间隔大小$a
my($a)=($xMax-$xMin)/$fn;
my($al)=log10($a);
my($nal)=int($al);
如果($a<1){
$nal=$nal-1;
}
#$a被缩放成一个名为$b的变量,介于1和10之间
我的($b)=$a/10^$nal;
#找到$b的最接近允许值)
我的($i);
对于($i=0;$i<$\u sqr;$i++){
如果($b<$sqr[$i])最后;
}
#计算间隔大小
$dist=$vInt[$i]*10^$nal;
$fm1=$xMin/$dist;
$m1=整数($fm1);
如果($fm1<0)$m1--;
如果(abs($m1+1.0)-$fm1)<$del)$m1++;
#找到了新的最小和最大限值
$xMinp=$dist*$m1;
$fm2=$xMax/$dist;
$m2=$fm2+1;
如果($fm2<-1)$m2--;
如果(abs($fm2+1-$m2)<$del)$m2--;
$xMaxp=$dist*$m2;
#如有必要,调整限额以考虑四舍五入
如果($xMinp>$xMin)$xMinp=$xMin;
如果($xMaxp<$xMax)$xMaxp=$xMax;
返回($xMinp、$xMaxp、$dist);
}
亚标度1_检验{
美元面值=(-3.1,11.1,5,
5.2, 10.1, 5,
-12000, -100, 9);
打印“xMin\txMax\tn\txMinp\txMaxp,dist\n”;
对于($i=0;$i<$\u par/3;$i++){
($xMinp,$xMaxp,$dist)=比例1($par[3*$i+0],
$par[3*$i+1]、$par[3*$i+2]);
打印“$par[3*$i+0]\t$par[3*$i+1]\t$par[3*$i+2]\t$xMinp\t$xMaxp,$dist\n”;
}
}
一个简单的例子是$increment=($max-$min)/$scale
行中的一些内容,您可以将scale调整为增量缩放的变量。由于您使用了它,它应该随着最大值和最小值的变化而成比例地变化。之后,您将拥有如下功能:
$end = false;
while($end==false){
$breakpoint = $last_value + $increment; // that's your current breakpoint
if($breakpoint > $max){
$end = true;
}
}
至少这是个概念。。。如果有问题,请告诉我。算法(示例值$min=-186
和$max=+153
作为限制):
取这两个极限值$min
,$max
,并在必要时标记它们
$end = false;
while($end==false){
$breakpoint = $last_value + $increment; // that's your current breakpoint
if($breakpoint > $max){
$end = true;
}
}