Проблема - значения настолько велики что
при выводе координатной оси они накладываются одно на другое
Как красиво оформить?
Или чтобы на координатной оси выводились не все значения от 0 до максимума а конкретные из таблицы?
Код не мой из учебного пособия...
//---------------------------------------------------------------------------------------------------------------------------------------------------------------
Свернутый текст
define('GRAPH_WIDTH', 800); // ширина картинки
define('GRAPH_HEIGHT', 700); // высота картинки
define('GRAPH_OFFSET_TOP', 40); // отступ сверху
define('GRAPH_OFFSET_LEFT', 40); // отступ слева
define('GRAPH_OFFSET_RIGHT', 5); // отстут справа
define('GRAPH_OFFSET_BOTTOM', 30); // отступ снизу
define('FONT_NAME', 'arial.ttf'); // Имя шрифта
define('FONT_SIZE', 12); // Размер шрифта
$colors = array(0xFF0000,0x00FF00,0x0000FF, // цвета столбцов
0xFFFF00,0x00FFFF,0xFF00FF);
require('win2uni.php');
// Считаем ширину столбцов
$col_width = (GRAPH_WIDTH - GRAPH_OFFSET_LEFT - GRAPH_OFFSET_RIGHT) / count($Data);
// Считаем высоту столбца, соответствующего максимальному значению
$col_maxheight = (GRAPH_HEIGHT - GRAPH_OFFSET_TOP - GRAPH_OFFSET_BOTTOM);
// Ищем максимальное значение в массиве, соответствующее столбцу максимальной высоты
$max_value = max($Data);
$image = imagecreatetruecolor(GRAPH_WIDTH,GRAPH_HEIGHT) // создаем изображение...
or die('Мимо изо нет'); // ...или прерываем работу скрипта в случае ошибки
imagefill($image, 0, 0, 0xFFFFFF); // белый фон
// рисуем столбцы
$x = GRAPH_OFFSET_LEFT;
$y = GRAPH_OFFSET_TOP + $col_maxheight;
$i = 0;
foreach($Data as $name => $value) {
imagefilledrectangle( // рисуем сплошной прямоугольник
$image,
$x,
$y - round($value*$col_maxheight/$max_value),
$x + $col_width - 1,
$y,
$colors[$i++%count($colors)]
);
// Выводим текст:
// .. преобразование в Unicode...
$text = win2uni($name);
// .. расчет координат...
$coord = imagettfbbox(FONT_SIZE,0,FONT_NAME,$text);
$text_x = $x + ($col_width - $coord[2] - $coord[0]) / 2;
$text_y = GRAPH_HEIGHT - 5;
// .. и вывод текста
imagettftext($image,FONT_SIZE,0,$text_x,$text_y,0x000000,FONT_NAME,$text);
$x += $col_width;
}
// Выводим заголовок
$text = win2uni($Title);
$coord = imagettfbbox(FONT_SIZE,0,FONT_NAME,$text);
$text_x = $x + ($col_width - $coord[2] - $coord[0]) / 2;
$text_y = (GRAPH_OFFSET_TOP - $coord[1] - $coord[7]) / 2;
imagettftext($image,FONT_SIZE,0,$text_x,$text_y,0x000000,FONT_NAME,$text);
// рисуем координатную ось Вот здесь вся загвоздка значения накладываются одно на другое если они мин(до30) нормально а когда больше 600 то пипец...
imageline($image, GRAPH_OFFSET_LEFT - 10, GRAPH_OFFSET_TOP,
GRAPH_OFFSET_LEFT - 5, $y, 0xCCCCCC);
for($value=0;$value<=$max_value;$value++)
{
imageline($image, GRAPH_OFFSET_LEFT - 7,
$Y = $y - round($value*$col_maxheight/$max_value),
GRAPH_OFFSET_LEFT - 5, $Y, 0xCCCCCC);
imagestring($image, 1, GRAPH_OFFSET_LEFT / 2, $Y - 4, $value, 0x000000);
}
header('Content-type: image/png');
imagepng($image);
imagedestroy($image);
?>
Спустя 1 час, 5 минут, 6 секунд (21.03.2010 - 12:59) jetistyum написал(а):
ну так зачем тебе учебное пособие? ты просто переписываешь и все*? попробуй понять логику и исправить как тебе нужно

Спустя 9 минут, 27 секунд (21.03.2010 - 13:09) sergeiss написал(а):
Цитата (F_Z @ 21.03.2010 - 12:54) |
Проблема - значения настолько велики что при выводе координатной оси они накладываются одно на другое Как красиво оформить? |
Вот честно скажу - даже не смотрел твой код


Общий ответ на твой вопрос - выводи значения наклонно, вплоть до вертикального (если требуется). Тогда ты сможешь получить требуемый результат, и чтобы при этом еще и эстетично всё было.
PS. Вот как тут, например: http://owndesign.ru/tests/rotate/rotate_graph_2d_test2.php; эту картинку я рисовал, подробнее про историю ее появления тут: http://phpforum.ru/index.php?showtopic=22888&hl=
Спустя 36 минут, 41 секунда (21.03.2010 - 13:45) F_Z написал(а):
Я думаю что не надо рисовать координаты каждой точки.
Нарисуем координаты независимо от числа данных, а в зависимости от мин/макс значений.
Например если Макс = 1123, Мин = 1000, (Макс - Мин = 123), делим длину диапазона на 10 или 20 интервалов (это число меток на оси), получаем 12.3 или 6.15, берем ближайшее кратное степени 10, в данном случае это будет 10.
Делим диапазон с шагом 10, получаем ряд - {1000,1010,1020,....,1100,1110,1120,1130}
В этих точках и рисуем метки.
???? м...
Нарисуем координаты независимо от числа данных, а в зависимости от мин/макс значений.
Например если Макс = 1123, Мин = 1000, (Макс - Мин = 123), делим длину диапазона на 10 или 20 интервалов (это число меток на оси), получаем 12.3 или 6.15, берем ближайшее кратное степени 10, в данном случае это будет 10.
Делим диапазон с шагом 10, получаем ряд - {1000,1010,1020,....,1100,1110,1120,1130}
В этих точках и рисуем метки.
???? м...

Спустя 11 минут, 41 секунда (21.03.2010 - 13:57) sergeiss написал(а):
F_Z - ну, если речь идет именно о том, что значения накладываются потому, что их много, то да, лучше будет сделать так, как ты описал.
Спустя 14 минут, 48 секунд (21.03.2010 - 14:12) F_Z написал(а):
Их не особо много просто максимальное значение может быть очень большим
наверное должно быть примерно так поправьте если что..
как то так? щас попробую...
наверное должно быть примерно так поправьте если что..
$min_value=0;
//Рисуем координатную линию
for($value=0;$value<=$max_value;$value++)
{
imageline($image, GRAPH_OFFSET_LEFT - 7,
$Y = $y - round($value*$col_maxheight/$max_value),
GRAPH_OFFSET_LEFT - 5, $Y, 0xCCCCCC);
//Вот здесь собственно расставляем подписи (наверное нужен еще один цикл?)
for($value1=0;$value1<=$z;$z=floor(($max_value - $min_value)/20);
$value1++)
{
imagestring($image, 1, GRAPH_OFFSET_LEFT / 2, $Y , $value1, 0x000000);
}
}
как то так? щас попробую...

Спустя 3 минуты, 59 секунд (21.03.2010 - 14:16) sergeiss написал(а):
Вот, поискал у себя в коде. В подобной ситуации вывожу подписи так:
Почему число 30? Чисто эмпирически подобрано было
Для моего конкретного случая
PS. И еще... Когда выводишь большой текст, то заключай его, плз, в специальные тэги. Чтобы его можно было развернуть только тогда, когда он нужен (я это про первое сообщение темы, я там уже проделал сию процедуру, чтобы было понятнее, о чем речь идет).
// $axe_h - массив подписей оси Х
$koef_h_out=ceil( count( $axe_h ) / 30.0 ) ;
$axe_h_index=-1;
foreach( $axe_h as $key => $val )
{
..... // тут идет вывод засечек на горизонтальной линии - выводятся все
$axe_h_index ++;
if( $axe_h_index % $koef_h_out !=0 ) continue; // пропуск вывода отдельных значений, когда их много
.... // вывод подписей, под углом 45 градусов
}
Почему число 30? Чисто эмпирически подобрано было

PS. И еще... Когда выводишь большой текст, то заключай его, плз, в специальные тэги. Чтобы его можно было развернуть только тогда, когда он нужен (я это про первое сообщение темы, я там уже проделал сию процедуру, чтобы было понятнее, о чем речь идет).
Спустя 14 минут, 24 секунды (21.03.2010 - 14:30) F_Z написал(а):
Спасибо за пример. Интересно?
Только у меня по оси Х, выводятся названия
(по Y кол.во)
А вот если я хочу что бы подписи по Х вертикально выводились?
Только у меня по оси Х, выводятся названия
(по Y кол.во)
А вот если я хочу что бы подписи по Х вертикально выводились?
Спустя 19 минут, 30 секунд (21.03.2010 - 14:50) F_Z написал(а):
Да вопрос в твоем примере переменная $key это?
Спустя 10 минут, 43 секунды (21.03.2010 - 15:01) sergeiss написал(а):
Цитата (F_Z @ 21.03.2010 - 15:50) |
Да вопрос в твоем примере переменная $key это? |
Хм... Вообще-то, это основы ПХП, цикл foreach

foreach( $axe_h as $key => $val )
{
...
}
Проходим по циклу $axe_h, на каждом шаге выбирая один элемент массива, записывая в переменную $key ключ этого элемента, а в $val - величину именно этого же элемента.
Внутри цикла используем эти значения для любых целей.
Цитата (F_Z @ 21.03.2010 - 15:30) |
А вот если я хочу что бы подписи по Х вертикально выводились? |
Задай угол при выводе данных...
Полностью мой код выглядит так (ранее я убрал то, что не было важно для ответа на вопрос)
$koef_h_out=ceil( count( $axe_h ) / 30.0 ) ;
$axe_h_index=-1;
foreach( $axe_h as $key => $val )
{
$left=$pad['left'] + $step['x']*$key;
$top=$size['y']-$pad['bottom'];
imageline( $image, $left, $top-3, $left, $top+3, $colors['axe_h']);
$axe_h_index ++;
if( $axe_h_index % $koef_h_out !=0 ) continue; // пропуска вывода отдельных значений, когда их много
$textsize=GetTextSize( $ttfsize, 45, "arial.ttf", $val);
$left=$pad['left'] + $step['x']*$key - $textsize['width']/2;
$top=$size['y']-$pad['bottom']+$textsize['height']+50;
imagettftext( $image, $ttfsize, 45, $left, $top, $colors['text'], "arial.ttf", $val);
}