Project

General

Profile

« Previous | Next » 

Revision e738c599

Added by Patrick Plitzner over 4 years ago

ref #7095 Add summary row to top of grid

View differences:

eu.etaxonomy.taxeditor.editor/src/main/java/eu/etaxonomy/taxeditor/editor/workingSet/matrix/AggregationConfiguration.java
1
/**
2
 * Copyright (C) 2018 EDIT
3
 * European Distributed Institute of Taxonomy
4
 * http://www.e-taxonomy.eu
5
 *
6
 * The contents of this file are subject to the Mozilla Public License Version 1.1
7
 * See LICENSE.TXT at the top of this package for the full license terms.
8
 */
9
package eu.etaxonomy.taxeditor.editor.workingSet.matrix;
10

  
11
import org.eclipse.nebula.widgets.nattable.config.IConfigRegistry;
12
import org.eclipse.nebula.widgets.nattable.data.IDataProvider;
13
import org.eclipse.nebula.widgets.nattable.style.DisplayMode;
14
import org.eclipse.nebula.widgets.nattable.summaryrow.DefaultSummaryRowConfiguration;
15
import org.eclipse.nebula.widgets.nattable.summaryrow.ISummaryProvider;
16
import org.eclipse.nebula.widgets.nattable.summaryrow.SummaryRowConfigAttributes;
17
import org.eclipse.nebula.widgets.nattable.summaryrow.SummaryRowLayer;
18
import org.eclipse.nebula.widgets.nattable.util.GUIHelper;
19

  
20
import eu.etaxonomy.cdm.model.description.Feature;
21
import eu.etaxonomy.cdm.model.description.QuantitativeData;
22

  
23
/**
24
 * @author pplitzner
25
 * @since Jan 4, 2018
26
 *
27
 */
28
public class AggregationConfiguration extends DefaultSummaryRowConfiguration {
29

  
30
    private final IDataProvider dataProvider;
31
    private Feature feature;
32

  
33
    public AggregationConfiguration(IDataProvider dataProvider, Feature feature) {
34
        this.dataProvider = dataProvider;
35
        this.feature = feature;
36
        this.summaryRowBgColor = GUIHelper.COLOR_BLUE;
37
        this.summaryRowFgColor = GUIHelper.COLOR_WHITE;
38
    }
39

  
40
    @Override
41
    public void addSummaryProviderConfig(IConfigRegistry configRegistry) {
42
        if(feature.isSupportsQuantitativeData()){
43
            configRegistry.registerConfigAttribute(
44
                    SummaryRowConfigAttributes.SUMMARY_PROVIDER,
45
                    new QuantitativeSummaryProvider(),
46
                    DisplayMode.NORMAL,
47
                    SummaryRowLayer.DEFAULT_SUMMARY_COLUMN_CONFIG_LABEL_PREFIX+MatrixUtility.getProperty(feature));
48
        }
49
    }
50

  
51
    class QuantitativeSummaryProvider implements ISummaryProvider {
52
        @Override
53
        public Object summarize(int columnIndex) {
54
            Float minTotal = null;
55
            Float maxTotal = null;
56
            int rowCount = AggregationConfiguration.this.dataProvider.getRowCount();
57

  
58
            for (int rowIndex = 0; rowIndex < rowCount; rowIndex++) {
59
                Object dataValue = AggregationConfiguration.this.dataProvider.getDataValue(columnIndex,
60
                        rowIndex);
61
                if(dataValue instanceof QuantitativeData){
62
                    QuantitativeData quantitativeData = (QuantitativeData)dataValue;
63
                    Float min = quantitativeData.getMin();
64
                    Float max = quantitativeData.getMax();
65
                    if(minTotal==null || min<minTotal){
66
                        minTotal = min;
67
                    }
68
                    if(maxTotal==null || max>maxTotal){
69
                        maxTotal = max;
70
                    }
71
                }
72
            }
73
            String summaryString = "";
74
            if(minTotal!=null){
75
                summaryString += "from "+minTotal;
76
            }
77
            if(maxTotal!=null){
78
                summaryString += " up to "+maxTotal;
79
            }
80
            return summaryString;
81
        }
82
    }
83

  
84
}
eu.etaxonomy.taxeditor.editor/src/main/java/eu/etaxonomy/taxeditor/editor/workingSet/matrix/CharacterMatrix.java
51 51
import org.eclipse.nebula.widgets.nattable.export.command.ExportCommandHandler;
52 52
import org.eclipse.nebula.widgets.nattable.extension.glazedlists.GlazedListsEventLayer;
53 53
import org.eclipse.nebula.widgets.nattable.extension.glazedlists.GlazedListsSortModel;
54
import org.eclipse.nebula.widgets.nattable.grid.GridRegion;
54 55
import org.eclipse.nebula.widgets.nattable.grid.data.DefaultColumnHeaderDataProvider;
55 56
import org.eclipse.nebula.widgets.nattable.grid.data.DefaultCornerDataProvider;
56 57
import org.eclipse.nebula.widgets.nattable.grid.data.DefaultRowHeaderDataProvider;
58
import org.eclipse.nebula.widgets.nattable.grid.data.FixedSummaryRowHeaderLayer;
57 59
import org.eclipse.nebula.widgets.nattable.grid.layer.ColumnHeaderLayer;
58 60
import org.eclipse.nebula.widgets.nattable.grid.layer.CornerLayer;
61
import org.eclipse.nebula.widgets.nattable.grid.layer.DefaultRowHeaderDataLayer;
59 62
import org.eclipse.nebula.widgets.nattable.grid.layer.GridLayer;
60
import org.eclipse.nebula.widgets.nattable.grid.layer.RowHeaderLayer;
61 63
import org.eclipse.nebula.widgets.nattable.hideshow.ColumnHideShowLayer;
62 64
import org.eclipse.nebula.widgets.nattable.hideshow.RowHideShowLayer;
65
import org.eclipse.nebula.widgets.nattable.layer.CompositeLayer;
63 66
import org.eclipse.nebula.widgets.nattable.layer.DataLayer;
64 67
import org.eclipse.nebula.widgets.nattable.layer.ILayer;
65 68
import org.eclipse.nebula.widgets.nattable.layer.ILayerListener;
......
78 81
import org.eclipse.nebula.widgets.nattable.sort.SortHeaderLayer;
79 82
import org.eclipse.nebula.widgets.nattable.sort.config.SingleClickSortConfiguration;
80 83
import org.eclipse.nebula.widgets.nattable.style.DisplayMode;
84
import org.eclipse.nebula.widgets.nattable.summaryrow.FixedSummaryRowLayer;
85
import org.eclipse.nebula.widgets.nattable.summaryrow.SummaryRowLayer;
81 86
import org.eclipse.nebula.widgets.nattable.ui.menu.AbstractHeaderMenuConfiguration;
87
import org.eclipse.nebula.widgets.nattable.ui.menu.DebugMenuConfiguration;
82 88
import org.eclipse.nebula.widgets.nattable.ui.menu.PopupMenuBuilder;
83 89
import org.eclipse.nebula.widgets.nattable.viewport.ViewportLayer;
84 90
import org.eclipse.swt.SWT;
......
184 190
        List<Feature> features = new ArrayList<>(tree.getDistinctFeatures());
185 191
        Collections.sort(features);
186 192

  
187

  
188 193
        descriptions = GlazedLists.eventList(getDescriptions(workingSet));
189 194
        SortedList<RowWrapper> sortedList = new SortedList<>(descriptions, null);
190 195

  
196
        ConfigRegistry configRegistry = new ConfigRegistry();
197

  
191 198
        /**
192 199
         * data provider
193 200
         */
......
196 203

  
197 204
        /**
198 205
         * BODY layer
206
         *
207
         *
208

  
209
        CompositeLayer
210
         - (top) SummaryRowLayer
211
         - (bottom) ViewportLayer
212

  
213
             ^
214
        ViewportLayer
215

  
216
             ^
217
        SelectionLayer
218

  
219
             ^
220
        RowHideShowLayer
221

  
222
             ^
223
        ColumnHideShowLayer
224

  
225
             ^
226
        ColumnReorderLayer
227

  
228
             ^
229
        RowReorderLayer
230

  
231
             ^
232
        DataLayer
233

  
234
             *
235

  
199 236
         */
200 237
        DataLayer bodyDataLayer = new DataLayer(bodyDataProvider);
201 238

  
202 239
        //register labels for columns
203
        final ColumnOverrideLabelAccumulator columnLabelAccumulator =new ColumnOverrideLabelAccumulator(bodyDataLayer);
204
        bodyDataLayer.setConfigLabelAccumulator(columnLabelAccumulator);
240
        ColumnOverrideLabelAccumulator bodyColumnLabelAccumulator =new ColumnOverrideLabelAccumulator(bodyDataLayer);
241
        bodyDataLayer.setConfigLabelAccumulator(bodyColumnLabelAccumulator);
205 242
        propertyToLabelMap.put(TAXON_COLUMN, "Taxon");
206
        columnLabelAccumulator.registerColumnOverrides(0, TAXON_COLUMN);
243
        bodyColumnLabelAccumulator.registerColumnOverrides(0, TAXON_COLUMN);
207 244
        propertyToLabelMap.put(COLLECTOR_COLUMN, "Collector + No");
208
        columnLabelAccumulator.registerColumnOverrides(1, COLLECTOR_COLUMN);
245
        bodyColumnLabelAccumulator.registerColumnOverrides(1, COLLECTOR_COLUMN);
209 246
        propertyToLabelMap.put(IDENTIFIER_COLUMN, "Identifier");
210
        columnLabelAccumulator.registerColumnOverrides(2, IDENTIFIER_COLUMN);
247
        bodyColumnLabelAccumulator.registerColumnOverrides(2, IDENTIFIER_COLUMN);
211 248
        propertyToLabelMap.put(COUNTRY_COLUMN, "Country");
212
        columnLabelAccumulator.registerColumnOverrides(3, COUNTRY_COLUMN);
249
        bodyColumnLabelAccumulator.registerColumnOverrides(3, COUNTRY_COLUMN);
213 250
        for(int i=0;i<features.size();i++){
214 251
            Feature feature = features.get(i);
215
            initLabels(columnLabelAccumulator, i, feature);
252
            initLabels(bodyColumnLabelAccumulator, i, feature);
216 253
        }
217 254

  
218 255
        GlazedListsEventLayer<RowWrapper> eventLayer = new GlazedListsEventLayer<>(bodyDataLayer, sortedList);
......
224 261
        SelectionLayer selectionLayer = new SelectionLayer(rowHideShowLayer);
225 262
        ViewportLayer viewportLayer = new ViewportLayer(selectionLayer);
226 263

  
264

  
265
        // create a standalone FixedSummaryRowLayer
266
        // since the summary row should be fixed at the top of the body
267
        // region the horizontal dependency of the FixedSummaryRowLayer
268
        // is the ViewportLayer
269
        FixedSummaryRowLayer summaryRowLayer =
270
                new FixedSummaryRowLayer(bodyDataLayer, viewportLayer, configRegistry, false);
271
        //regoster labels with summary prefix for summary layer
272
        ColumnOverrideLabelAccumulator summaryColumnLabelAccumulator =new ColumnOverrideLabelAccumulator(bodyDataLayer);
273
        summaryRowLayer.setConfigLabelAccumulator(summaryColumnLabelAccumulator);
274
        for(int i=0;i<features.size();i++){
275
            Feature feature = features.get(i);
276
            summaryColumnLabelAccumulator.registerColumnOverrides(
277
                    i+LEADING_COLUMN_COUNT,
278
                    SummaryRowLayer.DEFAULT_SUMMARY_COLUMN_CONFIG_LABEL_PREFIX+MatrixUtility.getProperty(feature));
279
        }
280
        // because the horizontal dependency is the ViewportLayer
281
        // we need to set the composite dependency to false
282
        summaryRowLayer.setHorizontalCompositeDependency(false);
283

  
284
        CompositeLayer composite = new CompositeLayer(1, 2);
285
        composite.setChildLayer("SUMMARY", summaryRowLayer, 0, 0);
286
        composite.setChildLayer(GridRegion.BODY, viewportLayer, 0, 1);
287

  
288

  
289

  
290

  
227 291
        /**
228 292
         * column header layer
229 293
         */
......
232 296
        DataLayer columnHeaderDataLayer = new DataLayer(columnHeaderDataProvider);
233 297
        ColumnHeaderLayer columnHeaderLayer = new ColumnHeaderLayer(columnHeaderDataLayer, viewportLayer, selectionLayer);
234 298

  
235
        ConfigRegistry configRegistry = new ConfigRegistry();
236

  
237 299
        // add the SortHeaderLayer to the column header layer stack
238 300
        // as we use GlazedLists, we use the GlazedListsSortModel which
239 301
        // delegates the sorting to the SortedList
......
250 312
         * row header layer
251 313
         */
252 314
        IDataProvider rowHeaderDataProvider = new DefaultRowHeaderDataProvider(bodyDataProvider);
253
        DataLayer rowHeaderDataLayer = new DataLayer(rowHeaderDataProvider, 40, 20);
254
        ILayer rowHeaderLayer = new RowHeaderLayer(rowHeaderDataLayer, viewportLayer, selectionLayer);
315
        DefaultRowHeaderDataLayer rowHeaderDataLayer = new DefaultRowHeaderDataLayer(rowHeaderDataProvider);
316
        FixedSummaryRowHeaderLayer fixedSummaryRowHeaderLayer = new FixedSummaryRowHeaderLayer(rowHeaderDataLayer,
317
                composite, selectionLayer);
318
        fixedSummaryRowHeaderLayer.setSummaryRowLabel("\u2211");
255 319

  
256 320

  
257 321
        /**
......
259 323
         */
260 324
        ILayer cornerLayer = new CornerLayer(
261 325
                new DataLayer(new DefaultCornerDataProvider(columnHeaderDataProvider, rowHeaderDataProvider)),
262
                rowHeaderLayer, sortHeaderLayer);
326
                fixedSummaryRowHeaderLayer, sortHeaderLayer);
263 327

  
264 328

  
265 329
        /**
266 330
         * GRID layer (composition of all other layers)
267 331
         */
268
        GridLayer gridLayer = new GridLayer(viewportLayer, sortHeaderLayer, rowHeaderLayer, cornerLayer);
332
        GridLayer gridLayer = new GridLayer(composite, sortHeaderLayer, fixedSummaryRowHeaderLayer, cornerLayer);
333

  
269 334

  
270 335

  
271 336
        natTable = new NatTable(parent, gridLayer, false);
......
284 349
        // to sort on a single click
285 350
        natTable.addConfiguration(new SingleClickSortConfiguration());
286 351

  
352
        //FIXME: this is for DEBUG ONLY
353
        natTable.addConfiguration(new DebugMenuConfiguration(natTable));
354

  
287 355
        // add the header menu configuration for adding the column header menu
288 356
        // with hide/show actions
289 357
        natTable.addConfiguration(new AbstractHeaderMenuConfiguration(natTable) {
......
310 378
            }
311 379
        });
312 380

  
313
        // add custom configuration for data conversion and add column labels
381
        // add custom configuration for data conversion and add column labels to viewport layer
314 382
        viewportLayer.addConfiguration(new AbstractRegistryConfiguration() {
315 383
            @Override
316 384
            public void configureRegistry(IConfigRegistry configRegistry) {
......
340 408

  
341 409
        });
342 410

  
411
        //register aggregation configuration for each feature
412
        features.forEach(feature->summaryRowLayer.addConfiguration(new AggregationConfiguration(bodyDataProvider, feature)));
413

  
343 414
        // add the ExportCommandHandler to the ViewportLayer in order to make
344 415
        // exporting work
345 416
        viewportLayer.registerCommandHandler(new ExportCommandHandler(viewportLayer));
......
354 425
                    StructuredSelection selection = new StructuredSelection();
355 426
                    if(selectedCells.size()==1){
356 427
                        ILayerCell cell = selectedCells.iterator().next();
357
                        selection = new StructuredSelection(cell.getDataValue());
428
                        Object dataValue = cell.getDataValue();
429
                        if(dataValue!=null){
430
                            selection = new StructuredSelection(dataValue);
431
                        }
358 432
                    }
359 433
                    selService.setSelection(selection);
360 434
                }
......
468 542
    private void initLabels(final ColumnOverrideLabelAccumulator columnLabelAccumulator,
469 543
            int index, Feature feature) {
470 544

  
471
        columnLabelAccumulator.registerColumnOverrides(index+LEADING_COLUMN_COUNT, getProperty(feature));
545
        columnLabelAccumulator.registerColumnOverrides(index+LEADING_COLUMN_COUNT, MatrixUtility.getProperty(feature));
472 546
        indexToFeatureMap.put(index+LEADING_COLUMN_COUNT, feature);
473 547

  
474 548
        String featureLabel = feature.getLabel();
......
493 567
                EditConfigAttributes.CELL_EDITABLE_RULE,
494 568
                IEditableRule.ALWAYS_EDITABLE,
495 569
                DisplayMode.EDIT,
496
                getProperty(feature)
570
                MatrixUtility.getProperty(feature)
497 571
                );
498 572
        if(feature.isSupportsQuantitativeData()){
499 573
            //add display converter for string representation
......
501 575
                    CellConfigAttributes.DISPLAY_CONVERTER,
502 576
                    new QuantitativeDataDisplayConverter(),
503 577
                    DisplayMode.NORMAL,
504
                    getProperty(feature));
578
                    MatrixUtility.getProperty(feature));
505 579
            //register quantitative editor
506 580
            configRegistry.registerConfigAttribute(
507 581
                    EditConfigAttributes.CELL_EDITOR,
508 582
                    new QuantitativeDataCellEditor(feature.getRecommendedStatisticalMeasures(), this),
509 583
                    DisplayMode.EDIT,
510
                    getProperty(feature));
584
                    MatrixUtility.getProperty(feature));
511 585
        }
512 586
        else if(feature.isSupportsCategoricalData()){
513 587
            //add display converter for string representation
......
515 589
                    CellConfigAttributes.DISPLAY_CONVERTER,
516 590
                    new CategoricalDataDisplayConverter(),
517 591
                    DisplayMode.NORMAL,
518
                    getProperty(feature));
592
                    MatrixUtility.getProperty(feature));
519 593

  
520 594
            //add combo box cell editor
521 595
            CategoricalDataCellEditor comboBoxCellEditor = new CategoricalDataCellEditor(new IComboBoxDataProvider() {
......
537 611
            configRegistry.registerConfigAttribute(EditConfigAttributes.CELL_EDITOR,
538 612
                    comboBoxCellEditor,
539 613
                    DisplayMode.EDIT,
540
                    getProperty(feature));
614
                    MatrixUtility.getProperty(feature));
541 615

  
542 616
        }
543 617

  
......
554 628
        return rowWrappers;
555 629
    }
556 630

  
557
    private String getProperty(Feature feature){
558
        return feature.getLabel();
559
    }
560

  
561 631
    public Map<Integer, Feature> getIndexToFeatureMap() {
562 632
        return indexToFeatureMap;
563 633
    }
eu.etaxonomy.taxeditor.editor/src/main/java/eu/etaxonomy/taxeditor/editor/workingSet/matrix/MatrixUtility.java
1
/**
2
* Copyright (C) 2018 EDIT
3
* European Distributed Institute of Taxonomy
4
* http://www.e-taxonomy.eu
5
*
6
* The contents of this file are subject to the Mozilla Public License Version 1.1
7
* See LICENSE.TXT at the top of this package for the full license terms.
8
*/
9
package eu.etaxonomy.taxeditor.editor.workingSet.matrix;
10

  
11
import eu.etaxonomy.cdm.model.description.Feature;
12

  
13
/**
14
 * Utility class for the character matrix editor
15
 * @author pplitzner
16
 * @since Jan 4, 2018
17
 *
18
 */
19
public class MatrixUtility {
20

  
21
    /**
22
     * Returns the column property string for the given {@link Feature}
23
     * @param feature
24
     * @return
25
     */
26
    public static String getProperty(Feature feature){
27
        return feature.getLabel();
28
    }
29
}

Also available in: Unified diff