package ch.akuhn.org.ggobi.plugins.ggvis; import org.eclipse.swt.SWT; import org.eclipse.swt.events.PaintEvent; import org.eclipse.swt.events.PaintListener; import org.eclipse.swt.graphics.Device; import org.eclipse.swt.graphics.GC; import org.eclipse.swt.widgets.Canvas; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell; import ch.akuhn.mds.MultidimensionalScaling.MultidimensionalScalingListener; public class Viz implements PaintListener, MultidimensionalScalingListener { private int zoom = 100; public Mds mds; private double[][] edges; public Viz open() { new Thread(new Runnable() { @Override public void run() { final int ms = 1000 / 50; final Display display = new Display(); final Shell shell = new Shell(display, SWT.SHELL_TRIM & ~SWT.RESIZE); final Canvas canvas = new Canvas(shell, SWT.DOUBLE_BUFFERED); canvas.addPaintListener(Viz.this); canvas.setSize(512, 512); shell.setText("MDS"); shell.pack(); shell.open(); display.timerExec(ms , new Runnable() { @Override public void run() { if (shell.isDisposed()) return; canvas.redraw(); display.timerExec(ms, this); } }); while (!shell.isDisposed()) { if (!display.readAndDispatch()) display.sleep(); } display.dispose(); System.exit(-1); } }).start(); return this; } @Override public void paintControl(PaintEvent e) { if (mds == null) return; Device device = e.gc.getDevice(); e.gc.setAntialias(SWT.ON); e.gc.setAlpha(128); e.gc.drawOval(256-zoom, 256-zoom, zoom*2, zoom*2); final double[][] pps = mds.points(); if (pps == null) return; for (int i = 0; i < pps[0].length; i++) { int x = (int) (pps[0][i] * zoom + 256); int y = (int) (pps[1][i] * zoom + 256); e.gc.drawLine(x - 2, y - 2, x + 2, y + 2); e.gc.drawLine(x - 2, y + 2, x + 2, y - 2); } e.gc.setForeground(device.getSystemColor(SWT.COLOR_RED)); drawEdges(e.gc); e.gc.setForeground(device.getSystemColor(SWT.COLOR_BLUE)); drawHistogram(e, mds.config_dist.getHistogram()); e.gc.setForeground(device.getSystemColor(SWT.COLOR_GREEN)); drawHistogram(e, mds.Dtarget.getHistogram()); } private void drawEdges(GC gc) { if (edges == null) return; final double[][] pps = mds.points(); if (pps == null) return; for (int i = 0; i < edges.length; i++) { for (int j = 0; j < edges.length; j++) { if (Double.isInfinite(edges[i][j])) continue; int x0 = (int) (pps[0][i] * zoom + 256); int y0 = (int) (pps[1][i] * zoom + 256); int x = (int) (pps[0][j] * zoom + 256); int y = (int) (pps[1][j] * zoom + 256); gc.drawLine(x0, y0, x, y); } } } private void drawHistogram(PaintEvent e, int[] histo) { int height = 50; for (int n = 0; n < histo.length; n++) { int xa = (512 * Math.max(0, n - 1)) / histo.length; int xb = (512 * n) / histo.length; int ya = 512 - histo[Math.max(0, n - 1)]/height; int yb = 512 - histo[n]/height ; e.gc.drawLine(xa, ya, xb, ya); e.gc.drawLine(xb, ya, xb, yb); } } @Override public void update(Mds mds0) { this.mds = mds0; } public Viz setEdges(double[][] distances) { this.edges = distances; return this; } }