Chart-GGPlot
view release on metacpan or search on metacpan
lib/Chart/GGPlot/Backend/Plotly.pm view on Meta::CPAN
# for traces of same legend group, show legend for
# only the first one of them.
$trace->showlegend(0);
}
}
$plotly->add_trace($trace);
}
if ( List::AllUtils::any { $_->$_call_if_can('showlegend') }
@$panel )
{
$plotly_layout{showlegend} = JSON::true;
# legend title
#
# TODO: See if plotly will officially support legend title
# https://github.com/plotly/plotly.js/issues/276
my $br = br();
my $legend_titles =
join( $br, map { $_->title =~ s/\n/$br/gr; } @$gdefs );
my $annotations = $plotly_layout{annotations} //= [];
push @$annotations,
{
x => 1.02,
y => 1,
align => 'left',
xanchor => 'left',
yanchor => 'bottom',
text => $legend_titles,
showarrow => JSON::false,
xref => 'paper',
yref => 'paper',
};
# Default right margin is too small for legend title.
#
# TODO: How to automatically calc the margin?
# May need to use libraries like Cairo for text width?
# Best if plotly can natively support legend title.
$plotly_layout{margin} = { r => 150 };
}
}
}
# Above operations already ensures for each legend group there be only
# one legend item. So there is no need to keep legendgroup gap, then
# it looks better to me compared with having the default gap.
$plotly_layout{legend} = { tracegroupgap => 0 };
$plotly_layout{hovermode} = 'closest';
$plotly_layout{barmode} = $barmode // 'relative';
# border
my $el_panel_border = $theme->at('panel_border');
unless ( not defined $el_panel_border or $el_panel_border->is_blank ) {
$plotly_layout{shapes} = [
{
type => 'rect',
fillcolor => 'transparent',
line => {
color => to_rgb( $el_panel_border->at('color') ),
width => 1,
linetype => 'solid',
},
xref => 'paper',
x0 => 0,
x1 => 1,
yref => 'paper',
y0 => 0,
y1 => 1,
}
];
}
if ( $theme->at('legend_position') eq 'none' ) {
$plotly_layout{showlegend} = JSON::false;
}
# colorbar
my ($colorbar) =
grep { $_->$_DOES('Chart::GGPlot::Guide::Colorbar') } @$gdefs;
if ($colorbar) {
my $colorbar_trace = $self->_colorbar_to_trace($colorbar);
$plotly->add_trace($colorbar_trace);
}
$log->debug( "plotly layout : " . Dumper( \%plotly_layout ) )
if $log->is_debug;
$plotly->layout( \%plotly_layout );
#$log->trace( "plotly html:\n" . $plotly->html ) if $log->is_trace;
$plotly->{config}{responsive} = JSON::true;
return $plotly;
}
method ggplotly ($ggplot) {
my $plot_built = $self->build($ggplot);
return $self->_to_plotly($plot_built);
}
method show ($ggplot, HashRef $opts={}) {
my $plotly = $self->ggplotly($ggplot);
if ( $opts->{width} or $opts->{height} ) {
$plotly->{layout}{width} = $opts->{width} if ( $opts->{width} );
$plotly->{layout}{height} = $opts->{height} if ( $opts->{height} );
$plotly->{config}{responsive} = JSON::false;
}
else {
$plotly->{config}{responsive} = JSON::true;
}
show_plot( $plotly );
}
method save ($ggplot, $filename, HashRef $opts={}) {
my $plotly = $self->ggplotly($ggplot);
my %opts = %$opts;
( run in 2.311 seconds using v1.01-cache-2.11-cpan-39bf76dae61 )