Php 显示从最小值到最大值的轴-计算比例和标签

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

编写一个在水平轴上显示数据的例程(使用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 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;
        } 
    }