/*
* ListRandomLayout.java
*
* Created on August 6, 2008, 1:37 PM
*
* Copyright 2003-2010 Tufts University Licensed under the
* Educational Community License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License. You may
* obtain a copy of the License at
*
* http://www.osedu.org/licenses/ECL-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an "AS IS"
* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/
/**
*
* @author akumar03
*/
package edu.tufts.vue.layout;
import java.io.*;
import java.net.*;
import java.util.*;
import java.util.List;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import tufts.vue.*;
import tufts.vue.ds.DataAction;
import tufts.vue.ds.XmlDataSource;
import edu.tufts.vue.metadata.MetadataList;
import edu.tufts.vue.metadata.VueMetadataElement;
import edu.tufts.vue.dataset.*;
/* ListRandomLaout - This layout scatters all the nodes at random in a square
* by default the area of the square is propotional to the number of nodes in
* selection.
*/
public class ListRandomLayout extends Layout {
public static String DEFAULT_METADATA_LABEL = "default";
public static final double FACTOR = 1.5;
public static final int MAX_COLLISION_CHECK = 20; // check number of times to check for collisions
/** Creates a new instance of ListRandomLayout */
public ListRandomLayout() {
}
public LWMap createMap(Dataset ds, String mapName) throws Exception {
Map<String, LWNode> nodeMap = new HashMap<String, LWNode>();
Map<String, Integer> repeatMap = new HashMap<String, Integer>();
LWMap map = new LWMap(mapName);
XmlDataSource datasource = new XmlDataSource(mapName,ds.getFileName());
Properties props = new Properties();
props.put("displayName", mapName);
props.put("name", mapName);
props.put("address", ds.getFileName());
datasource.setConfiguration(props);
VUE.getContentDock().setVisible(true);
VUE.getContentPanel().showDatasetsTab();
DataSetViewer.getDataSetList().addOrdered(datasource);
VUE.getContentPanel().getDSBrowser().getDataSetViewer().setActiveDataSource(datasource);
DataSourceViewer.saveDataSourceViewer();
List<LWComponent> nodes = DataAction.makeRowNodes(datasource.getSchema());
for(LWComponent component: nodes) {
map.add(component);
}
LayoutAction.random.act(new LWSelection(nodes));
return map;
}
/** It takes a map and scatters the nodes randomly
* @param map the map for layout
*/
public void layout(LWMap map) {
Iterator<LWNode> nodeIterator = map.getChildIterator();
while (nodeIterator.hasNext()) {
LWNode node = nodeIterator.next();
node.setLocation(MAP_SIZE * Math.random(), MAP_SIZE * Math.random());
}
}
public void layout(java.util.List<LWNode> nodeList) {
for (LWNode node : nodeList) {
node.setLocation(MAP_SIZE * Math.random(), MAP_SIZE * Math.random());
}
}
public void layout(LWSelection selection) {
// determine the left corner of the selection and and use that as the
// center for layout. We assume the selection is a rectangle.
// also compute the total number of nodes in the selection
double minX = Double.POSITIVE_INFINITY;
double minY = Double.POSITIVE_INFINITY;
double maxX = Double.NEGATIVE_INFINITY;
double maxY = Double.NEGATIVE_INFINITY;
double xAdd = X_COL_SIZE; // default horizontal distance between the nodes
double yAdd = Y_COL_SIZE; //default vertica
int total = 0;
Iterator<LWComponent> i = selection.iterator();
while (i.hasNext()) {
LWComponent c = i.next();
if (c instanceof LWNode) {
LWNode node = (LWNode) c;
minX = node.getLocation().getX() < minX ? node.getLocation().getX() : minX;
minY = node.getLocation().getY() < minY ? node.getLocation().getY() : minY;
maxX = node.getLocation().getX() > maxX ? node.getLocation().getX() : maxX;
maxY = node.getLocation().getY() > maxY ? node.getLocation().getY() : maxY;
xAdd = xAdd > node.getWidth() ? xAdd : node.getWidth();
yAdd = yAdd > node.getHeight() ? yAdd : node.getHeight();
total++;
}
}
double xSize = Math.sqrt(total) * (xAdd + X_SPACING) * FACTOR;
double ySize = Math.sqrt(total) * (yAdd + Y_SPACING) * FACTOR;
i = selection.iterator();
while (i.hasNext()) {
LWComponent c = i.next();
if (c instanceof LWNode) {
LWNode node = (LWNode) c;
double centerX = (minX + maxX) / 2;
double centerY = (minY + maxY) / 2;
double x = centerX + xSize * (Math.random() - 0.5);
double y = centerY + ySize * (Math.random() - 0.5);
int col_count = 0;
boolean flag = true;
while (flag && col_count < MAX_COLLISION_CHECK) {
LWComponent overlapComponent;
if(VUE.getActiveViewer() != null) {
if ((VUE.getActiveViewer().pickNode((float) x, (float) y) != null) || (VUE.getActiveViewer().pickNode((float) x + node.getWidth(), (float) y + node.getHeight()) != null) || (VUE.getActiveViewer().pickNode((float) x, (float) y + node.getHeight()) != null) || (VUE.getActiveViewer().pickNode((float) x + node.getWidth(), (float) y) != null)) {
x = centerX + xSize * (Math.random() - 0.5);
y = centerY + ySize * (Math.random() - 0.5);
} else {
flag = false;
}
}
col_count++;
// System.out.println("Node: "+node.getLabel()+" count:"+col_count);
}
node.setLocation(x, y);
}
}
}
}