@@ -265,49 +265,49 @@ void QgsLegendRenderer::setColumns( QList<Atom>& atomList )
265
265
266
266
// Divide atoms to columns
267
267
double totalHeight = 0 ;
268
- // bool first = true;
269
268
qreal maxAtomHeight = 0 ;
270
269
Q_FOREACH ( const Atom& atom, atomList )
271
270
{
272
- // if ( !first )
273
- // {
274
271
totalHeight += spaceAboveAtom ( atom );
275
- // }
276
272
totalHeight += atom.size .height ();
277
273
maxAtomHeight = qMax ( atom.size .height (), maxAtomHeight );
278
- // first = false;
279
274
}
280
275
281
276
// We know height of each atom and we have to split them into columns
282
277
// minimizing max column height. It is sort of bin packing problem, NP-hard.
283
278
// We are using simple heuristic, brute fore appeared to be to slow,
284
279
// the number of combinations is N = n!/(k!*(n-k)!) where n = atomsCount-1
285
280
// and k = columnsCount-1
286
-
287
- double avgColumnHeight = totalHeight / mSettings .columnCount ();
281
+ double maxColumnHeight = 0 ;
288
282
int currentColumn = 0 ;
289
283
int currentColumnAtomCount = 0 ; // number of atoms in current column
290
284
double currentColumnHeight = 0 ;
291
- double maxColumnHeight = 0 ;
292
285
double closedColumnsHeight = 0 ;
293
- // first = true; // first in column
286
+
294
287
for ( int i = 0 ; i < atomList.size (); i++ )
295
288
{
296
- Atom atom = atomList[i];
289
+ // Recalc average height for remaining columns including current
290
+ double avgColumnHeight = ( totalHeight - closedColumnsHeight ) / ( mSettings .columnCount () - currentColumn );
291
+
292
+ Atom atom = atomList.at ( i );
297
293
double currentHeight = currentColumnHeight;
298
- // if ( !first )
299
- // {
300
- currentHeight += spaceAboveAtom ( atom );
301
- // }
294
+ if ( currentColumnAtomCount > 0 )
295
+ currentHeight += spaceAboveAtom ( atom );
302
296
currentHeight += atom.size .height ();
303
297
304
- // Recalc average height for remaining columns including current
305
- avgColumnHeight = ( totalHeight - closedColumnsHeight ) / ( mSettings .columnCount () - currentColumn );
306
- if (( currentHeight - avgColumnHeight ) > atom.size .height () / 2 // center of current atom is over average height
307
- && currentColumnAtomCount > 0 // do not leave empty column
308
- && currentHeight > maxAtomHeight // no sense to make smaller columns than max atom height
309
- && currentHeight > maxColumnHeight // no sense to make smaller columns than max column already created
310
- && currentColumn < mSettings .columnCount () - 1 ) // must not exceed max number of columns
298
+ bool canCreateNewColumn = ( currentColumnAtomCount > 0 ) // do not leave empty column
299
+ && ( currentColumn < mSettings .columnCount () - 1 ); // must not exceed max number of columns
300
+
301
+ bool shouldCreateNewColumn = ( currentHeight - avgColumnHeight ) > atom.size .height () / 2 // center of current atom is over average height
302
+ && currentColumnAtomCount > 0 // do not leave empty column
303
+ && currentHeight > maxAtomHeight // no sense to make smaller columns than max atom height
304
+ && currentHeight > maxColumnHeight; // no sense to make smaller columns than max column already created
305
+
306
+ // also should create a new column if the number of items left < number of columns left
307
+ // in this case we should spread the remaining items out over the remaining columns
308
+ shouldCreateNewColumn |= ( atomList.size () - i < mSettings .columnCount () - currentColumn );
309
+
310
+ if ( canCreateNewColumn && shouldCreateNewColumn )
311
311
{
312
312
// New column
313
313
currentColumn++;
@@ -322,11 +322,9 @@ void QgsLegendRenderer::setColumns( QList<Atom>& atomList )
322
322
atomList[i].column = currentColumn;
323
323
currentColumnAtomCount++;
324
324
maxColumnHeight = qMax ( currentColumnHeight, maxColumnHeight );
325
-
326
- // first = false;
327
325
}
328
326
329
- // Alling labels of symbols for each layr/column to the same labelXOffset
327
+ // Align labels of symbols for each layr/column to the same labelXOffset
330
328
QMap<QString, qreal> maxSymbolWidth;
331
329
for ( int i = 0 ; i < atomList.size (); i++ )
332
330
{
0 commit comments