Масштаб графика такой, потому что там идет отсчет от нуля (как я понял). Да и числа воспринимаются не так как надо. Их, как минимум надо перевернуть. А по-хорошему - найти наименьшее число. Его приравнять к нулю, а остальные записать в виде разницы дней от наименьшего.
да, получается так, в идеальном варианте вертикальная ось это деньги, горизонтальная ось - дни текущего месяца( но совпадения координат должны исходить из текстового файла(то есть в один день ничего нет, а в другой может быть) 28072017 это будет на отметке 28 по горизонтальной оси масштабируемость по вертикальной оси 1:1000 будет достаточной) спасибо за помощь)
@elektryk, если у Вас отчет за 1 месяц, тогда отрезайте месяц и год от дат. Например так: PHP: $x = array_map( function( $a ) { return (int)mb_substr( $a, 0, 2 ); }, $x ); Получится массив такого вида: Код (Text): array(6) { [0]=> int(23) [1]=> int(24) [2]=> int(27) [3]=> int(19) [4]=> int(24) [5]=> int(27) }
да, одна приход, вторая расход --- Добавлено --- а из этой конструкции сразу нельзя преобразовать х1? PHP: $array = file("plusXY.txt"); $x1 = []; $y1 = []; foreach ( $array as $stroka1) { $parts = explode(' ', $stroka1); $x1[] = $parts[0]; $y1[] = $parts[1]; }
и как я понимаю можно же сначала выяснить количество дней в месяце, - это будет горизонтальные точки или 28(29) или 30(31) денежную вертикальную ось поделить на 1000 )
@elektryk, масштаб у Вас вычисляется автоматически по максимальным значениям: PHP: //объединяем данные из массивов данных для вычисления масштаба $x=array_merge($x1,$x2); $y=array_merge($y1,$y2); //получаем максимальные значения элементов для каждого массива $maxXVal=max($x); $maxYVal=max($y); //вычисляем масштаб преобразования данных в координаты рабочей области $scaleX=($maxX-$x0)/$maxXVal; $scaleY=($maxY-$y0)/$maxYVal; //задаем шаг для координатной сетки в пикселах $xStep=30; $yStep=30; Либо, нужно будет подправить под свои задачи эту часть скрипта. Нашел начало координат) Все же не ноль: PHP: global $im, $black, $l_grey, $x0, $y0, $maxX, $maxY; $x0=25.0; //начало оси координат по X $y0=20.0; //начало оси координат по Y
и ещё такой вопрос, текстовые файлы plusXY.txt и minusXY.txt пишутся непрерывно, если , как пример, взять срез в 1 год, то как на начало какого-то месяца указать на графике не ноль для начальных точек? и можно ли будет полностью год в график уместить? это отдельно график нужно будет делать?
В цикле, где создаются массивы, добавляете условие. В этом условии сравниваете дату с шаблоном требуемого месяца. Если захотите целый год уместить, то даты придется обрабатывать - немного изменится логика.
хорошо, с теорией вроде бы как понятно, теперь как это на практике решить? 1) вычислить текущий месяц по счёту, передать количество дней этого месяца в горизонтальную ось 2) привязать к координатной сетке по горизонтальной оси даты из массива, чтобы были на своём месте 3) учесть что начало линий графиков могут быть не в нуле, хотя это очень спорно.(вертикальная ось) как-то так)
@elektryk, чисто мое мнение: 1. Выбрать только текущий месяц: PHP: $shablon = '/' . date('mY') . '$/'; ... if(preg_match($shablon, $parts[0]) { ... } Количество дней месяца: PHP: $number = cal_days_in_month( CAL_GREGORIAN, 7, 2017 ); // или $number = cal_days_in_month( CAL_GREGORIAN, date('n'), date('Y') ); 2. Переписать функцию, рисующую даты. Там есть строка: PHP: //при необходимости выводим значения линий сетки по оси X ImageString($im, 1, ($x0+$xStep*$i)-1, $maxY+2, $i*$xCoef, $black); где $xStep - расстояние в пикселах между линиями сетки $xCoef - разность значения X между линиями сетки Вместо $i*$xCoef можно написать формулу, вычисляющую дату для каждого деления сетки. 3. Чтобы не заморачиваться - начало по Y можно сделать в нуле, а по X - в единице.
@elektryk оформление кода https://php.ru/forum/threads/tipichnyj-dialog-s-novichkom.59596/#post-527225
PHP: <?php $god = date('Y'); $mesac = date('m'); $number = cal_days_in_month(CAL_GREGORIAN, $mesac, $god); echo "{$number} days in $mesac $god"; ?>
хорошо, количество дней определили. теперь их надо расположить по горизонтальной оси а переменные обоих графиков горизонтальной оси привести в приятный вид
@elektryk, что значит "приятный вид"? Как Вы хотите отобразить даты? В приведенном Вами скрипте шаг сетки, ширина изображения и количество значений задаются пользователем. Они взаимосвязаны. Одно из них должно вычисляться из двух других.
@elektryk, вот Ваша функция, которая рисует сетку: PHP: function draw_grid($xStep,$yStep,$xCoef,$yCoef) { global $im,$black,$l_grey,$x0,$y0,$maxX,$maxY; $xSteps=($maxX-$x0)/$xStep-1; //определяем количество шагов по оси X $ySteps=($maxY-$y0)/$yStep-1; //определяем количество шагов по оси Y for($i=1;$i<$xSteps+1;$i++) //выводим сетку по оси X { imageline($im, $x0+$xStep*$i, $y0, $x0+$xStep*$i, $maxY-1, $l_grey); //при необходимости выводим значения линий сетки по оси X ImageString($im, 1, ($x0+$xStep*$i)-1, $maxY+2, $i*$xCoef, $black); } for($i=1;$i<$ySteps+1;$i++) { imageline($im, $x0+1, $maxY-$yStep*$i, $maxX, $maxY-$yStep*$i, $l_grey); //при необходимости выводим значения линий сетки по оси Y ImageString($im, 1, 0, ($maxY-$yStep*$i)-3, $i*$yCoef, $black); } } Количество шагов по X у Вас известно, а оно вычисляется исходя из размера ячейки сетки и ширины изображения. Должно быть наоборот. PHP: function draw_grid($count_days,$yStep,$xCoef,$yCoef) { global $im,$black,$l_grey,$x0,$y0,$maxX,$maxY; $xStep = ($maxX - $x0) / $count_days; $ySteps=... for($i=1;$i < $count_days + 1;$i++) //выводим сетку по оси X { imageline($im, $x0+$count_days * $i, $y0, $x0+$xStep*$i, $maxY-1, $l_grey); //при необходимости выводим значения линий сетки по оси X ImageString($im, 1, ($x0+$xStep*$i)-1, $maxY+2, $i, $black); } for($i=1;$i<$ySteps+1;$i++) { ... } } И вместо вот этого: PHP: //рисуем координатную сетку draw_grid($xStep,$yStep, round($xStep/$scaleX,1), round($yStep/$scaleY,1), true); Пишите вот это: PHP: //рисуем координатную сетку draw_grid($number, $yStep, round($xStep/$scaleX,1), round($yStep/$scaleY,1), true); По оси Y размерность сетки будет зависить от максимального значения. Но принцип правки тот же.
в оригинале PHP: global $im,$black,$l_grey,$x0,$y0,$maxX,$maxY; $xSteps=($maxX-$x0)/$xStep-1; //определяем количество шагов по оси X $ySteps=($maxY-$y0)/$yStep-1; //определяем количество шагов по оси Y и с s и без, график не получается( ошибка изображения в логах PHP Warning: imageline() expects parameter 3 to be integer, float given in
В оригинале y0 и был float. Почему у Вас раньше работало - удивительно. Добавьте (int) перед y0 в этой функции. или round(y0). Кстати следующий параметр тоже необходимо round() Мне вообще странно, что этот код работал с теми именами функций, что там есть.
может попунктно вообще сделать другой график, этот слишком замысловат и я в нём плыву. исходные два текстовых файла с записями есть и только от них можно отталкиваться. чтобы мне самой разобраться, так сказать)
Правильно мыслите. Я бы уточнил, что исходник не замысловат, а кривоват. Теперь от Вас нужно ТЗ. Какие требования к графику? К функционалу и т.п. Например, я до сих пор не могу понять - оба графика должны идти по возрастающей или отображать сумму прихода/расхода в какой-то день? И должны ли суммироваться приходы/расходы, если их несколько в один день?
Спасибо, за поддержку) можно я свои имена переменным давать буду? 1) определяем количество дней в месяце: PHP: $god = date('Y'); $mesac = date('m'); $number = cal_days_in_month(CAL_GREGORIAN, $mesac, $god); 2) определяем границы экрана, в котором будем рисовать график: ? 3) так как формат данных в текстовых файлах идёт своеобразный, нужно определять из них текущий месяц и убирать МесяцГод из первого столбца, переводя в переменную для горизонтальной оси лишь дни. Формат данных в текстовых файлах, пример: 23072017 10000 24072017 10000 27072017 51000 28072017 315000 30072017 50000 4) исходя из всего этого точки на графике должны быть в таком порядке(если Х принимаем за горизонтальную, а Y за вертикальную оси) x1(0)=(первое число для текущего месяца, найденное в текстовом файле) y1(0)=(значение в той же строке, в денежном эквиваленте) Так как текстовые файлы пополняются исключительно если есть какая-то сумма, автоматом добавляется и дата. формируется отчет, непрерывный, для всего периода работы этой системы. 5)координатная сетка по X = количеству дней текущего месяца по Y= максимальное значение (или приход, или расход)за текущий месяц, тут наверное придётся от приходов-расходов отталкиваться P.S. приходы-расходы формируются сторонним bash скриптом, и суммируются им же. график- лишь динамичная картинка, берущая данные из двух текстовых файлов, самостоятельные расчёты не нужны) Фухх, вот....
@elektryk, Имена вы можете давать какие хотите, но по функционалу у меня сразу возникают возражения. Может просто надо перефразировать Ваши пункты. 1. Представьте, что вы создаете скрипт, в который нужно загрузить данные и вывести их в нужном формате. Даты и количество дней - это нужно, но не в том месте, где будете использовать Ваш скрипт. 2. Тут просто достаточно предусмотреть вывод графика любого размера 3. Согласен. Даты надо преобразовывать. 4. Вот тут непонятно... Как суммы должны отображаться на графике? Конкретное значение за определенный день или сумма всех предыдущих значений? 5. В предыдущем примере у Вас было несколько сумм в один день. P.S.: Какой стиль программирования Вам ближе? Процедурный, модульный или объектно-ориентированный? Я представляю такую логику скрипта: PHP: // создаем график обозначая год $variable = new Grafik(2017); // добавляем приход $variable -> add_data('имя файла1', 'green'); // добавляем расход $variable -> add_data('имя файла2', 'red'); // выводим график нужного размера за нужный период (7 - июль) $variable -> display(1024, 768, 7); // или за весь год $variable -> display(1024, 768);