Revision b30b38df
Von Bernd Bleßmann vor mehr als 2 Jahren hinzugefügt
SL/Controller/CustomDataExport.pm | ||
---|---|---|
title => $self->query->name,
|
||
allow_pdf_export => 1,
|
||
allow_csv_export => 1,
|
||
allow_chart_export => 1,
|
||
attachment_basename => $report_name,
|
||
);
|
||
|
SL/Controller/Helper/ReportGenerator.pm | ||
---|---|---|
|
||
use Exporter 'import';
|
||
our @EXPORT = qw(
|
||
action_report_generator_export_as_pdf action_report_generator_export_as_csv
|
||
action_report_generator_export_as_pdf
|
||
action_report_generator_export_as_csv
|
||
action_report_generator_export_as_chart
|
||
action_report_generator_back report_generator_do
|
||
report_generator_list_objects
|
||
);
|
||
... | ... | |
for my $bar ($::request->layout->get('actionbar')) {
|
||
$bar->add(
|
||
action => [
|
||
$type eq 'pdf' ? $::locale->text('PDF export') : $::locale->text('CSV export'),
|
||
$type eq 'pdf' ? $::locale->text('PDF export') : $type eq 'csv' ? $::locale->text('CSV export') : $::locale->text('Chart export'),
|
||
submit => [ '#report_generator_form', { $key => "${value}report_generator_export_as_${type}" } ],
|
||
],
|
||
action => [
|
||
... | ... | |
print $::form->parse_html_template('report_generator/csv_export_options', { 'HIDDEN' => \@form_values });
|
||
}
|
||
|
||
sub action_report_generator_export_as_chart {
|
||
my ($self) = @_;
|
||
|
||
delete $::form->{action_report_generator_export_as_chart};
|
||
|
||
if ($::form->{report_generator_chart_options_set}) {
|
||
$self->report_generator_do('Chart');
|
||
return;
|
||
}
|
||
|
||
my $fields = delete $::form->{report_generator_chart_fields};
|
||
my @form_values = $::form->flatten_variables(grep { ($_ ne 'login') && ($_ ne 'password') } keys %{ $::form });
|
||
|
||
$::form->{title} = $::locale->text('Chart export -- options');
|
||
|
||
_setup_action_bar($self, 'chart'); # Sub not exported, therefore don't call via object.
|
||
|
||
$::form->header;
|
||
print $::form->parse_html_template('report_generator/chart_export_options', { 'HIDDEN' => \@form_values, fields => $fields });
|
||
}
|
||
|
||
sub action_report_generator_back {
|
||
$_[0]->report_generator_do('HTML');
|
||
}
|
SL/ReportGenerator.pm | ||
---|---|---|
use strict;
|
||
use SL::Helper::GlAttachments qw(append_gl_pdf_attachments);
|
||
use SL::Helper::CreatePDF qw(merge_pdfs);
|
||
use SL::JSON qw(to_json);
|
||
|
||
# Cause locales.pl to parse these files:
|
||
# parse_html_template('report_generator/html_report')
|
||
... | ... | |
'controller_class ' => '',
|
||
'allow_pdf_export' => 1,
|
||
'allow_csv_export' => 1,
|
||
'allow_chart_export' => 1,
|
||
'html_template' => 'report_generator/html_report',
|
||
'pdf_export' => {
|
||
'paper_size' => 'a4',
|
||
... | ... | |
'headers' => 1,
|
||
'encoding' => 'UTF-8',
|
||
},
|
||
'chart_export' => {
|
||
'assignment_x' => 'x',
|
||
'assignment_y' => 'y1',
|
||
},
|
||
};
|
||
$self->{export} = {
|
||
'nextsub' => '',
|
||
... | ... | |
$self->{options}->{pdf_export}->{$_} = $value->{$_} for keys %{ $value };
|
||
} elsif ($key eq 'csv_export') {
|
||
$self->{options}->{csv_export}->{$_} = $value->{$_} for keys %{ $value };
|
||
} elsif ($key eq 'chart_export') {
|
||
$self->{options}->{chart_export}->{$_} = $value->{$_} for keys %{ $value };
|
||
} else {
|
||
$self->{options}->{$key} = $value;
|
||
}
|
||
... | ... | |
$self->{options}->{$key} = $form->{$full_key} if (defined $form->{$full_key});
|
||
}
|
||
|
||
foreach my $format (qw(pdf csv)) {
|
||
foreach my $format (qw(pdf csv chart)) {
|
||
my $opts = $self->{options}->{"${format}_export"};
|
||
foreach my $key (keys %{ $opts }) {
|
||
my $full_key = "report_generator_${format}_options_${key}";
|
||
... | ... | |
} elsif ($format eq 'pdf') {
|
||
$self->generate_pdf_content();
|
||
|
||
} elsif ($format eq 'chart') {
|
||
$self->generate_chart_content();
|
||
|
||
} else {
|
||
$form->error('Incorrect usage -- unknown format (supported are HTML, CSV, PDF)');
|
||
$form->error('Incorrect usage -- unknown format (supported are HTML, CSV, PDF, Chart)');
|
||
}
|
||
}
|
||
|
||
... | ... | |
'RAW_BOTTOM_INFO_TEXT' => $opts->{raw_bottom_info_text},
|
||
'ALLOW_PDF_EXPORT' => $allow_pdf_export,
|
||
'ALLOW_CSV_EXPORT' => $opts->{allow_csv_export},
|
||
'SHOW_EXPORT_BUTTONS' => ($allow_pdf_export || $opts->{allow_csv_export}) && $self->{data_present},
|
||
'ALLOW_CHART_EXPORT' => $opts->{allow_chart_export},
|
||
'SHOW_EXPORT_BUTTONS' => ($allow_pdf_export || $opts->{allow_csv_export} || $opts->{allow_chart_export}) && $self->{data_present},
|
||
'HEADER_ROWS' => $header_rows,
|
||
'NUM_COLUMNS' => scalar @column_headers,
|
||
'ROWS' => \@rows,
|
||
... | ... | |
my ($self, $variables, %params) = @_;
|
||
|
||
my @actions;
|
||
foreach my $type (qw(pdf csv)) {
|
||
foreach my $type (qw(pdf csv chart)) {
|
||
next unless $variables->{"ALLOW_" . uc($type) . "_EXPORT"};
|
||
|
||
my $key = $variables->{CONTROLLER_DISPATCH} ? 'action' : 'report_generator_dispatch_to';
|
||
... | ... | |
$value = $variables->{CONTROLLER_DISPATCH} . "/${value}" if $variables->{CONTROLLER_DISPATCH};
|
||
|
||
push @actions, action => [
|
||
$type eq 'pdf' ? $::locale->text('PDF export') : $::locale->text('CSV export'),
|
||
$type eq 'pdf' ? $::locale->text('PDF export') : $type eq 'csv' ? $::locale->text('CSV export') : $::locale->text('Chart export'),
|
||
submit => [ '#report_generator_form', {(
|
||
$key => $value,
|
||
defined $params{action_bar_additional_submit_values}
|
||
... | ... | |
$params{action_bar} //= 1;
|
||
|
||
my $variables = $self->prepare_html_content(%params);
|
||
|
||
$self->setup_action_bar($variables, %params) if $params{action_bar};
|
||
|
||
my $stuff = $self->{form}->parse_html_template($self->{options}->{html_template}, $variables);
|
||
... | ... | |
}
|
||
}
|
||
|
||
sub generate_chart_content {
|
||
my ($self, %params) = @_;
|
||
|
||
$params{action_bar} //= 1;
|
||
|
||
my $opts = $self->{options};
|
||
|
||
my $assignment_x = $opts->{chart_export}->{assignment_x};
|
||
my $assignment_y = $opts->{chart_export}->{assignment_y};
|
||
|
||
my @data_x;
|
||
my @data_y;
|
||
foreach my $row_set (@{ $self->{data} }) {
|
||
next if ('ARRAY' ne ref $row_set);
|
||
foreach my $row (@{ $row_set }) {
|
||
my $x = $row->{$assignment_x}->{data}->[0];
|
||
my $y = $row->{$assignment_y}->{data}->[0];
|
||
if ($x) {
|
||
push @data_x, $x;
|
||
push @data_y, $y//0;
|
||
}
|
||
}
|
||
}
|
||
|
||
my $variables = {
|
||
'TITLE' => $opts->{title},
|
||
'TOP_INFO_TEXT' => $self->html_format($opts->{top_info_text}),
|
||
'RAW_TOP_INFO_TEXT' => $opts->{raw_top_info_text},
|
||
'BOTTOM_INFO_TEXT' => $self->html_format($opts->{bottom_info_text}),
|
||
'RAW_BOTTOM_INFO_TEXT' => $opts->{raw_bottom_info_text},
|
||
'EXPORT_VARIABLE_LIST' => join(' ', @{ $self->{export}->{variable_list} }),
|
||
'EXPORT_NEXTSUB' => $self->{export}->{nextsub},
|
||
'DATA_PRESENT' => $self->{data_present},
|
||
'CONTROLLER_DISPATCH' => $opts->{controller_class},
|
||
'TABLE_CLASS' => $opts->{table_class},
|
||
'SKIP_BUTTONS' => !!$params{action_bar},
|
||
};
|
||
|
||
$::request->layout->add_javascripts('chart.js', 'kivi.ChartReport.js');
|
||
|
||
$::form->header;
|
||
print $::form->parse_html_template('report_generator/chart_report',
|
||
{
|
||
data_x => to_json(\@data_x),
|
||
data_y => to_json(\@data_y),
|
||
label_x => $assignment_x,
|
||
label_y => $assignment_y,
|
||
%$variables,
|
||
}
|
||
);
|
||
}
|
||
|
||
sub check_for_pdf_api {
|
||
return eval { require PDF::API2; 1; } ? 1 : 0;
|
||
}
|
bin/mozilla/reportgenerator.pl | ||
---|---|---|
$bar->add(
|
||
combobox => [
|
||
action => [
|
||
$type eq 'pdf' ? $::locale->text('PDF export') : $::locale->text('CSV export'),
|
||
$type eq 'pdf' ? $::locale->text('PDF export') : $type eq 'csv' ? $::locale->text('CSV export') : $::locale->text('Chart export'),
|
||
submit => [ '#report_generator_form', { 'report_generator_dispatch_to' => "report_generator_export_as_${type}" } ],
|
||
],
|
||
action => [
|
||
... | ... | |
$main::lxdebug->leave_sub();
|
||
}
|
||
|
||
sub report_generator_export_as_chart {
|
||
$main::lxdebug->enter_sub();
|
||
|
||
my $form = $main::form;
|
||
my $locale = $main::locale;
|
||
|
||
if ($form->{report_generator_chart_options_set}) {
|
||
report_generator_do('Chart');
|
||
$main::lxdebug->leave_sub();
|
||
return;
|
||
}
|
||
|
||
my $fields = delete $form->{report_generator_chart_fields};
|
||
my @form_values = $form->flatten_variables(grep { ($_ ne 'login') && ($_ ne 'password') } keys %{ $form });
|
||
|
||
$form->{title} = $locale->text('Chart export -- options');
|
||
|
||
report_generator_setup_action_bar('chart');
|
||
|
||
$form->header();
|
||
print $form->parse_html_template('report_generator/chart_export_options', { 'HIDDEN' => \@form_values, fields => $fields });
|
||
|
||
$main::lxdebug->leave_sub();
|
||
}
|
||
|
||
sub report_generator_back {
|
||
$main::lxdebug->enter_sub();
|
||
|
js/kivi.ChartReport.js | ||
---|---|---|
namespace('kivi.ChartReport', function(ns) {
|
||
"use strict";
|
||
|
||
ns.data = undefined;
|
||
|
||
ns.chart = function() {
|
||
$(ns.data.data_y).each(function(idx) {ns.data.data_y[idx] = kivi.parse_amount('' + ns.data.data_y[idx]);});
|
||
console.log("bb: data_y (parsed): "); console.log(ns.data.data_y);
|
||
|
||
const ctx = 'chart';
|
||
const chart = new Chart(ctx, {
|
||
type: 'bar',
|
||
data: {
|
||
labels: ns.data.data_x,
|
||
datasets: [{
|
||
label: ns.data.label_y,
|
||
data: ns.data.data_y,
|
||
backgroundColor: [
|
||
'rgba(255, 99, 132, 0.2)',
|
||
'rgba(54, 162, 235, 0.2)',
|
||
'rgba(255, 206, 86, 0.2)',
|
||
'rgba(75, 192, 192, 0.2)',
|
||
'rgba(153, 102, 255, 0.2)',
|
||
'rgba(255, 159, 64, 0.2)'
|
||
],
|
||
borderColor: [
|
||
'rgba(255, 99, 132, 1)',
|
||
'rgba(54, 162, 235, 1)',
|
||
'rgba(255, 206, 86, 1)',
|
||
'rgba(75, 192, 192, 1)',
|
||
'rgba(153, 102, 255, 1)',
|
||
'rgba(255, 159, 64, 1)'
|
||
],
|
||
borderWidth: 1
|
||
}]
|
||
},
|
||
options: {
|
||
scales: {
|
||
y: {
|
||
beginAtZero: true
|
||
}
|
||
}
|
||
}
|
||
});
|
||
};
|
||
|
||
ns.debug = function() {
|
||
console.log("bb: data_x: "); console.log(ns.data.data_x);
|
||
console.log("bb: data_y: "); console.log(ns.data.data_y);
|
||
console.log("bb: label_x: "); console.log(ns.data.label_x);
|
||
console.log("bb: label_y: "); console.log(ns.data.label_y);
|
||
};
|
||
|
||
$(function() {
|
||
kivi.ChartReport.debug();
|
||
kivi.ChartReport.chart();
|
||
});
|
||
});
|
templates/webpages/report_generator/chart_export_options.html | ||
---|---|---|
[%- USE T8 %]
|
||
[%- USE HTML %]
|
||
[%- USE L %]
|
||
|
||
<h1>[% HTML.escape(title) %]</h1>
|
||
|
||
<form action="[% HTML.escape(script) %]" method="post" name="report_generator_form" id="report_generator_form">
|
||
|
||
[%- FOREACH var = HIDDEN %]
|
||
<input type="hidden" name="[% HTML.escape(var.key) %]" value="[% HTML.escape(var.value) %]">
|
||
[%- END %]
|
||
|
||
<input type="hidden" name="report_generator_chart_options_set" value="1">
|
||
<input type="hidden" name="report_generator_dispatch_to" value="">
|
||
|
||
<table>
|
||
<tr>
|
||
<th valign="top" align="right">[% 'Chart assignments' | $T8 %]: [% 'X' | $T8 %]</th>
|
||
<td>
|
||
[% L.select_tag('report_generator_chart_options_assignment_x',
|
||
fields,
|
||
default = SELF.report_generator_chart_options_assignment_x
|
||
value_key = 'name',
|
||
title_key = 'text') %]
|
||
</td>
|
||
</tr>
|
||
<tr>
|
||
<th valign="top" align="right">[% 'Chart assignments' | $T8 %]: [% 'Y' | $T8 %]</th>
|
||
<td>
|
||
[% L.select_tag('report_generator_chart_options_assignment_y',
|
||
fields,
|
||
default = SELF.report_generator_chart_options_assignment_y
|
||
value_key = 'name',
|
||
title_key = 'text') %]
|
||
</td>
|
||
</tr>
|
||
</table>
|
||
|
||
[%- IF CONTROLLER_DISPATCH %]
|
||
<input type="hidden" name="CONTROLLER_DISPATCH" value="[% CONTROLLER_DISPATCH | html %]">
|
||
[%- ELSE %]
|
||
<input type="hidden" name="action" value="report_generator_dispatcher">
|
||
[%- END %]
|
||
|
||
|
||
</form>
|
templates/webpages/report_generator/chart_report.html | ||
---|---|---|
[% USE P -%]
|
||
|
||
<h1>[% TITLE %]</h1>
|
||
|
||
[%- INCLUDE 'common/flash.html' %]
|
||
|
||
[% IF TOP_INFO_TEXT %]
|
||
<p>[% TOP_INFO_TEXT %]</p>
|
||
[% END %]
|
||
|
||
[% RAW_TOP_INFO_TEXT %]
|
||
|
||
<div class="chart-container" style="position: relative;">
|
||
<canvas id="chart" height="70vH"></canvas>
|
||
</div>
|
||
|
||
[% RAW_BOTTOM_INFO_TEXT %]
|
||
|
||
[% IF BOTTOM_INFO_TEXT %]
|
||
<p>[% BOTTOM_INFO_TEXT %]</p>
|
||
[% END %]
|
||
|
||
|
||
<script>
|
||
kivi.ChartReport.data = { data_x: [% data_x %],
|
||
data_y: [% data_y %],
|
||
label_y: "[% label_y %]",
|
||
label_x: "[% label_x %]"
|
||
};
|
||
</script>
|
templates/webpages/report_generator/html_report.html | ||
---|---|---|
[% FOREACH var = EXPORT_VARIABLES %]<input type="hidden" name="report_generator_hidden_[% var.key %]" value="[% HTML.escape(var.value) %]">
|
||
[% END %]
|
||
|
||
[% IF ALLOW_CHART_EXPORT %]
|
||
[% FOREACH row = HEADER_ROWS %]
|
||
[% FOREACH col = row %]
|
||
[% IF col.name && col.text %]
|
||
<input type="hidden" name="report_generator_chart_fields[+].name" value="[% HTML.escape(col.name) %]">
|
||
<input type="hidden" name="report_generator_chart_fields[].text" value="[% HTML.escape(col.text) %]">
|
||
[% END %]
|
||
[% END %]
|
||
[% END %]
|
||
[% END %]
|
||
|
||
[%- IF CONTROLLER_DISPATCH %]
|
||
[% IF !SKIP_BUTTONS %]
|
||
<input type="hidden" name="action" value="[% CONTROLLER_DISPATCH %]/dispatch">
|
Auch abrufbar als: Unified diff
Reports als Chart exportieren können