Question

J'ai des données d'une base de données (SQLite), mappant une valeur (un entier) à une date. Une date est une chaîne ayant le format suivant: AAAA-MM-JJ hh: mm . Les dates ne sont pas uniformément distribuées. Je veux tracer un graphique linéaire avec les dates sur X et les valeurs sur Y . Quel est le moyen le plus simple de procéder avec Perl?

J'ai essayé DBIx :: Chart , mais je n'ai pas pu le faire reconnaître mes dates. . J'ai également essayé GD :: Graph , mais comme le dit la documentation:

  

GD :: Graph ne supporte pas x numérique   axe comme il le devrait. Données pour X   les axes doivent être équidistants

Était-ce utile?

La solution

Vous pouvez conduire gnuplot en utilisant Graphique :: Gnuplot .

Sinon, si SVG est un format de sortie acceptable, il existe SVG :: TT :: Graphique .

Autres conseils

Vous pouvez utiliser Axis :: DateTime de Chart :: Clicker:

#!/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');

Vous devez convertir vos temps en timestamps Unix, mais ce sont des fichiers DWIM.

  

J'ai essayé DBIx :: Chart mais je ne pouvais pas le faire reconnaître mes dates.

Avez-vous essayé de traduire vos dates en Unix-Timestamps et de les utiliser comme dates X?

Cela a fait le tour pour moi:

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

Le moyen le plus simple que j'ai trouvé de faire cela avec Perl est d'utiliser Perl pour exécuter un processus gnuplot. Vous pouvez utiliser set timefmt x "% Y-% m-% d" et il analysera automatiquement les données dans le format que vous avez. Gnuplot supporte également une variété de formats de sortie.

Je recommanderais de normaliser les dates en nombres entiers. La méthode de la force brute consisterait bien sûr en secondes d’époque, mais cela pourrait ne pas sembler très beau sur un graphique; normalisez-le donc par une transformation linéaire en une plage décente (je peux vous donner des détails si vous le souhaitez).

Avez-vous besoin que votre graphique soit généré en temps réel ou s’agisse d’un rapport ponctuel? Dans ce dernier cas, vous pouvez utiliser les modules DateTime pour générer des valeurs Excel et les représenter graphiquement dans Excel (ou son équivalent open-source.)

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";

Il y a longtemps, j'ai fait quelque chose comme cela en utilisant Asymptote . C’est un package incroyable, mais difficile à utiliser.

Ce qui suit ne fonctionnera pas dans SQLLite car les requêtes récursives ne sont pas prises en charge, mais cela fonctionnera dans Oracle.

Vous pouvez créer une série chronologique continue pour les dB Oracle avec une sous-requête comme celle-ci:

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

Liez ensuite cette série temporelle aux données de votre graphique en utilisant un JOINDRE GAUCHE comme celui-ci:

    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;

L'exemple ci-dessus trace les 60 dernières minutes et fonctionnera ** avec DBIx :: Chart. Pour changer la résolution en heures, remplacez 'MI' par 'HH24' ou vous pouvez omettre tous les 24 heures le paramètre de format de date.

Pour modifier la plage, il suffit de définir la valeur CONNECT BY LEVEL sur le nombre de points de la série temporelle à tracer à la résolution spécifiée.

** Remarque: DBIx :: Chart fera un saut si toutes les valeurs de points de données sont égales à zéro (c'est-à-dire non définies). Je ne peux pas t'aider, désolé.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top