За последние 24 часа нас посетили 17211 программистов и 1457 роботов. Сейчас ищут 1485 программистов ...

Денежный отчёт(график!?)

Тема в разделе "Сделайте за меня", создана пользователем elektryk, 24 июл 2017.

  1. Maputo

    Maputo Активный пользователь

    С нами с:
    30 июл 2015
    Сообщения:
    1.136
    Симпатии:
    173
    Масштаб графика такой, потому что там идет отсчет от нуля (как я понял). Да и числа воспринимаются не так как надо.
    Их, как минимум надо перевернуть. А по-хорошему - найти наименьшее число. Его приравнять к нулю, а остальные записать в виде разницы дней от наименьшего.
     
  2. elektryk

    elektryk Новичок

    С нами с:
    24 июл 2017
    Сообщения:
    52
    Симпатии:
    4
    да, получается так, в идеальном варианте вертикальная ось это деньги, горизонтальная ось - дни текущего месяца( но совпадения координат должны исходить из текстового файла(то есть в один день ничего нет, а в другой может быть)
    28072017 это будет на отметке 28 по горизонтальной оси
    масштабируемость по вертикальной оси 1:1000 будет достаточной)
    спасибо за помощь)
     
  3. Maputo

    Maputo Активный пользователь

    С нами с:
    30 июл 2015
    Сообщения:
    1.136
    Симпатии:
    173
    @elektryk, если у Вас отчет за 1 месяц, тогда отрезайте месяц и год от дат.
    Например так:
    PHP:
    1. $x = array_map( function( $a )
    2.           {
    3.               return (int)mb_substr( $a, 0, 2 );
    4.           }, $x );
    Получится массив такого вида:
    Код (Text):
    1. array(6) {
    2.   [0]=>  int(23)
    3.   [1]=>  int(24)
    4.   [2]=>  int(27)
    5.   [3]=>  int(19)
    6.   [4]=>  int(24)
    7.   [5]=>  int(27)
    8. }
     
  4. elektryk

    elektryk Новичок

    С нами с:
    24 июл 2017
    Сообщения:
    52
    Симпатии:
    4
    да, одна приход, вторая расход
    --- Добавлено ---
    а из этой конструкции сразу нельзя преобразовать х1?

    PHP:
    1. $array = file("plusXY.txt");
    2.   $x1 = [];
    3.   $y1 = [];
    4.   foreach ( $array as $stroka1) {
    5.   $parts = explode(' ', $stroka1);
    6.   $x1[] = $parts[0];
    7.   $y1[] = $parts[1];
    8.   }
     
    #29 elektryk, 28 июл 2017
    Последнее редактирование модератором: 28 июл 2017
  5. Maputo

    Maputo Активный пользователь

    С нами с:
    30 июл 2015
    Сообщения:
    1.136
    Симпатии:
    173
    Конечно, здесь будет экономичнее сделать преобразование.
     
  6. elektryk

    elektryk Новичок

    С нами с:
    24 июл 2017
    Сообщения:
    52
    Симпатии:
    4
    и как я понимаю можно же сначала выяснить количество дней в месяце, - это будет горизонтальные точки или 28(29) или 30(31)
    денежную вертикальную ось поделить на 1000 )
     
  7. Maputo

    Maputo Активный пользователь

    С нами с:
    30 июл 2015
    Сообщения:
    1.136
    Симпатии:
    173
    @elektryk, масштаб у Вас вычисляется автоматически по максимальным значениям:
    PHP:
    1. //объединяем данные из массивов данных для вычисления масштаба
    2.     $x=array_merge($x1,$x2);
    3.     $y=array_merge($y1,$y2);
    4.     //получаем максимальные значения элементов для каждого массива
    5.     $maxXVal=max($x);
    6.     $maxYVal=max($y);
    7.     //вычисляем масштаб преобразования данных в координаты рабочей области
    8.     $scaleX=($maxX-$x0)/$maxXVal;
    9.     $scaleY=($maxY-$y0)/$maxYVal;
    10.     //задаем шаг для координатной сетки в пикселах
    11.     $xStep=30;
    12.     $yStep=30;
    Либо, нужно будет подправить под свои задачи эту часть скрипта.
    Нашел начало координат) Все же не ноль:
    PHP:
    1. global $im, $black, $l_grey, $x0, $y0, $maxX, $maxY;
    2.     $x0=25.0; //начало оси координат по X
    3.     $y0=20.0; //начало оси координат по Y
     
  8. elektryk

    elektryk Новичок

    С нами с:
    24 июл 2017
    Сообщения:
    52
    Симпатии:
    4
    и ещё такой вопрос, текстовые файлы plusXY.txt и minusXY.txt пишутся непрерывно, если , как пример, взять срез в 1 год, то как на начало какого-то месяца указать на графике не ноль для начальных точек? и можно ли будет полностью год в график уместить? это отдельно график нужно будет делать?
     
  9. Maputo

    Maputo Активный пользователь

    С нами с:
    30 июл 2015
    Сообщения:
    1.136
    Симпатии:
    173
    В цикле, где создаются массивы, добавляете условие. В этом условии сравниваете дату с шаблоном требуемого месяца.
    Если захотите целый год уместить, то даты придется обрабатывать - немного изменится логика.
     
  10. elektryk

    elektryk Новичок

    С нами с:
    24 июл 2017
    Сообщения:
    52
    Симпатии:
    4
    хорошо, с теорией вроде бы как понятно, теперь как это на практике решить?
    1) вычислить текущий месяц по счёту, передать количество дней этого месяца в горизонтальную ось
    2) привязать к координатной сетке по горизонтальной оси даты из массива, чтобы были на своём месте
    3) учесть что начало линий графиков могут быть не в нуле, хотя это очень спорно.(вертикальная ось)
    как-то так)
     
  11. Maputo

    Maputo Активный пользователь

    С нами с:
    30 июл 2015
    Сообщения:
    1.136
    Симпатии:
    173
    @elektryk, чисто мое мнение:
    1. Выбрать только текущий месяц:
    PHP:
    1. $shablon = '/' . date('mY') . '$/';
    2. ...
    3. if(preg_match($shablon, $parts[0])
    4. {
    5.     ...
    6. }
    Количество дней месяца:
    PHP:
    1. $number = cal_days_in_month( CAL_GREGORIAN, 7, 2017 );
    2. // или
    3. $number = cal_days_in_month( CAL_GREGORIAN, date('n'), date('Y') );
    2. Переписать функцию, рисующую даты. Там есть строка:
    PHP:
    1. //при необходимости выводим значения линий сетки по оси X
    2. ImageString($im, 1, ($x0+$xStep*$i)-1, $maxY+2, $i*$xCoef, $black);
    где $xStep - расстояние в пикселах между линиями сетки
    $xCoef - разность значения X между линиями сетки
    Вместо $i*$xCoef можно написать формулу, вычисляющую дату для каждого деления сетки.

    3. Чтобы не заморачиваться - начало по Y можно сделать в нуле, а по X - в единице.
     
    #36 Maputo, 28 июл 2017
    Последнее редактирование: 28 июл 2017
  12. denis01

    denis01 Суперстар
    Команда форума Модератор

    С нами с:
    9 дек 2014
    Сообщения:
    12.227
    Симпатии:
    1.714
    Адрес:
    Молдова, г.Кишинёв
  13. elektryk

    elektryk Новичок

    С нами с:
    24 июл 2017
    Сообщения:
    52
    Симпатии:
    4
    PHP:
    1. <?php
    2. $god = date('Y');
    3. $mesac = date('m');
    4. $number = cal_days_in_month(CAL_GREGORIAN, $mesac, $god);
    5. echo "{$number} days in $mesac $god";
    6. ?>
     
  14. elektryk

    elektryk Новичок

    С нами с:
    24 июл 2017
    Сообщения:
    52
    Симпатии:
    4
    хорошо, количество дней определили.
    теперь их надо расположить по горизонтальной оси
    а переменные обоих графиков горизонтальной оси привести в приятный вид
     
  15. Maputo

    Maputo Активный пользователь

    С нами с:
    30 июл 2015
    Сообщения:
    1.136
    Симпатии:
    173
    @elektryk, что значит "приятный вид"? Как Вы хотите отобразить даты?
    В приведенном Вами скрипте шаг сетки, ширина изображения и количество значений задаются пользователем. Они взаимосвязаны. Одно из них должно вычисляться из двух других.
     
  16. elektryk

    elektryk Новичок

    С нами с:
    24 июл 2017
    Сообщения:
    52
    Симпатии:
    4
    суммы
    15000
    10000
    5000
    500
    1 2 3 4 ..... 31 числа месяца
     
  17. Maputo

    Maputo Активный пользователь

    С нами с:
    30 июл 2015
    Сообщения:
    1.136
    Симпатии:
    173
    @elektryk, вот Ваша функция, которая рисует сетку:
    PHP:
    1. function draw_grid($xStep,$yStep,$xCoef,$yCoef)
    2. {
    3.     global $im,$black,$l_grey,$x0,$y0,$maxX,$maxY;
    4.     $xSteps=($maxX-$x0)/$xStep-1; //определяем количество шагов по оси X
    5.     $ySteps=($maxY-$y0)/$yStep-1; //определяем количество шагов по оси Y
    6.     for($i=1;$i<$xSteps+1;$i++)   //выводим сетку по оси X
    7.         {
    8.         imageline($im, $x0+$xStep*$i, $y0, $x0+$xStep*$i, $maxY-1, $l_grey);
    9.         //при необходимости выводим значения линий сетки по оси X
    10.         ImageString($im, 1, ($x0+$xStep*$i)-1, $maxY+2, $i*$xCoef, $black);
    11.         }
    12.     for($i=1;$i<$ySteps+1;$i++)
    13.         {
    14.         imageline($im, $x0+1, $maxY-$yStep*$i, $maxX, $maxY-$yStep*$i, $l_grey);
    15.         //при необходимости выводим значения линий сетки по оси Y
    16.         ImageString($im, 1, 0, ($maxY-$yStep*$i)-3, $i*$yCoef, $black);
    17.         }
    18. }
    Количество шагов по X у Вас известно, а оно вычисляется исходя из размера ячейки сетки и ширины изображения. Должно быть наоборот.
    PHP:
    1. function draw_grid($count_days,$yStep,$xCoef,$yCoef)
    2. {
    3.     global $im,$black,$l_grey,$x0,$y0,$maxX,$maxY;
    4.    $xStep = ($maxX - $x0) / $count_days;
    5.    $ySteps=...
    6.     for($i=1;$i < $count_days + 1;$i++)   //выводим сетку по оси X
    7.         {
    8.         imageline($im, $x0+$count_days * $i, $y0, $x0+$xStep*$i, $maxY-1, $l_grey);
    9.         //при необходимости выводим значения линий сетки по оси X
    10.         ImageString($im, 1, ($x0+$xStep*$i)-1, $maxY+2, $i, $black);
    11.         }
    12.     for($i=1;$i<$ySteps+1;$i++)
    13.         {
    14.         ...
    15.         }
    16. }
    И вместо вот этого:
    PHP:
    1. //рисуем координатную сетку
    2.     draw_grid($xStep,$yStep, round($xStep/$scaleX,1), round($yStep/$scaleY,1), true);
    Пишите вот это:
    PHP:
    1. //рисуем координатную сетку
    2.     draw_grid($number, $yStep, round($xStep/$scaleX,1), round($yStep/$scaleY,1), true);
    По оси Y размерность сетки будет зависить от максимального значения. Но принцип правки тот же.
     
  18. elektryk

    elektryk Новичок

    С нами с:
    24 июл 2017
    Сообщения:
    52
    Симпатии:
    4
    вечер добрый.)
    ySteps и yStep есть разница? а то что-то не сходится(
     
  19. Maputo

    Maputo Активный пользователь

    С нами с:
    30 июл 2015
    Сообщения:
    1.136
    Симпатии:
    173
    Это Вы у меня спрашиваете? Конечно есть) Это разные переменные и не я их придумал. ;)
     
  20. elektryk

    elektryk Новичок

    С нами с:
    24 июл 2017
    Сообщения:
    52
    Симпатии:
    4
    в оригинале
    PHP:
    1. global $im,$black,$l_grey,$x0,$y0,$maxX,$maxY;
    2.     $xSteps=($maxX-$x0)/$xStep-1; //определяем количество шагов по оси X
    3.     $ySteps=($maxY-$y0)/$yStep-1; //определяем количество шагов по оси Y
    и с s и без, график не получается(
    ошибка изображения
    в логах PHP Warning: imageline() expects parameter 3 to be integer, float given in
     
  21. Maputo

    Maputo Активный пользователь

    С нами с:
    30 июл 2015
    Сообщения:
    1.136
    Симпатии:
    173
    В оригинале y0 и был float. Почему у Вас раньше работало - удивительно. Добавьте (int) перед y0 в этой функции. или round(y0). Кстати следующий параметр тоже необходимо round()
    Мне вообще странно, что этот код работал с теми именами функций, что там есть.
     
  22. elektryk

    elektryk Новичок

    С нами с:
    24 июл 2017
    Сообщения:
    52
    Симпатии:
    4
    может попунктно вообще сделать другой график, этот слишком замысловат и я в нём плыву.
    исходные два текстовых файла с записями есть и только от них можно отталкиваться.
    чтобы мне самой разобраться, так сказать)
     
  23. Maputo

    Maputo Активный пользователь

    С нами с:
    30 июл 2015
    Сообщения:
    1.136
    Симпатии:
    173
    Правильно мыслите. Я бы уточнил, что исходник не замысловат, а кривоват.
    Теперь от Вас нужно ТЗ. Какие требования к графику? К функционалу и т.п.
    Например, я до сих пор не могу понять - оба графика должны идти по возрастающей или отображать сумму прихода/расхода в какой-то день? И должны ли суммироваться приходы/расходы, если их несколько в один день?
     
    elektryk нравится это.
  24. elektryk

    elektryk Новичок

    С нами с:
    24 июл 2017
    Сообщения:
    52
    Симпатии:
    4
    Спасибо, за поддержку)
    можно я свои имена переменным давать буду?
    1) определяем количество дней в месяце:
    PHP:
    1. $god = date('Y');
    2. $mesac = date('m');
    3. $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 скриптом, и суммируются им же.

    график- лишь динамичная картинка, берущая данные из двух текстовых файлов, самостоятельные расчёты не нужны)


    Фухх, вот....
     
    Maputo нравится это.
  25. Maputo

    Maputo Активный пользователь

    С нами с:
    30 июл 2015
    Сообщения:
    1.136
    Симпатии:
    173
    @elektryk, Имена вы можете давать какие хотите, но по функционалу у меня сразу возникают возражения. Может просто надо перефразировать Ваши пункты.

    1. Представьте, что вы создаете скрипт, в который нужно загрузить данные и вывести их в нужном формате. Даты и количество дней - это нужно, но не в том месте, где будете использовать Ваш скрипт.
    2. Тут просто достаточно предусмотреть вывод графика любого размера
    3. Согласен. Даты надо преобразовывать.
    4. Вот тут непонятно... Как суммы должны отображаться на графике? Конкретное значение за определенный день или сумма всех предыдущих значений?
    5. В предыдущем примере у Вас было несколько сумм в один день.

    P.S.: Какой стиль программирования Вам ближе? Процедурный, модульный или объектно-ориентированный?

    Я представляю такую логику скрипта:
    PHP:
    1. // создаем график обозначая год
    2. $variable = new Grafik(2017);
    3. // добавляем приход
    4. $variable -> add_data('имя файла1', 'green');
    5. // добавляем расход
    6. $variable -> add_data('имя файла2', 'red');
    7. // выводим график нужного размера за нужный период (7 - июль)
    8. $variable -> display(1024, 768, 7);
    9. // или за весь год
    10. $variable -> display(1024, 768);
     
    #50 Maputo, 30 июл 2017
    Последнее редактирование: 30 июл 2017