Pergunta

Eu tenho alguns dados de um banco de dados (SQLite), mapeando um valor (um inteiro) para uma data. A data é uma string com este formato: YYYY-MM-DD hh:mm. As datas não são uniformemente distribuídos. Eu quero fazer desenhar um gráfico de linha com as datas em X e os valores sobre Y. Qual é a maneira mais fácil de fazer isso com Perl?

Eu tentei DBIx :: Gráfico mas eu não poderia fazê-lo reconhecer minhas datas . Eu também tentei GD :: Graph , mas como a documentação diz:

GD :: Graph não suporta numérica x eixo da maneira que deveria. Dados para X eixos devem ser igualmente espaçadas

Foi útil?

Solução

Você pode dirigir gnuplot usando Gráfico :: Gnuplot .

Como alternativa, se SVG é um formato de saída aceitável, há SVG :: TT :: Graph .

Outras dicas

Você pode usar Chart :: do Clicker Axis :: DateTime:

#!/usr/local/bin/perl -w
use strict;
use Chart::Clicker;
use Chart::Clicker::Axis::DateTime;
use Chart::Clicker::Data::Series;
use Chart::Clicker::Data::DataSet;
use Chart::Clicker::Renderer::Point;

my $cc = Chart::Clicker->new;
my $series = Chart::Clicker::Data::Series->new(
    values    => [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ],
    keys      => [
        1256147117, 1256148117, 1256149117, 1256150117, 1256151117, 1256152117,
        1256153117, 1256154117, 1256155117, 1256156117
    ],
);
my $ctx = $cc->get_context('default');
$ctx->domain_axis(Chart::Clicker::Axis::DateTime->new(position => 'bottom', orientation     => 'horizontal'));
my $ds = Chart::Clicker::Data::DataSet->new(series => [ $series ]);
$cc->add_to_datasets($ds);
$cc->write_output('foo.png');

Você tem que converter seus tempos em Unix timestamps, mas DWIMs.

Eu tentei DBIx :: Gráfico mas eu não poderia fazê-lo reconhecer minhas datas.

Você já tentou traduzir suas datas para Unix-Timestamps e usá-los como datas X?

Este fez o truque para mim:

my $ctx = $chart->get_context('default');
$ctx->domain_axis(
    Chart::Clicker::Axis::DateTime->new(
        position        => 'bottom',
        orientation     => 'horizontal',
        ticks           => 5 ,
        format          => "%Y-%m-%d"
    )
);

A maneira mais fácil que eu encontrei para fazer isso com Perl é usar o Perl para executar um processo gnuplot. Você pode usar set timefmt x "%Y-%m-%d" e vai analisar automaticamente os dados no formato que você tem. Gnuplot também suporta uma variedade de formatos de saída.

Eu recomendaria normalizando as datas para números inteiros. A maneira como a força bruta seria de curso usando segundos marcaram época, mas que pode não parecer muito agradável em um gráfico, então normalize por uma linear transformar em alguma gama decente (eu posso fornecer detalhes de como se quiser).

Você precisa de seu gráfico a ser gerado em tempo real, ou é para um one-off relatório? Neste último caso, então você pode usar DateTime módulos para gerar valores Excel e elaborar gráficos no Excel (ou o seu homólogo de código aberto.)

use DateTime::Format::MySQL;
use DateTime::Format::Excel;

my $dt = DateTime::Format::MySQL->parse_datetime( '2003-01-16 23:12:01' );
print $dt, "\n";
my $daynum = DateTime::Format::Excel->format_datetime($dt);
print $daynum, "\n";

O tempo atrás eu fiz algo parecido com isto usando Asymptote . É um pacote incrível, mas não é fácil de usar.

A seguir irá não trabalho em SQLLite como consultas recursivas não são suportados, mas ele vai trabalhar na Oracle.

Você pode criar uma série temporal contínua para Oracle dBs com uma subconsulta como esta:

(SELECT   TRUNC (SYSDATE - x / 1440, 'MI') ts
             FROM   (SELECT       LEVEL x
                           FROM   DUAL
                     CONNECT BY   LEVEL <= 60))

Em seguida, vincule essa série de tempo para seus dados dos gráficos usando um LEFT JOIN como esta:

    SELECT   TO_CHAR (A.TS, 'DD/MM/YYYY HH24:MI') TS
        , b.DATAPOINT1, b.DATAPOINT2
   FROM   (SELECT   TRUNC (SYSDATE - x / 1440, 'MI') ts
             FROM   (SELECT       LEVEL x
                           FROM   DUAL
                     CONNECT BY   LEVEL <= 60)) a
        , MY_CHART_DATA b
  WHERE   a.ts = b.ts(+) ORDER BY   a.TS;

O exemplo acima irá traçar os últimos 60 minutos e vai trabalhar ** com DBIx :: Gráfico. Para alterar a resolução para horas mudança 'MI' para 'HH24', ou a cada 24 horas você pode omitir o formato da data parâmetro todos juntos.

Para alterar o intervalo basta definir o valor CONNECT BY LEVEL para o número de pontos de séries temporais é preciso enredo em sua resolução especificada.

** Nota: DBIx :: Gráfico vai vomitar, se todos os valores DATAPOINT são zero (ie indefinido.). não pode ajudá-lo lá, me desculpe.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top