From 504d253c86fcba1f87b348df4857bc10aacbc4ef Mon Sep 17 00:00:00 2001 From: Mathieu Bastian Date: Thu, 17 Feb 2022 19:58:08 +0100 Subject: [PATCH] Fixes and dynamically update partitions via separate localScale parameter --- .../appearance/AppearanceControllerImpl.java | 11 ++- .../gephi/appearance/AppearanceModelImpl.java | 41 +++++++--- .../AppearanceModelPersistenceProvider.java | 35 +++++---- .../appearance/AttributePartitionImpl.java | 2 +- .../gephi/appearance/DegreeRankingImpl.java | 32 ++++---- .../appearance/EdgeTypePartitionImpl.java | 25 ++++-- .../org/gephi/appearance/FunctionImpl.java | 41 +++++++--- .../gephi/appearance/InDegreeRankingImpl.java | 33 +------- .../appearance/OutDegreeRankingImpl.java | 33 +------- .../gephi/appearance/TimesetRankingImpl.java | 54 +++++++++++++ .../appearance/api/AppearanceController.java | 12 ++- .../gephi/appearance/api/AppearanceModel.java | 14 +++- .../AppearanceControllerTest.java | 4 +- .../AppearanceModelTest.java | 21 +++++ .../AttributePartitionTest.java | 12 +++ .../AttributeRankingTest.java | 27 +++++++ .../DegreeRankingTest.java | 19 +++-- .../EdgeTypePartitionTest.java | 78 +++++++++++++++++++ .../ui/appearance/plugin/Bundle.properties | 6 -- .../appearance/AppearanceTopComponent.java | 44 ++++++++--- .../desktop/appearance/AppearanceUIModel.java | 8 +- .../appearance/FunctionObserverExecutor.java | 2 +- .../desktop/appearance/Bundle.properties | 13 +--- .../java/org/gephi/graph/GraphGenerator.java | 28 ++++++- 24 files changed, 428 insertions(+), 167 deletions(-) create mode 100644 modules/AppearanceAPI/src/main/java/org/gephi/appearance/TimesetRankingImpl.java create mode 100644 modules/AppearanceAPI/src/test/java/org.gephi.appearance/EdgeTypePartitionTest.java diff --git a/modules/AppearanceAPI/src/main/java/org/gephi/appearance/AppearanceControllerImpl.java b/modules/AppearanceAPI/src/main/java/org/gephi/appearance/AppearanceControllerImpl.java index 186912253..158b93a50 100644 --- a/modules/AppearanceAPI/src/main/java/org/gephi/appearance/AppearanceControllerImpl.java +++ b/modules/AppearanceAPI/src/main/java/org/gephi/appearance/AppearanceControllerImpl.java @@ -157,9 +157,16 @@ public class AppearanceControllerImpl implements AppearanceController { } @Override - public void setUseLocalScale(boolean useLocalScale) { + public void setUseRankingLocalScale(boolean useLocalScale) { if (model != null) { - model.setLocalScale(useLocalScale); + model.setRankingLocalScale(useLocalScale); + } + } + + @Override + public void setUsePartitionLocalScale(boolean useLocalScale) { + if (model != null) { + model.setPartitionLocalScale(useLocalScale); } } } diff --git a/modules/AppearanceAPI/src/main/java/org/gephi/appearance/AppearanceModelImpl.java b/modules/AppearanceAPI/src/main/java/org/gephi/appearance/AppearanceModelImpl.java index c6c0ce44c..e2e8cea55 100644 --- a/modules/AppearanceAPI/src/main/java/org/gephi/appearance/AppearanceModelImpl.java +++ b/modules/AppearanceAPI/src/main/java/org/gephi/appearance/AppearanceModelImpl.java @@ -94,7 +94,8 @@ public class AppearanceModelImpl implements AppearanceModel { private final List nodeStaticFunctions; private final List edgeStaticFunctions; // LocalScale (if true, uses visible graph) - private boolean localScale = false; + private boolean rankingLocalScale = false; + private boolean partitionLocalScale = false; public AppearanceModelImpl(Workspace workspace) { this.workspace = workspace; @@ -103,11 +104,12 @@ public class AppearanceModelImpl implements AppearanceModel { this.nodeTransformers = initNodeTransformers(); this.edgeTransformers = initEdgeTransformers(); - degreeRanking = new DegreeRankingImpl(); - inDegreeRanking = new InDegreeRankingImpl(); - outDegreeRanking = new OutDegreeRankingImpl(); + degreeRanking = new DegreeRankingImpl(graphModel.defaultColumns().degree()); + inDegreeRanking = new InDegreeRankingImpl(graphModel.defaultColumns().inDegree()); + outDegreeRanking = new OutDegreeRankingImpl(graphModel.defaultColumns().outDegree()); edgeWeightRanking = new EdgeWeightRankingImpl(); - edgeTypePartition = new EdgeTypePartitionImpl(graphModel.getConfiguration().getEdgeLabelType()); + edgeTypePartition = new EdgeTypePartitionImpl(graphModel.defaultColumns().edgeType(), + graphModel.getConfiguration().getEdgeLabelType()); nodeAttributeRankings = new WeakHashMap<>(); edgeAttributeRankings = new WeakHashMap<>(); nodeAttributePartitions = new WeakHashMap<>(); @@ -123,8 +125,16 @@ public class AppearanceModelImpl implements AppearanceModel { initAttributeRankingsAndPartitions(); } - protected Graph getGraph() { - if (localScale) { + protected Graph getRankingGraph() { + if (rankingLocalScale) { + return graphModel.getGraphVisible(); + } else { + return graphModel.getGraph(); + } + } + + protected Graph getPartitionGraph() { + if (partitionLocalScale) { return graphModel.getGraphVisible(); } else { return graphModel.getGraph(); @@ -223,12 +233,21 @@ public class AppearanceModelImpl implements AppearanceModel { } @Override - public boolean isLocalScale() { - return localScale; + public boolean isRankingLocalScale() { + return rankingLocalScale; + } + + public void setRankingLocalScale(boolean localScale) { + this.rankingLocalScale = localScale; + } + + @Override + public boolean isPartitionLocalScale() { + return partitionLocalScale; } - public void setLocalScale(boolean localScale) { - this.localScale = localScale; + public void setPartitionLocalScale(boolean localScale) { + this.partitionLocalScale = localScale; } private List getNodeRankingFunctions() { diff --git a/modules/AppearanceAPI/src/main/java/org/gephi/appearance/AppearanceModelPersistenceProvider.java b/modules/AppearanceAPI/src/main/java/org/gephi/appearance/AppearanceModelPersistenceProvider.java index 09f6b1949..321735027 100644 --- a/modules/AppearanceAPI/src/main/java/org/gephi/appearance/AppearanceModelPersistenceProvider.java +++ b/modules/AppearanceAPI/src/main/java/org/gephi/appearance/AppearanceModelPersistenceProvider.java @@ -53,7 +53,8 @@ public class AppearanceModelPersistenceProvider implements WorkspaceXMLPersisten protected void writeXML(XMLStreamWriter writer, AppearanceModelImpl model) throws XMLStreamException { writer.writeStartElement("localscale"); - writer.writeAttribute("value", String.valueOf(model.isLocalScale())); + writer.writeAttribute("ranking", String.valueOf(model.isRankingLocalScale())); + writer.writeAttribute("partition", String.valueOf(model.isPartitionLocalScale())); writer.writeEndElement(); //Rankings @@ -72,8 +73,10 @@ public class AppearanceModelPersistenceProvider implements WorkspaceXMLPersisten if (eventType.equals(XMLEvent.START_ELEMENT)) { String name = reader.getLocalName(); if ("localscale".equalsIgnoreCase(name)) { - String val = reader.getAttributeValue(null, "value"); - model.setLocalScale(Boolean.parseBoolean(val)); + String partition = reader.getAttributeValue(null, "partition"); + String ranking = reader.getAttributeValue(null, "ranking"); + model.setPartitionLocalScale(Boolean.parseBoolean(partition)); + model.setRankingLocalScale(Boolean.parseBoolean(ranking)); } else if ("rankings".equalsIgnoreCase(name)) { String elementClass = reader.getAttributeValue(null, "for"); readRankings(reader, @@ -170,19 +173,23 @@ public class AppearanceModelPersistenceProvider implements WorkspaceXMLPersisten } } - protected void readInterpolator(XMLStreamReader reader, RankingImpl ranking) throws XMLStreamException { + protected void readInterpolator(XMLStreamReader reader, RankingImpl ranking) { String type = reader.getAttributeValue(null, "type"); Interpolator interpolator = null; - if (type.equals("log2")) { - interpolator = Interpolator.LOG2; - } else if (type.equals("linear")) { - interpolator = Interpolator.LINEAR; - } else if (type.equals("bezier")) { - float x1 = Float.parseFloat(reader.getAttributeValue(null, "x1")); - float y1 = Float.parseFloat(reader.getAttributeValue(null, "y1")); - float x2 = Float.parseFloat(reader.getAttributeValue(null, "x2")); - float y2 = Float.parseFloat(reader.getAttributeValue(null, "y2")); - interpolator = new Interpolator.BezierInterpolator(x1, y1, x2, y2); + switch (type) { + case "log2": + interpolator = Interpolator.LOG2; + break; + case "linear": + interpolator = Interpolator.LINEAR; + break; + case "bezier": + float x1 = Float.parseFloat(reader.getAttributeValue(null, "x1")); + float y1 = Float.parseFloat(reader.getAttributeValue(null, "y1")); + float x2 = Float.parseFloat(reader.getAttributeValue(null, "x2")); + float y2 = Float.parseFloat(reader.getAttributeValue(null, "y2")); + interpolator = new Interpolator.BezierInterpolator(x1, y1, x2, y2); + break; } if (interpolator != null) { ranking.setInterpolator(interpolator); diff --git a/modules/AppearanceAPI/src/main/java/org/gephi/appearance/AttributePartitionImpl.java b/modules/AppearanceAPI/src/main/java/org/gephi/appearance/AttributePartitionImpl.java index c43ecd40d..790e26ca8 100644 --- a/modules/AppearanceAPI/src/main/java/org/gephi/appearance/AttributePartitionImpl.java +++ b/modules/AppearanceAPI/src/main/java/org/gephi/appearance/AttributePartitionImpl.java @@ -119,7 +119,7 @@ public class AttributePartitionImpl extends PartitionImpl { @Override public int getVersion(Graph graph) { if (isValid(graph)) { - return getIndex(graph.getModel().getGraph()).getColumnIndex(column.get()).getVersion(); + return getIndex(graph).getColumnIndex(column.get()).getVersion(); } return 0; } diff --git a/modules/AppearanceAPI/src/main/java/org/gephi/appearance/DegreeRankingImpl.java b/modules/AppearanceAPI/src/main/java/org/gephi/appearance/DegreeRankingImpl.java index 912664efb..df3aa188e 100644 --- a/modules/AppearanceAPI/src/main/java/org/gephi/appearance/DegreeRankingImpl.java +++ b/modules/AppearanceAPI/src/main/java/org/gephi/appearance/DegreeRankingImpl.java @@ -42,9 +42,12 @@ package org.gephi.appearance; +import java.lang.ref.WeakReference; +import org.gephi.graph.api.Column; import org.gephi.graph.api.DirectedGraph; import org.gephi.graph.api.Element; import org.gephi.graph.api.Graph; +import org.gephi.graph.api.Index; import org.gephi.graph.api.Node; /** @@ -52,8 +55,11 @@ import org.gephi.graph.api.Node; */ public class DegreeRankingImpl extends RankingImpl { - public DegreeRankingImpl() { + protected final Column column; + + public DegreeRankingImpl(Column degreeColumn) { super(); + this.column = degreeColumn; } @Override @@ -63,28 +69,16 @@ public class DegreeRankingImpl extends RankingImpl { @Override public Number getMinValue(Graph graph) { - if (graph.getNodeCount() > 0) { - int min = Integer.MAX_VALUE; - DirectedGraph directedGraph = (DirectedGraph) graph; - for (Node node : directedGraph.getNodes()) { - min = Math.min(directedGraph.getDegree(node), min); - } - return min; - } - return 0; + return getIndex(graph).getMinValue(column); } @Override public Number getMaxValue(Graph graph) { - if (graph.getNodeCount() > 0) { - int max = Integer.MIN_VALUE; - DirectedGraph directedGraph = (DirectedGraph) graph; - for (Node node : directedGraph.getNodes()) { - max = Math.max(directedGraph.getDegree(node), max); - } - return max; - } - return 0; + return getIndex(graph).getMaxValue(column); + } + + private Index getIndex(Graph graph) { + return graph.getModel().getNodeIndex(graph.getView()); } @Override diff --git a/modules/AppearanceAPI/src/main/java/org/gephi/appearance/EdgeTypePartitionImpl.java b/modules/AppearanceAPI/src/main/java/org/gephi/appearance/EdgeTypePartitionImpl.java index 6fc8288fa..3ed32a75e 100644 --- a/modules/AppearanceAPI/src/main/java/org/gephi/appearance/EdgeTypePartitionImpl.java +++ b/modules/AppearanceAPI/src/main/java/org/gephi/appearance/EdgeTypePartitionImpl.java @@ -49,6 +49,7 @@ import org.gephi.graph.api.Column; import org.gephi.graph.api.Edge; import org.gephi.graph.api.Element; import org.gephi.graph.api.Graph; +import org.gephi.graph.api.Index; /** * @author mbastian @@ -56,10 +57,12 @@ import org.gephi.graph.api.Graph; public class EdgeTypePartitionImpl extends PartitionImpl { private final Class valueType; + private final Column column; - public EdgeTypePartitionImpl(Class valueType) { + public EdgeTypePartitionImpl(Column column, Class valueType) { super(); this.valueType = valueType; + this.column = column; } @Override @@ -82,24 +85,28 @@ public class EdgeTypePartitionImpl extends PartitionImpl { @Override public int count(Object value, Graph graph) { - return graph.getEdgeCount(graph.getModel().getEdgeType(value)); + return getIndex(graph).count(column, value); } @Override public float percentage(Object value, Graph graph) { - int count = count(value, graph); - return ((float) count) / graph.getEdgeCount(); + Index index = getIndex(graph); + int count = index.count(column, value); + return 100f * ((float) count / index.countElements(column)); } @Override public int size(Graph graph) { - int size = graph.getModel().getEdgeTypeCount(); - return graph.getEdgeCount(0) == 0 ? size - 1 : size; + return getIndex(graph).countValues(column); + } + + private Index getIndex(Graph graph) { + return graph.getModel().getEdgeIndex(graph.getView()); } @Override public Column getColumn() { - return null; + return column; } @Override @@ -114,7 +121,9 @@ public class EdgeTypePartitionImpl extends PartitionImpl { @Override public int getVersion(Graph graph) { - // TODO + if (isValid(graph)) { + return getIndex(graph).getColumnIndex(column).getVersion(); + } return 0; } } diff --git a/modules/AppearanceAPI/src/main/java/org/gephi/appearance/FunctionImpl.java b/modules/AppearanceAPI/src/main/java/org/gephi/appearance/FunctionImpl.java index e2e47584c..87288186a 100644 --- a/modules/AppearanceAPI/src/main/java/org/gephi/appearance/FunctionImpl.java +++ b/modules/AppearanceAPI/src/main/java/org/gephi/appearance/FunctionImpl.java @@ -42,6 +42,7 @@ package org.gephi.appearance; +import java.lang.ref.WeakReference; import java.util.Objects; import java.util.concurrent.atomic.AtomicInteger; import org.gephi.appearance.api.Function; @@ -67,8 +68,9 @@ public abstract class FunctionImpl implements Function { protected final TransformerUI transformerUI; protected final PartitionImpl partition; protected final RankingImpl ranking; - // Version protected final AtomicInteger version; + // Version + protected WeakReference lastGraph; protected FunctionImpl(AppearanceModelImpl model, String name, Class elementClass, Column column, Transformer transformer, TransformerUI transformerUI, PartitionImpl partition, @@ -88,7 +90,8 @@ public abstract class FunctionImpl implements Function { this.transformerUI = transformerUI; this.partition = partition; this.ranking = ranking; - this.version = new AtomicInteger(Integer.MIN_VALUE); + this.version = new AtomicInteger(partition != null ? partition.getVersion(model.getPartitionGraph()) : Integer.MIN_VALUE); + this.lastGraph = partition != null ? new WeakReference<>(model.getPartitionGraph()) : null; } @Override @@ -128,13 +131,28 @@ public abstract class FunctionImpl implements Function { } public boolean hasChanged() { - if(isSimple()) { - return false; - } else { - Graph graph = model.getGraph(); - int newVersion = isPartition() ? partition.getVersion(graph) : 0; - return version.getAndSet(newVersion) != newVersion; + if (isPartition()) { + Graph graph = model.getPartitionGraph(); + + // Check if view has changed + boolean viewChanged = false; + synchronized (this) { + if (lastGraph == null) { + lastGraph = new WeakReference<>(graph); + } else { + Graph lg = lastGraph.get(); + lastGraph = null; + if (lg == null || lg != graph) { + viewChanged = true; + lastGraph = new WeakReference<>(graph); + } + } + } + + int newVersion = partition.getVersion(graph); + return version.getAndSet(newVersion) != newVersion || viewChanged; } + return false; } public boolean isValid() { @@ -148,7 +166,12 @@ public abstract class FunctionImpl implements Function { @Override public Graph getGraph() { - return model.getGraph(); + if (isRanking()) { + return model.getRankingGraph(); + } else if (isPartition()) { + return model.getPartitionGraph(); + } + return model.getGraphModel().getGraph(); } @Override diff --git a/modules/AppearanceAPI/src/main/java/org/gephi/appearance/InDegreeRankingImpl.java b/modules/AppearanceAPI/src/main/java/org/gephi/appearance/InDegreeRankingImpl.java index 522a785fd..ac52210b0 100644 --- a/modules/AppearanceAPI/src/main/java/org/gephi/appearance/InDegreeRankingImpl.java +++ b/modules/AppearanceAPI/src/main/java/org/gephi/appearance/InDegreeRankingImpl.java @@ -42,6 +42,7 @@ package org.gephi.appearance; +import org.gephi.graph.api.Column; import org.gephi.graph.api.DirectedGraph; import org.gephi.graph.api.Element; import org.gephi.graph.api.Graph; @@ -50,10 +51,10 @@ import org.gephi.graph.api.Node; /** * @author mbastian */ -public class InDegreeRankingImpl extends RankingImpl { +public class InDegreeRankingImpl extends DegreeRankingImpl { - public InDegreeRankingImpl() { - super(); + public InDegreeRankingImpl(Column degreeColumn) { + super(degreeColumn); } @Override @@ -61,32 +62,6 @@ public class InDegreeRankingImpl extends RankingImpl { return ((DirectedGraph) gr).getInDegree((Node) element); } - @Override - public Number getMinValue(Graph graph) { - if (graph.getNodeCount() > 0) { - int min = Integer.MAX_VALUE; - DirectedGraph directedGraph = (DirectedGraph) graph; - for (Node node : directedGraph.getNodes()) { - min = Math.min(directedGraph.getInDegree(node), min); - } - return min; - } - return 0; - } - - @Override - public Number getMaxValue(Graph graph) { - if (graph.getNodeCount() > 0) { - int max = Integer.MIN_VALUE; - DirectedGraph directedGraph = (DirectedGraph) graph; - for (Node node : directedGraph.getNodes()) { - max = Math.max(directedGraph.getInDegree(node), max); - } - return max; - } - return 0; - } - @Override public boolean isValid(Graph graph) { return graph.isDirected(); diff --git a/modules/AppearanceAPI/src/main/java/org/gephi/appearance/OutDegreeRankingImpl.java b/modules/AppearanceAPI/src/main/java/org/gephi/appearance/OutDegreeRankingImpl.java index a2b7baeeb..f42391fea 100644 --- a/modules/AppearanceAPI/src/main/java/org/gephi/appearance/OutDegreeRankingImpl.java +++ b/modules/AppearanceAPI/src/main/java/org/gephi/appearance/OutDegreeRankingImpl.java @@ -42,6 +42,7 @@ package org.gephi.appearance; +import org.gephi.graph.api.Column; import org.gephi.graph.api.DirectedGraph; import org.gephi.graph.api.Element; import org.gephi.graph.api.Graph; @@ -50,10 +51,10 @@ import org.gephi.graph.api.Node; /** * @author mbastian */ -public class OutDegreeRankingImpl extends RankingImpl { +public class OutDegreeRankingImpl extends DegreeRankingImpl { - public OutDegreeRankingImpl() { - super(); + public OutDegreeRankingImpl(Column degreeColumn) { + super(degreeColumn); } @Override @@ -61,32 +62,6 @@ public class OutDegreeRankingImpl extends RankingImpl { return ((DirectedGraph) gr).getOutDegree((Node) element); } - @Override - public Number getMinValue(Graph graph) { - if (graph.getNodeCount() > 0) { - int min = Integer.MAX_VALUE; - DirectedGraph directedGraph = (DirectedGraph) graph; - for (Node node : directedGraph.getNodes()) { - min = Math.min(directedGraph.getOutDegree(node), min); - } - return min; - } - return 0; - } - - @Override - public Number getMaxValue(Graph graph) { - if (graph.getNodeCount() > 0) { - int max = Integer.MIN_VALUE; - DirectedGraph directedGraph = (DirectedGraph) graph; - for (Node node : directedGraph.getNodes()) { - max = Math.max(directedGraph.getOutDegree(node), max); - } - return max; - } - return 0; - } - @Override public boolean isValid(Graph graph) { return graph.isDirected(); diff --git a/modules/AppearanceAPI/src/main/java/org/gephi/appearance/TimesetRankingImpl.java b/modules/AppearanceAPI/src/main/java/org/gephi/appearance/TimesetRankingImpl.java new file mode 100644 index 000000000..c782f6746 --- /dev/null +++ b/modules/AppearanceAPI/src/main/java/org/gephi/appearance/TimesetRankingImpl.java @@ -0,0 +1,54 @@ +package org.gephi.appearance; + +import org.gephi.graph.api.Column; +import org.gephi.graph.api.Edge; +import org.gephi.graph.api.Element; +import org.gephi.graph.api.Graph; +import org.gephi.graph.api.Index; +import org.gephi.graph.api.Interval; +import org.gephi.graph.api.Node; +import org.gephi.graph.api.TimeIndex; + +public class TimesetRankingImpl extends RankingImpl { + + protected enum Mode {MIN, MAX}; + + private final Class elementClass; + private final Mode mode; + + public TimesetRankingImpl(Class elementClass, Mode mode) { + super(); + this.elementClass = elementClass; + this.mode = mode; + } + + @Override + public Number getValue(Element element, Graph graph) { + Interval timeBound = element.getTimeBounds(); + if(timeBound != null) { + return mode.equals(Mode.MIN) ? timeBound.getLow() : timeBound.getHigh(); + } + return null; + } + + @Override + public Number getMinValue(Graph graph) { + return getIndex(graph).getMinTimestamp(); + } + + @Override + public Number getMaxValue(Graph graph) { + return getIndex(graph).getMaxTimestamp(); + } + + private TimeIndex getIndex(Graph graph) { + return elementClass.isAssignableFrom(Node.class) ? graph.getModel().getNodeTimeIndex(graph.getView()) : graph.getModel().getEdgeTimeIndex(graph.getView()); + } + + @Override + public boolean isValid(Graph graph) { + return graph.getModel().isDynamic(); + } + + +} \ No newline at end of file diff --git a/modules/AppearanceAPI/src/main/java/org/gephi/appearance/api/AppearanceController.java b/modules/AppearanceAPI/src/main/java/org/gephi/appearance/api/AppearanceController.java index 1f4f5e20d..1702fe992 100644 --- a/modules/AppearanceAPI/src/main/java/org/gephi/appearance/api/AppearanceController.java +++ b/modules/AppearanceAPI/src/main/java/org/gephi/appearance/api/AppearanceController.java @@ -64,7 +64,17 @@ public interface AppearanceController { * @param useLocalScale true for local, false for * global */ - void setUseLocalScale(boolean useLocalScale); + void setUseRankingLocalScale(boolean useLocalScale); + + /** + * Sets whether partitions use a local or a global scale. When calculating the + * partitions it can use the complete graph or only the currently visible graph. When using the visible graph + * it is called the local scale. + * + * @param useLocalScale true for local, false for + * global + */ + void setUsePartitionLocalScale(boolean useLocalScale); /** * Apply the function's transformer. If the function is for nodes all nodes diff --git a/modules/AppearanceAPI/src/main/java/org/gephi/appearance/api/AppearanceModel.java b/modules/AppearanceAPI/src/main/java/org/gephi/appearance/api/AppearanceModel.java index 80f531fef..79433b600 100644 --- a/modules/AppearanceAPI/src/main/java/org/gephi/appearance/api/AppearanceModel.java +++ b/modules/AppearanceAPI/src/main/java/org/gephi/appearance/api/AppearanceModel.java @@ -63,12 +63,22 @@ public interface AppearanceModel { /** * Returns true if rankings are using the currently visible * graph as a scale. If false the complete graph is used to - * determine minimum and maximum values, the ranking scale. + * determine minimum and maximum values. * * @return true if using a local scale, false if * global scale */ - boolean isLocalScale(); + boolean isRankingLocalScale(); + + /** + * Returns true if partitions are using the currently visible + * graph as a source. If false the complete graph is used to + * determine partitions. + * + * @return true if using a local scale, false if + * global scale + */ + boolean isPartitionLocalScale(); /** * Returns the node partition for thid column. diff --git a/modules/AppearanceAPI/src/test/java/org.gephi.appearance/AppearanceControllerTest.java b/modules/AppearanceAPI/src/test/java/org.gephi.appearance/AppearanceControllerTest.java index 02ab1cb62..282d8f737 100644 --- a/modules/AppearanceAPI/src/test/java/org.gephi.appearance/AppearanceControllerTest.java +++ b/modules/AppearanceAPI/src/test/java/org.gephi.appearance/AppearanceControllerTest.java @@ -30,7 +30,7 @@ public class AppearanceControllerTest { AppearanceControllerImpl controller = new AppearanceControllerImpl(); controller.setModel(new AppearanceModelImpl(generator.getWorkspace())); - Assert.assertFalse(controller.getModel().isLocalScale()); + Assert.assertFalse(controller.getModel().isRankingLocalScale()); Node node = generator.getGraph().getNode(GraphGenerator.FIRST_NODE); @@ -105,7 +105,7 @@ public class AppearanceControllerTest { controller.transform(rankingFunction); Assert.assertEquals(0, (int) node1.size()); - controller.setUseLocalScale(true); + controller.setUseRankingLocalScale(true); controller.transform(rankingFunction); Assert.assertEquals(1, (int) node1.size()); } diff --git a/modules/AppearanceAPI/src/test/java/org.gephi.appearance/AppearanceModelTest.java b/modules/AppearanceAPI/src/test/java/org.gephi.appearance/AppearanceModelTest.java index 575943d7f..2e3958869 100644 --- a/modules/AppearanceAPI/src/test/java/org.gephi.appearance/AppearanceModelTest.java +++ b/modules/AppearanceAPI/src/test/java/org.gephi.appearance/AppearanceModelTest.java @@ -1,5 +1,7 @@ package org.gephi.appearance; +import java.util.Arrays; +import org.gephi.appearance.api.Function; import org.gephi.appearance.api.Partition; import org.gephi.appearance.api.Ranking; import org.gephi.appearance.spi.PartitionTransformer; @@ -9,6 +11,7 @@ import org.gephi.appearance.spi.Transformer; import org.gephi.graph.GraphGenerator; import org.gephi.graph.api.Column; import org.gephi.graph.api.Element; +import org.gephi.graph.api.GraphView; import org.junit.Assert; import org.junit.Test; import org.netbeans.junit.MockServices; @@ -58,6 +61,24 @@ public class AppearanceModelTest { Assert.assertEquals(0, model.countNodeAttributeRanking()); } + @Test + public void testHasChanged() { + MockServices.setServices(DummyTransformer.class); + GraphGenerator generator = GraphGenerator.build().withWorkspace().generateTinyGraph().addIntNodeColumn(); + AppearanceModelImpl model = new AppearanceModelImpl(generator.getWorkspace()); + Function function = + Arrays.stream(model.getNodeFunctions()).filter(f -> f.isPartition() && f.isAttribute()).findFirst().get(); + + Assert.assertFalse(function.hasChanged()); + GraphView view = generator.getGraphModel().createView(); + generator.getGraphModel().setVisibleView(view); + Assert.assertFalse(function.hasChanged()); + + model.setPartitionLocalScale(true); + Assert.assertTrue(function.hasChanged()); + Assert.assertFalse(function.hasChanged()); + } + public static class DummyTransformer implements Transformer, RankingTransformer, PartitionTransformer, SimpleTransformer { diff --git a/modules/AppearanceAPI/src/test/java/org.gephi.appearance/AttributePartitionTest.java b/modules/AppearanceAPI/src/test/java/org.gephi.appearance/AttributePartitionTest.java index 142e1f886..d5c231b0e 100644 --- a/modules/AppearanceAPI/src/test/java/org.gephi.appearance/AttributePartitionTest.java +++ b/modules/AppearanceAPI/src/test/java/org.gephi.appearance/AttributePartitionTest.java @@ -119,4 +119,16 @@ public class AttributePartitionTest { graph.removeNode(n1); Assert.assertNotEquals(version, p.getVersion(graph)); } + +// @Test +// public void testVersionDynamic() { +// Graph graph = GraphGenerator.build().generateTinyGraph().addTimestampDoubleColumn().getGraph(); +// Column column = graph.getModel().getNodeTable().getColumn(GraphGenerator.TIMESTAMP_DOUBLE_COLUMN); +// Node n1 = graph.getNode(GraphGenerator.FIRST_NODE); +// +// AttributePartitionImpl p = new AttributePartitionImpl(column); +// int version = p.getVersion(graph); +// n1.setAttribute(column, 99.0, 2000); +// Assert.assertNotEquals(version, p.getVersion(graph)); +// } } diff --git a/modules/AppearanceAPI/src/test/java/org.gephi.appearance/AttributeRankingTest.java b/modules/AppearanceAPI/src/test/java/org.gephi.appearance/AttributeRankingTest.java index 11f09edec..0ca8250ed 100644 --- a/modules/AppearanceAPI/src/test/java/org.gephi.appearance/AttributeRankingTest.java +++ b/modules/AppearanceAPI/src/test/java/org.gephi.appearance/AttributeRankingTest.java @@ -2,6 +2,7 @@ package org.gephi.appearance; import org.gephi.graph.GraphGenerator; import org.gephi.graph.api.Column; +import org.gephi.graph.api.Estimator; import org.gephi.graph.api.Graph; import org.gephi.graph.api.Node; import org.junit.Assert; @@ -53,4 +54,30 @@ public class AttributeRankingTest { AttributeRankingImpl p = new AttributeRankingImpl(column); Assert.assertTrue(p.isValid(graph)); } + + @Test + public void testArrayColumnNotValid() { + Graph graph = GraphGenerator.build().generateTinyGraph().addFloatArrayNodeColumn().getGraph(); + Column column = graph.getModel().getNodeTable().getColumn(GraphGenerator.FLOAT_ARRAY_COLUMN); + + AttributeRankingImpl p = new AttributeRankingImpl(column); + Assert.assertFalse(p.isValid(graph)); + } + + @Test + public void testDynamicTimestampColumn() { + Graph graph = GraphGenerator.build().generateTinyGraph().addTimestampDoubleColumn().getGraph(); + Column column = graph.getModel().getNodeTable().getColumn(GraphGenerator.TIMESTAMP_DOUBLE_COLUMN); + + AttributeRankingImpl p = new AttributeRankingImpl(column); + Assert.assertTrue(p.isValid(graph)); + + + Assert.assertEquals(GraphGenerator.TIMESTAMP_DOUBLE_COLUMN_VALUES[0][0], p.getMinValue(graph)); + Assert.assertEquals(GraphGenerator.TIMESTAMP_DOUBLE_COLUMN_VALUES[1][0], p.getMaxValue(graph)); + + Node n1 = graph.getNode(GraphGenerator.FIRST_NODE); + + Assert.assertEquals(GraphGenerator.TIMESTAMP_DOUBLE_COLUMN_VALUES[0][0], p.getValue(n1, graph)); + } } diff --git a/modules/AppearanceAPI/src/test/java/org.gephi.appearance/DegreeRankingTest.java b/modules/AppearanceAPI/src/test/java/org.gephi.appearance/DegreeRankingTest.java index d7a3c3f45..5176cc8ba 100644 --- a/modules/AppearanceAPI/src/test/java/org.gephi.appearance/DegreeRankingTest.java +++ b/modules/AppearanceAPI/src/test/java/org.gephi.appearance/DegreeRankingTest.java @@ -2,6 +2,7 @@ package org.gephi.appearance; import org.gephi.appearance.api.Interpolator; import org.gephi.graph.GraphGenerator; +import org.gephi.graph.api.Column; import org.gephi.graph.api.Graph; import org.gephi.graph.api.Node; import org.junit.Assert; @@ -12,15 +13,19 @@ public class DegreeRankingTest { @Test public void testEmpty() { Graph graph = GraphGenerator.build().getGraph(); - DegreeRankingImpl degreeRanking = new DegreeRankingImpl(); + Column col = graph.getModel().defaultColumns().degree(); + DegreeRankingImpl degreeRanking = new DegreeRankingImpl(col); - Assert.assertEquals(0, degreeRanking.getMinValue(graph)); - Assert.assertEquals(0, degreeRanking.getMaxValue(graph)); + Assert.assertNull(degreeRanking.getMinValue(graph)); + Assert.assertNull(degreeRanking.getMaxValue(graph)); } @Test public void testInterpolator() { - DegreeRankingImpl degreeRanking = new DegreeRankingImpl(); + Graph graph = GraphGenerator.build().getGraph(); + Column col = graph.getModel().defaultColumns().degree(); + DegreeRankingImpl degreeRanking = new DegreeRankingImpl(col); + Assert.assertSame(Interpolator.LINEAR, degreeRanking.getInterpolator()); degreeRanking.setInterpolator(Interpolator.LOG2); Assert.assertSame(Interpolator.LOG2, degreeRanking.getInterpolator()); @@ -29,7 +34,8 @@ public class DegreeRankingTest { @Test public void testOneEdge() { Graph graph = GraphGenerator.build().generateTinyGraph().getGraph(); - DegreeRankingImpl degreeRanking = new DegreeRankingImpl(); + Column col = graph.getModel().defaultColumns().degree(); + DegreeRankingImpl degreeRanking = new DegreeRankingImpl(col); Assert.assertEquals(1, degreeRanking.getMinValue(graph)); Assert.assertEquals(1, degreeRanking.getMaxValue(graph)); @@ -42,7 +48,8 @@ public class DegreeRankingTest { @Test public void testNormalization() { Graph graph = GraphGenerator.build().generateSmallRandomGraph().getGraph(); - DegreeRankingImpl degreeRanking = new DegreeRankingImpl(); + Column col = graph.getModel().defaultColumns().degree(); + DegreeRankingImpl degreeRanking = new DegreeRankingImpl(col); int minDegree = degreeRanking.getMinValue(graph).intValue(); int maxDegree = degreeRanking.getMaxValue(graph).intValue(); diff --git a/modules/AppearanceAPI/src/test/java/org.gephi.appearance/EdgeTypePartitionTest.java b/modules/AppearanceAPI/src/test/java/org.gephi.appearance/EdgeTypePartitionTest.java new file mode 100644 index 000000000..c5df2b0f4 --- /dev/null +++ b/modules/AppearanceAPI/src/test/java/org.gephi.appearance/EdgeTypePartitionTest.java @@ -0,0 +1,78 @@ +package org.gephi.appearance; + +import org.gephi.graph.GraphGenerator; +import org.gephi.graph.api.Column; +import org.gephi.graph.api.Edge; +import org.gephi.graph.api.Graph; +import org.gephi.graph.api.Node; +import org.gephi.graph.impl.GraphStoreConfiguration; +import org.junit.Assert; +import org.junit.Test; + +public class EdgeTypePartitionTest { + + @Test + public void testEmpty() { + Graph graph = GraphGenerator.build().getGraph(); + Column col = graph.getModel().defaultColumns().edgeType(); + EdgeTypePartitionImpl typePartition = new EdgeTypePartitionImpl(col, GraphStoreConfiguration.DEFAULT_EDGE_LABEL_TYPE); + + Assert.assertEquals(0, typePartition.getElementCount(graph)); + Assert.assertEquals(0, typePartition.getValues(graph).size()); + Assert.assertEquals(0, typePartition.getSortedValues(graph).size()); + Assert.assertEquals(0, typePartition.size(graph)); + } + + @Test + public void testSimpleGraph() { + Graph graph = GraphGenerator.build().generateTinyGraph().getGraph(); + Column col = graph.getModel().defaultColumns().edgeType(); + EdgeTypePartitionImpl typePartition = new EdgeTypePartitionImpl(col, GraphStoreConfiguration.DEFAULT_EDGE_LABEL_TYPE); + + Assert.assertEquals(1, typePartition.getElementCount(graph)); + Assert.assertEquals(1, typePartition.getValues(graph).size()); + Assert.assertEquals(1, typePartition.getSortedValues(graph).size()); + Assert.assertEquals(1, typePartition.size(graph)); + } + + @Test + public void testMultiGraph() { + Graph graph = GraphGenerator.build().generateTinyMultiGraph().getGraph(); + Column col = graph.getModel().defaultColumns().edgeType(); + EdgeTypePartitionImpl typePartition = new EdgeTypePartitionImpl(col, GraphStoreConfiguration.DEFAULT_EDGE_LABEL_TYPE); + + Assert.assertEquals(2, typePartition.getElementCount(graph)); + Assert.assertEquals(2, typePartition.getValues(graph).size()); + Assert.assertEquals(2, typePartition.getSortedValues(graph).size()); + Assert.assertEquals(2, typePartition.size(graph)); + } + + @Test + public void testIsValid() { + Graph graph = GraphGenerator.build().generateTinyMultiGraph().getGraph(); + Column col = graph.getModel().defaultColumns().edgeType(); + EdgeTypePartitionImpl typePartition = new EdgeTypePartitionImpl(col, GraphStoreConfiguration.DEFAULT_EDGE_LABEL_TYPE); + Assert.assertTrue(typePartition.isValid(graph)); + } + + @Test + public void testIsNotValid() { + Graph graph = GraphGenerator.build().generateTinyGraph().getGraph(); + Column col = graph.getModel().defaultColumns().edgeType(); + EdgeTypePartitionImpl typePartition = new EdgeTypePartitionImpl(col, GraphStoreConfiguration.DEFAULT_EDGE_LABEL_TYPE); + Assert.assertFalse(typePartition.isValid(graph)); + } + + @Test + public void testVersion() { + Graph graph = GraphGenerator.build().generateTinyMultiGraph().getGraph(); + Column col = graph.getModel().defaultColumns().edgeType(); + EdgeTypePartitionImpl p = new EdgeTypePartitionImpl(col, GraphStoreConfiguration.DEFAULT_EDGE_LABEL_TYPE); + Edge e2 = graph.getEdge(GraphGenerator.SECOND_EDGE); + + int version = p.getVersion(graph); + graph.removeEdge(e2); + Assert.assertNotEquals(version, version = p.getVersion(graph)); + Assert.assertEquals(version, p.getVersion(graph)); + } +} diff --git a/modules/AppearancePluginUI/src/main/resources/org/gephi/ui/appearance/plugin/Bundle.properties b/modules/AppearancePluginUI/src/main/resources/org/gephi/ui/appearance/plugin/Bundle.properties index da6247590..5a3b096fd 100644 --- a/modules/AppearancePluginUI/src/main/resources/org/gephi/ui/appearance/plugin/Bundle.properties +++ b/modules/AppearancePluginUI/src/main/resources/org/gephi/ui/appearance/plugin/Bundle.properties @@ -3,12 +3,6 @@ Unique.name = Unique Attribute.ranking.name = Ranking Attribute.partition.name = Partition - -ColorTransformerUI.name = Color -SizeTransformerUI.name = Size -LabelColorTransformerUI.name = Label Color -LabelSizeTransformerUI.name = Label Size - RankingColorTransformerPanel.labelColor.text=Color: RankingSizeTransformerPanel.labelMaxSize.text=Max size: RankingSizeTransformerPanel.labelMinSize.text=Min size: diff --git a/modules/DesktopAppearance/src/main/java/org/gephi/desktop/appearance/AppearanceTopComponent.java b/modules/DesktopAppearance/src/main/java/org/gephi/desktop/appearance/AppearanceTopComponent.java index 1a34041e0..aa284c60f 100644 --- a/modules/DesktopAppearance/src/main/java/org/gephi/desktop/appearance/AppearanceTopComponent.java +++ b/modules/DesktopAppearance/src/main/java/org/gephi/desktop/appearance/AppearanceTopComponent.java @@ -106,7 +106,8 @@ public class AppearanceTopComponent extends TopComponent implements Lookup.Provi private javax.swing.JPanel controlPanel; private javax.swing.JToolBar controlToolbar; private javax.swing.JToggleButton enableAutoButton; - private javax.swing.JToggleButton localScaleButton; + private javax.swing.JToggleButton rankingLocalScaleButton; + private javax.swing.JToggleButton partitionLocalScaleButton; private javax.swing.JPanel mainPanel; private org.jdesktop.swingx.JXHyperlink splineButton; private javax.swing.JToggleButton stopAutoApplyButton; @@ -334,7 +335,8 @@ public class AppearanceTopComponent extends TopComponent implements Lookup.Provi applyButton.setVisible(true); applyButton.setEnabled(true); } - localScaleButton.setSelected(model.isLocalScale()); + rankingLocalScaleButton.setSelected(model.isRankingLocalScale()); + partitionLocalScaleButton.setSelected(model.isPartitionLocalScale()); return; } //Disable @@ -349,16 +351,23 @@ public class AppearanceTopComponent extends TopComponent implements Lookup.Provi private void initControls() { //Add ranking controls - toolbar.addRankingControl(localScaleButton); + toolbar.addRankingControl(rankingLocalScaleButton); toolbar.addRankingControl(splineButton); //Add partition controls -// toolbar.addPartitionControl(localScaleButton); + toolbar.addPartitionControl(partitionLocalScaleButton); + //Actions - localScaleButton.addActionListener(new ActionListener() { + rankingLocalScaleButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + controller.getAppearanceController().setUseRankingLocalScale(rankingLocalScaleButton.isSelected()); + } + }); + partitionLocalScaleButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { - controller.getAppearanceController().setUseLocalScale(localScaleButton.isSelected()); + controller.getAppearanceController().setUsePartitionLocalScale(partitionLocalScaleButton.isSelected()); } }); splineButton.addActionListener(new ActionListener() { @@ -496,7 +505,8 @@ public class AppearanceTopComponent extends TopComponent implements Lookup.Provi attibuteBox = new javax.swing.JComboBox(); centerPanel = new javax.swing.JPanel(); controlToolbar = toolbar.getControlToolbar(); - localScaleButton = new javax.swing.JToggleButton(); + rankingLocalScaleButton = new javax.swing.JToggleButton(); + partitionLocalScaleButton = new javax.swing.JToggleButton(); splineButton = new org.jdesktop.swingx.JXHyperlink(); controlPanel = new javax.swing.JPanel(); applyButton = new javax.swing.JButton(); @@ -567,15 +577,25 @@ public class AppearanceTopComponent extends TopComponent implements Lookup.Provi controlToolbar.setMargin(new java.awt.Insets(0, 4, 0, 0)); controlToolbar.setOpaque(true); - localScaleButton.setIcon(new javax.swing.ImageIcon( + rankingLocalScaleButton.setIcon(new javax.swing.ImageIcon( getClass().getResource("/org/gephi/desktop/appearance/resources/funnel.png"))); // NOI18N - localScaleButton.setToolTipText(org.openide.util.NbBundle + rankingLocalScaleButton.setToolTipText(org.openide.util.NbBundle .getMessage(AppearanceTopComponent.class, "AppearanceTopComponent.localScaleButton.toolTipText")); // NOI18N - localScaleButton.setFocusable(false); - localScaleButton + rankingLocalScaleButton.setFocusable(false); + rankingLocalScaleButton + .setSelectedIcon(new javax.swing.ImageIcon(UIUtils.generateSelectedDarkImage((new javax.swing.ImageIcon( + getClass().getResource("/org/gephi/desktop/appearance/resources/funnel.png")).getImage())))); // NOI18N + controlToolbar.add(rankingLocalScaleButton); + + partitionLocalScaleButton.setIcon(new javax.swing.ImageIcon( + getClass().getResource("/org/gephi/desktop/appearance/resources/funnel.png"))); // NOI18N + partitionLocalScaleButton.setToolTipText(org.openide.util.NbBundle + .getMessage(AppearanceTopComponent.class, "AppearanceTopComponent.partitionLocalScaleButton.toolTipText")); // NOI18N + partitionLocalScaleButton.setFocusable(false); + partitionLocalScaleButton .setSelectedIcon(new javax.swing.ImageIcon(UIUtils.generateSelectedDarkImage((new javax.swing.ImageIcon( getClass().getResource("/org/gephi/desktop/appearance/resources/funnel.png")).getImage())))); // NOI18N - controlToolbar.add(localScaleButton); + controlToolbar.add(partitionLocalScaleButton); org.openide.awt.Mnemonics.setLocalizedText(splineButton, org.openide.util.NbBundle .getMessage(AppearanceTopComponent.class, "AppearanceTopComponent.splineButton.text")); // NOI18N diff --git a/modules/DesktopAppearance/src/main/java/org/gephi/desktop/appearance/AppearanceUIModel.java b/modules/DesktopAppearance/src/main/java/org/gephi/desktop/appearance/AppearanceUIModel.java index b73569528..f7a2b2ecd 100644 --- a/modules/DesktopAppearance/src/main/java/org/gephi/desktop/appearance/AppearanceUIModel.java +++ b/modules/DesktopAppearance/src/main/java/org/gephi/desktop/appearance/AppearanceUIModel.java @@ -134,8 +134,12 @@ public class AppearanceUIModel { functionObserverExecutor.stop(); } - public boolean isLocalScale() { - return appearanceModel.isLocalScale(); + public boolean isRankingLocalScale() { + return appearanceModel.isRankingLocalScale(); + } + + public boolean isPartitionLocalScale() { + return appearanceModel.isPartitionLocalScale(); } public void saveTransformerProperties() { diff --git a/modules/DesktopAppearance/src/main/java/org/gephi/desktop/appearance/FunctionObserverExecutor.java b/modules/DesktopAppearance/src/main/java/org/gephi/desktop/appearance/FunctionObserverExecutor.java index 67466f534..5ee29d281 100644 --- a/modules/DesktopAppearance/src/main/java/org/gephi/desktop/appearance/FunctionObserverExecutor.java +++ b/modules/DesktopAppearance/src/main/java/org/gephi/desktop/appearance/FunctionObserverExecutor.java @@ -10,7 +10,7 @@ import org.openide.util.Lookup; public class FunctionObserverExecutor implements Runnable { - private static final long DEFAULT_DELAY = 1000; //ms + private static final long DEFAULT_DELAY = 1500; //ms private final AppearanceUIModel model; private final AppearanceUIController controller; private ScheduledExecutorService executor; diff --git a/modules/DesktopAppearance/src/main/resources/org/gephi/desktop/appearance/Bundle.properties b/modules/DesktopAppearance/src/main/resources/org/gephi/desktop/appearance/Bundle.properties index fe27313c4..002b54b0c 100644 --- a/modules/DesktopAppearance/src/main/resources/org/gephi/desktop/appearance/Bundle.properties +++ b/modules/DesktopAppearance/src/main/resources/org/gephi/desktop/appearance/Bundle.properties @@ -6,21 +6,9 @@ CTL_AppearanceTopComponent=Appearance AppearanceTopComponent.choose.text=---Choose an attribute -PartitionChooser.applyButton.text=Apply - AppearanceToolbar.nodes.label = Nodes AppearanceToolbar.edges.label = Edges -PartitionChooser.groupLink.text=Group -PartitionChooser.group.label=Group -PartitionChooser.ungroup.label=Ungroup -PartitionChooser.groupLink.toolTipText=Group the partition, one group per part -PartitionChooser.pieLink.text=Show Pie -PartitionChooser.showpie.label=Show Pie -PartitionChooser.hidepie.label=Hide Pie -PartitionChooser.refreshBusyLabel.text= -PartitionChooser.refreshButton.text= -PartitionChooser.refreshButton.toolTipText=Refresh AppearanceTopComponent.applyButton.text=Apply AppearanceTopComponent.enableAutoButton.toolTipText=Enable auto transformation - applied continuously AppearanceTopComponent.splineButton.toolTipText=Configure rank interpolation @@ -28,6 +16,7 @@ AppearanceTopComponent.splineButton.text=Spline... AppearanceTopComponent.splineEditor.title=Interpolate AppearanceTopComponent.applyButton.toolTipText=Apply the current transformation to the graph AppearanceTopComponent.localScaleButton.toolTipText=\ Use local scale. The bounds are calculated only on the visible graph instead of the complete graph. +AppearanceTopComponent.partitionLocalScaleButton.toolTipText=\ Use visible graph instead of complete graph for partition calculations AppearanceTopComponent.stopAutoApplyButton.toolTipText=Stop auto apply AppearanceTopComponent.stopAutoApplyButton.text=Stop AppearanceTopComponent.autoApplyButton.toolTipText=Apply continuously even when the values changes diff --git a/modules/GraphAPI/src/test/java/org/gephi/graph/GraphGenerator.java b/modules/GraphAPI/src/test/java/org/gephi/graph/GraphGenerator.java index ada64d6d0..721fdf4f7 100644 --- a/modules/GraphAPI/src/test/java/org/gephi/graph/GraphGenerator.java +++ b/modules/GraphAPI/src/test/java/org/gephi/graph/GraphGenerator.java @@ -19,6 +19,7 @@ public class GraphGenerator { public static final String INT_COLUMN = "age"; public static final String DOUBLE_COLUMN = "value"; + public static final String FLOAT_ARRAY_COLUMN = "values"; public static final String STRING_COLUMN = "country"; public static final String TIMESTAMP_SET_COLUMN = "events"; public static final String INTERVAL_SET_COLUMN = "events"; @@ -27,8 +28,11 @@ public class GraphGenerator { public static final String FIRST_NODE = "1"; public static final String SECOND_NODE = "2"; public static final String FIRST_EDGE = "1"; + public static final String SECOND_EDGE = "2"; public static final String[] STRING_COLUMN_VALUES = new String[] {"France", "Germany"}; + public static final float[][] FLOAT_ARRAY_COLUMN_VALUES = new float[][] {{1f, 2f}, {4f, 3f}}; public static final int INT_COLUMN_MIN_VALUE = 10; + public static final double[][] TIMESTAMP_DOUBLE_COLUMN_VALUES = new double[][] {{3.0}, {6.0}}; private final GraphModel graphModel; private Workspace workspace; @@ -73,6 +77,18 @@ public class GraphGenerator { return this; } + public GraphGenerator generateTinyMultiGraph() { + Node n1 = graphModel.factory().newNode(FIRST_NODE); + Node n2 = graphModel.factory().newNode(SECOND_NODE); + Edge e1 = graphModel.factory().newEdge(FIRST_EDGE, n1, n2, 0, 1.0, true); + Edge e2 = graphModel.factory().newEdge(SECOND_EDGE, n1, n2, 1, 1.0, true); + graphModel.getDirectedGraph().addNode(n1); + graphModel.getDirectedGraph().addNode(n2); + graphModel.getDirectedGraph().addEdge(e1); + graphModel.getDirectedGraph().addEdge(e2); + return this; + } + public GraphGenerator addIntNodeColumn() { graphModel.getNodeTable().addColumn(INT_COLUMN, Integer.class); int age = INT_COLUMN_MIN_VALUE; @@ -82,6 +98,15 @@ public class GraphGenerator { return this; } + public GraphGenerator addFloatArrayNodeColumn() { + graphModel.getNodeTable().addColumn(FLOAT_ARRAY_COLUMN, float[].class); + Node n1 = graphModel.getGraph().getNode(FIRST_NODE); + Node n2 = graphModel.getGraph().getNode(SECOND_NODE); + n1.setAttribute(FLOAT_ARRAY_COLUMN, FLOAT_ARRAY_COLUMN_VALUES[0]); + n2.setAttribute(FLOAT_ARRAY_COLUMN, FLOAT_ARRAY_COLUMN_VALUES[1]); + return this; + } + public GraphGenerator addDoubleNodeColumn() { graphModel.getNodeTable().addColumn(DOUBLE_COLUMN, Double.class); double val = 10; @@ -109,9 +134,10 @@ public class GraphGenerator { public GraphGenerator addTimestampDoubleColumn() { graphModel.getNodeTable().addColumn(TIMESTAMP_DOUBLE_COLUMN, TimestampDoubleMap.class); + int index = 0; for (Node node : graphModel.getGraph().getNodes()) { node.setAttribute(TIMESTAMP_DOUBLE_COLUMN, new TimestampDoubleMap(new double[] {2000}, - new double[] {Math.random() * 100.0})); + TIMESTAMP_DOUBLE_COLUMN_VALUES[index++])); } return this; } -- GitLab