blob: 917ec1d376831ddc366678e623c22f751bf08050 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2009 University of Manchester and Others
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Eleni Michailidou - initial API and implementation
*******************************************************************************/
package org.eclipse.actf.examples.simplevisualizer.vicramtest;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Map;
import org.eclipse.actf.model.dom.dombycom.IElementEx;
import org.eclipse.actf.model.dom.dombycom.INodeEx;
import org.eclipse.actf.model.ui.IModelService;
import org.eclipse.actf.model.ui.editor.browser.ICurrentStyles;
import org.eclipse.actf.model.ui.util.ModelServiceUtils;
import org.eclipse.swt.graphics.Rectangle;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
/*
* Visualization Class:
* Gives a heatmap of the page similar to an eye tracking heatmap. The eye tracking heatmap uses colours to indicates the level
* of attention each area receives based on the number of fixations that each area had. Fixations are the number of times that participants looked
* at that area.
* The visualization code will duplicate these results based on results derived from eye tracking studies.
* Red Areas of most attention: Images
* 2-3 First Items on Menus
* Yellow
* Green
* Gray
*
*
* The visualization code is based on the Complexity.java code. Since it is used to identify the structural elements we will send information from there (:S)
*/
public class Visualization2 {
private static Rectangle rectangle;
private static IModelService modelService;
private static Map<String, ICurrentStyles> styleMap;
private static int[][] newOverlayPixels;
private static boolean flag;
private static int webPageHeight;
private static int webPageWidth;
private static ArrayList<Rectangle> listItems, images, redCoordList,
yellowCoordList, greenCoordList, redCoordImg, yellowCoordImg,
greenCoordImg;
public static int[][] findElements(int[][] overlayPixels,
Rectangle imageSize, boolean flag) {
newOverlayPixels = overlayPixels;
webPageHeight = imageSize.height;
webPageWidth = imageSize.width;
System.out.println("Image Size: Height " + webPageHeight + "width "
+ webPageWidth);
modelService = ModelServiceUtils.getActiveModelService();
// listItems = new Rectangle[];
Document doc = modelService.getDocument();
Document docLive = modelService.getLiveDocument();
listItems = new ArrayList<Rectangle>();
images = new ArrayList<Rectangle>();
redCoordList = new ArrayList<Rectangle>();
yellowCoordList = new ArrayList<Rectangle>();
greenCoordList = new ArrayList<Rectangle>();
redCoordImg = new ArrayList<Rectangle>();
yellowCoordImg = new ArrayList<Rectangle>();
greenCoordImg = new ArrayList<Rectangle>();
if (doc != null || docLive != null) {
// get document element
// identify tag name and node type
// Element docElement = doc.getDocumentElement();
Element docLiveElement = docLive.getDocumentElement();
// call methods that identify the elements that will be highlighted
// for attention
// and calculate final score for VCS and aesthetics
Node node = docLiveElement.getElementsByTagName("body").item(0);
identifyElements(node);
determineColour();
// identifyElements(docElement.getElementsByTagName("body").item(0));
}
return newOverlayPixels;
}
/*
* identifyElements: identifies what the node elements are
* (img/p/lists/menus etc) finds the coordinates of the interested elements
* and assignes them in the appropriate coordinate Array (or Object)
*/
public static void identifyElements(Node node) {
if (node == null)
return;
int type = node.getNodeType();
// System.out.print("Type: " +type + "Name: " + node.getNodeName());
if (type == Node.DOCUMENT_NODE) {
identifyElements(((Document) node).getDocumentElement());
}
if (type == Node.ELEMENT_NODE) {
// checks and counts the type of element
String nodeName = node.getNodeName();
System.out.println("NodeName: " + nodeName);
if (nodeName.equalsIgnoreCase("a")) {
}
if (nodeName.equalsIgnoreCase("p")) {
}
if (nodeName.equalsIgnoreCase("img")) {
// Get the location of the image
if (node instanceof IElementEx) {
// IStyle style = ((IElementEx)node).getStyle();
// TO DO: FIND SIZE OF IMAGE - THE BIGGEST IMAGE GETS THE
// RED COLOR
// THE LOCATION OF THE IMAGE WITH RESPECT TO THE SIZE OF THE
// PAGE MATTERS
/*
* Put the image found in an array and sort it based on its
* width and height size. The image with the largest size
* and if it is located within the top quearter of the page
* is assigned the red color.
*/
rectangle = ((IElementEx) node).getLocation();
System.out.println("Rectangle: " + rectangle);
// highlight on the left for testing purposes
// ((INodeEx) node).highlight();
// colour if the (x2,y2) point of the node is in the top
// half of the page
// check for first quarter since colourNode does not work
// for points on the very right hand side of the page
// int pointX2 = rectangle.width + rectangle.x;
// int pointY2 = rectangle.height + rectangle.y;
if (rectangle.y < (webPageHeight / 2)) { // && pointX2 <
// (webPageWidth/2)){
// if(rectangle.height > 90 && rectangle.width >90){
if (rectangle.height > 5 && rectangle.width > 5) {
images.add(rectangle);
// colourNodes(rectangle,0x3D1AED);
((INodeEx) node).highlight();
}
}
}
// System.out.println("Image Rectangle: "+ rectangle);
}
if (nodeName.equalsIgnoreCase("form")) {
}
if (nodeName.equalsIgnoreCase("table")) {
}
if (nodeName.equalsIgnoreCase("ul")
|| nodeName.equalsIgnoreCase("ol")) {
if (node instanceof IElementEx) {
// IStyle style = ((IElementEx)node).getStyle();
/*
* THE LOCATION OF THE list WITH RESPECT TO THE SIZE OF THE
* PAGE MATTERS -- Y1 point needs to be in the top half of
* the page -- need to find location of the first 3 items of
* the menu which will be coloured
*/
// location of the list
rectangle = ((IElementEx) node).getLocation();
//
/*
* If listItems <=3, then color the whole list node else
* color the first three list items (find location of the
* first three <li> nodes) OR send to colour the first three
* <li> elements
*
* CASE: Multiple lists <ol>/<ul> under the same column
* Solution attempt: to put all list items in an array. Then
* colour the 3 first items with the same x1 (and/or x2)
* point see following method
*/
if (rectangle.y < (webPageHeight / 2)) {
// create array that will put the list items with the
// same X1 point
// recurse to find the number of items of the list
NodeList listChildren = node.getChildNodes();
int nodelistItems = 0;
if (listChildren != null) {
int len = listChildren.getLength();
for (int i = 0; i < len; i++) {
// System.out.println("List Rectangle: "+
// rectangle + " List Items: "+ nodelistItems);
if (listChildren.item(i).getNodeName()
.equalsIgnoreCase("li")) {
nodelistItems++;
rectangle = ((IElementEx) listChildren
.item(i)).getLocation();
int listItemsLen = listItems.size();
System.out.println("length" + listItemsLen);
listItems.add(rectangle);
}
}
}
// test
for (int k = 0; k < listItems.size(); k++)
System.out.println("list item " + k + "- "
+ listItems.get(k));
}
}
}
// recurse to find the rest of the counters
NodeList children = node.getChildNodes();
if (children != null) {
int len = children.getLength();
for (int i = 0; i < len; i++) {
identifyElements(children.item(i));
}
}
}// ends if (type == Node.ELEMENT_NODE)
if (type == Node.TEXT_NODE) {
// where the word count begins
// String string = node.getNodeValue();
// words = " "+ string;
// if (words == null)
// wordCount = 0;
// else
// {
// StringTokenizer total = new StringTokenizer(words,
// "'?!@#$&*/-,:.<>()~;=_");
// int count2 = 0;
// while (total.hasMoreTokens() == true)
// {
// StringTokenizer token = new StringTokenizer(total.nextToken());
// wordCount += token.countTokens();
// }
// }
}// ends if (type == Node.TEXT_NODE)
}
/*
* DetermineColour This method works on the arrays created in
* identifyElements and determines the colour for each of the elements This
* method is called from the main method since need to finish the whole
* page's element identification before colouring For example: listItems[] -
* need to call the first 3 items with the same X point to red colour, then
* 1 with yellow and 1 with green
*/
public static void determineColour() {
/*
* do for images what did for lists (put them in a list and red the two
* with the largest area )
*/
if (images.size() > 0) {
ArrayList<Rectangle> imagesByArea = images;
Collections.sort(imagesByArea, new Comparator<Rectangle>() {
public int compare(Rectangle o1, Rectangle o2) {
if ((o1.width * o1.height) > (o2.width * o2.height)) {
return -1;
} else {
return 1;
}
}
});
// display elements of ArrayList
System.out
.println("ArrayList elements after sorting in descending order of Area : ");
for (int i = 0; i < imagesByArea.size(); i++)
System.out.println(imagesByArea.get(i));
/*
* Need to call the first 3 items to red colour, then 4 with yellow
* and 1 with green
*/
int counter = 0;
for (int i = 0; i < imagesByArea.size(); i++) {
if (counter <= 3) {
redCoordList.add(imagesByArea.get(i));
} else if (counter > 3 && counter <= 6) {
yellowCoordList.add(imagesByArea.get(i));
} else if (counter == 7) {
greenCoordList.add(imagesByArea.get(i));
}
counter++;
}
}
// color Red = 0x3D1AED, the 3 first list items with the same x1
if (listItems.size() > 0) {
/*
* To sort an ArrayList object, use Collection.sort and implement
* Comparator method.
*/
// arrayList by the X coordinate
ArrayList<Rectangle> listItemsByX = listItems;
Collections.sort(listItemsByX, new Comparator<Rectangle>() {
public int compare(Rectangle o1, Rectangle o2) {
if (o1.x <= o2.x) {
return -1;
} else {
return 1;
}
}
});
/*
* TESTING ARRAY Sort
*/
// display elements of ArrayList
System.out
.println("ArrayList elements after sorting in ascending order of Point X : ");
for (int i = 0; i < listItemsByX.size(); i++)
System.out.println(listItemsByX.get(i));
/*
* Need to call the first 3 items with the same X point to red
* colour, then 1 with yellow and 1 with green
*/
int counterX = 0;
int pointX = listItemsByX.get(0).x;
System.out.println("Point X: " + pointX);
// redColour
redCoordList.add(listItemsByX.get(0));
for (int i = 1; i < listItemsByX.size(); i++) {
if (pointX == listItemsByX.get(i).x && counterX < 3) {
redCoordList.add(listItemsByX.get(i));
} else if (pointX == listItemsByX.get(i).x
&& (counterX == 3 || counterX == 4)) {
yellowCoordList.add(listItemsByX.get(i));
} else if (pointX == listItemsByX.get(i).x && counterX == 5) {
greenCoordList.add(listItemsByX.get(i));
} else if (pointX != listItemsByX.get(i).x) {
counterX = 0;
pointX = listItemsByX.get(i).x;
}
counterX++;
}
// do the same for horizontal lists
// arrayList by the Y coordinate - for horizontal menu
ArrayList<Rectangle> listItemsByY = listItems;
Collections.sort(listItemsByY, new Comparator<Rectangle>() {
public int compare(Rectangle o1, Rectangle o2) {
if (o1.y <= o2.y) {
return -1;
} else {
return 1;
}
}
});
int counterY = 0;
int pointY = listItemsByY.get(0).y;
System.out.println("Point Y: " + pointY);
// redColour
redCoordList.add(listItemsByY.get(0));
for (int i = 1; i < listItemsByY.size(); i++) {
if (pointY == listItemsByY.get(i).y && counterY < 3) {
redCoordList.add(listItemsByY.get(i));
} else if (pointY == listItemsByY.get(i).y
&& (counterY == 3 || counterY == 4)) {
yellowCoordList.add(listItemsByY.get(i));
} else if (pointY == listItemsByY.get(i).y && counterY == 5) {
greenCoordList.add(listItemsByY.get(i));
} else if (pointY != listItemsByY.get(i).y) {
counterY = 0;
pointY = listItemsByY.get(i).y;
}
counterY++;
}
/*
* TESTING ARRAY Sort
*/
// System.out.println("ArrayList elements after sorting in ascending order of Point Y : ");
// for(int i=0; i<listItemsByY.size(); i++)
// System.out.println(listItemsByY.get(i));
// End testing
// send to colour
for (int i = 0; i < redCoordList.size(); i++)
colourNodes(redCoordList.get(i), 0x3D1AED);
for (int i = 0; i < yellowCoordList.size(); i++)
colourNodes(yellowCoordList.get(i), 0x00D4FF);
for (int i = 0; i < greenCoordList.size(); i++)
colourNodes(greenCoordList.get(i), 0x008000);
}
}
/*
* Colours the nodes based on the coordinates and colour
*/
public static void colourNodes(Rectangle coordinates, int colour) {
// colour = 0x00D4FF;
int x1 = coordinates.x;
int y1 = coordinates.y;
int x2 = (coordinates.width) + x1;
int y2 = (coordinates.height) + y1;
System.out.println("Coordinates: x1 - " + x1 + ", y1 - " + y1
+ ",x2 - " + x2 + ", y2 - " + y2);
// colour test
/*
* for (int b = 40; b < 400; b++) { for (int a = 50; a < 600; a++) { if
* (flag) { newOverlayPixels[b][a] = colour; } else {
* newOverlayPixels[a][b] = colour; } } }
*/
for (int b = y1; b < (y2); b++) {
for (int a = x1; a < (x2); a++) {
if (flag) {
newOverlayPixels[a][b] = colour;
} else {
newOverlayPixels[b][a] = colour;
}
}
}
}
}