001    /*
002     * Copyright (C) 2008-2010 by Holger Arndt
003     *
004     * This file is part of the Universal Java Matrix Package (UJMP).
005     * See the NOTICE file distributed with this work for additional
006     * information regarding copyright ownership and licensing.
007     *
008     * UJMP is free software; you can redistribute it and/or modify
009     * it under the terms of the GNU Lesser General Public License as
010     * published by the Free Software Foundation; either version 2
011     * of the License, or (at your option) any later version.
012     *
013     * UJMP is distributed in the hope that it will be useful,
014     * but WITHOUT ANY WARRANTY; without even the implied warranty of
015     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
016     * GNU Lesser General Public License for more details.
017     *
018     * You should have received a copy of the GNU Lesser General Public
019     * License along with UJMP; if not, write to the
020     * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
021     * Boston, MA  02110-1301  USA
022     */
023    
024    package org.ujmp.jung;
025    
026    import java.util.HashMap;
027    import java.util.Map;
028    
029    import javax.swing.event.TableModelEvent;
030    import javax.swing.event.TableModelListener;
031    
032    import org.ujmp.core.Coordinates;
033    import org.ujmp.core.Matrix;
034    import org.ujmp.core.exceptions.MatrixException;
035    import org.ujmp.gui.MatrixGUIObject;
036    
037    import edu.uci.ics.jung.graph.Edge;
038    import edu.uci.ics.jung.graph.Vertex;
039    import edu.uci.ics.jung.graph.impl.DirectedSparseEdge;
040    import edu.uci.ics.jung.graph.impl.DirectedSparseGraph;
041    import edu.uci.ics.jung.graph.impl.DirectedSparseVertex;
042    import edu.uci.ics.jung.utils.UserData;
043    
044    public class MatrixGraphWrapper extends DirectedSparseGraph implements TableModelListener {
045    
046            public static final int MAXEDGES = 256000;
047    
048            public static final int MAXVERTICES = 128000;
049    
050            public static final double MINEDGEVALUE = 0.5;
051    
052            private MatrixGUIObject matrix = null;
053    
054            private final Map<Integer, Vertex> vertices = new HashMap<Integer, Vertex>();
055    
056            public MatrixGraphWrapper(Matrix m) throws MatrixException {
057                    this((MatrixGUIObject) m.getGUIObject());
058            }
059    
060            public MatrixGraphWrapper(MatrixGUIObject m) throws MatrixException {
061                    super();
062                    this.matrix = m;
063    
064                    if (m != null) {
065    
066                            // limit the number of vertices
067                            int stepsize = matrix.getColumnCount() / MAXVERTICES + 1;
068    
069                            for (int i = 0; i < matrix.getColumnCount(); i += stepsize) {
070                                    Vertex v = new DirectedSparseVertex();
071                                    v.setUserDatum(JungGraphPanel.Data.Column, i, UserData.SHARED);
072                                    if (matrix.getColumnName(i) != null) {
073                                            v.setUserDatum(JungGraphPanel.Data.Label, matrix.getColumnName(i), UserData.SHARED);
074                                    } else
075                                            v.setUserDatum(JungGraphPanel.Data.Label, "" + i, UserData.SHARED);
076    
077                                    addVertex(v);
078                                    vertices.put(i, v);
079    
080                                    if (i % 100 == 0) {
081                                            System.out.println(i);
082                                    }
083                            }
084    
085                            System.out.println("edges");
086    
087                            int i = 0;
088                            for (long[] rc : matrix.coordinates()) {
089                                    if (i++ % 100 == 0) {
090                                            System.out.println(i);
091                                    }
092                                    double value = matrix.getDoubleValueAt(rc);
093                                    if (Math.abs(value) >= MINEDGEVALUE) {
094                                            Vertex v1 = getVertex((int) rc[Coordinates.ROW]);
095                                            Vertex v2 = getVertex((int) rc[Coordinates.COLUMN]);
096                                            if (v1 != null && v2 != null) {
097                                                    if (numEdges() < MAXEDGES) {
098                                                            Edge e = new DirectedSparseEdge(v1, v2);
099                                                            e.addUserDatum(JungGraphPanel.Data.Label, matrix.getDoubleValueAt(rc), UserData.SHARED);
100                                                            e.addUserDatum(JungGraphPanel.Data.RowColumn, rc, UserData.SHARED);
101                                                            e.addUserDatum(JungGraphPanel.Data.Value, matrix.getDoubleValueAt(rc), UserData.SHARED);
102                                                            addEdge(e);
103                                                    }
104                                            }
105                                    }
106                            }
107    
108                            m.addTableModelListener(this);
109    
110                    }
111            }
112    
113            public void tableChanged() throws MatrixException {
114                    if (true) {
115                            return;
116                    }
117                    for (long[] rc : matrix.coordinates()) {
118    
119                            Vertex v1 = getVertex((int) rc[Coordinates.ROW]);
120                            Vertex v2 = getVertex((int) rc[Coordinates.COLUMN]);
121    
122                            if (v1 != null && v2 != null) {
123    
124                                    Edge e = v1.findEdge(v2);
125                                    double newValue = matrix.getDoubleValueAt(rc);
126    
127                                    if (e == null && Math.abs(newValue) >= MINEDGEVALUE) {
128                                            if (numEdges() < MAXEDGES) {
129                                                    e = new DirectedSparseEdge(v1, v2);
130                                                    e.addUserDatum(JungGraphPanel.Data.Label, matrix.getDoubleValueAt(rc), UserData.SHARED);
131                                                    e.addUserDatum(JungGraphPanel.Data.RowColumn, rc, UserData.SHARED);
132                                                    e.addUserDatum(JungGraphPanel.Data.Value, matrix.getDoubleValueAt(rc), UserData.SHARED);
133                                                    addEdge(e);
134                                            }
135                                    } else if (e != null && Math.abs(newValue) >= MINEDGEVALUE) {
136                                            double oldValue = (Double) e.getUserDatum(JungGraphPanel.Data.Value);
137                                            if (oldValue != newValue) {
138                                                    e.setUserDatum(JungGraphPanel.Data.Value, newValue, UserData.SHARED);
139                                            }
140                                    } else if (e != null && Math.abs(newValue) < MINEDGEVALUE) {
141                                            removeEdge(e);
142                                    }
143                            }
144                    }
145                    mGraphListenerHandler.handleAdd((Edge) null);
146            }
147    
148            private Vertex getVertex(int index) {
149                    return vertices.get(index);
150                    // if (v == null) {
151                    // for (Object o : getVertices()) {
152                    // v = (Vertex) o;
153                    // int row = (Integer) v.getUserDatum(Data.Column);
154                    // if (row == index) {
155                    // vertices.put(index, v);
156                    // return v;
157                    // }
158                    // }
159                    // }
160                    // return null;
161            }
162    
163            public void tableChanged(TableModelEvent e) {
164                    try {
165                            tableChanged();
166                    } catch (MatrixException e1) {
167                            // TODO Auto-generated catch block
168                            e1.printStackTrace();
169                    }
170            }
171    
172            
173            protected void finalize() throws Throwable {
174                    super.finalize();
175                    matrix.removeTableModelListener(this);
176            }
177    
178    }