在绘制统计图时遇到的Data::Dumper模块的问题

Data::Dumper模块可以说是我最最常用的一个perl模块: 它可以将perl变量以可读的形式打印保存起来. 不过最近发现了它的一个小问题: 当变量中存在浮点数时, 浮点数会以字符串类型被Dump出来.

起源

前几天统计出了一些数据, 现在需要根据这些数据输出一份统计图, 用于展示及分析. 绘制统计图的方法有很多, 比如可以把数据按一定的格式直接输出出来, 然后导入到对应的工具中, 例如excel等, 但是觉得比较麻烦, 并且不够灵活; 也考虑过使用R来搞, 成图方便, 操作数据也相当灵活, 不过自己的R语言的水平真心太菜了, 时间也比较赶, 于是放弃; 因为之前的统计计算用的都是perl, 那自然也希望能够用perl来生成图表. 同样有很多现成的绘图模块提供使用, 但是学习成本还是有点高; 好吧, 最后采用了perl结合highcharts的方式来成图. 原因主要有三点:

  1. 方便, 仅仅需要填充数据段.
  2. 统计图以html页面方式呈现, 还可以添加一些辅助文字.
  3. 好看;)

采用highcharts来成图的话, 我们仅需要生成对应的数据格式就ok了, 例如像官网上的这个例子:

highcharts example
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
$(function () {
    $('#container').highcharts({
        title: {
            text: 'Monthly Average Temperature',
            x: -20 //center
        },
        subtitle: {
            text: 'Source: WorldClimate.com',
            x: -20
        },
        xAxis: {
            categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
            'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
        },
        yAxis: {
            title: {
            text: 'Temperature (°C)'
        },
        plotLines: [{
                value: 0,
                width: 1,
                color: '#808080'
            }]
        },
        tooltip: {
            valueSuffix: '°C'
        },
        legend: {
            layout: 'vertical',
            align: 'right',
            verticalAlign: 'middle',
            borderWidth: 0
        },
        series: [{
                name: 'Tokyo',
                data: [7.0, 6.9, 9.5, 14.5, 18.2, 21.5, 25.2, 26.5, 23.3, 18.3, 13.9, 9.6]
            }, {
                name: 'New York',
                data: [-0.2, 0.8, 5.7, 11.3, 17.0, 22.0, 24.8, 24.1, 20.1, 14.1, 8.6, 2.5]
            }, {
                name: 'Berlin',
                data: [-0.9, 0.6, 3.5, 8.4, 13.5, 17.0, 18.6, 17.9, 14.3, 9.0, 3.9, 1.0]
            }, {
                name: 'London',
                data: [3.9, 4.2, 5.7, 8.5, 11.9, 15.2, 17.0, 16.6, 14.2, 10.3, 6.6, 4.8]
            }]
        });
});

我们可以根据需要填充seriesxAxis的内容即可. 那接下的问题就是如何把perl的数据结构按js的数据结构导出来.

Data::Dumper

上面这个问题有两种解决方案

  1. 将perl数据以JSON形式导出来, js的数据结构是简化了的JSON数据结构
  2. 利用Data::Dumper模块将perl数据导出成js样式

一开始没有多思考就采取了方法2, 先用下面这段代码试一试:

have a try
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#!/usr/bin/perl

use 5.010;
use strict;

use Data::Dumper;

my $data = {
    name     => 'why not',
    nickname => 'little grey',
    age      => 34,
    colors   => [qw(blue red green pink black white)],
    school   => [
            {
                name     => 'otz',
                score    => [1 .. 10],
            },
            {
                name     => 'rto',
                score    => [11.1, 22.3, 75.65],
            }
    ],
    share    => {
        old   => 'conan',
        new   => 'kid',
    },
};

$Data::Dumper::Terse = 1;
$Data::Dumper::Pair  = ' : ';
$Data::Dumper::Useperl = 1;

print Dumper $data;

执行了下确实ok, 关键是下面三个变量的赋值, 具体可以参考Data::Dumper的说明. 不过有个致命的问题, 发现导出的浮点数被强制加了引号…. 这个问题就比较致命了, 因为highcharts的数据段仅接受数值.

好吧, google下发现果真有这个问题, 并且貌似也不打算修复. 有兴趣的同学请参考:

  1. http://www.nntp.perl.org/group/perl.perl5.porters/2012/02/msg183122.html
  2. http://www.perlmonks.org/?node_id=909619

好吧, 我们用JSON方式导出吧, 反而更加简单了.

PPPPSSSS

表示fedora升级好麻烦呀……

Comments