From ffce9d86cded5e9f7fa66c145a12408c5b839f4d Mon Sep 17 00:00:00 2001 From: luukkainen Date: Tue, 2 Jul 2013 13:50:48 +0000 Subject: [PATCH] refs #4373 git-svn-id: https://www.simantics.org/svn/simantics/sysdyn/trunk@27673 ac1ea38d-2e2b-0410-8846-a27921b304fc --- org.simantics.jfreechart.ontology/graph.tg | Bin 12519 -> 12857 bytes .../graph/JFreeChart.pgraph | 10 +- .../simantics/sysdyn/JFreeChartResource.java | 15 ++ .../jfreechart/chart/CategoryPlot.java | 22 +++ .../jfreechart/chart/FilteredDataset.java | 26 +++ .../chart/FilteringCategoryDataset.java | 178 ++++++++++++++++++ .../jfreechart/chart/FilteringPieDataset.java | 117 ++++++++++++ .../simantics/jfreechart/chart/PiePlot.java | 18 ++ .../properties/DoublePropertyFactory2.java | 119 ++++++++++++ .../properties/DoublePropertyModifier2.java | 49 +++++ .../bar/BarGeneralPropertiesTab.java | 24 ++- .../pie/PieGeneralPropertiesTab.java | 26 ++- 12 files changed, 601 insertions(+), 3 deletions(-) create mode 100644 org.simantics.jfreechart/src/org/simantics/jfreechart/chart/FilteredDataset.java create mode 100644 org.simantics.jfreechart/src/org/simantics/jfreechart/chart/FilteringCategoryDataset.java create mode 100644 org.simantics.jfreechart/src/org/simantics/jfreechart/chart/FilteringPieDataset.java create mode 100644 org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/DoublePropertyFactory2.java create mode 100644 org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/DoublePropertyModifier2.java diff --git a/org.simantics.jfreechart.ontology/graph.tg b/org.simantics.jfreechart.ontology/graph.tg index 3abaa9be847550808ab81c7e8e16fbfe528e4f5a..5a57c746c0774f4bfe84830680f528209574867a 100644 GIT binary patch literal 12857 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 literal 12519 zcmai)2YVFP6^1Elt1iH_BsRu&Fpd$$cEH_2q6h>CNmSR-?noL~?TDFO72GifgL}aR zx48G-JMO*rj`Iuh50dkpxd$E2LlU0nNcTPEyLImD+A8jjyuO|hBSwrQ8&QfM?q6|L zmx)(s2{)W<=uM+=jV z>%*vJT7<#`WvQVYI$f@PDd^Gs{5ckl=zM_^O&Qtbs zrmFTr=YDfLlihXA@fzRTm>p`vy!}i^NEItMR6*T~EID_xv%HZ`Kk3HY(b4QHZ3#Lf zFTw&G9(qWPrXM4#mn@8Yzp;l7 z37xlDRQ1|*4UzA)`MHcAac>jZU(_%dV5{?>iIx399MEZN@jCr1IX;6ouX>I- zt;VIHwk616c|JuTR+$lJ*1F7&AiZ&!7i~mWpCA&c)J>dPr&76pc^#&>M5ui^+3mhF2g}9EmizdIDRtp_{j#xn@Uk(SB4HHz$wv7G79YLNS z$}@n=%KE~XZ&`vNPAJ9EiG4g0o8cHLkLfA(X}S0@`2xPps=Es~sk+ze>j?Qtb^G!) z{1>Rib2*W&`F$JtB|PVUFh#> zrn)A-KS=r*p5Q346M_r}`@bg9gloH@MQ z4SbahFZVHs&n!*cIF-l3aZGJ8=_a~$lMp#CW~uVlz#l$n7qTz4cHOY+bas`xM~mwA zz;U`7Q#of$7C?L~n{w?J%k;R@{@$L{}m zuIf0&ohyBOmLiZUrk5n2zn6eZ)r5LEUP>#|nhkNN2H8=*ywKa}NA5|eV&8#hZFl8h z!VxVtiSjaby2EH_c*h1fkXnsTM{cm4?5b`I zd-p4%JoHs!0Re05YGV{ZTUKo_} zD%`77-WtxU=;Q=>I9`Kujmm1*S@K}K0%yC*O2d&VavQb*l&%QrzRb~8oxEe;hjW9f z=}xlTbQeVdCi@PY-72exv#R(W;B%YYzwg4`qw<0zPZkfS8xP=na0eVEgEEex{siJ4sA!oO7|Udf3SbVsY>b1ged=7;%w z*h>Ywm@D}x41fH*1>Rk$G!9OV){^K3PAqN`ZmgJ3w3>yJ}nM zBT~LS?a?O$IbLUTB>8YG*;)3LtX=0ebY&tK7drEJYO$~{!?jXPv!8P+<$-X^b`5*W zT8Ce+bJ;VV9`EESIhC7a)4LX2|A$foOz~Gdqtdt_&jw*oD9cF2f8Az zVyQ9hd3s&=nf-TlBggiwfm^*T?5&WK(zd#pw7-FKi(0=NXBDUMWrso^0COtdh|i28 ztLZaiA)PNoUe=nLt z>*$FJ?O{ZBjf;)vSWUVR(@mn^(SPQ^q$I$@ZSu`$ziFH@_Q1<qV*IKuVA3Aa;#C@K`2suvWgp4)NDe`okx!`~SG z+VEF~zcl=X;m-|!X82RXpBVnw@JEI}H2i_#_YJ>i_+7*A7=GLETZZ2>yvOhxhF>@Q zn&DRszhd}h!!H?rp19)Q^pAeuPX>O-@npvjIzHL)1N8e>vQx;OBa`}Rj;Fi)6CEF^ z^qw{OV97s$+F+gk4Dp?={&;GG?@)T++Z|7EaT(8T#7~n6V}4*gKd{X2SQnT19Y_2W znbc!`U>WZm$9lX^ntZV2ja z`^cnzn&av2JdAUEq&hG6ntZV2*HIg+^Y1bFV96g#ZLs8Hymynye%3nH`-!;hr{v4{ zv7dLT`fA5gk9@?X9_Jmb>u(`$A^U|4aqx07-1lda-ApF=mr#2b*-d1BkRb+MLiQ6G zYQc-iej~fl@oxIPmkjY6$RvIZwXZjPo#AT@qeklSaqeox=TZAA!&e%__?ymif0jmi1ZTSk`Z?W0^1NcaVwR5014S;#v_+7}tV(C`JsqW?9u!Fv8+-5*%SH__!w|ENEoO!U5Tto0DrdSI;w7CqGC zOv`+5-p?fy{VyGBeZ;jsSoEO<7JbxjCKJ6c9BVzqwH{dXu>auQWP8a_k2RP305Q$z zTQlaW8EXsH^975(#D%3^SoDQAQ|+MA!+s4I?l)W@mi73Y+F-pNV7(q-S&y|YU;0OV zo=o&UbFB3c*Lq;l!}AXoJ=Di!qW7s|t%tbQ18Y67=%GF$6TMFyYdyrZ9$4#vMGy6x z$VBgB$660@tq0b6V9`T;ADQTV zbFB3c*Lq;B2Npfl_mGJmz6*i19$4#vMX$}}iyrE`$wcoR$660@tp^r8%oi+rsP7^Z zy|*1}J;b#hSoE-eV9`Upuj06Gz@q<_W37j{)FYlz`ENSb<3U{4gJnGE4=j49#~E5e z_7fRmn$fpr%tbTSN;CFGGxl0D&JuVr*>7acj%7R&7nXWq(HEBfg=M_Lm`^8}^tX)K zp5b#0pKbUo!)Fl7dg8o*Wxda&_UUA@pL-nZ{XtyvSGc&=LtMtchuZ7OMDGp9S`Trp z2NpftZ{Xczd&yA0j!g7kcdYdg*Lq;l!+gP_hx#>SqW79(t%tbQ1B)KU2NpfluObt@ zR~>6T#I+t+^e{fK=%K!yO!QuHto0DrdSKDR^9vR|)UPBHy_X$pJ;b#hSoCmTfkhAX zIFs`HVed8LY=Pzc;&}l}J>pBrWIQi9*5g53j|VK{ffiWwP``*w>Mx=8sfwpLmhY=a zIhOCM6Npby`Pko+70;mdNs5nlEd3+*L=``X+9xO;L+#@g*HC+&;!4M&hrZ^L-Ri!t zKjT>9=nHXS^rabnfsb(YSPRY18h*~PtRKdM{D)or^VI%3nZ&W4V7;DTy`IOZe5~iO zim{%@D8_n%Wj@HAqvBZ4*^05AvlL@JXDY_{!J-H4dNNthCmc&0eIYK4zBHpRu&gKM zs`*L7PdS$L!g!D`>-jXb|3)TptS4BnCs@{VBDMcYrt`r%A1wJ3sC~G~$NC>;c&cLT z$DxXmKgIANijjY?V(cGS)(_g6Q9GGT#y`oi+#fl^TMTbCyv^`-!#fP`bgb_qj7P>R zabc+!7JXs#k3G@z0qgl_4qd*)@!4I+HyMr$$AoWjfT4n wDfw{LI1P2lzr(EKP}|EC>p0Fj7V$Wy(I3^TKe3O8;>=L4e)!Lg<^R0@2SXb3egFUf 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); -- 2.47.1