使用 gd 调整字体大小和填充以创建动态条形图
Resizing font size and padding using gd to create a dynamic bar chart
受此 code 的启发,我正在尝试创建一个简单的条形图,能够根据 $data 动态创建、调整条形和文本的大小, $身高和$体重:
<?php
$width = 300;
$height = 200;
$font_path = getenv('WINDIR') . DIRECTORY_SEPARATOR . "Fonts" . DIRECTORY_SEPARATOR;
$font = 'arial.ttf';
$data = ['jan'=>30,'fev'=>40,'mar'=>90,'apr'=>77,
'mai'=>33, 'jun'=>44, 'bigggggggg' => 80];
$columns = count($data);
$padding = ($width+$height)/100;
$column_width = $width / $columns;
$image = imagecreate($width, $height);
$gray = imagecolorallocate($image, 0xcc, 0xcc, 0xcc);
$black = imagecolorallocate($image, 0, 0, 0);
$gray_lite = imagecolorallocate($image, 0xee, 0xee, 0xee);
$gray_dark = imagecolorallocate($image, 0x7f, 0x7f, 0x7f);
$white = imagecolorallocate($image, 0xff, 0xff, 0xff);
imagefilledrectangle($image, 0, 0, $width, $height, $white);
$maxv = max($data);
$array_values = array_values($data);
$array_keys = array_keys($data);
for ($i = 0; $i < $columns; $i++) {
$font_size = ($height / 100) * $padding;
$column_height = ($height / 100) * (( $array_values[$i] / $maxv) * 100);
$string = $array_keys[$i];
$x1 = $i * $column_width;
$y1 = $height - $column_height;
$x2 = (($i + 1) * $column_width) - $padding;
$y2 = $height - ($padding*4);
$maxChars = ($font_size * 2) / $padding;
if (strlen($string) > ($maxChars)) {
$string = substr($string, 0, $maxChars) . '...';
}
imagefilledrectangle($image, $x1, $y1, $x2, $y2, $gray);
imagettftext($image, $font_size, 0, $x1, $y2+$font_size+$padding, $black, $font_path.$font,
$string);
imageline($image, $x1, $y1, $x1, $y2, $gray_lite);
imageline($image, $x1, $y2, $x2, $y2, $gray_lite);
imageline($image, $x2, $y1, $x2, $y2, $gray_dark);
}
header("Content-type: image/png");
imagepng($image);
imagedestroy($image);
使用 300x200 没问题:
但使用 600x400:
我该怎么做才能解决这个问题?
您在$padding
的基础上创建了$font_size
,$font_size
在图表大小增长
的情况下会快速增长
取而代之,让 $font_size
依赖于条形图的 $height
和 Y
位置,它应该可以正常工作,请试试这个脚本
<?php
$width = 600;
$height = 400;
$font_path = getenv('WINDIR') . DIRECTORY_SEPARATOR . "Fonts" . DIRECTORY_SEPARATOR;
$font = 'arial.ttf';
$data = ['jan'=>30,'fev'=>40,'mar'=>90,'apr'=>77,
'mai'=>33, 'jun'=>44, 'bigggggggg' => 80];
$columns = count($data);
$padding = ($width+$height)/100;
$column_width = $width / $columns;
$image = imagecreate($width, $height);
$gray = imagecolorallocate($image, 0xcc, 0xcc, 0xcc);
$black = imagecolorallocate($image, 0, 0, 0);
$gray_lite = imagecolorallocate($image, 0xee, 0xee, 0xee);
$gray_dark = imagecolorallocate($image, 0x7f, 0x7f, 0x7f);
$white = imagecolorallocate($image, 0xff, 0xff, 0xff);
imagefilledrectangle($image, 0, 0, $width, $height, $white);
$maxv = max($data);
$array_values = array_values($data);
$array_keys = array_keys($data);
for ($i = 0; $i < $columns; $i++) {
$column_height = ($height / 100) * (( $array_values[$i] / $maxv) * 100);
$string = $array_keys[$i];
$x1 = $i * $column_width;
$y1 = $height - $column_height;
$x2 = (($i + 1) * $column_width) - $padding;
$y2 = $height - ($padding*4);
$maxChars = ($font_size * 2) / $padding;
if (strlen($string) > ($maxChars)) {
$string = substr($string, 0, $maxChars) . '...';
}
$font_size = ($height - $y2) / 2.5;
imagefilledrectangle($image, $x1, $y1, $x2, $y2, $gray);
imagettftext($image, $font_size, 0, $x1, $y2+$font_size+$padding, $black, $font_path.$font,
$string);
imageline($image, $x1, $y1, $x1, $y2, $gray_lite);
imageline($image, $x1, $y2, $x2, $y2, $gray_lite);
imageline($image, $x2, $y1, $x2, $y2, $gray_dark);
}
header("Content-type: image/png");
imagepng($image);
imagedestroy($image);
只是 $font_size = ($height - $y2) / 2.5;
的小改动
尝试一下是否可行。
基本上您的字体大小是 height/100,当高度为 200 时它是有效的,但是当您将高度增加一倍时,我们也需要更改字体大小以匹配它。
看看这是不是你想要的结果MaxInfo.Tech
<?php
$width = 600;
$height = 400;
$font_path = getenv('WINDIR') . DIRECTORY_SEPARATOR . "Fonts" . DIRECTORY_SEPARATOR;
$font = 'arial.ttf';
$data = ['jan'=>30,'fev'=>40,'mar'=>90,'apr'=>77,
'mai'=>33, 'jun'=>44, 'bigggggggg' => 80];
$columns = count($data);
$padding = ($width+$height)/100;
$column_width = $width / $columns;
$image = imagecreate($width, $height);
$gray = imagecolorallocate($image, 0xcc, 0xcc, 0xcc);
$black = imagecolorallocate($image, 0, 0, 0);
$gray_lite = imagecolorallocate($image, 0xee, 0xee, 0xee);
$gray_dark = imagecolorallocate($image, 0x7f, 0x7f, 0x7f);
$white = imagecolorallocate($image, 0xff, 0xff, 0xff);
imagefilledrectangle($image, 0, 0, $width, $height, $white);
$maxv = max($data);
$array_values = array_values($data);
$array_keys = array_keys($data);
for ($i = 0; $i < $columns; $i++) {
$font_size = ($height / 200) * $padding;
$column_height = ($height / 100) * (( $array_values[$i] / $maxv) * 100);
$string = $array_keys[$i];
$x1 = $i * $column_width;
$y1 = $height - $column_height;
$x2 = (($i + 1) * $column_width) - $padding;
$y2 = $height - ($padding*4);
$maxChars = ($font_size * 2) / $padding;
if (strlen($string) > ($maxChars)) {
$string = substr($string, 0, $maxChars) . '...';
}
imagefilledrectangle($image, $x1, $y1, $x2, $y2, $gray);
imagettftext($image, $font_size, 0, $x1, $y2+$font_size+$padding, $black, $font_path.$font,
$string);
imageline($image, $x1, $y1, $x1, $y2, $gray_lite);
imageline($image, $x1, $y2, $x2, $y2, $gray_lite);
imageline($image, $x2, $y1, $x2, $y2, $gray_dark);
}
header("Content-type: image/png");
imagepng($image);
imagedestroy($image);
另请注意,为了更好地格式化它,您还可以将其他基于高度或宽度的变量更改为比 100 的静态分隔符更动态的变量。
只有字体大小计算可以在前面的代码中修复:
$font_size = ($height / 100) * $padding; //Changing this line
$column_height = ($height / 100) * (( $array_values[$i] / $maxv) * 100);
$string = $array_keys[$i];
$x1 = $i * $column_width;
$y1 = $height - $column_height;
$x2 = (($i + 1) * $column_width) - $padding;
$y2 = $height - ($padding*4);
$maxChars = ($font_size * 2) / $padding;
动态更改后如下:
$column_height = ($height / 100) * (( $array_values[$i] / $maxv) * 100);
$string = $array_keys[$i];
$x1 = $i * $column_width;
$y1 = $height - $column_height;
$x2 = (($i + 1) * $column_width) - $padding;
$y2 = $height - ($padding*4);
$font_size = ($x2 - $x1) / 4; //Changed line and location
$maxChars = ($font_size * 2) / $padding;
除此更改外,不需要任何其他内容。
受此 code 的启发,我正在尝试创建一个简单的条形图,能够根据 $data 动态创建、调整条形和文本的大小, $身高和$体重:
<?php
$width = 300;
$height = 200;
$font_path = getenv('WINDIR') . DIRECTORY_SEPARATOR . "Fonts" . DIRECTORY_SEPARATOR;
$font = 'arial.ttf';
$data = ['jan'=>30,'fev'=>40,'mar'=>90,'apr'=>77,
'mai'=>33, 'jun'=>44, 'bigggggggg' => 80];
$columns = count($data);
$padding = ($width+$height)/100;
$column_width = $width / $columns;
$image = imagecreate($width, $height);
$gray = imagecolorallocate($image, 0xcc, 0xcc, 0xcc);
$black = imagecolorallocate($image, 0, 0, 0);
$gray_lite = imagecolorallocate($image, 0xee, 0xee, 0xee);
$gray_dark = imagecolorallocate($image, 0x7f, 0x7f, 0x7f);
$white = imagecolorallocate($image, 0xff, 0xff, 0xff);
imagefilledrectangle($image, 0, 0, $width, $height, $white);
$maxv = max($data);
$array_values = array_values($data);
$array_keys = array_keys($data);
for ($i = 0; $i < $columns; $i++) {
$font_size = ($height / 100) * $padding;
$column_height = ($height / 100) * (( $array_values[$i] / $maxv) * 100);
$string = $array_keys[$i];
$x1 = $i * $column_width;
$y1 = $height - $column_height;
$x2 = (($i + 1) * $column_width) - $padding;
$y2 = $height - ($padding*4);
$maxChars = ($font_size * 2) / $padding;
if (strlen($string) > ($maxChars)) {
$string = substr($string, 0, $maxChars) . '...';
}
imagefilledrectangle($image, $x1, $y1, $x2, $y2, $gray);
imagettftext($image, $font_size, 0, $x1, $y2+$font_size+$padding, $black, $font_path.$font,
$string);
imageline($image, $x1, $y1, $x1, $y2, $gray_lite);
imageline($image, $x1, $y2, $x2, $y2, $gray_lite);
imageline($image, $x2, $y1, $x2, $y2, $gray_dark);
}
header("Content-type: image/png");
imagepng($image);
imagedestroy($image);
使用 300x200 没问题:
但使用 600x400:
我该怎么做才能解决这个问题?
您在$padding
的基础上创建了$font_size
,$font_size
在图表大小增长
取而代之,让 $font_size
依赖于条形图的 $height
和 Y
位置,它应该可以正常工作,请试试这个脚本
<?php
$width = 600;
$height = 400;
$font_path = getenv('WINDIR') . DIRECTORY_SEPARATOR . "Fonts" . DIRECTORY_SEPARATOR;
$font = 'arial.ttf';
$data = ['jan'=>30,'fev'=>40,'mar'=>90,'apr'=>77,
'mai'=>33, 'jun'=>44, 'bigggggggg' => 80];
$columns = count($data);
$padding = ($width+$height)/100;
$column_width = $width / $columns;
$image = imagecreate($width, $height);
$gray = imagecolorallocate($image, 0xcc, 0xcc, 0xcc);
$black = imagecolorallocate($image, 0, 0, 0);
$gray_lite = imagecolorallocate($image, 0xee, 0xee, 0xee);
$gray_dark = imagecolorallocate($image, 0x7f, 0x7f, 0x7f);
$white = imagecolorallocate($image, 0xff, 0xff, 0xff);
imagefilledrectangle($image, 0, 0, $width, $height, $white);
$maxv = max($data);
$array_values = array_values($data);
$array_keys = array_keys($data);
for ($i = 0; $i < $columns; $i++) {
$column_height = ($height / 100) * (( $array_values[$i] / $maxv) * 100);
$string = $array_keys[$i];
$x1 = $i * $column_width;
$y1 = $height - $column_height;
$x2 = (($i + 1) * $column_width) - $padding;
$y2 = $height - ($padding*4);
$maxChars = ($font_size * 2) / $padding;
if (strlen($string) > ($maxChars)) {
$string = substr($string, 0, $maxChars) . '...';
}
$font_size = ($height - $y2) / 2.5;
imagefilledrectangle($image, $x1, $y1, $x2, $y2, $gray);
imagettftext($image, $font_size, 0, $x1, $y2+$font_size+$padding, $black, $font_path.$font,
$string);
imageline($image, $x1, $y1, $x1, $y2, $gray_lite);
imageline($image, $x1, $y2, $x2, $y2, $gray_lite);
imageline($image, $x2, $y1, $x2, $y2, $gray_dark);
}
header("Content-type: image/png");
imagepng($image);
imagedestroy($image);
只是 $font_size = ($height - $y2) / 2.5;
尝试一下是否可行。
基本上您的字体大小是 height/100,当高度为 200 时它是有效的,但是当您将高度增加一倍时,我们也需要更改字体大小以匹配它。
看看这是不是你想要的结果MaxInfo.Tech
<?php
$width = 600;
$height = 400;
$font_path = getenv('WINDIR') . DIRECTORY_SEPARATOR . "Fonts" . DIRECTORY_SEPARATOR;
$font = 'arial.ttf';
$data = ['jan'=>30,'fev'=>40,'mar'=>90,'apr'=>77,
'mai'=>33, 'jun'=>44, 'bigggggggg' => 80];
$columns = count($data);
$padding = ($width+$height)/100;
$column_width = $width / $columns;
$image = imagecreate($width, $height);
$gray = imagecolorallocate($image, 0xcc, 0xcc, 0xcc);
$black = imagecolorallocate($image, 0, 0, 0);
$gray_lite = imagecolorallocate($image, 0xee, 0xee, 0xee);
$gray_dark = imagecolorallocate($image, 0x7f, 0x7f, 0x7f);
$white = imagecolorallocate($image, 0xff, 0xff, 0xff);
imagefilledrectangle($image, 0, 0, $width, $height, $white);
$maxv = max($data);
$array_values = array_values($data);
$array_keys = array_keys($data);
for ($i = 0; $i < $columns; $i++) {
$font_size = ($height / 200) * $padding;
$column_height = ($height / 100) * (( $array_values[$i] / $maxv) * 100);
$string = $array_keys[$i];
$x1 = $i * $column_width;
$y1 = $height - $column_height;
$x2 = (($i + 1) * $column_width) - $padding;
$y2 = $height - ($padding*4);
$maxChars = ($font_size * 2) / $padding;
if (strlen($string) > ($maxChars)) {
$string = substr($string, 0, $maxChars) . '...';
}
imagefilledrectangle($image, $x1, $y1, $x2, $y2, $gray);
imagettftext($image, $font_size, 0, $x1, $y2+$font_size+$padding, $black, $font_path.$font,
$string);
imageline($image, $x1, $y1, $x1, $y2, $gray_lite);
imageline($image, $x1, $y2, $x2, $y2, $gray_lite);
imageline($image, $x2, $y1, $x2, $y2, $gray_dark);
}
header("Content-type: image/png");
imagepng($image);
imagedestroy($image);
另请注意,为了更好地格式化它,您还可以将其他基于高度或宽度的变量更改为比 100 的静态分隔符更动态的变量。
只有字体大小计算可以在前面的代码中修复:
$font_size = ($height / 100) * $padding; //Changing this line
$column_height = ($height / 100) * (( $array_values[$i] / $maxv) * 100);
$string = $array_keys[$i];
$x1 = $i * $column_width;
$y1 = $height - $column_height;
$x2 = (($i + 1) * $column_width) - $padding;
$y2 = $height - ($padding*4);
$maxChars = ($font_size * 2) / $padding;
动态更改后如下:
$column_height = ($height / 100) * (( $array_values[$i] / $maxv) * 100);
$string = $array_keys[$i];
$x1 = $i * $column_width;
$y1 = $height - $column_height;
$x2 = (($i + 1) * $column_width) - $padding;
$y2 = $height - ($padding*4);
$font_size = ($x2 - $x1) / 4; //Changed line and location
$maxChars = ($font_size * 2) / $padding;
除此更改外,不需要任何其他内容。