diff --git a/src/gui/org/deidentifier/arx/gui/resources/crossSR.png b/src/gui/org/deidentifier/arx/gui/resources/crossSR.png new file mode 100644 index 0000000000..288adf8552 Binary files /dev/null and b/src/gui/org/deidentifier/arx/gui/resources/crossSR.png differ diff --git a/src/gui/org/deidentifier/arx/gui/resources/messages.properties b/src/gui/org/deidentifier/arx/gui/resources/messages.properties index 5a47d636bc..7f48b9ba9f 100644 --- a/src/gui/org/deidentifier/arx/gui/resources/messages.properties +++ b/src/gui/org/deidentifier/arx/gui/resources/messages.properties @@ -655,7 +655,8 @@ SeparatorDialog.9=Error StatisticsView.0=Distribution StatisticsView.1=Contingency StatisticsView.2=Properties -StatisticsView.3=Enable/disable +StatisticsView.3=Enable/disable visualization +StatisticsView.13=Enable/disable suppressed records StatisticsView.4=Distribution (table) StatisticsView.5=Contingency (table) StatisticsView.6=Summary statistics diff --git a/src/gui/org/deidentifier/arx/gui/resources/tickSR.png b/src/gui/org/deidentifier/arx/gui/resources/tickSR.png new file mode 100644 index 0000000000..e7168a6aba Binary files /dev/null and b/src/gui/org/deidentifier/arx/gui/resources/tickSR.png differ diff --git a/src/gui/org/deidentifier/arx/gui/view/impl/common/async/AnalysisContextVisualization.java b/src/gui/org/deidentifier/arx/gui/view/impl/common/async/AnalysisContextVisualization.java index 96fce438fe..d15ceb2118 100644 --- a/src/gui/org/deidentifier/arx/gui/view/impl/common/async/AnalysisContextVisualization.java +++ b/src/gui/org/deidentifier/arx/gui/view/impl/common/async/AnalysisContextVisualization.java @@ -17,6 +17,8 @@ package org.deidentifier.arx.gui.view.impl.common.async; +import org.deidentifier.arx.aggregates.StatisticsFrequencyDistribution; + /** * The current context. * @@ -38,4 +40,12 @@ public interface AnalysisContextVisualization { * @return */ public boolean isValid(); + + /** + * Hide suppressed records. + * + * @param distribution + * @return + */ + public void hideSuppressedData(StatisticsFrequencyDistribution distribution) throws InterruptedException; } diff --git a/src/gui/org/deidentifier/arx/gui/view/impl/risk/AnalysisContextRisk.java b/src/gui/org/deidentifier/arx/gui/view/impl/risk/AnalysisContextRisk.java index 74d8d70856..41ed54732f 100644 --- a/src/gui/org/deidentifier/arx/gui/view/impl/risk/AnalysisContextRisk.java +++ b/src/gui/org/deidentifier/arx/gui/view/impl/risk/AnalysisContextRisk.java @@ -18,6 +18,7 @@ package org.deidentifier.arx.gui.view.impl.risk; import org.deidentifier.arx.DataHandle; +import org.deidentifier.arx.aggregates.StatisticsFrequencyDistribution; import org.deidentifier.arx.gui.model.Model; import org.deidentifier.arx.gui.view.impl.common.async.AnalysisContext; import org.deidentifier.arx.gui.view.impl.common.async.AnalysisContextVisualization; @@ -68,4 +69,11 @@ public boolean isValid(){ else if (this.model == null) return false; else return true; } + + @Override + public void + hideSuppressedData(StatisticsFrequencyDistribution distribution) throws InterruptedException { + // TODO Auto-generated method stub + //Empty by design + } } diff --git a/src/gui/org/deidentifier/arx/gui/view/impl/utility/AnalysisContextClassification.java b/src/gui/org/deidentifier/arx/gui/view/impl/utility/AnalysisContextClassification.java index a2d97e78e8..7096f60c2b 100644 --- a/src/gui/org/deidentifier/arx/gui/view/impl/utility/AnalysisContextClassification.java +++ b/src/gui/org/deidentifier/arx/gui/view/impl/utility/AnalysisContextClassification.java @@ -18,6 +18,7 @@ package org.deidentifier.arx.gui.view.impl.utility; import org.deidentifier.arx.DataHandle; +import org.deidentifier.arx.aggregates.StatisticsFrequencyDistribution; import org.deidentifier.arx.gui.model.Model; import org.deidentifier.arx.gui.view.impl.common.async.AnalysisContext; import org.deidentifier.arx.gui.view.impl.common.async.AnalysisContextVisualization; @@ -67,4 +68,12 @@ public boolean isValid(){ else if (this.model.getSelectedFeatures().isEmpty()) return false; else return true; } + + @Override + public void + hideSuppressedData(StatisticsFrequencyDistribution distribution) throws InterruptedException { + // TODO Auto-generated method stub + // Empty by design + + } } diff --git a/src/gui/org/deidentifier/arx/gui/view/impl/utility/AnalysisContextContingency.java b/src/gui/org/deidentifier/arx/gui/view/impl/utility/AnalysisContextContingency.java index 468e883024..7474002aa4 100644 --- a/src/gui/org/deidentifier/arx/gui/view/impl/utility/AnalysisContextContingency.java +++ b/src/gui/org/deidentifier/arx/gui/view/impl/utility/AnalysisContextContingency.java @@ -20,6 +20,7 @@ import org.deidentifier.arx.AttributeType; import org.deidentifier.arx.DataHandle; import org.deidentifier.arx.DataType; +import org.deidentifier.arx.aggregates.StatisticsFrequencyDistribution; import org.deidentifier.arx.gui.model.Model; import org.deidentifier.arx.gui.view.impl.common.async.AnalysisContext; import org.deidentifier.arx.gui.view.impl.common.async.AnalysisContextVisualization; @@ -105,4 +106,11 @@ public boolean isValid(){ else if (this.attributeType2 == null) return false; else return true; } + + @Override + public void + hideSuppressedData(StatisticsFrequencyDistribution distribution) throws InterruptedException { + // TODO Auto-generated method stub + //Empty by design + } } diff --git a/src/gui/org/deidentifier/arx/gui/view/impl/utility/AnalysisContextDistribution.java b/src/gui/org/deidentifier/arx/gui/view/impl/utility/AnalysisContextDistribution.java index 08ce467b1a..79922eed6f 100644 --- a/src/gui/org/deidentifier/arx/gui/view/impl/utility/AnalysisContextDistribution.java +++ b/src/gui/org/deidentifier/arx/gui/view/impl/utility/AnalysisContextDistribution.java @@ -17,9 +17,14 @@ package org.deidentifier.arx.gui.view.impl.utility; +import java.util.ArrayList; + import org.deidentifier.arx.AttributeType; import org.deidentifier.arx.DataHandle; import org.deidentifier.arx.DataType; +import org.deidentifier.arx.AttributeType.Hierarchy; +import org.deidentifier.arx.aggregates.StatisticsBuilderInterruptible; +import org.deidentifier.arx.aggregates.StatisticsFrequencyDistribution; import org.deidentifier.arx.gui.model.Model; import org.deidentifier.arx.gui.view.impl.common.async.AnalysisContext; import org.deidentifier.arx.gui.view.impl.common.async.AnalysisContextVisualization; @@ -32,13 +37,13 @@ public class AnalysisContextDistribution implements AnalysisContextVisualization{ /** Context information. */ - public String attribute = null; + public String attribute = null; /** Context information. */ - public DataType dataType = null; + public DataType dataType = null; /** Context information. */ - public AttributeType attributeType = null; + public AttributeType attributeType = null; /** Context information. */ public DataHandle handle = null; @@ -47,8 +52,14 @@ public class AnalysisContextDistribution implements AnalysisContextVisualization public Model model = null; /** Context information. */ - public AnalysisContext context = null; + public AnalysisContext context = null; + /** Context distribution. */ + public String [] newDistValues = null; + + /** Context distribution. */ + public double [] newDistFreqs = null; + /** * Creates a new context from the given context. * @@ -86,4 +97,33 @@ public boolean isValid(){ else if (this.attributeType == null) return false; else return true; } + + /** + * Hide suppressed records. + * + * @param distribution + * @throws InterruptedException + */ + public void hideSuppressedData( StatisticsFrequencyDistribution distribution) throws InterruptedException { + + ArrayList newValues = new ArrayList(); + for (String s: distribution.values) { + newValues.add(s); + } + double srSum = 0.0; + int sr=newValues.indexOf("*"); + newValues.removeIf(element-> (element=="*")); + + for (int i = 0; i helpids = new HashMap(); @@ -108,28 +126,53 @@ public LayoutUtilityStatistics(final Composite parent, final ModelPart target, final ModelPart reset) { - this.enabled = controller.getResources().getManagedImage("tick.png"); //$NON-NLS-1$ - this.disabled = controller.getResources().getManagedImage("cross.png"); //$NON-NLS-1$ + // initialize controller components + + // initialize check button icons + this.icnVisEnabled = controller.getResources().getManagedImage("tick.png"); //$NON-NLS-1$ + this.icnVisDisabled = controller.getResources().getManagedImage("cross.png"); //$NON-NLS-1$ + + this.icnSREnabled = controller.getResources().getManagedImage("tickSR.png"); //$NON-NLS-1$ + this.icnSRDisabled = controller.getResources().getManagedImage("crossSR.png"); //$NON-NLS-1$ + this.controller = controller; controller.addListener(ModelPart.MODEL, this); controller.addListener(ModelPart.SELECTED_UTILITY_VISUALIZATION, this); - // Create enable/disable button - final String label = Resources.getMessage("StatisticsView.3"); //$NON-NLS-1$ - ComponentTitledFolderButtonBar bar = new ComponentTitledFolderButtonBar("id-50", helpids); //$NON-NLS-1$ - bar.add(label, disabled, true, new Runnable() { @Override public void run() { - toggleEnabled(); - toggleImage(); + // Create toolbar + ComponentTitledFolderButtonBar toolbarVis = new ComponentTitledFolderButtonBar("id-50", helpids); //$NON-NLS-1$ + + // Create suppressed records and visualisation enable/disable check buttons + final String chkbtnSuppressedRecordsLabel = Resources.getMessage("StatisticsView.13"); //$NON-NLS-1$ + final String chkbtnVisualisationLabel = Resources.getMessage("StatisticsView.3"); //$NON-NLS-1$ + + + // add check buttons to the to the toolbar + + if (!(target == ModelPart.INPUT)) { + toolbarVis.add(chkbtnSuppressedRecordsLabel, icnSRDisabled, true, new Runnable() { @Override public void run() { + toggleChkbtnSuppressedRecords(); + toggleChkbtnSRIcon(); + }}); + } + + toolbarVis.add(chkbtnVisualisationLabel, icnVisDisabled, true, new Runnable() { @Override public void run() { + toggleChkbtnVisualization(); + toggleChkbtnVizIcon(); }}); + // Create the tab folder - folder = new ComponentTitledFolder(parent, controller, bar, null, false, true); + folder = new ComponentTitledFolder(parent, controller, toolbarVis, null, false, true); + distHist = new ViewStatisticsDistributionHistogram(folder.createItem(TAB_DISTRIBUTION, null, true), controller, target, reset ); + distTbl = new ViewStatisticsDistributionTable(folder.createItem(TAB_DISTRIBUTION_TABLE, null, true), controller, target, reset); + // Register tabs this.registerView(new ViewStatisticsSummaryTable(folder.createItem(TAB_SUMMARY, null, true), controller, target, reset), "help.utility.summary"); //$NON-NLS-1$ - this.registerView(new ViewStatisticsDistributionHistogram(folder.createItem(TAB_DISTRIBUTION, null, true), controller, target, reset), "help.utility.distribution"); //$NON-NLS-1$ - this.registerView(new ViewStatisticsDistributionTable(folder.createItem(TAB_DISTRIBUTION_TABLE, null, true), controller, target, reset), "help.utility.distribution"); //$NON-NLS-1$ + this.registerView( distHist, "help.utility.distribution"); //$NON-NLS-1$ + this.registerView( distTbl , "help.utility.distribution"); //$NON-NLS-1$ this.registerView(new ViewStatisticsContingencyHeatmap(folder.createItem(TAB_CONTINGENCY, null, true), controller, target, reset), "help.utility.contingency"); //$NON-NLS-1$ this.registerView(new ViewStatisticsContingencyTable(folder.createItem(TAB_CONTINGENCY_TABLE, null, true), controller, target, reset), "help.utility.contingency"); //$NON-NLS-1$ this.registerView(new ViewStatisticsEquivalenceClassTable(folder.createItem(TAB_CLASSES_TABLE, null, true), controller, target, reset), "help.utility.classes"); //$NON-NLS-1$ @@ -143,12 +186,21 @@ public LayoutUtilityStatistics(final Composite parent, // Init folder this.folder.setSelection(0); - this.enable = folder.getButtonItem(label); - this.enable.setEnabled(false); + this.chkbtnVisualisation = folder.getButtonItem(chkbtnVisualisationLabel); + this.chkbtnVisualisation.setEnabled(false); + this.chkbtnVisualisation.setToolTipText("Disable visualization!"); + + if ( !(target == ModelPart.INPUT) ) { + this.chkbtnSuppressedRecords = folder.getButtonItem(chkbtnSuppressedRecordsLabel); + this.chkbtnSuppressedRecords.setEnabled(true); + this.chkbtnSuppressedRecords.setToolTipText("Hide suppressed records!"); + + }; // Set initial visibility folder.setVisibleItems(Arrays.asList(new String[] { TAB_SUMMARY, TAB_DISTRIBUTION, + TAB_DISTRIBUTION_TABLE, TAB_CONTINGENCY, TAB_CLASSES_TABLE, TAB_PROPERTIES })); @@ -188,9 +240,9 @@ public List getVisibleItems() { @Override public void reset() { model = null; - enable.setSelection(true); - enable.setImage(enabled); - enable.setEnabled(false); + chkbtnVisualisation.setSelection(true); + chkbtnVisualisation.setImage(icnVisEnabled); + chkbtnVisualisation.setEnabled(false); } /** @@ -227,13 +279,12 @@ public void update(ModelEvent event) { if (event.part == ModelPart.MODEL) { this.model = (Model)event.data; - this.enable.setEnabled(true); - this.enable.setSelection(model.isVisualizationEnabled()); - this.toggleImage(); + this.chkbtnVisualisation.setEnabled(true); + this.chkbtnVisualisation.setSelection(model.isVisualizationEnabled()); } else if (event.part == ModelPart.SELECTED_UTILITY_VISUALIZATION) { - this.enable.setSelection(model.isVisualizationEnabled()); - this.toggleImage(); + this.chkbtnVisualisation.setSelection(model.isVisualizationEnabled()); } + this.toggleChkbtnVizIcon(); } /** @@ -259,19 +310,56 @@ private void registerView(ViewStatisticsBasic view, String helpid) { /** * Toggle visualization enabled. */ - private void toggleEnabled() { - this.model.setVisualizationEnabled(this.enable.getSelection()); - this.controller.update(new ModelEvent(this, ModelPart.SELECTED_UTILITY_VISUALIZATION, enable.getSelection())); + /** + * Toggle visualization . + */ + private void toggleChkbtnVisualization() { + this.model.setVisualizationEnabled(this.chkbtnVisualisation.getSelection()); + this.controller.update(new ModelEvent(this, ModelPart.SELECTED_UTILITY_VISUALIZATION, chkbtnVisualisation.getSelection())); } /** - * Toggle image. + * Toggle suppressed records */ - private void toggleImage(){ - if (enable.getSelection()) { - enable.setImage(enabled); - } else { - enable.setImage(disabled); + private void toggleChkbtnSuppressedRecords() { + if (this.chkbtnVisualisation.getSelection()) { + this.hideSuppressedRecords = this.chkbtnSuppressedRecords.getSelection(); + + this.model.setVisualizationEnabled(false); + this.controller.update(new ModelEvent(this, ModelPart.SELECTED_UTILITY_VISUALIZATION, false)); + + this.distHist.update(new ModelEvent(this, ModelPart.SELECTED_UTILITY_VISUALIZATION, false),this.hideSuppressedRecords); + this.distTbl.update(new ModelEvent(this, ModelPart.SELECTED_UTILITY_VISUALIZATION, false),this.hideSuppressedRecords); + + this.model.setVisualizationEnabled(true); + this.controller.update(new ModelEvent(this, ModelPart.SELECTED_UTILITY_VISUALIZATION, true)); } } + + + /** + * Toggle check button image. + */ + private void toggleChkbtnVizIcon(){ + if (!this.chkbtnVisualisation.getSelection()) { + this.chkbtnVisualisation.setImage(icnVisDisabled); + this.chkbtnVisualisation.setToolTipText("Enable visualization!"); + } else { + this.chkbtnVisualisation.setImage(icnVisEnabled); + this.chkbtnVisualisation.setToolTipText("Disable visualization!"); + } + } + + /** + * Toggle check button image. + */ + private void toggleChkbtnSRIcon(){ + if (!this.chkbtnSuppressedRecords.getSelection()) { + this.chkbtnSuppressedRecords.setImage(icnSRDisabled); + this.chkbtnSuppressedRecords.setToolTipText("Hide suppressed records!"); + } else { + this.chkbtnSuppressedRecords.setImage(icnSREnabled); + this.chkbtnSuppressedRecords.setToolTipText("View suppressed records!"); + } + } } diff --git a/src/gui/org/deidentifier/arx/gui/view/impl/utility/ViewStatistics.java b/src/gui/org/deidentifier/arx/gui/view/impl/utility/ViewStatistics.java index 202bb031c5..b800bccbf8 100644 --- a/src/gui/org/deidentifier/arx/gui/view/impl/utility/ViewStatistics.java +++ b/src/gui/org/deidentifier/arx/gui/view/impl/utility/ViewStatistics.java @@ -386,4 +386,12 @@ protected void setStatusEmpty(){ protected void setStatusWorking(){ this.status.setWorking(); } + + /** + * Status working. + */ + public void update(ModelEvent event, Boolean hideSuppressedRecords) { + // TODO Auto-generated method stub + + } } diff --git a/src/gui/org/deidentifier/arx/gui/view/impl/utility/ViewStatisticsDistributionHistogram.java b/src/gui/org/deidentifier/arx/gui/view/impl/utility/ViewStatisticsDistributionHistogram.java index 46726126fa..7a386248d3 100644 --- a/src/gui/org/deidentifier/arx/gui/view/impl/utility/ViewStatisticsDistributionHistogram.java +++ b/src/gui/org/deidentifier/arx/gui/view/impl/utility/ViewStatisticsDistributionHistogram.java @@ -21,6 +21,7 @@ import org.deidentifier.arx.aggregates.StatisticsBuilderInterruptible; import org.deidentifier.arx.aggregates.StatisticsFrequencyDistribution; import org.deidentifier.arx.gui.Controller; +import org.deidentifier.arx.gui.model.ModelEvent; import org.deidentifier.arx.gui.model.ModelEvent.ModelPart; import org.deidentifier.arx.gui.resources.Resources; import org.deidentifier.arx.gui.view.SWTUtil; @@ -72,6 +73,9 @@ public class ViewStatisticsDistributionHistogram extends ViewStatistics