~gephi.team/gephi/0.8.1

« back to all changes in this revision

Viewing changes to RankingPlugin/src/org/gephi/ranking/plugin/AttributeRankingBuilder.java

  • Committer: Mathieu Bastian
  • Date: 2011-07-19 04:14:33 UTC
  • Revision ID: git-v1:fc8aece8315f8e214fdb55d8cd035682fd1ca44b
Major refactoring of the Ranking modules, and creation of SPIs for ranking builders and transformers. Creation of a RankingPlugin module with new ranking and transformers implementations. Simplification of the RankingAPI module and fit to conventions. Update of the DesktopRanking module with cleaner code and introduction of a RankingUIController and RankingUIModel to manage states. Deletion of the RankingResult mechanism and introduction of RankingEvent and RankingListener interfaces to manages ranking events. Documentation of the API and SPI, ready to be declared stable.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
Copyright 2008-2010 Gephi
 
3
Authors : Mathieu Bastian <mathieu.bastian@gephi.org>
 
4
Website : http://www.gephi.org
 
5
 
 
6
This file is part of Gephi.
 
7
 
 
8
Gephi is free software: you can redistribute it and/or modify
 
9
it under the terms of the GNU Affero General Public License as
 
10
published by the Free Software Foundation, either version 3 of the
 
11
License, or (at your option) any later version.
 
12
 
 
13
Gephi is distributed in the hope that it will be useful,
 
14
but WITHOUT ANY WARRANTY; without even the implied warranty of
 
15
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
16
GNU Affero General Public License for more details.
 
17
 
 
18
You should have received a copy of the GNU Affero General Public License
 
19
along with Gephi.  If not, see <http://www.gnu.org/licenses/>.
 
20
 */
 
21
package org.gephi.ranking.plugin;
 
22
 
 
23
import java.math.BigDecimal;
 
24
import java.math.BigInteger;
 
25
import java.util.ArrayList;
 
26
import java.util.Arrays;
 
27
import java.util.Comparator;
 
28
import java.util.List;
 
29
import org.gephi.data.attributes.api.AttributeColumn;
 
30
import org.gephi.data.attributes.api.AttributeController;
 
31
import org.gephi.data.attributes.api.AttributeModel;
 
32
import org.gephi.data.attributes.api.AttributeUtils;
 
33
import org.gephi.data.attributes.api.Estimator;
 
34
import org.gephi.data.attributes.type.DynamicType;
 
35
import org.gephi.data.attributes.type.TimeInterval;
 
36
import org.gephi.dynamic.api.DynamicController;
 
37
import org.gephi.dynamic.api.DynamicModel;
 
38
import org.gephi.graph.api.Attributable;
 
39
import org.gephi.graph.api.Graph;
 
40
import org.gephi.graph.api.GraphController;
 
41
import org.gephi.graph.api.GraphModel;
 
42
import org.gephi.ranking.api.Ranking;
 
43
import org.gephi.ranking.api.RankingModel;
 
44
import org.gephi.ranking.spi.RankingBuilder;
 
45
import org.openide.util.Lookup;
 
46
import org.openide.util.lookup.ServiceProvider;
 
47
 
 
48
/**
 
49
 * Ranking builder for attributes. Builds the {@link Ranking} instances that
 
50
 * maps to all numerical attribute columns.
 
51
 * <p>
 
52
 * The ranking is built for the workspace associated to the given {@link RankingModel}.
 
53
 * <p>
 
54
 * When the column is dynamic, the ranking uses the current time interval defined
 
55
 * in the DynamicAPI. The time interval value is set when the ranking is built and
 
56
 * won't be updated.
 
57
 * 
 
58
 * @author Mathieu Bastian
 
59
 */
 
60
@ServiceProvider(service = RankingBuilder.class)
 
61
public class AttributeRankingBuilder implements RankingBuilder {
 
62
 
 
63
    private final GraphController graphController;
 
64
    private final AttributeController attributeController;
 
65
    private final AttributeUtils attributeUtils;
 
66
 
 
67
    public AttributeRankingBuilder() {
 
68
        attributeController = Lookup.getDefault().lookup(AttributeController.class);
 
69
        attributeUtils = Lookup.getDefault().lookup(AttributeUtils.class);
 
70
        graphController = Lookup.getDefault().lookup(GraphController.class);
 
71
    }
 
72
 
 
73
    @Override
 
74
    public Ranking[] buildRanking(RankingModel model) {
 
75
        AttributeModel attributeModel = attributeController.getModel(model.getWorkspace());
 
76
        List<Ranking> rankings = new ArrayList<Ranking>();
 
77
        GraphModel graphModel = graphController.getModel(model.getWorkspace());
 
78
        Graph graph = graphModel.getGraphVisible();
 
79
 
 
80
        //Nodes
 
81
        for (AttributeColumn col : attributeModel.getNodeTable().getColumns()) {
 
82
            if (attributeUtils.isNumberColumn(col)) {
 
83
                AttributeRanking ranking = new AttributeRanking(Ranking.NODE_ELEMENT, col, graph);
 
84
                rankings.add(ranking);
 
85
            }
 
86
        }
 
87
 
 
88
        //Edges
 
89
        for (AttributeColumn col : attributeModel.getEdgeTable().getColumns()) {
 
90
            if (attributeUtils.isNumberColumn(col)) {
 
91
                AttributeRanking ranking = new AttributeRanking(Ranking.EDGE_ELEMENT, col, graph);
 
92
                rankings.add(ranking);
 
93
            }
 
94
        }
 
95
 
 
96
        //Dynamic
 
97
        DynamicController dynamicController = Lookup.getDefault().lookup(DynamicController.class);
 
98
        if (dynamicController != null) {
 
99
            DynamicModel dynamicModel = dynamicController.getModel();
 
100
            if (dynamicModel != null) {
 
101
                TimeInterval visibleInterval = dynamicModel.getVisibleInterval();
 
102
 
 
103
                //Nodes
 
104
                for (AttributeColumn col : attributeModel.getNodeTable().getColumns()) {
 
105
                    if (attributeUtils.isDynamicNumberColumn(col)) {
 
106
                        DynamicAttributeRanking ranking = new DynamicAttributeRanking(Ranking.NODE_ELEMENT, col, graph, visibleInterval, dynamicModel.getNumberEstimator());
 
107
                        rankings.add(ranking);
 
108
                    }
 
109
                }
 
110
 
 
111
                //Edges
 
112
                for (AttributeColumn col : attributeModel.getEdgeTable().getColumns()) {
 
113
                    if (attributeUtils.isDynamicNumberColumn(col)) {
 
114
                        DynamicAttributeRanking ranking = new DynamicAttributeRanking(Ranking.EDGE_ELEMENT, col, graph, visibleInterval, dynamicModel.getNumberEstimator());
 
115
                        rankings.add(ranking);
 
116
                    }
 
117
                }
 
118
            }
 
119
        }
 
120
 
 
121
        //Sort attributes by alphabetical order
 
122
        Ranking[] rankingArray = rankings.toArray(new Ranking[0]);
 
123
        Arrays.sort(rankingArray, new Comparator<Ranking>() {
 
124
 
 
125
            @Override
 
126
            public int compare(Ranking a, Ranking b) {
 
127
                return (a.toString().compareTo(b.toString()));
 
128
            }
 
129
        });
 
130
 
 
131
        return rankingArray;
 
132
    }
 
133
 
 
134
    private static class AttributeRanking extends AbstractRanking<Attributable> {
 
135
 
 
136
        private final AttributeColumn column;
 
137
        private final Graph graph;
 
138
 
 
139
        public AttributeRanking(String elementType, AttributeColumn column, Graph graph) {
 
140
            super(elementType);
 
141
            this.column = column;
 
142
            this.graph = graph;
 
143
        }
 
144
 
 
145
        @Override
 
146
        public Number getValue(Attributable attributable) {
 
147
            return (Number) attributable.getAttributes().getValue(column.getIndex());
 
148
        }
 
149
 
 
150
        @Override
 
151
        public float normalize(Number value) {
 
152
            return (value.floatValue() - getMinimumValue().floatValue()) / (float) (getMaximumValue().floatValue() - getMinimumValue().floatValue());
 
153
        }
 
154
 
 
155
        @Override
 
156
        public Number unNormalize(float normalizedValue) {
 
157
            double val = (normalizedValue * (getMaximumValue().doubleValue() - getMinimumValue().doubleValue())) + getMinimumValue().doubleValue();
 
158
            switch (column.getType()) {
 
159
                case BIGDECIMAL:
 
160
                    return new BigDecimal(val);
 
161
                case BIGINTEGER:
 
162
                    return new BigInteger("" + val);
 
163
                case DOUBLE:
 
164
                    return new Double(val);
 
165
                case FLOAT:
 
166
                    return new Float(val);
 
167
                case INT:
 
168
                    return new Integer((int) val);
 
169
                case LONG:
 
170
                    return new Long((long) val);
 
171
                case SHORT:
 
172
                    return new Short((short) val);
 
173
                default:
 
174
                    return new Double(val);
 
175
            }
 
176
        }
 
177
 
 
178
        @Override
 
179
        public String getName() {
 
180
            return column.getTitle();
 
181
        }
 
182
 
 
183
        @Override
 
184
        public Number getMaximumValue() {
 
185
            if (maximum == null) {
 
186
                AbstractRanking.refreshMinMax(this, graph);
 
187
            }
 
188
            return maximum;
 
189
        }
 
190
 
 
191
        @Override
 
192
        public Number getMinimumValue() {
 
193
            if (minimum == null) {
 
194
                AbstractRanking.refreshMinMax(this, graph);
 
195
            }
 
196
            return minimum;
 
197
        }
 
198
    }
 
199
 
 
200
    private static class DynamicAttributeRanking extends AbstractRanking<Attributable> {
 
201
 
 
202
        private final AttributeColumn column;
 
203
        private final Graph graph;
 
204
        private final TimeInterval timeInterval;
 
205
        private final Estimator estimator;
 
206
 
 
207
        public DynamicAttributeRanking(String elementType, AttributeColumn column, Graph graph, TimeInterval timeInterval, Estimator estimator) {
 
208
            super(elementType);
 
209
            this.column = column;
 
210
            this.timeInterval = timeInterval;
 
211
            this.estimator = estimator;
 
212
            this.graph = graph;
 
213
        }
 
214
 
 
215
        @Override
 
216
        public Number getValue(Attributable attributable) {
 
217
            DynamicType<? extends Number> dynamicType = (DynamicType<? extends Number>) attributable.getAttributes().getValue(column.getIndex());
 
218
            if (dynamicType != null) {
 
219
                return (Number) dynamicType.getValue(timeInterval == null ? Double.NEGATIVE_INFINITY : timeInterval.getLow(),
 
220
                        timeInterval == null ? Double.POSITIVE_INFINITY : timeInterval.getHigh(), estimator);
 
221
            }
 
222
            return null;
 
223
        }
 
224
 
 
225
        @Override
 
226
        public float normalize(Number value) {
 
227
            return (value.floatValue() - minimum.floatValue()) / (float) (getMaximumValue().floatValue() - getMinimumValue().floatValue());
 
228
        }
 
229
 
 
230
        @Override
 
231
        public Number unNormalize(float normalizedValue) {
 
232
            double val = (normalizedValue * (getMaximumValue().doubleValue() - getMinimumValue().doubleValue())) + getMinimumValue().doubleValue();
 
233
            switch (column.getType()) {
 
234
                case BIGDECIMAL:
 
235
                    return new BigDecimal(val);
 
236
                case BIGINTEGER:
 
237
                    return new BigInteger("" + val);
 
238
                case DOUBLE:
 
239
                    return new Double(val);
 
240
                case FLOAT:
 
241
                    return new Float(val);
 
242
                case INT:
 
243
                    return new Integer((int) val);
 
244
                case LONG:
 
245
                    return new Long((long) val);
 
246
                case SHORT:
 
247
                    return new Short((short) val);
 
248
                default:
 
249
                    return new Double(val);
 
250
            }
 
251
        }
 
252
 
 
253
        @Override
 
254
        public String getName() {
 
255
            return column.getTitle();
 
256
        }
 
257
 
 
258
        @Override
 
259
        public Number getMaximumValue() {
 
260
            if (maximum == null) {
 
261
                AbstractRanking.refreshMinMax(this, graph);
 
262
            }
 
263
            return maximum;
 
264
        }
 
265
 
 
266
        @Override
 
267
        public Number getMinimumValue() {
 
268
            if (minimum == null) {
 
269
                AbstractRanking.refreshMinMax(this, graph);
 
270
            }
 
271
            return minimum;
 
272
        }
 
273
    }
 
274
}