Skip to content
Permalink
Browse files

Extra tweaks to legend column auto breaking when manual breaks are pr…

…esent
  • Loading branch information
nyalldawson committed May 6, 2020
1 parent d574bf7 commit f09ec88156832c5f7916ab8c6df02ce735ec1180
@@ -439,6 +439,7 @@ int QgsLegendRenderer::setColumns( QList<LegendComponentGroup> &componentGroups
// the target number of columns allowed is dictated by the number of forced column
// breaks OR the manually set column count (whichever is greater!)
const int targetNumberColumns = std::max( forcedColumnBreaks + 1, mSettings.columnCount() );
const int numberAutoPlacedBreaks = targetNumberColumns - forcedColumnBreaks - 1;

// We know height of each group and we have to split them into columns
// minimizing max column height. It is sort of bin packing problem, NP-hard.
@@ -450,11 +451,12 @@ int QgsLegendRenderer::setColumns( QList<LegendComponentGroup> &componentGroups
int currentColumnGroupCount = 0; // number of groups in current column
double currentColumnHeight = 0;
double closedColumnsHeight = 0;
int autoPlacedBreaks = 0;

for ( int i = 0; i < componentGroups.size(); i++ )
{
// Recalc average height for remaining columns including current
double avgColumnHeight = ( totalHeight - closedColumnsHeight ) / ( targetNumberColumns - currentColumn );
double avgColumnHeight = ( totalHeight - closedColumnsHeight ) / ( numberAutoPlacedBreaks + 1 - autoPlacedBreaks );

LegendComponentGroup group = componentGroups.at( i );
double currentHeight = currentColumnHeight;
@@ -463,7 +465,8 @@ int QgsLegendRenderer::setColumns( QList<LegendComponentGroup> &componentGroups
currentHeight += group.size.height();

bool canCreateNewColumn = ( currentColumnGroupCount > 0 ) // do not leave empty column
&& ( currentColumn < targetNumberColumns - 1 ); // must not exceed max number of columns
&& ( currentColumn < targetNumberColumns - 1 ) // must not exceed max number of columns
&& ( autoPlacedBreaks < numberAutoPlacedBreaks );

bool shouldCreateNewColumn = ( currentHeight - avgColumnHeight ) > group.size.height() / 2 // center of current group is over average height
&& currentColumnGroupCount > 0 // do not leave empty column
@@ -481,6 +484,8 @@ int QgsLegendRenderer::setColumns( QList<LegendComponentGroup> &componentGroups
{
// New column
currentColumn++;
if ( !group.placeColumnBreakBeforeGroup )
autoPlacedBreaks++;
currentColumnGroupCount = 0;
closedColumnsHeight += currentColumnHeight;
currentColumnHeight = group.size.height();
@@ -164,6 +164,8 @@ class TestQgsLegendRenderer : public QObject
void testColumnBreaks();
void testColumnBreaks2();
void testColumnBreaks3();
void testColumnBreaks4();
void testColumnBreaks5();
void testRasterStroke();
void testFilterByPolygon();
void testFilterByExpression();
@@ -985,6 +987,50 @@ void TestQgsLegendRenderer::testColumnBreaks3()
QVERIFY( _verifyImage( testName, mReport ) );
}

void TestQgsLegendRenderer::testColumnBreaks4()
{
QString testName = QStringLiteral( "legend_column_breaks4" );

QgsLayerTreeModel legendModel( mRoot );

QgsLayerTreeLayer *layer = legendModel.rootGroup()->findLayer( mVL3 );
QgsMapLayerLegendUtils::setLegendNodeColumnBreak( layer, 0, true );
legendModel.refreshLayerLegend( layer );

layer = legendModel.rootGroup()->findLayer( mRL );
QgsMapLayerLegendUtils::setLegendNodeColumnBreak( layer, 0, true );
legendModel.refreshLayerLegend( layer );

QgsLegendSettings settings;
settings.setColumnCount( 5 );
settings.setSplitLayer( true );
_setStandardTestFont( settings, QStringLiteral( "Bold" ) );
_renderLegend( testName, &legendModel, settings );
QVERIFY( _verifyImage( testName, mReport ) );
}

void TestQgsLegendRenderer::testColumnBreaks5()
{
QString testName = QStringLiteral( "legend_column_breaks5" );

QgsLayerTreeModel legendModel( mRoot );

QgsLayerTreeLayer *layer = legendModel.rootGroup()->findLayer( mVL3 );
QgsMapLayerLegendUtils::setLegendNodeColumnBreak( layer, 0, true );
legendModel.refreshLayerLegend( layer );

layer = legendModel.rootGroup()->findLayer( mRL );
QgsMapLayerLegendUtils::setLegendNodeColumnBreak( layer, 0, true );
legendModel.refreshLayerLegend( layer );

QgsLegendSettings settings;
settings.setColumnCount( 4 );
settings.setSplitLayer( false );
_setStandardTestFont( settings, QStringLiteral( "Bold" ) );
_renderLegend( testName, &legendModel, settings );
QVERIFY( _verifyImage( testName, mReport ) );
}

void TestQgsLegendRenderer::testRasterStroke()
{
QString testName = QStringLiteral( "legend_raster_border" );
Binary file not shown.
Binary file not shown.
Binary file not shown.

0 comments on commit f09ec88

Please sign in to comment.
You can’t perform that action at this time.