<dependency>
<groupId>jp.sourceforge.talisman</groupId>
<artifactId>mds</artifactId>
- <version>1.1.0</version>
+ <version>1.0.0-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
<dependency>
<artifactId>i18n</artifactId>
<version>1.0.1</version>
</dependency>
- <dependency>
- <groupId>jp.sourceforge.talisman</groupId>
- <artifactId>mds</artifactId>
- <version>1.0.0</version>
- </dependency>
</dependencies>
<licenses>
<configuration>
<source>1.6</source>
<target>1.6</target>
- <encoding>shift_jis</encoding>
+ <encoding>utf-8</encoding>
</configuration>
</plugin>
index++;
}
- stigmata.showMDSGraph(set, extraction.getContext());
+ stigmata.showMdsGraph(set, extraction.getContext());
}
private void graphButtonActionPerformed(ActionEvent e){
import jp.sourceforge.stigmata.ui.swing.actions.AboutAction;
import jp.sourceforge.stigmata.ui.swing.actions.LicenseAction;
import jp.sourceforge.stigmata.ui.swing.graph.SimilarityDistributionGraphPane;
-import jp.sourceforge.stigmata.ui.swing.mds.MDSGraphPanel;
+import jp.sourceforge.stigmata.ui.swing.mds.MdsViewerPane;
import jp.sourceforge.stigmata.ui.swing.tab.EditableTabbedPane;
import jp.sourceforge.stigmata.utils.Utility;
import jp.sourceforge.talisman.i18n.Messages;
tabPane.setSelectedIndex(tabPane.getTabCount() - 1);
}
- public void showMDSGraph(BirthmarkSet[] set, BirthmarkContext context){
+ public void showMdsGraph(BirthmarkSet[] set, BirthmarkContext context){
try{
- MDSGraphPanel panel = new MDSGraphPanel(this, set, context);
+ MdsViewerPane panel = new MdsViewerPane(this, set, context);
int mappingGraphCount = getNextCount("mds_graph");
GUIUtility.addNewTab(
getMessages(), "mappinggraph", tabPane, panel,
+++ /dev/null
-package jp.sourceforge.stigmata.ui.swing.mds;
-
-/*
- * $Id$
- */
-
-/**
- * @author Haruaki TAMADA
- * @version $Revision$ $Date$
- */
-public class Coordinate{
- private double x, y, z;
- private String label;
- private String showName;
- private int groupId = 0;
-
- public Coordinate(String label, double x, double y){
- this(label, shortenLabel(label), x, y, Double.NaN);
- }
-
- public Coordinate(String label, double x, double y, double z){
- this(label, shortenLabel(label), x, y, z);
- }
-
- public Coordinate(String label, String showName, double x, double y){
- this(label, showName, x, y, Double.NaN);
- }
-
- public Coordinate(String label, String showName, double x, double y, double z){
- this.label = label;
- this.showName = showName;
- this.x = x;
- this.y = y;
- this.z = z;
- }
-
- public String toString(){
- return String.format("%s[%d] (%g, %g)", getLabel(), getGroupId(), getX(), getY());
- }
-
- public int getGroupId(){
- return groupId;
- }
-
- public void setGroupId(int groupId){
- this.groupId = groupId;
- }
-
- public String getLabel(){
- return label;
- }
-
- public void setLabel(String label){
- this.label = label;
- }
-
- public String getShowName(){
- return showName;
- }
-
- public void setShowName(String showName){
- this.showName = showName;
- }
-
- public double getX(){
- return x;
- }
-
- public void setX(double x){
- this.x = x;
- }
-
- public double getY(){
- return y;
- }
-
- public void setY(double y){
- this.y = y;
- }
-
- public double getZ(){
- return z;
- }
-
- public void setZ(double z){
- this.z = z;
- }
-
- private static String shortenLabel(String label){
- int index = label.lastIndexOf('/');
- if(index < 0){
- index = label.lastIndexOf('\\');
- }
- int firstIndex = label.indexOf('.');
- int lastIndex = label.lastIndexOf('.');
- int length = label.length();
- String returnValue = label;
-
- if(index < 0 && (firstIndex != lastIndex && lastIndex != (length - 1))){
- index = lastIndex;
- returnValue = label.substring(index + 1);
- if("jar".equals(returnValue)){
- returnValue = label;
- }
- }
- return returnValue;
- }
-}
+++ /dev/null
-package jp.sourceforge.stigmata.ui.swing.mds;
-
-/*
- * $Id$
- */
-
-/**
- * @author Haruaki TAMADA
- * @version $Revision$ $Date$
- */
-public enum GeometoryType{
- RECTANGLE,
- UPPER_TRIANGLE,
- CIRCLE,
- XMARK,
- RHOMBUS,
- DOWNER_TRIANGLE,
- FILLED_RECTANGLE,
- CROSS,
- FILLED_UPPER_TRIANGLE,
- FILLED_CIRCLE,
- FILLED_RHOMBUS,
- STAR,
- FILLED_DOWNER_TRIANGLE;
-
- public static int getMaxGroupCount(){
- return FILLED_DOWNER_TRIANGLE.ordinal();
- }
-}
+++ /dev/null
-package jp.sourceforge.stigmata.ui.swing.mds;
-
-/*
- * $Id$
- */
-
-import java.awt.BorderLayout;
-import java.awt.Color;
-import java.awt.Dimension;
-import java.awt.FlowLayout;
-import java.awt.GridLayout;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-import java.awt.event.ComponentAdapter;
-import java.awt.event.ComponentEvent;
-import java.net.URL;
-
-import javax.swing.Action;
-import javax.swing.Box;
-import javax.swing.JCheckBox;
-import javax.swing.JComboBox;
-import javax.swing.JLabel;
-import javax.swing.JPanel;
-
-import jp.sourceforge.stigmata.BirthmarkContext;
-import jp.sourceforge.stigmata.BirthmarkEnvironment;
-import jp.sourceforge.stigmata.BirthmarkSet;
-import jp.sourceforge.stigmata.ComparisonPair;
-import jp.sourceforge.stigmata.ExtractionResultSet;
-import jp.sourceforge.stigmata.result.SingleExtractionResultSet;
-import jp.sourceforge.stigmata.ui.swing.ClippedLRListCellRenderer;
-import jp.sourceforge.stigmata.ui.swing.GUIUtility;
-import jp.sourceforge.stigmata.ui.swing.PopupButton;
-import jp.sourceforge.stigmata.ui.swing.StigmataFrame;
-import jp.sourceforge.stigmata.ui.swing.actions.ChangeColorAction;
-import jp.sourceforge.stigmata.ui.swing.actions.SaveAction;
-import jp.sourceforge.stigmata.ui.swing.mds.mark.DrawerFactory;
-import jp.sourceforge.talisman.i18n.Messages;
-import Jama.Matrix;
-
-/**
- *
- * @author Haruaki TAMADA
- * @version $Revision$ $Date$
- */
-public class MDSGraphPanel extends JPanel{
- private static final long serialVersionUID = -7256554014379112897L;
-
- private StigmataFrame stigmata;
- private BirthmarkSet[] set;
- private BirthmarkContext context;
- private LabelMap labels;
- private MDSGraphViewer viewer;
-
- public MDSGraphPanel(StigmataFrame stigmata, BirthmarkSet[] set, BirthmarkContext context){
- this.stigmata = stigmata;
- this.context = context;
- this.set = set;
-
- double[][] matrix = initData(set, context);
- initLayouts(matrix);
- }
-
- private double[][] initData(BirthmarkSet[] set, BirthmarkContext context){
- labels = new LabelMap();
- double[][] matrix = new double[set.length][set.length];
-
- for(int i = 0; i < set.length; i++){
- for(int j = 0; j <= i; j++){
- ComparisonPair pair = new ComparisonPair(set[i], set[j], context);
- matrix[i][j] = 1d - pair.calculateSimilarity();
- if(i != j){
- matrix[j][i] = matrix[i][j];
- }
- }
- String className = set[i].getName();
- labels.addLabel(className);
- String groupName = getGroupName(set[i].getLocation());
- labels.setGroup(className, groupName);
- }
- return matrix;
- }
-
- private String getGroupName(URL location){
- String url = location.toString();
- if(url.startsWith("jar:")){
- url = url.substring("jar:".length(), url.lastIndexOf('!'));
- }
- return url;
- }
-
- /**
- * This method must called after
- * {@link #initData(BirthmarkSet[], BirthmarkEnvironment) <code>initData</code>}.
- * Because this method uses calculated value in initData method.
- */
- private void initLayouts(double[][] matrix){
- final Messages messages = stigmata.getMessages();
- viewer = new MDSGraphViewer(stigmata.getMessages(), new MDSMethod(new Matrix(matrix)), labels);
- viewer.setShowLabel(true);
-
- viewer.addActionListener(new ActionListener(){
- public void actionPerformed(ActionEvent e){
- String c = e.getActionCommand();
- for(int i = 0; i < set.length; i++){
- if(c.equals(set[i].getName())){
- ExtractionResultSet ers = new SingleExtractionResultSet(context, set[i]);
- stigmata.showExtractionResult(ers);
- }
- }
- }
- });
- JCheckBox check = new JCheckBox(stigmata.getMessages().get("showlabel.button.label"), true);
- check.addActionListener(new ActionListener(){
- public void actionPerformed(ActionEvent e){
- JCheckBox c = (JCheckBox)e.getSource();
- viewer.setShowLabel(c.isSelected());
- }
- });
-
- Action pointColorAction = new ChangeColorAction(
- "updatecolor", stigmata, Color.BLACK, new ActionListener(){
- public void actionPerformed(ActionEvent e){
- ChangeColorAction action = (ChangeColorAction)e.getSource();
- viewer.setPointColor(action.getColor());
- }
- });
- Action overColorAction = new ChangeColorAction(
- "updateovercolor", stigmata, Color.BLUE, new ActionListener(){
- public void actionPerformed(ActionEvent e){
- ChangeColorAction action = (ChangeColorAction)e.getSource();
- viewer.setOverColor(action.getColor());
- }
- });
- SaveAction saveMDSAction = new SaveAction(stigmata, new MDSImageExporter(viewer));
- saveMDSAction.setExtensions(stigmata.getMessages().getArray("savemds.extensions"));
- saveMDSAction.setDescrpition(stigmata.getMessages().get("savemds.description"));
-
- SaveAction saveCoordinate = new SaveAction(stigmata, new MDSPointsLocationExporter(viewer));
- saveCoordinate.setExtensions(stigmata.getMessages().getArray("savelocation.extensions"));
- saveCoordinate.setDescrpition(stigmata.getMessages().get("savelocation.description"));
-
- PopupButton colorButton = new PopupButton(
- GUIUtility.createButton(messages, "updatecolor", pointColorAction)
- );
- colorButton.addMenuItem(GUIUtility.createJMenuItem(messages, "updateovercolor", overColorAction));
- PopupButton saveButton = new PopupButton(
- GUIUtility.createButton(messages, "savemds", saveMDSAction)
- );
- saveButton.addMenuItem(GUIUtility.createJMenuItem(messages, "savelocation", saveCoordinate));
-
- JLabel numberOfDotsLabel = new JLabel(String.valueOf(set.length));
- GUIUtility.decorateJComponent(messages, numberOfDotsLabel, "mdsgraph.count");
- // set the number of dots of each groups
- JComboBox numberOfGroupsLabelCombo = new JComboBox();
- GeometoryType[] types = GeometoryType.values();
- DrawerFactory factory = DrawerFactory.getInstance();
- for(String name: labels.getGroupNames()){
- int count = labels.getGroupElementCount(name);
- if(count != 0){
- ClippedLRListCellRenderer.LRItem item = new ClippedLRListCellRenderer.LRItem(name, count);
- item.setIcon(factory.createIcon(types[labels.getGroupId(name)]));
- numberOfGroupsLabelCombo.addItem(item);
- }
- }
- numberOfGroupsLabelCombo.setEditable(false);
- Dimension dim = new Dimension(100, numberOfGroupsLabelCombo.getPreferredSize().height);
- numberOfGroupsLabelCombo.setRenderer(new ClippedLRListCellRenderer(dim, 50));
- GUIUtility.decorateJComponent(messages, numberOfGroupsLabelCombo, "mdsgraph.group");
-
- JPanel north = new JPanel(new GridLayout(1, 2));
- north.add(numberOfDotsLabel);
- north.add(numberOfGroupsLabelCombo);
-
- Box south = Box.createHorizontalBox();
- south.add(Box.createHorizontalGlue());
- south.add(saveButton);
- south.add(Box.createHorizontalGlue());
- south.add(colorButton);
- south.add(Box.createHorizontalGlue());
- south.add(check);
- south.add(Box.createHorizontalGlue());
-
- JPanel center = new JPanel(new FlowLayout(FlowLayout.CENTER));
- center.addComponentListener(new ComponentAdapter(){
- @Override
- public void componentResized(ComponentEvent e){
- Dimension d = e.getComponent().getSize();
- viewer.setSize(d.width - 10, d.height - 10);
- }
- });
- setLayout(new BorderLayout());
-
- center.add(viewer);
-
- add(north, BorderLayout.NORTH);
- add(center, BorderLayout.CENTER);
- add(south, BorderLayout.SOUTH);
- }
-}
+++ /dev/null
-package jp.sourceforge.stigmata.ui.swing.mds;
-
-/*
- * $Id$
- */
-
-import java.awt.BorderLayout;
-import java.awt.Color;
-import java.awt.Component;
-import java.awt.Dimension;
-import java.awt.Graphics;
-import java.awt.Point;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
-import javax.swing.JFrame;
-import javax.swing.JLabel;
-import javax.swing.JLayeredPane;
-
-import jp.sourceforge.stigmata.ui.swing.mds.mark.DrawerFactory;
-import jp.sourceforge.talisman.i18n.Messages;
-import Jama.Matrix;
-
-/**
- * @author Haruaki TAMADA
- * @version $Revision$ $Date$
- */
-public class MDSGraphViewer extends JLayeredPane{
- private static final long serialVersionUID = -9196070059428975126L;
- private static final int POINT_LAYER = DEFAULT_LAYER;
- private static final int LABEL_LAYER = DEFAULT_LAYER;
-
- private Messages messages;
- private MDSMethod mds;
- private List<Coordinate> plots = new ArrayList<Coordinate>();
- private Color overColor = PointComponent.DEFAULT_OVER_COLOR;
- private Color pointColor = getForeground();
- private boolean sameAspect = false;
- private boolean showLabel = false;
- private List<PointComponent> points = new ArrayList<PointComponent>();
- private List<ActionListener> listeners = new ArrayList<ActionListener>();
-
- public MDSGraphViewer(Messages messages, MDSMethod mds){
- this(messages, mds, null);
- }
-
- public MDSGraphViewer(Messages messages, MDSMethod mds, LabelMap labels){
- this.messages = messages;
- this.mds = mds;
-
- setSize(500, 500);
- setMinimumSize(getSize());
- initLayouts(labels);
- }
-
- public void addActionListener(ActionListener listener){
- listeners.add(listener);
- }
-
- public void removeActionListener(ActionListener listener){
- listeners.remove(listener);
- }
-
- public Messages getMessages(){
- return messages;
- }
-
- public void setMessages(Messages messages){
- if(messages == null){
- throw new NullPointerException();
- }
- this.messages = messages;
- }
-
- @Override
- public void setSize(int width, int height){
- if(width < height) height = width;
- else width = height;
- super.setSize(width, height);
- setPreferredSize(getSize());
- }
-
- public Iterator<Coordinate> coordinates(){
- return plots.iterator();
- }
-
- public int getPointCount(){
- return plots.size();
- }
-
- public Coordinate getCoordinate(int index){
- return plots.get(index);
- }
-
- public boolean isShowLabel(){
- return showLabel;
- }
-
- public void setShowLabel(boolean showLabel){
- this.showLabel = showLabel;
- repaint();
- }
-
- public boolean isSameAspect(){
- return sameAspect;
- }
-
- public void setSameAspect(boolean sameAspect){
- this.sameAspect = sameAspect;
- repaint();
- }
-
- public Color getOverColor(){
- return overColor;
- }
-
- public void setOverColor(Color color){
- this.overColor = color;
- for(int i = 0; i < getComponentCount(); i++){
- Component c = getComponent(i);
- if(c instanceof PointComponent){
- ((PointComponent)c).setOverColor(color);
- }
- }
- }
-
- public Color getPointColor(){
- return pointColor;
- }
-
- public void setPointColor(Color color){
- this.pointColor = color;
- for(int i = 0; i < getComponentCount(); i++){
- Component c = getComponent(i);
- if(c instanceof PointComponent){
- ((PointComponent)c).setForeground(color);
- }
- }
- }
-
- @Override
- public void paintComponent(Graphics g){
- super.paintComponent(g);
-
- Dimension d = getSize();
-
- g.setColor(Color.GRAY);
-
- g.drawLine(0, 0, d.width - 1, 0);
- g.drawLine(d.width - 1, 0, d.width - 1, d.height - 1);
- g.drawLine(d.width / 2, d.height, d.width / 2, 0);
-
- g.drawLine(0, 0, 0, d.height - 1);
- g.drawLine(0, d.height - 1, d.width - 1, d.height - 1);
- g.drawLine(0, d.height / 2, d.width, d.height / 2);
-
- updatePointComponents(d);
- }
-
- protected void fireEvent(PointComponent p){
- ActionEvent e = new ActionEvent(this, 0, p.getLabel());
- for(ActionListener l: listeners){
- l.actionPerformed(e);
- }
- }
-
- private void initLayouts(LabelMap labels){
- double[] x = mds.getCoordinate(0);
- double[] y = mds.getCoordinate(1);
- double[] z = mds.getCoordinate(2);
-
- double max = 0d;
- for(int i = 0; i < x.length; i++){
- if(max < Math.abs(x[i])) max = Math.abs(x[i]);
- }
- for(int i = 0; i < y.length; i++){
- if(max < Math.abs(y[i])) max = Math.abs(y[i]);
- }
- for(int i = 0; i < z.length; i++){
- if(max < Math.abs(z[i])) max = Math.abs(z[i]);
- }
-
- int w = getWidth();
- int h = getHeight();
-
- int ww = w - 20;
- int hh = h - 20;
- DrawerFactory factory = DrawerFactory.getInstance();
- GeometoryType[] types = GeometoryType.values();
- ActionListener clickedListener = new ActionListener(){
- public void actionPerformed(ActionEvent e){
- fireEvent((PointComponent)e.getSource());
- }
- };
-
- for(int i = 0; i < x.length; i++){
- double[] xy = new double[] { - x[i] / max, - y[i] / max, z[i] / max, };
- double xx = xy[0] * ww / 2 + (w / 2);
- double yy = xy[1] * hh / 2 + (h / 2);
- String label = String.valueOf(i);
- if(labels != null && labels.isAvailableLabel(i)){
- label = labels.getLabel(i);
- }
- Coordinate coordinate = new Coordinate(label, xy[0], xy[1], xy[2]);
- if(labels != null && labels.isGroupEnabled()){
- coordinate.setGroupId(labels.getGroupIdFromElementName(coordinate.getLabel()));
- }
- plots.add(coordinate);
-
- PointComponent p = new PointComponent(
- label, x[i], y[i], factory.create(types[coordinate.getGroupId()])
- );
- p.addActionListener(clickedListener);
- add(p, POINT_LAYER);
- JLabel l = new JLabel(coordinate.getShowName());
- add(l, LABEL_LAYER);
- p.setShowLabel(l);
-
- Dimension size = p.getSize();
- p.setLocation(
- new Point((int)(xx - (size.getWidth() / 2d)), (int)(yy - (size.getHeight() / 2d)))
- );
- points.add(p);
-
- l.setSize(l.getPreferredSize());
- Point pcp = p.getLocation();
- Dimension dsize = l.getSize();
- l.setLocation(new Point(pcp.x - (dsize.width / 2), pcp.y - 15));
- l.setVisible(isShowLabel());
- }
- }
-
- private void updatePointComponents(Dimension d){
- int index = 0;
- double width = d.getWidth();
- double height = d.getHeight();
- if(isSameAspect()){
- if(width < height) height = width;
- else width = height;
- }
-
- for(PointComponent pc: points){
- updateLocation(pc, plots.get(index), width, height, d);
- JLabel label = pc.getShowLabel();
- Point pcp = pc.getLocation();
- Dimension dsize = label.getSize();
- label.setLocation(new Point(pcp.x - (dsize.width / 2), pcp.y - 15));
- label.setVisible(isShowLabel());
- index++;
- }
- }
-
- private void updateLocation(PointComponent c, Coordinate coordinate, double width, double height, Dimension d){
- double xx = coordinate.getX() * (width - 20d) / 2d + (d.getWidth() / 2d);
- double yy = coordinate.getY() * (height - 20d) / 2d + (d.getHeight() / 2d);
- Dimension size = c.getSize();
- c.setLocation(
- new Point((int)(xx - (size.getWidth() / 2d)), (int)(yy - (size.getHeight() / 2)))
- );
- }
-
- public static void main(String[] args) throws Exception{
- MDSMethod mds;
- LabelMap labels = new LabelMap(new String[] {
- "Atlanta", "Chicago", "Denver", "Houston", "Los Angeles", "Miami",
- "New York", "San Francisco", "Seattle", "Washington D.C.",
- });
- Matrix matrix = new Matrix(new double[][]{
- { 0, 587, 1212, 701, 1936, 604, 748, 2139, 2182, 543, },
- { 587, 0, 920, 940, 1745, 1188, 713, 1858, 1737, 597, },
- { 1212, 920, 0, 879, 831, 1726, 1631, 949, 1021, 1494, },
- { 701, 940, 879, 0, 1374, 968, 1420, 1645, 1891, 1220, },
- { 1936, 1745, 831, 1374, 0, 2339, 2451, 347, 959, 2300, },
- { 604, 1188, 1726, 968, 2339, 0, 1092, 2592, 2734, 923, },
- { 748, 713, 1631, 1420, 2451, 1092, 0, 2571, 2408, 205, },
- { 2139, 1858, 949, 1645, 347, 2594, 2571, 0, 678, 2442, },
- { 2182, 1737, 1021, 1891, 959, 2734, 2408, 678, 0, 2329, },
- { 543, 597, 1494, 1220, 2300, 923, 205, 2442, 2329, 0, },
- });
- mds = new MDSMethod(matrix);
-
- mds.getCoordinateMatrix().print(8, 4);
- MDSGraphViewer viewer = new MDSGraphViewer(new Messages("resources.messages"), mds, labels);
- viewer.setShowLabel(true);
- JFrame f = new JFrame();
- f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
- f.getContentPane().add(viewer, BorderLayout.CENTER);
- f.pack();
- f.setVisible(true);
- }
-}
+++ /dev/null
-package jp.sourceforge.stigmata.ui.swing.mds;
-
-/*
- * $Id$
- */
-
-import Jama.EigenvalueDecomposition;
-import Jama.Matrix;
-
-/**
- * @author Haruaki TAMADA
- * @version $Revision$ $Date$
- */
-public class MDSMethod{
- private Matrix target;
- private Matrix coordinate;
- private Matrix eigenValues;
- private Matrix eigenVectors;
- private int[] indexes;
-
- public MDSMethod(Matrix matrix){
- this.target = matrix;
- }
-
- protected Matrix getCenteredInnerProductMatrix(){
- Matrix centering = getCenteringMatrix(target.getColumnDimension());
- Matrix trans = centering.transpose();
-
- return centering.times(target).times(trans).times(-1);
- }
-
- public Matrix getEigenValues(){
- if(eigenValues == null){
- getCoordinateMatrix();
- }
- return (Matrix)eigenValues.clone();
- }
-
- public Matrix getEigenVectors(){
- if(eigenVectors == null){
- getCoordinateMatrix();
- }
- return (Matrix)eigenVectors.clone();
- }
-
- public double[] getCoordinate(int axis){
- if(coordinate == null){
- getCoordinateMatrix();
- }
- double[] v = new double[coordinate.getRowDimension()];
- for(int i = 0; i < v.length; i++){
- v[i] = coordinate.get(i, indexes[axis]);
- }
- return v;
- }
-
- public Matrix getCoordinateMatrix(){
- if(coordinate == null){
- Matrix mat = getCenteredInnerProductMatrix();
- EigenvalueDecomposition eigen = mat.eig();
- Matrix eigenVectors = eigen.getV();
- Matrix eigenValues = eigen.getD();
- Matrix coordinate = (Matrix)eigenVectors.clone();
-
- int col = mat.getColumnDimension();
- int row = mat.getRowDimension();
- for(int i = 0; i < row; i++){
- for(int j = 0; j < col; j++){
- double v = coordinate.get(i, j);
- v = v * Math.sqrt(eigenValues.get(j, j));
- coordinate.set(i, j, v);
- }
- }
- sortValues(eigenValues);
- this.coordinate = coordinate;
- this.eigenVectors = eigenVectors;
- this.eigenValues = eigenValues;
- }
-
- return coordinate;
- }
-
- protected static Matrix getCenteringMatrix(int n){
- Matrix matrix = Matrix.identity(n, n);
-
- for(int i = 0; i < n; i++){
- for(int j = 0; j < n; j++){
- matrix.set(i, j, matrix.get(i, j) - (1d / n));
- }
- }
- return matrix;
- }
-
- private void sortValues(Matrix m){
- double[] v = new double[m.getColumnDimension()];
- int[] index = new int[v.length];
- for(int i = 0; i < v.length; i++){
- v[i] = m.get(i, i);
- index[i] = i;
- }
-
- for(int i = 0; i < v.length; i++){
- for(int j = i + 1; j < v.length; j++){
- if(Math.abs(v[i]) < Math.abs(v[j])){
- double tmpValue = v[j];
- v[j] = v[i];
- v[i] = tmpValue;
- int tmpIndex = index[j];
- index[j] = index[i];
- index[i] = tmpIndex;
- }
- }
- }
-
- indexes = index;
- }
-}
/**
* @author Haruaki TAMADA
- * @version $Revision$ $Date$
+ * @version $Revision$
*/
-public class MDSImageExporter implements BinaryDataWritable{
+public class MdsImageExporter implements BinaryDataWritable{
private MdsPane viewer;
- public MDSImageExporter(MdsPane viewer){
+ public MdsImageExporter(MdsPane viewer){
this.viewer = viewer;
}
import java.io.IOException;
import java.io.PrintWriter;
-import java.util.Iterator;
import jp.sourceforge.stigmata.ui.swing.UnsupportedFormatException;
import jp.sourceforge.stigmata.utils.AsciiDataWritable;
+import jp.sourceforge.talisman.mds.Item;
+import jp.sourceforge.talisman.mds.ui.swing.MdsPane;
/**
*
* @author Haruaki TAMADA
* @version $Revision$
*/
-public class MDSPointsLocationExporter implements AsciiDataWritable{
- private MDSGraphViewer viewer;
+public class MdsItemsLocationExporter implements AsciiDataWritable{
+ private MdsPane viewer;
- public MDSPointsLocationExporter(MDSGraphViewer viewer){
+ public MdsItemsLocationExporter(MdsPane viewer){
this.viewer = viewer;
}
if(!format.equals("csv")){
throw new UnsupportedFormatException(viewer.getMessages().format("error.unsupportedformat", format));
}
- for(Iterator<Coordinate> i = viewer.coordinates(); i.hasNext(); ){
- Coordinate c = i.next();
- out.printf("%s,%s,%g,%g%n", c.getLabel(), c.getGroupId(), c.getX(), c.getY());
+ for(Item item: viewer.getItems()){
+ out.printf("%s,%s,%g,%g%n", item.getName(), item.getGroupId(), item.get(0), item.get(1));
}
}
--- /dev/null
+package jp.sourceforge.stigmata.ui.swing.mds;
+
+/*
+ * $Id$
+ */
+
+import java.awt.BorderLayout;
+import java.awt.Dimension;
+import java.awt.FlowLayout;
+import java.awt.GridLayout;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.ComponentAdapter;
+import java.awt.event.ComponentEvent;
+import java.net.URL;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.swing.Action;
+import javax.swing.Box;
+import javax.swing.JButton;
+import javax.swing.JCheckBox;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JTextField;
+import javax.swing.JToolBar;
+
+import jp.sourceforge.stigmata.BirthmarkContext;
+import jp.sourceforge.stigmata.BirthmarkEnvironment;
+import jp.sourceforge.stigmata.BirthmarkSet;
+import jp.sourceforge.stigmata.ComparisonPair;
+import jp.sourceforge.stigmata.ui.swing.GUIUtility;
+import jp.sourceforge.stigmata.ui.swing.PopupButton;
+import jp.sourceforge.stigmata.ui.swing.StigmataFrame;
+import jp.sourceforge.stigmata.ui.swing.actions.SaveAction;
+import jp.sourceforge.talisman.i18n.MessageManager;
+import jp.sourceforge.talisman.i18n.Messages;
+import jp.sourceforge.talisman.i18n.ResourceNotFoundException;
+import jp.sourceforge.talisman.mds.Item;
+import jp.sourceforge.talisman.mds.MdsMethod;
+import jp.sourceforge.talisman.mds.Table;
+import jp.sourceforge.talisman.mds.ui.MdsGraphSetting;
+import jp.sourceforge.talisman.mds.ui.swing.MdsPane;
+import jp.sourceforge.talisman.mds.ui.swing.actions.AntiClockwiseRotateAction;
+import jp.sourceforge.talisman.mds.ui.swing.actions.ClearAction;
+import jp.sourceforge.talisman.mds.ui.swing.actions.ClockwiseRotateAction;
+import jp.sourceforge.talisman.mds.ui.swing.actions.ClusteringAction;
+import jp.sourceforge.talisman.mds.ui.swing.actions.HorizontalFlipAction;
+import jp.sourceforge.talisman.mds.ui.swing.actions.VerticalFlipAction;
+import jp.sourceforge.talisman.mds.ui.swing.actions.ZoomEnabler;
+import jp.sourceforge.talisman.mds.ui.swing.actions.ZoomInAction;
+import jp.sourceforge.talisman.mds.ui.swing.actions.ZoomOutAction;
+
+/**
+ *
+ * @author Haruaki TAMADA
+ * @version $Revision$ $Date$
+ */
+public class MdsViewerPane extends JPanel implements ZoomEnabler,
+ MessageManager{
+ private static final long serialVersionUID = -7256554014379112897L;
+ private static final int[] ZOOM_PATTERN = { 30, 40, 50, 75, 100, 125, 150,
+ 200, 300, 400, };
+
+ private StigmataFrame stigmata;
+ private BirthmarkSet[] set;
+ private BirthmarkContext context;
+ private MdsPane mdspane;
+ private MdsGraphSetting setting;
+
+ private int currentZoomPattern = 4;
+ private boolean userInputtedValue = false;
+ private JTextField zoomRatio;
+ private ZoomInAction zoomin;
+ private ZoomOutAction zoomout;
+
+ public MdsViewerPane(StigmataFrame stigmata, BirthmarkSet[] set, BirthmarkContext context){
+ this.stigmata = stigmata;
+ this.context = context;
+ this.set = set;
+
+ try{
+ initLayouts();
+
+ setGroups();
+ } catch(ResourceNotFoundException e){
+ e.printStackTrace();
+ throw new InternalError(e.getMessage());
+ }
+ }
+
+ public void zoomIn(){
+ currentZoomPattern++;
+ userInputtedValue = false;
+ zoom(ZOOM_PATTERN[currentZoomPattern]);
+ }
+
+ public void zoomOut(){
+ if(!userInputtedValue){
+ currentZoomPattern--;
+ }
+ userInputtedValue = false;
+ zoom(ZOOM_PATTERN[currentZoomPattern]);
+ }
+
+ public void zoom(int ratio){
+ for(int i = 0; i < ZOOM_PATTERN.length; i++){
+ if(ratio <= ZOOM_PATTERN[i]){
+ currentZoomPattern = i;
+ break;
+ }
+ }
+ if(userInputtedValue && ratio < ZOOM_PATTERN[0]){
+ currentZoomPattern = -1;
+ }
+ if(userInputtedValue && ratio > ZOOM_PATTERN[ZOOM_PATTERN.length - 1]){
+ currentZoomPattern = ZOOM_PATTERN.length - 1;
+ }
+ zoomin.setEnabled(currentZoomPattern < (ZOOM_PATTERN.length - 1));
+ zoomout.setEnabled(currentZoomPattern != 0);
+
+ zoomRatio.setText(ratio + " %");
+ mdspane.setZoomRatio(ratio);
+ }
+
+ public Messages getMessages(){
+ return stigmata.getMessages();
+ }
+
+ private Table<String> initData(BirthmarkSet[] set, BirthmarkContext context){
+ Table<String> table = new Table<String>();
+
+ for(int i = 0; i < set.length; i++){
+ for(int j = 0; j <= i; j++){
+ ComparisonPair pair = new ComparisonPair(set[i], set[j],
+ context);
+ table.addValue(set[i].getName(), set[j].getName(), 1d - pair
+ .calculateSimilarity());
+ }
+ }
+ return table;
+ }
+
+ private String getGroupName(URL location){
+ String url = location.toString();
+ if(url.startsWith("jar:")){
+ url = url.substring("jar:".length(), url.lastIndexOf('!'));
+ }
+ return url;
+ }
+
+ private void setGroups(){
+ Item[] items = mdspane.getItems();
+ Map<String, BirthmarkSet> map = new HashMap<String, BirthmarkSet>();
+ Map<String, Integer> groupMap = new HashMap<String, Integer>();
+ for(BirthmarkSet s: set) map.put(s.getName(), s);
+
+ for(Item item: items){
+ BirthmarkSet s = map.get(item.getName());
+ int groupId = 0;
+ if(s != null){
+ String groupName = getGroupName(s.getLocation());
+ Integer i = groupMap.get(groupName);
+ if(i == null){
+ i = groupMap.size() + 1;
+ groupMap.put(groupName, i);
+ }
+ groupId = i;
+ }
+ item.setGroupId(groupId);
+ }
+ }
+
+ /**
+ * This method must called after
+ * {@link #initData(BirthmarkSet[], BirthmarkEnvironment) <code>initData</code>}.
+ * Because this method uses calculated value in initData method.
+ */
+ private void initLayouts() throws ResourceNotFoundException{
+ Table<String> table = initData(set, context);
+
+ final Messages messages = stigmata.getMessages();
+ setting = new MdsGraphSetting();
+ mdspane = new MdsPane(new MdsMethod<String>(table), setting, messages);
+ setting.setShowLabels(true);
+
+ JCheckBox check = new JCheckBox(stigmata.getMessages().get("showlabel.button.label"), true);
+ check.addActionListener(new ActionListener(){
+ public void actionPerformed(ActionEvent e){
+ JCheckBox c = (JCheckBox)e.getSource();
+ setting.setShowLabels(c.isSelected());
+ }
+ });
+ Action openSelection = new OpenItemsAction(mdspane, this);
+
+ Action clusteringAction = new ClusteringAction(mdspane);
+
+ SaveAction exportMdsImageAction = new SaveAction(stigmata,
+ new MdsImageExporter(mdspane));
+ exportMdsImageAction.setExtensions(stigmata.getMessages().getArray(
+ "savemds.extensions"));
+ exportMdsImageAction.setDescrpition(stigmata.getMessages().get(
+ "savemds.description"));
+
+ SaveAction exportItemsAction = new SaveAction(stigmata, new MdsItemsLocationExporter(mdspane));
+ exportItemsAction.setExtensions(stigmata.getMessages().getArray("savelocation.extensions"));
+ exportItemsAction.setDescrpition(stigmata.getMessages().get("savelocation.description"));
+
+ PopupButton saveButton = new PopupButton(GUIUtility.createButton(messages, "savemds", exportMdsImageAction));
+ saveButton.addMenuItem(GUIUtility.createJMenuItem(messages, "savelocation", exportItemsAction));
+
+ JLabel numberOfDotsLabel = new JLabel(String.valueOf(set.length));
+ GUIUtility.decorateJComponent(messages, numberOfDotsLabel, "mdsgraph.count");
+
+ zoomRatio = new JTextField("100%", 5);
+ GUIUtility.decorateJComponent(messages, zoomRatio, "mdszoomratio");
+ zoomRatio.setColumns(5);
+ zoomRatio.addActionListener(new ActionListener(){
+ public void actionPerformed(ActionEvent e){
+ try{
+ String label = zoomRatio.getText();
+ if(label.endsWith("%")){
+ label = label.substring(0, label.lastIndexOf('%'));
+ }
+ label = label.trim();
+ int ratio = Integer.parseInt(label);
+ userInputtedValue = true;
+ zoom(ratio);
+ } catch(NumberFormatException exception){
+ zoomRatio.setText(mdspane.getZoomRatio() + " %");
+ }
+ }
+ });
+
+ JToolBar toolbar = new JToolBar();
+ toolbar.add(new ClockwiseRotateAction(mdspane));
+ toolbar.add(new AntiClockwiseRotateAction(mdspane));
+ toolbar.add(new HorizontalFlipAction(mdspane));
+ toolbar.add(new VerticalFlipAction(mdspane));
+ toolbar.add(zoomin = new ZoomInAction(this, this));
+ toolbar.add(zoomout = new ZoomOutAction(this, this));
+ toolbar.add(new ClearAction(mdspane));
+
+ JPanel south1 = new JPanel(new GridLayout(1, 2));
+ south1.add(numberOfDotsLabel);
+ south1.add(zoomRatio);
+
+ Box south2 = Box.createHorizontalBox();
+ south2.add(Box.createHorizontalGlue());
+ south2.add(saveButton);
+ south2.add(Box.createHorizontalGlue());
+ south2.add(new JButton(openSelection));
+ south2.add(Box.createHorizontalGlue());
+ south2.add(new JButton(clusteringAction));
+ south2.add(Box.createHorizontalGlue());
+ south2.add(check);
+ south2.add(Box.createHorizontalGlue());
+
+ JPanel south = new JPanel(new GridLayout(2, 1));
+ south.add(south1);
+ south.add(south2);
+
+ JPanel center = new JPanel(new FlowLayout(FlowLayout.CENTER));
+ center.addComponentListener(new ComponentAdapter(){
+ @Override
+ public void componentResized(ComponentEvent e){
+ Dimension d = e.getComponent().getSize();
+ mdspane.setSize(d.width - 10, d.height - 10);
+ }
+ });
+ setLayout(new BorderLayout());
+
+ center.add(mdspane);
+ JScrollPane scroll = new JScrollPane(center);
+ scroll.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
+ scroll.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
+
+ add(toolbar, BorderLayout.NORTH);
+ add(scroll, BorderLayout.CENTER);
+ add(south, BorderLayout.SOUTH);
+ }
+}
\ No newline at end of file
--- /dev/null
+package jp.sourceforge.stigmata.ui.swing.mds;
+
+/*
+ * $Id$
+ */
+
+import java.awt.event.ActionEvent;
+
+import javax.swing.AbstractAction;
+import javax.swing.Icon;
+import javax.swing.JOptionPane;
+import javax.swing.JScrollPane;
+import javax.swing.JTable;
+import javax.swing.table.DefaultTableModel;
+
+import jp.sourceforge.talisman.i18n.MessageManager;
+import jp.sourceforge.talisman.mds.Item;
+import jp.sourceforge.talisman.mds.ui.swing.ItemsOpenEvent;
+import jp.sourceforge.talisman.mds.ui.swing.ItemsOpenListener;
+import jp.sourceforge.talisman.mds.ui.swing.ItemsSelectionEvent;
+import jp.sourceforge.talisman.mds.ui.swing.ItemsSelectionListener;
+import jp.sourceforge.talisman.mds.ui.swing.MdsPane;
+
+/**
+ *
+ * @author Haruaki Tamada
+ * @version $Revision$
+ */
+public class OpenItemsAction extends AbstractAction{
+ private static final long serialVersionUID = 5956900396146338537L;
+
+ private MdsPane mdsPane;
+ private MessageManager mm;
+ private boolean selectedItemFlag = false;
+
+ public OpenItemsAction(MdsPane initMdsPane, MessageManager initMm){
+ super(initMm.getMessages().get("openallitems.label"));
+
+ this.mdsPane = initMdsPane;
+ this.mm = initMm;
+ if(initMm.getMessages().hasValue("openitems.icon")){
+ Icon icon = initMm.getMessages().getIcon("openitems.icon");
+ putValue(SMALL_ICON, icon);
+ }
+ initMdsPane.addItemsSelectionListener(new ItemsSelectionListener(){
+ public void valueChanged(ItemsSelectionEvent e){
+ Item[] items = mdsPane.getSelectedItems();
+ selectedItemFlag = items.length != 0;
+ if(selectedItemFlag){
+ putValue(AbstractAction.NAME, mm.getMessages().get("openitems.label"));
+ }
+ else{
+ putValue(AbstractAction.NAME, mm.getMessages().get("openallitems.label"));
+ }
+ }
+ });
+ initMdsPane.addItemsOpenListener(new ItemsOpenListener(){
+ public void itemOpened(ItemsOpenEvent e){
+ showItems(e.getItems());
+ }
+ });
+ }
+
+ @Override
+ public void actionPerformed(ActionEvent e){
+ Item[] items;
+ if(selectedItemFlag){
+ items = mdsPane.getSelectedItems();
+ }
+ else{
+ items = mdsPane.getItems();
+ }
+ showItems(items);
+ }
+
+ private void showItems(Item[] items){
+ DefaultTableModel model = new DefaultTableModel();
+ model.addColumn(mm.getMessages().get("openitems.namelabel"));
+ model.addColumn(mm.getMessages().get("openitems.xlabel"));
+ model.addColumn(mm.getMessages().get("openitems.ylabel"));
+
+ for(Item item : items){
+ Object[] values = new Object[3];
+ values[0] = item.getName();
+ values[1] = item.get(0);
+ values[2] = item.get(1);
+ model.addRow(values);
+ }
+ JTable table = new JTable(model);
+ JScrollPane scroll = new JScrollPane(
+ table, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
+ JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS
+ );
+
+ JOptionPane.showMessageDialog(
+ mdsPane, scroll, mm.getMessages().get("selected.items.title"),
+ JOptionPane.INFORMATION_MESSAGE
+ );
+ }
+}
# $Id$\r
-# $Revision$ $Date$\r
+# $Revision$\r
\r
stigmata.version=${pom.version}\r
\r
savelocation.extensions=csv\r
savelocation.description=Save coordinates (csv)\r
\r
+openitems.label=Show Selected Items...\r
+openallitems.label=Show All Items...\r
+openitems.icon=\r
+openitems.namelabel=Name\r
+openitems.xlabel=X\r
+openitems.ylabel=Y\r
+\r
updatecolor.label=Update color...\r
updatecolor.tooltip=Update color\r
updatecolor.button.label=${updatecolor.label}\r
\r
mdsgraph.count.border=The number of dots\r
mdsgraph.group.border=The number of each marks\r
+mdszoomratio.border=Zoom Ratio\r
\r
################################################\r
# graph pane\r
rank_4.label=Similarity: (0.6, 0.8]\r
rank_5.label=Similarity: (0.8, 1.0]\r
\r
+\r
+#### talisman.mds package\r
+icon.path=${icon.directory}\r
+\r
+horizontal.flip.icon=${icon.path}shape_flip_horizontal.png\r
+vertical.flip.icon=${icon.path}shape_flip_vertical.png\r
+zoom.in.icon=${icon.path}zoom_in.png\r
+zoom.out.icon=${icon.path}zoom_out.png\r
+rotate.clockwise.icon=${icon.path}shape_rotate_clockwise.png\r
+rotate.anticlockwise.icon=${icon.path}shape_rotate_anticlockwise.png\r
+\r
+rotate.clockwise.tooltip=Rotate Clockwise\r
+horizontal.flip.tooltip=Horizontal Flip\r
+vertical.flip.tooltip=Vertical Flip\r
+zoom.in.tooltip=Zoom in\r
+zoom.out.tooltip=Zoom out\r
+rotate.anticlockwise.tooltip=Rotate Anti-clockwise\r
+clear.tooltip=Clear\r
+\r
+horizontal.flip.label=Horizontal flip\r
+vertical.flip.label=Vertical flip\r
+zoom.in.label=Zoom in\r
+zoom.out.label=Zoom out\r
+rotate.clockwise.label=Rotate clockwise\r
+rotate.anticlockwise.label=Rotate anti-clockwise\r
+clear.label=Clear\r
+\r
+clustering.label=Clustering...\r
+clustering.tooltip=Clustering Items\r
+clustering.setting.title=Clustering settings\r
+clustering.cluster.size=Cluster size\r
+itemdistancecalculator.label=Item distance calculator\r
+ida.label.CITY_BLOCK_DISTANCE=City Block distance\r
+ida.label.DOMINANCE_METRIC=Dominance metric\r
+ida.label.MINKOWSKY_DISTANCE=Minkowsky distance\r
+ida.label.NORMALIZED_EUCLIDEAN_DISTANCE=Normalized Euclidean distance\r
+ida.label.SQUARED_EUCLIDEAN_DISTANCE=Squared Euclidean distance\r
+\r
+clusterdistancecalculator.label=Cluster distance calculator\r
+cda.label.CENTROID_METHOD=Centroid method\r
+cda.label.FURTHEST_NEIGHBOR_METHOD=Furthest neighbor method\r
+cda.label.NEAREST_NEIGHBOR_METHOD=Nearest neighbor method\r
+cda.label.GROUP_AVERAGE_METHOD=Group average method\r
+cda.label.WARDS_METHOD=Wards method\r
+\r
+clusteringalgorithm.label=Clustering algorithm\r
+ca.label.PARALLEL_HCM=Parallel Hard c-Mean\r
+ca.label.SEQUENTIAL_HCM=Sequential Hard c-Mean\r
+ca.label.EXCHANGE_METHOD=Exchange Method\r
+ca.label.HIERARCHICAL_METHOD=Hierarchical Method\r
+ca.label.LANCE_AND_WILLIAMS_METHOD=LW Method (Lance and Williams Method)\r
+\r
+show.relation.title=Relation data\r
+\r
+show.relation.label=Show relation data...\r
+show.relation.tooltip=\r
+show.coordinates.label=Show items...\r
+\r
+show.coordinates.title=Items\r
+show.coordinate.xaxis.label=X\r
+show.coordinate.rank.label=Rank\r
+\r
+show.labels.label=Show labels\r
+store.image.label=Store image...\r
+store.coordinates.label=Store items...\r
+\r
+selected.coordinates.title=Selected items\r
+\r
+show.error.io.message=I/O error\r
+show.error.dialog.title=Error\r
+\r
+show.coordinate.rawstress.label=Raw stress\r
+show.coordinate.normalizedstress.label=Normalized stress\r
+\r
+title.illegal.argument=Illegal Argument\r