Строим график

Тема в разделе "PHP", создана пользователем B0nuse, 10 дек 2010.

Статус темы:
Закрыта.
Модераторы: latteo
  1. B0nuse

    B0nuse Постоялец

    Регистр.:
    6 июн 2009
    Сообщения:
    105
    Симпатии:
    21
    Задача:
    Есть файл data.txt с данными вида:
    Код:
    01.12.2010;0;0
    01.12.2010;1;1
    01.12.2010;1;2
    01.12.2010;2;3
    02.12.2010;0;4
    02.12.2010;1;3
    02.12.2010;1;2
    03.12.2010;0;3
    03.12.2010;1;2
    03.12.2010;2;1
    03.12.2010;3;0
    и так далее.
    Где значения - дата;час;количество. Значения в файле идут по порядку.
    Есть пхп, создающее массив:
    PHP:
    <?php  
      
    // Файл данных 
      
    $filename "data.txt";  
      if (!
    is_file($filename)) exit("Отсутсвует файл данных"); 
      
    // Читаем содержимое файла 
      
    $arr file($filename); 
      foreach(
    $arr as $line
      { 
        
    $num preg_split("|[;]+|",$line); 
        
    $graph[$num[0]][$num[1]][] = $num[3]; 
      } 
    print_r($graph);
    ?>
    Нужно доделать скрипт, чтобы он создавал график на основе этих данных, где по оси Y - количество, а по оси X - дата и час
    и чтобы он сохранял полученное изображение в файл.
    Соответственно, размер картинки должен определаяться:
    По оси Y - максимальное значение количества + небольшой пустой промежуток снизу и сверху.
    По оси X - количество значений + небольшие промежутки слева и справа.
    Желательны подписи по осям.

    ЗЫ. Навеяно задачей http://www.softtime.ru/info/task.php?id_article=91 и ее примерным решением http://www.softtime.ru/forum/read.php?id_forum=7&id_theme=16872
    ЗЫЫ. Тему можно перенести в раздел "PHP Pro"
     
  2. DenisK

    DenisK

    Регистр.:
    8 фев 2007
    Сообщения:
    205
    Симпатии:
    13
    есть специальные библиотеки php для построения графиков.
    Лучше использовать их.

    например
    http://jpgraph.net/
     
    B0nuse нравится это.
  3. Alternator

    Alternator

    Регистр.:
    23 мар 2009
    Сообщения:
    295
    Симпатии:
    145

    Если без использования библиотек, то вам поможет gd2
     
  4. SiZE

    SiZE Постоялец

    Регистр.:
    31 янв 2010
    Сообщения:
    51
    Симпатии:
    10
    Строить графики за тебя никто не будет бесплатно. Не поймите меня не правильно, подсказать, как сделать можно, но просить готовое решение помоему не правильно.

    Создаешь изображение через imagecreatetruecolor, рисуешь линии через imageline, текст пишешь imagestring.

    Остальное все чистой воды математика.
     
  5. saen

    saen

    Регистр.:
    6 авг 2006
    Сообщения:
    756
    Симпатии:
    129
    а gd2 по-твоему не библиотека? :D
     
  6. B0nuse

    B0nuse Постоялец

    Регистр.:
    6 июн 2009
    Сообщения:
    105
    Симпатии:
    21
    Основная загвоздка в подписях к осям... т.к. у меня три группы данных - две для оси Х и одна для У

    Тогда такой вопрос - как масштабировать картинку?
    У меня около 250тыс значений... и это еще не предел.
    Какие максимальные размеры картинки при построении ее через imagecreatetruecolor?
     
  7. saen

    saen

    Регистр.:
    6 авг 2006
    Сообщения:
    756
    Симпатии:
    129
    да никаких в общем, ограничиваться будет твоими вычислительными мощнностями и настройками php.ini
    но по уму разработчики не делают сразу картинки таких размеров, возьми хоть к примеру google maps или яндекс карты. там изображения подгружаются динамически по мере надобности
     
  8. SiZE

    SiZE Постоялец

    Регистр.:
    31 янв 2010
    Сообщения:
    51
    Симпатии:
    10
    Можно ограничить вывод диапазоном дат, группировать значения, например выводить среднее.
     
  9. B0nuse

    B0nuse Постоялец

    Регистр.:
    6 июн 2009
    Сообщения:
    105
    Симпатии:
    21
    На самом деле, насколько я понял, ограничиваться будет именно количеством записей в массиве, т.е. его размером.
    У меня туда умещается около 250тыс значений, а потом пишет, что не может выделить память...
    Вот набросал скрипт. Вроде работает.
    Как сохранить его результат в файл, чтобы можно было кэшировать?
    Если есть предложения по улучшению самого скрипта создания графика - буду рад выслушать.
    PHP:
    <?php  
      
    // Файл данных 
      
    $filename "data.txt";  
      if (!
    is_file($filename)) exit("Отсутсвует файл данных"); 
      
    // Читаем содержимое файла 
      
    $arr file($filename); 
      
    $i=0;
      foreach(
    $arr as $line){ 
        
    $num preg_split("|[;]+|",$line); 
        
    $d_key explode("."$num[0]);
        
    $date  mktime(000, (int)$d_key[1], (int)$d_key[0], (int)$d_key[2]);
        
    $graph[$i]['date']=(int)$date;
        
    $graph[$i]['hour']=(int)$num[1];
        
    $graph[$i]['usr']=(int)$num[2];
      
    // Высота изображения 
        
    $height max($height,(int)$num[2]); 
        
    $i++;
      } 
      
    // Ширина изображения 
      
    $width=count($arr);
      
    // Масштабируем размеры
      
    $height=$height/10;
      
    $width=$width/100;
      
    // Рисуем изображение
      
    $img imagecreatetruecolor($width 20,$height 30);  
      if (!
    $img) exit("Не удалось создать изображение");  
      
    // Формируем цвета 
      
    $white imagecolorallocate($img255255255);  
      
    $black imagecolorallocate($img000);  
      
    // Фон делаем белым 
      
    imagefill($img11$white);  
      
    // Выводим график 
    // Выводим вертикальные линии по У и подписываем их
    $z=0;
    $z1=50;
    while(
    $z<$height){
    imageline($img,0,$height-$z,$width,$height-$z,$black);
    imagestring($img,1,$width,$height-$z,$z*10,$black);
    $z=$z+$z1;
    }
    // определяем координаты
    $x=0;
    while(
    $x<$width*100){
        
    $y=$height-$graph[$x]['usr']/10;
    // подписываем часы по Х
    if($graph[$x]['hour']>$graph[$x-1]['hour']){
    imagestring($img,1,$x/100,$height+5,$graph[$x]['hour'],$black);
    }
    // подписываем дату по Х
    if($graph[$x]['date']>$graph[$x-1]['date']){
    imagestring($img,1,$x/100,$height+15,date("Y-m-d",$graph[$x]['date']),$black);
    }
    // выводим линии графика
    imageline($img,$x/100,$y,$x1/100,$y1,$black);
    $x1=$x;
    $y1=$y;
    $x=++;
    }
      
    // Отправляем изображение в окно браузера 
      
    header ("Content-type: image/jpeg");  
      
    imagejpeg($img);  
      
    imagedestroy($img);
    ?>
     
  10. SiZE

    SiZE Постоялец

    Регистр.:
    31 янв 2010
    Сообщения:
    51
    Симпатии:
    10
    Ты в imagejpeg указываешь только полученную картинку, а тебе надо еще указать вторым параметром путь по которому она будет сохраняться, и если хочешь третьим качество сжатия JPG (я обычно 90 ставлю)

    bool imagejpeg ( resource $image [, string $filename [, int $quality ]] )
     
    B0nuse нравится это.
Статус темы:
Закрыта.