diff --git a/modules/BridgingPlugin/README.md b/modules/BridgingPlugin/README.md new file mode 100644 index 0000000000..61ca9b57bc --- /dev/null +++ b/modules/BridgingPlugin/README.md @@ -0,0 +1,4 @@ +## Bridge Plugin + +This README supports Markdown, see [syntax](https://help.github.com/articles/markdown-basics/) + diff --git a/modules/BridgingPlugin/pom.xml b/modules/BridgingPlugin/pom.xml new file mode 100644 index 0000000000..6e2ea8fdd9 --- /dev/null +++ b/modules/BridgingPlugin/pom.xml @@ -0,0 +1,112 @@ + + + 4.0.0 + + gephi-plugin-parent + org.gephi + 0.10.0 + + + ia.ppgco.facom.ufu.br + bridge-gephi-plugin + 1.0.2 + nbm + + Bridging Centrality Plugin + Bridging Centrality plugin. + + + + org.gephi + statistics-api + + + org.gephi + utils-longtask + + + org.netbeans.api + org-openide-util + + + + + org.gephi + graph-api + + + org.gephi + statistics-plugin + + + org.gephi + utils-longtask + + + org.gephi + ui-utils + + + org.gephi + utils + + + org.gephi + core-library-wrapper + + + org.netbeans.api + org-openide-util + + + org.netbeans.api + org-openide-util-lookup + + + + + + + org.codehaus.mojo + nbm-maven-plugin + + Apache 2.0 + Getúlio de Morais Pereira + Anderson Rodrigues dos Santos + Luis Felipe Nunes Reis + santosardr@ufu.br + https://github.com/santosardr/gephi-plugins + + + + + + + org.apache.maven.plugins + maven-jar-plugin + 2.4 + + true + + + + org.apache.maven.plugins + maven-compiler-plugin + + 11 + 11 + + + + org.netbeans.api + nbm-maven-plugin + 4.5 + + GPL-3.0 + + + + + + + diff --git a/modules/BridgingPlugin/src/main/java/ia/ppgco/facom/ufu/br/gephi/plugin/bridgingcoefficient/BridgingCentralityMetric.java b/modules/BridgingPlugin/src/main/java/ia/ppgco/facom/ufu/br/gephi/plugin/bridgingcoefficient/BridgingCentralityMetric.java new file mode 100644 index 0000000000..17873894df --- /dev/null +++ b/modules/BridgingPlugin/src/main/java/ia/ppgco/facom/ufu/br/gephi/plugin/bridgingcoefficient/BridgingCentralityMetric.java @@ -0,0 +1,572 @@ +package ia.ppgco.facom.ufu.br.gephi.plugin.bridgingcoefficient; + +import java.io.IOException; +import java.time.Duration; +import java.time.LocalDateTime; +import org.gephi.graph.api.Graph; +import org.gephi.graph.api.GraphModel; +import org.gephi.graph.api.Node; +import org.gephi.graph.api.Table; +import org.gephi.statistics.plugin.GraphDistance; +import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.ListIterator; +import java.util.Map; +import java.util.Stack; +import java.util.logging.Logger; +import javax.swing.JOptionPane; +import org.gephi.graph.api.*; +import org.gephi.statistics.plugin.ChartUtils; +import org.gephi.utils.TempDirUtils; +import org.gephi.utils.TempDirUtils.TempDir; +import org.gephi.utils.progress.Progress; +import org.gephi.utils.progress.ProgressTicket; +import org.jfree.chart.ChartFactory; +import org.jfree.chart.JFreeChart; +import org.jfree.chart.plot.PlotOrientation; +import org.jfree.data.xy.XYSeries; +import org.jfree.data.xy.XYSeriesCollection; +import org.openide.util.NbBundle; +import java.math.BigDecimal; +import org.jfree.chart.plot.XYPlot; +import org.jfree.chart.axis.NumberAxis; +import org.jfree.chart.axis.NumberTickUnit; + +/** + * + * @author getulio + */ +public class BridgingCentralityMetric extends GraphDistance { + + private static final Logger LOG = Logger.getLogger(BridgingCentralityMetric.class.getName()); + + public static final String BETWEENNESS_CENTRALITY = "betweennesscentrality2"; + public static final String BRIDGING_CENTRALITY = "bridgingcentrality"; + public static final String BRIDGING_COEFFICIENT = "bridgingcoefficient"; + + // relatorio de execucao + private String report = ""; + + // controle de execucao, com possibilidade de interrupcao pelo usuario + private boolean cancelled = false; + private ProgressTicket progressTicket; + + // parametros de entrada do usuario + private boolean directed; + private boolean normalized; + + // tomada de tempo de execucao + private LocalDateTime start = null; + private LocalDateTime stop_betweeness = null; + private LocalDateTime stop_bridging = null; + + // estatisticas calculadas pelo algoritmo + private double[] mybetweenness; + private double[] bridging_cent; + private double bridging_coef; + + // variaveis globais + private int Number_of_Nodes; + + /** + * Bridging Centrality algorithm .... + * + * @param graphModel + */ + @Override + public void execute(GraphModel graphModel) { + directed = graphModel.getGraphVisible().isDirected(); + + final Graph graph; + if (directed) { + graph = graphModel.getDirectedGraphVisible(); + } else { + graph = graphModel.getUndirectedGraphVisible(); + } + + execute(graph); + LOG.log(java.util.logging.Level.INFO, "Success Bridging Centrality calculations."); + } + + @Override + public void execute(Graph graph) { + + graph.readLock(); + + try { + + initializeAttributeColunms(graph.getModel()); + //number of nodes + Number_of_Nodes = graph.getNodeCount(); + + //creates one array for each coeficient to be calculated + mybetweenness = new double[Number_of_Nodes]; + bridging_cent = new double[Number_of_Nodes]; + + //a humble index strategy, a sequential index + HashMap indicies = createIndiciesMap(graph); + //marks the start of the process + start = LocalDateTime.now(); + //calculates mybetweenness + mybetweenness = calculateBetweeness(graph, indicies, directed, normalized); + //mark the end of the process + stop_betweeness = LocalDateTime.now(); + // calculates bridging coefficient and bridging centrality + saveCalculatedValues(graph, indicies, mybetweenness); + //mark the end of the process of the bridging metrics + stop_bridging = LocalDateTime.now(); + // ----------- + if (cancelled) { + String msg = NbBundle.getMessage(BridgingCentralityMetric.class, "BridgingCentralityMetric.alert.message"); + String title = NbBundle.getMessage(BridgingCentralityMetric.class, "BridgingCentralityMetric.alert.title"); + JOptionPane.showMessageDialog(null, msg, title, JOptionPane.WARNING_MESSAGE); + LOG.log(java.util.logging.Level.WARNING, msg); + } else { + //Print results + Duration diff_1 = Duration.between(start, stop_betweeness); + Duration diff_2 = Duration.between(stop_betweeness, stop_bridging); + String duration = NbBundle.getMessage(BridgingCentralityMetric.class, "BridgingCentralityMetric.report.duration"); + + report += "" + duration + " : " + diff_1.getSeconds() + " seconds (Betweenness)
"; + report += "" + duration + " : " + diff_2.getSeconds() + " seconds (Bridging)
"; + report += "" + duration + " : " + (diff_1.getSeconds() + diff_2.getSeconds()) + " seconds (Total)
"; + + report += "
"; + } + // ----------- + } finally { + graph.readUnlock(); + } + } + + /** + * Inicializa a tabela de nós + * + * @param graphModel + */ + private void initializeAttributeColunms(GraphModel graphModel) { + + Table nodeTable = graphModel.getNodeTable(); + + if (!nodeTable.hasColumn(BETWEENNESS_CENTRALITY)) { + nodeTable.addColumn(BETWEENNESS_CENTRALITY, "Betweenness Centrality", BigDecimal.class, new BigDecimal("0")); + } + + if (!nodeTable.hasColumn(BRIDGING_COEFFICIENT)) { + nodeTable.addColumn(BRIDGING_COEFFICIENT, "Bridging Coefficient", BigDecimal.class, new BigDecimal("0")); + } + + if (!nodeTable.hasColumn(BRIDGING_CENTRALITY)) { + nodeTable.addColumn(BRIDGING_CENTRALITY, "Bridging Centrality", BigDecimal.class, new BigDecimal("0")); + } + } + + @Override + public HashMap createIndiciesMap(Graph graph) { + + HashMap indicies = new HashMap(); + + int index = 0; + for (Node n : graph.getNodes()) { + indicies.put(n, index); + index++; + } + + return indicies; + } + + /** + * + * @param graph + * @param indicies + * @param directed + * @param normalized + * + * @return array with betweeness statistics + */ + private double[] calculateBetweeness(Graph graph, HashMap indicies, boolean directed, boolean normalized) { + + double[] nodeBetweenness = new double[Number_of_Nodes]; + + int count = 0; + + Progress.start(progressTicket, Number_of_Nodes); + //Bread First Search (BFS) to calculate all the shortest paths from node s to t + for (Node s : graph.getNodes()) { + //The below structures are candidates to performance improvments: + //Creates a stack for each node, ... + Stack S = new Stack(); + //... a linked listed for each node, ... + LinkedList[] Pred = new LinkedList[Number_of_Nodes]; + // ... define sigma(s, t) as the number of shortest paths between nodes s and t ... + double[] sigma = new double[Number_of_Nodes]; + //...and also a distance for each node. + int[] dist = new int[Number_of_Nodes]; + + int s_index = indicies.get(s); + //all parameters are set empty + BFS_Initialization(Pred, sigma, dist, s_index, Number_of_Nodes); + + LinkedList Q = new LinkedList(); + //All nodes are added to the end of the Q list + //Starting node: 1. Choose the starting node s and put it on the queue Q. + Q.addLast(s); + while (!Q.isEmpty()) { + //The calculation always starts from first node. 1. dequeue v from Q + Node v = Q.removeFirst(); + //Despite of being removed of the list the node is stored in a stack S + //This stack will be poped up to simulate the backtracking of the shortest paths + //from all nodes s and t; and allows us to calculate the mybetweenness in the process + S.push(v); + //Recovery of the node index. + //Using this index we will directely access the 'dist' and 'sigma' attributes of the node + int v_index = indicies.get(v); + //Read all edges conected to the node + EdgeIterable edgeIter = getEdgeIter(graph, v, directed); + //Iterate for all edges to access their nodes in the opposite side + for (Edge edge : edgeIter) { + //Obtain a new node in the opposite edge of the node + Node reachable = graph.getOpposite(v, edge); + //recover the index of the reachable node + //Using this index we will directely access the 'dist' and 'sigma' attributes of the reachable node + int r_index = indicies.get(reachable); + //if the reachable node where not investigated yet (dist<0) ... + if (dist[r_index] < 0) { + //... add the reachable node to the list of further nodes to be analysed ... + Q.addLast(reachable); + //... and increment the 'dist' of the reachable node to the value of the initial node plus zero + dist[r_index] = dist[v_index] + 1; + //It meaks sense because the distance from the reachable node to the current node is exactly 1. + } + //If the reachable node was just incorporated to the list of further analyses then the next condition + //will be always true, even because v_index no longer changes. However, the current node here + //could be a reachable node from another one causing the increment of the distantce 'dist'. Once the + //distance is augmented by one the node no longer will be analysed (no loops). Still, the + //next condition certificates the 'sigma' sum only in care of difference of exacltly one edge between + //the current node and the reachable node, no matter the value of 'dist'. + if (dist[r_index] == (dist[v_index] + 1)) { + sigma[r_index] = sigma[r_index] + sigma[v_index]; + //The current node v will be added to the list of nodes to visit of the reachable node + Pred[r_index].addLast(v); + } + } + } + + // ------------- + //All nodes and its connections had its paths length computed. + //Now is possible to calculate the mybetweenness poping up the stack created with the BFS + //1. set delta(v) to zero for all nodes v in V. + double[] delta = new double[Number_of_Nodes]; + //3. while S is not empty, ... + while (!S.empty()) { + //... pop w off S + Node w = S.pop(); + + int w_index = indicies.get(w); + + ListIterator it = Pred[w_index].listIterator(); + while (it.hasNext()) { + Node u = it.next(); + int u_index = indicies.get(u); + //for all nodes u in Pred(w) set delta(u) to delta(u) + MAGIC(delta(w)). + delta[u_index] += (sigma[u_index] / sigma[w_index]) * (1 + delta[w_index]); + //MAGIC(delta(w)) is an incremental formula based on the recursive definition + //of the shortests paths from s to w. It means that a proportion of shortests + //paths from the w predecessors incorporates the u (or v) node. This proportion + //is the division operation. This proportion multiplies at least one path plus + //the remaining shortest paths to w. The incremental sum of all these shortests + //paths proportions (deltas) raises the integral mybetweenness metric. + } + + if (w != s) { + nodeBetweenness[w_index] += delta[w_index]; + } + } + + count++; + + if (cancelled) { + return nodeBetweenness; + } + + Progress.progress(progressTicket, count); + } + + // corrige e normaliza o resultado da mybetweenness + calculateCorrection(graph, indicies, nodeBetweenness, directed, normalized); + + return nodeBetweenness; + } + + /** + * Salva as estatisticas calculadas como atributos de cada nó + * + * @param graph + * @param indicies + * @param nodeBetweenness + */ + private void saveCalculatedValues(Graph graph, HashMap indicies, double[] nodeBetweenness) { + + for (Node s : graph.getNodes()) { + + int s_index = indicies.get(s); + + bridging_coef = bridging_coeficient(graph, s); + //The bridging centrality is just a multiplication of two other metrics + bridging_cent[s_index] = bridging_coef * mybetweenness[s_index]; + + s.setAttribute(BETWEENNESS_CENTRALITY, new BigDecimal(nodeBetweenness[s_index])); + s.setAttribute(BRIDGING_COEFFICIENT, new BigDecimal(bridging_coef)); + s.setAttribute(BRIDGING_CENTRALITY, new BigDecimal(bridging_cent[s_index])); + } + } + + /** + * Aplica as correcoes/normalizacoes nos nós, para a betweeness + * + * @param graph + * @param indicies + * @param nodeBetweenness + * @param directed + * @param normalized + */ + private void calculateCorrection(Graph graph, HashMap indicies, double[] nodeBetweenness, boolean directed, boolean normalized) { + int s_index; + for (Node s : graph.getNodes()) { + + s_index = indicies.get(s); + + // corrige o resultado, para o caso de rede nao dirigida + if (!directed) { + nodeBetweenness[s_index] /= 2; + } + + // normaliza o resultado + if (normalized) { + nodeBetweenness[s_index] /= directed ? (Number_of_Nodes - 1) * (Number_of_Nodes - 2) : (Number_of_Nodes - 1) * (Number_of_Nodes - 2) / 2; + } + } + } + + private void BFS_Initialization(LinkedList[] Pred, double[] sigma, int[] dist, int index, int n) { + //There is a potential problem in this function: the Node s is passed but never used. + //For what node these parameteres are being set? + for (int w = 0; w < n; w++) { + //1. Mark w as unvisited by setting dist[w] (the distance between s and the node w) to infinity. + dist[w] = -1; + //2. Set Pred[w] (nodes that immediately precede w on a shortest path from s) to the empty list. + Pred[w] = new LinkedList(); + + sigma[w] = 0; + } + //The number of shortest paths start with the value 1 since sigma(v,v)=1 + sigma[index] = 1; + //Starting node: 2. Set dist[s] to 0. + dist[index] = 0; + } + + private EdgeIterable getEdgeIter(Graph graph, Node v, boolean directed) { + + if (directed) { + return ((DirectedGraph) graph).getOutEdges(v); + } + + return graph.getEdges(v); + } + + /** + * Should return plain text or HTML text that describe the algorithm execution. + * + * @return + */ + @Override + public String getReport() { + + String htmlIMG1 = ""; + String htmlIMG2 = ""; + String htmlIMG3 = ""; + + try { + TempDir tempDir = TempDirUtils.createTempDir(); + htmlIMG1 = createImageFile(tempDir, bridging_cent, "Bridging Centrality Distribution", "Value", "Count"); + // htmlIMG2 = createImageFile(tempDir, bridging_coef, "Bridging Coefficient Distribution", "Value", "Count"); + htmlIMG3 = createImageFile(tempDir, mybetweenness, "Betweenness Centrality Distribution", "Value", "Count"); + } catch (IOException ex) { + + String msg = NbBundle.getMessage(BridgingCentralityMetric.class, "BridgingCentralityMetric.error.message"); + String title = NbBundle.getMessage(BridgingCentralityMetric.class, "BridgingCentralityMetric.error.title"); + JOptionPane.showMessageDialog(null, msg, title, JOptionPane.ERROR_MESSAGE); + + LOG.log(java.util.logging.Level.SEVERE, msg, ex); + } + + String report_title = NbBundle.getMessage(BridgingCentralityMetric.class, "BridgingCentralityMetric.report.title"); + String params = NbBundle.getMessage(BridgingCentralityMetric.class, "BridgingCentralityMetric.report.params"); + String param_1 = NbBundle.getMessage(BridgingCentralityMetric.class, "BridgingCentralityMetric.report.params.par_1"); + String value_1_1 = NbBundle.getMessage(BridgingCentralityMetric.class, "BridgingCentralityMetric.report.params.par_1.value_1"); + String value_1_2 = NbBundle.getMessage(BridgingCentralityMetric.class, "BridgingCentralityMetric.report.params.par_1.value_2"); + String value_2_1 = NbBundle.getMessage(BridgingCentralityMetric.class, "BridgingCentralityMetric.report.params.par_2.value_1"); + String value_2_2 = NbBundle.getMessage(BridgingCentralityMetric.class, "BridgingCentralityMetric.report.params.par_2.value_2"); + String results = NbBundle.getMessage(BridgingCentralityMetric.class, "BridgingCentralityMetric.report.results"); + + String param_2 = NbBundle.getMessage(BridgingCentralityMetric.class, "BridgingCentralityMetric.report.params.par_2"); + + String rep = "

" + report_title + "

" + + "
" + + "
" + + "

" + params + " :

" + + param_1 + " : " + (directed ? value_1_1 : value_1_2) + "
" + + param_2 + " : " + (normalized ? value_2_1 : value_2_2) + "
" + + "

" + results + ":

"; + + rep += report; + + String algorithms = NbBundle.getMessage(BridgingCentralityMetric.class, "BridgingCentralityMetric.report.algorithm"); + String credits = NbBundle.getMessage(BridgingCentralityMetric.class, "BridgingCentralityMetric.report.credits"); + String contact = NbBundle.getMessage(BridgingCentralityMetric.class, "BridgingCentralityMetric.report.contact"); + + rep += "

" + + "
Please, check the Data Laboratory Tab for the full listing of Bridging Centrality for the graph.
" + + "

" + + htmlIMG1 + "

" + + htmlIMG2 + "

" + + htmlIMG3 + "

" + + "

" + + "

" + algorithms + ":

" + + "
    " + + "
  • Ulrik Brandes, A Faster Algorithm for Betweenness Centrality, in Journal of Mathematical Sociology 25(2):163-177, (2001)
  • " + + "
  • Hwang, W., Cho, Y. R., Zhang, A., & Ramanathan, M. (2006, March). Bridging centrality: identifying bridging nodes in scale-free networks. In Proceedings of the 12th ACM SIGKDD international conference on Knowledge discovery and data mining (pp. 20-23).
  • " + + "
" + + "" + credits + ": " + + "
    " + + "
  • Getúlio de Morais Pereira
  • " + + "
  • Anderson Rodrigues dos Santos
  • " + + "
  • Luis Felipe Nunes Reis
  • " + + "
      " + + "
    • " + contact + " : santosardr@ufu.br
    • " + + "
    " + + "
      " + + " "; + + return rep; + } + + private String createImageFile(TempDir tempDir, double[] pVals, String pName, String pX, String pY) { + + //distribution of nodeIDs + Map dist = new HashMap(); + + for (int i = 0; i < Number_of_Nodes; i++) { + Double d = pVals[i]; + if (dist.containsKey(d)) { + Integer v = dist.get(d); + dist.put(d, v + 1); + } else { + dist.put(d, 1); + } + } + + //Distribution series + XYSeries dSeries = ChartUtils.createXYSeries(dist, pName); + + XYSeriesCollection dataset = new XYSeriesCollection(); + dataset.addSeries(dSeries); + dataset.setAutoWidth(true); + + JFreeChart chart = ChartFactory.createXYLineChart( + pName, + pX, + pY, + dataset, + PlotOrientation.VERTICAL, + true, + false, + false); + + XYPlot xyPlot = (XYPlot) chart.getPlot(); + NumberAxis domain = (NumberAxis) xyPlot.getDomainAxis(); + domain.setRange(0.00, domain.getUpperBound()); + domain.setTickUnit(new NumberTickUnit(domain.getUpperBound() / 10)); + + chart.removeLegend(); + ChartUtils.decorateChart(chart); + // ChartUtils.scaleChart(chart, dSeries, normalized); + + return ChartUtils.renderChart(chart, pName + ".png"); + } + + /** + * Calcula o bridging coeficient de um dado vertice + * + * @param graph + * @param node + * + * @return bridging coefficient value + */ + private static double bridging_coeficient(Graph graph, Node node) { + if(isIsolatedNode(graph,node)){ + return 0; + } + //The inverse degree of a node divided by the inverse degree of all their imediate neighbors + double n = 1.0 / graph.getDegree(node); + + double d = 0.0; + Iterator it = graph.getNeighbors(node).iterator(); + while (it.hasNext()) { + Node t = (Node) it.next(); + d += 1.0 / graph.getDegree(t); + } + + return n / d; + } + + /** + * cancelar a execucao do algoritmo + */ + @Override + public boolean cancel() { + this.cancelled = true; + return true; + } + + @Override + public void setProgressTicket(ProgressTicket progressTicket) { + this.progressTicket = progressTicket; + } + + @Override + public boolean isDirected() { + return directed; + } + + @Override + public void setDirected(boolean directed) { + this.directed = directed; + } + + @Override + public boolean isNormalized() { + return normalized; + } + + @Override + public void setNormalized(boolean normalized) { + this.normalized = normalized; + } + + public static boolean isIsolatedNode(Graph graph, Node node) { + + NodeIterable iterable = graph.getNodes(); + + for (Node s : iterable) { + if (graph.isAdjacent(node, s)) { + iterable.doBreak(); + return false; + } + } + // If loop ends without return false, it is an isolated node + return true; + } + +} diff --git a/modules/BridgingPlugin/src/main/java/ia/ppgco/facom/ufu/br/gephi/plugin/bridgingcoefficient/BridgingCentralityMetricBuilder.java b/modules/BridgingPlugin/src/main/java/ia/ppgco/facom/ufu/br/gephi/plugin/bridgingcoefficient/BridgingCentralityMetricBuilder.java new file mode 100644 index 0000000000..152d8da612 --- /dev/null +++ b/modules/BridgingPlugin/src/main/java/ia/ppgco/facom/ufu/br/gephi/plugin/bridgingcoefficient/BridgingCentralityMetricBuilder.java @@ -0,0 +1,26 @@ +package ia.ppgco.facom.ufu.br.gephi.plugin.bridgingcoefficient; + +import org.gephi.statistics.spi.Statistics; +import org.gephi.statistics.spi.StatisticsBuilder; +import org.openide.util.NbBundle; +import org.openide.util.lookup.ServiceProvider; + +/** + * + * @author Getúlio de Morais Pereira + */ +@ServiceProvider(service = StatisticsBuilder.class) +public class BridgingCentralityMetricBuilder implements StatisticsBuilder { + + public String getName() { + return NbBundle.getMessage(BridgingCentralityMetricBuilder.class, "BridgingCentralityMetricBuilder.name"); + } + + public Statistics getStatistics() { + return new BridgingCentralityMetric(); + } + + public Class getStatisticsClass() { + return BridgingCentralityMetric.class; + } +} diff --git a/modules/BridgingPlugin/src/main/java/ia/ppgco/facom/ufu/br/gephi/plugin/bridgingcoefficient/BridgingCentralityMetricPanel.form b/modules/BridgingPlugin/src/main/java/ia/ppgco/facom/ufu/br/gephi/plugin/bridgingcoefficient/BridgingCentralityMetricPanel.form new file mode 100644 index 0000000000..f2eb2d3b75 --- /dev/null +++ b/modules/BridgingPlugin/src/main/java/ia/ppgco/facom/ufu/br/gephi/plugin/bridgingcoefficient/BridgingCentralityMetricPanel.form @@ -0,0 +1,170 @@ + + +
      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/modules/BridgingPlugin/src/main/java/ia/ppgco/facom/ufu/br/gephi/plugin/bridgingcoefficient/BridgingCentralityMetricPanel.java b/modules/BridgingPlugin/src/main/java/ia/ppgco/facom/ufu/br/gephi/plugin/bridgingcoefficient/BridgingCentralityMetricPanel.java new file mode 100644 index 0000000000..faac527fa9 --- /dev/null +++ b/modules/BridgingPlugin/src/main/java/ia/ppgco/facom/ufu/br/gephi/plugin/bridgingcoefficient/BridgingCentralityMetricPanel.java @@ -0,0 +1,146 @@ +package ia.ppgco.facom.ufu.br.gephi.plugin.bridgingcoefficient; + +/** + * + * @author getulio + */ +public class BridgingCentralityMetricPanel extends javax.swing.JPanel { + + private static final long serialVersionUID = -3590479963190614570L; + + public BridgingCentralityMetricPanel() { + initComponents(); + } + + public boolean isDirected() { + return isDirectedCheckBox.isSelected(); + } + + public void setDirected(boolean directed) { + isDirectedCheckBox.setSelected(directed); + } + + public void directedCheckBox(boolean enabled) { + isDirectedCheckBox.setEnabled(enabled); + isDirectedLabel.setEnabled(enabled); + } + + public boolean isNormalized() { + return isNormalizedCheckBox.isSelected(); + } + + public void setNormalized(boolean normalized) { + isNormalizedCheckBox.setSelected(normalized); + } + + /** + * This method is called from within the constructor to initialize the form. + * WARNING: Do NOT modify this code. The content of this method is always + * regenerated by the Form Editor. + */ + // //GEN-BEGIN:initComponents + private void initComponents() { + + jPanel1 = new javax.swing.JPanel(); + jPanel2 = new javax.swing.JPanel(); + titleLabel = new javax.swing.JLabel(); + isDirectedLabel = new javax.swing.JLabel(); + isDirectedCheckBox = new javax.swing.JCheckBox(); + jSeparator1 = new javax.swing.JSeparator(); + isNormalizedLabel = new javax.swing.JLabel(); + isNormalizedCheckBox = new javax.swing.JCheckBox(); + + setPreferredSize(new java.awt.Dimension(340, 194)); + + jPanel1.setPreferredSize(new java.awt.Dimension(340, 194)); + jPanel1.setLayout(new java.awt.BorderLayout()); + + jPanel2.setPreferredSize(new java.awt.Dimension(340, 194)); + + titleLabel.setFont(new java.awt.Font("Tahoma", 0, 24)); // NOI18N + titleLabel.setText(org.openide.util.NbBundle.getMessage(BridgingCentralityMetricPanel.class, "BridgingCentralityMetricPanel.titleLabel.text")); // NOI18N + + isDirectedLabel.setText(org.openide.util.NbBundle.getMessage(BridgingCentralityMetricPanel.class, "BridgingCentralityMetricPanel.isDirectedLabel.text")); // NOI18N + isDirectedLabel.setMaximumSize(new java.awt.Dimension(110, 23)); + isDirectedLabel.setMinimumSize(new java.awt.Dimension(110, 23)); + + isNormalizedLabel.setText(org.openide.util.NbBundle.getMessage(BridgingCentralityMetricPanel.class, "BridgingCentralityMetricPanel.isNormalizedLabel.text")); // NOI18N + isNormalizedLabel.setMaximumSize(new java.awt.Dimension(110, 23)); + isNormalizedLabel.setMinimumSize(new java.awt.Dimension(110, 23)); + + javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2); + jPanel2.setLayout(jPanel2Layout); + jPanel2Layout.setHorizontalGroup( + jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel2Layout.createSequentialGroup() + .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel2Layout.createSequentialGroup() + .addContainerGap() + .addComponent(isNormalizedCheckBox) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(isNormalizedLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(jPanel2Layout.createSequentialGroup() + .addContainerGap() + .addComponent(isDirectedCheckBox) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(isDirectedLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(jPanel2Layout.createSequentialGroup() + .addContainerGap() + .addComponent(jSeparator1, javax.swing.GroupLayout.PREFERRED_SIZE, 300, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(jPanel2Layout.createSequentialGroup() + .addGap(56, 56, 56) + .addComponent(titleLabel))) + .addContainerGap(497, Short.MAX_VALUE)) + ); + jPanel2Layout.setVerticalGroup( + jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel2Layout.createSequentialGroup() + .addGap(23, 23, 23) + .addComponent(titleLabel) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jSeparator1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(isDirectedCheckBox) + .addComponent(isDirectedLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel2Layout.createSequentialGroup() + .addComponent(isNormalizedLabel, javax.swing.GroupLayout.DEFAULT_SIZE, 23, Short.MAX_VALUE) + .addGap(157, 157, 157)) + .addGroup(jPanel2Layout.createSequentialGroup() + .addComponent(isNormalizedCheckBox) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))) + ); + + jPanel1.add(jPanel2, java.awt.BorderLayout.CENTER); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); + this.setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addGap(0, 0, Short.MAX_VALUE) + .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, 803, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(0, 0, Short.MAX_VALUE)) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addGap(0, 0, Short.MAX_VALUE) + .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, 283, javax.swing.GroupLayout.PREFERRED_SIZE)) + ); + }// //GEN-END:initComponents + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JCheckBox isDirectedCheckBox; + private javax.swing.JLabel isDirectedLabel; + private javax.swing.JCheckBox isNormalizedCheckBox; + private javax.swing.JLabel isNormalizedLabel; + private javax.swing.JPanel jPanel1; + private javax.swing.JPanel jPanel2; + private javax.swing.JSeparator jSeparator1; + private javax.swing.JLabel titleLabel; + // End of variables declaration//GEN-END:variables +} diff --git a/modules/BridgingPlugin/src/main/java/ia/ppgco/facom/ufu/br/gephi/plugin/bridgingcoefficient/BridgingCentralityMetricUI.java b/modules/BridgingPlugin/src/main/java/ia/ppgco/facom/ufu/br/gephi/plugin/bridgingcoefficient/BridgingCentralityMetricUI.java new file mode 100644 index 0000000000..1517732ed4 --- /dev/null +++ b/modules/BridgingPlugin/src/main/java/ia/ppgco/facom/ufu/br/gephi/plugin/bridgingcoefficient/BridgingCentralityMetricUI.java @@ -0,0 +1,116 @@ +package ia.ppgco.facom.ufu.br.gephi.plugin.bridgingcoefficient; + +import javax.swing.JPanel; +import org.gephi.graph.api.Graph; +import org.gephi.graph.api.GraphController; +import org.gephi.statistics.spi.Statistics; +import org.gephi.statistics.spi.StatisticsUI; +import org.openide.util.Lookup; +import org.openide.util.NbBundle; +import org.openide.util.lookup.ServiceProvider; + +/** + * + * @author getulio + */ +@ServiceProvider(service = StatisticsUI.class) +public class BridgingCentralityMetricUI implements StatisticsUI { + + private final StatSettings settings = new StatSettings(); + + private BridgingCentralityMetricPanel panel; + private BridgingCentralityMetric metric; + + private boolean isDirected; + private boolean isNormalized; + + public void setDirected(boolean isDirected) { + this.isDirected = isDirected; + } + + public boolean isDirected() { + return isDirected; + } + + public void setNormalized(boolean isNormalized) { + this.isNormalized = isNormalized; + } + + public boolean isNormalized() { + return isNormalized; + } + + public JPanel getSettingsPanel() { + panel = new BridgingCentralityMetricPanel(); + return panel; + } + + public void setup(Statistics ststcs) { + + metric = (BridgingCentralityMetric) ststcs; + + if ( panel != null ) { + + metric.setNormalized( true ); // default + + panel.setDirected(metric.isDirected()); + panel.setNormalized(metric.isNormalized()); + + GraphController graphController = Lookup.getDefault().lookup(GraphController.class); + Graph graph = graphController.getGraphModel().getGraphVisible(); + panel.directedCheckBox( graph.isDirected() ); + } + } + + public void unsetup() { + if (panel != null) { + metric.setDirected(panel.isDirected()); + metric.setNormalized(panel.isNormalized()); + settings.save(metric); + } + panel = null; + metric = null; + } + + public Class getStatisticsClass() { + return BridgingCentralityMetric.class; + } + + /** + * If your metric doesn't have a single result value, return null. + */ + public String getValue() { + return null; + } + + public String getDisplayName() { + return NbBundle.getMessage(BridgingCentralityMetricUI.class, "BridgingCentralityMetricUI.displayName"); + } + + public String getShortDescription() { + return NbBundle.getMessage(BridgingCentralityMetricUI.class, "BridgingCentralityMetricUI.shortDescription"); + } + + public String getCategory() { + return StatisticsUI.CATEGORY_NETWORK_OVERVIEW; + } + + /** + * The position control the order the metric front-end are displayed. + * Returns a value between 1 and 1000, that indicates the position. + * Less means upper. + */ + public int getPosition() { + return 200; + } + + + private static class StatSettings { + + private void save(BridgingCentralityMetric stat) { + stat.isDirected(); + stat.isNormalized(); + } + } + +} diff --git a/modules/BridgingPlugin/src/main/nbm/manifest.mf b/modules/BridgingPlugin/src/main/nbm/manifest.mf new file mode 100644 index 0000000000..ebc7706b53 --- /dev/null +++ b/modules/BridgingPlugin/src/main/nbm/manifest.mf @@ -0,0 +1,5 @@ +Manifest-Version: 1.0 +OpenIDE-Module-Name: Bridging Centrality Plugin +OpenIDE-Module-Short-Description: Bridging Centrality Plugin +OpenIDE-Module-Long-Description: Bridging Centrality (BC) depicts nodes connected to immediate neighbors that, by turn, are connecting clusters of nodes. BC is the result of Betweenness Centrality multiplied by Bridging Node Centrality. BC can be useful to identify links for groups of nodes. This plugin appends the new data columns to the Gephi data laboratory tab: Betweenness, Bridging Node and Bridging Centrality. +OpenIDE-Module-Display-Category: Metric diff --git a/modules/BridgingPlugin/src/main/resources/ia/ppgco/facom/ufu/br/gephi/plugin/bridgingcoefficient/Bundle.properties b/modules/BridgingPlugin/src/main/resources/ia/ppgco/facom/ufu/br/gephi/plugin/bridgingcoefficient/Bundle.properties new file mode 100644 index 0000000000..6ad7467dfb --- /dev/null +++ b/modules/BridgingPlugin/src/main/resources/ia/ppgco/facom/ufu/br/gephi/plugin/bridgingcoefficient/Bundle.properties @@ -0,0 +1,30 @@ +BridgingCentralityMetricBuilder.name=Bridging Centrality Algorithm + +BridgingCentralityMetricUI.displayName=Bridging Centrality +BridgingCentralityMetricUI.shortDescription=Bridging Centrality (BC) depicts nodes connected to immediate neighbors that, by turn, are connecting clusters of nodes. BC is the result of Betweenness Centrality multiplied by Bridging Node Centrality. BC can be useful to identify links for groups of nodes. For instance, considering a protein network, BC could point up proteins acting as a bridge between corresponding molecular functions. This plugin appends the new data columns to the Gephi data laboratory tab: Betweenness, Bridging Node and Bridging Centrality. + +BridgingCentralityMetricPanel.isDirectedLabel.text=Directed Network +BridgingCentralityMetricPanel.titleLabel.text=Bridging Centrality +BridgingCentralityMetricPanel.isNormalizedLabel.text=Normalized [0..1] + +BridgingCentralityMetric.bwexists.message=Betweenness Centrality values already exists. Recalculate? +BridgingCentralityMetric.finish.message=Bridging Centrality calculated successfully. +BridgingCentralityMetric.alert.message=Execution interrupted by user +BridgingCentralityMetric.alert.title=Warning + +BridgingCentralityMetric.error.message=Error creating graphs to the report. Please, verify directory permissions. +BridgingCentralityMetric.error.title=Error + +BridgingCentralityMetric.report.title=Bridging Centrality - Final Report +BridgingCentralityMetric.report.params=Parameters +BridgingCentralityMetric.report.params.par_1=Network type +BridgingCentralityMetric.report.params.par_2=Normalized[0..1] +BridgingCentralityMetric.report.params.par_1.value_1=directed +BridgingCentralityMetric.report.params.par_1.value_2=undirected +BridgingCentralityMetric.report.params.par_2.value_1=normalized +BridgingCentralityMetric.report.params.par_2.value_2=not normalized +BridgingCentralityMetric.report.results=Results +BridgingCentralityMetric.report.duration=Duration +BridgingCentralityMetric.report.algorithm=Algorithms +BridgingCentralityMetric.report.credits=Implemented by +BridgingCentralityMetric.report.contact=Contact diff --git a/modules/BridgingPlugin/src/main/resources/ia/ppgco/facom/ufu/br/gephi/plugin/bridgingcoefficient/Bundle_pt_BR.properties b/modules/BridgingPlugin/src/main/resources/ia/ppgco/facom/ufu/br/gephi/plugin/bridgingcoefficient/Bundle_pt_BR.properties new file mode 100644 index 0000000000..c585394e93 --- /dev/null +++ b/modules/BridgingPlugin/src/main/resources/ia/ppgco/facom/ufu/br/gephi/plugin/bridgingcoefficient/Bundle_pt_BR.properties @@ -0,0 +1,30 @@ +BridgingCentralityMetricBuilder.name=Bridging Centrality Algorithm + +BridgingCentralityMetricUI.displayName=Bridging Centrality +BridgingCentralityMetricUI.shortDescription=Bridging Centrality (BC) depicts nodes connected to immediate neighbors that, by turn, are connecting clusters of nodes. BC is the result of Betweenness Centrality multiplied by Bridging Node Centrality. BC can be useful to identify links for groups of nodes. For instance, considering a protein network, BC could point up proteins acting as a bridge between corresponding molecular functions. This plugin appends the new data columns to the Gephi data laboratory tab: Betweenness, Bridging Node and Bridging Centrality. + +BridgingCentralityMetricPanel.isDirectedLabel.text=Rede dirigida +BridgingCentralityMetricPanel.titleLabel.text=Bridging Centrality +BridgingCentralityMetricPanel.isNormalizedLabel.text=Normalizado [0..1] + +BridgingCentralityMetric.bwexists.message=Valores de Betweenness Centrality j\u00e1 existem. Recalcular? +BridgingCentralityMetric.finish.message=C\u00e1lculo de Bridging Centrality concluido com sucesso. +BridgingCentralityMetric.alert.message=Execu\u00e7\u00e3o interrompida pelo usu\u00e1rio +BridgingCentralityMetric.alert.title=Alerta + +BridgingCentralityMetric.error.message=Erro na cria\u00e7\u00e3o dos gr\u00e1ficos do relat\u00f3rio de execu\u00e7\u00e3o. Verifique permiss\u00e3o de escrita/leitura no diret\u00f3rio da aplica\u00e7\u00e3o. +BridgingCentralityMetric.error.title=Erro + +BridgingCentralityMetric.report.title=Bridging Centrality - Relat\u00f3rio de Execu\u00e7\u00e3o +BridgingCentralityMetric.report.params=Par\u00e2metros +BridgingCentralityMetric.report.params.par_1=Tipo de rede +BridgingCentralityMetric.report.params.par_2=Normalizado [0..1] +BridgingCentralityMetric.report.params.par_1.value_1=dirigida +BridgingCentralityMetric.report.params.par_1.value_2=n\u00e3o dirigida +BridgingCentralityMetric.report.params.par_2.value_1=normalizado +BridgingCentralityMetric.report.params.par_2.value_2=n\u00e3o normalizado +BridgingCentralityMetric.report.results=Resultados +BridgingCentralityMetric.report.duration=Dura\u00e7\u00e3o +BridgingCentralityMetric.report.algorithm=Algoritmos +BridgingCentralityMetric.report.credits=Implementado por +BridgingCentralityMetric.report.contact=Contato \ No newline at end of file diff --git a/pom.xml b/pom.xml index afb8f2bf5d..d317b96c00 100644 --- a/pom.xml +++ b/pom.xml @@ -8,10 +8,55 @@ pom gephi-plugins + Bridging Centrality Gephi plugin. + 2018 + + + + + CDDL 1.0 + http://www.opensource.org/licenses/CDDL-1.0 + CDDL License 1.0 + + + GPL v3 + http://www.opensource.org/licenses/GPL-3.0 + GPL v3 License + + + + + + scm:git:git://github.com/santosardr/gephi-plugins.git + scm:git:git@github.com:santosardr/gephi-plugins.git + https://github.com/santosardr/gephi-plugins + + + + + + getulio + Getúlio de Morais Pereira + getulio@iftm.edu.br + https://www.researchgate.net/profile/Getulio_De_Morais_Pereira + IFTM Campus Ituiutaba + http://www.iftm.edu.br + -3 + + + santosardr + Anderson Rodrigues dos Santos + santosardr@ufu.br + https://www.researchgate.net/profile/Anderson_Santos_3 + Universidade Federal de Uberlândia + http://www.ufu.br + -3 + + - + modules/BridgingPlugin @@ -20,15 +65,10 @@ 0.10.0 ${project.build.directory}/plugins_clusters github + 1.8 + 1.8 - - - scm:git:git://github.com/gephi/gephi-plugins.git - scm:git:git@github.com:gephi/gephi-plugins.git - https://github.com/gephi/gephi-plugins - - @@ -97,6 +137,14 @@ maven-scm-publish-plugin 3.1.0 + + org.netbeans.api + nbm-maven-plugin + 4.5 + + GPL-3.0 + + @@ -214,6 +262,13 @@ true + + org.netbeans.api + nbm-maven-plugin + + GPL-3.0 + +