From: luukkainen Date: Tue, 2 Jul 2013 13:50:48 +0000 (+0000) Subject: refs #4373 X-Git-Tag: 1.8.1~278 X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=commitdiff_plain;h=ffce9d86cded5e9f7fa66c145a12408c5b839f4d;p=simantics%2Fsysdyn.git refs #4373 git-svn-id: https://www.simantics.org/svn/simantics/sysdyn/trunk@27673 ac1ea38d-2e2b-0410-8846-a27921b304fc --- diff --git a/org.simantics.jfreechart.ontology/graph.tg b/org.simantics.jfreechart.ontology/graph.tg index 3abaa9be..5a57c746 100644 Binary files a/org.simantics.jfreechart.ontology/graph.tg and b/org.simantics.jfreechart.ontology/graph.tg differ diff --git a/org.simantics.jfreechart.ontology/graph/JFreeChart.pgraph b/org.simantics.jfreechart.ontology/graph/JFreeChart.pgraph index aaf0a275..f185b412 100644 --- a/org.simantics.jfreechart.ontology/graph/JFreeChart.pgraph +++ b/org.simantics.jfreechart.ontology/graph/JFreeChart.pgraph @@ -130,4 +130,12 @@ JFREE.Right -- JFREE.ChartElement.component --> JFREE.Chart + * + */ +public interface FilteredDataset { + + public boolean isFiltering(); + public void setFiltering(boolean filtering); + + + public double getFilterFraction(); + /** + * Sets filtering fraction 0 <= fraction <= 1 + * With filtering fraction 0 nothing gets filtered. + * With filtering fraction 1 everything gets filtered. + * + * @param filterFraction + */ + public void setFilterFraction(double filterFraction); + + public void updateFiltered(); +} diff --git a/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/FilteringCategoryDataset.java b/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/FilteringCategoryDataset.java new file mode 100644 index 00000000..510518aa --- /dev/null +++ b/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/FilteringCategoryDataset.java @@ -0,0 +1,178 @@ +package org.simantics.jfreechart.chart; + +/** + * Filters CategoryDataset by creating "Other" item for filtered data. + * + * @author Marko Luukkainen + * + */ +import java.util.List; + +import org.jfree.data.category.DefaultCategoryDataset; +import org.jfree.data.general.AbstractDataset; +import org.jfree.data.general.DatasetChangeEvent; + +@SuppressWarnings("rawtypes") +public class FilteringCategoryDataset extends AbstractDataset implements org.jfree.data.category.CategoryDataset, FilteredDataset{ + + private static final long serialVersionUID = -4955124650051030544L; + + org.jfree.data.category.CategoryDataset original; + DefaultCategoryDataset filtered; + org.jfree.data.category.CategoryDataset used; + + boolean filterRows = true; + boolean filtering = true; + double filterFraction = 0.05; + private Comparable other; + + public FilteringCategoryDataset(org.jfree.data.category.CategoryDataset dataset, Comparable other) { + this.original = dataset; + this.filtered = new DefaultCategoryDataset(); + this.other = other; + this.used = filtered; + updateFiltered(); + } + + @Override + public boolean isFiltering() { + return filtering; + } + + @Override + public void setFiltering(boolean filtering) { + this.filtering = filtering; + if (filtering) + used = filtered; + else + used = original; + notifyListeners(new DatasetChangeEvent(this, this)); + } + + public void setFilterFraction(double filterFraction) { + this.filterFraction = filterFraction; + } + + public double getFilterFraction() { + return filterFraction; + } + + /** + * Filter rows or columns. + * @param filterRows + */ + public void setFilterRows(boolean filterRows) { + this.filterRows = filterRows; + } + + public boolean isFilterRows() { + return filterRows; + } + + public void updateFiltered() { + filtered.clear(); + if (filterRows) { + for (Object column : original.getColumnKeys()) { + Double total = 0.0; + Double other = 0.0; + for (Object row : original.getRowKeys()) { + Number value = original.getValue((Comparable) row, (Comparable)column); + if (value != null) + total+=value.doubleValue(); + } + total *= filterFraction; + for (Object row : original.getRowKeys()) { + Number value = original.getValue((Comparable) row, (Comparable)column); + if (value == null) + continue; + if (value.doubleValue() > total) { + filtered.addValue(value, (Comparable) row, (Comparable)column); + } else { + other += value.doubleValue(); + } + } + if (other > 0.0) { + filtered.addValue(other, this.other, (Comparable)column); + } + } + } else { + for (Object row : original.getRowKeys()) { + Double total = 0.0; + Double other = 0.0; + for (Object column : original.getColumnKeys()) { + Number value = original.getValue((Comparable) row, (Comparable)column); + if (value != null) + total += value.doubleValue(); + } + total *= filterFraction; + for (Object column : original.getColumnKeys()) { + Number value = original.getValue((Comparable) row, (Comparable)column); + if (value == null) + continue; + if (value.doubleValue() > total) { + filtered.addValue(value, (Comparable) row, (Comparable)column); + } else { + other += value.doubleValue(); + } + } + if (other > 0.0) { + filtered.addValue(other, (Comparable)row, this.other); + } + } + } + } + + @Override + public int getColumnCount() { + return used.getColumnCount(); + } + + @Override + public int getRowCount() { + return used.getRowCount(); + } + + @Override + public Number getValue(Comparable rowKey, Comparable columnKey) { + return used.getValue(rowKey, columnKey); + } + + @Override + public Number getValue(int row, int column) { + return used.getValue(row, column); + } + + @Override + public List getColumnKeys() { + return used.getColumnKeys(); + } + + @Override + public Comparable getColumnKey(int column) { + return used.getColumnKey(column); + } + + @Override + public List getRowKeys() { + return used.getRowKeys(); + } + + @Override + public Comparable getRowKey(int row) { + return used.getRowKey(row); + } + + @Override + public int getRowIndex(Comparable key) { + return used.getRowIndex(key); + } + + @Override + public int getColumnIndex(Comparable key) { + return used.getColumnIndex(key); + } + + + + +} diff --git a/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/FilteringPieDataset.java b/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/FilteringPieDataset.java new file mode 100644 index 00000000..f815b03f --- /dev/null +++ b/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/FilteringPieDataset.java @@ -0,0 +1,117 @@ +package org.simantics.jfreechart.chart; + +import java.util.List; + +import org.jfree.data.general.AbstractDataset; +import org.jfree.data.general.DatasetChangeEvent; +import org.jfree.data.general.DefaultPieDataset; +import org.jfree.data.general.PieDataset; + +/** + * Filters PieDataset by creating "Other" item for filtered data. + * + * @author Marko Luukkainen + * + */ +@SuppressWarnings("rawtypes") +public class FilteringPieDataset extends AbstractDataset implements PieDataset, FilteredDataset{ + + private static final long serialVersionUID = -4955124650051030544L; + + PieDataset original; + DefaultPieDataset filtered; + PieDataset used; + + + boolean filtering = true; + double filterFraction = 0.05; + + private Comparable other = "other"; + + public FilteringPieDataset(PieDataset dataset, Comparable other) { + this.original = dataset; + this.filtered = new DefaultPieDataset(); + this.other = other; + this.used = filtered; + updateFiltered(); + } + + @Override + public boolean isFiltering() { + return filtering; + } + + @Override + public void setFiltering(boolean filtering) { + this.filtering = filtering; + if (filtering) + used = filtered; + else + used = original; + notifyListeners(new DatasetChangeEvent(this, this)); + } + + + public void setFilterFraction(double filterFraction) { + this.filterFraction = filterFraction; + } + + public double getFilterFraction() { + return filterFraction; + } + + public void updateFiltered() { + filtered.clear(); + Double total = 0.0; + Double other = 0.0; + for (Object key : original.getKeys()) { + total += original.getValue((Comparable) key).doubleValue(); + } + total *= filterFraction; + for (Object key : original.getKeys()) { + Number value = original.getValue((Comparable) key).doubleValue(); + + if (value.doubleValue() > total) { + filtered.setValue((Comparable) key,value); + } else { + other += value.doubleValue(); + } + } + if (other > 0.0) { + filtered.setValue(this.other, other); + } + + + } + + @Override + public List getKeys() { + return used.getKeys(); + } + + @Override + public int getItemCount() { + return used.getItemCount(); + } + + @Override + public Comparable getKey(int index) { + return used.getKey(index); + } + + @Override + public int getIndex(Comparable key) { + return used.getIndex(key); + } + + @Override + public Number getValue(Comparable key) { + return used.getValue(key); + } + + @Override + public Number getValue(int index) { + return used.getValue(index); + } + +} diff --git a/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/PiePlot.java b/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/PiePlot.java index 925816a8..2c070500 100644 --- a/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/PiePlot.java +++ b/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/PiePlot.java @@ -79,6 +79,11 @@ public class PiePlot extends AbstractPlot { protected void getOtherProperties(ReadGraph graph, PlotProperties properties) throws DatabaseException { Boolean labelsVisible = graph.getPossibleRelatedValue(resource, JFreeChartResource.getInstance(graph).Plot_visibleLabels, Bindings.BOOLEAN); properties.otherProperties.put("labelsVisible", labelsVisible); + + Boolean useFilter = graph.getPossibleRelatedValue(resource, JFreeChartResource.getInstance(graph).Filter_used, Bindings.BOOLEAN); + Double filterFraction = graph.getPossibleRelatedValue(resource, JFreeChartResource.getInstance(graph).Filter_fraction, Bindings.DOUBLE); + properties.otherProperties.put("useFilter", useFilter); + properties.otherProperties.put("filterFraction", filterFraction); } @Override @@ -103,6 +108,19 @@ public class PiePlot extends AbstractPlot { pieDataset = (org.jfree.data.general.PieDataset)dataset; piePlot.setDataset(pieDataset); + if (pieDataset instanceof FilteredDataset) { + FilteredDataset f = (FilteredDataset)pieDataset; + Boolean useFilter = (Boolean)properties.otherProperties.get("useFilter"); + Double filterFraction = (Double)properties.otherProperties.get("filterFraction"); + if (useFilter != null && filterFraction != null) { + f.setFiltering(useFilter); + f.setFilterFraction(filterFraction*0.01); + f.updateFiltered(); + } else { + f.setFiltering(false); + } + } + Boolean labelsVisible = (Boolean)properties.otherProperties.get("labelsVisible"); if(Boolean.FALSE.equals(labelsVisible)) piePlot.setLabelGenerator(null); diff --git a/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/DoublePropertyFactory2.java b/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/DoublePropertyFactory2.java new file mode 100644 index 00000000..3bd42500 --- /dev/null +++ b/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/DoublePropertyFactory2.java @@ -0,0 +1,119 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.jfreechart.chart.properties; + +import org.simantics.browsing.ui.swt.widgets.impl.ReadFactoryImpl; +import org.simantics.databoard.Bindings; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.common.request.ObjectsWithType; +import org.simantics.db.exception.DatabaseException; +import org.simantics.layer0.Layer0; +import org.simantics.utils.datastructures.Quad; + +/** + * PropertyFactory for finding a double property. Supports also finding the + * property from a first occurrence of resource ConsistsOf type HasProperty + * + * @author Teemu Lempinen + * @author Marko Luukkainen + * + */ +public class DoublePropertyFactory2 extends ReadFactoryImpl { + + final private String propertyURI; + final private String typeURI; + final private Double defaultValue; + + /** + * PropertyFactory for finding a boolean property with propertyURI + * + * @param propertyURI URI for the boolean property + */ + public DoublePropertyFactory2(String propertyURI) { + this(null, propertyURI); + } + + + /** + * PropertyFactory for finding a boolean property with propertyURI. + * + * Finds the property for first ObjectWithType(resource, L0.ConsistsOf, type) + * + * Supports inverting the result (e.g. if required information is IsHidden, but database contains IsVisible) + * + * @param typeURI URI for a resource (resource ConsistsOf type) (null allowed) + * @param propertyURI URI for the boolean property + * @param inverse Invert the result? + */ + public DoublePropertyFactory2(String typeURI, String propertyURI) { + this(typeURI, propertyURI, 0.0); + } + + /** + * PropertyFactory for finding a boolean property with propertyURI. + * + * Finds the property for first ObjectWithType(resource, L0.ConsistsOf, type) + * + * Supports inverting the result (e.g. if required information is IsHidden, but database contains IsVisible) + * + * @param typeURI URI for a resource (resource ConsistsOf type) (null allowed -> not used) + * @param propertyURI URI for the boolean property + * @param inverse Invert the result? + * @param defaultValue default value + */ + public DoublePropertyFactory2(String typeURI, String propertyURI, double defaultValue) { + this.propertyURI = propertyURI; + this.typeURI = typeURI; + this.defaultValue = defaultValue; + } + + @Override + public Object getIdentity(Object inputContents) { + return new Quad((Resource) inputContents, propertyURI, getClass(), defaultValue); + } + + @Override + public String perform(ReadGraph graph, Resource r) throws DatabaseException { + if(typeURI == null) { + // if no typeUri, use the default resource r + return getValue(graph, r); + } else { + // typeURI was defined, find the property for the first occurence of ConsistsOf type + Resource type = graph.getResource(typeURI); + for(Resource o : graph.syncRequest(new ObjectsWithType(r, Layer0.getInstance(graph).ConsistsOf, type))) { + // Returns the value for the first occurrence + return getValue(graph, o); + } + } + // if nothing was found with typeURI + return ""; + } + + /** + * Return the value for a Boolean literal possibly inverted (or default if resource != Boolean literal) + * + * @param graph ReadGraph + * @param resource Literal Boolean resource + * @return value of the parameter (or default or inverted) + * @throws DatabaseException + */ + private String getValue(ReadGraph graph, Resource resource) throws DatabaseException { + Double value = graph.getPossibleRelatedValue(resource, graph.getResource(propertyURI), Bindings.DOUBLE); + if(value != null) { + return value.toString(); + } else if (defaultValue != null){ + return defaultValue.toString(); + } + return ""; + } +} \ No newline at end of file diff --git a/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/DoublePropertyModifier2.java b/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/DoublePropertyModifier2.java new file mode 100644 index 00000000..a7dfe81b --- /dev/null +++ b/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/DoublePropertyModifier2.java @@ -0,0 +1,49 @@ +package org.simantics.jfreechart.chart.properties; + +import org.simantics.browsing.ui.swt.widgets.impl.TextModifyListenerImpl; +import org.simantics.databoard.Bindings; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.request.ObjectsWithType; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.management.ISessionContext; +import org.simantics.layer0.Layer0; + +public class DoublePropertyModifier2 extends TextModifyListenerImpl { + + final private String typeUri; + final private String propertyURI; + + public DoublePropertyModifier2(ISessionContext context, String propertyURI) { + this.propertyURI = propertyURI; + this.typeUri = null; + } + + public DoublePropertyModifier2(ISessionContext context, String typeURI, String propertyURI) { + this.propertyURI = propertyURI; + this.typeUri = typeURI; + } + + @Override + public void applyText(WriteGraph graph, Resource input, String text) throws DatabaseException { + if (typeUri == null) + applyValue(graph, input, text); + else { + Resource type = graph.getResource(typeUri); + for(Resource object : graph.syncRequest(new ObjectsWithType(input, Layer0.getInstance(graph).ConsistsOf, type))) { + applyValue(graph, object,text); + } + } + + } + + private void applyValue(WriteGraph graph, Resource input, String text) throws DatabaseException { + if (text == null || text.trim().isEmpty()) { + if (graph.hasStatement(input, graph.getResource(propertyURI))) + graph.denyValue(input, graph.getResource(propertyURI)); + } else { + graph.claimLiteral(input, graph.getResource(propertyURI), Double.parseDouble(text), Bindings.DOUBLE); + } + } + +} diff --git a/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/bar/BarGeneralPropertiesTab.java b/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/bar/BarGeneralPropertiesTab.java index f66cc7e1..8221f819 100644 --- a/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/bar/BarGeneralPropertiesTab.java +++ b/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/bar/BarGeneralPropertiesTab.java @@ -40,6 +40,8 @@ import org.simantics.db.exception.DatabaseException; import org.simantics.db.management.ISessionContext; import org.simantics.jfreechart.chart.properties.BooleanPropertyFactory; import org.simantics.jfreechart.chart.properties.BooleanSelectionListener; +import org.simantics.jfreechart.chart.properties.DoublePropertyFactory2; +import org.simantics.jfreechart.chart.properties.DoublePropertyModifier2; import org.simantics.jfreechart.chart.properties.DoubleValidator; import org.simantics.jfreechart.chart.properties.JFreeChartPropertyColorProvider; import org.simantics.jfreechart.chart.properties.LabelPropertyTabContributor; @@ -77,7 +79,7 @@ public class BarGeneralPropertiesTab extends LabelPropertyTabContributor { sc.setExpandVertical(true); composite = new Composite(sc, SWT.NONE); - GridLayoutFactory.fillDefaults().numColumns(3).margins(3, 3).applyTo(composite); + GridLayoutFactory.fillDefaults().numColumns(4).margins(3, 3).applyTo(composite); // General properties Group general = new Group(composite, SWT.NONE); @@ -203,6 +205,26 @@ public class BarGeneralPropertiesTab extends LabelPropertyTabContributor { sc.setContent(composite); Point size = composite.computeSize(SWT.DEFAULT, SWT.DEFAULT); sc.setMinSize(size); + + Group filteringGroup = new Group(composite, SWT.NONE); + GridDataFactory.fillDefaults().applyTo(filteringGroup); + GridLayoutFactory.fillDefaults().margins(3, 3).numColumns(2).applyTo(filteringGroup); + hideGroup.setText("Filter"); + label = new Label(filteringGroup, SWT.NONE); + GridDataFactory.fillDefaults().grab(false, true).align(SWT.END, SWT.CENTER).applyTo(label); + label.setText("Use:"); + Button useFilter = new Button(filteringGroup, support, SWT.CHECK); + useFilter.setSelectionFactory(new BooleanPropertyFactory(JFreeChartResource.URIs.Plot, JFreeChartResource.URIs.Filter_used, false)); + useFilter.addSelectionListener(new BooleanSelectionListener(context, JFreeChartResource.URIs.Plot, JFreeChartResource.URIs.Filter_used)); + label = new Label(filteringGroup, SWT.NONE); + GridDataFactory.fillDefaults().grab(false, true).align(SWT.END, SWT.CENTER).applyTo(label); + label.setText("Fraction:"); + TrackedText fraction = new TrackedText(filteringGroup, support, SWT.BORDER); + GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER).grab(true, false).applyTo(fraction.getWidget()); + fraction.setTextFactory(new DoublePropertyFactory2(JFreeChartResource.URIs.Plot,JFreeChartResource.URIs.Filter_fraction)); + fraction.addModifyListener(new DoublePropertyModifier2(context, JFreeChartResource.URIs.Plot, JFreeChartResource.URIs.Filter_fraction)); + fraction.setInputValidator(new DoubleValidator(true)); + fraction.setColorProvider(new JFreeChartPropertyColorProvider(fraction.getResourceManager())); } /** diff --git a/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/pie/PieGeneralPropertiesTab.java b/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/pie/PieGeneralPropertiesTab.java index cb721a58..9f72dc2b 100644 --- a/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/pie/PieGeneralPropertiesTab.java +++ b/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/pie/PieGeneralPropertiesTab.java @@ -29,6 +29,8 @@ import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport; import org.simantics.db.management.ISessionContext; import org.simantics.jfreechart.chart.properties.BooleanPropertyFactory; import org.simantics.jfreechart.chart.properties.BooleanSelectionListener; +import org.simantics.jfreechart.chart.properties.DoublePropertyFactory2; +import org.simantics.jfreechart.chart.properties.DoublePropertyModifier2; import org.simantics.jfreechart.chart.properties.DoubleValidator; import org.simantics.jfreechart.chart.properties.JFreeChartPropertyColorProvider; import org.simantics.jfreechart.chart.properties.LabelPropertyTabContributor; @@ -61,7 +63,7 @@ public class PieGeneralPropertiesTab extends LabelPropertyTabContributor { sc.setExpandVertical(true); composite = new Composite(sc, SWT.NONE); - GridLayoutFactory.fillDefaults().numColumns(2).margins(3, 3).applyTo(composite); + GridLayoutFactory.fillDefaults().numColumns(3).margins(3, 3).applyTo(composite); // General properties Group general = new Group(composite, SWT.NONE); @@ -151,6 +153,28 @@ public class PieGeneralPropertiesTab extends LabelPropertyTabContributor { hlabels.setSelectionFactory(new BooleanPropertyFactory(JFreeChartResource.URIs.Plot, JFreeChartResource.URIs.Plot_visibleLabels, true)); hlabels.addSelectionListener(new BooleanSelectionListener(context, JFreeChartResource.URIs.Plot, JFreeChartResource.URIs.Plot_visibleLabels)); + + Group filteringGroup = new Group(composite, SWT.NONE); + GridDataFactory.fillDefaults().applyTo(filteringGroup); + GridLayoutFactory.fillDefaults().margins(3, 3).numColumns(2).applyTo(filteringGroup); + hideGroup.setText("Filter"); + label = new Label(filteringGroup, SWT.NONE); + GridDataFactory.fillDefaults().grab(false, true).align(SWT.END, SWT.CENTER).applyTo(label); + label.setText("Use:"); + Button useFilter = new Button(filteringGroup, support, SWT.CHECK); + useFilter.setSelectionFactory(new BooleanPropertyFactory(JFreeChartResource.URIs.Plot, JFreeChartResource.URIs.Filter_used, false)); + useFilter.addSelectionListener(new BooleanSelectionListener(context, JFreeChartResource.URIs.Plot, JFreeChartResource.URIs.Filter_used)); + label = new Label(filteringGroup, SWT.NONE); + GridDataFactory.fillDefaults().grab(false, true).align(SWT.END, SWT.CENTER).applyTo(label); + label.setText("Fraction:"); + TrackedText fraction = new TrackedText(filteringGroup, support, SWT.BORDER); + GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER).grab(true, false).applyTo(fraction.getWidget()); + fraction.setTextFactory(new DoublePropertyFactory2(JFreeChartResource.URIs.Plot,JFreeChartResource.URIs.Filter_fraction)); + fraction.addModifyListener(new DoublePropertyModifier2(context, JFreeChartResource.URIs.Plot, JFreeChartResource.URIs.Filter_fraction)); + fraction.setInputValidator(new DoubleValidator(true)); + fraction.setColorProvider(new JFreeChartPropertyColorProvider(fraction.getResourceManager())); + + sc.setContent(composite); Point size = composite.computeSize(SWT.DEFAULT, SWT.DEFAULT); sc.setMinSize(size);