Skip to content

Commit

Permalink
Fix for chart ordering bug. Fixes #42.
Browse files Browse the repository at this point in the history
  • Loading branch information
jmcnamara committed Nov 18, 2012
1 parent 6b685ae commit 11b7503
Show file tree
Hide file tree
Showing 9 changed files with 369 additions and 33 deletions.
1 change: 1 addition & 0 deletions lib/Excel/Writer/XLSX/Chartsheet.pm
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,7 @@ sub _prepare_chart {
my $chart_id = shift;
my $drawing_id = shift;

$self->{_chart}->{_id} = $chart_id -1;

my $drawing = Excel::Writer::XLSX::Drawing->new();
$self->{_drawing} = $drawing;
Expand Down
15 changes: 9 additions & 6 deletions lib/Excel/Writer/XLSX/Workbook.pm
Original file line number Diff line number Diff line change
Expand Up @@ -381,10 +381,6 @@ sub add_chart {

my $chart = Excel::Writer::XLSX::Chart->factory( $type, $arg{subtype} );

# Get an incremental id to use for axes ids.
my $chart_index = scalar @{ $self->{_charts} };
$chart->{_id} = $chart_index;

# If the chart isn't embedded let the workbook control it.
if ( !$embedded ) {

Expand Down Expand Up @@ -1424,8 +1420,6 @@ sub _prepare_drawings {
my $shape_count = scalar @{ $sheet->{_shapes} };
next unless ( $chart_count + $image_count + $shape_count );

$sheet->_sort_charts();

$drawing_id++;

for my $index ( 0 .. $chart_count - 1 ) {
Expand Down Expand Up @@ -1454,6 +1448,15 @@ sub _prepare_drawings {
push @{ $self->{_drawings} }, $drawing;
}

# Sort the workbook charts references into the order that the were
# written from the worksheets above.
my @chart_data = @{ $self->{_charts} };

@chart_data = sort { $a->{_id} <=> $b->{_id} } @chart_data;

$self->{_charts} = \@chart_data;


$self->{_drawing_count} = $drawing_id;
}

Expand Down
29 changes: 3 additions & 26 deletions lib/Excel/Writer/XLSX/Worksheet.pm
Original file line number Diff line number Diff line change
Expand Up @@ -4718,32 +4718,6 @@ sub insert_chart {
}
###############################################################################
#
# _sort_charts()
#
# Sort the worksheet charts into the order that they were created in rather
# than the insertion order. This is ensure that the chart and drawing objects
# written in the same order. The chart id is used to sort back into creation
# order.
#
sub _sort_charts {
my $self = shift;
my $chart_count = scalar @{ $self->{_charts} };
# Return if no sorting is required.
return if $chart_count < 2;
my @chart_data = @{ $self->{_charts} };
# Sort the charts into creation order based on the chart id.
@chart_data = sort { $a->[2]->{_id} <=> $b->[2]->{_id} } @chart_data;
$self->{_charts} = \@chart_data;
}
###############################################################################
#
# _prepare_chart()
Expand All @@ -4761,6 +4735,9 @@ sub _prepare_chart {
my ( $row, $col, $chart, $x_offset, $y_offset, $scale_x, $scale_y ) =
@{ $self->{_charts}->[$index] };
$chart->{_id} = $chart_id -1;
my $width = int( 0.5 + ( 480 * $scale_x ) );
my $height = int( 0.5 + ( 288 * $scale_y ) );
Expand Down
2 changes: 1 addition & 1 deletion t/regression/chart_name03.t
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,8 @@ $chart2->add_series( values => '=Sheet1!$A$1:$A$5' );
$chart2->add_series( values => '=Sheet1!$B$1:$B$5' );
$chart2->add_series( values => '=Sheet1!$C$1:$C$5' );

$worksheet->insert_chart( 'E24', $chart2 );
$worksheet->insert_chart( 'E9', $chart1 );
$worksheet->insert_chart( 'E24', $chart2 );

$workbook->close();

Expand Down
119 changes: 119 additions & 0 deletions t/regression/chart_order01.t
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
###############################################################################
#
# Tests the output of Excel::Writer::XLSX against Excel generated files.
#
# reverse ('(c)'), November 2012, John McNamara, jmcnamara@cpan.org
#

use lib 't/lib';
use TestFunctions qw(_compare_xlsx_files _is_deep_diff);
use strict;
use warnings;

use Test::More tests => 1;

###############################################################################
#
# Tests setup.
#
my $filename = 'chart_order01.xlsx';
my $dir = 't/regression/';
my $got_filename = $dir . $filename;
my $exp_filename = $dir . 'xlsx_files/' . $filename;

my $ignore_members = [];

my $ignore_elements = {};


###############################################################################
#
# Test the creation of a simple Excel::Writer::XLSX file.
#
use Excel::Writer::XLSX;

my $workbook = Excel::Writer::XLSX->new( $got_filename );
my $worksheet1 = $workbook->add_worksheet();
my $worksheet2 = $workbook->add_worksheet();
my $worksheet3 = $workbook->add_worksheet();

my $chart1 = $workbook->add_chart(
type => 'column',
embedded => 1,
);

my $chart2 = $workbook->add_chart(
type => 'bar',
embedded => 1,
);

my $chart3 = $workbook->add_chart(
type => 'line',
embedded => 1,
);

my $chart4 = $workbook->add_chart(
type => 'pie',
embedded => 1,
);




# For testing, copy the randomly generated axis ids in the target xlsx file.
$chart1->{_axis_ids} = [ 54976896, 54978432 ];
$chart2->{_axis_ids} = [ 54310784, 54312320 ];
$chart3->{_axis_ids} = [ 69816704, 69818240 ];
$chart4->{_axis_ids} = [ 69816704, 69818240 ];

my $data = [
[ 1, 2, 3, 4, 5 ],
[ 2, 4, 6, 8, 10 ],
[ 3, 6, 9, 12, 15 ],

];

$worksheet1->write( 'A1', $data );
$worksheet2->write( 'A1', $data );
$worksheet3->write( 'A1', $data );

$chart1->add_series( values => '=Sheet1!$A$1:$A$5' );
$chart2->add_series( values => '=Sheet2!$A$1:$A$5' );
$chart3->add_series( values => '=Sheet3!$A$1:$A$5' );
$chart4->add_series( values => '=Sheet1!$B$1:$B$5' );


$worksheet1->insert_chart( 'E9', $chart1 );
$worksheet2->insert_chart( 'E9', $chart2 );
$worksheet3->insert_chart( 'E9', $chart3 );
$worksheet1->insert_chart( 'E24', $chart4 );

$workbook->close();


###############################################################################
#
# Compare the generated and existing Excel files.
#

my ( $got, $expected, $caption ) = _compare_xlsx_files(

$got_filename,
$exp_filename,
$ignore_members,
$ignore_elements,
);

_is_deep_diff( $got, $expected, $caption );


###############################################################################
#
# Cleanup.
#
unlink $got_filename;

__END__
120 changes: 120 additions & 0 deletions t/regression/chart_order02.t
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
###############################################################################
#
# Tests the output of Excel::Writer::XLSX against Excel generated files.
#
# reverse ('(c)'), November 2012, John McNamara, jmcnamara@cpan.org
#

use lib 't/lib';
use TestFunctions qw(_compare_xlsx_files _is_deep_diff);
use strict;
use warnings;

use Test::More tests => 1;

###############################################################################
#
# Tests setup.
#
my $filename = 'chart_order01.xlsx';
my $dir = 't/regression/';
my $got_filename = $dir . $filename;
my $exp_filename = $dir . 'xlsx_files/' . $filename;

my $ignore_members = [];

my $ignore_elements = {};


###############################################################################
#
# Test the creation of a simple Excel::Writer::XLSX file.
#
use Excel::Writer::XLSX;

my $workbook = Excel::Writer::XLSX->new( $got_filename );
my $worksheet1 = $workbook->add_worksheet();
my $worksheet2 = $workbook->add_worksheet();
my $worksheet3 = $workbook->add_worksheet();


my $chart4 = $workbook->add_chart(
type => 'pie',
embedded => 1,
);

my $chart3 = $workbook->add_chart(
type => 'line',
embedded => 1,
);

my $chart2 = $workbook->add_chart(
type => 'bar',
embedded => 1,
);

my $chart1 = $workbook->add_chart(
type => 'column',
embedded => 1,
);




# For testing, copy the randomly generated axis ids in the target xlsx file.
$chart1->{_axis_ids} = [ 54976896, 54978432 ];
$chart2->{_axis_ids} = [ 54310784, 54312320 ];
$chart3->{_axis_ids} = [ 69816704, 69818240 ];
$chart4->{_axis_ids} = [ 69816704, 69818240 ];

my $data = [
[ 1, 2, 3, 4, 5 ],
[ 2, 4, 6, 8, 10 ],
[ 3, 6, 9, 12, 15 ],

];

$worksheet1->write( 'A1', $data );
$worksheet2->write( 'A1', $data );
$worksheet3->write( 'A1', $data );

$chart1->add_series( values => '=Sheet1!$A$1:$A$5' );
$chart2->add_series( values => '=Sheet2!$A$1:$A$5' );
$chart3->add_series( values => '=Sheet3!$A$1:$A$5' );
$chart4->add_series( values => '=Sheet1!$B$1:$B$5' );


$worksheet1->insert_chart( 'E9', $chart1 );
$worksheet2->insert_chart( 'E9', $chart2 );
$worksheet3->insert_chart( 'E9', $chart3 );
$worksheet1->insert_chart( 'E24', $chart4 );

$workbook->close();


###############################################################################
#
# Compare the generated and existing Excel files.
#

my ( $got, $expected, $caption ) = _compare_xlsx_files(

$got_filename,
$exp_filename,
$ignore_members,
$ignore_elements,
);

_is_deep_diff( $got, $expected, $caption );


###############################################################################
#
# Cleanup.
#
unlink $got_filename;

__END__
Loading

0 comments on commit 11b7503

Please sign in to comment.