1 package MojoFacets::Data;
6 use base 'Mojolicious::Controller';
8 use Data::Dump qw(dump);
16 my $path = $self->app->home->rel_dir('data');
17 die "no data dir $path" unless -d $path;
19 opendir(my $dir, $path) || die $!;
21 grep { -f "$path/$_" && $_ =~ m/\.js(on)?$/ }
25 $self->render( files => [ @files ] );
34 my $path = $self->app->home->rel_file( 'data/' . $self->param('path') );
35 die "$path $!" unless -r $path;
37 $self->session('path' => $self->param('path'));
39 # we could use Mojo::JSON here, but it's too slow
40 # $data = from_json read_file $path;
41 $data = read_file $path;
42 Encode::_utf8_on($data);
43 warn "# json snippet: ", substr($data,0,200);
44 $data = from_json $data;
48 foreach my $e ( @{ $data->{items} } ) {
49 foreach my $n ( keys %$e ) {
50 $stats->{$n}->{count}++;
51 $stats->{$n}->{number}++
52 if $e->{$n} =~ m/^[-+]?([0-9]*\.[0-9]+|[0-9]+)$/;
53 $stats->{$n}->{array} += $#{ $e->{$n} } + 1
54 if ref $e->{$n} eq 'ARRAY';
58 foreach my $n ( keys %$stats ) {
59 next unless defined $stats->{$n}->{array};
60 delete $stats->{$n}->{array}
61 if $stats->{$n}->{array} == $stats->{$n}->{count};
66 $self->redirect_to( '/data/columns' );
74 message => 'Select columns to display',
76 checked => $self->_checked( $self->_perm_array('columns') ),
81 my ($self,$name) = @_;
83 my @array = $self->param($name);
86 $self->session($name => [ @array ]);
87 } elsif ( my $session = $self->session($name) ) {
88 if ( ref $session eq 'ARRAY' ) {
91 die "$name not array ",dump($session);
94 warn "# $name ",dump @array;
99 my ($self,$name,$default) = @_;
101 my $scalar = $self->param($name);
103 if ( defined $scalar ) {
104 $self->session($name => $scalar);
106 $scalar = $self->session($name);
109 if ( ! defined $scalar ) {
111 die "no default for $name" unless defined $scalar;
112 $self->session($name => $scalar);
115 warn "# $name ",dump $scalar;
122 my $name = $self->param('filter_name') || die "name?";
123 my @vals = $self->param('filter_vals');
125 warn "# filter $name vals ",dump(@vals);
127 my $filters = $self->session('filters');
129 $filters->{$name} = [ @vals ];
131 delete $filters->{$name};
133 $self->session( 'filters' => $filters );
135 warn "# filters ",dump($self->session('filters'));
137 $self->session( 'offset' => 0 );
139 $self->redirect_to('/data/table');
143 my ( $self, $filters, $i ) = @_;
145 foreach my $n ( keys %$filters ) {
146 if ( ! defined $i->{$n} ) {
150 foreach my $v ( @{ $i->{$n} } ) { # FIXME not array?
151 $pass = 0 unless grep { m/^\Q$v\E$/ } @{ $filters->{$n} };
159 my $filters = $self->session('filters');
161 $filters ? $self->_filter_item( $filters, $_ ) : 1;
162 } @{ $data->{items} };
168 $self->redirect_to('/data/index') unless $data->{items};
170 my @columns = $self->_perm_array('columns');
171 my $order = $self->_perm_scalar('order', $columns[0]);
172 my $offset = $self->_perm_scalar('offset', 0);
173 my $limit = $self->_perm_scalar('limit', 20);
176 ( $a->{$order} || '' ) cmp ( $b->{$order} || '' ) # FIXME - multi-level sort
177 } $self->_data_items;
179 # warn "# sorted ", dump @sorted;
181 my $rows = $#sorted + 1;
183 warn "$rows $offset $limit";
189 sorted => [ splice @sorted, $offset, $limit ],
190 columns => [ @columns ],
201 my $name = $self->param('name') || die "no name";
203 foreach my $i ( $self->_data_items ) {
204 next unless exists $i->{$name};
205 if ( ref $i->{$name} eq 'ARRAY' ) {
206 $facet->{$_}++ foreach @{ $i->{$name} };
208 $facet->{ $i->{$name} }++;
212 # warn "# facet $name ",dump $facet;
215 if ( my $f = $self->session('filters') ) {
216 if ( defined $f->{$name} ) {
217 $checked = $self->_checked( @{ $f->{$name} } );
221 my $sort = $self->param('sort') || 'c';
223 my @facet_names = sort {
224 $sort =~ m/a/i ? lc $a cmp lc $b :
225 $sort =~ m/d/i ? lc $b cmp lc $a :
226 $facet->{$b} <=> $facet->{$a}
230 $self->render( name => $name, facet => $facet, checked => $checked,
231 facet_names => \@facet_names, sort => $sort,
238 $checked->{$_}++ foreach @_;
239 warn "# _checked ",dump($checked);