Extra tweaks to legend column auto breaking when manual breaks are present

This commit is contained in:
Nyall Dawson 2020-05-06 10:22:27 +10:00
parent d574bf7aaa
commit f09ec88156
5 changed files with 53 additions and 2 deletions

View File

@ -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();

View File

@ -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.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB