You are on page 1of 154

NAVIZ: A TOOL FOR VISUALIZING THE USER BEHAVIOR OVER WEBSITE

BOWO PRASETYO

A THESIS PRESENTED TO THE GRADUATE SCHOOL OF THE UNIVERSITY OF TOKYO IN PARTIAL FULFILLMENT OF THE REQUIREMENTS FOR THE DEGREE OF MASTER OF INFORMATION SCIENCE AND TECHNOLOGY UNIVERSITY OF TOKYO

SUMMER 2002

ACKNOWLEDGMENTS

I wish to thank Prof. Masaru Kitsuregawa for allowing me to explore my areas of interest and guiding me through this thesis and for his gracious understanding of the various difficulties that punctuated my graduate study. I wish to thank all my friends, Iko Pramudiono, Katsumi Takahashi, Masashi Toyoda and others which I cannot mention one by one, for being there when I needed them. I wish to express my gratitude to the NTT Directory Services Co. for providing me with web access log data of NTT i-Townpage served on i-Mode website, which is used as experiment data in this thesis. I wish to express my gratitude to the Japan Monbu-Kagakusho who granted me with the scholarship during my period of study at the University of Tokyo. I will be eternally indebted to them. Also I wish to thank my parents for their love and patience since my childhood until now and allowing me to learn precious experiences from them. May I can reward their eternal love and affection some time in the future. Last but not least, I wish to thank my beloved wife, Silvia Surini, for her patience and support during my study. Without her nice smile and delicious food I would not be able to finish this thesis.

ii

TABLE OF CONTENTS ACKNOWLEDGMENTS ...ii TABLE OF CONTENTSiii 1. INTRODUCTION..1 A) Importance of Analyzing Website Visitor Behavior.....1 B) Visual Data Analysis as Effective Tool 3 C) Motivation and Purpose of This Thesis5 2. BACKGROUND AND RELATED WORK ..6 A) Web Usage Mining to Discover Behavior Patterns .....6 B) A Mining Technique Generalized Sequential Pattern .....11 C) Visualization Tools of Visitor Behavior .15 3. NAVIZ CONCEPT ...17 A) Appropriate Web Traversal Properties ...18 B) Visitor Behavior in Traversal Diagram ..19 C) Algorithm for Drawing Directed Graphs ...21 4. NAVIZ IMPLEMENTATION...22 A) System Architecture ...22 B) Visualization Features ....27 5. NAVIZ EXPERIMENT 30 A) NTT i-Townpage served on i-Mode ......30 B) Global Visitor Behavior .34 C) Comparison of Visitor Behavior by Time, Place and Category Class ...38 6. CONCLUSION AND FUTURE WORK.54 References ..54 APPENDIX ....Ai

iii

1. INTRODUCTION

This chapter provides an introduction about the motivation behind and purpose of this thesis. It is organized into three sections. The first provides a brief overview of Internet and the importance of studying visitor behavior on a website. Data mining is introduced as a method to study website visitor behavior. Second is a general overview of visual analysis of data, which is needed to analyze data mining results. Third chapter describes the motivation and purpose of this thesis. The chapter ends with an outline of the structure of this thesis.

A) Importance of Analyzing Website Visitor Behavior

Internet or World Wide Web (WWW) is probably the most rapid growing technology of the human society in this century. Just in count of years, it has infiltrated into all aspects of human life such as the ways of doing business by e-commerce, providing and receiving education by online school, managing the organization by intranet etc. And the most direct effect of WWW technology is the complete change of information collection, conveying, and exchange; we can mention it such as email, website, ftp, chat, newsgroup etc. With the rapid progress of WWW technology, and the ever growing popularity of it, today Web has turned to be the largest information source available in the earth. More than 9% of world population or about 581 million people all around the world have now been connecting to the Web, and are growing as rapid as 9 million users per month in the last two years [13]. Popular websites such as NTT Docomo i-Townpage can have hundred of thousand of visitors in a day.

Fig. 1. Visitor behavior on a website In order to enhance website performance and improve system design, webmasters need to find the way to know their visitor behavior on the website. Usually every web server has a mechanism to register a web log entry for every single access they get such as the URL requested, the IP address from which the request originated, and a timestamp. This web log record contains wealth of information about visitors of website and becomes a treasure for webmasters in which they can track visitors browsing behavior down to individual mouse clicks. First attempt to take advantage of web log record is statistical analysis which has been successful in providing webmasters with a set of basic information such as number of requests made, ip-address originated the requests, total files and kilobytes served, totals and averages by specific time periods, URLs from which user came to the site, browsers making the requests, etc. Another way to exploit more information from web log record is by utilizing data mining techniques such as association rule, sequential pattern, and clustering, which recently have been prosperously researched by many people. Applying data mining techniques such as
2

Generalized Sequential Pattern algorithm [1] on a web log record, certain patterns (rules) which are hidden inside and cannot be revealed by statistical method can be discovered. For example: About 30% of visitors on a website exit as soon as they enter the Top page (Fig. 1), Around 2% of visitors reach the Search Result page through the path of Top Region List Result. Knowing such a pattern of visitor behavior is very advantageous for webmasters to improve design and enhance performance of their website. With the rapid progress of WWW technology, and the ever growing popularity of the Web, a huge number of web log record are being collected. Popular websites can have their web log growing by hundreds of megabytes every day. Considering these huge number files of raw web log data, it is a difficult task to retrieve significant and useful pattern of visitor behavior. A common problem with data mining techniques on the web log record is that they resulted in large number of patterns such that it is not suitable for human to analyze directly. Thus in turn, it is needed a tool which can analyze the large number of patterns discovered from web log record easily and effectively. Naviz proposed in this thesis is a tool that is designed for such a purpose by visualizing visitor behavior patterns such that it can be analyzed visually. Prefecture List Local Top Input Form Search

B) Visual Data Analysis as Effective Tool

The data mining process results in a set of patterns of data. While small number of patterns may be understood easily by examine them by hand, large number of patterns

requires more effective way to analyze. Often the most effective way to understand and analyze a set of information is to look at a picture of them (analysis by visual) rather than to investigate their accurate values in a list (analysis by value). Large number of discovered patterns can be effectively analyzed by utilizing visuals which may be traditional statistical images like bar graphs and pie diagrams or innovative custom displays related to the analysis in question. Moreover its combination with the analysis by value technique can be used for maximum understanding of the significance and meaning of the data, such as method implemented by Naviz proposed in this thesis. Visualization of data mining patterns on web log record provided by Naviz also meets requirements of graphical displays proposed by Edward R. Tufte [9], whose works are often considered the standards by which data graphics are judged. He says that graphical displays should: Show the data. Induce the viewer to think about the substance rather than about methodology, graphics design, the technology of graphic production, or something else. Avoid distorting what the data have to say. Present many numbers in small space. Make large data sets coherent. Encourage comparison between data. Supply a broad overview to fine detail. Serve a clear purpose. Be closely integrated with the statistical and verbal descriptions of the data set. On the other hand, construction of effective web log visualization is a challenging task. As stated in works of Mukherjea et. al [2], there are various problems involved:

The navigational views are two or three dimensional projections of generally multidimensional hypermedia networks

Even if such a view is developed, the resulting structure would be very complex for any non trivial hypermedia system

As the size of the underlying information space increases, it becomes very difficult to fit the whole information structure on a screen

And yet the user should be able to get an idea of not only the structure but the actual contents of the nodes and links just by looking at the navigational views.

C) Motivation and Purpose of This Thesis

In the ever growing WWW technology today, website developers, designers, and maintainers are having difficulties to analyze the efficiency of their website. Two of the major problems with current web log analysis are difficulty to understand what visitors are trying to do on a website and how they are doing it. This requires analysis of the visitor navigational behavior on the website, which gives webmasters know how to improve structure of the hyperlinks as well as the content of the documents in the website. Some data mining techniques to discover visitor behavior patterns have been proposed. However due to the large number of discovered patterns, effective method to visualize the results is needed. This thesis proposes Naviz, a website visitor behavior visualization system that can be used interactively to visually present the behavior of a user visiting a website. Its purpose is to provide a visual analysis tool in the area of web usage mining, which can be used to easily and effectively visualize the result from data mining process on a web log file.

The second chapter summarizes the background and academic research in the area of web usage mining with a focus on visualizing web log record of a website. The third chapter describes in detail the visualization concept used in this thesis. Chapter 4 describes the implementation of the Naviz system, also details the steps in a typical usage of the Naviz system. Chapter 5 is dedicated to describe the experiment results that have been conducted on web log file of NTT Docomo Mobile i-Townpage website. The last chapter gives conclusive remarks and outlines the areas of future work and development.

2. BACKGROUND AND RELATED WORK

Applying data mining technique on to the Web data to automatically discover and analyze the useful information from it is called Web mining [10]. Based on what type of web data to be mined, Web mining can be classified into three types: web content mining, web structure mining, and web usage mining. Web content mining tries to mine the data contained in the Web itself such as text contained in the website, result of search engine, etc. Web structure mining focuses on the HTML structure of websites and tries to find relationship patterns of hyperlink structure between websites. Web usage mining uses web log record as target and tries to discover usage patterns of visitors on a website. Web usage mining is particularly of interest for this thesis since it is used to discover visitor behavior from web log file.

A) Web Usage Mining to Discover Behavior Patterns

Web usage mining uses web log record as target to apply data mining technique to and

Fig. 2. Web Usage Mining consists of three distinctive phases: preprocessing, pattern discovery, and pattern analysis. With the assistance of the diagram of the web usage mining process shown in Fig. 2, the architecture of the web usage mining may be understood easily. Before the description of web usage mining process, its necessary to clarify the definitions of the related data abstractions. The following definitions are from the Web characterization terminology & definition sheets draft published by the World Wide Web Committee Web usage characterization activity [12]. User is the principal using a client to interactively retrieve and render resources or resource manifestations. Page view is visual rendering of a web page in a specific client environment at a specific point in time. Click stream is a sequential series of page view request. User session is a delimited set of user clicks (click stream) across one or more web servers. Server session is a collection of user clicks to a single web server during a user session. It is also called a visit. Episode is a subset of related user clicks that occur within a user session. The term Visitor which is used throughout this thesis refers to term User in the above definition.

Table 1. Web log record sorted by user-id and time


# 1 2 3 4 5 6 7 8 9 10 Cookie ed7f4f97ed9a 148d6d74d2ef fd509af20b60 e163befe4685 c032d7df3b4d 4c937d7253da 6b7f0f3ae815 59f3239d100c 5895706e1f15 315a3ffa00c8 User Agent DoCoMo/1.0/N502i DoCoMo/1.0/N502i DoCoMo/1.0/N501i DoCoMo/1.0/N501i DoCoMo/1.0/N501i DoCoMo/1.0/N501i DoCoMo/1.0/N501i DoCoMo/1.0/N501i DoCoMo/1.0/N501i DoCoMo/1.0/N501i Time 20000501005801 20000501005810 20000501024205 20000501024215 20000501024221 20000501024230 20000501024240 20000501024257 20000501024301 20000501024413 IP Address 45c2bf42898b 851306baaf4f 45c2bf42898b 45c2bf42898b 45c2bf42898b 7d6828dc70bd 7d6828dc70bd 45c2bf42898b 7d6828dc70bd 7d6828dc70bd CGI_1 /dcm-bin/docomo?T1&uid= /dcm-bin/docomo?Note&Re= T1&uid= /dcm-bin/docomo?T1&uid= /dcm-bin/docomo?T2&uid= /dcm-bin/docomo?T3&uid= /dcm-bin/docomo?J1&uid= /dcm-bin/docomo?GS&uid= /dcm-bin/docomo?J1&uid= /dcm-bin/docomo?NR&uid= /dcm-bin/docomo?N=%90%5 E%89%68&L=%95%BA%8C %C9&sJ1=J28&OP=2&uid= /dcm-bin/docomo?uid= CGI_2 (UID) 00eeiCojPbrB 00eeiCojPbrB 00eeiCojPzJo 00eeiCojPzJo 00eeiCojPzJo 00eeiCojPzJo 00eeiCojPzJo 00eeiCojPzJo 00eeiCojPzJo 00eeiCojPzJo &sJ0=A02 &sJ1=J28 &OP=1&sJ1=J28 &OP=1&sJ1=J28 &OP=2&sJ1=J28 &Re=NR&G1=++-%8E%51% 8F%C6-++ &OP=2&sG1=%83%72&N=% 90%5E%89%68&L=%95%BA %8C%C9&Re=NR&sJ1=J28 &G2=-%8C%9F%8D%F5&OP=2&sJ1=J28&N=%90%5 E%89%68&L=%95%BA%8C %C9&Re=NR CGI_3

11

b23db4675c57

DoCoMo/1.0/N501i

20000501024444

45c2bf42898b

00eeiCojPzJo

12 13 14

6b6997f92f7d ae331534fb02 51619553be44

DoCoMo/1.0/N501i DoCoMo/1.0/N501i DoCoMo/1.0/N501i

20000501024459 20000501001203 20000501001222

45c2bf42898b 7d6828dc70bd 851306baaf4f

/dcm-bin/docomo?G1&uid= /dcm-bin/docomo?T1&uid= /dcm-bin/docomo?T2&uid=

00eeiCojPzJo 00eeiCoLhErx 00eeiCoLhErx

Preprocessing Before applying data mining algorithm to the web log record, a data preparation must be performed to convert the raw web log data into the data abstraction necessary for the further process. As shown in Fig. 2, the input of the preprocessing phase is the web log files and the output is the session files. Data preprocessing includes data cleansing, user identification, sessionizing, path completion and formatting. In web usage mining process, the data of interest is the access records to certain web pages (usually identified by its filename extension such as html, cgi, php, pl, asp, jsp, etc), not byproduct records such as any access to images (gif, jpg, bmp), sounds (ra, mp3), movies (mov, mpg), etc. Therefore, a data cleansing is needed to eliminate those irrelevant byproduct items from the web log record. These kinds of data are not used in data mining process and usually take up large portion in web log file. Next the user identification is a process to identify the user, and can be done using ip-address, agent, cookies, user-id or client side tracking. The sessionizing is a process to divide the page accesses of each user, who is likely to visit the website more than once, into individual server sessions (visits). The simplest way to do is to use a timeout to break a users click-stream into session. The thirty minutes is used as a default timeout as a result of work of L. Catledge et. al. [11]. Another important step is path completion, a process to determine if there are important accesses that are not recorded in the access log. Methods similar to those used for user identification can be used for path completion. The final procedure of the preprocessing is formatting, which is a preparation module to properly format the sessions such that it can be used in the further process. Example of web log record is given in Table 1 based on data which is actually used as experiment data in this thesis. It includes information such as cookie, user agent, time,

Table 2. Web log record user identification and sessionizing


# 1 2 3 4 5 6 7 8 9 10 11 12 13 14 Time 20000501005801 20000501005810 20000501024205 20000501024215 20000501024221 20000501024230 20000501024240 20000501024257 20000501024301 20000501024413 20000501024444 20000501024459 20000501001203 20000501001222 Time Gap (min) 0.15 103.92 0.17 0.10 0.15 0.17 0.28 0.73 0.07 0.52 0.25 152.93 0.32 G1 T1 T2 CGI_1 T1 Note T1 T2 T3 J1 GS J1 NR CGI_2 00eeiCojPbrB 00eeiCojPbrB 00eeiCojPzJo 00eeiCojPzJo 00eeiCojPzJo 00eeiCojPzJo 00eeiCojPzJo 00eeiCojPzJo 00eeiCojPzJo 00eeiCojPzJo 00eeiCojPzJo 00eeiCojPzJo 00eeiCoLhErx 00eeiCoLhErx

ip-address, cgi parameters, etc. In this thesis, only accesses from mobile phone (DoCoMo) user agent are used. Since cgi parameters passed from user contain a lot of information such as the requested page (CGI_1), user-id (CGI_2), place, category, etc, we can make use of them in our experiment. Instead of using cookie and ip-address, user-id embedded in cgi parameters can be used to exactly identify the user. As result 3 users are identified from web log record example, 00eeiCojPbrB, 00eeiCojPzJo, and 00eeiCoLhErx as shown in Table 2. In case of mobile phone web log record, sessionizing is usually performed using a 5 minutes timeout to break a users click-stream, not 30 minutes as in other type of access. From the web log record 3 sessions, one for each user, are found. Session of user 00eeiCojPbrB can be identified as accessing a sequence of page T1 J1 GS J1 NR Note, user 00eeiCojPzJo: sequence T1 T2 T3

G1, and user 00eeiCoLhErx: sequence T1

T2. After

formatting the data to the suitable form, now it is ready to be supplied to pattern discovery algorithm, which will try to reveal the patterns hidden inside the data.

10

Pattern Discovery This is the key component of the web usage mining. Pattern discovery of the web log record converge the algorithms and techniques from several research areas, such as data mining, machine learning, statistics, and pattern recognition. Data mining technique, especially Generalized Sequential Pattern algorithm proposed by R. Srikant et. al. [1] is of interest in this thesis since it is used to discover patterns from the web log record. This technique intends to find the pattern, such that a set of the items follows the presence of another in a time-ordered set of sessions or episodes, and will be described in detail in the next section. Pattern Analysis Pattern Analysis is a final stage of the whole web usage mining. The goal of this process is to eliminate the irrelative rules or patterns and to extract the interesting rules or patterns from the output of the pattern discovery process. The output of web usage mining algorithms is often a very large number of patterns that is not easy for human to understand, and thus need to be transformed to a format which can be understood easily. This can be done with the help of some analysis methodologies and tools. There are several approaches for the pattern analysis. One is to use the knowledge query mechanism such as SQL, another is to construct multi-dimensional data cube to perform OLAP operations, while more recent techniques are to use graphical visualization, such as Naviz proposed in this thesis.

B) A Mining Technique Generalized Sequential Pattern

R. Srikant et. al. in[1] proposed a Generalized Sequential Pattern (GSP) algorithm to

11

find from a database of data-sequences, all sequences whose support is greater than the user-specified minimum support. Let L = {i1,i2,...,im} be a set of literals, called items. An itemset is a non-empty set of items. A sequence is an ordered list of itemsets. A sequence s is denoted by (s1 s2 ... sn), where sj is an itemset, also called an element of the sequence. An element of a sequence is denoted by (x1,x2,...,xm) where xj is an item. An item can occur only once in an element of a sequence, but can occur multiple times in different elements. An itemset is considered to be a sequence with a single element. A sequence (a1 a2 ... an) is a subsequence of another sequence (b1 b2 ... bm) if there exist integers i1<i2<...<in such that a1 bi1, a2 bi2, ..., an bin. For example, the sequence ((3) (4,5) (8)) is a subsequence of ((7) (3,8) (9) (4,5,6) (8)), since (3) (3,8), (4,5) (4,5,6), and (8) (8). However, the sequence ((3) (5)) is not a subsequence of ((3,5)) (and vice versa). Let a database D of sequences called data-sequences is given, each data-sequences is a list of transactions, ordered by increasing transaction-time. A transaction has the following fields: sequence-id, transaction-id, transaction-time, and the items present in the transaction. The support for a sequence is defined as the fraction of total data-sequences that contain the sequence. In the absence of taxonomies, sliding windows and time constraints, a data-sequence contains a sequence s if s is a subsequence of the data-sequence. The sliding window generalization relaxes the definition of when a data-sequence contributes to the support of a sequence by allowing a set of transactions to contain an element of a sequence, as long as the difference in transaction-times between the transactions in the set is less than the user-specified window-size. Time constraint is of interest in this thesis, since it is used to implement GSP algorithm in web log mining. It restricts the time gap between sets of transactions that contain consecutive

12

elements of the sequence. Formally, a data-sequence d = (d1 ... dm) contains a sequence s = (s1 ... sn) if there exist integers l1 u1 < l 2 u 2 < < l n u n such that: si is contained in

ui k =li

d k , and transaction-time(dui) transaction-time(dli)

window-size, 1 i n . transaction-time(dli) transaction-time(dui-1) > min-gap, and transaction-time(dui) transaction-time(dli-1) max-gap, 2 i n


L1 := {frequent 1-sequences}; k := 2; // k represents pass number while(Lk-1 0) do begin Ck := new candidates of size k generated from Lk-1; forall data-sequences d D do Increment the count of all candidates Ck that are contained in d; Lk := All candidates Ck with minimum support; k := k + 1; end Result := k Lk ;

Fig. 1. Algorithm of GSP To implement GSP algorithm in web log mining, the first step is to transform each access in web log record to its appropriate counterpart in data mining. First, each user session can be thought of in two ways; either as a single transaction of any page references, or a set of many transactions each consisting of a single page reference. The goal of transaction identification is to create meaningful clusters of references for each user. In the web log record used in this experiment, a single page reference itself simply forms a transaction, and a session forms a data-sequence, therefore in Table 3 data-sequence (T1 Note) consists of 2 transactions, while data-sequence

(T1 T2 T3 J1 GS J1 NR G1) consists of 8 transactions, etc. Since a transaction consists only of a single item, there is no need to use a sliding window generalization (window-size = 0). The time constraint used to restrict the time gap between sets of transactions that contain consecutive elements of the sequence is same as
13

the timeout that has been used to break a users click-stream in sessionizing process (min-gap = 0, max-gap = 5 min). For example in Table 3, log record database D contains

Table 3. Data-sequences in the web log record database


Sequence-id 1 1 2 2 2 2 2 2 2 2 3 3 Transaction-id 1 2 3 4 5 6 7 8 9 10 11 12 Transaction-time 20000501005801 20000501005810 20000501024205 20000501024215 20000501024221 20000501024230 20000501024240 20000501024257 20000501024301 20000501024459 20000501001203 20000501001222 Time Gap (min) 0.15 103.92 0.17 0.10 0.15 0.17 0.28 0.73 0.07 152.93 0.32 Page T1 Note T1 T2 T3 J1 GS J1 NR G1 T1 T2

3 data-sequences. Page T1 contained in 3 data-sequences 1, 2, and 3, therefore sup(T1) = 3/3; sequence (T1 T2) contained in 2 and 3, therefore sup(T1 T2) = 2/3; sequence (T1 T2 T3) is contained in 2, therefore sup(T1 T2 T3) = 1/3.

Table 3. Generalized sequential pattern mining result


L1 T1 Note T2 T3 J1 GS NR L2 T1>Note T1>T2 T2>T3 T3>J1 J1>GS GS>J1 J1>NR NR>G1 L3 T1>T2>T3 T2>T3>J1 T3>J1>GS J1>GS>J1 GS>J1>NR J1>NR>G1 L8 T1>T2>T3>J1>GS>J1>NR>G1

C) Visualization Tools of Visitor Behavior


14

In this section, some of methods to visualizing web log record that has been proposed in the past are reviewed. WebViz [4] was known as the first attempt that has been made in the field of web log visualization, which utilizes the statistical properties of the data. While subsequently proposed methods in web log visualization also incorporate some technique of data mining.

WebViz: A Tool for World-Wide Web Access Log Analysis Pitkow et. al. in 1994 proposed WebViz [4] as a tool for web log analysis and provides graphical view of websites local documents and access patterns. By incorporating the Web-Path paradigm [4], i.e. establishment of relationship between documents in database and web access log, into an interactive tool, webmasters can see the documents in their website as well as the hyperlinks traveled (represented visually as links) by visitors. WebViz also enables webmasters to filter the access log by domain names or DSN numbers, directory names, and start and stop times, and play back the events in the access log. The drawback of WebViz is that it was designed to visualize the statistical property of the data only (i.e. frequency and recency information), it can not handle sequential patterns (i.e. has no related data mining tools). It displayed web log access in two-dimensional directed graph, but without enough considerations about appropriate web traversal properties. Also WebViz did not visualize modern dynamic page effectively.

WUM : A Web Utilization Miner In 1998, Spiliopoulou et. al. presented Web Utilization Miner [5], WUM as a mining

15

system for the discovery of interesting navigation patterns. One of the most important features of WUM is that using WUMs mining language MINT; human expert can dynamically specify the interestingness criteria for navigation patterns. This includes specification of criteria of statistical, structural and textual nature. To discover the navigation patterns satisfying the experts criteria, WUM exploits Aggregation Service that extracts information on web access log and retains aggregated statistical information. Although WUM provides an integrated and robust environment to do web log analysis job, but since it focuses mainly on data mining and its mining language, it lacks aesthetic visualization of the data as well as considerations of appropriate web traversal properties and dynamic page.

VISVIP: 3D Visualization of Paths through Websites Cugini et. al. in 1999 proposed VISVIP [6], a tool which allows website developers and usability engineers to visualize the paths taken through the site. The graphical layout of the website can be dynamically customized and simplified, and which subjects paths to view can be dynamically selected. VISVIP also provide an animated representation of traversal along the path through the website. The time spent on each page visit can be represented using the third dimension of the 3D display. VISVIP gives good visualization regarding paths taken through the site, but it has drawbacks such as it needs client customization to instrument a website so as to record the activity of a subject navigating the site. As almost currently available visualizations, VISVIP also did not consider appropriate web traversal properties as well as dynamic page.

WebQuilt: A Framework for Capturing and Visualizing the Web Experience

16

The most recent work done by Hong et. al. in 2001, proposed WebQuilt [7] as a web logging and visualization system that helps web design teams run usability tests and analyze the collected data. To overcome many of the problems with server-side and client-side logging, WebQuilt uses a proxy to log the activity. It aggregates logged usage traces and visualize in a zooming interface that shows the web pages viewed. Also it shows the most common paths taken through the website for a given task, as well as the optimal path for that task. WebQuilt as well as almost currently available visualizations, also has drawbacks that it did not consider appropriate web traversal properties and dynamic page.

3. NAVIZ CONCEPT

Agrawal et. al. [1] in 1995 has given the basic of sequential pattern data mining, which later also widely used to discover traversal paths from web log data. But finding interesting knowledge from the discovered patterns is not an easy task. Since the number of discovered patterns is generally large, and there is no metric that well represents their usefulness. Thus visualization tool is needed to help human users to interpret them. As mentioned in the previous chapter, the drawbacks of current visualization tools includes lack of capability to handle sequential pattern, lack of aesthetic visualization, necessity of client-side customization and the common drawbacks are that most of them do not consider about modern dynamic page. Considering about inherent web traversal topology, which are intrinsically directed cyclic graphs, Naviz was designed to overcome those drawbacks by combining two-dimensional graph of traversal diagram and facilities to visualize interesting

17

traversal paths by specifying certain visited pages and path attributes such as number of hops, support and confidence. It combines the power of sequential pattern mining tools and intuitive-looking of graph drawing tools, to create interactive visualization of traversal paths, in an aesthetic layout of graph. Since it uses log miner and graph layout producer separately from visualization part, Naviz may easily adapt to the latest technology of this two methods whenever its newer version is available, while the future development of its visualization part can continue to be explored.

A) Appropriate Web Traversal Properties

Visualization of web log data, first of all it should give a good understanding of global visitor access. To achieve this goal, it is important to consider about inherent web traversal topology, i.e. WWW visitor access traversals are intrinsically directed cyclic graphs. This can be thought of as a hypermedia-like structure, with nodes represent pages and edges represent traversals between pages. For visualizing this visitor traversal on website, it is found that introducing two appropriate web traversal properties below is very helpful. Hierarchical structure regarding traversal traffic, i.e. more traversed edges are placed at the higher level and less traversed edges at the lower level position. This would give an intuitive description of visitors that are traversing over the site, which enter from top of the graph and then exit to bottom. Grouping of related pages, for example, pages that have high degree of transitional probability among them are better to be placed together near to each other. This pages grouping would be useful for webmasters to easily find what pages are related

18

each other. By incorporating these two properties, Naviz can visualize visitor behavior on a website effectively and easy to understand.

B) Visitor Behavior in Traversal Diagram

First the notation page class and instance that is used in this thesis will be explained. A page class is an abstraction of web pages that offers the same navigational functions in the web traversal topology. Instance is a member of page class that has certain semantics. Instance membership is user defined. Usually an instance is defined by parameters of its page class; however one can ignore some parameters so that an instance may include some different representations of web access logs. For example, logs often include visitor ID as a CGI parameter. But user can define logs with certain CGI parameters as an instance although they have different visitor ID, since this CGI parameter does not affect the semantics of the instance. The page class is a generalization of the web page definition so far since a static web page can be seen as a page class with a single instance. To represent navigational behavior traversal path, a sequence of page classes traversed by visitors, is used. Following association rule, some parameters to assess the strength of the traversal path can be defined: Support of a traversal path A B is the percentage of sessions that contain the sequence of A B against the total number of sessions. Users of a traversal path A B is the percentage of visitors that traversed between A B against the total number of visitors.

19

The confidence of a traversal path is the probability of a visitor to visit the last page in the sequence of traversal path. For example the confidence of traversal path A B C D is the probability of a visitor to visit page D after he/she visited pages A B C consecutively. It can be obtained by dividing the number of sessions that contain sequence A B C D by the number of sessions that contain page A B C. When the sequence only contains two page classes A B, the confidence can also be interpreted as page transition probability from A to B. To derive traversal paths from web access logs GSP algorithm [1] is used. Note that

Naviz is not limited to this algorithm only. The capability to set constraints such as deriving only the traversal paths of visitor with certain attributes has been added also. For example, to extract traversal paths of daytime visitors web logs whose accesses between 6:00 until 18:00 is filtered.
page as node traversal as edge support as thickness confidence as color

Fig. 3. Traversal diagram of visitor behavior.


20

To acquire a global view of navigational behavior, it is needed to draw all traversal paths above certain parameter thresholds. As mentioned before, it must be able to draw directed cyclic graphs, hierarchical structure and nodes grouping also. As the underlying unit of drawing, the shortest traversal paths with a pair of page classes is used, since they also convey the relationships between two adjacent page classes. Finally traversal diagram is drawn as a directed graph with page classes as the nodes and the traversal paths between any pair of page classes as the weighted edges (Fig. 3).

C) Algorithm for Drawing Directed Graphs

To draw the underlying graph layout which representing traversal diagram, Naviz utilizes a graph drawing tool called GraphViz created by Gansner et. al. In their paper [3] in 1993, they described a four-pass algorithm for drawing directed graphs. The first pass assigns discrete ranks to nodes. In a top to bottom drawing, ranks determine Y coordinates. Edges that span more than one rank are broken into chains of virtual nodes and unit-length edges. The second pass orders nodes within ranks to minimize crossings. The third pass sets X coordinates of nodes to keep edges short. The last pass routes edge splines. Furthermore, as secondary role in the algorithm, Gansner et. al. propose the next aesthetic principles: Expose hierarchical structure in the graph. Avoid visual anomalies that do not convey information about the underlying graph. Keep edges short, and

21

Favor symmetry and balance. This algorithm is proven to be able to draw graph layout very well and very fast,

while still maintaining the aesthetic principles. Furthermore, this algorithm satisfies the requirements of appropriate website traversal properties that are needed by Naviz to draw traversal diagram.

4. NAVIZ IMPLEMENTATION

A) System Architecture

Naviz was designed to visualize traversal paths discovered from data mining on web log file. Naviz was developed as a Java JApplet program, which run on almost modern browsers with Java 2 plugin installed. It combines a separated log miner that utilize the GSP algorithm sequential pattern mining [1], a graph layout producer called Graphviz [8], an open source graph drawing software from AT&T that implemented algorithm in [3], and Naviz ability to interactively analyze the sequential patterns discovered. As shown in Fig. 4, Naviz is a client-server application, which consists of: A java applet as user interface in the client side. Naviz applet displays the visualization of the traversal diagram and traversal path to the user, interactively responds to users request and passes it to the server through servlets. Users can set the threshold of support value and confidence degree to control the number of nodes and edges that will be displayed in traversal diagram. For traversal path visualization, users can specify number of hops and visited pages to find interesting paths. Furthermore, users can define the place, category and time class of the underlying

22

Client Naviz Applet Server Naviz Servlets

Pattern Repository

Graphviz

Log Miner

Log File

Fig. 4. Naviz architecture web log record that will be visualized, such that their behavior can be compared by Naviz. Users also can change interactively strategy of hiearchization and page grouping to explore the best possible structure of traversal diagram. Java servlets in the server side, as interface that allows communication between client and server. Due to security restrictions that are applied to applet, Naviz applet cannot directly write-access file system in the server, nor running the program. Hence, Naviz servlets acts as interface between applet and server-side programs, by opening HTTP connections between client and server. Server-side applications Pattern repository containing discovered patterns. Naviz uses a pattern repository that manages the miner output files such as traversals paths discovered from web log data. Currently repository contains traversals paths only. As Naviz visualization capability will improve, in the future it will be expanded to handle other pattern also such as clustering results. Graphviz that is responsible for drawing the graph layout.
23

Graphviz which is responsible for drawing graph layout, allows us to specify detail parameters to draw graph regarding appropriate web traversal properties. Moreover, it is able to give the output as coordinate and size information of the graph in easily readable format for Naviz to use. Log miner to discover traversals/paths from web log data. Currently Naviz has implemented interactive communication between Naviz applet and log miner. If Naviz applet has requested a pattern that doesnt exist in pattern repository, Naviz servlets will automatically launch the log miner to find such a pattern from web log file. Naviz mining engine currently implemented association rule mining, sequential pattern mining (traversals paths), and clustering.

24

Minimum Support and Confidence

Pattern Repository
paths data edges data

Naviz Servlet
paths array: {support, confidence, node1nodeN} edges array: {support,

Naviz Applet

traversal path traversal diagram

confidence, start, finish}

GraphViz
graph layout: nodes, edges Layout Cache

Log Miner

Fig. 5. Naviz detail mechanism Fig. 5 shows detail mechanism of Naviz. Naviz has been programmed to operate on

internal representations of graph, and to allow the user to view the graph as traversal diagram. Naviz which run as an applet in the client browser, start up GraphViz on server through servlets, to compute the graph layout. Whenever a user asks for new layout, Naviz first will try to find the layout in the cache; if it doesnt exist Naviz reads edge data from pattern repository and sends it to GraphViz. GraphViz computes the layout and sends the graph back to Naviz applet along with coordinate and size information as graph attributes. Naviz applet then redraws the traversal diagram using the new layout. The traversal data is read from pattern repository, directly sent back to Naviz applet, and then drawn on top of traversal diagram. When edge and path data is being read from pattern repository, a user specified minimum support and confidence is set as a filter to reduce the number of pattern. Whenever a user has requested a pattern that is not available in the pattern repository, Naviz servlet will launch the log miner to find such a pattern from
25

web log file and write it into repository.


Fig. 6 shows the user interface of Navizs control panel. 4 combo boxes at the top left

of the panel indicate the place, category, start and finish time class of the traversal diagram that is being displayed. All means that the traversal diagram includes all instances of the corresponding class. These combo boxes also define properties of the new traversal diagram that will be displayed by clicking on button View; the size of the new window can be specified in the text fields beside the button. Slide bar of Minsup and Minconf is used to set the minimum value of support/confidence of edges that will be shown on traversal diagram. Path button is used to switch between traversal diagram and traversal path mode that will be described in the following paragraph. Slide bar below the button is used to set the sequential rule number that will be shown. Four buttons of ||, <>, <|, and |> are used to search sequential rules from repository that uses closed-closed, open-open, open-closed, and closed-open method (will be described later), respectively. Combo box beside them has sup, conf, and hop options that are used to sort the appearance of sequential rules according to support, confidence, and hop number, respectively, either in ascending (v button) or descending (^ button) order. Check box and text box below the combo box is used to enable/input the hop number restriction on path searching. Layout button is used to change the layout of underlying traversal diagram according to minimum support, confidence and other properties. Clicking on _|_|_| button will bring a new window consists of six traversal diagrams displaying top six of traversal paths in order. Remaining Time, Place, and Ctgry button is a convenience way to do behavior comparison regarding to time, place, and category classes respectively.

26

Fig. 6. Naviz control panel

B) Visualization Features

Using Naviz webmasters can analyze web log data to discover navigational behavior of their visitors. From our experiment Naviz can discover knowledge about 1) the traversal diagram of visitor traversals on the site, 2) how many visitors are visiting which page, 3) how high is transition probability between two pages, 4) which pages are related each other, 5) how many number of hops are needed to reach certain page, 6) which path drove the most visitors to exit from site, 7) which path drove the most visitors to successfully find their goal, 8) are there visitors who were being lost in website etc. Naviz has two operation modes, i.e. traversal diagram mode and traversal path mode. In traversal diagram mode Naviz displays traversal diagram that describes global visitor traversals on the entire site. It is a two-dimensional graph which nodes represent pages and edges represent traversals between pages. Thickness of edge represents support value of traversal and color of edge (ranges from blue to red) represents confidence degree (low to high). In traversal path mode, Naviz displays traversal path on top of traversal diagram, in such a manner that only one path is showed at one time. Which paths are being showed can be filtered by specifying the pages that are visited and optionally by the number of hops required to reach those pages. Found paths are then displayed in traversal diagram one after another and can be ordered by support, confidence, or number of hops. Naviz uses several strategies to form effective view of traversal diagram and traversal paths:
27

1.

Consideration of appropriate web traversal properties. Edge hierarchization Default strategy of edge hierarchization is that more traversed edges are placed in

upper level position and less traversed ones in lower level. This would intuitively describe visitor traversals on a website from top to bottom of graph and give better understanding of the traversal diagram. This strategy can be changed interactively, i.e. higher confidence edges in upper level and lower confidence edges in lower level, although it may not suitable to visualize the traversal diagram. Moreover, graph orientation can be changed either vertically or horizontally. Page grouping In visualizing the traversal diagram, it is often useful to group pages that are related each other. This is done by give a certain weight to indicate the importance of edges, such as more important edge will have shorter length. By default Naviz binds weight to confidence degree of edges, such that pages with high degree of confidence (transition probability) will be grouped together. It can be changed interactively to be bound to support value, so pages with high support (heavy traffic of traversal among them) will be grouped together. Again, this later strategy may not suitable to visualize the traversal diagram. 2. Navigational behavior comparison web log data contains the information about various properties of the visitor visit such as time, place, category etc. Utilizing this information Naviz can display the traversal diagram of the same website regarding to different properties in different windows that is displayed side by side. This is useful particularly to compare the visitor behavior of the same website regarding to different properties. In case of Mobile

28

Townpage, 3 important properties have been defined, i.e. time, place, and category. Time class has several instances of time span in a day, place has several instances of prefectures in Japan such as Tokyo, Osaka, etc., and category has instances such as karaoke, izakaya, restaurant etc. Therefore for example Naviz can do behavior comparison of day behavior vs. night behavior, Tokyo people behavior vs. Osaka people behavior, karaoke people behavior vs. izakaya people behavior, etc. 3. Traversal path filtering Traversal paths is visualized over the underlying traversal diagram in such a manner that only one path will be showed in one time. Path number slide bar can be used to show the desirable path. For traversal path visualizations, Naviz implemented two filtering mechanisms i.e. filtering by number of hops (path length) and by visited pages. The number of displayed paths will decrease/increase correspondingly as we decrease/increase the number of hops. We can choose which pages are being visited, and find the paths of visitors that are traversing over those pages. There is no limit in the number of pages to choose. In general there are four methods to find the path: Closed-closed method: find paths that begin exactly at first chosen page, traverse over consecutive chosen pages and finish exactly at last chosen page. Closed-open method: find paths that begin exactly at first chosen page, traverse over consecutive chosen pages and finish at any page. Open-closed method: find paths that begin at any page, traverse over consecutive chosen pages and finish exactly at last chosen page. Open-open method: find paths that begin at any page, traverse over consecutive chosen pages and finish at any page.

29

4.

Interactive environment. Furthermore Naviz utilizes the interactive environment to provide more capabilities

to explore navigational behavior from the data. Layout of the traversal diagram, strategy of hierarchization, grouping, and filtering all can be changed interactively to select the best structure representing the web log data. Users use mouse to point to a particular node/edge and Naviz will show detail explanations about the node/edge below the graph such as pages title and url, edges support value and confidence degree etc. Clicking on the node will either bring the corresponding page in the browser (in traversal diagram mode), or selecting the pages for path searching (in traversal path mode).

5. NAVIZ EXPERIMENT

A) NTT i-Townpage served on i-Mode

30

Townpage is the name of ``yellow pages'', a directory service of phone numbers in Japan. It consists 11 million listings under 2000 categories. At 1995 it started internet version namely i-Townpage whose URL http://itp.ne.jp/. The visitors of i-Townpage can specify the location and some other search conditions such as business category or any free keywords and get the list of companies or shops that matched, as well as their phone number and address. Visitors can input the location by browsing the address hierarchy or from the nearest station or landmark. Currently i-Townpage records about 40 million page views monthly. At this moment i-Townpage has four versions: Standard version: for access with ordinary web browser which is also equipped with some features like online maps. Lite version: simplified version for device with limited display capability such as PDA. Mobile Townpage: a version for i-Mode users. An illustration of its usage is shown in Fig. 7 i-mode users can directly make a call from the search results.

Welcome to the Mobile Townpage 1.Search by Categori es 2.Keyword search

Please Select Category 1.Hotels 2.Restaurants 3.Airlines 4.Travel Agencies 5.Book Dealers-Reta il

Please Select Region 1.Tokyo 2.Osaka 3.Aichi -Nagoya4.Kanagawa -Yokohama,Kawasaki-

http://english.itp.ne.jp/ Source: NTT Directory Systems

Ready for search? -Searchor -Results listed alpha beticalSelect detail regions Category

Results 1-10 (of 495) 1.Agnes Hotel 2-20-1 Kagurazaka , Shinjuku-ku, To kyo 03-3267-5505

Fig. 7. Mobile Townpage typical usage


31

L-mode version: a version for L-mode access, a new service from NTT that enables internet access from stationary/fixed phone. Because the limited display and communication ability of mobile phones, a website for mobile phone has to be carefully designed so that the visitors can reach their goal with least clicks. The Mobile Townpage is not simply a reduced version of standard one but it is completely redesigned to meet the demand of i-Mode users. Nearly 40% visitors of i-Townpage accesses from mobile phones. Figure gives a simple illustration of Mobile Townpage typical usage. A visitor first inputs industry category by choosing from prearranged Category List or entering free keywords in Input Form. Then he/she decides the location. Afterward he/she can begin the search or browse more detailed location, and then get the Search Result.

32

Table 4. Edges discovered from web log record sorted by support value
start_node Start Prefecture List Region List Top Start Start Prefecture List Local Top Local Top Top Prefecture List Search Result Region List Top Category Menu 1 Region List Top Local Top Category Menu 2 Top Local Top Prefecture List Region List Top Top Local Top Category List Input Form End Local Top End Prefecture List Region List Category Menu 2 Prefecture List Region List Input Form Category Menu 3 end_node support 71.3054 61.6683 47.684 46.9162 35.8722 35.4333 33.9377 32.5073 31.8483 30.8386 27.7306 27.3661 26.2213 25.7128 25.0853 21.4627 21.2034 18.8155 18.6382 confidence 76.8053 82.5526 92.1699 55.1483 75.0839 78.6304 84.0869 35.2533 34.5386 36.2496 80.7494 34.0821 93.0353 60.3139 74.1879 91.1342 49.9595 37.511 43.5817 from_hour 0 0 0 0 13 19 13 0 0 0 19 0 13 13 0 19 19 13 0 to_hour 0 0 0 0 18 12 18 0 0 0 12 0 18 18 0 12 12 18 0 place 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 category 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

Table 5. Paths discovered from web log record sorted by support value
id 11 11 26 26 182 182 291 291 1453 1453 1453 382 382 382 1149 1149 1149 3798 3798 3798 3798 2892 2892 2892 2892 Start Top Prefecture List Local Top Top Region List Region List Prefecture List Top Region List Prefecture List Region List Prefecture List Local Top Start Top Region List Top Region List Prefecture List Local Top Start Top Region List Prefecture List node support 76.8053 76.8053 57.9264 57.9264 45.806 45.806 45.6374 45.6374 43.5543 43.5543 43.5543 43.4543 43.4543 43.4543 42.2664 42.2664 42.2664 41.1211 41.1211 41.1211 41.1211 40.0719 40.0719 40.0719 40.0719 confidence -0.1041 -0.1041 -0.0785 -0.0785 -0.0621 -0.0621 -0.0619 -0.0619 95.0844 95.0844 95.0844 95.2163 95.2163 95.2163 55.0306 55.0306 55.0306 94.4135 94.4135 94.4135 94.4135 94.8079 94.8079 94.8079 94.8079 from_hour 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 to_hour 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 place 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 category 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

33

B) Global Visitor Behavior

Data mining is performed on the web log data of Mobile Townpage site from 1 to 7 May 2000 with size of 15 GB, using minimum support threshold of 0.1%, and currently results in a set of traversal patterns containing 8611 edges (traversals between two pages) such as in Table 4 and 58125 paths (traversals consist of more than two pages) such as in
Table 5 (this figures may increase as more patterns of instances is being discovered).

Edges are essentially paths consisting of two pages only, start_node and end_node, and become basic elements to form traversal diagram. For example, edge Start Top. Paths usually consist of more than two pages, for example path no 1453: Top Region List Prefecture List. Support of edge or path reflects the traffic

of visitors going through it. Confidence has important meaning in case of edge only; that is transition probability from start_node to end_node. Other fields from_hour and to_hour is instance of class Time; place and category is instance of class Place and Category respectively. These instances information is used to perform behavior comparison. Traversal diagram visualization
Fig. 8 is the visualization result of edges by Naviz on traversal diagram mode, it

gives the global view of visitor traversal on the entire site of Mobile Townpage. Here, the minimum-maximum support is set to 0.6%-100% and minimum-maximum confidence to 0%-100%. Total of 115 most important edges out of 8611 edges available in repository are being visualized. The Start and End pages are not actual pages belong to the site, they are actually another sites located somewhere on the Web, and indicate the entry and

34

exit door to and from the site. The important pages include Top as the sites top page, Category List a place for visitors to choose their category option, Input Form where visitors fill in the free keyword, and Search Result which indicates that visitors found the answer and thus reached their goal. Also we can see in the traversal diagram that many edges are coming into or going out from Search Result indicating the importance of the page. When visualizing traversal diagram, Naviz considers appropriate web traversal properties, so that we can think of visitors came into the site from top of the graph and went out from the bottom. We can see the most traversed edges, the thick one, that are forming sequence of pages Top Region List Prefecture List Local Top are placed in the upper position of the graph. While the less traversed edges that are connecting City Menu 1 City Menu 2, Station Menu 1 Station Menu 2 etc. are placed in the lower position of the graph. Naviz also allows us to find related pages easily. Also we can see that there are several groups of related pages, which indicates that those pages have high degree of transition probability among them: i.e. group (Top Region List Prefecture List Local Top Commercial), group (Category Menu 1 Category Menu 2), group (Station Menu 1 Station Menu 2) etc. Just by viewing the traversal diagram we can easily grasp and understand the global behavior of visitors over the site, since looking at the traversal diagram is as looking at the picture of the visitor behavior itself. Furthermore by analyzing the detail value of traversal diagrams components, we can know that more than 30% of visitors in the Top page flow directly to go out from the site with probability more than 36%; while only about 11% of visitors in the Local Top page are going to see Commercial with

35

probability less than 12%. By the means of mouse point and click, we can easily and interactively investigate each node and edge on traversal diagram that is considered important, to look closely at their detail values. Traversal path visualization Switching to traversal path mode, Naviz has discovered some interesting visitor behavior on Mobile Townpage site. First, success paths in which visitors are successful finding their goal is of interest of many webmasters. It can be identified as paths which traverse from Start Search Result End. We can start to find such a

path by doing the following steps: in the traversal path mode select pages Start, Search Result, and End consecutively, optionally we can specify number of hops too, and then do searching by clicking on the one of four search buttons. Since Start is the first page, and End is the last page on every complete path, four methods of searching (closed-closed, closed-open, open-closed, and open-open) have the same effect. As the result Fig. 9 shows the most high traffic of the success paths: i.e. about 2.8 % of visitors successfully reached the Search Result page through the path Start Top Region List Prefecture List Local Top Input Form Search

Result and then exit from the site. We can see from the traversal diagram that since there is no way to go to Search Result from pages before the Input Form, this top success path is the most efficient way for people to reach Search Result page, except for paths that are using bookmark. Fig. 10 shows top 2 5 of success paths. Second top success path shows that about 0.85% of visitors runs through Start Search Result

End, which means that visitors came into the site directly to the Search Result page (they bookmarked the result). Third success path is about 0.84% and took very long path

36

of Start List

Top

Region List

Prefecture List

Local Top

Category

City Menu 1

City Menu 2

Search Confirm

Search Result

End. Fourth and fifth top success path is supported by 0.63% and 0.54% of visitors respectively. Next interesting one is the exit path which is a path taken by visitors to exit from the site. The top exit path as shown in Fig. 11 tells us the shocking result that 28.76 % of visitors left the site as soon as they came into the Top page. Fig. 12 shows top 2 5 of exit paths. Second top exit path is interesting since it is also a top success path. Webmasters ideally wish to make into reality that the top exit path in their website is also the top success path. Top 3, 4, and 5 of exit path is supported by 2.44%, 2.43%, and 2.34% of visitors respectively. Finally another interesting path is the lost path in which visitors failed to find their goal even after a long struggle in the labyrinth of the site. Fig. 13 shows that 0.5 % of visitors failed to find their goal through Start List Local Top Category List Top Region List Prefecture

City Menu 1

End. Even worse is

another lost path in Fig. 14 which shows that 0.06% of visitors still failed to find their goal, even though once they have tried to browse Category List, but didnt succeed; went back to Local Top, filled in some keywords in Input Form, failed again; then tried to browse Category Menu 1, useless too; and eventually exited the site without getting the answer. Using Naviz in traversal path mode, we can easily and interactively investigate every path by specifying the traversed pages and the hop number. The discovered paths can then be browsed one by one on top of the traversal diagram, while the appearance order of the path can be specified either by support, confidence or hop number, either in

37

ascending or descending order.

C) Comparison of Visitor Behavior by Time, Place and Category Class

Time based comparison Using Naviz comparison function, some interesting differences between day behavior and night behavior of i-mode internet users can be discovered. Fig. 15 shows the top exit path of both behavior; they share the common top exit path with difference in support value, 12.7% for day and 16.1% for night. Fig. 16 shows the second top exit path; 1.82% of day visitors successfully found their goal, while 1.33% of night visitors chose rather to leave the site. The pie chart below the graph indicates the ratio of total visitors that support the behavior. The night visitors are slightly more than the day visitors. Fig. 17 shows the top success path of both behavior. Similar to exit path, they share also the common top success path with difference in support value, 1.82% for day and 1.0% for night. However the second top success path in Fig. 18 shows the significant difference between two behavior, while 0.52% of day visitors bookmarked their previous results, 0.44% of night visitors seem enjoyed browsing long path to find their goal. These facts indicate that people of day have more certain objective when browsing the site compared to people of night. Location based comparison Besides time based behavior comparison, Naviz can also perform location based behavior comparison. Fig. 19 shows behavior comparison between Tokyo people and Osaka people. Since top 1 and 2 of exit paths didnt reveal any significant differences, third top exit path is used. It tells us that 0.36% of Tokyo people took longer path than the

38

path taken by 0.23% of Osaka people to exit. Fig. 20 shows third top success path of both behavior. Based on this result, 0.1% of Tokyo people took longer path than the path taken by 0.06% of Osaka people to reach their goal. Another interesting behavior difference of two people is that while Tokyo people tend to view Category List page before entering Input Form page, Osaka people seem like to go directly to Input Form page. This may indicate that Tokyo people like to have guidance from Category List to know what they want to search, while Osaka people already know what they want to search. Category based comparison Another Naviz feature is category based behavior comparison. Fig. 21 shows the fourth top exit path (in the same time it is third top success path too) of hotel people and izakaya people behavior. According to this result, 0.07% of hotel people took longer path than 0.05% of izakaya people to reach their goal as well as to exit the site. Since top 1, 2, and 3 of exit path as well as top 1 and 2 of success path dont reveal any significant differences, we may conclude that visitors of both category almost have the same behavior. Essentially, Naviz comparison function allows us to compare visitor behavior of a website based on time, place, and category, or combination of them. There is no restriction in the way of combining the comparison condition.

39

Fig. 8. Traversal diagram of visitor behavior of NTT Mobile Townpage.

40

Fig. 9. Top success path of visitor behavior of NTT Mobile Townpage.


41

Fig. 10. Top 2 5 success path of visitor behavior (top-left to bottom-right).


42

Fig. 11. Top exit path of visitor behavior of NTT Mobile Townpage.
43

Fig. 12. Top 2 5 exit path of visitor behavior (top-left to bottom-right).


44

Fig. 13. Lost path of visitor behavior of NTT Mobile Townpage.


45

Fig. 14. Another lost path of visitor behavior of NTT Mobile Townpage.
46

Fig. 15. : Top exit path of day behavior vs. night behavior
47

Fig. 16. Second top exit path of day behavior vs. night behavior
48

Fig. 17. Top success path of day behavior vs. night behavior
49

Fig. 18. Second top success path of day behavior vs. night behavior
50

Fig. 19. Third top exit path of Tokyo people vs. Osaka people
51

Fig. 20. Third top success path of Tokyo people vs. Osaka people
52

Fig. 21. Fourth top exit path of Hotel people vs. Izakaya people
53

6. CONCLUSION AND FUTURE WORK

Experiment in visualization of traversal paths discovered from web log data of NTT i-Townpage served on i-Mode website shows that Naviz has successfully visualized a traversal diagram of visitor behavior, discovered various interesting visitor behavior on the website as well as performed various behavior comparison based on time, place and category. It can be concluded that the important factors in visualizing the visitor navigational behavior from web log data is to consider appropriate web traversal properties to make it easy to grasp and understand the global visitor behavior, as well as perform behavior comparison based on classes and instances found as cgi parameters in modern dynamic pages, and utilize interactive environment to provide greater capability to analyze the discovered traversal paths. Of course this is not describing all the important factors needed in web log visualization, rather we need more study and experiment in web log data mining on various kinds of website. In the future Naviz will be improved with capability of making future predictions of visitor behavior based on their behavior in the past. Besides visualization of traversals and paths, Naviz will be improved also with the capability to visualize results of web access log clustering.
References

[1] R. Srikant, and R. Agrawal. Mining Sequential Patterns: Generalizations and Performance Improvements. In Fifth Intl Conference on Extending Database Technology (EDBT96), pages 3-17, Avignon, France, March 1996. [2] Mukherjea, S & Foley, J., D. (1995). Visualizing the World-Wide Web with the

54

Navigational View Builder. Computer Networks and ISDN Systems, 27 (6), 1075-1087 [3] E. Gansner, E. Koutsofios, S. North, and K. Vo. A technique for drawing directed graphs. Transactions on Software Engineering, 19(3):214230, March 1993. [4] Pitkow, J. and K. Bharat. WebViz: A Tool for World-Wide Web Access Log Analysis. In Proceedings of First International Conference on the World-Wide Web 1994. [5] M. Spiliopoulou and L.C. Faulstich. WUM : A Web Utilization Miner. EDBT Workshop WebDB98, Valencia, Spain, 1998. Springer Verlag. [6] Cugini, J. and J. Scholtz. VISVIP: 3D Visualization of Paths through Websites. In Proceedings of International Workshop on Web-Based Information Visualization (WebVis'99). Florence, Italy. pp. 259-263. IEEE Computer Society, September 1-3 1999. [7] Jason I. Hong, and James A. Landay, "WebQuilt: A Framework for Capturing and Visualizing the Web Experience." In Proceedings of The Tenth International World Wide Web Conference (WWW10), Hong Kong, May 2001. [8] http://www.research.att.com/sw/tools/graphviz/ [9] Tufte, E. The Visual Display of Quantitative Information. Cheshire, CT. Graphics Press: 1983. [10] Oren Etzioni. The World Wide Web: Quagmire or Gold Mine. Communications of the ACM, 39(11): 65-68, 1996. [11] L. Catledge and J. Pitkow. Characterizing browsing behaviors on the World Wide Web. Computer Networks and ISDN Systems, 27(6), 1995. [12] http://www.w3.org/WCA, http://www.w3.org/1999/05/WCAterms/ [13] http://www.nua.ie/surveys/how_many_online/

55

APPENDIX TABLE OF CONTENTS

A5.1 GRAPHVIZ .............................................................................. A94 A5.2 LOG MINER ............................................................................ A94

APPENDIX: NAVIZ PROGRAM SOURCE CODE....................... A1 A1 A2 NAVIZ APPLET ......................................................................... A2 NAVIZ SERVLETS .................................................................... A58
A2.1 NAVIZ SERVLET ....................................................................... A58 A2.2 NAVIZ PATH SERVLET............................................................... A69 A2.3 NAVIZ ATTRIBUTE SERVLET ...................................................... A73

A5.3 PATTERN REPOSITORY ............................................................. A94

APPENDIX TABLE OF FIGURES

FIGURE A 1. NAVIZ ARCHITECTURE ........................................................... A2 FIGURE A 2. NAVIZ APPLET MECHANISM ...................................................... A3 FIGURE A 3. NAVIZ LAUNCHER .................................................................... A3 FIGURE A 4. ALGORITHM FOR PATH SELECTION .............................................. A4 FIGURE A 5. ALGORITHM FOR INCLUDE FUNCTION: OPEN OPEN .................. A5 FIGURE A 6. ALGORITHM FOR INCLUDE FUNCTION: OPEN CLOSED .............. A5

A3

HELPER CLASSES ................................................................... A76


A3.1 CLASS OF CANVAS TO DRAW TRAVERSAL DIAGRAM .................. A76 A3.2 CLASS OF THREAD PARALLELIZATION ...................................... A82 A3.3 CLASSES OF APPLET COMMUNICATION ..................................... A84

FIGURE A 7. ALGORITHM FOR INCLUDE FUNCTION: CLOSED OPEN .............. A6 A4 DATA TYPE CLASSES.............................................................. A86 FIGURE A 8. ALGORITHM FOR INCLUDE FUNCTION: CLOSED CLOSED .......... A6
A4.1 TYPES OF NODE AND EDGE DATA ............................................ A86 A4.2 TYPES OF REQUEST AND RESPONSE OF SERVLETS ...................... A90

FIGURE A 9 NAVIZSERVLET ALGORITHM. .....................................................A58 FIGURE A 10. NAVIZPATHSERVLET ALGORITHMS ..........................................A69

A5

SERVER SIDE APPLICATIONS .................................................. A94

Ai

Appendix Naviz Applet Class

Applet Communicator (Interface) 4. Data Type Classes 1. Types of Node and Edge Data Naviz Node Naviz Edge

Appendix: Naviz Program Source Code

2.

Types of Request and Response of Servlets Request and Response of Naviz Servlet Naviz Request Naviz Response

Request and Response of Naviz Path Servlet Naviz is designed as client server application with an applet in client side and several servlets plus applications in server side. Roughly, as shown in Figure A 1 Naviz components can be mentioned as below: 1. 2. Naviz Applet Class Naviz Servlet Classes 1. 2. 3. 3. Naviz Servlet: NavizServlet Naviz Path Servlet Naviz Attribute Servlet 5. Naviz Path Request Naviz Path Response

Request and Response of Naviz Attribute Servlet Naviz Attribute Request Naviz Attribute Response

Server Side Applications 1. 2. 3. GraphViz Log Miner Pattern Repository

Helper Classes 1. 2. 3. Class of Canvas to Draw Traversal Diagram (NavizCanvas) Class of Thread Parallelization (SwingWorker) Classes of Applet Communication Message Relayer

A1

Appendix Naviz Applet Class


Client side NavizCanvas SwingWorker NavizApplet MessageRelayer SwingWorker SwingWorker AppletCommunicator

task to read node (NavizNode) and edge (NavizEdge) data from MySQL Database (Pattern Repository), and feed it to GraphViz to make graph layout of traversal diagram. If the requested patterns do not exist in repository, it launches Log Miner to mine the patterns from web log file and store them into repository. NavizServlet receives request from applet in the form NavizRequest and send the

Naviz Request

Naviz Response

Naviz Path

Naviz Path

Naviz Attribute Request

Naviz Attribute Response

response in the form NavizResponse. NavizPathServlet is responsible to read path data from repository and uses NavisPathRequest and NavizPathResponse to

Server side NavizServlet


NavizNode NavizEdge

communicate with applet. NavizAttributeServlet uses NavizAttributeRequest


NavizPathServlet NavizAttributeServlet

and NavizAttributeResponse to communicate with applet and is responsible to read attribute data from repository, such as time, place, and category that are used to perform behavior comparison.

GraphViz

Log Miner

MySQL Database

Main Class

Data Type Class

A1 Naviz Applet

Figure A 1. Naviz Architecture NavizApplet implements AppletCommunicator interface in order to be able to communicate with other applets in the client side, and instantiates MessageRelayer to open the communication. It uses NavizCanvas to draw traversal diagram, and SwingWorkers that each invokes new thread that parallely open HTTP connection to each servlet in server side. NavizServlet has primary

A2

Appendix Naviz Applet Class


NavizApplet init

NavizLauncher.jsp
connectToServlet SwingWorker connectToPathServlet SwingWorker construct finish

NavizApplet.jsp NavizApplet

layoutButtonActionPerformed orderingButtonActionPerformed directionButtonActionPerformed

construct nsTextFieldActionPerformed mcTextFieldActionPerformed colorComboBoxActionPerformed widthComboBoxActionPerformed weightComboBoxActionPerformed drawBezier orderComboBoxActionPerformed getSubPaths minconfScrollBarAdjustmentValueChanged maxconfScrollBarAdjustmentValueChanged minsupScrollBarAdjustmentValueChanged maxsupScrollBarAdjustmentValueChanged pathButtonActionPerformed hopCheckBoxActionPerformed minhopTextFieldActionPerformed maxhopTextFieldActionPerformed descButtonActionPerformed ascButtonActionPerformed sortComboBoxActionPerformed closedOpenButtonActionPerformed openOpenButtonActionPerformed openClosedButtonActionPerformed closedClosedButtonActionPerformed finish

Figure A 3. Naviz Launcher Naviz Applet is the core of the Naviz visualisation system, and is embedded in a jsp page called NavizApplet.jsp launched by NavizLauncher.jsp as shown in

minmaxSupConf

Figure A 3. It has mechanism as shown in Figure A 2. When NavizApplet is initiated, it calls connectToServlet, connectToPathServlet, and

NavizCanvas setData setPaths

connectToAttributeServlet which each makes http connection paralelly to the corresponding servlet. After the response was received, connectToServlet calls drawBezier to spline edges, and set data to NavizCanvas. Upon receiving the

connectToAttributeServlet SwingWorker construct finish

response, connectToPathServlet calls minmaxSupConf to assign minimum and maximum support and confidence to each path, and getSubPaths to find the satisfied paths and set the paths to NavizCanvas. It needs to call the functions after connectToServlet received response from servlet. In case

function instance server

connectToPathServlet receive response first, it will not call the functions and instead connectToServlet will call them. And connectToAttributeServlet will set the comparison data to the NavizCanvas. There are many event handlers that also calls connectToServlet to request new layout to the server, and getSubPaths to find the satisfied paths. After the edge and path of NavizCanvas was set, it will responsible to draw the traversal diagram or path to the screen. Function of getSubPaths has important task to search paths according hop

Figure A 2. Naviz Applet Mechanism

A3

Appendix Naviz Applet Class

number and visited pages in 4 types of method, closed-closed, closed-open, open-closed, open-open. It has mechanism as shown in Figure A 4. First each path is checked wether it has edge whose support and confidence is out of the range. If hop checking is selected, check wether path length is in the range. Then using include function to check if the path satisfies the pages (nodes) specified. For branching condition, by default yes condition goes down, unless it is specified else. Open open method is shown in Figure A 5. It consists of two loops of i from 0 to specified nodeSize, and j from 0 to path.nodeSize. First it will check if nodes[i] = path.node[j]. Then the order of nodes and path.node is checked wether same or not by comparing j and order[i-1]. As shown in Figure A 6, open closed method cut both the loops at original size 1, and check the last node independently. In contrast with previous method, closed open method start both the loops from 1, and check the first node independently (Figure A 7). Finally, closed closed method checks first and last node independently (Figure A 8).
i+1

nodes[] type

i = 0

minsup<=sup[i]<=maxsup minconf<=conf[i]<=maxconf

hop?

minhop<=hop[i]<=maxhop

include(i)?

subPaths.insert(i)

i<pathSize

return subPaths

Figure A 4. Algorithm for path selection

A4

Appendix Naviz Applet Class

nodes[] type

previous

type=open-closed

next

b=false

type=open-open

next i+1

i=0

j=0

i=0 nodes[i]=path.node[j] i+1 j=0 j+1 nodes[i]=path.node[j]

i=0

j>=order[i-1]

order[0]=j,b=true j+1 i=0 j>=order[i-1] yes order[0]=j,b=true order[i]=j,b=true yes yes j<path.nodeSize yes i<nodeSize !b? b=false i<nodeSize-1 !b? j<path.nodeSize-1

order[i]=j,b=true

b=false

lastNodes=path.lastNode

b=false

return b

b=true

return b

Figure A 5. Algorithm for include function: open open

Figure A 6. Algorithm for include function: open closed

A5

Appendix Naviz Applet Class


previous type=closed-closed

previous

type=closed-open

next nodes[0]=path.node[0]

nodes[0]=path.node[0]

order[0]=0,b=true

order[0]=0,b=true

i=1

i=1

i+1

j=1

i+1

j=1

nodes[i]=path.node[j]

nodes[i]=path.node[j]

j+1

i=1

j>=order[i-1]

j+1

i=1

j>=order[i-1]

order[1]=j,b=true

order[i]=j,b=true

order[1]=j,b=true

order[i]=j,b=true

yes j<path.nodeSize-1 b=false

yes j<path.nodeSize yes i<nodeSize !b? b=false

yes i<nodeSize-1 !b?

lastNodes=path.lastNode return b b=true

b=false

return b

Figure A 7. Algorithm for include function: closed open Figure A 8. Algorithm for include function: closed closed

/* * NavizApplet.java *

A6

Appendix Naviz Applet Class


* Created on 2002/04/01, 17:30 */ package naviz; import import import import import import import import import javax.swing.*; java.text.*; java.util.*; java.awt.event.*; java.awt.geom.*; java.awt.*; java.net.*; java.io.*; netscape.javascript.JSObject; private private private private private int newWinWidth; Vector hours; static final int STANDARD_CONTROL_WIDTH = 825; static final int DETAIL_CONTROL_WIDTH = 1275; boolean attributeWorkFinished;

/** * * @author praz */ public class NavizApplet extends JApplet implements AppletCommunicator { // General Variables private boolean initiated; // flag to indicate whether an applet has been initiated or not private boolean copiedData; // flag to indicate that the edge and path are copied from another applet private String baseDir; // base directory of applet address private int windowColNum; // column number of browser window private int windowRowNum; // row number of browser window private double windowMaxHor; // maximum horizontal of screen private double windowMaxVer; // maximum vertical of screen private int screenTop; private int screenLeft; private double screenWidth; private double screenHeight; public NavizCanvas canvas; // diagram drawing area public JSObject jsobjectWin; // current browser containing applet public NumberFormat numberFormat; // format number in sup, conf textbox private private private private private int int int int int placeIndex; categoryIndex; fromHourIndex; toHourIndex; newWinHeight;

private int appletNum; // applet number public int getAppletNum() { return appletNum; } public void setAppletNum(int appletNum){ this.appletNum = appletNum; } private int parentNum; // applet parent number public int getParentNum() { return parentNum; } public void setParentNum(int parentNum){ this.parentNum = parentNum; } private String propertyPage; public void setPropertyPage(String propertyPage){ this.propertyPage = propertyPage; } public String getPropertyPage(){ return propertyPage; } public void setPathButton(String pathButtonText){ if(initiated){ if(pathButtonText.equals("Diagram")) pathButton.setText("Path"); else pathButton.setText("Diagram"); pathButtonActionPerformed(null); } } public String getPathButton(){ return pathButton.getText(); } public void changeLayout(){ layoutButtonActionPerformed(null); } public void detailControl(){ detailButtonActionPerformed(null); }

A7

Appendix Naviz Applet Class


// Diagram Variables private String website; // web log private int fromHour; // time behavior public int getFromHour(){ return fromHour; } private int toHour; // time behavior public int getToHour(){ return toHour; } private int place; // place behavior public int getPlace(){ return place; } private int category; // category behavior public int getCategory(){ return category; } private int comparison; // behavior comparison (1) or not (0) private String selectedNode; // last traversed node by mouse private NavizEdge selectedEdge; // last traversed edge by mouse private double minsup; // minimum support public double getMinsup() { return minsup; } public void setMinsup(double minsup){ if(minsup>=0.0 && minsup<=maxsup){ this.minsup = minsup; if(initiated) minsupScrollBar.setValue((int)(minsup/incsup)); } } private double maxsup; // maximum support public double getMaxsup() { return maxsup; } public void setMaxsup(double maxsup){ if(maxsup<=100.0 && maxsup>=minsup){ this.maxsup = maxsup; if(initiated) maxsupScrollBar.setValue((int)(maxsup/incsup)); } } private double incsup; // support increment public double getIncsup() { return incsup; } public void setIncsup(double incsup){ if(incsup>0.0 && incsup<maxsup-minsup){ this.incsup = incsup; double val = incsup; double oldMinsup = minsup; double oldMaxsup = maxsup; if(initiated){ incsupTextField.setText(String.valueOf(val)); minsupScrollBar.setVisibleAmount ((int)(val>1.0?responsePacket.dataMaxsup/10:responsePacket.dataMaxsup/( 10*val))); minsupScrollBar.setBlockIncrement ((int)(val>1.0?responsePacket.dataMaxsup/10:responsePacket.dataMaxsup/( 10*val))); minsupScrollBar.setMaximum ((int)(val>1.0?responsePacket.dataMaxsup:responsePacket.dataMaxsup/val) +(int)(val>1.0?responsePacket.dataMaxsup/10:responsePacket.dataMaxsup/( 10*val))); maxsupScrollBar.setVisibleAmount ((int)(val>1.0?responsePacket.dataMaxsup/10:responsePacket.dataMaxsup/( 10*val))); maxsupScrollBar.setBlockIncrement ((int)(val>1.0?responsePacket.dataMaxsup/10:responsePacket.dataMaxsup/( 10*val))); maxsupScrollBar.setMaximum ((int)(val>1.0?responsePacket.dataMaxsup:responsePacket.dataMaxsup/val) +(int)(val>1.0?responsePacket.dataMaxsup/10:responsePacket.dataMaxsup/( 10*val))); } minsup = oldMinsup; maxsup = oldMaxsup; } } private double minconf; // minimum confidence public double getMinconf() { return minconf; } public void setMinconf(double minconf){ if(minconf>=0.0 && minconf<=maxconf){ this.minconf = minconf; if(initiated) minconfScrollBar.setValue((int)(minconf/incconf)); }

A8

Appendix Naviz Applet Class


} private double maxconf; // maximum confidence public double getMaxconf() { return maxconf; } public void setMaxconf(double maxconf){ if(maxconf<=100.0 && maxconf>=minconf){ this.maxconf = maxconf; if(initiated) maxconfScrollBar.setValue((int)(maxconf/incconf)); } } private double incconf; // confidence increment public double getIncconf() { return incconf; } public void setIncconf(double incconf){ if(incconf>0.0 && incconf<maxconf-minconf){ this.incconf = incconf; double val = incconf; double oldMinconf = minconf; double oldMaxconf = maxconf; if(initiated){ incconfTextField.setText(String.valueOf(val)); minconfScrollBar.setVisibleAmount ((int)(val>1.0?responsePacket.dataMaxconf/10:responsePacket.dataMaxconf /(10*val))); minconfScrollBar.setBlockIncrement ((int)(val>1.0?responsePacket.dataMaxconf/10:responsePacket.dataMaxconf /(10*val))); minconfScrollBar.setMaximum ((int)(val>1.0?responsePacket.dataMaxconf:responsePacket.dataMaxconf/va l)+(int)(val>1.0?responsePacket.dataMaxconf/10:responsePacket.dataMaxco nf/(10*val))); maxconfScrollBar.setVisibleAmount ((int)(val>1.0?responsePacket.dataMaxconf/10:responsePacket.dataMaxconf /(10*val))); maxconfScrollBar.setBlockIncrement ((int)(val>1.0?responsePacket.dataMaxconf/10:responsePacket.dataMaxconf /(10*val))); maxconfScrollBar.setMaximum ((int)(val>1.0?responsePacket.dataMaxconf:responsePacket.dataMaxconf/va l)+(int)(val>1.0?responsePacket.dataMaxconf/10:responsePacket.dataMaxco nf/(10*val))); } minconf = oldMinconf; maxconf = oldMaxconf; } } private double layoutMinsup; // minimum support to public double getLayoutMinsup() { return layoutMinsup; } public void setLayoutMinsup(double layoutMinsup){ this.layoutMinsup = layoutMinsup; setMinsup(layoutMinsup); } private double layoutMaxsup; // maximum support to public double getLayoutMaxsup() { return layoutMaxsup; } public void setLayoutMaxsup(double layoutMaxsup){ this.layoutMaxsup = layoutMaxsup; setMaxsup(layoutMaxsup); } private double layoutMinconf; // minimum confidence public double getLayoutMinconf() { return layoutMinconf; } public void setLayoutMinconf(double layoutMinconf){ this.layoutMinconf = layoutMinconf; setMinconf(layoutMinconf); } private double layoutMaxconf; // maximum confidence public double getLayoutMaxconf() { return layoutMaxconf; } public void setLayoutMaxconf(double layoutMaxconf){ this.layoutMaxconf = layoutMaxconf; setMaxconf(layoutMaxconf); } private double minLineWidth; // minimum edge width public double getMinLineWidth() { return minLineWidth; } public void setMinLineWidth(double minLineWidth){ this.minLineWidth = minLineWidth; } private double maxLineWidth; // maximum edge width public double getMaxLineWidth() { return maxLineWidth; } make layout

make layout

to make layout

to make layout

in pixels

in pixels

A9

Appendix Naviz Applet Class


public void setMaxLineWidth(double maxLineWidth){ this.maxLineWidth = maxLineWidth; } private double maxHue; // maximum hue of value of edge color (0-1) public double getMaxHue() { return maxHue; } public void setMaxHue(double maxHue){ this.maxHue = maxHue; } public void setHopCheckBox(boolean selected){ if(initiated) hopCheckBox.setSelected(selected); } public boolean getHopCheckBox(){ return hopCheckBox.isSelected(); } // Edge Variables public NavizRequest requestPacket; servlet public NavizResponse responsePacket; servlet private JPopupMenu popup; // popup mode private MouseListener popupListener; // object to send to edge // object to receive from edge window to appear in diagram // listener of popup } private int widthByRow; // bound edge width by sup or conf public void setWidthByRow(int widthByRow){ this.widthByRow = widthByRow; if(initiated) widthComboBox.setSelectedIndex(widthByRow); } public int getWidthByRow(){ return widthByRow; } private int colorByRow; // bound edge color by sup or conf public void setColorByRow(int colorByRow){ this.colorByRow = colorByRow; if(initiated) colorComboBox.setSelectedIndex(colorByRow); } public int getColorByRow(){ return colorByRow; } private int pathColorByRow; // bound path color by sup or conf public void setPathColorByRow(int pathColorByRow){ this.pathColorByRow = pathColorByRow; } public int getPathColorByRow(){ return pathColorByRow; } private boolean workFinished; // flag to indicate that edge servlet has finished the work public boolean isWorkFinished() { return workFinished; } public void setWorkFinished(boolean workFinished) { this.workFinished = workFinished; } // Path Constants public selection public selection public public public mode public static final int PATH_NODES_INITIAL_CAPACITY = 5; // of visited page in path filtering static final int PATH_NODES_CAPACITY_INCREMENT = 5; // of visited page in path filtering static final int ASCENDING = 1; // sort paths in path mode static final int DESCENDING = -1; // sort paths in path mode static final int CLOSED_CLOSED = 0; // path filtering static final int OPEN_CLOSED = 1; // path filtering mode

private int orderByRow; // hierarchize edges by sup or conf public void setOrderByRow(int orderByRow){ this.orderByRow = orderByRow; if(initiated) orderComboBox.setSelectedIndex(orderByRow); } public int getOrderByRow(){ return orderByRow; } private int weightByRow; // group nodes by sup or conf public void setWeightByRow(int weightByRow){ this.weightByRow = weightByRow; if(initiated) weightComboBox.setSelectedIndex(weightByRow); } public int getWeightByRow(){ return weightByRow;

A10

Appendix Naviz Applet Class


public static final int CLOSED_OPEN = 2; // path filtering mode public static final int OPEN_OPEN = 3; // path filtering mode // Path Variables private boolean pathCompleted; // flag to indicate that path array process has completed private JPopupMenu pathPopup; // popup window to appear in path mode private MouseListener pathPopupListener; // listener of pathpopup public NavizPathRequest pathRequestPacket; // object to send to path servlet public NavizPathResponse pathResponsePacket; // object to receive form path servlet public Vector pathNodes; // selected nodes to find paths public Vector permanentPathNodes; // selected permanent nodes to find paths public Vector avoidNodes; // avoided nodes to find paths public Vector permanentAvoidNodes; // avoided permanent nodes to find paths private int minhop; // minimum hop number public void setMinhop(int minhop){ this.minhop = minhop; if(initiated){ minhopTextField.setText(String.valueOf(minhop)); minhopTextFieldActionPerformed(null); } } public int getMinhop(){ return minhop; } private int maxhop; // maximum hop number public void setMaxhop(int maxhop){ this.maxhop = maxhop; if(initiated){ maxhopTextField.setText(String.valueOf(maxhop)); maxhopTextFieldActionPerformed(null); } } public int getMaxhop(){ return maxhop; } public int sortPath; // sort paths in path mode: sup, conf, hop public void setSortPath(int sortPath){ this.sortPath = sortPath; if(initiated)

sortComboBox.setSelectedIndex(sortPath==NavizPathServlet.PATH_SUPPORT_R OW?0:(sortPath==NavizPathServlet.PATH_CONFIDENCE_ROW?1:2)); } public int getSortPath(){ return sortPath; } public int sortType; // sort paths in path mode: ASCENDING, DESCENDING; public void setSortType(int sortType){ this.sortType = sortType; if(initiated){ if(sortType==ASCENDING) ascButtonActionPerformed(null); else descButtonActionPerformed(null); } } public int getSortType(){ return sortType; } public int pathType; // type of path: CLOSED_CLOSED, OPEN_CLOSED, CLOSED_OPEN, OPEN_OPEN public void setPathType(int pathType){ this.pathType = pathType; if(initiated){ switch(pathType){ case OPEN_OPEN: openOpenButtonActionPerformed(null); break; case OPEN_CLOSED: openClosedButtonActionPerformed(null); break; case CLOSED_OPEN: closedOpenButtonActionPerformed(null); break; case CLOSED_CLOSED: closedClosedButtonActionPerformed(null); break; } } } public int getPathType(){ return pathType; } private int pathNo; // current path number showed in path mode public int getPathNo() { return pathNo;

A11

Appendix Naviz Applet Class


} public void setPathNo(int pathNo){ this.pathNo = pathNo; if(initiated) pathNoScrollBar.setValue(pathNo); } private int maxPathNo; // maximum found path number public int getMaxPathNo() { return maxPathNo; } public void setMaxPathNo(int maxPathNo){ if(maxPathNo>=0){ this.maxPathNo = maxPathNo; if(initiated){ pathNoScrollBar.setVisibleAmount ((int)(maxPathNo/10)); pathNoScrollBar.setBlockIncrement ((int)(maxPathNo/10)); pathNoScrollBar.setMaximum (maxPathNo+(int)(maxPathNo/10)); } } } private int pathOrderByRow; // order paths by sup or conf public int getPathOrderByRow() { return pathOrderByRow; } public void setPathOrderByRow(int pathOrderByRow){ if (pathOrderByRow==NavizPathServlet.PATH_LENGTH_ROW||pathOrderByRow==Navi zPathServlet.PATH_SUPPORT_ROW||pathOrderByRow==NavizPathServlet.PATH_CO NFIDENCE_ROW) this.pathOrderByRow = pathOrderByRow; } private boolean pathWorkFinished; // flag to indicate that path servlet has finished the work public boolean isPathWorkFinished() { return pathWorkFinished; } public void setPathWorkFinished(boolean pathWorkFinished) { this.pathWorkFinished = pathWorkFinished; } public void addPathNodes(String selectedNode){ pathNodes.addElement(selectedNode); } public void addAvoidNodes(String selectedNode){ avoidNodes.addElement(selectedNode); } // GraphViz Variables private boolean dotCenter; // centers drawing on page: true, false private boolean dotConcentrate; // enable edges concentrators: true, false private int dotFontsize; // point size of label: in points private double dotXMargin; // margin included in page: private double dotYMargin; // margin included in page: private int dotMclimit; // adjust mincross iterations: f times public void setDotMclimit(int dotMclimit){ this.dotMclimit = dotMclimit; if(initiated){ mcTextField.setText(String.valueOf(dotMclimit)); mcTextFieldActionPerformed(null); } } public int getDotMclimit(){ return dotMclimit; } private double dotNodesep; // separation between nodes, in inches private int dotNslimit; // bounds network simplex iterations by f (num of nodes) public void setDotNslimit(int dotNslimit){ this.dotNslimit = dotNslimit; if(initiated){ nsTextField.setText(String.valueOf(dotNslimit)); nsTextFieldActionPerformed(null); } } public int getDotNslimit(){ return dotNslimit; } //private double dotXPage; // unit of pagination: in inches //private double dotYPage; // unit of pagination: in inches private double dotRanksep; // separation between ranks, in inches private double dotRotate; // rotation: in degree private double dotXSize; // graph size: in inches public double getDotXSize() { return dotXSize; } public void setDotXSize(double dotXSize){ this.dotXSize = dotXSize; } private double dotYSize; // graph size: in inches public double getDotYSize() { return dotYSize;

A12

Appendix Naviz Applet Class


} public void setDotYSize(double dotYSize){ this.dotYSize = dotYSize; } private String dotClusterrank; // rank of cluster: local, global, none private String dotColor; // background or cluster outline color: "hue saturation brightness", colorname private String dotFontcolor; // type face color: colorname private String dotFontname; // PostScript font family: fontname private String dotLabel; // graph label: any string private boolean dotOrdering; // for ordered edges: out public void setDotOrdering(boolean dotOrdering){ this.dotOrdering = dotOrdering; if(initiated){ if(dotOrdering = false) orderingButton.setText("?"); else orderingButton.setText("?"); orderingButtonActionPerformed(null); } } public boolean isDotOrdering(){ return dotOrdering; } private String dotOrientation; // orientation: portrait, landscape private String dotRank; // rank: same, min, max private String dotRankdir; // rank direction: LR: left-right or TB: top-bottom public void setDotRankdir(String dotRankdir){ this.dotRankdir = dotRankdir; if(initiated){ if(dotRankdir.equals("TB")) directionButton.setText("v"); else directionButton.setText(">"); directionButtonActionPerformed(null); } } public String getDotRankdir(){ return dotRankdir; } private String dotRatio; // ratio: auto, compress, fill, x/y ratio private int nodeFontsize; // size of font in node in points public int getNodeFontsize() { return nodeFontsize; } public void setNodeFontsize(int nodeFontsize){ this.nodeFontsize = nodeFontsize; } private String nodeColor; // color of node private String nodeFontcolor; // color of font in node private String nodeFontname; // name of font in node public String getNodeFontname() { return nodeFontname; } public void setNodeFontname(String nodeFontname){ this.nodeFontname = nodeFontname; } private String nodeShape; // shape of node private private ranks private private private private int edgeFontsize; // size of font in edge in points int edgeMinlen; // minimum distance between start and end: in String String String String edgeColor; // color of edge edgeFontcolor; // color of font in edge edgeFontname; // name of font in edge edgeDir; // edge direction: forward, back, both, none

/** Creates new form NavizApplet */ public NavizApplet() { initComponents (); // Create the drawing area canvas = new NavizCanvas(); canvas.setDoubleBuffered (true); canvas.setOpaque (true); canvas.setBackground(Color.white); canvas.addMouseListener(new MouseAdapter() { public void mouseClicked(MouseEvent evt) { canvasMouseClicked(evt); } } ); canvas.addMouseMotionListener(new MouseMotionAdapter() { public void mouseMoved(MouseEvent evt) { canvasMouseMoved(evt); } } ); canvasPanel.add(canvas); canvas.setApplet(this); // Create the diagram popup menu.

A13

Appendix Naviz Applet Class


popup = new JPopupMenu(); JMenuItem menuItem = new JMenuItem("Open URL"); menuItem.setActionCommand("Open URL"); menuItem.addActionListener(canvas); popup.add(menuItem); menuItem = new JMenuItem("Property"); menuItem.setActionCommand("Property"); menuItem.addActionListener(canvas); popup.add(menuItem); // Create the path popup menu. pathPopup = new JPopupMenu(); menuItem = new JMenuItem("Select"); menuItem.setActionCommand("Select"); menuItem.addActionListener(canvas); pathPopup.add(menuItem); menuItem = new JMenuItem("Avoid"); menuItem.setActionCommand("Avoid"); menuItem.addActionListener(canvas); pathPopup.add(menuItem); menuItem = new JMenuItem("Clear"); menuItem.setActionCommand("Clear"); menuItem.addActionListener(canvas); pathPopup.add(menuItem); pathPopup.addSeparator(); menuItem = new JMenuItem("Open URL"); menuItem.setActionCommand("Open URL"); menuItem.addActionListener(canvas); pathPopup.add(menuItem); menuItem = new JMenuItem("Property"); menuItem.setActionCommand("Property"); menuItem.addActionListener(canvas); pathPopup.add(menuItem); //Add listener to components that can bring up popup menus. popupListener = new PopupListener(); pathPopupListener = new PathPopupListener(); canvas.addMouseListener(popupListener); // Create number format for sup, conf textbox numberFormat = NumberFormat.getInstance(); if (numberFormat instanceof DecimalFormat) { ((DecimalFormat) numberFormat).setMaximumIntegerDigits(3); initiated = false; copiedData = false; attributeWorkFinished = false; appletNum = 0; parentNum = -1; windowColNum = 3; windowRowNum = 2; windowMaxHor = 1.0; windowMaxVer = 1.0; propertyPage = "NavizProperty.jsp"; ((DecimalFormat) numberFormat).setMaximumFractionDigits(2); } // Set to invisible the detail control panel maxsupLabel.setVisible(false); maxsupScrollBar.setVisible(false); maxsupTextField.setVisible(false); maxsupPercent.setVisible(false); incsupLabel.setVisible(false); incsupTextField.setVisible(false); incsupPercent.setVisible(false); maxconfLabel.setVisible(false); maxconfScrollBar.setVisible(false); maxconfTextField.setVisible(false); maxconfPercent.setVisible(false); incconfLabel.setVisible(false); incconfTextField.setVisible(false); incconfPercent.setVisible(false); orderComboBox.setVisible(false); weightComboBox.setVisible(false); widthComboBox.setVisible(false); colorComboBox.setVisible(false); orderLabel.setVisible(false); weightLabel.setVisible(false); widthLabel.setVisible(false); colorLabel.setVisible(false); directionButton.setVisible(false); orderingButton.setVisible(false); mcLabel.setVisible(false); mcTextField.setVisible(false); nsLabel.setVisible(false); nsTextField.setVisible(false); // Set initial general variables

A14

Appendix Naviz Applet Class


numberFormat = NumberFormat.getInstance(); if (numberFormat instanceof DecimalFormat){ ((DecimalFormat)numberFormat).setMaximumIntegerDigits(3); ((DecimalFormat)numberFormat).setMaximumFractionDigits(3); } placeIndex = 0; categoryIndex = 0; fromHourIndex = 0; toHourIndex = 0; newWinWidth = 1024; newWinHeight = 768; hours = new Vector(13); Vector hour = new Vector(NavizAttributeServlet.ATTRIBUTE_TUPLE_SIZE); //insert id hour.addElement(new Integer(0)); //insert cnt hour.addElement(new Integer(0)); //insert code hour.addElement("All"); //insert name hour.addElement("All"); hours.addElement(hour); Vector hour0 = new Vector(NavizAttributeServlet.ATTRIBUTE_TUPLE_SIZE); //insert id hour0.addElement(new Integer(10)); //insert cnt hour0.addElement(new Integer(0)); //insert code hour0.addElement("Night"); //insert name hour0.addElement("00:00"); hours.addElement(hour0); Vector hour1 = new Vector(NavizAttributeServlet.ATTRIBUTE_TUPLE_SIZE); //insert id hour1.addElement(new Integer(11)); //insert cnt hour1.addElement(new Integer(0)); //insert code hour1.addElement("Night"); //insert name hour1.addElement("02:00"); hours.addElement(hour1); Vector hour2 = new Vector(NavizAttributeServlet.ATTRIBUTE_TUPLE_SIZE); //insert id hour2.addElement(new Integer(12)); //insert cnt hour2.addElement(new Integer(0)); //insert code hour2.addElement("Night"); //insert name hour2.addElement("04:00"); hours.addElement(hour2); Vector hour11 = new Vector(NavizAttributeServlet.ATTRIBUTE_TUPLE_SIZE); //insert id hour11.addElement(new Integer(13)); //insert cnt hour11.addElement(new Integer(0)); //insert code hour11.addElement("Day"); //insert name hour11.addElement("06:00"); hours.addElement(hour11); Vector hour3 = new Vector(NavizAttributeServlet.ATTRIBUTE_TUPLE_SIZE); //insert id hour3.addElement(new Integer(14)); //insert cnt hour3.addElement(new Integer(0)); //insert code hour3.addElement("Day"); //insert name hour3.addElement("08:00"); hours.addElement(hour3); Vector hour4 = new Vector(NavizAttributeServlet.ATTRIBUTE_TUPLE_SIZE); //insert id hour4.addElement(new Integer(15)); //insert cnt hour4.addElement(new Integer(0)); //insert code

A15

Appendix Naviz Applet Class


hour4.addElement("Day"); //insert name hour4.addElement("10:00"); hours.addElement(hour4); Vector hour5 = new Vector(NavizAttributeServlet.ATTRIBUTE_TUPLE_SIZE); //insert id hour5.addElement(new Integer(16)); //insert cnt hour5.addElement(new Integer(0)); //insert code hour5.addElement("Day"); //insert name hour5.addElement("12:00"); hours.addElement(hour5); Vector hour6 = new Vector(NavizAttributeServlet.ATTRIBUTE_TUPLE_SIZE); //insert id hour6.addElement(new Integer(17)); //insert cnt hour6.addElement(new Integer(0)); //insert code hour6.addElement("Day"); //insert name hour6.addElement("14:00"); hours.addElement(hour6); Vector hour7 = new Vector(NavizAttributeServlet.ATTRIBUTE_TUPLE_SIZE); //insert id hour7.addElement(new Integer(18)); //insert cnt hour7.addElement(new Integer(0)); //insert code hour7.addElement("Day"); //insert name hour7.addElement("16:00"); hours.addElement(hour7); Vector hour8 = new Vector(NavizAttributeServlet.ATTRIBUTE_TUPLE_SIZE); //insert id hour8.addElement(new Integer(19)); //insert cnt hour8.addElement(new Integer(0)); //insert code hour8.addElement("Night"); //insert name hour8.addElement("18:00"); hours.addElement(hour8); Vector hour9 = new Vector(NavizAttributeServlet.ATTRIBUTE_TUPLE_SIZE); //insert id hour9.addElement(new Integer(20)); //insert cnt hour9.addElement(new Integer(0)); //insert code hour9.addElement("Night"); //insert name hour9.addElement("20:00"); hours.addElement(hour9); Vector hour10 = new Vector(NavizAttributeServlet.ATTRIBUTE_TUPLE_SIZE); //insert id hour10.addElement(new Integer(21)); //insert cnt hour10.addElement(new Integer(0)); //insert code hour10.addElement("Night"); //insert name hour10.addElement("22:00"); hours.addElement(hour10); // Set initial diagram website = null; fromHour = 0; toHour = 0; place = 0; category = 0; comparison = 1; selectedNode = null; selectedEdge = null; minsup = 0.6; maxsup = 100.0; layoutMinsup = 0.6; layoutMaxsup = 100.0; incsup = 0.1;

A16

Appendix Naviz Applet Class


minconf = 0.0; maxconf = 100.0; layoutMinconf = 0.0; layoutMaxconf = 100.0; incconf = 1.0; minLineWidth = 1.0; maxLineWidth = 10.0; maxHue = 0.625; // Set initial edge orderByRow = NavizServlet.EDGE_SUPPORT_ROW; weightByRow = NavizServlet.EDGE_CONFIDENCE_ROW; widthByRow = NavizServlet.EDGE_SUPPORT_ROW; colorByRow = NavizServlet.EDGE_CONFIDENCE_ROW; pathColorByRow = NavizServlet.EDGE_SUPPORT_ROW; requestPacket = new NavizRequest(); workFinished = false; // Set initial path minhop = 1; maxhop = 100; pathNo = 0; pathNodes = new Vector(PATH_NODES_INITIAL_CAPACITY,PATH_NODES_CAPACITY_INCREMENT); pathNodes.addElement("00"); pathNodes.addElement("99"); permanentPathNodes = (Vector)pathNodes.clone(); avoidNodes = new Vector(PATH_NODES_INITIAL_CAPACITY,PATH_NODES_CAPACITY_INCREMENT); permanentAvoidNodes = (Vector)avoidNodes.clone(); pathType = CLOSED_CLOSED; sortPath = NavizPathServlet.PATH_SUPPORT_ROW; sortType = DESCENDING; pathOrderByRow = NavizPathServlet.PATH_SUPPORT_ROW; pathRequestPacket = new NavizPathRequest(); pathWorkFinished = false; pathCompleted = false; // Set initial GraphViz dotCenter = true; // centers drawing on page: true, false dotOrdering = false; // enable edges concentrators: true, false dotFontsize = 12; // point size of label: in points dotXMargin = 0.0; dotYMargin = 0.0; // margin included in page: dotMclimit = 1; // adjust mincross iterations: f times dotNodesep = 0.25; // separation between nodes, in inches dotNslimit = 1; // bounds network simplex iterations by f (num of nodes) //dotXPage; //dotYPage; // unit of pagination: in inches dotRanksep = 0.25; // separation between ranks, in inches dotRotate = 0; // rotation: in degree dotXSize = 12.0; dotYSize = 7.0; // graph size: in inches dotClusterrank = "none"; // rank of cluster: local, global, none dotColor = "white"; // background or cluster outline color: "hue saturation brightness", colorname dotFontcolor = "black"; // type face color: colorname dotFontname = "Helvetica"; // PostScript font family: fontname dotLabel = ""; // graph label: any string dotOrdering = false; // for ordered edges: out dotOrientation = "portrait"; // orientation: portrait, landscape dotRank = "same"; // rank: same, min, max dotRankdir = "TB"; // rank direction: LR: left-right or TB: top-bottom dotRatio = "fill"; //dotRatio = String.valueOf(dotYSize/dotXSize); // ratio: auto, compress, fill, y/x ratio nodeFontsize = 26; // in points nodeColor = "black"; nodeFontcolor = "black"; nodeFontname = "Helvetica"; nodeShape = "ellipse"; // ellipse, box, circle, doublecircle, diamond, plaintext, record, polygon edgeFontsize = 12; edgeMinlen = 1; ranks edgeColor = "black"; edgeFontcolor = "black"; edgeFontname = "Helvetica"; edgeDir = "forward"; // edge direction: forward, back, both, none } /** This method is called from within the constructor to * initialize the form. * WARNING: Do NOT modify this code. The content of this method is * always regenerated by the Form Editor.

// minimum distance between start and end: in

A17

Appendix Naviz Applet Class


*/ private void initComponents() {//GEN-BEGIN:initComponents mainPanel = new JPanel(); controlScrollPane = new JScrollPane(); controlView = new JPanel(); minsupLabel = new JLabel(); minsupScrollBar = new JScrollBar(); minsupTextField = new JTextField(); jLabel21 = new JLabel(); minconfLabel = new JLabel(); minconfScrollBar = new JScrollBar(); minconfTextField = new JTextField(); jLabel22 = new JLabel(); pathButton = new JButton(); pathNoScrollBar = new JScrollBar(); pathNoTextField = new JTextField(); closedClosedButton = new JButton(); openOpenButton = new JButton(); openClosedButton = new JButton(); closedOpenButton = new JButton(); sortComboBox = new JComboBox(); ascButton = new JButton(); descButton = new JButton(); hopCheckBox = new JCheckBox(); minhopTextField = new JTextField(); maxhopTextField = new JTextField(); layoutButton = new JButton(); detailButton = new JButton(); launchButton = new JButton(); viewTimeButton = new JButton(); maxsupScrollBar = new JScrollBar(); maxsupLabel = new JLabel(); maxsupTextField = new JTextField(); maxsupPercent = new JLabel(); maxconfScrollBar = new JScrollBar(); maxconfLabel = new JLabel(); maxconfTextField = new JTextField(); maxconfPercent = new JLabel(); incsupLabel = new JLabel(); incsupTextField = new JTextField(); incsupPercent = new JLabel(); incconfLabel = new JLabel(); incconfTextField = new JTextField(); incconfPercent = new JLabel(); orderLabel = new JLabel(); orderComboBox = new JComboBox(); weightLabel = new JLabel(); weightComboBox = new JComboBox(); widthLabel = new JLabel(); widthComboBox = new JComboBox(); colorLabel = new JLabel(); colorComboBox = new JComboBox(); mcLabel = new JLabel(); mcTextField = new JTextField(); nsLabel = new JLabel(); nsTextField = new JTextField(); orderingButton = new JButton(); directionButton = new JButton(); windowColNumTextField = new JTextField(); windowRowNumTextField = new JTextField(); windowMaxHorTextField = new JTextField(); windowMaxVerTextField = new JTextField(); placeButton = new JButton(); categoryButton = new JButton(); placeComboBox = new JComboBox(); categoryComboBox = new JComboBox(); toHourComboBox = new JComboBox(); fromHourComboBox = new JComboBox(); comparisonButton = new JButton(); widthTextField = new JTextField(); heightTextField = new JTextField(); canvasPanel = new JPanel(); getContentPane().setLayout(null); mainPanel.setLayout(null); mainPanel.setBorder(new border.SoftBevelBorder(border.BevelBorder.RAISED)); controlScrollPane.setBorder(null); controlScrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROL LBAR_NEVER); controlView.setLayout(null); controlView.setPreferredSize(new Dimension(450, 50)); minsupLabel.setFont(new Font("Dialog", 1, 10)); minsupLabel.setText("Minsup"); minsupLabel.setToolTipText("Minimum support of data"); minsupLabel.addMouseListener(new MouseAdapter() { public void mouseClicked(MouseEvent evt) { minsupLabelMouseClicked(evt);

A18

Appendix Naviz Applet Class


} }); controlView.add(minsupLabel); minsupLabel.setBounds(230, 0, 36, 20); minsupScrollBar.setBlockIncrement(100); minsupScrollBar.setMaximum(1100); minsupScrollBar.setOrientation(JScrollBar.HORIZONTAL); minsupScrollBar.setToolTipText("Minimum support of data"); minsupScrollBar.setVisibleAmount(100); minsupScrollBar.setPreferredSize(new Dimension(100, 20)); minsupScrollBar.addAdjustmentListener(new AdjustmentListener() { public void adjustmentValueChanged(AdjustmentEvent evt) { minsupScrollBarAdjustmentValueChanged(evt); } }); controlView.add(minsupScrollBar); minsupScrollBar.setBounds(270, 0, 80, 20); minsupTextField.setText("0.7"); minsupTextField.setToolTipText("Minimum support of data"); minsupTextField.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { minsupTextFieldActionPerformed(evt); } }); minsupTextField.addFocusListener(new FocusAdapter() { public void focusLost(FocusEvent evt) { minsupTextFieldFocusLost(evt); } }); controlView.add(minsupTextField); minsupTextField.setBounds(350, 0, 30, 20); jLabel21.setText("%"); controlView.add(jLabel21); jLabel21.setBounds(380, 0, 10, 16); minconfLabel.setFont(new Font("Dialog", 1, 10)); minconfLabel.setText("Minconf"); minconfLabel.setToolTipText("Minimum confidence of data"); minconfLabel.addMouseListener(new MouseAdapter() { public void mouseClicked(MouseEvent evt) { minconfLabelMouseClicked(evt); } }); controlView.add(minconfLabel); minconfLabel.setBounds(230, 20, 40, 20); minconfScrollBar.setMaximum(110); minconfScrollBar.setOrientation(JScrollBar.HORIZONTAL); minconfScrollBar.setToolTipText("Minimum confidence of data"); minconfScrollBar.setPreferredSize(new Dimension(100, 20)); minconfScrollBar.addAdjustmentListener(new AdjustmentListener() { public void adjustmentValueChanged(AdjustmentEvent evt) { minconfScrollBarAdjustmentValueChanged(evt); } }); controlView.add(minconfScrollBar); minconfScrollBar.setBounds(270, 20, 80, 20); minconfTextField.setText("0"); minconfTextField.setToolTipText("Minimum confidence of data"); minconfTextField.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { minconfTextFieldActionPerformed(evt); } }); minconfTextField.addFocusListener(new FocusAdapter() { public void focusLost(FocusEvent evt) { minconfTextFieldFocusLost(evt); } }); controlView.add(minconfTextField); minconfTextField.setBounds(350, 20, 30, 20); jLabel22.setText("%"); controlView.add(jLabel22); jLabel22.setBounds(380, 20, 10, 16); pathButton.setFont(new Font("Dialog", 1, 10)); pathButton.setText("Path"); pathButton.setToolTipText("Switch between diagram mode and path mode");

A19

Appendix Naviz Applet Class


pathButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { pathButtonActionPerformed(evt); } }); controlView.add(pathButton); pathButton.setBounds(390, 0, 110, 20); pathNoScrollBar.setMaximum(110); pathNoScrollBar.setOrientation(JScrollBar.HORIZONTAL); pathNoScrollBar.setToolTipText("Number of path to be displayed"); pathNoScrollBar.setPreferredSize(new Dimension(100, 20)); pathNoScrollBar.setEnabled(false); pathNoScrollBar.addAdjustmentListener(new AdjustmentListener() { public void adjustmentValueChanged(AdjustmentEvent evt) { pathNoScrollBarAdjustmentValueChanged(evt); } }); controlView.add(pathNoScrollBar); pathNoScrollBar.setBounds(390, 20, 80, 20); pathNoTextField.setText("0"); pathNoTextField.setToolTipText("Number of path to be displayed"); pathNoTextField.setEnabled(false); pathNoTextField.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { pathNoTextFieldActionPerformed(evt); } }); pathNoTextField.addFocusListener(new FocusAdapter() { public void focusLost(FocusEvent evt) { pathNoTextFieldFocusLost(evt); } }); controlView.add(pathNoTextField); pathNoTextField.setBounds(470, 20, 30, 20); closedClosedButton.setFont(new Font("Dialog", 0, 10)); closedClosedButton.setText("||"); closedClosedButton.setToolTipText("Find closed-closed path"); closedClosedButton.setBorder(new border.BevelBorder(border.BevelBorder.RAISED)); closedClosedButton.setMargin(new Insets(1, 1, 1, 1)); closedClosedButton.setEnabled(false); closedClosedButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { closedClosedButtonActionPerformed(evt); } }); controlView.add(closedClosedButton); closedClosedButton.setBounds(500, 0, 20, 20); openOpenButton.setFont(new Font("Dialog", 0, 10)); openOpenButton.setText("<>"); openOpenButton.setToolTipText("Find open-open path"); openOpenButton.setBorder(new border.BevelBorder(border.BevelBorder.RAISED)); openOpenButton.setMargin(new Insets(1, 1, 1, 1)); openOpenButton.setEnabled(false); openOpenButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { openOpenButtonActionPerformed(evt); } }); controlView.add(openOpenButton); openOpenButton.setBounds(520, 0, 20, 20); openClosedButton.setFont(new Font("Dialog", 0, 10)); openClosedButton.setText("<|"); openClosedButton.setToolTipText("Find open-closed path"); openClosedButton.setBorder(new border.BevelBorder(border.BevelBorder.RAISED)); openClosedButton.setMargin(new Insets(1, 1, 1, 1)); openClosedButton.setEnabled(false); openClosedButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { openClosedButtonActionPerformed(evt); } }); controlView.add(openClosedButton); openClosedButton.setBounds(500, 20, 20, 20); closedOpenButton.setFont(new Font("Dialog", 0, 10)); closedOpenButton.setText("|>"); closedOpenButton.setToolTipText("Find closed-open path");

A20

Appendix Naviz Applet Class


closedOpenButton.setBorder(new border.BevelBorder(border.BevelBorder.RAISED)); closedOpenButton.setMargin(new Insets(1, 1, 1, 1)); closedOpenButton.setEnabled(false); closedOpenButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { closedOpenButtonActionPerformed(evt); } }); controlView.add(closedOpenButton); closedOpenButton.setBounds(520, 20, 20, 20); sortComboBox.setFont(new Font("Dialog", 0, 10)); sortComboBox.setModel(new DefaultComboBoxModel(new String[] { "sup", "conf", "hop" })); sortComboBox.setToolTipText("Sort path by sup, conf or hop"); sortComboBox.setEnabled(false); sortComboBox.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { sortComboBoxActionPerformed(evt); } }); controlView.add(sortComboBox); sortComboBox.setBounds(540, 0, 50, 20); ascButton.setFont(new Font("Dialog", 0, 10)); ascButton.setText("v"); ascButton.setToolTipText("Ascending sorting"); ascButton.setBorder(new border.BevelBorder(border.BevelBorder.RAISED)); ascButton.setMargin(new Insets(0, 0, 0, 0)); ascButton.setSelected(true); ascButton.setEnabled(false); ascButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { ascButtonActionPerformed(evt); } }); controlView.add(ascButton); ascButton.setBounds(590, 0, 10, 20); descButton.setFont(new Font("Dialog", 0, 10)); descButton.setText("^"); descButton.setToolTipText("Descending sorting"); descButton.setBorder(new border.BevelBorder(border.BevelBorder.RAISED)); descButton.setMargin(new Insets(0, 0, 0, 0)); descButton.setEnabled(false); descButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { descButtonActionPerformed(evt); } }); controlView.add(descButton); descButton.setBounds(600, 0, 10, 20); hopCheckBox.setFont(new Font("Dialog", 0, 10)); hopCheckBox.setToolTipText("Hop number filtering"); hopCheckBox.setMargin(new Insets(0, 0, 0, 0)); hopCheckBox.setMaximumSize(new Dimension(10, 21)); hopCheckBox.setMinimumSize(new Dimension(10, 21)); hopCheckBox.setPreferredSize(new Dimension(10, 21)); hopCheckBox.setEnabled(false); hopCheckBox.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { hopCheckBoxActionPerformed(evt); } }); controlView.add(hopCheckBox); hopCheckBox.setBounds(540, 20, 10, 21); minhopTextField.setText("0"); minhopTextField.setToolTipText("Minimum hop number of path"); minhopTextField.setEnabled(false); minhopTextField.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { minhopTextFieldActionPerformed(evt); } }); minhopTextField.addFocusListener(new FocusAdapter() { public void focusLost(FocusEvent evt) { minhopTextFieldFocusLost(evt); } }); controlView.add(minhopTextField);

A21

Appendix Naviz Applet Class


minhopTextField.setBounds(550, 20, 30, 20); maxhopTextField.setText("0"); maxhopTextField.setToolTipText("Maximum hop number of path"); maxhopTextField.setEnabled(false); maxhopTextField.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { maxhopTextFieldActionPerformed(evt); } }); maxhopTextField.addFocusListener(new FocusAdapter() { public void focusLost(FocusEvent evt) { maxhopTextFieldFocusLost(evt); } }); controlView.add(maxhopTextField); maxhopTextField.setBounds(580, 20, 30, 20); layoutButton.setFont(new Font("Dialog", 1, 10)); layoutButton.setText("Layout"); layoutButton.setToolTipText("Change layout according to minimum and maximum limit"); layoutButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { layoutButtonActionPerformed(evt); } }); controlView.add(layoutButton); layoutButton.setBounds(610, 0, 80, 20); detailButton.setFont(new Font("Dialog", 1, 10)); detailButton.setText("Detail >>"); detailButton.setToolTipText("Show or hide detail settings"); detailButton.setHorizontalTextPosition(SwingConstants.CENTER); detailButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { detailButtonActionPerformed(evt); } }); controlView.add(detailButton); detailButton.setBounds(610, 20, 80, 20); launchButton.setFont(new Font("Dialog", 0, 10)); launchButton.setText("_|_|_|"); launchButton.setToolTipText("Launch multiple windows"); launchButton.setBorder(new border.BevelBorder(border.BevelBorder.RAISED)); launchButton.setMargin(new Insets(1, 1, 1, 1)); launchButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { launchButtonActionPerformed(evt); } }); controlView.add(launchButton); launchButton.setBounds(730, 0, 40, 20); viewTimeButton.setFont(new Font("Dialog", 0, 10)); viewTimeButton.setText("Time"); viewTimeButton.setToolTipText("Launch time behavior comparison"); viewTimeButton.setBorder(new border.BevelBorder(border.BevelBorder.RAISED)); viewTimeButton.setMargin(new Insets(1, 1, 1, 1)); viewTimeButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { viewTimeButtonActionPerformed(evt); } }); controlView.add(viewTimeButton); viewTimeButton.setBounds(730, 20, 40, 20); maxsupScrollBar.setBlockIncrement(100); maxsupScrollBar.setMaximum(1100); maxsupScrollBar.setOrientation(JScrollBar.HORIZONTAL); maxsupScrollBar.setToolTipText("Maximum support of data"); maxsupScrollBar.setValue(1000); maxsupScrollBar.setVisibleAmount(100); maxsupScrollBar.setPreferredSize(new Dimension(100, 20)); maxsupScrollBar.addAdjustmentListener(new AdjustmentListener() { public void adjustmentValueChanged(AdjustmentEvent evt) { maxsupScrollBarAdjustmentValueChanged(evt); } }); controlView.add(maxsupScrollBar); maxsupScrollBar.setBounds(850, 0, 80, 20);

A22

Appendix Naviz Applet Class


maxsupLabel.setFont(new Font("Dialog", 1, 10)); maxsupLabel.setText("Maxsup"); maxsupLabel.setToolTipText("Maximum support of data"); controlView.add(maxsupLabel); maxsupLabel.setBounds(810, 0, 50, 20); maxsupTextField.setText("100"); maxsupTextField.setToolTipText("Maximum support of data"); maxsupTextField.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { maxsupTextFieldActionPerformed(evt); } }); maxsupTextField.addFocusListener(new FocusAdapter() { public void focusLost(FocusEvent evt) { maxsupTextFieldFocusLost(evt); } }); controlView.add(maxsupTextField); maxsupTextField.setBounds(930, 0, 30, 20); maxsupPercent.setText("%"); controlView.add(maxsupPercent); maxsupPercent.setBounds(960, 0, 9, 16); maxconfScrollBar.setMaximum(110); maxconfScrollBar.setOrientation(JScrollBar.HORIZONTAL); maxconfScrollBar.setToolTipText("Maximum confidence of data"); maxconfScrollBar.setValue(100); maxconfScrollBar.setPreferredSize(new Dimension(100, 20)); maxconfScrollBar.addAdjustmentListener(new AdjustmentListener() { public void adjustmentValueChanged(AdjustmentEvent evt) { maxconfScrollBarAdjustmentValueChanged(evt); } }); controlView.add(maxconfScrollBar); maxconfScrollBar.setBounds(850, 20, 80, 20); maxconfLabel.setFont(new Font("Dialog", 1, 10)); maxconfLabel.setText("Maxconf"); maxconfLabel.setToolTipText("Maximum confidence of data"); controlView.add(maxconfLabel); maxconfLabel.setBounds(810, 20, 50, 20);

maxconfTextField.setText("100"); maxconfTextField.setToolTipText("Maximum confidence of data"); maxconfTextField.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { maxconfTextFieldActionPerformed(evt); } }); maxconfTextField.addFocusListener(new FocusAdapter() { public void focusLost(FocusEvent evt) { maxconfTextFieldFocusLost(evt); } }); controlView.add(maxconfTextField); maxconfTextField.setBounds(930, 20, 30, 20); maxconfPercent.setText("%"); controlView.add(maxconfPercent); maxconfPercent.setBounds(960, 20, 9, 16); incsupLabel.setFont(new Font("Dialog", 1, 10)); incsupLabel.setText("Inc"); incsupLabel.setToolTipText("Incremental value of support"); controlView.add(incsupLabel); incsupLabel.setBounds(970, 0, 20, 20); incsupTextField.setText("0.1"); incsupTextField.setToolTipText("Incremental value of support"); incsupTextField.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { incsupTextFieldActionPerformed(evt); } }); incsupTextField.addFocusListener(new FocusAdapter() { public void focusLost(FocusEvent evt) { incsupTextFieldFocusLost(evt); } }); controlView.add(incsupTextField); incsupTextField.setBounds(990, 0, 30, 20); incsupPercent.setText("%");

A23

Appendix Naviz Applet Class


controlView.add(incsupPercent); incsupPercent.setBounds(1020, 0, 9, 16); incconfLabel.setFont(new Font("Dialog", 1, 10)); incconfLabel.setText("Inc"); incconfLabel.setToolTipText("Incremental value of confidence"); controlView.add(incconfLabel); incconfLabel.setBounds(970, 20, 20, 20); incconfTextField.setText("1"); incconfTextField.setToolTipText("Incremental value of confidence"); incconfTextField.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { incconfTextFieldActionPerformed(evt); } }); incconfTextField.addFocusListener(new FocusAdapter() { public void focusLost(FocusEvent evt) { incconfTextFieldFocusLost(evt); } }); controlView.add(incconfTextField); incconfTextField.setBounds(990, 20, 30, 20); incconfPercent.setText("%"); controlView.add(incconfPercent); incconfPercent.setBounds(1020, 20, 9, 16); orderLabel.setFont(new Font("Dialog", 0, 10)); orderLabel.setText("Order"); orderLabel.setToolTipText("Order edge by support or confidence"); controlView.add(orderLabel); orderLabel.setBounds(1030, 0, 26, 20); orderComboBox.setFont(new Font("Dialog", 0, 10)); orderComboBox.setMaximumRowCount(2); orderComboBox.setModel(new DefaultComboBoxModel(new String[] { "sup", "conf" })); orderComboBox.setToolTipText("Order edge by support or confidence"); orderComboBox.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { orderComboBoxActionPerformed(evt); } });

controlView.add(orderComboBox); orderComboBox.setBounds(1070, 0, 50, 20); weightLabel.setFont(new Font("Dialog", 0, 10)); weightLabel.setText("Weight"); weightLabel.setToolTipText("Weighten edge by support or confidence"); controlView.add(weightLabel); weightLabel.setBounds(1030, 20, 33, 20); weightComboBox.setFont(new Font("Dialog", 0, 10)); weightComboBox.setMaximumRowCount(2); weightComboBox.setModel(new DefaultComboBoxModel(new String[] { "sup", "conf" })); weightComboBox.setToolTipText("Weighten edge by support or confidence"); weightComboBox.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { weightComboBoxActionPerformed(evt); } }); controlView.add(weightComboBox); weightComboBox.setBounds(1070, 20, 50, 20); widthLabel.setFont(new Font("Dialog", 0, 10)); widthLabel.setText("Width"); widthLabel.setToolTipText("Edge width by support or confidence"); controlView.add(widthLabel); widthLabel.setBounds(1120, 0, 27, 20); widthComboBox.setFont(new Font("Dialog", 0, 10)); widthComboBox.setMaximumRowCount(2); widthComboBox.setModel(new DefaultComboBoxModel(new String[] { "sup", "conf" })); widthComboBox.setToolTipText("Edge width by support or confidence"); widthComboBox.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { widthComboBoxActionPerformed(evt); } }); controlView.add(widthComboBox); widthComboBox.setBounds(1150, 0, 50, 20);

A24

Appendix Naviz Applet Class


colorLabel.setFont(new Font("Dialog", 0, 10)); colorLabel.setText("Color"); colorLabel.setToolTipText("Edge color by support or confidence"); controlView.add(colorLabel); colorLabel.setBounds(1120, 20, 25, 20); colorComboBox.setFont(new Font("Dialog", 0, 10)); colorComboBox.setMaximumRowCount(2); colorComboBox.setModel(new DefaultComboBoxModel(new String[] { "sup", "conf" })); colorComboBox.setToolTipText("Edge color by support or confidence"); colorComboBox.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { colorComboBoxActionPerformed(evt); } }); controlView.add(colorComboBox); colorComboBox.setBounds(1150, 20, 50, 20); mcLabel.setFont(new Font("Dialog", 0, 10)); mcLabel.setText("mc"); mcLabel.setToolTipText("Minimum cross iteration factor"); controlView.add(mcLabel); mcLabel.setBounds(1200, 0, 15, 20); mcTextField.setText("1"); mcTextField.setToolTipText("Minimum cross iteration factor"); mcTextField.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { mcTextFieldActionPerformed(evt); } }); mcTextField.addFocusListener(new FocusAdapter() { public void focusLost(FocusEvent evt) { mcTextFieldFocusLost(evt); } }); controlView.add(mcTextField); mcTextField.setBounds(1220, 0, 20, 20); nsLabel.setFont(new Font("Dialog", 0, 10)); nsLabel.setText("ns"); nsLabel.setToolTipText("Network simplex iteration factor"); controlView.add(nsLabel); nsLabel.setBounds(1200, 20, 10, 20); nsTextField.setText("1"); nsTextField.setToolTipText("Network simplex iteration factor"); nsTextField.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { nsTextFieldActionPerformed(evt); } }); nsTextField.addFocusListener(new FocusAdapter() { public void focusLost(FocusEvent evt) { nsTextFieldFocusLost(evt); } }); controlView.add(nsTextField); nsTextField.setBounds(1220, 20, 20, 20); orderingButton.setFont(new Font("Dialog", 0, 10)); orderingButton.setText("="); orderingButton.setToolTipText("Switch between balanced and ordered edge"); orderingButton.setMargin(new Insets(1, 1, 1, 1)); orderingButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { orderingButtonActionPerformed(evt); } }); controlView.add(orderingButton); orderingButton.setBounds(1240, 20, 20, 20); directionButton.setFont(new Font("Dialog", 0, 10)); directionButton.setText(">"); directionButton.setToolTipText("Switch between vertical and horizontal layout"); directionButton.setMargin(new Insets(1, 1, 1, 1)); directionButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { directionButtonActionPerformed(evt); } }); controlView.add(directionButton);

A25

Appendix Naviz Applet Class


directionButton.setBounds(1240, 0, 20, 20); windowColNumTextField.setText("2"); windowColNumTextField.setToolTipText("Window column number"); windowColNumTextField.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { windowColNumTextFieldActionPerformed(evt); } }); windowColNumTextField.addFocusListener(new FocusAdapter() { public void focusLost(FocusEvent evt) { windowColNumTextFieldFocusLost(evt); } }); controlView.add(windowColNumTextField); windowColNumTextField.setBounds(690, 0, 20, 20); windowRowNumTextField.setText("2"); windowRowNumTextField.setToolTipText("Window row number"); windowRowNumTextField.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { windowRowNumTextFieldActionPerformed(evt); } }); windowRowNumTextField.addFocusListener(new FocusAdapter() { public void focusLost(FocusEvent evt) { windowRowNumTextFieldFocusLost(evt); } }); controlView.add(windowRowNumTextField); windowRowNumTextField.setBounds(710, 0, 20, 20); windowMaxHorTextField.setText("1.0"); windowMaxHorTextField.setToolTipText("Maximum horizontal screen"); windowMaxHorTextField.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { windowMaxHorTextFieldActionPerformed(evt); } }); windowMaxHorTextField.addFocusListener(new FocusAdapter() { public void focusLost(FocusEvent evt) { } }); controlView.add(windowMaxHorTextField); windowMaxHorTextField.setBounds(690, 20, 20, 20); windowMaxVerTextField.setText("1.0"); windowMaxVerTextField.setToolTipText("Maximum vertical screen"); windowMaxVerTextField.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { windowMaxVerTextFieldActionPerformed(evt); } }); windowMaxVerTextField.addFocusListener(new FocusAdapter() { public void focusLost(FocusEvent evt) { windowMaxVerTextFieldFocusLost(evt); } }); controlView.add(windowMaxVerTextField); windowMaxVerTextField.setBounds(710, 20, 20, 20); placeButton.setFont(new Font("Dialog", 0, 10)); placeButton.setText("Place"); placeButton.setToolTipText("Launch time behavior comparison"); placeButton.setBorder(new border.BevelBorder(border.BevelBorder.RAISED)); placeButton.setMargin(new Insets(1, 1, 1, 1)); placeButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { placeButtonActionPerformed(evt); } }); controlView.add(placeButton); placeButton.setBounds(770, 0, 40, 20); categoryButton.setFont(new Font("Dialog", 0, 10)); categoryButton.setText("Ctgry"); categoryButton.setToolTipText("Launch time behavior comparison"); categoryButton.setBorder(new border.BevelBorder(border.BevelBorder.RAISED)); categoryButton.setMargin(new Insets(1, 1, 1, 1)); categoryButton.addActionListener(new ActionListener() { windowMaxHorTextFieldFocusLost(evt);

A26

Appendix Naviz Applet Class


public void actionPerformed(ActionEvent evt) { categoryButtonActionPerformed(evt); } }); controlView.add(categoryButton); categoryButton.setBounds(770, 20, 40, 20); placeComboBox.setFont(new Font("Dialog", 0, 10)); placeComboBox.setToolTipText("Place"); placeComboBox.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { placeComboBoxActionPerformed(evt); } }); controlView.add(placeComboBox); placeComboBox.setBounds(0, 0, 90, 20); categoryComboBox.setFont(new Font("Dialog", 0, 10)); categoryComboBox.setToolTipText("Category"); categoryComboBox.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { categoryComboBoxActionPerformed(evt); } }); controlView.add(categoryComboBox); categoryComboBox.setBounds(0, 20, 90, 20); toHourComboBox.setFont(new Font("Dialog", 0, 10)); toHourComboBox.setModel(new DefaultComboBoxModel(new String[] { "All", "00:00", "02:00", "04:00", "06:00", "08:00", "10:00", "12:00", "14:00", "16:00", "18:00", "20:00", "22:00" })); toHourComboBox.setToolTipText("toHour"); toHourComboBox.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { toHourComboBoxActionPerformed(evt); } }); controlView.add(toHourComboBox); toHourComboBox.setBounds(90, 20, 60, 20); fromHourComboBox.setFont(new Font("Dialog", 0, 10)); fromHourComboBox.setModel(new DefaultComboBoxModel(new String[] { "All", "00:00", "02:00", "04:00", "06:00", "08:00", "10:00", "12:00", "14:00", "16:00", "18:00", "20:00", "22:00" })); fromHourComboBox.setToolTipText("fromHour"); fromHourComboBox.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { fromHourComboBoxActionPerformed(evt); } }); controlView.add(fromHourComboBox); fromHourComboBox.setBounds(90, 0, 60, 20); comparisonButton.setFont(new Font("Dialog", 0, 10)); comparisonButton.setText("View"); comparisonButton.setToolTipText("Show behavior comparison"); comparisonButton.setMargin(new Insets(2, 2, 2, 2)); comparisonButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { comparisonButtonActionPerformed(evt); } }); controlView.add(comparisonButton); comparisonButton.setBounds(150, 0, 33, 40); widthTextField.setText("800"); widthTextField.setToolTipText("Width of new window"); widthTextField.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { widthTextFieldActionPerformed(evt); } }); widthTextField.addFocusListener(new FocusAdapter() { public void focusLost(FocusEvent evt) { widthTextFieldFocusLost(evt); } }); controlView.add(widthTextField); widthTextField.setBounds(190, 0, 40, 20); heightTextField.setText("600"); heightTextField.setToolTipText("Height of new window"); heightTextField.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) {

A27

Appendix Naviz Applet Class


heightTextFieldActionPerformed(evt); } }); heightTextField.addFocusListener(new FocusAdapter() { public void focusLost(FocusEvent evt) { heightTextFieldFocusLost(evt); } }); controlView.add(heightTextField); heightTextField.setBounds(190, 20, 40, 20); controlScrollPane.setViewportView(controlView); mainPanel.add(controlScrollPane); controlScrollPane.setBounds(10, 10, 1240, 55); canvasPanel.setLayout(null); canvasPanel.setBackground(Color.white); canvasPanel.setBorder(new border.EtchedBorder(null, Color.gray)); mainPanel.add(canvasPanel); canvasPanel.setBounds(10, 65, 1240, 80); getContentPane().add(mainPanel); mainPanel.setBounds(0, 0, 1260, 150); }//GEN-END:initComponents private void heightTextFieldFocusLost(FocusEvent evt) {//GEN-FIRST:event_heightTextFieldFocusLost heightTextFieldActionPerformed(null); }//GEN-LAST:event_heightTextFieldFocusLost private void widthTextFieldFocusLost(FocusEvent evt) {//GEN-FIRST:event_widthTextFieldFocusLost widthTextFieldActionPerformed(null); }//GEN-LAST:event_widthTextFieldFocusLost private void heightTextFieldActionPerformed(ActionEvent evt) {//GEN-FIRST:event_heightTextFieldActionPerformed int val = Integer.parseInt(heightTextField.getText()); if(val>0 && val!=newWinHeight){ newWinHeight = val; }else{ private void categoryButtonActionPerformed(ActionEvent evt) {//GEN-FIRST:event_categoryButtonActionPerformed try{ if(categoryButton.getForeground().equals(Color.black)){ categoryButton.setForeground(Color.red); int width, height; if(windowMaxHor<=1.0) width = (int)(screenWidth/3 * windowMaxHor); else width = (int)(windowMaxHor); if(windowMaxVer<=1.0) height = (int)(screenHeight/2 * windowMaxVer); else height = (int)(windowMaxVer); int appletNum = MessageRelayer.getMaxAppletNum()+1; String url = "NavizApplet6Frame.jsp?parentnum1=-1&appletnum1="+appletNum+"&website1= "+website+"&from_hour1="+0+"&to_hour1="+0+"&place1="+0+"&category1="+0+ "&width1="+width+"&height1="+height+"&min_line_width1="+minLineWidth+"& max_line_width1="+maxLineWidth+"&comparison1=1"; url += "&parentnum2="+appletNum+"&appletnum2="+appletNum+"&website2="+website+ "&from_hour2="+0+"&to_hour2="+0+"&place2="+0+"&category2="+((Integer)(( Vector)MessageRelayer.getAttributeResponsePacket().categories.elementAt (1)).elementAt(NavizAttributeServlet.ATTRIBUTE_ID)).intValue()+"&width2 ="+width+"&height2="+height+"&min_line_width2="+minLineWidth+"&max_line _width2="+maxLineWidth+"&comparison2=1"; url += "&parentnum3="+appletNum+"&appletnum3="+appletNum+"&website3="+website+ "&from_hour3="+0+"&to_hour3="+0+"&place3="+0+"&category3="+((Integer)(( Vector)MessageRelayer.getAttributeResponsePacket().categories.elementAt (2)).elementAt(NavizAttributeServlet.ATTRIBUTE_ID)).intValue()+"&width3 ="+width+"&height3="+height+"&min_line_width3="+minLineWidth+"&max_line _width3="+maxLineWidth+"&comparison3=1"; heightTextField.setText(String.valueOf(newWinHeight)); } }//GEN-LAST:event_heightTextFieldActionPerformed private void widthTextFieldActionPerformed(ActionEvent evt) {//GEN-FIRST:event_widthTextFieldActionPerformed int val = Integer.parseInt(widthTextField.getText()); if(val>0 && val!=newWinWidth){ newWinWidth = val; }else{ widthTextField.setText(String.valueOf(newWinWidth)); } }//GEN-LAST:event_widthTextFieldActionPerformed

A28

Appendix Naviz Applet Class


url += "&parentnum4="+appletNum+"&appletnum4="+appletNum+"&website4="+website+ "&from_hour4="+0+"&to_hour4="+0+"&place4="+0+"&category4="+((Integer)(( Vector)MessageRelayer.getAttributeResponsePacket().categories.elementAt (3)).elementAt(NavizAttributeServlet.ATTRIBUTE_ID)).intValue()+"&width4 ="+width+"&height4="+height+"&min_line_width4="+minLineWidth+"&max_line _width4="+maxLineWidth+"&comparison4=1"; url += "&parentnum5="+appletNum+"&appletnum5="+appletNum+"&website5="+website+ "&from_hour5="+0+"&to_hour5="+0+"&place5="+0+"&category5="+((Integer)(( Vector)MessageRelayer.getAttributeResponsePacket().categories.elementAt (4)).elementAt(NavizAttributeServlet.ATTRIBUTE_ID)).intValue()+"&width5 ="+width+"&height5="+height+"&min_line_width5="+minLineWidth+"&max_line _width5="+maxLineWidth+"&comparison5=1"; url += "&parentnum6="+appletNum+"&appletnum6="+appletNum+"&website6="+website+ "&from_hour6="+0+"&to_hour6="+0+"&place6="+0+"&category6="+((Integer)(( Vector)MessageRelayer.getAttributeResponsePacket().categories.elementAt (5)).elementAt(NavizAttributeServlet.ATTRIBUTE_ID)).intValue()+"&width6 ="+width+"&height6="+height+"&min_line_width6="+minLineWidth+"&max_line _width6="+maxLineWidth+"&comparison6=1"; url = buildUrl(url); String name = "categorybehavior"; String features = "resizable,scrollbars,width="+width*3+",height="+height*2+",left="+scre enLeft+",top="+screenTop; String eval = name+" = window.open('"+url+"','"+name+"','"+features+"');"; eval += name+".focus();"; jsobjectWin.eval(eval); }else{ categoryButton.setForeground(Color.black); String name = "categorybehavior"; String eval = name+".close();"; jsobjectWin.eval(eval); } }catch(Exception e){ System.err.println("NavizApplet.categoryButtonMouseClicked: "+e.toString()); } }//GEN-LAST:event_categoryButtonActionPerformed private void placeButtonActionPerformed(ActionEvent evt) {//GEN-FIRST:event_placeButtonActionPerformed try{ if(placeButton.getForeground().equals(Color.black)){ placeButton.setForeground(Color.red); int width, height; if(windowMaxHor<=1.0) width = (int)(screenWidth/3 * windowMaxHor); else width = (int)(windowMaxHor); if(windowMaxVer<=1.0) height = (int)(screenHeight/2 * windowMaxVer); else height = (int)(windowMaxVer); int appletNum = MessageRelayer.getMaxAppletNum()+1; String url = "NavizApplet6Frame.jsp?parentnum1=-1&appletnum1="+appletNum+"&website1= "+website+"&from_hour1="+0+"&to_hour1="+0+"&place1="+0+"&category1="+0+ "&width1="+width+"&height1="+height+"&min_line_width1="+minLineWidth+"& max_line_width1="+maxLineWidth+"&comparison1=1"; url += "&parentnum2="+appletNum+"&appletnum2="+appletNum+"&website2="+website+ "&from_hour2="+0+"&to_hour2="+0+"&place2="+((Integer)((Vector)MessageRe layer.getAttributeResponsePacket().places.elementAt(1)).elementAt(Naviz AttributeServlet.ATTRIBUTE_ID)).intValue()+"&category2="+0+"&width2="+w idth+"&height2="+height+"&min_line_width2="+minLineWidth+"&max_line_wid th2="+maxLineWidth+"&comparison2=1"; url += "&parentnum3="+appletNum+"&appletnum3="+appletNum+"&website3="+website+ "&from_hour3="+0+"&to_hour3="+0+"&place3="+((Integer)((Vector)MessageRe layer.getAttributeResponsePacket().places.elementAt(2)).elementAt(Naviz AttributeServlet.ATTRIBUTE_ID)).intValue()+"&category3="+0+"&width3="+w idth+"&height3="+height+"&min_line_width3="+minLineWidth+"&max_line_wid th3="+maxLineWidth+"&comparison3=1"; url += "&parentnum4="+appletNum+"&appletnum4="+appletNum+"&website4="+website+ "&from_hour4="+0+"&to_hour4="+0+"&place4="+((Integer)((Vector)MessageRe layer.getAttributeResponsePacket().places.elementAt(3)).elementAt(Naviz AttributeServlet.ATTRIBUTE_ID)).intValue()+"&category4="+0+"&width4="+w idth+"&height4="+height+"&min_line_width4="+minLineWidth+"&max_line_wid th4="+maxLineWidth+"&comparison4=1"; url += "&parentnum5="+appletNum+"&appletnum5="+appletNum+"&website5="+website+ "&from_hour5="+0+"&to_hour5="+0+"&place5="+((Integer)((Vector)MessageRe layer.getAttributeResponsePacket().places.elementAt(4)).elementAt(Naviz AttributeServlet.ATTRIBUTE_ID)).intValue()+"&category5="+0+"&width5="+w idth+"&height5="+height+"&min_line_width5="+minLineWidth+"&max_line_wid th5="+maxLineWidth+"&comparison5=1"; url += "&parentnum6="+appletNum+"&appletnum6="+appletNum+"&website6="+website+ "&from_hour6="+0+"&to_hour6="+0+"&place6="+((Integer)((Vector)MessageRe layer.getAttributeResponsePacket().places.elementAt(5)).elementAt(Naviz

A29

Appendix Naviz Applet Class


AttributeServlet.ATTRIBUTE_ID)).intValue()+"&category6="+0+"&width6="+w idth+"&height6="+height+"&min_line_width6="+minLineWidth+"&max_line_wid th6="+maxLineWidth+"&comparison6=1"; url = buildUrl(url); String name = "placebehavior"; String features = "resizable,scrollbars,width="+width*3+",height="+height*2+",left="+scre enLeft+",top="+screenTop; String eval = name+" = window.open('"+url+"','"+name+"','"+features+"');"; eval += name+".focus();"; jsobjectWin.eval(eval); }else{ placeButton.setForeground(Color.black); String name = "placebehavior"; String eval = name+".close();"; jsobjectWin.eval(eval); } }catch(Exception e){ System.err.println("NavizApplet.placeButtonMouseClicked: "+e.toString()); } }//GEN-LAST:event_placeButtonActionPerformed private void comparisonButtonActionPerformed(ActionEvent evt) {//GEN-FIRST:event_comparisonButtonActionPerformed try{ int appletNum = this.appletNum; String url = buildUrl("NavizApplet.jsp?parentnum="+this.appletNum+"&appletnum="+appl etNum+"&website="+website+"&from_hour="+((Vector)hours.elementAt(fromHo urIndex)).elementAt(NavizAttributeServlet.ATTRIBUTE_ID).toString()+"&to _hour="+((Vector)hours.elementAt(toHourIndex)).elementAt(NavizAttribute Servlet.ATTRIBUTE_ID).toString()+"&place="+((Vector)MessageRelayer.getA ttributeResponsePacket().places.elementAt(placeIndex)).elementAt(NavizA ttributeServlet.ATTRIBUTE_ID).toString()+"&category="+((Vector)MessageR elayer.getAttributeResponsePacket().categories.elementAt(categoryIndex) ).elementAt(NavizAttributeServlet.ATTRIBUTE_ID).toString()+"&width="+ne wWinWidth+"&height="+newWinHeight+"&min_line_width="+minLineWidth+"&max _line_width="+maxLineWidth+"&comparison=1#applet"); String name = "behavior"+((Vector)hours.elementAt(fromHourIndex)).elementAt(NavizAttr ibuteServlet.ATTRIBUTE_ID).toString()+((Vector)hours.elementAt(toHourIn dex)).elementAt(NavizAttributeServlet.ATTRIBUTE_ID).toString()+((Vector )MessageRelayer.getAttributeResponsePacket().places.elementAt(placeInde x)).elementAt(NavizAttributeServlet.ATTRIBUTE_ID).toString()+((Vector)M essageRelayer.getAttributeResponsePacket().categories.elementAt(categor yIndex)).elementAt(NavizAttributeServlet.ATTRIBUTE_ID).toString(); String features = "resizable,scrollbars,width="+newWinWidth+",height="+newWinHeight+",lef t="+0+",top="+0; String eval = name+" = window.open('"+url+"','"+name+"','"+features+"');"; eval += name+".focus();"; jsobjectWin.eval(eval); }catch(Exception e){ System.err.println("NavizApplet.viewTimeButtonMouseClicked: "+e.toString()); } }//GEN-LAST:event_comparisonButtonActionPerformed private void toHourComboBoxActionPerformed(ActionEvent evt) {//GEN-FIRST:event_toHourComboBoxActionPerformed if(toHourComboBox.getSelectedIndex()!=toHourIndex){ toHourIndex = toHourComboBox.getSelectedIndex(); } }//GEN-LAST:event_toHourComboBoxActionPerformed private void fromHourComboBoxActionPerformed(ActionEvent evt) {//GEN-FIRST:event_fromHourComboBoxActionPerformed if(fromHourComboBox.getSelectedIndex()!=fromHourIndex){ fromHourIndex = fromHourComboBox.getSelectedIndex(); } }//GEN-LAST:event_fromHourComboBoxActionPerformed private void categoryComboBoxActionPerformed(ActionEvent evt) {//GEN-FIRST:event_categoryComboBoxActionPerformed if(categoryComboBox.getSelectedIndex()!=categoryIndex){ categoryIndex = categoryComboBox.getSelectedIndex(); } }//GEN-LAST:event_categoryComboBoxActionPerformed private void placeComboBoxActionPerformed(ActionEvent evt) {//GEN-FIRST:event_placeComboBoxActionPerformed if(placeComboBox.getSelectedIndex()!=placeIndex){ placeIndex = placeComboBox.getSelectedIndex(); } }//GEN-LAST:event_placeComboBoxActionPerformed private void nsTextFieldFocusLost(FocusEvent evt) {//GEN-FIRST:event_nsTextFieldFocusLost nsTextFieldActionPerformed(null);

A30

Appendix Naviz Applet Class


}//GEN-LAST:event_nsTextFieldFocusLost private void mcTextFieldFocusLost(FocusEvent evt) {//GEN-FIRST:event_mcTextFieldFocusLost mcTextFieldActionPerformed(null); }//GEN-LAST:event_mcTextFieldFocusLost private void incconfTextFieldFocusLost(FocusEvent evt) {//GEN-FIRST:event_incconfTextFieldFocusLost incconfTextFieldActionPerformed(null); }//GEN-LAST:event_incconfTextFieldFocusLost private void incsupTextFieldFocusLost(FocusEvent evt) {//GEN-FIRST:event_incsupTextFieldFocusLost incsupTextFieldActionPerformed(null); }//GEN-LAST:event_incsupTextFieldFocusLost private void maxconfTextFieldFocusLost(FocusEvent evt) {//GEN-FIRST:event_maxconfTextFieldFocusLost maxconfTextFieldActionPerformed(null); }//GEN-LAST:event_maxconfTextFieldFocusLost private void maxsupTextFieldFocusLost(FocusEvent evt) {//GEN-FIRST:event_maxsupTextFieldFocusLost maxsupTextFieldActionPerformed(null); }//GEN-LAST:event_maxsupTextFieldFocusLost private void windowMaxVerTextFieldFocusLost(FocusEvent evt) {//GEN-FIRST:event_windowMaxVerTextFieldFocusLost windowMaxVerTextFieldActionPerformed(null); }//GEN-LAST:event_windowMaxVerTextFieldFocusLost private void windowMaxHorTextFieldFocusLost(FocusEvent evt) {//GEN-FIRST:event_windowMaxHorTextFieldFocusLost windowMaxHorTextFieldActionPerformed(null); }//GEN-LAST:event_windowMaxHorTextFieldFocusLost private void windowRowNumTextFieldFocusLost(FocusEvent evt) {//GEN-FIRST:event_windowRowNumTextFieldFocusLost windowRowNumTextFieldActionPerformed(null); }//GEN-LAST:event_windowRowNumTextFieldFocusLost private void windowColNumTextFieldFocusLost(FocusEvent evt) {//GEN-FIRST:event_windowColNumTextFieldFocusLost windowColNumTextFieldActionPerformed(null); }//GEN-LAST:event_windowColNumTextFieldFocusLost private void maxhopTextFieldFocusLost(FocusEvent evt) {//GEN-FIRST:event_maxhopTextFieldFocusLost maxhopTextFieldActionPerformed(null); }//GEN-LAST:event_maxhopTextFieldFocusLost private void minhopTextFieldFocusLost(FocusEvent evt) {//GEN-FIRST:event_minhopTextFieldFocusLost minhopTextFieldActionPerformed(null); }//GEN-LAST:event_minhopTextFieldFocusLost private void pathNoTextFieldFocusLost(FocusEvent evt) {//GEN-FIRST:event_pathNoTextFieldFocusLost pathNoTextFieldActionPerformed(null); }//GEN-LAST:event_pathNoTextFieldFocusLost private void minconfTextFieldFocusLost(FocusEvent evt) {//GEN-FIRST:event_minconfTextFieldFocusLost minconfTextFieldActionPerformed(null); }//GEN-LAST:event_minconfTextFieldFocusLost private void minsupTextFieldFocusLost(FocusEvent evt) {//GEN-FIRST:event_minsupTextFieldFocusLost minsupTextFieldActionPerformed(null); }//GEN-LAST:event_minsupTextFieldFocusLost private void minconfLabelMouseClicked(MouseEvent evt) {//GEN-FIRST:event_minconfLabelMouseClicked try{ if(widthByRow==NavizServlet.EDGE_SUPPORT_ROW){ String url = buildUrl("NavizLegend.jsp?linewidth=sup&minsup="+responsePacket.dataMin sup+"&maxsup="+responsePacket.dataMaxsup+"&minconf="+responsePacket.dat aMinconf+"&maxconf="+responsePacket.dataMaxconf+"&maxhue="+maxHue+"&min realwidth="+(minLineWidth*NavizCanvas.LINE_WIDTH_RATIO)+"&maxrealwidth= "+(maxLineWidth*NavizCanvas.LINE_WIDTH_RATIO)); String name = "suplegend"; String features = "resizable,scrollbars,width=300,height=200"; String eval = name+" = window.open('"+url+"','"+name+"','"+features+"');"; eval += name+".focus();"; jsobjectWin.eval(eval); }else{ String url = buildUrl("NavizLegend.jsp?linewidth=conf&minsup="+responsePacket.dataMi

A31

Appendix Naviz Applet Class


nsup+"&maxsup="+responsePacket.dataMaxsup+"&minconf="+responsePacket.da taMinconf+"&maxconf="+responsePacket.dataMaxconf+"&maxhue="+maxHue+"&mi nrealwidth="+(minLineWidth*NavizCanvas.LINE_WIDTH_RATIO)+"&maxrealwidth ="+(maxLineWidth*NavizCanvas.LINE_WIDTH_RATIO)); String name = "conflegend"; String features = "resizable,scrollbars,width=300,height=200"; String eval = name+" = window.open('"+url+"','"+name+"','"+features+"');"; eval += name+".focus();"; jsobjectWin.eval(eval); } }catch(Exception e){ System.err.println("NavizApplet.minconfLabelMouseClick: "+e.toString()); } }//GEN-LAST:event_minconfLabelMouseClicked private void minsupLabelMouseClicked(MouseEvent evt) {//GEN-FIRST:event_minsupLabelMouseClicked try{ if(widthByRow==NavizServlet.EDGE_SUPPORT_ROW){ String url = buildUrl("NavizLegend.jsp?linewidth=sup&minsup="+responsePacket.dataMin sup+"&maxsup="+responsePacket.dataMaxsup+"&minconf="+responsePacket.dat aMinconf+"&maxconf="+responsePacket.dataMaxconf+"&maxhue="+maxHue+"&min realwidth="+(minLineWidth*NavizCanvas.LINE_WIDTH_RATIO)+"&maxrealwidth= "+(maxLineWidth*NavizCanvas.LINE_WIDTH_RATIO)); String name = "suplegend"; String features = "resizable,scrollbars,width=300,height=200"; String eval = name+" = window.open('"+url+"','"+name+"','"+features+"');"; eval += name+".focus();"; jsobjectWin.eval(eval); }else{ String url = buildUrl("NavizLegend.jsp?linewidth=conf&minsup="+responsePacket.dataMi nsup+"&maxsup="+responsePacket.dataMaxsup+"&minconf="+responsePacket.da taMinconf+"&maxconf="+responsePacket.dataMaxconf+"&maxhue="+maxHue+"&mi nrealwidth="+(minLineWidth*NavizCanvas.LINE_WIDTH_RATIO)+"&maxrealwidth ="+(maxLineWidth*NavizCanvas.LINE_WIDTH_RATIO)); String name = "conflegend"; String features = "resizable,scrollbars,width=300,height=200"; String eval = name+" = window.open('"+url+"','"+name+"','"+features+"');"; eval += name+".focus();"; jsobjectWin.eval(eval); } }catch(Exception e){ System.err.println("NavizApplet.minsupLabelMouseClick: "+e.toString()); } }//GEN-LAST:event_minsupLabelMouseClicked private void orderingButtonActionPerformed(ActionEvent evt) {//GEN-FIRST:event_orderingButtonActionPerformed if(orderingButton.getText().equals("=")){ orderingButton.setText("+"); dotOrdering = true; }else{ orderingButton.setText("="); dotOrdering = false; } connectToServlet(); if(parentNum==-1){ String[] appletNames = MessageRelayer.getAppletNames(); for(int i=0; i<appletNames.length; i++) if(!appletNames[i].equals(this.getName())){ NavizApplet app = (NavizApplet)MessageRelayer.getApplet(appletNames[i]); if(!(app==null||app.getParentNum()!=appletNum)) app.setDotOrdering(dotOrdering); } } }//GEN-LAST:event_orderingButtonActionPerformed private void directionButtonActionPerformed(ActionEvent evt) {//GEN-FIRST:event_directionButtonActionPerformed if(directionButton.getText().equals(">")){ directionButton.setText("v"); dotRankdir = "LR"; }else{ directionButton.setText(">"); dotRankdir = "TB"; } connectToServlet(); if(parentNum==-1){ String[] appletNames = MessageRelayer.getAppletNames(); for(int i=0; i<appletNames.length; i++) if(!appletNames[i].equals(this.getName())){

A32

Appendix Naviz Applet Class


NavizApplet app = (NavizApplet)MessageRelayer.getApplet(appletNames[i]); if(!(app==null||app.getParentNum()!=appletNum)) app.setDotRankdir(dotRankdir); } } }//GEN-LAST:event_directionButtonActionPerformed private void nsTextFieldActionPerformed(ActionEvent evt) {//GEN-FIRST:event_nsTextFieldActionPerformed int val = Integer.parseInt(nsTextField.getText()); if(val>0 && val<=99 && val!=dotNslimit){ dotNslimit = Integer.parseInt(nsTextField.getText()); connectToServlet(); if(parentNum==-1){ String[] appletNames = MessageRelayer.getAppletNames(); for(int i=0; i<appletNames.length; i++) if(!appletNames[i].equals(this.getName())){ NavizApplet app = (NavizApplet)MessageRelayer.getApplet(appletNames[i]); if(!(app==null||app.getParentNum()!=appletNum)) app.setDotNslimit(dotNslimit); } } }else{ nsTextField.setText(String.valueOf(dotNslimit)); } }//GEN-LAST:event_nsTextFieldActionPerformed private void mcTextFieldActionPerformed(ActionEvent evt) {//GEN-FIRST:event_mcTextFieldActionPerformed int val = Integer.parseInt(mcTextField.getText()); if(val>0 && val<=99 && val!=dotMclimit){ dotMclimit = Integer.parseInt(mcTextField.getText()); connectToServlet(); if(parentNum==-1){ String[] appletNames = MessageRelayer.getAppletNames(); for(int i=0; i<appletNames.length; i++) if(!appletNames[i].equals(this.getName())){ NavizApplet app = (NavizApplet)MessageRelayer.getApplet(appletNames[i]); if(!(app==null||app.getParentNum()!=appletNum)) app.setDotMclimit(dotMclimit); } } }else{ mcTextField.setText(String.valueOf(dotMclimit)); } }//GEN-LAST:event_mcTextFieldActionPerformed private void colorComboBoxActionPerformed(ActionEvent evt) {//GEN-FIRST:event_colorComboBoxActionPerformed if(colorComboBox.getSelectedIndex()!=colorByRow){ if(colorComboBox.getSelectedIndex()==NavizServlet.EDGE_SUPPORT_ROW){ colorByRow=NavizServlet.EDGE_SUPPORT_ROW; widthByRow=NavizServlet.EDGE_CONFIDENCE_ROW; }else{ colorByRow=NavizServlet.EDGE_CONFIDENCE_ROW; widthByRow=NavizServlet.EDGE_SUPPORT_ROW; } widthComboBox.setSelectedIndex(widthByRow); connectToServlet(); if(parentNum==-1){ String[] appletNames = MessageRelayer.getAppletNames(); for(int i=0; i<appletNames.length; i++) if(!appletNames[i].equals(this.getName())){ NavizApplet app = (NavizApplet)MessageRelayer.getApplet(appletNames[i]); if(!(app==null||app.getParentNum()!=appletNum)) app.setColorByRow(colorByRow); } } } }//GEN-LAST:event_colorComboBoxActionPerformed private void widthComboBoxActionPerformed(ActionEvent evt) {//GEN-FIRST:event_widthComboBoxActionPerformed if(widthComboBox.getSelectedIndex()!=widthByRow){ if(widthComboBox.getSelectedIndex()==NavizServlet.EDGE_SUPPORT_ROW){ widthByRow=NavizServlet.EDGE_SUPPORT_ROW; colorByRow=NavizServlet.EDGE_CONFIDENCE_ROW; }else{ widthByRow=NavizServlet.EDGE_CONFIDENCE_ROW; colorByRow=NavizServlet.EDGE_SUPPORT_ROW; } colorComboBox.setSelectedIndex(colorByRow); connectToServlet(); if(parentNum==-1){ String[] appletNames = MessageRelayer.getAppletNames(); for(int i=0; i<appletNames.length; i++)

A33

Appendix Naviz Applet Class


if(!appletNames[i].equals(this.getName())){ NavizApplet app = (NavizApplet)MessageRelayer.getApplet(appletNames[i]); if(!(app==null||app.getParentNum()!=appletNum)) app.setWidthByRow(widthByRow); } } } }//GEN-LAST:event_widthComboBoxActionPerformed private void weightComboBoxActionPerformed(ActionEvent evt) {//GEN-FIRST:event_weightComboBoxActionPerformed if(weightComboBox.getSelectedIndex()!=weightByRow){ if(weightComboBox.getSelectedIndex()==NavizServlet.EDGE_SUPPORT_ROW) weightByRow=NavizServlet.EDGE_SUPPORT_ROW; else weightByRow=NavizServlet.EDGE_CONFIDENCE_ROW; connectToServlet(); if(parentNum==-1){ String[] appletNames = MessageRelayer.getAppletNames(); for(int i=0; i<appletNames.length; i++) if(!appletNames[i].equals(this.getName())){ NavizApplet app = (NavizApplet)MessageRelayer.getApplet(appletNames[i]); if(!(app==null||app.getParentNum()!=appletNum)) app.setWeightByRow(weightByRow); } } } }//GEN-LAST:event_weightComboBoxActionPerformed private void orderComboBoxActionPerformed(ActionEvent evt) {//GEN-FIRST:event_orderComboBoxActionPerformed if(orderComboBox.getSelectedIndex()!=orderByRow){ if(orderComboBox.getSelectedIndex()==NavizServlet.EDGE_SUPPORT_ROW) orderByRow=NavizServlet.EDGE_SUPPORT_ROW; else orderByRow=NavizServlet.EDGE_CONFIDENCE_ROW; connectToServlet(); if(parentNum==-1){ String[] appletNames = MessageRelayer.getAppletNames(); for(int i=0; i<appletNames.length; i++) if(!appletNames[i].equals(this.getName())){ NavizApplet app = (NavizApplet)MessageRelayer.getApplet(appletNames[i]); if(!(app==null||app.getParentNum()!=appletNum)) app.setOrderByRow(orderByRow); } } } }//GEN-LAST:event_orderComboBoxActionPerformed private void incconfTextFieldActionPerformed(ActionEvent evt) {//GEN-FIRST:event_incconfTextFieldActionPerformed double val = Double.parseDouble(incconfTextField.getText()); if (val>0.0 && val<maxconf-minconf){ incconf = val; double oldMinconf = minconf; double oldMaxconf = maxconf; minconfScrollBar.setVisibleAmount ((int)(val>1.0?responsePacket.dataMaxconf/10:responsePacket.dataMaxconf /(10*val))); minconfScrollBar.setBlockIncrement ((int)(val>1.0?responsePacket.dataMaxconf/10:responsePacket.dataMaxconf /(10*val))); minconfScrollBar.setMaximum ((int)(val>1.0?responsePacket.dataMaxconf:responsePacket.dataMaxconf/va l)+(int)(val>1.0?responsePacket.dataMaxconf/10:responsePacket.dataMaxco nf/(10*val))); maxconfScrollBar.setVisibleAmount ((int)(val>1.0?responsePacket.dataMaxconf/10:responsePacket.dataMaxconf /(10*val))); maxconfScrollBar.setBlockIncrement ((int)(val>1.0?responsePacket.dataMaxconf/10:responsePacket.dataMaxconf /(10*val))); maxconfScrollBar.setMaximum ((int)(val>1.0?responsePacket.dataMaxconf:responsePacket.dataMaxconf/va l)+(int)(val>1.0?responsePacket.dataMaxconf/10:responsePacket.dataMaxco nf/(10*val))); minconf = oldMinconf; maxconf = oldMaxconf; if(parentNum==-1){ String[] appletNames = MessageRelayer.getAppletNames(); for(int i=0; i<appletNames.length; i++) if(!appletNames[i].equals(this.getName())){ NavizApplet app = (NavizApplet)MessageRelayer.getApplet(appletNames[i]); if(!(app==null||app.getParentNum()!=appletNum)) app.setIncconf(incconf); }

A34

Appendix Naviz Applet Class


} }else{ incconfTextField.setText (String.valueOf(incconf)); } }//GEN-LAST:event_incconfTextFieldActionPerformed private void incsupTextFieldActionPerformed(ActionEvent evt) {//GEN-FIRST:event_incsupTextFieldActionPerformed double val = Double.parseDouble(incsupTextField.getText()); if (val>0.0 && val<maxsup-minsup){ incsup = val; double oldMinsup = minsup; double oldMaxsup = maxsup; minsupScrollBar.setVisibleAmount ((int)(val>1.0?responsePacket.dataMaxsup/10:responsePacket.dataMaxsup/( 10*val))); minsupScrollBar.setBlockIncrement ((int)(val>1.0?responsePacket.dataMaxsup/10:responsePacket.dataMaxsup/( 10*val))); minsupScrollBar.setMaximum ((int)(val>1.0?responsePacket.dataMaxsup:responsePacket.dataMaxsup/val) +(int)(val>1.0?responsePacket.dataMaxsup/10:responsePacket.dataMaxsup/( 10*val))); maxsupScrollBar.setVisibleAmount ((int)(val>1.0?responsePacket.dataMaxsup/10:responsePacket.dataMaxsup/( 10*val))); maxsupScrollBar.setBlockIncrement ((int)(val>1.0?responsePacket.dataMaxsup/10:responsePacket.dataMaxsup/( 10*val))); maxsupScrollBar.setMaximum ((int)(val>1.0?responsePacket.dataMaxsup:responsePacket.dataMaxsup/val) +(int)(val>1.0?responsePacket.dataMaxsup/10:responsePacket.dataMaxsup/( 10*val))); minsup = oldMinsup; maxsup = oldMaxsup; if(parentNum==-1){ String[] appletNames = MessageRelayer.getAppletNames(); for(int i=0; i<appletNames.length; i++) if(!appletNames[i].equals(this.getName())){ NavizApplet app = (NavizApplet)MessageRelayer.getApplet(appletNames[i]); if(!(app==null||app.getParentNum()!=appletNum)) app.setIncsup(incsup); } } }else{ incsupTextField.setText (String.valueOf(incsup)); } }//GEN-LAST:event_incsupTextFieldActionPerformed private void maxconfTextFieldActionPerformed(ActionEvent evt) {//GEN-FIRST:event_maxconfTextFieldActionPerformed double val = Double.parseDouble(maxconfTextField.getText()); if(val<=100.0 && val>=minconf){ maxconf = val; maxconfScrollBar.setValue((int)(maxconf/incconf)); }else{ maxconfTextField.setText (String.valueOf(maxconf)); } }//GEN-LAST:event_maxconfTextFieldActionPerformed private void maxsupTextFieldActionPerformed(ActionEvent evt) {//GEN-FIRST:event_maxsupTextFieldActionPerformed double val = Double.parseDouble(maxsupTextField.getText()); if(val<=100.0 && val>=minsup){ maxsup = val; maxsupScrollBar.setValue((int)(maxsup/incsup)); }else{ maxsupTextField.setText (String.valueOf(maxsup)); } }//GEN-LAST:event_maxsupTextFieldActionPerformed private void maxconfScrollBarAdjustmentValueChanged(AdjustmentEvent evt) {//GEN-FIRST:event_maxconfScrollBarAdjustmentValueChanged if(evt.getValue()*incconf<=100.0 && evt.getValue()*incconf>=minconf){ maxconf = evt.getValue()*incconf; maxconfTextField.setText (format(maxconf)); canvas.setData(responsePacket.nodes,supconfFilter(responsePacket.edges) ); if(canvas.isViewPath()){ if(workFinished && pathWorkFinished){ Vector paths = getSubPaths(permanentPathNodes,permanentAvoidNodes,pathType); if(maxPathNo>=0){ canvas.setPaths(paths); setMaxPathNo(maxPathNo); if(pathNo>maxPathNo){ setPathNo(maxPathNo); canvas.setPathNo(pathNo); }

A35

Appendix Naviz Applet Class


} } } canvas.repaint(); if(parentNum==-1){ String[] appletNames = MessageRelayer.getAppletNames(); for(int i=0; i<appletNames.length; i++) if(!appletNames[i].equals(this.getName())){ NavizApplet app = (NavizApplet)MessageRelayer.getApplet(appletNames[i]); if(!(app==null||app.getParentNum()!=appletNum)) app.setMaxconf(maxconf); } } }else{ maxconfScrollBar.setValue((int)(maxconf/incconf)); } }//GEN-LAST:event_maxconfScrollBarAdjustmentValueChanged private void maxsupScrollBarAdjustmentValueChanged(AdjustmentEvent evt) {//GEN-FIRST:event_maxsupScrollBarAdjustmentValueChanged if(evt.getValue()*incsup<=100.0 && evt.getValue()*incsup>=minsup){ maxsup = evt.getValue()*incsup; maxsupTextField.setText(format(maxsup)); canvas.setData(responsePacket.nodes,supconfFilter(responsePacket.edges) ); if(canvas.isViewPath()){ if(workFinished && pathWorkFinished){ Vector paths = getSubPaths(permanentPathNodes,permanentAvoidNodes,pathType); if(maxPathNo>=0){ canvas.setPaths(paths); setMaxPathNo(maxPathNo); if(pathNo>maxPathNo){ setPathNo(maxPathNo); canvas.setPathNo(pathNo); } } } } canvas.repaint(); if(parentNum==-1){ String[] appletNames = MessageRelayer.getAppletNames(); for(int i=0; i<appletNames.length; i++) if(!appletNames[i].equals(this.getName())){ NavizApplet app = (NavizApplet)MessageRelayer.getApplet(appletNames[i]); if(!(app==null||app.getParentNum()!=appletNum)) app.setMaxsup(maxsup); } } }else{ maxsupScrollBar.setValue((int)(maxsup/incsup)); } }//GEN-LAST:event_maxsupScrollBarAdjustmentValueChanged private void launchButtonActionPerformed(ActionEvent evt) {//GEN-FIRST:event_launchButtonActionPerformed try{ if(launchButton.getForeground().equals(Color.black)){ launchButton.setForeground(Color.red); int width, height; if(windowMaxHor<=1.0) width = (int)(screenWidth/3 * windowMaxHor); else width = (int)(windowMaxHor); if(windowMaxVer<=1.0) height = (int)(screenHeight/2 * windowMaxVer); else height = (int)(windowMaxVer); int appletNum = MessageRelayer.getMaxAppletNum()+1; String url = "NavizApplet6Frame.jsp?parentnum1=-1&appletnum1="+appletNum+"&website1= "+website+"&from_hour1="+fromHour+"&to_hour1="+toHour+"&place1="+place+ "&category1="+category+"&width1="+width+"&height1="+height+"&min_line_w idth1="+minLineWidth+"&max_line_width1="+maxLineWidth+"&comparison1=1"; url += "&parentnum2="+appletNum+"&appletnum2="+(appletNum+1)+"&website2="+webs ite+"&from_hour2="+fromHour+"&to_hour2="+toHour+"&place2="+place+"&cate gory2="+category+"&width2="+width+"&height2="+height+"&min_line_width2= "+minLineWidth+"&max_line_width2="+maxLineWidth+"&comparison2=1"; url += "&parentnum3="+appletNum+"&appletnum3="+(appletNum+2)+"&website3="+webs ite+"&from_hour3="+fromHour+"&to_hour3="+toHour+"&place3="+place+"&cate gory3="+category+"&width3="+width+"&height3="+height+"&min_line_width3= "+minLineWidth+"&max_line_width3="+maxLineWidth+"&comparison3=1"; url += "&parentnum4="+appletNum+"&appletnum4="+(appletNum+3)+"&website4="+webs ite+"&from_hour4="+fromHour+"&to_hour4="+toHour+"&place4="+place+"&cate gory4="+category+"&width4="+width+"&height4="+height+"&min_line_width4= "+minLineWidth+"&max_line_width4="+maxLineWidth+"&comparison4=1"; url += "&parentnum5="+appletNum+"&appletnum5="+(appletNum+4)+"&website5="+webs

A36

Appendix Naviz Applet Class


ite+"&from_hour5="+fromHour+"&to_hour5="+toHour+"&place5="+place+"&cate gory5="+category+"&width5="+width+"&height5="+height+"&min_line_width5= "+minLineWidth+"&max_line_width5="+maxLineWidth+"&comparison5=1"; url += "&parentnum6="+appletNum+"&appletnum6="+(appletNum+5)+"&website6="+webs ite+"&from_hour6="+fromHour+"&to_hour6="+toHour+"&place6="+place+"&cate gory6="+category+"&width6="+width+"&height6="+height+"&min_line_width6= "+minLineWidth+"&max_line_width6="+maxLineWidth+"&comparison6=1"; url = buildUrl(url); String name = "pathbehavior"; String features = "resizable,scrollbars,width="+width*3+",height="+height*2+",left="+scre enLeft+",top="+screenTop; String eval = name+" = window.open('"+url+"','"+name+"','"+features+"');"; eval += name+".focus();"; jsobjectWin.eval(eval); }else{ launchButton.setForeground(Color.black); String name = "pathbehavior"; String eval = name+".close();"; jsobjectWin.eval(eval); } }catch(Exception e){ System.err.println("NavizApplet.launchButtonActionPerformed: "+e.toString()); } }//GEN-LAST:event_launchButtonActionPerformed private void viewTimeButtonActionPerformed(ActionEvent evt) {//GEN-FIRST:event_viewTimeButtonActionPerformed try{ if(viewTimeButton.getForeground().equals(Color.black)){ viewTimeButton.setForeground(Color.red); int width, height; if(windowMaxHor<=1.0) width = (int)(screenWidth/2 * windowMaxHor); else width = (int)(windowMaxHor); if(windowMaxVer<=1.0) height = (int)(screenHeight * windowMaxVer); else height = (int)(windowMaxVer); int appletNum = MessageRelayer.getMaxAppletNum()+1; String url = "NavizApplet2Frame.jsp?parentnum1=-1&appletnum1="+appletNum+"&website1= "+website+"&from_hour1="+13+"&to_hour1="+18+"&place1="+place+"&category 1="+category+"&width1="+width+"&height1="+height+"&min_line_width1="+mi nLineWidth+"&max_line_width1="+maxLineWidth+"&comparison1=1"; url += "&parentnum2="+appletNum+"&appletnum2="+appletNum+"&website2="+website+ "&from_hour2="+19+"&to_hour2="+12+"&place2="+place+"&category2="+catego ry+"&width2="+width+"&height2="+height+"&min_line_width2="+minLineWidth +"&max_line_width2="+maxLineWidth+"&comparison2=1"; url = buildUrl(url); String name = "timebehavior"; String features = "resizable,scrollbars,width="+width*2+",height="+height+",left="+screen Left+",top="+screenTop; String eval = name+" = window.open('"+url+"','"+name+"','"+features+"');"; eval += name+".focus();"; jsobjectWin.eval(eval); }else{ viewTimeButton.setForeground(Color.black); String name = "timebehavior"; String eval = name+".close();"; jsobjectWin.eval(eval); } }catch(Exception e){ System.err.println("NavizApplet.viewTimeButtonMouseClicked: "+e.toString()); } }//GEN-LAST:event_viewTimeButtonActionPerformed private void windowMaxVerTextFieldActionPerformed(ActionEvent evt) {//GEN-FIRST:event_windowMaxVerTextFieldActionPerformed double val = Double.parseDouble(windowMaxVerTextField.getText()); if(val>0.0 && val!=windowMaxVer){ windowMaxVer = val; }else{ windowMaxVerTextField.setText(String.valueOf(windowMaxVer)); } }//GEN-LAST:event_windowMaxVerTextFieldActionPerformed private void windowMaxHorTextFieldActionPerformed(ActionEvent evt) {//GEN-FIRST:event_windowMaxHorTextFieldActionPerformed double val = Double.parseDouble(windowMaxHorTextField.getText()); if(val>0.0 && val!=windowMaxHor){ windowMaxHor = val; }else{ windowMaxHorTextField.setText(String.valueOf(windowMaxHor)); } }//GEN-LAST:event_windowMaxHorTextFieldActionPerformed

A37

Appendix Naviz Applet Class


orderLabel.setVisible(true); weightLabel.setVisible(true); widthLabel.setVisible(true); colorLabel.setVisible(true); directionButton.setVisible(true); orderingButton.setVisible(true); mcLabel.setVisible(true); mcTextField.setVisible(true); nsLabel.setVisible(true); nsTextField.setVisible(true); }else{ detailButton.setText("Detail >>"); controlView.setPreferredSize(new Dimension(STANDARD_CONTROL_WIDTH,controlView.getHeight())); controlView.revalidate(); maxsupLabel.setVisible(false); maxsupScrollBar.setVisible(false); maxsupTextField.setVisible(false); maxsupPercent.setVisible(false); incsupLabel.setVisible(false); incsupTextField.setVisible(false); incsupPercent.setVisible(false); maxconfLabel.setVisible(false); maxconfScrollBar.setVisible(false); maxconfTextField.setVisible(false); maxconfPercent.setVisible(false); incconfLabel.setVisible(false); incconfTextField.setVisible(false); incconfPercent.setVisible(false); orderComboBox.setVisible(false); weightComboBox.setVisible(false); widthComboBox.setVisible(false); colorComboBox.setVisible(false); orderLabel.setVisible(false); weightLabel.setVisible(false); widthLabel.setVisible(false); colorLabel.setVisible(false); directionButton.setVisible(false); orderingButton.setVisible(false); mcLabel.setVisible(false); mcTextField.setVisible(false); nsLabel.setVisible(false); nsTextField.setVisible(false); } if(parentNum==-1){ String[] appletNames = MessageRelayer.getAppletNames();

private void windowRowNumTextFieldActionPerformed(ActionEvent evt) {//GEN-FIRST:event_windowRowNumTextFieldActionPerformed int val = Integer.parseInt(windowRowNumTextField.getText()); if(val>0 && val<=9 && val!=windowRowNum){ windowRowNum = val; }else{ windowRowNumTextField.setText(String.valueOf(windowRowNum)); } }//GEN-LAST:event_windowRowNumTextFieldActionPerformed private void windowColNumTextFieldActionPerformed(ActionEvent evt) {//GEN-FIRST:event_windowColNumTextFieldActionPerformed int val = Integer.parseInt(windowColNumTextField.getText()); if(val>0 && val<=9 && val!=windowColNum){ windowColNum = val; }else{ windowColNumTextField.setText(String.valueOf(windowColNum)); } }//GEN-LAST:event_windowColNumTextFieldActionPerformed private void detailButtonActionPerformed(ActionEvent evt) {//GEN-FIRST:event_detailButtonActionPerformed if(detailButton.getText().equals("Detail >>")){ detailButton.setText("<< Hide"); controlView.setPreferredSize(new Dimension(DETAIL_CONTROL_WIDTH,controlView.getHeight())); controlView.revalidate(); maxsupLabel.setVisible(true); maxsupScrollBar.setVisible(true); maxsupTextField.setVisible(true); maxsupPercent.setVisible(true); incsupLabel.setVisible(true); incsupTextField.setVisible(true); incsupPercent.setVisible(true); maxconfLabel.setVisible(true); maxconfScrollBar.setVisible(true); maxconfTextField.setVisible(true); maxconfPercent.setVisible(true); incconfLabel.setVisible(true); incconfTextField.setVisible(true); incconfPercent.setVisible(true); orderComboBox.setVisible(true); weightComboBox.setVisible(true); widthComboBox.setVisible(true); colorComboBox.setVisible(true);

A38

Appendix Naviz Applet Class


for(int i=0; i<appletNames.length; i++) if(!appletNames[i].equals(this.getName())){ NavizApplet app = (NavizApplet)MessageRelayer.getApplet(appletNames[i]); if(!(app==null||app.getParentNum()!=appletNum)) app.detailControl(); } } }//GEN-LAST:event_detailButtonActionPerformed private void layoutButtonActionPerformed(ActionEvent evt) {//GEN-FIRST:event_layoutButtonActionPerformed if(layoutMinsup!=minsup || layoutMinconf!=minconf || layoutMaxsup!=maxsup || layoutMaxconf!=maxconf){ layoutMinsup = minsup; layoutMaxsup = maxsup; layoutMinconf = minconf; layoutMaxconf = maxconf; connectToServlet(); if(parentNum==-1){ String[] appletNames = MessageRelayer.getAppletNames(); for(int i=0; i<appletNames.length; i++) if(!appletNames[i].equals(this.getName())){ NavizApplet app = (NavizApplet)MessageRelayer.getApplet(appletNames[i]); if(!(app==null||app.getParentNum()!=appletNum)) app.changeLayout(); } } } }//GEN-LAST:event_layoutButtonActionPerformed private void maxhopTextFieldActionPerformed(ActionEvent evt) {//GEN-FIRST:event_maxhopTextFieldActionPerformed int val = Integer.parseInt(maxhopTextField.getText()); if(val>0 && val>=minhop && val!=maxhop){ maxhop = val; if(workFinished && pathWorkFinished){ Vector paths = getSubPaths(permanentPathNodes,permanentAvoidNodes,pathType); if(maxPathNo>=0){ canvas.setPaths(paths); setMaxPathNo(maxPathNo); setPathNo(appletNum-(parentNum==-1?appletNum:parentNum)); canvas.setPathNo(pathNo); } } canvas.repaint(); if(parentNum==-1){ String[] appletNames = MessageRelayer.getAppletNames(); for(int i=0; i<appletNames.length; i++) if(!appletNames[i].equals(this.getName())){ NavizApplet app = (NavizApplet)MessageRelayer.getApplet(appletNames[i]); if(!(app==null||app.getParentNum()!=appletNum)) app.setMaxhop(maxhop); } } }else{ maxhopTextField.setText(String.valueOf(maxhop)); } }//GEN-LAST:event_maxhopTextFieldActionPerformed private void minhopTextFieldActionPerformed(ActionEvent evt) {//GEN-FIRST:event_minhopTextFieldActionPerformed int val = Integer.parseInt(minhopTextField.getText()); if(val>0 && val<=maxhop && val!=minhop){ minhop = val; if(workFinished && pathWorkFinished){ Vector paths = getSubPaths(permanentPathNodes,permanentAvoidNodes,pathType); if(maxPathNo>=0){ canvas.setPaths(paths); setMaxPathNo(maxPathNo); setPathNo(appletNum-(parentNum==-1?appletNum:parentNum)); canvas.setPathNo(pathNo); } } canvas.repaint(); if(parentNum==-1){ String[] appletNames = MessageRelayer.getAppletNames(); for(int i=0; i<appletNames.length; i++) if(!appletNames[i].equals(this.getName())){ NavizApplet app = (NavizApplet)MessageRelayer.getApplet(appletNames[i]); if(!(app==null||app.getParentNum()!=appletNum)) app.setMinhop(minhop); } } }else{

A39

Appendix Naviz Applet Class


minhopTextField.setText(String.valueOf(minhop)); } }//GEN-LAST:event_minhopTextFieldActionPerformed private void hopCheckBoxActionPerformed(ActionEvent evt) {//GEN-FIRST:event_hopCheckBoxActionPerformed if(parentNum==-1){ if(hopCheckBox.isSelected()){ minhopTextField.setEnabled(true); maxhopTextField.setEnabled(true); }else{ minhopTextField.setEnabled(false); maxhopTextField.setEnabled(false); } } if(workFinished && pathWorkFinished){ Vector paths = getSubPaths(permanentPathNodes,permanentAvoidNodes,pathType); if(maxPathNo>=0){ canvas.setPaths(paths); setMaxPathNo(maxPathNo); setPathNo(appletNum-(parentNum==-1?appletNum:parentNum)); canvas.setPathNo(pathNo); } } canvas.repaint(); if(parentNum==-1){ String[] appletNames = MessageRelayer.getAppletNames(); for(int i=0; i<appletNames.length; i++) if(!appletNames[i].equals(this.getName())){ NavizApplet app = (NavizApplet)MessageRelayer.getApplet(appletNames[i]); if(!(app==null||app.getParentNum()!=appletNum)) app.setHopCheckBox(hopCheckBox.isSelected()); } } }//GEN-LAST:event_hopCheckBoxActionPerformed private void descButtonActionPerformed(ActionEvent evt) {//GEN-FIRST:event_descButtonActionPerformed sortType = DESCENDING; ascButton.setSelected(false); ascButton.setBorder(new border.BevelBorder(border.BevelBorder.RAISED)); descButton.setSelected(true); descButton.setBorder(new border.BevelBorder(border.BevelBorder.LOWERED)); if(workFinished && pathWorkFinished){ Vector paths = getSubPaths(permanentPathNodes,permanentAvoidNodes,pathType); if(maxPathNo>=0){ canvas.setPaths(paths); setMaxPathNo(maxPathNo); setPathNo(appletNum-(parentNum==-1?appletNum:parentNum)); canvas.setPathNo(pathNo); } } canvas.repaint(); if(parentNum==-1){ String[] appletNames = MessageRelayer.getAppletNames(); for(int i=0; i<appletNames.length; i++) if(!appletNames[i].equals(this.getName())){ NavizApplet app = (NavizApplet)MessageRelayer.getApplet(appletNames[i]); if(!(app==null||app.getParentNum()!=appletNum)) app.setSortType(sortType); } } }//GEN-LAST:event_descButtonActionPerformed private void ascButtonActionPerformed(ActionEvent evt) {//GEN-FIRST:event_ascButtonActionPerformed sortType = ASCENDING; ascButton.setSelected(true); ascButton.setBorder(new border.BevelBorder(border.BevelBorder.LOWERED)); descButton.setSelected(false); descButton.setBorder(new border.BevelBorder(border.BevelBorder.RAISED)); if(workFinished && pathWorkFinished){ Vector paths = getSubPaths(permanentPathNodes,permanentAvoidNodes,pathType); if(maxPathNo>=0){ canvas.setPaths(paths); setMaxPathNo(maxPathNo); setPathNo(appletNum-(parentNum==-1?appletNum:parentNum)); canvas.setPathNo(pathNo); } } canvas.repaint(); if(parentNum==-1){ String[] appletNames = MessageRelayer.getAppletNames();

A40

Appendix Naviz Applet Class


for(int i=0; i<appletNames.length; i++) if(!appletNames[i].equals(this.getName())){ NavizApplet app = (NavizApplet)MessageRelayer.getApplet(appletNames[i]); if(!(app==null||app.getParentNum()!=appletNum)) app.setSortType(sortType); } } }//GEN-LAST:event_ascButtonActionPerformed private void sortComboBoxActionPerformed(ActionEvent evt) {//GEN-FIRST:event_sortComboBoxActionPerformed switch(sortComboBox.getSelectedIndex()){ case 0: sortPath = NavizPathServlet.PATH_SUPPORT_ROW; break; case 1: sortPath = NavizPathServlet.PATH_CONFIDENCE_ROW; break; case 2: sortPath = NavizPathServlet.PATH_LENGTH_ROW; } if(workFinished && pathWorkFinished){ Vector paths = getSubPaths(permanentPathNodes,permanentAvoidNodes,pathType); if(maxPathNo>=0){ canvas.setPaths(paths); setMaxPathNo(maxPathNo); setPathNo(appletNum-(parentNum==-1?appletNum:parentNum)); canvas.setPathNo(pathNo); } } canvas.repaint(); if(parentNum==-1){ String[] appletNames = MessageRelayer.getAppletNames(); for(int i=0; i<appletNames.length; i++) if(!appletNames[i].equals(this.getName())){ NavizApplet app = (NavizApplet)MessageRelayer.getApplet(appletNames[i]); if(!(app==null||app.getParentNum()!=appletNum)) app.setSortPath(sortPath); } } }//GEN-LAST:event_sortComboBoxActionPerformed private void closedOpenButtonActionPerformed(ActionEvent evt) {//GEN-FIRST:event_closedOpenButtonActionPerformed pathType = CLOSED_OPEN; openClosedButton.setSelected(false); openClosedButton.setBorder(new border.BevelBorder(border.BevelBorder.RAISED)); closedOpenButton.setSelected(true); closedOpenButton.setBorder(new border.BevelBorder(border.BevelBorder.LOWERED)); openOpenButton.setSelected(false); openOpenButton.setBorder(new border.BevelBorder(border.BevelBorder.RAISED)); closedClosedButton.setSelected(false); closedClosedButton.setBorder(new border.BevelBorder(border.BevelBorder.RAISED)); if(pathNodes.size()>0){ permanentPathNodes = (Vector)pathNodes.clone(); pathNodes.removeAllElements(); } if(avoidNodes.size()>0){ permanentAvoidNodes = (Vector)avoidNodes.clone(); avoidNodes.removeAllElements(); } if(workFinished && pathWorkFinished){ Vector paths = getSubPaths(permanentPathNodes,permanentAvoidNodes,pathType); if(maxPathNo>=0){ canvas.setPaths(paths); setMaxPathNo(maxPathNo); setPathNo(appletNum-(parentNum==-1?appletNum:parentNum)); canvas.setPathNo(pathNo); } } canvas.repaint(); if(parentNum==-1){ String[] appletNames = MessageRelayer.getAppletNames(); for(int i=0; i<appletNames.length; i++) if(!appletNames[i].equals(this.getName())){ NavizApplet app = (NavizApplet)MessageRelayer.getApplet(appletNames[i]); if(!(app==null||app.getParentNum()!=appletNum)) app.setPathType(pathType); } } }//GEN-LAST:event_closedOpenButtonActionPerformed private void openOpenButtonActionPerformed(ActionEvent evt)

A41

Appendix Naviz Applet Class


{//GEN-FIRST:event_openOpenButtonActionPerformed pathType = OPEN_OPEN; openClosedButton.setSelected(false); openClosedButton.setBorder(new border.BevelBorder(border.BevelBorder.RAISED)); closedOpenButton.setSelected(false); closedOpenButton.setBorder(new border.BevelBorder(border.BevelBorder.RAISED)); openOpenButton.setSelected(true); openOpenButton.setBorder(new border.BevelBorder(border.BevelBorder.LOWERED)); closedClosedButton.setSelected(false); closedClosedButton.setBorder(new border.BevelBorder(border.BevelBorder.RAISED)); if(pathNodes.size()>0){ permanentPathNodes = (Vector)pathNodes.clone(); pathNodes.removeAllElements(); } if(avoidNodes.size()>0){ permanentAvoidNodes = (Vector)avoidNodes.clone(); avoidNodes.removeAllElements(); } if(workFinished && pathWorkFinished){ Vector paths = getSubPaths(permanentPathNodes,permanentAvoidNodes,pathType); if(maxPathNo>=0){ canvas.setPaths(paths); setMaxPathNo(maxPathNo); setPathNo(appletNum-(parentNum==-1?appletNum:parentNum)); canvas.setPathNo(pathNo); } } canvas.repaint(); if(parentNum==-1){ String[] appletNames = MessageRelayer.getAppletNames(); for(int i=0; i<appletNames.length; i++) if(!appletNames[i].equals(this.getName())){ NavizApplet app = (NavizApplet)MessageRelayer.getApplet(appletNames[i]); if(!(app==null||app.getParentNum()!=appletNum)) app.setPathType(pathType); } } }//GEN-LAST:event_openOpenButtonActionPerformed private void openClosedButtonActionPerformed(ActionEvent evt) {//GEN-FIRST:event_openClosedButtonActionPerformed pathType = OPEN_CLOSED; openClosedButton.setSelected(true); openClosedButton.setBorder(new border.BevelBorder(border.BevelBorder.LOWERED)); closedOpenButton.setSelected(false); closedOpenButton.setBorder(new border.BevelBorder(border.BevelBorder.RAISED)); openOpenButton.setSelected(false); openOpenButton.setBorder(new border.BevelBorder(border.BevelBorder.RAISED)); closedClosedButton.setSelected(false); closedClosedButton.setBorder(new border.BevelBorder(border.BevelBorder.RAISED)); if(pathNodes.size()>0){ permanentPathNodes = (Vector)pathNodes.clone(); pathNodes.removeAllElements(); } if(avoidNodes.size()>0){ permanentAvoidNodes = (Vector)avoidNodes.clone(); avoidNodes.removeAllElements(); } if(workFinished && pathWorkFinished){ Vector paths = getSubPaths(permanentPathNodes,permanentAvoidNodes,pathType); if(maxPathNo>=0){ canvas.setPaths(paths); setMaxPathNo(maxPathNo); setPathNo(appletNum-(parentNum==-1?appletNum:parentNum)); canvas.setPathNo(pathNo); } } canvas.repaint(); if(parentNum==-1){ String[] appletNames = MessageRelayer.getAppletNames(); for(int i=0; i<appletNames.length; i++) if(!appletNames[i].equals(this.getName())){ NavizApplet app = (NavizApplet)MessageRelayer.getApplet(appletNames[i]); if(!(app==null||app.getParentNum()!=appletNum)) app.setPathType(pathType); } } }//GEN-LAST:event_openClosedButtonActionPerformed private void closedClosedButtonActionPerformed(ActionEvent evt)

A42

Appendix Naviz Applet Class


{//GEN-FIRST:event_closedClosedButtonActionPerformed pathType = CLOSED_CLOSED; openClosedButton.setSelected(false); openClosedButton.setBorder(new border.BevelBorder(border.BevelBorder.RAISED)); closedOpenButton.setSelected(false); closedOpenButton.setBorder(new border.BevelBorder(border.BevelBorder.RAISED)); openOpenButton.setSelected(false); openOpenButton.setBorder(new border.BevelBorder(border.BevelBorder.RAISED)); closedClosedButton.setSelected(true); closedClosedButton.setBorder(new border.BevelBorder(border.BevelBorder.LOWERED)); if(pathNodes.size()>0){ permanentPathNodes = (Vector)pathNodes.clone(); pathNodes.removeAllElements(); } if(avoidNodes.size()>0){ permanentAvoidNodes = (Vector)avoidNodes.clone(); avoidNodes.removeAllElements(); } if(workFinished && pathWorkFinished){ Vector paths = getSubPaths(permanentPathNodes,permanentAvoidNodes,pathType); if(maxPathNo>=0){ canvas.setPaths(paths); setMaxPathNo(maxPathNo); setPathNo(appletNum-(parentNum==-1?appletNum:parentNum)); canvas.setPathNo(pathNo); } } canvas.repaint(); if(parentNum==-1){ String[] appletNames = MessageRelayer.getAppletNames(); for(int i=0; i<appletNames.length; i++) if(!appletNames[i].equals(this.getName())){ NavizApplet app = (NavizApplet)MessageRelayer.getApplet(appletNames[i]); if(!(app==null||app.getParentNum()!=appletNum)) app.setPathType(pathType); } } }//GEN-LAST:event_closedClosedButtonActionPerformed private void pathNoTextFieldActionPerformed(ActionEvent evt) {//GEN-FIRST:event_pathNoTextFieldActionPerformed int pathNo = Integer.parseInt(pathNoTextField.getText()); pathNoScrollBar.setValue(pathNo); }//GEN-LAST:event_pathNoTextFieldActionPerformed private void pathNoScrollBarAdjustmentValueChanged(AdjustmentEvent evt) {//GEN-FIRST:event_pathNoScrollBarAdjustmentValueChanged pathNo = evt.getValue(); if(pathNo>maxPathNo){ pathNo=maxPathNo; pathNoScrollBar.setValue(pathNo); }else{ pathNoTextField.setText (String.valueOf(pathNo+1)); canvas.setPathNo(pathNo); canvas.repaint(); if(parentNum==-1){ String[] appletNames = MessageRelayer.getAppletNames(); for(int i=0; i<appletNames.length; i++) if(!appletNames[i].equals(this.getName())){ NavizApplet app = (NavizApplet)MessageRelayer.getApplet(appletNames[i]); if(!(app==null||app.getParentNum()!=appletNum)) app.setPathNo(pathNo+((NavizApplet)MessageRelayer.getApplet(appletNames [i])).getAppletNum()-appletNum); } } } }//GEN-LAST:event_pathNoScrollBarAdjustmentValueChanged private void pathButtonActionPerformed(ActionEvent evt) {//GEN-FIRST:event_pathButtonActionPerformed if(pathButton.getText().equals("Diagram")){ pathButton.setText("Path"); canvas.removeMouseListener(pathPopupListener); canvas.addMouseListener(popupListener); pathNoScrollBar.setEnabled(false); pathNoTextField.setEnabled(false); closedClosedButton.setEnabled(false); closedClosedButton.setEnabled(false); openOpenButton.setEnabled(false); openClosedButton.setEnabled(false); closedOpenButton.setEnabled(false); sortComboBox.setEnabled(false); ascButton.setEnabled(false); descButton.setEnabled(false);

A43

Appendix Naviz Applet Class


hopCheckBox.setEnabled(false); minhopTextField.setEnabled(false); maxhopTextField.setEnabled(false); canvas.setViewPath(false); }else{ pathButton.setText("Diagram"); canvas.removeMouseListener(popupListener); canvas.addMouseListener(pathPopupListener); pathNoScrollBar.setEnabled(true); pathNoTextField.setEnabled(true); closedClosedButton.setEnabled(true); openOpenButton.setEnabled(true); openClosedButton.setEnabled(true); closedOpenButton.setEnabled(true); sortComboBox.setEnabled(true); ascButton.setEnabled(true); descButton.setEnabled(true); hopCheckBox.setEnabled(true); if(hopCheckBox.isSelected()){ minhopTextField.setEnabled(true); maxhopTextField.setEnabled(true); } canvas.setViewPath(true); if(workFinished && pathWorkFinished){ Vector paths = getSubPaths(permanentPathNodes,permanentAvoidNodes,pathType); if(maxPathNo>=0){ canvas.setPaths(paths); setMaxPathNo(maxPathNo); setPathNo(appletNum-(parentNum==-1?appletNum:parentNum)); canvas.setPathNo(pathNo); } } } canvas.repaint(); if(parentNum==-1){ String[] appletNames = MessageRelayer.getAppletNames(); for(int i=0; i<appletNames.length; i++) if(!appletNames[i].equals(this.getName())){ NavizApplet app = (NavizApplet)MessageRelayer.getApplet(appletNames[i]); if(!(app==null||app.getParentNum()!=appletNum)) app.setPathButton(pathButton.getText()); } } }//GEN-LAST:event_pathButtonActionPerformed private void minconfTextFieldActionPerformed(ActionEvent evt) {//GEN-FIRST:event_minconfTextFieldActionPerformed double val = Double.parseDouble(minconfTextField.getText()); if(val>=0.0 && val<=maxconf){ minconf = val; minconfScrollBar.setValue((int)(minconf/incconf)); }else{ minconfTextField.setText (String.valueOf(minconf)); } }//GEN-LAST:event_minconfTextFieldActionPerformed private void minsupTextFieldActionPerformed(ActionEvent evt) {//GEN-FIRST:event_minsupTextFieldActionPerformed double val = Double.parseDouble(minsupTextField.getText()); if(val>=0.0 && val<=maxsup){ minsup = val; minsupScrollBar.setValue((int)(minsup/incsup)); }else{ minsupTextField.setText (String.valueOf(minsup)); } }//GEN-LAST:event_minsupTextFieldActionPerformed private void minconfScrollBarAdjustmentValueChanged(AdjustmentEvent evt) {//GEN-FIRST:event_minconfScrollBarAdjustmentValueChanged if(evt.getValue()*incconf>=0.0 && evt.getValue()*incconf<=maxconf){ minconf = evt.getValue()*incconf; minconfTextField.setText (format(minconf)); canvas.setData(responsePacket.nodes,supconfFilter(responsePacket.edges) ); if(canvas.isViewPath()){ if(workFinished && pathWorkFinished){ Vector paths = getSubPaths(permanentPathNodes,permanentAvoidNodes,pathType); if(maxPathNo>=0){ canvas.setPaths(paths); setMaxPathNo(maxPathNo); if(pathNo>maxPathNo){ setPathNo(maxPathNo); canvas.setPathNo(pathNo); } } } }

A44

Appendix Naviz Applet Class


canvas.repaint(); if(parentNum==-1){ String[] appletNames = MessageRelayer.getAppletNames(); for(int i=0; i<appletNames.length; i++) if(!appletNames[i].equals(this.getName())){ NavizApplet app = (NavizApplet)MessageRelayer.getApplet(appletNames[i]); if(!(app==null||app.getParentNum()!=appletNum)) app.setMinconf(minconf); } } }else{ minconfScrollBar.setValue((int)(minconf/incconf)); } }//GEN-LAST:event_minconfScrollBarAdjustmentValueChanged private void minsupScrollBarAdjustmentValueChanged(AdjustmentEvent evt) {//GEN-FIRST:event_minsupScrollBarAdjustmentValueChanged if(evt.getValue()*incsup>=0.0 && evt.getValue()*incsup<=maxsup){ minsup = evt.getValue()*incsup; minsupTextField.setText(format(minsup)); canvas.setData(responsePacket.nodes,supconfFilter(responsePacket.edges) ); if(canvas.isViewPath()){ if(workFinished && pathWorkFinished){ Vector paths = getSubPaths(permanentPathNodes,permanentAvoidNodes,pathType); if(maxPathNo>=0){ canvas.setPaths(paths); setMaxPathNo(maxPathNo); if(pathNo>maxPathNo){ setPathNo(maxPathNo); canvas.setPathNo(pathNo); } } } } canvas.repaint(); if(parentNum==-1){ String[] appletNames = MessageRelayer.getAppletNames(); for(int i=0; i<appletNames.length; i++) if(!appletNames[i].equals(this.getName())){ NavizApplet app = (NavizApplet)MessageRelayer.getApplet(appletNames[i]); if(!(app==null||app.getParentNum()!=appletNum)) app.setMinsup(minsup); } } }else{ minsupScrollBar.setValue((int)(minsup/incsup)); } }//GEN-LAST:event_minsupScrollBarAdjustmentValueChanged // Canvas Event Handler private void canvasMouseClicked(MouseEvent evt){ if(!evt.isPopupTrigger() && selectedNode!=null){ if(canvas.isViewPath()){ pathNodeSelected(); }else{ diagramClicked(); } } } private void canvasMouseMoved(MouseEvent evt) { selectedNode = canvas.selectNode((double)evt.getX(),(double)evt.getY()); canvas.setSelectedNode(selectedNode); if(canvas.isViewPath()){ if(selectedNode==null){ try{ canvas.setSelectedEdge(canvas.selectEdge((double)evt.getX(),(double)evt .getY())); }catch(Exception e){ System.err.println("NavizApplet.canvasMouseMoved: "+e.toString()); } } }else{ if(selectedNode==null){ try{ canvas.setSelectedEdge(canvas.selectEdge((double)evt.getX(),(double)evt .getY())); }catch(Exception e){ System.err.println("NavizApplet.canvasMouseMoved: "+e.toString()); } } }

A45

Appendix Naviz Applet Class


canvas.repaint(); } // Applet life cycle public void init() { super.init(); MessageRelayer.addApplet(this); String param = getParameter("appletNum"); if(param != null && !param.equals("")){ try{ appletNum = Integer.parseInt(param); }catch(Exception e){ appletNum = 0; } } MessageRelayer.setMaxAppletNum(appletNum); param = getParameter("parentNum"); if(param != null && !param.equals("")){ try{ parentNum = Integer.parseInt(param); }catch(Exception e){ parentNum = -1; } } param = getParameter("website"); if(param != null && !param.equals("") && !param.equals("null")) website = param; param = getParameter("fromHour"); if(param != null && !param.equals("")){ try{ fromHour = Integer.parseInt(param); }catch(Exception e){ fromHour = 0; } } param = getParameter("toHour"); if(param != null && !param.equals("")){ try{ toHour = Integer.parseInt(param); }catch(Exception e){ toHour = 0; } } param = getParameter("place"); if(param != null && !param.equals("")){ try{ place = Integer.parseInt(param); }catch(Exception e){ place = 0; } } param = getParameter("category"); if(param != null && !param.equals("")){ try{ category = Integer.parseInt(param); }catch(Exception e){ category = 0; } } param = getParameter("comparison"); if(param != null && !param.equals("")){ try{ comparison = Integer.parseInt(param); }catch(Exception e){ comparison = 1; } } param = getParameter("dotXSize"); if(param != null && !param.equals("")){ try{ dotXSize = Double.parseDouble(param); }catch(Exception e){ dotXSize = 12.0; } } param = getParameter("dotYSize"); if(param != null && !param.equals("")){ try{ dotYSize = Double.parseDouble(param); }catch(Exception e){ dotYSize = 7.0; } } param = getParameter("minLineWidth"); if(param != null && !param.equals("")){ try{ minLineWidth = Double.parseDouble(param); }catch(Exception e){ minLineWidth = 1.0; }

A46

Appendix Naviz Applet Class


} param = getParameter("maxLineWidth"); if(param != null && !param.equals("")){ try{ maxLineWidth = Double.parseDouble(param); }catch(Exception e){ maxLineWidth = 10.0; } } System.out.println("name: "+getName()+"appletNum: "+appletNum+", parentNum: "+parentNum); System.out.println(fromHour+","+toHour+","+place+","+category); windowColNumTextField.setText(String.valueOf(windowColNum)); windowRowNumTextField.setText(String.valueOf(windowRowNum)); windowMaxVerTextField.setText(String.valueOf(windowMaxVer)); windowMaxHorTextField.setText(String.valueOf(windowMaxHor)); widthTextField.setText(String.valueOf(newWinWidth)); heightTextField.setText(String.valueOf(newWinHeight)); orderComboBox.setSelectedIndex(orderByRow); weightComboBox.setSelectedIndex(weightByRow); widthComboBox.setSelectedIndex(widthByRow); colorComboBox.setSelectedIndex(colorByRow); openClosedButton.setSelected(false); openClosedButton.setBorder(new border.BevelBorder(border.BevelBorder.RAISED)); closedOpenButton.setSelected(false); closedOpenButton.setBorder(new border.BevelBorder(border.BevelBorder.RAISED)); openOpenButton.setSelected(false); openOpenButton.setBorder(new border.BevelBorder(border.BevelBorder.RAISED)); closedClosedButton.setSelected(true); closedClosedButton.setBorder(new border.BevelBorder(border.BevelBorder.LOWERED)); descButton.setSelected(true); descButton.setBorder(new border.BevelBorder(border.BevelBorder.LOWERED)); minhopTextField.setText(String.valueOf(minhop)); maxhopTextField.setText(String.valueOf(maxhop)); mainPanel.setBounds(0,0,getWidth(),getHeight()); controlScrollPane.setBounds(controlScrollPane.getX(),controlScrollPane. getY(),mainPanel.getWidth()-2*controlScrollPane.getX(),controlScrollPan e.getHeight()); controlView.setPreferredSize(new Dimension(STANDARD_CONTROL_WIDTH,controlView.getHeight())); controlView.revalidate(); canvasPanel.setBounds(canvasPanel.getX(),canvasPanel.getY(),mainPanel.g etWidth()-2*canvasPanel.getX(),mainPanel.getHeight()-canvasPanel.getY() -canvasPanel.getX()); canvas.setBounds(5, 5, canvasPanel.getWidth()-10, canvasPanel.getHeight()-10); if(parentNum!=-1){ comparisonButton.setEnabled(false); launchButton.setEnabled(false); viewTimeButton.setEnabled(false); placeButton.setEnabled(false); categoryButton.setEnabled(false); } String path = getCodeBase().toString(); baseDir = path; /* int i = path.lastIndexOf("/naviz"); if(i>0) baseDir = path.substring(0,i);*/ /* else{ i = path.lastIndexOf('/'); baseDir = path.substring(0,i); }*/ jsobjectWin = JSObject.getWindow(this); JSObject screen = (JSObject)jsobjectWin.getMember("screen"); try{ screenTop = (int)Double.parseDouble(screen.getMember("availTop").toString()); screenLeft = (int)Double.parseDouble(screen.getMember("availLeft").toString()); }catch(Exception e){ screenTop = 0; screenLeft = 0; }

sortComboBox.setSelectedIndex(sortPath==NavizPathServlet.PATH_SUPPORT_R OW?0:(sortPath==NavizPathServlet.PATH_CONFIDENCE_ROW?1:2)); ascButton.setSelected(false); ascButton.setBorder(new border.BevelBorder(border.BevelBorder.RAISED));

A47

Appendix Naviz Applet Class


screenWidth = Double.parseDouble(screen.getMember("availWidth").toString()); screenHeight = Double.parseDouble(screen.getMember("availHeight").toString()); connectToAttributeServlet(); connectToServlet(); connectToPathServlet(); } public void start() { super.start(); } public void stop() { super.stop(); } public void destroy() { super.destroy(); MessageRelayer.removeApplet(this); } private void connectToServlet(){ // // Applet client-side code to send a requestPacket object // to a servlet in a serialized fashion. // // A POST method is sent to the servlet. // final SwingWorker worker = new SwingWorker(){ public Object construct(){ workFinished = false; try{ URL servletUrl = new URL(baseDir+"servlet/naviz.NavizServlet"); URLConnection servletConnection = servletUrl.openConnection(); // inform the connection that we will send output and accept input servletConnection.setDoInput(true); servletConnection.setDoOutput(true); // Don't use a cached version of URL connection. servletConnection.setUseCaches (false); servletConnection.setDefaultUseCaches (false); // Specify the content type that we will send binary data servletConnection.setRequestProperty ("Content-Type", "application/octet-stream"); // send the student object to the servlet using serialization ObjectOutputStream outputToServlet = new ObjectOutputStream(servletConnection.getOutputStream()); // serialize the object buildRequest(); outputToServlet.writeObject(requestPacket); outputToServlet.flush(); outputToServlet.close(); // now, let's read the response from the servlet. ObjectInputStream inputFromServlet = new ObjectInputStream(servletConnection.getInputStream()); responsePacket = (NavizResponse)inputFromServlet.readObject(); inputFromServlet.close(); }catch(Exception e){ System.err.println("nNavizApplet.connectToServlet error: "+e.toString()); } return responsePacket; } public void finished(){ for(Enumeration e = responsePacket.edges.elements(); e.hasMoreElements(); ) drawBezier((NavizEdge)e.nextElement()); if(attributeWorkFinished){ canvas.setData(responsePacket.nodes,supconfFilter(responsePacket.edges) ); } if(pathWorkFinished){ initiated = true; setIncsup(incsup); setMinsup(minsup); setMaxsup(maxsup); setIncconf(incconf); setMinconf(minconf); setMaxconf(maxconf); if(!(pathCompleted||copiedData)){ double[] minmax; for(int i=0; i<pathResponsePacket.paths.size(); i++){ minmax = minmaxSupConf((Vector)pathResponsePacket.paths.elementAt(i)); ((Vector)pathResponsePacket.paths.elementAt(i)).insertElementAt(new Double(minmax[0]),NavizPathServlet.PATH_MINSUP_ROW); ((Vector)pathResponsePacket.paths.elementAt(i)).insertElementAt(new Double(minmax[1]),NavizPathServlet.PATH_MAXSUP_ROW);

A48

Appendix Naviz Applet Class


((Vector)pathResponsePacket.paths.elementAt(i)).insertElementAt(new Double(minmax[2]),NavizPathServlet.PATH_MINCONF_ROW); ((Vector)pathResponsePacket.paths.elementAt(i)).insertElementAt(new Double(minmax[3]),NavizPathServlet.PATH_MAXCONF_ROW); } pathCompleted = true; } if(pathNodes.size()>0){ permanentPathNodes = (Vector)pathNodes.clone(); pathNodes.removeAllElements(); } if(avoidNodes.size()>0){ permanentAvoidNodes = (Vector)avoidNodes.clone(); avoidNodes.removeAllElements(); } Vector paths = getSubPaths(permanentPathNodes,permanentAvoidNodes,pathType); if(maxPathNo>=0){ canvas.setPaths(paths); setMaxPathNo(maxPathNo); setPathNo(appletNum-(parentNum==-1?appletNum:parentNum)); canvas.setPathNo(pathNo); } canvas.repaint(); } workFinished = true; } }; worker.start(); //required for SwingWorker 3 } private void connectToPathServlet(){ // // Applet client-side code to send a requestPacket object // to a servlet in a serialized fashion. // // A POST method is sent to the servlet. // final SwingWorker worker = new SwingWorker(){ public Object construct(){ pathWorkFinished = false; pathCompleted = false; pathResponsePacket = null; /* String[] appletNames = MessageRelayer.getAppletNames(); for(int i=0; i<appletNames.length; i++) if(!appletNames[i].equals(NavizApplet.this.getName())){ NavizApplet app = (NavizApplet)MessageRelayer.getApplet(appletNames[i]); if(app!=null){ if(fromHour==app.getFromHour() && toHour==app.getToHour() && place==app.getPlace() && category==app.getCategory()) pathResponsePacket = (NavizPathResponse)app.pathResponsePacket.clone(); copiedData = true; break; } }*/ if(pathResponsePacket==null){ try{ URL servletUrl = new URL(baseDir+"servlet/naviz.NavizPathServlet"); URLConnection servletConnection = servletUrl.openConnection(); // inform the connection that we will send output and accept input servletConnection.setDoInput(true); servletConnection.setDoOutput(true); // Don't use a cached version of URL connection. servletConnection.setUseCaches (false); servletConnection.setDefaultUseCaches (false); // Specify the content type that we will send binary data servletConnection.setRequestProperty ("Content-Type", "application/octet-stream"); // send the student object to the servlet using serialization ObjectOutputStream outputToServlet = new ObjectOutputStream(servletConnection.getOutputStream()); // serialize the object buildPathRequest(); outputToServlet.writeObject(pathRequestPacket); outputToServlet.flush(); outputToServlet.close(); // now, let's read the response from the servlet. ObjectInputStream inputFromServlet = new ObjectInputStream(servletConnection.getInputStream()); pathResponsePacket = (NavizPathResponse)inputFromServlet.readObject(); inputFromServlet.close(); }catch(Exception e){

A49

Appendix Naviz Applet Class


if(maxPathNo>=0){ canvas.setPaths(paths); setMaxPathNo(maxPathNo); setPathNo(appletNum-(parentNum==-1?appletNum:parentNum)); canvas.setPathNo(pathNo); } canvas.repaint(); } pathWorkFinished = true; } }; worker.start(); //required for SwingWorker 3 } private void connectToAttributeServlet(){ // // Applet client-side code to send a requestPacket object // to a servlet in a serialized fashion. // // A POST method is sent to the servlet. // final SwingWorker worker = new SwingWorker(){ public Object construct(){ if(!MessageRelayer.isAttributeRead()){ try{ URL servletUrl = new URL(baseDir+"servlet/naviz.NavizAttributeServlet"); URLConnection servletConnection = servletUrl.openConnection(); // inform the connection that we will send output and accept input servletConnection.setDoInput(true); servletConnection.setDoOutput(true); // Don't use a cached version of URL connection. servletConnection.setUseCaches (false); servletConnection.setDefaultUseCaches (false); // Specify the content type that we will send binary data servletConnection.setRequestProperty ("Content-Type", "application/octet-stream"); // send the student object to the servlet using serialization ObjectOutputStream outputToServlet = new ObjectOutputStream(servletConnection.getOutputStream()); // serialize the object

System.err.println("nNavizApplet.connectToPathServlet error: "+e.toString()); } } return pathResponsePacket; } public void finished(){ if(workFinished){ initiated = true; setIncsup(incsup); setMinsup(minsup); setMaxsup(maxsup); setIncconf(incconf); setMinconf(minconf); setMaxconf(maxconf); if(!(pathCompleted || copiedData)){ double[] minmax; for(int i=0; i<pathResponsePacket.paths.size(); i++){ minmax = minmaxSupConf((Vector)pathResponsePacket.paths.elementAt(i)); ((Vector)pathResponsePacket.paths.elementAt(i)).insertElementAt(new Double(minmax[0]),NavizPathServlet.PATH_MINSUP_ROW); ((Vector)pathResponsePacket.paths.elementAt(i)).insertElementAt(new Double(minmax[1]),NavizPathServlet.PATH_MAXSUP_ROW); ((Vector)pathResponsePacket.paths.elementAt(i)).insertElementAt(new Double(minmax[2]),NavizPathServlet.PATH_MINCONF_ROW); ((Vector)pathResponsePacket.paths.elementAt(i)).insertElementAt(new Double(minmax[3]),NavizPathServlet.PATH_MAXCONF_ROW); } pathCompleted = true; } if(pathNodes.size()>0){ permanentPathNodes = (Vector)pathNodes.clone(); pathNodes.removeAllElements(); } if(avoidNodes.size()>0){ permanentAvoidNodes = (Vector)avoidNodes.clone(); avoidNodes.removeAllElements(); } Vector paths = getSubPaths(permanentPathNodes,permanentAvoidNodes,pathType);

A50

Appendix Naviz Applet Class


} } for(int i=0;i<hours.size();i++){ if(((Integer)((Vector)hours.elementAt(i)).elementAt(NavizAttributeServl et.ATTRIBUTE_ID)).intValue()==fromHour) fromHourIndex=i; if(((Integer)((Vector)hours.elementAt(i)).elementAt(NavizAttributeServl et.ATTRIBUTE_ID)).intValue()==toHour) toHourIndex=i; } placeComboBox.setSelectedIndex(placeIndex); categoryComboBox.setSelectedIndex(categoryIndex); fromHourComboBox.setSelectedIndex(fromHourIndex); toHourComboBox.setSelectedIndex(toHourIndex); MessageRelayer.setAttributeRead(true); if(workFinished){ canvas.setData(responsePacket.nodes,supconfFilter(responsePacket.edges) ); } attributeWorkFinished = true; } }; worker.start(); //required for SwingWorker 3 } // Helper functions private double[] minmaxSupConf(Vector path){ double[] supconf; double[] minmax = new double[4]; minmax[0] = 100; // minsup minmax[1] = 0; // maxsup minmax[2] = 100; // minconf minmax[3] = 0; // maxconf for(int i=NavizPathServlet.PATH_NODE_ROW-4; i<path.size()-1; i++){ supconf = supconfEdge((String)path.elementAt(i),(String)path.elementAt(i+1)); if(supconf[0]<minmax[0]) minmax[0] = supconf[0]; if(supconf[0]>minmax[1]) minmax[1] = supconf[0]; if(supconf[1]<minmax[2]) minmax[2] = supconf[1]; if(supconf[1]>minmax[3]) minmax[3] = supconf[1]; } return minmax; } private double[] supconfEdge(String start, String end){ double[] supconf = new double[2];

outputToServlet.writeObject(MessageRelayer.getAttributeRequestPacket()) ; outputToServlet.flush(); outputToServlet.close(); // now, let's read the response from the servlet. ObjectInputStream inputFromServlet = new ObjectInputStream(servletConnection.getInputStream()); MessageRelayer.setAttributeResponsePacket((NavizAttributeResponse)input FromServlet.readObject()); inputFromServlet.close(); }catch(Exception e){ System.err.println("nNavizApplet.connectToPathServlet error: "+e.toString()); } } return MessageRelayer.getAttributeResponsePacket(); } public void finished(){ for(int i=0;i<MessageRelayer.getAttributeResponsePacket().places.size();i++){ placeComboBox.addItem(((Vector)MessageRelayer.getAttributeResponsePacke t().places.elementAt(i)).elementAt(NavizAttributeServlet.ATTRIBUTE_NAME )); if(((Integer)((Vector)MessageRelayer.getAttributeResponsePacket().place s.elementAt(i)).elementAt(NavizAttributeServlet.ATTRIBUTE_ID)).intValue ()==place){ placeIndex=i; } } for(int i=0;i<MessageRelayer.getAttributeResponsePacket().categories.size();i++ ){ categoryComboBox.addItem(((Vector)MessageRelayer.getAttributeResponsePa cket().categories.elementAt(i)).elementAt(NavizAttributeServlet.ATTRIBU TE_NAME)); if(((Integer)((Vector)MessageRelayer.getAttributeResponsePacket().categ ories.elementAt(i)).elementAt(NavizAttributeServlet.ATTRIBUTE_ID)).intV alue()==category){ categoryIndex=i;

A51

Appendix Naviz Applet Class


NavizEdge edge = (NavizEdge)responsePacket.edges.get(start+"->"+end); if(edge==null){ supconf[0] = 0.0; supconf[1] = 0.0; }else{ supconf[0] = edge.getSup(); supconf[1] = edge.getConf(); } return supconf; } private void buildPathRequest(){ pathRequestPacket.website = website; pathRequestPacket.fromHour = fromHour; pathRequestPacket.toHour = toHour; pathRequestPacket.place = place; pathRequestPacket.category = category; } private void buildRequest(){ requestPacket.website = website; requestPacket.fromHour = fromHour; requestPacket.toHour = toHour; requestPacket.place = place; requestPacket.category = category; requestPacket.minLineWidth = minLineWidth; requestPacket.maxLineWidth = maxLineWidth; requestPacket.minsup = minsup; requestPacket.maxsup = maxsup; requestPacket.minconf = minconf; requestPacket.maxconf = maxconf; requestPacket.layoutMinsup = layoutMinsup; requestPacket.layoutMaxsup =layoutMaxsup; requestPacket.layoutMinconf = layoutMinconf; requestPacket.layoutMaxconf = layoutMaxconf; requestPacket.maxHue = maxHue; requestPacket.orderByRow = orderByRow; requestPacket.weightByRow = weightByRow; requestPacket.widthByRow = widthByRow; requestPacket.colorByRow = colorByRow; requestPacket.dotCenter = dotCenter; requestPacket.dotOrdering = dotOrdering; requestPacket.dotFontsize = dotFontsize; requestPacket.dotXMargin = dotXMargin; requestPacket.dotYMargin = dotYMargin; requestPacket.dotMclimit = dotMclimit; requestPacket.dotNodesep = dotNodesep; requestPacket.dotNslimit = dotNslimit; //requestPacket.dotXPage; //requestPacket.dotYPage; requestPacket.dotRanksep = dotRanksep; requestPacket.dotRotate = dotRotate; requestPacket.dotXSize = dotXSize; requestPacket.dotYSize = dotYSize; requestPacket.dotClusterrank = dotClusterrank; requestPacket.dotColor = dotColor; requestPacket.dotFontcolor = dotFontcolor; requestPacket.dotFontname = dotFontname; requestPacket.dotLabel = dotLabel; requestPacket.dotOrdering = dotOrdering; requestPacket.dotOrientation = dotOrientation; requestPacket.dotRank = dotRank; requestPacket.dotRankdir = dotRankdir; requestPacket.dotRatio = dotRatio; requestPacket.nodeFontsize = nodeFontsize; requestPacket.nodeColor = nodeColor; requestPacket.nodeFontcolor = nodeFontcolor; requestPacket.nodeFontname = nodeFontname; requestPacket.nodeShape = nodeShape; requestPacket.edgeFontsize = edgeFontsize; requestPacket.edgeMinlen = edgeMinlen; requestPacket.edgeColor = edgeColor; requestPacket.edgeFontcolor = edgeFontcolor; requestPacket.edgeFontname = edgeFontname; requestPacket.edgeDir = edgeDir; } public double normalizeLineWidth(double d, int row){ double maxd=1, mind=0; if (row==NavizServlet.EDGE_SUPPORT_ROW){ maxd = responsePacket.dataMaxsup; mind = responsePacket.dataMinsup; }else{ maxd = responsePacket.dataMaxconf; mind = responsePacket.dataMinconf; } return requestPacket.maxLineWidth + (d-maxd)*(requestPacket.maxLineWidth-requestPacket.minLineWidth)/(maxdmind); } public double normalizeLineColor(double d, int row){

A52

Appendix Naviz Applet Class


double maxd=1, mind=0; if (row==NavizServlet.EDGE_SUPPORT_ROW){ maxd = responsePacket.dataMaxsup; mind = responsePacket.dataMinsup; }else{ maxd = responsePacket.dataMaxconf; mind = responsePacket.dataMinconf; } return (d-maxd)*requestPacket.maxHue/(mind-maxd); } public double unnormalizeLineColor(double d, int row){ double maxd=1, mind=0; if (row==NavizServlet.EDGE_SUPPORT_ROW){ maxd = responsePacket.dataMaxsup; mind = responsePacket.dataMinsup; }else{ maxd = responsePacket.dataMaxconf; mind = responsePacket.dataMinconf; } return maxd + d*(mind-maxd)/requestPacket.maxHue; } public double normalizePathLineWidth(double d, int row){ double maxd=1, mind=0; if (row==NavizServlet.EDGE_SUPPORT_ROW){ maxd = pathResponsePacket.pathMaxsup; mind = pathResponsePacket.pathMinsup; }else{ maxd = pathResponsePacket.pathMaxconf; mind = pathResponsePacket.pathMinconf; } return requestPacket.maxLineWidth + (d-maxd)*(requestPacket.maxLineWidth-requestPacket.minLineWidth)/(maxdmind); } public double normalizePathLineColor(double d, int row){ double maxd=1, mind=0; if (row==NavizServlet.EDGE_SUPPORT_ROW){ maxd = pathResponsePacket.pathMaxsup; mind = pathResponsePacket.pathMinsup; }else{ maxd = pathResponsePacket.pathMaxconf; mind = pathResponsePacket.pathMinconf; } double p = Math.log((1+Math.exp(-maxd/requestPacket.maxHue))*(requestPacket.maxHue -maxd)/(mind-maxd)); double q = ((1+Math.exp(-maxd/requestPacket.maxHue))*(requestPacket.maxHue-maxd)/( mind-maxd))/Math.exp(maxd/requestPacket.maxHue); return Math.exp(p-d) - q; //(d-maxd)*requestPacket.maxHue/(mind-maxd); } public Vector getSubPaths(Vector nodes, Vector avoids, int type){ Vector subPaths = new Vector(pathResponsePacket.paths.size()/10,NavizPathServlet.PATH_CAPACIT Y_INCREMENT/10); for(int i=0; i<pathResponsePacket.paths.size(); i++){ if(((Double)((Vector)pathResponsePacket.paths.elementAt(i)).elementAt(N avizPathServlet.PATH_MINSUP_ROW)).doubleValue() >= minsup && ((Double)((Vector)pathResponsePacket.paths.elementAt(i)).elementAt(Navi zPathServlet.PATH_MAXSUP_ROW)).doubleValue() <= maxsup && ((Double)((Vector)pathResponsePacket.paths.elementAt(i)).elementAt(Navi zPathServlet.PATH_MINCONF_ROW)).doubleValue() >= minconf && ((Double)((Vector)pathResponsePacket.paths.elementAt(i)).elementAt(Navi zPathServlet.PATH_MAXCONF_ROW)).doubleValue() <= maxconf){ if(this.hopCheckBox.isSelected()){ if(((Vector)pathResponsePacket.paths.elementAt(i)).size()-NavizPathServ let.PATH_NODE_ROW >= minhop && ((Vector)pathResponsePacket.paths.elementAt(i)).size()-NavizPathServlet .PATH_NODE_ROW <= maxhop) if(include(nodes,(Vector)pathResponsePacket.paths.elementAt(i),type)) subPaths.insertElementAt(pathResponsePacket.paths.elementAt(i),binarySe arch(subPaths,(Vector)pathResponsePacket.paths.elementAt(i))); }else{ if(include(nodes,(Vector)pathResponsePacket.paths.elementAt(i),type)) subPaths.insertElementAt(pathResponsePacket.paths.elementAt(i),binarySe arch(subPaths,(Vector)pathResponsePacket.paths.elementAt(i))); } } } maxPathNo = subPaths.size()-1; // System.out.println(subPaths.toString());

A53

Appendix Naviz Applet Class


// System.out.println("subPaths was called..."); return subPaths; } private boolean include(Vector nodes, Vector path, int type){ boolean b = false; int order[] = new int[nodes.size()]; if(type == CLOSED_CLOSED){ if(nodes.elementAt(0).equals(path.elementAt(NavizPathServlet.PATH_NODE_ ROW))){ order[0] = 0; b = true; } if(b){ for(int i=1; i<nodes.size()-1; i++){ for(int j=1; j<path.size()-NavizPathServlet.PATH_NODE_ROW-1; j++){ if(nodes.elementAt(i).equals(path.elementAt(j+NavizPathServlet.PATH_NOD E_ROW))){ if(i==1){ order[1] = j; b = true; break; }else{ if(j>=order[i-1]){ order[i] = j; b = true; break; } } } b = false; } if(!b) break; } } if(b){ if(nodes.lastElement().equals(path.lastElement())) b = true; else b = false; } }else if(type == OPEN_OPEN){ for(int i=0; i<nodes.size(); i++){ for(int j=0; j<path.size()-NavizPathServlet.PATH_NODE_ROW; j++){ if(nodes.elementAt(i).equals(path.elementAt(j+NavizPathServlet.PATH_NOD E_ROW))){ if(i==0){ order[0] = j; b = true; break; }else{ if(j>=order[i-1]){ order[i] = j; b = true; break; } } } b = false; } if(!b) break; } }else if(type == OPEN_CLOSED){ for(int i=0; i<nodes.size()-1; i++){ for(int j=0; j<path.size()-NavizPathServlet.PATH_NODE_ROW-1; j++){ if(nodes.elementAt(i).equals(path.elementAt(j+NavizPathServlet.PATH_NOD E_ROW))){ if(i==0){ order[0] = j; b = true; break; }else{ if(j>=order[i-1]){ order[i] = j; b = true; break; } } } b = false; } if(!b) break; } if(b){ if(nodes.lastElement().equals(path.lastElement())) b = true;

A54

Appendix Naviz Applet Class


else b = false; } }else if(type == CLOSED_OPEN){ if(nodes.elementAt(0).equals(path.elementAt(NavizPathServlet.PATH_NODE_ ROW))){ order[0] = 0; b = true; } if(b){ for(int i=1; i<nodes.size(); i++){ for(int j=1; j<path.size()-NavizPathServlet.PATH_NODE_ROW; j++){ if(nodes.elementAt(i).equals(path.elementAt(j+NavizPathServlet.PATH_NOD E_ROW))){ if(i==1){ order[1] = j; b = true; break; }else{ if(j>=order[i-1]){ order[i] = j; b = true; break; } } } b = false; } if(!b) break; } } } return b; } private int binarySearch(Vector path, Vector obj){ // search obj in path using binary search technique int min = -1; // minimum position int max = path.size(); // maximum position int pos = 0; // current position while(min<pos && pos<max){ // current position's value <(>) obj's value if(((Double)((Vector)path.elementAt(pos)).elementAt(sortPath)).doubleVa lue()*sortType < ((Double)obj.elementAt(sortPath)).doubleValue()*sortType) min = pos; // current position's value >(<) obj's value else if(((Double)((Vector)path.elementAt(pos)).elementAt(sortPath)).doubleVa lue()*sortType > ((Double)obj.elementAt(sortPath)).doubleValue()*sortType) max = pos; // current position's value == obj's value else break; pos = Math.round((float)((min+max)/2.0)); } return pos; } private String format(double d){ return numberFormat.format(d); } private Hashtable supconfFilter(Hashtable edges){ String key = null; NavizEdge thisEdge = null; Hashtable newEdges = new Hashtable(edges.size()); for(Enumeration k=edges.keys();k.hasMoreElements();){ key = (String)k.nextElement(); thisEdge = (NavizEdge)edges.get(key); if(thisEdge.getSup()>=minsup && thisEdge.getSup()<=maxsup && thisEdge.getConf()>=minconf && thisEdge.getConf()<=maxconf) newEdges.put(key,thisEdge); } return newEdges; } public String buildUrl(String url){ return url.startsWith("http://")?url:(baseDir+"naviz/"+url); } // helper function to draw the bezier spline protected void drawBezier(NavizEdge edge) { GeneralPath path = new GeneralPath(); CubicCurve2D.Double cubic = new CubicCurve2D.Double(); for (int i=0; i<edge.getPointNum()-3; i+=3){ cubic.setCurve(edge.getPoints(i),edge.getPoints(i+1),edge.getPoints(i+2 ),edge.getPoints(i+3)); path.append(cubic,true); } edge.setPath(path); }

A55

Appendix Naviz Applet Class


public void diagramClicked(){ try{ String url = buildUrl(((NavizNode)responsePacket.nodes.get(selectedNode)).getUrl()); String name = "nodeurl"; String features = "resizable,width=200,height=300"; String eval = name+" = window.open('"+url+"','"+name+"','"+features+"');"; eval += name+".focus();"; System.out.println(eval); jsobjectWin.eval(eval); }catch(Exception e){ System.err.println("nNavizApplet.canvasMouseClicked error: "+e.toString()); } } public void pathNodeSelected(){ pathNodes.addElement(selectedNode); canvas.repaint(); if(parentNum==-1){ String[] appletNames = MessageRelayer.getAppletNames(); for(int i=0; i<appletNames.length; i++) if(!appletNames[i].equals(this.getName())){ NavizApplet app = (NavizApplet)MessageRelayer.getApplet(appletNames[i]); if(!(app==null||app.getParentNum()!=appletNum)) app.addPathNodes(selectedNode); } } } public void pathNodeAvoided(){ avoidNodes.addElement(selectedNode); canvas.repaint(); if(parentNum==-1){ String[] appletNames = MessageRelayer.getAppletNames(); for(int i=0; i<appletNames.length; i++) if(!appletNames[i].equals(this.getName())){ NavizApplet app = (NavizApplet)MessageRelayer.getApplet(appletNames[i]); if(!(app==null||app.getParentNum()!=appletNum)) app.addAvoidNodes(selectedNode); } } } public void pathNodeCleared(String selectedNode){ try{

pathNodes.removeElementAt(pathNodes.lastIndexOf(selectedNode)); }catch(Exception e){ } try{ avoidNodes.removeElementAt(avoidNodes.lastIndexOf(selectedNode)); }catch(Exception e){ } canvas.repaint(); if(parentNum==-1){ String[] appletNames = MessageRelayer.getAppletNames(); for(int i=0; i<appletNames.length; i++) if(!appletNames[i].equals(this.getName())){ NavizApplet app = (NavizApplet)MessageRelayer.getApplet(appletNames[i]); if(!(app==null||app.getParentNum()!=appletNum)) app.pathNodeCleared(selectedNode); } } } public void addApplet(AppletCommunicator remote_app){} public void removeApplet(AppletCommunicator remote_app){} public void postCommand(Object command){} class PopupListener extends MouseAdapter { public void mousePressed(MouseEvent e) { maybeShowPopup(e); } public void mouseReleased(MouseEvent e) { maybeShowPopup(e); } private void maybeShowPopup(MouseEvent e) { if (e.isPopupTrigger()) { popup.show(e.getComponent(), e.getX(), e.getY()); } } } class PathPopupListener extends MouseAdapter { public void mousePressed(MouseEvent e) { maybeShowPopup(e); } public void mouseReleased(MouseEvent e) { maybeShowPopup(e); }

A56

Appendix Naviz Applet Class


private void maybeShowPopup(MouseEvent e) { if (e.isPopupTrigger()) { pathPopup.show(e.getComponent(), e.getX(), e.getY()); } } } // - //GEN-BEGIN:variables private JPanel mainPanel; private JScrollPane controlScrollPane; private JPanel controlView; private JLabel minsupLabel; private JScrollBar minsupScrollBar; private JTextField minsupTextField; private JLabel jLabel21; private JLabel minconfLabel; private JScrollBar minconfScrollBar; private JTextField minconfTextField; private JLabel jLabel22; private JButton pathButton; private JScrollBar pathNoScrollBar; private JTextField pathNoTextField; private JButton closedClosedButton; private JButton openOpenButton; private JButton openClosedButton; private JButton closedOpenButton; private JComboBox sortComboBox; private JButton ascButton; private JButton descButton; private JCheckBox hopCheckBox; private JTextField minhopTextField; private JTextField maxhopTextField; private JButton layoutButton; private JButton detailButton; private JButton launchButton; private JButton viewTimeButton; private JScrollBar maxsupScrollBar; private JLabel maxsupLabel; private JTextField maxsupTextField; private JLabel maxsupPercent; private JScrollBar maxconfScrollBar; private JLabel maxconfLabel; private JTextField maxconfTextField; private JLabel maxconfPercent; private JLabel incsupLabel; private JTextField incsupTextField; private JLabel incsupPercent; private JLabel incconfLabel; private JTextField incconfTextField; private JLabel incconfPercent; private JLabel orderLabel; private JComboBox orderComboBox; private JLabel weightLabel; private JComboBox weightComboBox; private JLabel widthLabel; private JComboBox widthComboBox; private JLabel colorLabel; private JComboBox colorComboBox; private JLabel mcLabel; private JTextField mcTextField; private JLabel nsLabel; private JTextField nsTextField; private JButton orderingButton; private JButton directionButton; private JTextField windowColNumTextField; private JTextField windowRowNumTextField; private JTextField windowMaxHorTextField; private JTextField windowMaxVerTextField; private JButton placeButton; private JButton categoryButton; private JComboBox placeComboBox; private JComboBox categoryComboBox; private JComboBox toHourComboBox; private JComboBox fromHourComboBox; private JButton comparisonButton; private JTextField widthTextField; private JTextField heightTextField; private JPanel canvasPanel; // //GEN-END:variables }

A57

Appendix Naviz Servlet Classes

GraphViz to create layout that has hierarchical structure according to edge support (visitor traffic). Furthermore, NavizServlet will give weight to each edge according to its confidence degree, such that GraphViz will draw edges with heavier weight shorter. This will make the edges with high confidence to be

A2 Naviz Servlets

drawn shorter, hence gives effect of page grouping according to edge confidence (transition probability).
readNode

A2.1 Naviz Servlet


ifFileCached readDiagram buildDot readStatus readPlain runCommand

As shown in Figure A 9 NavizServlet has main task to response to the graph layout request: 1. 2. Check the layout in the cache (ifFileCached), send it if available. Read general edge data from repository (readDiagram), and feed it to GraphViz (buildDot) to make new layout (runCommand). 3. Read layout created by GraphViz (readPlain), store it in the cache, and send
readEdge ifDataExist

mineLog

it. 4. If specific edge data for comparison is not available in the repository (ifDataExist), launch Log Miner to mine desirable pattern (mineLog) and store it into repository. 5. Read specific edge data needed for comparison (readEdge), and send it. The job of buildDot function is to write the nodes and edges data to a .dot file that will be read by GraphVizs dot program to create layout. While writing out the edges data, NavizServlet orders edges according to their support value, such that high support edges will be written out first. This will has
/* * NavizServlet.java * * Created on 2002/07/12, 11:42 */ package naviz; import javax.servlet.*; import javax.servlet.http.*; import java.util.*;

Figure A 9 NavizServlet algorithm.

A58

Appendix Naviz Servlet Classes


import java.sql.*; import java.io.*; /** * * @author praz * @version */ public class NavizServlet extends HttpServlet implements SingleThreadModel { // default value of public static final public static final public static final public static final support public static final confidence public static final edge's start public static final edge's end public public public public public public comment public public edge static static static static static static final final final final final final arguments int EDGE_INITIAL_CAPACITY = 500; int EDGE_CAPACITY_INCREMENT = 100; int EDGE_TUPLE_SIZE = 4; int EDGE_SUPPORT_ROW = 0; // row number of int EDGE_CONFIDENCE_ROW = 1; // row number of int EDGE_START_ROW = 2; int EDGE_END_ROW = 3; // row number of // row number of private String plainFile; private String psFile; private Vector inputData; public Hashtable nodeData; public Hashtable nodeDataByName; private private private private private private private private private Connection navizDB=null; PreparedStatement selectEdge=null; PreparedStatement selectEdgeTest=null; PreparedStatement selectMinMaxSupConf=null; PreparedStatement selectSessionNumAnd=null; PreparedStatement selectSessionNumOr=null; PreparedStatement selectRunstat=null; PreparedStatement insertRunstat=null; PreparedStatement deleteRunstat=null;

int int int int int int

NODE_INITIAL_CAPACITY = 100; NODE_CAPACITY_INCREMENT = 20; NODE_TUPLE_SIZE = 5; NODE_ID_ROW = 0; // row number of id NODE_NAME_ROW = 1; // row number of name NODE_COMMENT_ROW = 2; // row number of

static final int NODE_LINK_ROW = 3; // row number of link static final int NODE_EXIST = 4; // row number of existence in

public static final int FILE_ACCURACY = 100; public static final double MAX_LINE_WEIGHT = 100.0; public String baseDir; public String dirSeparator = ""; //public String dirSeparator = "/"; // end default value of arguments private private private private NavizRequest requestPacket; NavizResponse responsePacket; String statusFile; String dotFile;

/** Initializes the servlet. */ public void init(ServletConfig config) throws ServletException { super.init(config); System.out.println("NavizServlet.init: initiated..."); try{ Class.forName("org.gjt.mm.mysql.Driver"); navizDB = DriverManager.getConnection("jdbc:mysql:///wl","praz","4it2womd"); //navizDB = DriverManager.getConnection("jdbc:mysql://nogizaka.tkl.iis.u-tokyo.ac.j p:3366/wl3","praz","4it2womd"); selectEdge = navizDB.prepareStatement("select start_node,end_node,support,confidence from edge where support>=? and support<=? and confidence>=? and confidence<=? and from_hour=? and to_hour=? and place=? and category=? order by ? desc"); selectEdgeTest = navizDB.prepareStatement("select start_node from edge where from_hour=? and to_hour=? and place=? and category=?"); selectMinMaxSupConf = navizDB.prepareStatement("select min(support) as minsup, max(support) as maxsup, min(confidence) as minconf, max(confidence) as maxconf from edge where support>=? and support<=? and confidence>=? and confidence<=? and from_hour=? and to_hour=? and place=? and category=?"); selectSessionNumAnd = navizDB.prepareStatement("select count(*) as senum from sedata where type=1 and time>=? and time<=? and addr=? and cate=?"); selectSessionNumOr = navizDB.prepareStatement("select count(*) as senum from sedata where type=1 and (time>=? or time<=?) and addr=? and cate=?");

A59

Appendix Naviz Servlet Classes


selectRunstat = navizDB.prepareStatement("select * from runstat where from_hour=? and to_hour=? and place=? and category=?"); insertRunstat = navizDB.prepareStatement("insert into runstat (from_hour,to_hour,place,category) values (?,?,?,?)"); deleteRunstat = navizDB.prepareStatement("delete from runstat where from_hour=? and to_hour=? and place=? and category=?"); }catch(Exception e){ System.out.println("NavizServlet.init error: "+e.toString()); e.printStackTrace(); } } /** Destroys the servlet. */ public void destroy() { } /** Processes requests for both HTTP <code>GET</code> and <code>POST</code> methods. * @param request servlet request * @param response servlet response */ protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { try{ responsePacket = new NavizResponse(); inputData = new Vector(EDGE_INITIAL_CAPACITY,EDGE_CAPACITY_INCREMENT); // get an input stream from the applet ObjectInputStream inputFromApplet = new ObjectInputStream(request.getInputStream()); // read the string data from applet requestPacket = (NavizRequest)inputFromApplet.readObject(); inputFromApplet.close(); System.out.println("NavizServlet.doPost: request accepted from: "+request.getRemoteHost()); buildDiagram(); // send back a confirmation message to the applet response.setContentType("application/octet-stream"); ObjectOutputStream outputToApplet = new ObjectOutputStream(response.getOutputStream()); outputToApplet.writeObject(responsePacket); outputToApplet.flush(); outputToApplet.close(); /** Handles the HTTP <code>POST</code> method. * @param request servlet request * @param response servlet response */ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { processRequest(request, response); } /** Returns a short description of the servlet. */ public String getServletInfo() { return "Naviz servlet which is responsible to build traversal diagram."; } public void buildDiagram(){ makeFilename(); readNode(); if(isFileCached()){ readStatus(); }else{ readDiagram(); buildDot(); runCommand(); } readPlain(); if(isDataExist()) readEdge(); System.out.println("NavizServlet.doPost: response sent..."); }catch(Exception e){ System.out.println("NavizServlet.doPost error: "+e.toString()); e.printStackTrace(); } } /** Handles the HTTP <code>GET</code> method. * @param request servlet request * @param response servlet response */ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { processRequest(request, response); }

A60

Appendix Naviz Servlet Classes


else{ mineLog(); readEdge(); } } private void makeFilename(){ //baseDir = "C:Progra~1Apache~1.0webappsexamplesWEB-INFclassesnaviz website"; baseDir = "C:projectnaviznaviz"; //baseDir = "/usr/local/jakarta-tomcat-4.0.1/webapps/examples/WEB-INF/classes/naviz /"; //baseDir += requestPacket.website + dirSeparator; String filename = "d"; filename += requestPacket.place; filename += requestPacket.category; filename += requestPacket.fromHour; filename += requestPacket.toHour; filename += Math.round(FILE_ACCURACY*requestPacket.layoutMinsup); filename += Math.round(FILE_ACCURACY*requestPacket.layoutMaxsup); filename += Math.round(FILE_ACCURACY*requestPacket.layoutMinconf); filename += Math.round(FILE_ACCURACY*requestPacket.layoutMaxconf); filename += Math.round(FILE_ACCURACY*requestPacket.minLineWidth); filename += Math.round(FILE_ACCURACY*requestPacket.maxLineWidth); filename += Math.round(FILE_ACCURACY*requestPacket.dotXSize); filename += Math.round(FILE_ACCURACY*requestPacket.dotYSize); filename += requestPacket.orderByRow; filename += requestPacket.weightByRow; filename += requestPacket.widthByRow; filename += requestPacket.colorByRow; filename += requestPacket.dotMclimit; filename += requestPacket.dotNslimit; filename += requestPacket.dotRankdir.equals("TB")?"t":"l"; filename += requestPacket.dotOrdering?"t":"f"; statusFile = baseDir + "storage" + dirSeparator + filename + ".stt"; dotFile = baseDir + "storage" + dirSeparator + filename + ".dot"; plainFile = baseDir + "storage" + dirSeparator + filename + ".txt"; psFile = baseDir + "storage" + dirSeparator + filename + ".ps"; } private void readNode(){ System.out.println("NavizServlet.readNode: entered..."); try{ PreparedStatement selectNode = navizDB.prepareStatement("select * from node"); nodeData = new Hashtable(NODE_INITIAL_CAPACITY); nodeDataByName = new Hashtable(NODE_INITIAL_CAPACITY); ResultSet nodeSet = selectNode.executeQuery(); while(nodeSet.next()){ Vector vectorTuple = new Vector(NODE_TUPLE_SIZE,NODE_TUPLE_SIZE); // insert id vectorTuple.addElement(nodeSet.getString("id")); // insert name vectorTuple.addElement(nodeSet.getString("name")); // insert comment vectorTuple.addElement(nodeSet.getString("comment")==null?nodeSet.getSt ring("name"):nodeSet.getString("comment")); // insert link vectorTuple.addElement(nodeSet.getString("link")==null?"":nodeSet.getSt ring("link")); vectorTuple.addElement("false"); nodeData.put(nodeSet.getString("id"),vectorTuple); nodeDataByName.put(nodeSet.getString("name"),vectorTuple); } PreparedStatement selectSessionNum = null; if (requestPacket.fromHour<=requestPacket.toHour) selectSessionNum = selectSessionNumAnd; else selectSessionNum = selectSessionNumOr; selectSessionNum.setInt(1,requestPacket.fromHour==0?10:requestPacket.fr omHour); selectSessionNum.setInt(2,requestPacket.toHour==0?21:requestPacket.toHo ur); selectSessionNum.setInt(3,requestPacket.place); selectSessionNum.setInt(4,requestPacket.category); System.out.println(selectSessionNum.toString()); ResultSet sessionNumSet = selectSessionNum.executeQuery(); if(sessionNumSet.next()) responsePacket.sessionNum = sessionNumSet.getInt("senum"); }catch(Exception e){ System.out.println("NavizServlet.readNode error: "+e.toString()); e.printStackTrace(); } System.out.println("NavizServlet.readNode: exited..."); }

A61

Appendix Naviz Servlet Classes


private boolean isFileCached(){ boolean cached = false; try{ File fileCached = new File(plainFile); if(fileCached.exists()){ System.out.println("Cached: "+plainFile); cached = true; }else{ System.out.println("Not cached: "+plainFile); } }catch(Exception e){ System.out.println("NavizServlet.isFileCached error: "+e.toString()); e.printStackTrace(); } return cached; } private void readStatus(){ FileReader fR = null; BufferedReader bR = null; System.out.println("Read status file: " + statusFile); try{ File f = new File(statusFile); fR = new FileReader(f); bR = new BufferedReader(fR,(int)f.length()); responsePacket.dataMinsup = Double.parseDouble(bR.readLine()); responsePacket.dataMaxsup = Double.parseDouble(bR.readLine()); responsePacket.dataMinconf = Double.parseDouble(bR.readLine()); responsePacket.dataMaxconf = Double.parseDouble(bR.readLine()); bR.close(); fR.close(); }catch(Exception e){ System.out.println("NavizServlet.readStatus error: " + e.toString()); e.printStackTrace(); } } private void readDiagram(){ System.out.println("NavizServlet.readDiagram: entered..."); try{ // filter tuple by "minSup <= sup <= maxSup && minConf <= conf <= maxConf" selectEdge.setDouble(1,requestPacket.layoutMinsup); selectEdge.setDouble(2,requestPacket.layoutMaxsup); selectEdge.setDouble(3,requestPacket.layoutMinconf); selectEdge.setDouble(4,requestPacket.layoutMaxconf); selectEdge.setInt(5,0); selectEdge.setInt(6,0); selectEdge.setInt(7,0); selectEdge.setInt(8,0); selectEdge.setString(9,requestPacket.orderByRow==EDGE_SUPPORT_ROW?"supp ort":"confidence"); // order by ResultSet edgeSet = selectEdge.executeQuery(); inputData = new Vector(selectEdge.getFetchSize(),EDGE_CAPACITY_INCREMENT); responsePacket.edges = new Hashtable(selectEdge.getFetchSize()); while(edgeSet.next()){ Vector vectorTuple = new Vector(EDGE_TUPLE_SIZE,EDGE_TUPLE_SIZE); // insert support vectorTuple.addElement(new Double(edgeSet.getDouble("support"))); // insert confidence vectorTuple.addElement(new Double(edgeSet.getDouble("confidence"))); // insert edge's start Vector start_node = (Vector)nodeData.get(edgeSet.getString("start_node")); if(start_node!=null){ vectorTuple.addElement(start_node.elementAt(NODE_NAME_ROW)); start_node.setElementAt("true",NODE_EXIST); ((Vector)nodeDataByName.get(start_node.elementAt(NODE_NAME_ROW))).setEl ementAt("true",NODE_EXIST); }else{ System.out.println("NULL"+edgeSet.getString("start_node")+" "); } // insert edge's end Vector end_node = (Vector)nodeData.get(edgeSet.getString("end_node")); if(end_node!=null){ vectorTuple.addElement(end_node.elementAt(NODE_NAME_ROW)); end_node.setElementAt("true",NODE_EXIST); ((Vector)nodeDataByName.get(end_node.elementAt(NODE_NAME_ROW))).setElem entAt("true",NODE_EXIST); }else{ System.out.println("NULL"+edgeSet.getString("end_node")+" ");

A62

Appendix Naviz Servlet Classes


} inputData.addElement(vectorTuple); } selectMinMaxSupConf.setDouble(1,requestPacket.layoutMinsup); selectMinMaxSupConf.setDouble(2,requestPacket.layoutMaxsup); selectMinMaxSupConf.setDouble(3,requestPacket.layoutMinconf); selectMinMaxSupConf.setDouble(4,requestPacket.layoutMaxconf); selectMinMaxSupConf.setInt(5,0); selectMinMaxSupConf.setInt(6,0); selectMinMaxSupConf.setInt(7,0); selectMinMaxSupConf.setInt(8,0); ResultSet minMaxSupConfSet = selectMinMaxSupConf.executeQuery(); if(minMaxSupConfSet.next()){ responsePacket.dataMinsup=minMaxSupConfSet.getDouble("minsup"); responsePacket.dataMaxsup=minMaxSupConfSet.getDouble("maxsup"); responsePacket.dataMinconf=minMaxSupConfSet.getDouble("minconf"); responsePacket.dataMaxconf=minMaxSupConfSet.getDouble("maxconf"); } responsePacket.dataMaxsup += responsePacket.dataMaxsup/100.0; responsePacket.dataMaxconf += responsePacket.dataMaxconf/100.0; if(responsePacket.dataMinsup<=0) responsePacket.dataMinsup=0; if(responsePacket.dataMinconf<=0) responsePacket.dataMinconf=0; if(responsePacket.dataMaxsup<=responsePacket.dataMinsup) responsePacket.dataMaxsup+=1; if(responsePacket.dataMaxconf<=responsePacket.dataMinconf) responsePacket.dataMaxconf+=1; }catch(Exception e){ System.out.println("NavizServlet.readDiagram error: "+e.toString()); e.printStackTrace(); } System.out.println("NavizServlet.readDiagram: exited..."); } private void buildDot(){ FileWriter fW = null; BufferedWriter bW = null; System.out.println("Build dot file: " + dotFile); try{ File f = new File(dotFile); f.delete(); f.createNewFile(); fW = new FileWriter(f); bW = new BufferedWriter(fW); bW.write("digraph G{n"); // graph global properties //bW.write("center="+requestPacket.dotCenter+";n"); // centers drawing on page: true, false //bW.write("clusterrank="+requestPacket.dotClusterrank+";n"); // rank of cluster: local, global, none bW.write("color="+requestPacket.dotColor+";n"); // background or cluster outline color: "hue saturation brightness", colorname //bW.write("concentrate="+requestPacket.dotConcentrate+";n"); // enable edges concentrators: true, false bW.write("fontcolor="+requestPacket.dotFontcolor+";n"); // type face color: namecolor bW.write("fontname="+requestPacket.dotFontname+";n"); // PostScript font family: fontname bW.write("fontsize="+requestPacket.dotFontsize+";n"); // point size of label: in points bW.write("label=""+requestPacket.dotLabel+"";n"); // graph label: any string //bW.write("layerpath="+"id:id:id:...+"";n"); bW.write("margin=""+requestPacket.dotXMargin+","+requestPacket.dotYMar gin+"";n"); // margin included in page: bW.write("mclimit="+requestPacket.dotMclimit+";n"); // adjust mincross iterations: f times bW.write("nodesep="+requestPacket.dotNodesep+";n"); // separation between nodes, in inches bW.write("nslimit="+requestPacket.dotNslimit+";n"); // bounds network simplex iterations by f * num of nodes if(requestPacket.dotOrdering) bW.write("ordering=out;n"); // for ordered edges: out //bW.write("orientation="+requestPacket.dotOrientation+";n"); // orientation: portrait, landscape //bW.write("page=""+requestPacket.dotXPage+","+requestPacket.YPage+"" ;n"); // unit of pagination: in inches //bW.write("rank="+requestPacket.dotRank+";n"); // rank: same, min, max bW.write("rankdir="+requestPacket.dotRankdir+";n"); // rank direction: LR: left-right or TB: top-bottom bW.write("ranksep="+requestPacket.dotRanksep+";n"); // separation between ranks, in inches bW.write("ratio="+requestPacket.dotRatio+";n"); // ratio: auto, compress, fill, y/x ratio

A63

Appendix Naviz Servlet Classes


//bW.write("rotate="+requestPacket.dotRotate+";n"); // rotation: in degree bW.write("size=""+requestPacket.dotXSize+","+requestPacket.dotYSize+" ";n"); // graph size: in inches bW.write("node [color="+requestPacket.nodeColor+" fontcolor="+requestPacket.nodeFontcolor+" fontname="+requestPacket.nodeFontname+" fontsize="+requestPacket.nodeFontsize+" shape="+requestPacket.nodeShape+"];n"); bW.write("edge [fontcolor="+requestPacket.edgeFontcolor+" fontname="+requestPacket.edgeFontname+" fontsize="+requestPacket.edgeFontsize+" dir="+requestPacket.edgeDir+" minlen="+requestPacket.edgeMinlen+"];n"); for(int i=0;i<inputData.size();i++){ bW.write("""+((Vector)inputData.elementAt(i)).elementAt(EDGE_START_ROW ).toString()+"" -> ""+((Vector)inputData.elementAt(i)).elementAt(EDGE_END_ROW).toString() +"" ["); //bW.write("label=""+Math.rint(((Double)((Vector)inputData.elementAt(i )).elementAt(EDGE_SUPPORT_ROW)).doubleValue()*100.0)/100.0+","+Math.rin t(((Double)((Vector)inputData.elementAt(i)).elementAt(EDGE_CONFIDENCE_R OW)).doubleValue()*100.0)/100.0+"","); bW.write("weight="+normalizeLineWeight(((Double)((Vector)inputData.elem entAt(i)).elementAt(requestPacket.weightByRow)).doubleValue(),requestPa cket.weightByRow)+","); bW.write("style="setlinewidth("+normalizeLineWidth(((Double)((Vector)i nputData.elementAt(i)).elementAt(requestPacket.widthByRow)).doubleValue (),requestPacket.widthByRow)+")","); bW.write("color=""+normalizeLineColor(((Double)((Vector)inputData.elem entAt(i)).elementAt(requestPacket.colorByRow)).doubleValue(),requestPac ket.colorByRow)+" 1 .95"];n"); //color="hue saturation=1 brightness=.95" } for(Enumeration e=nodeData.elements();e.hasMoreElements();){ Vector node = (Vector)e.nextElement(); if(node.elementAt(NODE_EXIST).equals("true")) bW.write("""+node.elementAt(NODE_NAME_ROW)+"" [label=""+node.elementAt(NODE_COMMENT_ROW)+""];n"); } bW.write("}"); bW.close(); fW.close(); }catch(Exception e){ System.out.println("NavizServlet.buildDot error: " + e.toString()); e.printStackTrace(); } } private void buildStatus(){ FileWriter fileWriterStatus = null; BufferedWriter bufferedWriterStatus = null; try{ File f = new File(statusFile); f.delete(); f.createNewFile(); fileWriterStatus = new FileWriter(f); bufferedWriterStatus = new BufferedWriter(fileWriterStatus); bufferedWriterStatus.write(responsePacket.dataMinsup+"n"); bufferedWriterStatus.write(responsePacket.dataMaxsup+"n"); bufferedWriterStatus.write(responsePacket.dataMinconf+"n"); bufferedWriterStatus.write(responsePacket.dataMaxconf+"n"); bufferedWriterStatus.close(); fileWriterStatus.close(); }catch(Exception e){ System.out.println("NavizServlet.buildStatus error: " + e.toString()); e.printStackTrace(); } } private void runCommand(){ try{ String stringCommand = "dot -Tplain " + dotFile + " -o " + plainFile; System.out.println("Launching: " + stringCommand); Runtime.getRuntime().exec(stringCommand).waitFor(); buildStatus(); }catch(Exception e){ System.out.println("NavizServlet.runCommand error: " + e.toString()); e.printStackTrace(); } } private void readPlain(){ FileReader fR = null; BufferedReader bR = null; String stringTuple = null;

A64

Appendix Naviz Servlet Classes


System.out.println("Read plain file: " + plainFile); try{ File file = new File(plainFile); fR = new FileReader(file); bR = new BufferedReader(fR,(int)file.length()); stringTuple = bR.readLine(); }catch(Exception e){ System.out.println("NavizServlet.readPlain error1: " + e.toString()); e.printStackTrace(); return; } double scaleFactor=1.0, boundingBoxX=0.0, boundingBoxY=0.0; if(stringTuple != null){ // first tuple contains // graph scalefactor bounding_box_x bounding_box_y StringTokenizer stringTokenizerTuple = new StringTokenizer(stringTuple); stringTokenizerTuple.nextToken(); try{ scaleFactor = Double.parseDouble(stringTokenizerTuple.nextToken()); boundingBoxX = Double.parseDouble(stringTokenizerTuple.nextToken()); boundingBoxY = Double.parseDouble(stringTokenizerTuple.nextToken()); }catch(NumberFormatException e){ scaleFactor = 1.0; boundingBoxX = 0.0; boundingBoxY = 0.0; } responsePacket.scaleFactor = scaleFactor; responsePacket.height = boundingBoxY*72*scaleFactor; responsePacket.width = boundingBoxX*72*scaleFactor; }else return; StringTokenizer stringTokenizerTuple, st; String startname, endname, opt_text="", s; int n, opt_x, opt_y; double sup=0.0, conf=0.0, width=1.0, hue=0.0; do{ nextTuple:{ try{ stringTuple = bR.readLine(); }catch(IOException e){ System.out.println(e.toString()); e.printStackTrace(); break; } if(stringTuple != null){ stringTokenizerTuple = new StringTokenizer(stringTuple," t"); // vector of data in a tuple s = stringTokenizerTuple.nextToken(); if(s.equals("node")){ // next group of tuples contain // node name x y xsize ysize label_text String name = stringTokenizerTuple.nextToken(); if(name.substring(0,1).equals(""")){ if(name.substring(name.length()-1,name.length()).equals(""")){ name = name.substring(1,name.length()-1); }else{ name = name.substring(1) + stringTokenizerTuple.nextToken("""); stringTokenizerTuple.nextToken(" t"); } } int[] circle = new int[4]; try{ circle[0] = (int)(Double.parseDouble(stringTokenizerTuple.nextToken())*72*scaleFact or); circle[1] = (int)((boundingBoxY Double.parseDouble(stringTokenizerTuple.nextToken()))*72*scaleFactor); circle[2] = (int)(Double.parseDouble(stringTokenizerTuple.nextToken())*72*scaleFact or); circle[3] = (int)(Double.parseDouble(stringTokenizerTuple.nextToken())*72*scaleFact or); }catch(NumberFormatException e){ circle[0]=0;circle[1]=(int)(boundingBoxY*72*scaleFactor);circle[2]=0;ci rcle[3]=0; } NavizNode node; Vector nameNode = (Vector)nodeDataByName.get(name); if(nameNode==null){ // System.out.println("NULL "+name); node = new NavizNode(name,name,"",circle[0],circle[1],circle[2],circle[3]); }else{

A65

Appendix Naviz Servlet Classes


// System.out.println("NOT NULL "+name+" "+(String)nameNode.elementAt(NODE_LINK_ROW)); node = new NavizNode(name,(String)nameNode.elementAt(NODE_COMMENT_ROW),(String)nam eNode.elementAt(NODE_LINK_ROW),circle[0],circle[1],circle[2],circle[3]) ; } responsePacket.nodes.put(node.getName(),node); }else if(s.equals("edge")){ NavizEdge edge = new NavizEdge(); // next group of tuples contain // edge startname endname n x1 y1 x2 y2 ... xn yn opt_text opt_x opt_y style color startname = stringTokenizerTuple.nextToken(); if(startname.substring(0,1).equals(""")){ if(startname.substring(startname.length()-1,startname.length()).equals( """)){ startname = startname.substring(1,startname.length()-1); }else{ startname = startname.substring(1) + stringTokenizerTuple.nextToken("""); stringTokenizerTuple.nextToken(" t"); } } edge.setStart(startname); endname = stringTokenizerTuple.nextToken(); if(endname.substring(0,1).equals(""")){ if(endname.substring(endname.length()-1,endname.length()).equals(""")) { endname = endname.substring(1,endname.length()-1); }else{ endname = endname.substring(1) + stringTokenizerTuple.nextToken("""); stringTokenizerTuple.nextToken(" t"); } } edge.setEnd(endname); if(!startname.equals(endname)){ if(requestPacket.dotRankdir.equals("TB")){ if(((NavizNode)responsePacket.nodes.get(startname)).getY()>((NavizNode) responsePacket.nodes.get(endname)).getY()) edge.setDirection(-1); }else{ if(((NavizNode)responsePacket.nodes.get(startname)).getX()>((NavizNode) responsePacket.nodes.get(endname)).getX()) edge.setDirection(-1); } } try{ s = stringTokenizerTuple.nextToken(); n = Integer.parseInt(s); }catch(NumberFormatException e){ n=0; } edge.setPointNum(n); for(int i=0;i<n;i++){ try{ edge.setXPoints((int)(Double.parseDouble(stringTokenizerTuple.nextToken ())*72*scaleFactor),i); edge.setYPoints((int)((boundingBoxY Double.parseDouble(stringTokenizerTuple.nextToken()))*72*scaleFactor),i ); }catch(Exception e){ edge.setXPoints(i==0?0:edge.getXPoints(i-1),i); edge.setYPoints(i==0?(int)(boundingBoxY*72*scaleFactor):edge.getYPoints (i-1),i); } } st = new StringTokenizer(stringTokenizerTuple.nextToken(),"(),"); if(!st.nextToken().equals("setlinewidth")){ // it contains edge label opt_text = st.toString(); try{ opt_x = (int)(Double.parseDouble(stringTokenizerTuple.nextToken())*72*scaleFact or); opt_y = (int)((boundingBoxY-Double.parseDouble(stringTokenizerTuple.nextToken() ))*72*scaleFactor); }catch(NumberFormatException e){ opt_x = 0; opt_y = 0; }

A66

Appendix Naviz Servlet Classes


edge.setLabel(opt_text); edge.setLabelX(opt_x); edge.setLabelY(opt_y); st = new StringTokenizer(stringTokenizerTuple.nextToken(),"()"); st.nextToken(); } try{ width = Double.parseDouble(st.nextToken()); hue = Double.parseDouble(stringTokenizerTuple.nextToken()); sup = EDGE_SUPPORT_ROW==requestPacket.widthByRow?unnormalizeLineWidth(width,E DGE_SUPPORT_ROW):unnormalizeLineColor(hue,EDGE_SUPPORT_ROW); conf = EDGE_CONFIDENCE_ROW==requestPacket.widthByRow?unnormalizeLineWidth(widt h,EDGE_CONFIDENCE_ROW):unnormalizeLineColor(hue,EDGE_CONFIDENCE_ROW); }catch(Exception e){ System.out.println("NavizServlet.readPlain error2: " + e.toString()); e.printStackTrace(); } edge.setWidth(width); edge.setSup(sup); edge.setConf(conf); if(st.hasMoreTokens()) break nextTuple; responsePacket.edges.put(edge.getHashKey(),edge); }else{ break; } } } }while(stringTuple != null); try{ bR.close(); fR.close(); }catch(IOException e){ System.out.println("NavizServlet.readPlain error3: " + e.toString()); e.printStackTrace(); } } private void readEdge(){ System.out.println("NavizServlet.readEdge: entered..."); if(!(requestPacket.fromHour==0 && requestPacket.toHour==0 && requestPacket.place==0 && requestPacket.category==0)){ try{ /* for(Enumeration e = responsePacket.edges.elements(); e.hasMoreElements();){ NavizEdge edge = (NavizEdge)e.nextElement(); edge.setSup(0.0); edge.setConf(0.0); }*/ // filter tuple by "minSup <= sup <= maxSup && minConf <= conf <= maxConf" selectEdge.setDouble(1,requestPacket.layoutMinsup); selectEdge.setDouble(2,requestPacket.layoutMaxsup); selectEdge.setDouble(3,requestPacket.layoutMinconf); selectEdge.setDouble(4,requestPacket.layoutMaxconf); selectEdge.setInt(5,requestPacket.fromHour); selectEdge.setInt(6,requestPacket.toHour); selectEdge.setInt(7,requestPacket.place); selectEdge.setInt(8,requestPacket.category); selectEdge.setString(9,requestPacket.orderByRow==EDGE_SUPPORT_ROW?"supp ort":"confidence"); // order by System.out.println("Query: "+selectEdge.toString()); ResultSet edgeSet = selectEdge.executeQuery(); String start = ""; String end = ""; while(edgeSet.next()){ Vector start_node = (Vector)nodeData.get(edgeSet.getString("start_node")); Vector end_node = (Vector)nodeData.get(edgeSet.getString("end_node")); if(start_node!=null && end_node!=null){ start = (String)start_node.elementAt(NODE_NAME_ROW); end = (String)end_node.elementAt(NODE_NAME_ROW); ((NavizEdge)responsePacket.edges.get(start+"->"+end)).setSup(edgeSet.ge tDouble("support")); ((NavizEdge)responsePacket.edges.get(start+"->"+end)).setConf(edgeSet.g etDouble("confidence")); } } }catch(Exception e){ System.out.println("NavizServlet.readEdge error: "+e.toString()); e.printStackTrace(); } System.out.println("NavizServlet.readEdge: exited...");

A67

Appendix Naviz Servlet Classes


} } private boolean isDataExist(){ System.out.println("NavizServlet.isDataExist: entered..."); boolean dataExist = false; try{ // filter tuple by "minSup <= sup <= maxSup && minConf <= conf <= maxConf" selectEdgeTest.setInt(1,requestPacket.fromHour); selectEdgeTest.setInt(2,requestPacket.toHour); selectEdgeTest.setInt(3,requestPacket.place); selectEdgeTest.setInt(4,requestPacket.category); System.out.println("Query: "+selectEdgeTest.toString()); ResultSet edgeTestSet = selectEdgeTest.executeQuery(); if(edgeTestSet.next()){ selectRunstat.setInt(1,requestPacket.fromHour); selectRunstat.setInt(2,requestPacket.toHour); selectRunstat.setInt(3,requestPacket.place); selectRunstat.setInt(4,requestPacket.category); System.out.println("Query: "+selectRunstat.toString()); ResultSet runstatSet = selectRunstat.executeQuery(); if(!runstatSet.next()) dataExist = true; } }catch(Exception e){ System.out.println("NavizServlet.isDataExist error: "+e.toString()); e.printStackTrace(); } System.out.println("NavizServlet.isDataExist: exited..."); return dataExist; } private void mineLog(){ try{ insertRunstat.setInt(1,requestPacket.fromHour); insertRunstat.setInt(2,requestPacket.toHour); insertRunstat.setInt(3,requestPacket.place); insertRunstat.setInt(4,requestPacket.category); System.out.println("Query: "+insertRunstat.toString()); insertRunstat.executeQuery(); double minsup; if(requestPacket.place!=0&&requestPacket.category!=0) minsup = 1.0; else minsup = 0.1; String stringCommand = "rsh komagome.tkl.iis.u-tokyo.ac.jp /home/iko/arc/logmining/logmine 1 "+requestPacket.fromHour+" "+requestPacket.toHour+" "+requestPacket.category+" "+requestPacket.place+" "+minsup+" 377988"; System.out.println("Launching: " + stringCommand); Runtime.getRuntime().exec(stringCommand).waitFor(); deleteRunstat.setInt(1,requestPacket.fromHour); deleteRunstat.setInt(2,requestPacket.toHour); deleteRunstat.setInt(3,requestPacket.place); deleteRunstat.setInt(4,requestPacket.category); System.out.println("Query: "+deleteRunstat.toString()); deleteRunstat.executeQuery(); }catch(Exception e){ System.out.println("NavizServlet.mineLog error: " + e.toString()); e.printStackTrace(); } } private int normalizeLineWeight(double d, int row){ double maxd=1, mind=0; if (row==EDGE_SUPPORT_ROW){ maxd = responsePacket.dataMaxsup; mind = responsePacket.dataMinsup; }else{ maxd = responsePacket.dataMaxconf; mind = responsePacket.dataMinconf; } return (int)(MAX_LINE_WEIGHT + (d-maxd)*MAX_LINE_WEIGHT/(maxd-mind)); } private double normalizeLineWidth(double d, int row){ double maxd=1, mind=0; if (row==EDGE_SUPPORT_ROW){ maxd = responsePacket.dataMaxsup; mind = responsePacket.dataMinsup; }else{ maxd = responsePacket.dataMaxconf; mind = responsePacket.dataMinconf; } return requestPacket.maxLineWidth + (d-maxd)*(requestPacket.maxLineWidth-requestPacket.minLineWidth)/(maxdmind); } private double unnormalizeLineWidth(double d, int row){ double maxd=1, mind=0; if (row==EDGE_SUPPORT_ROW){ maxd = responsePacket.dataMaxsup;

A68

Appendix Naviz Servlet Classes


mind = responsePacket.dataMinsup; }else{ maxd = responsePacket.dataMaxconf; mind = responsePacket.dataMinconf; } return maxd + (d-requestPacket.maxLineWidth)*(maxd-mind)/(requestPacket.maxLineWidthrequestPacket.minLineWidth); } private double normalizeLineColor(double d, int row){ double maxd=1, mind=0; if (row==EDGE_SUPPORT_ROW){ maxd = responsePacket.dataMaxsup; mind = responsePacket.dataMinsup; }else{ maxd = responsePacket.dataMaxconf; mind = responsePacket.dataMinconf; } return (d-maxd)*requestPacket.maxHue/(mind-maxd); } private double unnormalizeLineColor(double d, int row){ double maxd=1, mind=0; if (row==EDGE_SUPPORT_ROW){ maxd = responsePacket.dataMaxsup; mind = responsePacket.dataMinsup; }else{ maxd = responsePacket.dataMaxconf; mind = responsePacket.dataMinconf; } return maxd + d*(mind-maxd)/requestPacket.maxHue; } }

readNode timer

dataExist

ifDataExist

dataExist=false

readPath

dataExist=true

Figure A 10. NavizPathServlet algorithms

/* * NavizPathServlet.java * * Created on 2002/07/12, 13:52 */ package naviz; import import import import import javax.servlet.*; javax.servlet.http.*; java.util.*; java.sql.*; java.io.*;

A2.2 Naviz Path Servlet


NavizPathServlet has main task to response to the paths data request from client. It reads path data from repository (if available) and send it to the client. If specific path data is not available, it will wait for NavizServlet to launch Log Miner to prepare the requested paths.

/** * * @author praz * @version */ public class NavizPathServlet extends HttpServlet implements SingleThreadModel { // default value of public static final public static final public static final length public static final arguments int PATH_INITIAL_CAPACITY = 5000; int PATH_CAPACITY_INCREMENT = 500; int PATH_LENGTH_ROW = 0; // row number of path int PATH_SUPPORT_ROW = 1; // row number of path

A69

Appendix Naviz Servlet Classes


support public static final int PATH_CONFIDENCE_ROW = 2; // row number of path confidence public static final int PATH_MINSUP_ROW = 3; // row number of path edge minimum support public static final int PATH_MAXSUP_ROW = 4; // row number of path edge maximum support public static final int PATH_MINCONF_ROW = 5; // row number of path edge minimum confidence public static final int PATH_MAXCONF_ROW = 6; // row number of path edge maximum confidence public static final int PATH_NODE_ROW = 7; // first row number of path nodes public static final int PATH_TUPLE_SIZE = 11; //public String baseDir; public String dirSeparator = ""; //public String dirSeparator = "/"; // end default value of arguments private NavizPathRequest pathRequestPacket; private NavizPathResponse pathResponsePacket; private boolean dataExist = false; public Hashtable nodeData; public Hashtable nodeDataByName; private private private private private Connection navizDB=null; PreparedStatement selectSequence=null; PreparedStatement selectSequenceTest=null; PreparedStatement selectMinMaxSupConf=null; PreparedStatement selectRunstat=null; to_hour=? and place=? and category=? and sequence=id order by id, order_num"); selectSequenceTest = navizDB.prepareStatement("select id from sequence where from_hour=? and to_hour=? and place=? and category=?"); selectMinMaxSupConf = navizDB.prepareStatement("select min(support) as minsup, max(support) as maxsup, min(confidence) as minconf, max(confidence) as maxconf from sequence where from_hour=? and to_hour=? and place=? and category=?"); selectRunstat = navizDB.prepareStatement("select * from runstat where from_hour=? and to_hour=? and place=? and category=?"); }catch(Exception e){ System.out.println("NavizPathServlet.init error: "+e.toString()); e.printStackTrace(); } } /** Destroys the servlet. */ public void destroy() { } /** Processes requests for both HTTP <code>GET</code> and <code>POST</code> methods. * @param request servlet request * @param response servlet response */ protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { try{ pathResponsePacket = new NavizPathResponse(); // get an input stream from the applet ObjectInputStream inputFromApplet = new ObjectInputStream(request.getInputStream()); // read the string data from applet pathRequestPacket = (NavizPathRequest)inputFromApplet.readObject(); inputFromApplet.close(); System.out.println("NavizPathServlet.doPost: request accepted from: "+request.getRemoteHost()); readNode(); Timer timer = new Timer(); IsDataExist task = new IsDataExist(); timer.schedule(task,5000,5000);

/** Initializes the servlet. */ public void init(ServletConfig config) throws ServletException { super.init(config); System.out.println("NavizPathServlet.init: initiated..."); try{ Class.forName("org.gjt.mm.mysql.Driver"); navizDB = DriverManager.getConnection("jdbc:mysql:///wl","praz","4it2womd"); //navizDB = DriverManager.getConnection("jdbc:mysql://nogizaka.tkl.iis.u-tokyo.ac.j p:3366/wl3","praz","4it2womd"); selectSequence = navizDB.prepareStatement("select id, support, confidence, node, order_num from sequence, seq_body where from_hour=? and

A70

Appendix Naviz Servlet Classes


task.run(); System.out.println("dataExist: "+dataExist); while(!dataExist); timer.cancel(); readPath(); // send back a confirmation message to the applet response.setContentType("application/octet-stream"); ObjectOutputStream outputToApplet = new ObjectOutputStream(response.getOutputStream()); outputToApplet.writeObject(pathResponsePacket); outputToApplet.flush(); outputToApplet.close(); System.out.println("NavizPathServlet.doPost: response sent..."); }catch(Exception e){ System.out.println("NavizPathServlet.doPost error: "+e.toString()); e.printStackTrace(); } } /** Handles the HTTP <code>GET</code> method. * @param request servlet request * @param response servlet response */ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { processRequest(request, response); } /** Handles the HTTP <code>POST</code> method. * @param request servlet request * @param response servlet response */ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { processRequest(request, response); } /** Returns a short description of the servlet. */ public String getServletInfo() { return "Naviz path servlet which is responsible to retrieve paths from database."; } class IsDataExist extends TimerTask{ public IsDataExist(){} public void run(){ System.out.println("NavizPathServlet.isDataExist: entered..."); try{ // filter tuple by "minSup <= sup <= maxSup && minConf <= conf <= maxConf" selectSequenceTest.setInt(1,pathRequestPacket.fromHour); selectSequenceTest.setInt(2,pathRequestPacket.toHour); selectSequenceTest.setInt(3,pathRequestPacket.place); selectSequenceTest.setInt(4,pathRequestPacket.category); System.out.println("Query: "+selectSequenceTest.toString()); ResultSet sequenceTestSet = selectSequenceTest.executeQuery(); if(sequenceTestSet.next()){ selectRunstat.setInt(1,pathRequestPacket.fromHour); selectRunstat.setInt(2,pathRequestPacket.toHour); selectRunstat.setInt(3,pathRequestPacket.place); selectRunstat.setInt(4,pathRequestPacket.category); System.out.println("Query: "+selectRunstat.toString()); ResultSet runstatSet = selectRunstat.executeQuery(); if(!runstatSet.next()) dataExist = true; } }catch(Exception e){ System.out.println("NavizPathServlet.isDataExist error: "+e.toString()); e.printStackTrace(); } System.out.println("NavizPathServlet.isDataExist: exited..."); } }; private void readNode(){ System.out.println("NavizPathServlet.readNode: entered..."); try{ PreparedStatement selectNode = navizDB.prepareStatement("select * from node"); nodeData = new Hashtable(NavizServlet.NODE_INITIAL_CAPACITY); nodeDataByName = new Hashtable(NavizServlet.NODE_INITIAL_CAPACITY); ResultSet nodeSet = selectNode.executeQuery(); while(nodeSet.next()){ Vector vectorTuple = new Vector(NavizServlet.NODE_TUPLE_SIZE); // insert id vectorTuple.addElement(nodeSet.getString("id"));

A71

Appendix Naviz Servlet Classes


// insert name vectorTuple.addElement(nodeSet.getString("name")); // insert comment vectorTuple.addElement(nodeSet.getString("comment")==null?nodeSet.getSt ring("name"):nodeSet.getString("comment")); // insert link vectorTuple.addElement(nodeSet.getString("link")==null?"":nodeSet.getSt ring("link")); vectorTuple.addElement("false"); nodeData.put(nodeSet.getString("id"),vectorTuple); nodeDataByName.put(nodeSet.getString("name"),vectorTuple); } }catch(Exception e){ System.out.println("NavizPathServlet.readNode error: "+e.toString()); e.printStackTrace(); } System.out.println("NavizPathServlet.readNode: exited..."); } private void readPath(){ System.out.println("NavizPathServlet.readPath: entered..."); // filter tuple by "minSup <= sup <= maxSup && minConf <= conf <= maxConf" try{ pathResponsePacket.paths = new Vector(PATH_INITIAL_CAPACITY,PATH_CAPACITY_INCREMENT); selectSequence.setInt(1,pathRequestPacket.fromHour); selectSequence.setInt(2,pathRequestPacket.toHour); selectSequence.setInt(3,pathRequestPacket.place); selectSequence.setInt(4,pathRequestPacket.category); System.out.println("Query: "+selectSequence.toString()); ResultSet sequenceSet = selectSequence.executeQuery(); int prevId = -1; int orderNum = -1; if(sequenceSet.next()){ do{ Vector vectorTuple = new Vector(PATH_TUPLE_SIZE,PATH_TUPLE_SIZE); prevId = sequenceSet.getInt("id"); // insert support vectorTuple.addElement(new Double(sequenceSet.getDouble("support"))); // insert confidence vectorTuple.addElement(new Double(sequenceSet.getDouble("confidence"))); while(sequenceSet.getInt("id") == prevId){ // insert nodes Vector node = (Vector)nodeData.get(sequenceSet.getString("node")); if(node!=null) vectorTuple.addElement(node.elementAt(NavizServlet.NODE_NAME_ROW)); orderNum = sequenceSet.getInt("order_num"); if(!sequenceSet.next()) prevId=-1; } vectorTuple.insertElementAt(new Double(orderNum),PATH_LENGTH_ROW); pathResponsePacket.paths.addElement(vectorTuple); }while(prevId!=-1); } selectMinMaxSupConf.setInt(1,pathRequestPacket.fromHour); selectMinMaxSupConf.setInt(2,pathRequestPacket.toHour); selectMinMaxSupConf.setInt(3,pathRequestPacket.place); selectMinMaxSupConf.setInt(4,pathRequestPacket.category); ResultSet minMaxSupConfSet = selectMinMaxSupConf.executeQuery(); if(minMaxSupConfSet.next()){ pathResponsePacket.pathMinsup=minMaxSupConfSet.getDouble("minsup"); pathResponsePacket.pathMaxsup=minMaxSupConfSet.getDouble("maxsup"); pathResponsePacket.pathMinconf=minMaxSupConfSet.getDouble("minconf"); pathResponsePacket.pathMaxconf=minMaxSupConfSet.getDouble("maxconf"); } pathResponsePacket.pathMaxsup += pathResponsePacket.pathMaxsup/100.0; pathResponsePacket.pathMaxconf += pathResponsePacket.pathMaxconf/100.0; }catch(Exception e){ System.out.println("NavizPathServlet.readPath error: "+e.toString()); e.printStackTrace(); } System.out.println("NavizPathServlet.readPath: exited..."); } }

A72

Appendix Naviz Servlet Classes

A2.3 Naviz Attribute Servlet


NavizAttributeServlet has main task to read the attributes needed to be used in comparison function, such as total session number, and available values of properties place and category.
/* * NavizAttributeServlet.java * * Created on 2002/07/12, 13:56 */ package naviz; import import import import import javax.servlet.*; javax.servlet.http.*; java.sql.*; java.io.*; java.util.*;

private NavizAttributeRequest attributeRequestPacket; private NavizAttributeResponse attributeResponsePacket; private private private private private Connection navizDB=null; PreparedStatement selectTotalSessionNum=null; PreparedStatement selectPlace=null; PreparedStatement selectCategory=null; PreparedStatement selectStation=null;

/** * * @author praz * @version */ public class NavizAttributeServlet extends HttpServlet implements SingleThreadModel {

// default value of arguments public static final int ATTRIBUTE_INITIAL_CAPACITY = 1000; public static final int ATTRIBUTE_CAPACITY_INCREMENT = 200; public static final int ATTRIBUTE_ID = 0; // row number of count public static final int ATTRIBUTE_COUNT = 1; // row number of count public static final int ATTRIBUTE_CODE = 2; // row number of code public static final int ATTRIBUTE_NAME = 3; // row number of name public static final int ATTRIBUTE_TUPLE_SIZE = 4; // end default value of arguments

/** Initializes the servlet. */ public void init(ServletConfig config) throws ServletException { super.init(config); System.out.println("NavizAttributeServlet.init: initiated..."); try{ Class.forName("org.gjt.mm.mysql.Driver"); navizDB = DriverManager.getConnection("jdbc:mysql:///wl","praz","4it2womd"); //navizDB = DriverManager.getConnection("jdbc:mysql://nogizaka.tkl.iis.u-tokyo.ac.j p:3366/wl3","praz","4it2womd"); selectTotalSessionNum = navizDB.prepareStatement("select count(*) as senum from sedata where type=1 and time>=10 and time<=21 and addr=0 and cate=0"); selectPlace = navizDB.prepareStatement("select * from attributes where left(code,1)='J'"); selectCategory = navizDB.prepareStatement("select * from attributes where left(code,1)='G'"); selectStation = navizDB.prepareStatement("select * from attributes where left(code,1)='E'"); }catch(Exception e){ System.out.println("NavizAttributeServlet.init error: "+e.toString()); e.printStackTrace(); } } /** Destroys the servlet. */ public void destroy() { } /** Processes requests for both HTTP <code>GET</code> and <code>POST</code> methods. * @param request servlet request

A73

Appendix Naviz Servlet Classes


* @param response servlet response */ protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { try{ attributeResponsePacket = new NavizAttributeResponse(); // get an input stream from the applet ObjectInputStream inputFromApplet = new ObjectInputStream(request.getInputStream()); // read the string data from applet attributeRequestPacket = (NavizAttributeRequest)inputFromApplet.readObject(); inputFromApplet.close(); System.out.println("NavizAttributeServlet.doPost: request accepted from: "+request.getRemoteHost()); readAttribute(); // send back a confirmation message to the applet response.setContentType("application/octet-stream"); ObjectOutputStream outputToApplet = new ObjectOutputStream(response.getOutputStream()); outputToApplet.writeObject(attributeResponsePacket); outputToApplet.flush(); outputToApplet.close(); System.out.println("NavizAttributeServlet.doPost: response sent..."); }catch(Exception e){ System.out.println("NavizAttributeServlet.doPost error: "+e.toString()); e.printStackTrace(); } } /** Handles the HTTP <code>GET</code> method. * @param request servlet request * @param response servlet response */ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { processRequest(request, response); } /** Handles the HTTP <code>POST</code> method. * @param request servlet request * @param response servlet response */ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { processRequest(request, response); } /** Returns a short description of the servlet. */ public String getServletInfo() { return "Short description"; } private void readAttribute(){ System.out.println("NavizAttributeServlet.readPath: entered..."); // filter tuple by "minSup <= sup <= maxSup && minConf <= conf <= maxConf" try{ ResultSet totalSessionNumSet = selectTotalSessionNum.executeQuery(); if(totalSessionNumSet.next()) attributeResponsePacket.totalSessionNum = totalSessionNumSet.getInt("senum"); attributeResponsePacket.places = new Vector(ATTRIBUTE_INITIAL_CAPACITY,ATTRIBUTE_CAPACITY_INCREMENT); System.out.println("Query: "+selectPlace.toString()); ResultSet placeSet = selectPlace.executeQuery(); Vector vectorTuple0 = new Vector(ATTRIBUTE_TUPLE_SIZE); // insert id vectorTuple0.addElement(new Integer(0)); // insert count vectorTuple0.addElement(new Integer(0)); // insert code vectorTuple0.addElement("All"); // insert name vectorTuple0.addElement("All"); attributeResponsePacket.places.addElement(vectorTuple0); while(placeSet.next()){ Vector vectorTuple = new Vector(ATTRIBUTE_TUPLE_SIZE); // insert id vectorTuple.addElement(new Integer(placeSet.getInt("item"))); // insert count vectorTuple.addElement(new Integer(placeSet.getInt("cnt"))); // insert code vectorTuple.addElement(new

A74

Appendix Naviz Servlet Classes


String(placeSet.getString("code"))); // insert name vectorTuple.addElement(new String(placeSet.getString("attrib"))); attributeResponsePacket.places.addElement(vectorTuple); } attributeResponsePacket.categories = new Vector(ATTRIBUTE_INITIAL_CAPACITY,ATTRIBUTE_CAPACITY_INCREMENT); System.out.println("Query: "+selectCategory.toString()); ResultSet categorySet = selectCategory.executeQuery(); Vector vectorTuple1 = new Vector(ATTRIBUTE_TUPLE_SIZE); // insert id vectorTuple1.addElement(new Integer(0)); // insert count vectorTuple1.addElement(new Integer(0)); // insert code vectorTuple1.addElement("All"); // insert name vectorTuple1.addElement("All"); attributeResponsePacket.categories.addElement(vectorTuple1); while(categorySet.next()){ Vector vectorTuple = new Vector(ATTRIBUTE_TUPLE_SIZE); // insert id vectorTuple.addElement(new Integer(categorySet.getInt("item"))); // insert count vectorTuple.addElement(new Integer(categorySet.getInt("cnt"))); // insert code vectorTuple.addElement(new String(categorySet.getString("code"))); // insert name vectorTuple.addElement(new String(categorySet.getString("attrib"))); attributeResponsePacket.categories.addElement(vectorTuple); } attributeResponsePacket.stations = new Vector(ATTRIBUTE_INITIAL_CAPACITY,ATTRIBUTE_CAPACITY_INCREMENT); System.out.println("Query: "+selectStation.toString()); ResultSet stationSet = selectStation.executeQuery(); Vector vectorTuple2 = new Vector(ATTRIBUTE_TUPLE_SIZE); // insert id vectorTuple2.addElement(new Integer(0)); // insert count vectorTuple2.addElement(new Integer(0)); // insert code vectorTuple2.addElement("All"); // insert name vectorTuple2.addElement("All"); attributeResponsePacket.stations.addElement(vectorTuple2); while(stationSet.next()){ Vector vectorTuple = new Vector(ATTRIBUTE_TUPLE_SIZE); // insert id vectorTuple.addElement(new Integer(stationSet.getInt("item"))); // insert count vectorTuple.addElement(new Integer(stationSet.getInt("cnt"))); // insert code vectorTuple.addElement(new String(stationSet.getString("code"))); // insert name vectorTuple.addElement(new String(stationSet.getString("attrib"))); attributeResponsePacket.stations.addElement(vectorTuple); } }catch(Exception e){ System.out.println("NavizAttributeServlet.readPath error: "+e.toString()); e.printStackTrace(); } System.out.println("NavizAttributeServlet.readPath: exited..."); } }

A75

Appendix Helper Classes

A3

Helper Classes

A3.1 Class of Canvas to Draw Traversal Diagram


NavizCanvas has main task to draw the traversal diagram into the screen. The nodes, edges, and paths data is supplied from NavizApplet in advance. As shown in the data type classes section, NavizNode and NavizEdge data type contains sufficient information to draw itself into the screen. Such as, size, location, and title for nodes, or location, spline information, start_node, end_node, sup, conf, etc. for edges. And paths supplied to canvas is sub paths that already satisfies condition specified by user. Thus the job of canvas is quite straightforward, roughly includes checks if the mode is traversal diagram or traversal path, and draws corresponding traversal diagram by calling appropriate java built in function to draw nodes or edges.
/* * NavizCanvas.java * * Created on 2001/07/13, 17:32 */ package naviz; import import import import import import import javax.swing.JPanel; java.util.*; java.awt.event.*; java.awt.geom.*; java.awt.*; com.jrefinery.data.*; com.jrefinery.chart.*;

/** * * @author Bowo Prasetyo * @version */ public class NavizCanvas extends JPanel implements ItemListener, ActionListener{ public static final public static final public static final public static final public static final public static final public static final public static final public static final public static final public static final (int)SUP_CHART_WIDTH + int TOP = 75; // pixels int LEFT = 0; int HEIGHT = 600; int WIDTH = 900; double PIE_CHART_WIDTH = 75.0; double PIE_CHART_HEIGHT = 75.0; double SUP_CHART_WIDTH = 15.0; double SUP_CHART_HEIGHT = 75.0; double CONF_CHART_WIDTH = 15.0; double CONF_CHART_HEIGHT = 75.0; int LEFT_MARGIN = (int)PIE_CHART_WIDTH + (int)CONF_CHART_WIDTH + 15;

public static final double LINE_WIDTH_RATIO = 0.75; private static final double FONT_WIDTH_RATIO = 0.65; private static final int ALPHA = 256; // ???? - ??????? private Hashtable nodes; private Hashtable edges; private FontMetrics fm; // ???????? private private private private private private DefaultPieDataset pieDataset; PiePlot piePlot; DefaultCategoryDataset supDataset; DefaultCategoryDataset confDataset; VerticalCategoryPlot supPlot; VerticalCategoryPlot confPlot;

// property that has set method only private NavizApplet applet; private Vector paths; public void setApplet(NavizApplet applet){ this.applet = applet; }

A76

Appendix Helper Classes


public void setPaths(Vector paths){ this.paths = paths; } // property that has both get and set methods private boolean viewPath; private int pathNo; private String selectedNode; private String message; private NavizEdge selectedEdge; public boolean isViewPath() { return viewPath; } public void setViewPath(boolean viewPath) { this.viewPath = viewPath; } public int getPathNo() { return pathNo; } public void setPathNo(int pathNo){ this.pathNo = pathNo; } public String getSelectedNode() { return selectedNode; } public void setSelectedNode(String selectedNode) { this.selectedNode = selectedNode; selectedEdge = null; } public String getMessage() { return message; } public void setMessage(String message){ this.message = message; } public void addMessage(String message){ this.message += message; } public NavizEdge getSelectedEdge() { return selectedEdge; } public void setSelectedEdge(NavizEdge selectedEdge) { this.selectedEdge = selectedEdge; selectedNode = null; } /** Creates new NavizCanvas */ public NavizCanvas() { selectedEdge = null; selectedNode = null; message = ""; viewPath = false; } public void setData(Hashtable hn, Hashtable he){ nodes = hn; edges = he; pieDataset = new DefaultPieDataset(); pieDataset.setValue("Session",new Double(((double) applet.responsePacket.sessionNum)/MessageRelayer.getAttributeResponsePa cket().totalSessionNum)); pieDataset.setValue("Remaining",new Double(1.0-((double) applet.responsePacket.sessionNum)/MessageRelayer.getAttributeResponsePa cket().totalSessionNum)); piePlot = new PiePlot(pieDataset); piePlot.setSectionLabelType(PiePlot.NO_LABELS); piePlot.setOutlineStroke(null); } private int getFontSize(Graphics2D g){ NavizNode thisNode = (NavizNode)nodes.elements().nextElement(); FontMetrics fm = new FontMetrics(new Font(applet.getNodeFontname(),Font.PLAIN,applet.getNodeFontsize())){}; Rectangle2D bound = fm.getStringBounds(thisNode.getComment(),g); return (int)(applet.getNodeFontsize()*thisNode.getW()/bound.getWidth()*FONT_WI DTH_RATIO); } public void paintComponent(Graphics g0){ super.paintComponent(g0); Graphics2D g = (Graphics2D)g0; if(applet.isWorkFinished() && applet.isPathWorkFinished()){ Rectangle2D.Double pieChartArea = new Rectangle2D.Double(0,getHeight()-PIE_CHART_HEIGHT,PIE_CHART_WIDTH,PIE_C HART_HEIGHT); if(viewPath && paths!=null){ NavizNode thisNode; g.setFont(new Font(applet.getNodeFontname(),Font.PLAIN,getFontSize(g))); fm = g.getFontMetrics(); for(Enumeration e=nodes.elements();e.hasMoreElements();){ thisNode = (NavizNode)e.nextElement(); Rectangle2D bound = fm.getStringBounds(thisNode.getComment(),g);

A77

Appendix Helper Classes


if(inPath(thisNode.getName())){ g.setColor(Color.getHSBColor((float)applet.normalizePathLineColor(((Dou ble)((Vector)paths.elementAt(pathNo)).elementAt(applet.getPathColorByRo w()+1)).doubleValue(),applet.getPathColorByRow()),(float)1.0,(float)0.9 5)); g.drawOval((int)(thisNode.getX()-thisNode.getW()/2),(int)(thisNode.getY ()-thisNode.getH()/2),(int)(thisNode.getW()),(int)(thisNode.getH())); g.setColor(g.getColor().darker()); g.drawString(thisNode.getComment(),(int)(thisNode.getX()-bound.getWidth ()/2),(int)(thisNode.getY()+bound.getHeight()/4)); }else{ g.setColor(Color.lightGray); // g.setColor(Color.black); g.drawOval((int)(thisNode.getX()-thisNode.getW()/2),(int)(thisNode.getY ()-thisNode.getH()/2),(int)(thisNode.getW()),(int)(thisNode.getH())); g.drawString(thisNode.getComment(),(int)(thisNode.getX()-bound.getWidth ()/2),(int)(thisNode.getY()+bound.getHeight()/4)); } if(thisNode.getName().equals((String)((Vector)paths.elementAt(pathNo)). elementAt(NavizPathServlet.PATH_NODE_ROW)) || thisNode.getName().equals((String)((Vector)paths.elementAt(pathNo)).las tElement())){ // g.setColor(Color.black); g.setColor(Color.getHSBColor((float)applet.normalizePathLineColor(((Dou ble)((Vector)paths.elementAt(pathNo)).elementAt(applet.getPathColorByRo w()+1)).doubleValue(),applet.getPathColorByRow()),(float)1.0,(float)0.9 5).darker()); g.drawOval((int)(thisNode.getX()-thisNode.getW()/2-3),(int)(thisNode.ge tY()-thisNode.getH()/2-3),(int)(thisNode.getW()+6),(int)(thisNode.getH( )+6)); } if(selectedNode==null?false:thisNode.getName().equals(selectedNode)){ g.setColor(Color.yellow); g.drawOval((int)(thisNode.getX()-thisNode.getW()/2),(int)(thisNode.getY ()-thisNode.getH()/2),(int)(thisNode.getW()),(int)(thisNode.getH())); g.drawString(thisNode.getComment(),(int)(thisNode.getX()-bound.getWidth ()/2),(int)(thisNode.getY()+bound.getHeight()/4)); } } if(applet.pathNodes!=null) for(int j=0; j<applet.pathNodes.size(); j++){ thisNode = (NavizNode)nodes.get((String)applet.pathNodes.elementAt(j)); Rectangle2D bound = fm.getStringBounds(thisNode.getComment(),g); g.setColor(Color.blue); g.drawOval((int)(thisNode.getX()-thisNode.getW()/2),(int)(thisNode.getY ()-thisNode.getH()/2),(int)(thisNode.getW()),(int)(thisNode.getH())); g.drawString(thisNode.getComment(),(int)(thisNode.getX()-bound.getWidth ()/2),(int)(thisNode.getY()+bound.getHeight()/4)); } if(applet.avoidNodes!=null) for(int j=0; j<applet.avoidNodes.size(); j++){ thisNode = (NavizNode)nodes.get((String)applet.avoidNodes.elementAt(j)); Rectangle2D bound = fm.getStringBounds(thisNode.getComment(),g); g.setColor(Color.red); g.drawOval((int)(thisNode.getX()-thisNode.getW()/2),(int)(thisNode.getY ()-thisNode.getH()/2),(int)(thisNode.getW()),(int)(thisNode.getH())); g.drawString(thisNode.getComment(),(int)(thisNode.getX()-bound.getWidth ()/2),(int)(thisNode.getY()+bound.getHeight()/4)); } g.setColor(Color.lightGray); for(Enumeration e=edges.elements();e.hasMoreElements();){ NavizEdge thisEdge = (NavizEdge)e.nextElement(); g.draw(thisEdge.getPath()); g.fillPolygon(thisEdge.getArrowXPoints(),thisEdge.getArrowYPoints(),3); } // g.setColor(Color.black); g.setColor(Color.getHSBColor((float)applet.normalizePathLineColor(((Dou ble)((Vector)paths.elementAt(pathNo)).elementAt(applet.getPathColorByRo w()+1)).doubleValue(),applet.getPathColorByRow()),(float)1.0,(float)0.9 5));

A78

Appendix Helper Classes


//g.setStroke(new BasicStroke((float)(applet.normalizePathLineWidth(((Double)((Vector)pat hs.elementAt(pathNo)).elementAt(applet.getWidthByRow()+1)).doubleValue( ),applet.getWidthByRow())*LINE_WIDTH_RATIO))); String path = (String)((Vector)paths.elementAt(pathNo)).elementAt(NavizPathServlet.PA TH_NODE_ROW)+"->"; for(int i=0; i<((Vector)paths.elementAt(pathNo)).size()-NavizPathServlet.PATH_NODE_R OW-1; i++){ path += (String)((Vector)paths.elementAt(pathNo)).elementAt(NavizPathServlet.PA TH_NODE_ROW+i+1)+"->"; NavizEdge edge = (NavizEdge)edges.get((String)((Vector)paths.elementAt(pathNo)).elementA t(NavizPathServlet.PATH_NODE_ROW+i)+"->"+(String)((Vector)paths.element At(pathNo)).elementAt(NavizPathServlet.PATH_NODE_ROW+i+1)); if(edge!=null){ g.setStroke(new BasicStroke((float)(applet.normalizeLineWidth(applet.getWidthByRow()==N avizServlet.EDGE_SUPPORT_ROW?edge.getSup():edge.getConf(),applet.getWid thByRow())*LINE_WIDTH_RATIO))); g.draw(edge.getPath()); g.fillPolygon(edge.getArrowXPoints(),edge.getArrowYPoints(),3); } } path = path.substring(0,path.length()-2); g.setFont(new Font(applet.getNodeFontname(),Font.PLAIN,10)); g.setColor(Color.black); g.setStroke(new BasicStroke()); String footer = (String)((Vector)paths.elementAt(pathNo)).elementAt(NavizPathServlet.PA TH_NODE_ROW)+"-->"+(String)((Vector)paths.elementAt(pathNo)).lastElemen t()+": "+pathNo; footer += " Length: "+(((Vector)paths.elementAt(pathNo)).size()-NavizPathServlet.PATH_NODE_ ROW); footer += " Support: "+((Double)((Vector)paths.elementAt(pathNo)).elementAt(NavizPathServlet .PATH_SUPPORT_ROW)).toString(); footer += " Confidence: "+((Double)((Vector)paths.elementAt(pathNo)).elementAt(NavizPathServlet .PATH_CONFIDENCE_ROW)).toString(); g.drawString(footer,LEFT_MARGIN,getHeight()-17); footer = "Cond: "+(applet.pathNodes.size()==0?applet.permanentPathNodes.toString():appl et.pathNodes.toString()); footer += "!"+(applet.avoidNodes.size()==0?applet.permanentAvoidNodes.toString(): applet.avoidNodes.toString())+","+(applet.pathType==NavizApplet.OPEN_CL OSED?"<|":applet.pathType==NavizApplet.CLOSED_OPEN?"|>":applet.pathType ==NavizApplet.OPEN_OPEN?"<>":"||"); footer += " Path: "+path+message; g.drawString(footer,LEFT_MARGIN,getHeight()-5); Double[][] data = new Double[1][1]; String[] names = new String[1]; names[0] = "sup"; data[0][0] = (Double)((Vector)paths.elementAt(pathNo)).elementAt(NavizPathServlet.PA TH_SUPPORT_ROW); supDataset = new DefaultCategoryDataset(names,data); VerticalNumberAxis rangeAxis = new VerticalNumberAxis(); HorizontalCategoryAxis domainAxis = new HorizontalCategoryAxis(); VerticalBarRenderer renderer = new VerticalBarRenderer(); rangeAxis.setLowerMargin(0.0); rangeAxis.setUpperMargin(100.0); supPlot = new VerticalCategoryPlot(supDataset,domainAxis,rangeAxis,renderer); Rectangle2D.Double supChartArea = new Rectangle2D.Double(PIE_CHART_WIDTH+5,getHeight()-SUP_CHART_HEIGHT,SUP_C HART_WIDTH,SUP_CHART_HEIGHT); DrawInfoGraph(g,pieChartArea,supChartArea,null); }else{ g.setFont(new Font(applet.getNodeFontname(),Font.PLAIN,getFontSize(g))); fm = g.getFontMetrics(); NavizNode node = null; for(Enumeration e=nodes.elements();e.hasMoreElements();){ NavizNode thisNode = (NavizNode)e.nextElement(); if(selectedNode==null?false:thisNode.getName().equals(selectedNode)){ node = thisNode; g.setColor(Color.red); }else g.setColor(Color.black); Rectangle2D bound = fm.getStringBounds(thisNode.getComment(),g); g.drawOval((int)(thisNode.getX()-thisNode.getW()/2),(int)(thisNode.getY ()-thisNode.getH()/2),(int)(thisNode.getW()),(int)(thisNode.getH()));

A79

Appendix Helper Classes


"+selectedEdge.getEnd(); footer += " Support: "+selectedEdge.getSup(); footer += " Confidence: "+selectedEdge.getConf(); g.drawString(footer,LEFT_MARGIN,getHeight()-5); Double[][] data = new Double[1][1]; data[0][0] = new Double(selectedEdge.getSup()); String[] names = new String[1]; names[0] = "sup"; supDataset = new DefaultCategoryDataset(names,data); VerticalNumberAxis rangeAxis = new VerticalNumberAxis(); HorizontalCategoryAxis domainAxis = new HorizontalCategoryAxis(); VerticalBarRenderer renderer = new VerticalBarRenderer(); rangeAxis.setLowerMargin(0.0); rangeAxis.setUpperMargin(100.0); supPlot = new VerticalCategoryPlot(supDataset,domainAxis,rangeAxis,renderer); supChartArea = new Rectangle2D.Double(PIE_CHART_WIDTH+5,getHeight()-SUP_CHART_HEIGHT,SUP_C HART_WIDTH,SUP_CHART_HEIGHT); data[0][0] = new Double(selectedEdge.getConf()); names[0] = "conf"; confDataset = new DefaultCategoryDataset(names,data); confPlot = new VerticalCategoryPlot(confDataset,domainAxis,rangeAxis,renderer); confChartArea = new Rectangle2D.Double(PIE_CHART_WIDTH+SUP_CHART_WIDTH+10,getHeight()-CONF_ CHART_HEIGHT,CONF_CHART_WIDTH,CONF_CHART_HEIGHT); } g.setColor(Color.black); g.drawString(message,LEFT_MARGIN,getHeight()-17); DrawInfoGraph(g,pieChartArea,supChartArea,confChartArea); } }else{ g.drawString(message,LEFT_MARGIN,20); g.setFont(new Font(applet.getNodeFontname(),Font.BOLD,18)); fm = g.getFontMetrics(); Rectangle2D bound = fm.getStringBounds("Now loading data. Please wait...",g); g.drawString("Now loading data. Please wait...",(int)(getWidth()/2-bound.getWidth()/2),(int)(getHeight()/2-bou nd.getHeight()/4)); } } private void DrawInfoGraph(Graphics2D g, Rectangle2D pieChartArea, Rectangle2D supChartArea, Rectangle2D confChartArea){

g.drawString(thisNode.getComment(),(int)(thisNode.getX()-bound.getWidth ()/2),(int)(thisNode.getY()+bound.getHeight()/4)); } for(Enumeration e=edges.elements();e.hasMoreElements();){ NavizEdge thisEdge = (NavizEdge)e.nextElement(); g.setColor(Color.getHSBColor((float)applet.normalizeLineColor(applet.ge tColorByRow()==NavizServlet.EDGE_SUPPORT_ROW?thisEdge.getSup():thisEdge .getConf(),applet.getColorByRow()),(float)1.0,(float)0.95)); g.setStroke(new BasicStroke((float)(applet.normalizeLineWidth(applet.getWidthByRow()==N avizServlet.EDGE_SUPPORT_ROW?thisEdge.getSup():thisEdge.getConf(),apple t.getWidthByRow())*LINE_WIDTH_RATIO))); g.draw(thisEdge.getPath()); g.fillPolygon(thisEdge.getArrowXPoints(),thisEdge.getArrowYPoints(),3); } g.setFont(new Font(applet.getNodeFontname(),Font.PLAIN,10)); String footer; Rectangle2D.Double supChartArea = null; Rectangle2D.Double confChartArea = null; if(node!=null){ g.setColor(Color.black); g.setStroke(new BasicStroke()); footer = "Node: "+node.getName(); footer += " Label: "+node.getComment(); footer += " URL: "+node.getUrl(); g.drawString(footer,LEFT_MARGIN,getHeight()-5); }else if(selectedEdge!=null){ g.setColor(Color.getHSBColor((float)applet.normalizeLineColor(applet.ge tColorByRow()==NavizServlet.EDGE_SUPPORT_ROW?selectedEdge.getSup():sele ctedEdge.getConf(),applet.getColorByRow()),(float)1.0,(float)0.95).brig hter()); g.setStroke(new BasicStroke((float)(applet.normalizeLineWidth(applet.getWidthByRow()==N avizServlet.EDGE_SUPPORT_ROW?selectedEdge.getSup():selectedEdge.getConf (),applet.getWidthByRow())*LINE_WIDTH_RATIO))); g.draw(selectedEdge.getPath()); g.fillPolygon(selectedEdge.getArrowXPoints(),selectedEdge.getArrowYPoin ts(),3); g.setColor(Color.black); g.setStroke(new BasicStroke()); footer = "Edge: "+selectedEdge.getStart()+" -->

A80

Appendix Helper Classes


piePlot.draw(g,pieChartArea,null); if(supChartArea!=null) supPlot.draw(g,supChartArea,null); if(confChartArea!=null) confPlot.draw(g,confChartArea,null); } public String selectNode(double x, double y){ String id = null; if(nodes!=null) for(Enumeration e=nodes.elements();e.hasMoreElements();){ NavizNode thisNode = (NavizNode)e.nextElement(); Ellipse2D.Double ellips = new Ellipse2D.Double((double)(thisNode.getX()-thisNode.getW()/2),(double)(t hisNode.getY()-thisNode.getH()/2),(double)thisNode.getW(),(double)thisN ode.getH()); if(ellips.contains(x,y)){ id = thisNode.getName(); break; } } return id; } public NavizEdge selectEdge(double x, double y){ NavizEdge edge = null; if(edges!=null) for(Enumeration e=edges.elements();e.hasMoreElements();){ NavizEdge thisEdge = (NavizEdge)e.nextElement(); if(thisEdge.getPath()==null?false:intersects(thisEdge.getPath().getPath Iterator(null),x,y,1.0,1.0)){ edge = thisEdge; break; } } return edge; } private boolean intersects(PathIterator path,double x,double y, double h, double w){ boolean doIntersects = false; CubicCurve2D.Double cubic = new CubicCurve2D.Double(); QuadCurve2D.Double quad = new QuadCurve2D.Double(); Line2D.Double line = new Line2D.Double(); int t = -1; double[] coords = new double[6]; path.currentSegment(coords); Point2D p = new Point2D.Double(coords[0],coords[1]); path.next(); while(!path.isDone()){ t = path.currentSegment(coords); if(t==path.SEG_CUBICTO){ cubic.setCurve(p.getX(),p.getY(),coords[0],coords[1],coords[2],coords[3 ],coords[4],coords[5]); if(doIntersects = cubic.intersects(x,y,h,w)) break; p.setLocation(coords[4],coords[5]); }else if(t==path.SEG_QUADTO){ quad.setCurve(p.getX(),p.getY(),coords[0],coords[1],coords[2],coords[3] ); if(doIntersects = quad.intersects(x,y,h,w)) break; p.setLocation(coords[2],coords[3]); }else if(t==path.SEG_LINETO){ line.setLine(p.getX(),p.getY(),coords[0],coords[1]); if(doIntersects = line.intersects(x,y,h,w)) break; p.setLocation(coords[0],coords[1]); } path.next(); } return doIntersects; } private boolean inPath(String id){ boolean inpath = false; for(int i=0; i<((Vector)paths.elementAt(pathNo)).size()-NavizPathServlet.PATH_NODE_R OW; i++){ if(id.equals((String)((Vector)paths.elementAt(pathNo)).elementAt(NavizP athServlet.PATH_NODE_ROW+i))){ inpath = true; break; } } return inpath; } public void itemStateChanged(ItemEvent itemEvent){ } public void actionPerformed(ActionEvent actionEvent){ if(actionEvent.getActionCommand().equals("Property")){ if(selectedNode!=null){ NavizNode node = (NavizNode)nodes.get(selectedNode); try{ String url =

A81

Appendix Helper Classes


applet.buildUrl(applet.getPropertyPage()+"?propttl=Node Property&prop1nam=ID&prop1val="+node.getName()+"&prop2nam=Label&prop2va l="+node.getComment()+"&prop3nam=URL&prop3val=<A HREF=""+applet.buildUrl(node.getUrl())+"">"+applet.buildUrl(node.getU rl())+"</A>"); String name = "nodeproperty"; String features = "resizable,width=400,height=200"; String eval = name+" = window.open('"+url+"','"+name+"','"+features+"');"; eval += name+".focus();"; applet.jsobjectWin.eval(eval); }catch(Exception e){ System.err.println("nNavizCanvas.actionPerformed error: "+e.toString()); } }else if(selectedEdge!=null){ try{ String url = applet.buildUrl(applet.getPropertyPage()+"?propttl=Edge Property&prop1nam=ID&prop1val="+selectedEdge.getStart()+" --> "+selectedEdge.getEnd()+"&prop2nam=Label&prop2val="+((NavizNode)nodes.g et(selectedEdge.getStart())).getComment()+" --> "+((NavizNode)nodes.get(selectedEdge.getEnd())).getComment()+"&prop3nam =Support&prop3val="+selectedEdge.getSup()+"&prop4nam=Confidence&prop4va l="+selectedEdge.getConf()); String name = "edgeproperty"; String features = "resizable,width=400,height=200"; String eval = name+" = window.open('"+url+"','"+name+"','"+features+"');"; eval += name+".focus();"; applet.jsobjectWin.eval(eval); }catch(Exception e){ System.err.println("nNavizCanvas.actionPerformed error: "+e.toString()); } } }else if(actionEvent.getActionCommand().equals("Open URL")){ if(selectedNode!=null){ applet.diagramClicked(); } }else if(actionEvent.getActionCommand().equals("Select")){ if(selectedNode!=null){ applet.pathNodeSelected(); } }else if(actionEvent.getActionCommand().equals("Avoid")){ if(selectedNode!=null){ applet.pathNodeAvoided(); } }else if(actionEvent.getActionCommand().equals("Clear")){ if(selectedNode!=null){ applet.pathNodeCleared(selectedNode); } } } }

A3.2 Class of Thread Parallelization


Thread parallelization is needed since access to the servlet generally consume long time. It is implemented into three connections, i.e. connectToServlet that connect to NavizServlet to request graph layout, connectToPathServlet that connect to NavizPathServlet to request paths data, and

connectToAttributeServlet that connect to NavizAttributeServlet to request properties data needed in behavior comparison. The class SwingWorker used to implement thread parallelization is the default way of this job in the Java Swing environment.
package naviz; import javax.swing.SwingUtilities; /** * This is the 3rd version of SwingWorker (also known as * SwingWorker 3), an abstract class that you subclass to * perform GUI-related work in a dedicated thread. For * instructions on using this class, see: * * http://java.sun.com/docs/books/tutorial/uiswing/misc/threads.html * * Note that the API changed slightly in the 3rd version: * You must now invoke start() on the SwingWorker after

A82

Appendix Helper Classes


* creating it. */ public abstract class SwingWorker { private Object value; // see getValue(), setValue() private Thread thread; /** * Class to maintain reference to current worker thread * under separate synchronization control. */ private static class ThreadVar { private Thread thread; ThreadVar(Thread t) { thread = t; } synchronized Thread get() { return thread; } synchronized void clear() { thread = null; } } private ThreadVar threadVar; /** * Get the value produced by the worker thread, or null if it * hasn't been constructed yet. */ protected synchronized Object getValue() { return value; } /** * Set the value produced by worker thread */ private synchronized void setValue(Object x) { value = x; } /** * Compute the value to be returned by the <code>get</code> method. */ public abstract Object construct(); /** * Called on the event dispatching thread (not on the worker thread) * after the <code>construct</code> method has returned. */ public void finished() { } /** * A new method that interrupts the worker thread. Call this method * to force the worker to stop what it's doing. */ public void interrupt() { Thread t = threadVar.get(); if (t != null) { t.interrupt(); } threadVar.clear(); } /** * Return the value created by the <code>construct</code> method. * Returns null if either the constructing thread or the current * thread was interrupted before a value was produced. * * @return the value created by the <code>construct</code> method */ public Object get() { while (true) { Thread t = threadVar.get(); if (t == null) { return getValue(); } try { t.join(); } catch (InterruptedException e) { Thread.currentThread().interrupt(); // propagate return null; } } }

/** * Start a thread that will call the <code>construct</code> method * and then exit. */ public SwingWorker() { final Runnable doFinished = new Runnable() { public void run() { finished(); } }; Runnable doConstruct = new Runnable() {

A83

Appendix Helper Classes


public void run() { try { setValue(construct()); } finally { threadVar.clear(); } SwingUtilities.invokeLater(doFinished); } }; Thread t = new Thread(doConstruct); threadVar = new ThreadVar(t); } /** * Start the worker thread. */ public void start() { Thread t = threadVar.get(); if (t != null) { t.start(); } } } import java.util.*; import java.applet.Applet; /* Copyright Notice Web Techniques grants permission to use this source code for private or commercial use provided that credit to Web Techniques and the author is clearly expressed within the comments of the source code. All source code is provided as-is, and should be utilized at your own risk. For questions, contact editors@webtechniques.com. */ /** * * @author praz * @version */ public class MessageRelayer { private static Hashtable Apps = null; // Stores Applet references. private static boolean firstCall = false; private static int maxAppletNum = 0; private static boolean attributeRead = false; private static NavizAttributeRequest attributeRequestPacket; // object to send to attribute servlet private static NavizAttributeResponse attributeResponsePacket; // object to receive from attribute servlet private MessageRelayer(){} // Ensures class can't be instantiated. public static synchronized boolean isAttributeRead(){ * Created on 2001/12/11, 20:42 MessageRelayer maintains all the applet references. You can either use the getApplet() method to post directly to the and applet or use the postCommand() method to post through the MessageRelayer. */ package naviz;

A3.3 Classes of Applet Communication


Since NavizApplet performs many behavior comparisons using more than one applet, it needs to have the ability to communicate with another applets in the client environment. Below is the class MessageRelayer and interface AppletCommunicator from Web Techniques (http://www.webtechniques.com) that is used to implement this ability.
/* * MessageRelayer.java *

A84

Appendix Helper Classes


return attributeRead; } public static synchronized NavizAttributeRequest getAttributeRequestPacket(){ return attributeRequestPacket; } public static synchronized NavizAttributeResponse getAttributeResponsePacket(){ return attributeResponsePacket; } public static synchronized void setAttributeRead(boolean b){ attributeRead = b; } public static synchronized void setAttributeRequestPacket(NavizAttributeRequest request){ attributeRequestPacket = request; } public static synchronized void setAttributeResponsePacket(NavizAttributeResponse response){ attributeResponsePacket = response; } public static synchronized void addApplet(Applet remote_applet){ if(Apps == null){ // Has a hashtable been created. Apps = new Hashtable(); } Apps.put(remote_applet.getName(), remote_applet); } public static synchronized void removeApplet(Applet remote_applet){ if(Apps != null){ // Hashtable must have been created first. Apps.remove(remote_applet.getName()); } if(Apps.size() == 0){ Apps = null; // Dereference if not in use. } } public static synchronized String[] getAppletNames(){ Enumeration keys = Apps.keys(); Vector names = new Vector(); for(int i=0; keys.hasMoreElements(); i++){ names.addElement(keys.nextElement()); } String[] applet_names = new String[names.size()]; for(int i=0; i < names.size(); i++){ applet_names[i] = (String) names.elementAt(i); } return(applet_names); } public static synchronized Applet getApplet(String applet_name){ Applet remote_applet = (Applet) Apps.get(applet_name); if(verifyAppletRef(remote_applet)){ return(remote_applet); }else{ return(null); } } public static void postCommand(String applet_name, Object command){ AppletCommunicator remote_applet = (AppletCommunicator)getApplet(applet_name); remote_applet.postCommand(command); } private static boolean verifyAppletRef(Applet remote_applet){ boolean valid = false; if(remote_applet.isActive()){ return(true); }else{ removeApplet(remote_applet); return(false); } } public static boolean isFirstCall(){ return firstCall; } public static void setFirstCall(boolean fc){ firstCall = fc; } public static int getMaxAppletNum(){ return maxAppletNum; } public static void setMaxAppletNum(int appletNum){ if(maxAppletNum<appletNum) maxAppletNum = appletNum; } } /* * AppletCommunicator.java * * Created on 2001/12/11, 21:07 */ package naviz;

A85

Appendix Helper Classes


* * @author praz * @version */ public interface AppletCommunicator{ // defines method to send a command to another // AppletCommunicator. public void postCommand(Object command); // defines method which adds AppletCommunicators with // which the Applet can communicate. public void addApplet(AppletCommunicator remote_applet); // defines method which removes AppletCommunicators as // they are removed from the browser. public void removeApplet(AppletCommunicator remote_applet); }

/* Copyright Notice Web Techniques grants permission to use this source code for private or commercial use provided that credit to Web Techniques and the author is clearly expressed within the comments of the source code. All source code is provided as-is, and should be utilized at your own risk. For questions, contact editors@webtechniques.com. */ /**

NavizNode
NavizNode contains all sufficient information about the node such as name (unique to identify each node), comment (can be shown as node title), url (url

A4 Data Type Classes

representated by the node), location (x, y) and size (w, h).


/* * NavizNode.java * * Created on 2001/07/13, 18:31 */ package naviz; import java.io.Serializable;

A4.1 Types of Node and Edge Data


There are two main data types that is used bay Naviz, i.e. NavizNode to store data of each node, and NavizEdge to store data of each edge. In addition, there are three data types, NavizRequest, NavizPathRequest, and

NavizAttributeRequest, that are used to send request from applet to servlet, and three of its counterpart, NavizResponse, NavizPathResponse, and

NavizAttributeResponse, that are used to send response from servlet to applet.

/** * * @author Bowo Prasetyo * @version */ public class NavizNode extends Object implements Serializable {

A86

Appendix Data Type Classes


private private private private private private private int x; int y; int h; int w; String name; String comment; String url; } public void setUrl(String url) { this.url = url; } /** Creates new NavizNode */ public NavizNode() { } public NavizNode(String name, String comment, String url, int x, int y, int w, int h) { this.name = name; this.comment = comment; this.url = url; this.x = x; this.y = y; this.w = w; this.h = h; } }

public int getX() { return x; } public void setX(int x){ this.x = x; } public int getY() { return y; } public void setY(int y){ this.y = y; } public int getH() { return h; } public void setH(int h){ this.h = h; } public int getW() { return w; } public void setW(int w){ this.w = w; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getComment() { return comment; } public void setComment(String comment) { this.comment = comment; } public String getUrl() { return url;

NavizEdge
NavizEdge contains all sufficient information about the edge such as start_node + end_node (unique to identify each edge), sup (can be visualized as edges width), conf (can be visualized as edges color), number of Bezier points needed to spline the edge, and their location (x, y).
/* * NavizEdge.java * * Created on 2001/07/13, 18:33 */ package naviz; import java.io.Serializable; import java.awt.geom.GeneralPath; import java.awt.Point; /**

A87

Appendix Data Type Classes


* * @author Bowo Prasetyo * @version */ public class NavizEdge extends Object implements Serializable { private static final double ARROW_LENGTH = 0.5; private static final double ARROW_WIDTH = 0.25; private private private private private private private private private private private int pointNum; int labelX; int labelY; double width; double sup; double conf; int direction; String start; String end; String label; GeneralPath path; // pixels return width; } public void setWidth(double width){ this.width = width; double arrowLength = 5+ARROW_LENGTH*width; double arrowWidth = 2+ARROW_WIDTH*width; if(direction==-1){ double x = xPoints[0]-xPoints[1]; double y = yPoints[0]-yPoints[1]; double a = Math.sqrt(x*x+y*y); if(a==0){ arrowXPoints[0] = xPoints[0]; arrowYPoints[0] = yPoints[0]; }else{ arrowXPoints[0] = (int)(xPoints[0] + arrowLength*x/a); arrowYPoints[0] = (int)(yPoints[0] + arrowLength*y/a); } if(y==0){ arrowXPoints[1] = xPoints[0]; arrowYPoints[1] = yPoints[0] - (int)(arrowWidth); arrowXPoints[2] = xPoints[0]; arrowYPoints[2] = yPoints[0] + (int)(arrowWidth); }else{ double b = x/y; arrowXPoints[1] = (int)(xPoints[0] + arrowWidth/Math.sqrt(1+b*b)); arrowYPoints[1] = (int)(yPoints[0] b*arrowWidth/Math.sqrt(1+b*b)); arrowXPoints[2] = (int)(xPoints[0] arrowWidth/Math.sqrt(1+b*b)); arrowYPoints[2] = (int)(yPoints[0] + b*arrowWidth/Math.sqrt(1+b*b)); } }else{ int i = pointNum-1; double x = xPoints[i]-xPoints[i-1]; double y = yPoints[i]-yPoints[i-1]; double a = Math.sqrt(x*x+y*y); if(a==0){ arrowXPoints[0] = xPoints[i]; arrowYPoints[0] = yPoints[i]; }else{ arrowXPoints[0] = (int)(xPoints[i] + arrowLength*x/a); arrowYPoints[0] = (int)(yPoints[i] + arrowLength*y/a); } if(y==0){

public String getHashKey(){ return start+"->"+end; } public int getPointNum() { return pointNum; } public void setPointNum(int pointNum){ this.pointNum = pointNum; xPoints = new int[pointNum]; yPoints = new int[pointNum]; points = new Point[pointNum]; } public int getLabelX() { return labelX; } public void setLabelX(int labelX){ this.labelX = labelX; } public int getLabelY() { return labelY; } public void setLabelY(int labelY){ this.labelY = labelY; } public double getWidth() {

A88

Appendix Data Type Classes


arrowXPoints[1] = xPoints[i]; arrowYPoints[1] = yPoints[i] - (int)(arrowWidth); arrowXPoints[2] = xPoints[i]; arrowYPoints[2] = yPoints[i] + (int)(arrowWidth); }else{ double b = x/y; arrowXPoints[1] = (int)(xPoints[i] + arrowWidth/Math.sqrt(1+b*b)); arrowYPoints[1] = (int)(yPoints[i] b*arrowWidth/Math.sqrt(1+b*b)); arrowXPoints[2] = (int)(xPoints[i] arrowWidth/Math.sqrt(1+b*b)); arrowYPoints[2] = (int)(yPoints[i] + b*arrowWidth/Math.sqrt(1+b*b)); } } } public double getSup() { return sup; } public void setSup(double sup){ this.sup = sup; } public double getConf() { return conf; } public void setConf(double conf){ this.conf = conf; } public int getDirection() { return direction; } public void setDirection(int direction) { this.direction = direction; } public String getStart() { return start; } public void setStart(String start) { this.start = start; } public String getEnd() { return end; } public void setEnd(String end) { this.end = end; } public String getLabel() { return label; } public void setLabel(String label) { this.label = label; } public GeneralPath getPath() { return path; } public void setPath(GeneralPath path) { this.path = path; } // property that has index private int[] xPoints; private int[] yPoints; private int[] arrowXPoints; private int[] arrowYPoints; private Point[] points; public Point getPoints(int index) { return points[index]; } public Point[] getPoints() { return points; } public void setPoints(int index,Point points) { this.points[index] = points; } public void setPoints(Point[] points) { this.points = points; } public int[] getArrowXPoints() { return arrowXPoints; } public int[] getXPoints() { return xPoints; } public int[] getArrowYPoints() { return arrowYPoints; } public int[] getYPoints() { return yPoints; } public int getXPoints(int i) {

A89

Appendix Data Type Classes


return xPoints[i]; } public void setXPoints(int xPoints, int i){ this.xPoints[i] = xPoints; } public int getYPoints(int i) { return yPoints[i]; } public void setYPoints(int yPoints, int i){ this.yPoints[i] = yPoints; points[i] = new Point(xPoints[i],yPoints); } /** Creates new NavizEdge */ public NavizEdge() { direction = 1; arrowXPoints = new int[3]; arrowYPoints = new int[3]; } } */ package naviz; import java.io.Serializable; /** * * @author praz * @version */ public class NavizRequest extends Object implements Serializable { public public public public public public public public public public public public public public public public public public public public String website; int fromHour; int toHour; int place; int category; double minLineWidth; double maxLineWidth; double minsup; double maxsup; double minconf; double maxconf; double layoutMinsup; double layoutMaxsup; double layoutMinconf; double layoutMaxconf; double maxHue; int orderByRow; int weightByRow; int widthByRow; int colorByRow;

A4.2 Types of Request and Response of Servlets


In addition, there are three data types, NavizRequest, NavizPathRequest, and NavizAttributeRequest, that are used to send request from applet to servlet, and three of its counterpart, NavizResponse, NavizPathResponse, and

NavizAttributeResponse, that are used to send response from servlet to applet.

Request and Response of NavizServlet


Naviz Request
/* * NavizRequest.java * * Created on 2001/09/13, 10:37

public boolean dotCenter; // centers drawing on page: true, false public boolean dotConcentrate; // enable edges concentrators: true, false public int dotFontsize; // point size of label: in points public double dotXMargin; public double dotYMargin; // margin included in page: public int dotMclimit; // adjust mincross iterations: f times public double dotNodesep; // separation between nodes, in inches public int dotNslimit; // bounds network simplex iterations by f (num of nodes) //public double dotXPage; //public double dotYPage; // unit of pagination: in inches

A90

Appendix Data Type Classes


public double dotRanksep; // separation between ranks, in inches public double dotRotate; // rotation: in degree public double dotXSize; public double dotYSize; // graph size: in inches public String dotClusterrank; // rank of cluster: local, global, none public String dotColor; // background or cluster outline color: "hue saturation brightness", colorname public String dotFontcolor; // type face color: colorname public String dotFontname; // PostScript font family: fontname public String dotLabel; // graph label: any string public boolean dotOrdering; // for ordered edges: out public String dotOrientation; // orientation: portrait, landscape public String dotRank; // rank: same, min, max public String dotRankdir; // rank direction: LR: left-right or TB: top-bottom public String dotRatio; // ratio: auto, compress, fill, x/y ratio public public public public public public public ranks public public public public int nodeFontsize; String nodeColor; String nodeFontcolor; String nodeFontname; String nodeShape; // in points

import java.io.Serializable; import java.util.Hashtable; /** * * @author praz * @version */ public class NavizResponse extends Object implements Serializable { public public public public public public public public public public Hashtable nodes; Hashtable edges; double scaleFactor; double dataMinsup; double dataMaxsup; double dataMinconf; double dataMaxconf; double height; double width; int sessionNum;

int edgeFontsize; int edgeMinlen; // minimum distance between start and end: in String String String String edgeColor; edgeFontcolor; edgeFontname; edgeDir; // edge direction: forward, back, both, none

/** Creates new NavizResponse */ public NavizResponse() { nodes = new Hashtable(NavizServlet.EDGE_INITIAL_CAPACITY); edges = new Hashtable(NavizServlet.EDGE_INITIAL_CAPACITY); dataMinsup = 100.0; dataMaxsup = 0.0; dataMinconf = 100.0; dataMaxconf = 0.0; } public Object clone(){ NavizResponse res = new NavizResponse(); res.nodes = (Hashtable)nodes.clone(); res.edges = (Hashtable)edges.clone(); res.scaleFactor = scaleFactor; res.dataMinsup = dataMinsup; res.dataMaxsup = dataMaxsup; res.dataMinconf = dataMinconf; res.dataMaxconf = dataMaxconf; res.height = height; res.width = width; return res; } }

/** Creates new NavizRequest */ public NavizRequest() { } }

Naviz Response
/* * NavizResponse.java * * Created on 2001/09/13, 10:42 */ package naviz;

A91

Appendix Data Type Classes


package naviz;

Request and Response of NavizPathServlet


Naviz Path Request
/* * NavizPathRequest.java * * Created on 2001/09/21, 16:10 */ package naviz; import java.io.Serializable; import java.util.Vector; /** * * @author praz * @version */ public class NavizPathRequest extends Object implements Serializable { public public public public public public String website; int fromHour; int toHour; int place; int category; Vector pathNodes;

import java.io.Serializable; import java.util.Vector; /** * * @author praz * @version */ public class NavizPathResponse extends Object implements Serializable { public public public public public Vector double double double double paths; pathMinsup; pathMaxsup; pathMinconf; pathMaxconf;

/** Creates new NavizPathResponse */ public NavizPathResponse() { paths = new Vector(NavizPathServlet.PATH_INITIAL_CAPACITY,NavizPathServlet.PATH_CAP ACITY_INCREMENT); pathMinsup = 100.0; pathMaxsup = 0.0; pathMinconf = 100.0; pathMaxconf = 0.0; } public Object clone(){ NavizPathResponse res = new NavizPathResponse(); res.paths = (Vector)paths.clone(); res.pathMinsup = pathMinsup; res.pathMaxsup = pathMaxsup; res.pathMinconf = pathMinconf; res.pathMaxconf = pathMaxconf; return res; } }

/** Creates new NavizPathRequest */ public NavizPathRequest() { } }

Naviz Path Response


/* * NavizPathResponse.java * * Created on 2001/09/21, 16:13 */

Request and Response of NavizAttributeServlet


Naviz Attribute Request

A92

Appendix Data Type Classes


/* * NavizAttributeRequest.java * * Created on 2001/09/21, 16:10 */ package naviz; import java.io.Serializable; /** * * @author praz * @version */ public class NavizAttributeRequest extends Object implements Serializable { /** Creates new NavizPathRequest */ public NavizAttributeRequest() { } } import java.util.Vector; /** * * @author praz * @version */ public class NavizAttributeResponse extends Object implements Serializable { public public public public int totalSessionNum; Vector places; Vector categories; Vector stations;

Naviz Attribute Response


/* * NavizAttributeResponse.java * * Created on 2001/09/21, 16:13 */ package naviz; import java.io.Serializable;

/** Creates new NavizPathResponse */ public NavizAttributeResponse() { totalSessionNum = 0; places = new Vector(NavizAttributeServlet.ATTRIBUTE_INITIAL_CAPACITY,NavizAttributeS ervlet.ATTRIBUTE_CAPACITY_INCREMENT); categories = new Vector(NavizAttributeServlet.ATTRIBUTE_INITIAL_CAPACITY,NavizAttributeS ervlet.ATTRIBUTE_CAPACITY_INCREMENT); stations = new Vector(NavizAttributeServlet.ATTRIBUTE_INITIAL_CAPACITY,NavizAttributeS ervlet.ATTRIBUTE_CAPACITY_INCREMENT); } }

A93

Appendix Server Side Applications

A5

Server Side Applications

A5.1

GraphViz
2.

`id` int(11) NOT NULL default '0', `name` char(32) NOT NULL default '', `comment` char(255) default NULL, `link` char(255) default NULL, PRIMARY KEY (`id`), KEY `e_name` (`name`) ) TYPE=MyISAM;

To draw the underlying graph layout which representing traversal diagram, Naviz utilizes a graph drawing tool called GraphViz [8], an open source graph drawing software from AT&T that implemented algorithm in [3] proposed by Gansner et. al. Naviz system assumes that GraphViz is installed and included in the PATH environment variable.

edge: to store edge information, such as start and end node, support, confidence, from_hour, to_hour, place, and category.
CREATE TABLE `edge` ( `start_node` int(11) NOT NULL default '0', `end_node` int(11) NOT NULL default '0', `support` double(16,4) NOT NULL default '0.0000', `confidence` double(16,4) NOT NULL default '0.0000', `from_hour` int(11) NOT NULL default '0', `to_hour` int(11) NOT NULL default '0', `place` int(11) NOT NULL default '0', `category` int(11) NOT NULL default '0', KEY `e_supconf` (`support`,`confidence`), KEY `e_fromto` (`from_hour`,`to_hour`), KEY `e_place` (`place`), KEY `e_category` (`category`) ) TYPE=MyISAM;

A5.2

Log Miner

Currently Naviz utilizes a separated log miner that using the GSP algorithm sequential pattern mining [1]. This Log Miner can mine edges and paths pattern from web log file of NTT Docomo Mobile Townpage, and store them in pattern repository described below. 3.

sequence: to store paths information such as id, support, confidence, place, category, from_hour, and to_hour.
CREATE TABLE `sequence` ( `id` int(11) NOT NULL auto_increment, `support` double(16,4) NOT NULL default '0.0000', `confidence` double(16,4) NOT NULL default '0.0000', `place` int(11) NOT NULL default '0', `category` int(11) NOT NULL default '0', `from_hour` int(11) NOT NULL default '0', `to_hour` int(11) NOT NULL default '0', PRIMARY KEY (`id`), KEY `e_category` (`category`), KEY `e_fromto` (`from_hour`,`to_hour`), KEY `e_supconf` (`support`,`confidence`), KEY `e_place` (`place`)

A5.3

Pattern Repository

Naviz uses MySQL Database as repository to store the discovered patterns. The tables used by Naviz are: 1. node: to store node data, such as id, name, comment, and link.
CREATE TABLE `node` (

A94

Appendix Server Side Applications


) TYPE=MyISAM;

4.

seq_body: to store path body information such as node and its order.
CREATE TABLE `seq_body` ( `sequence` int(11) NOT NULL default '-1', `order_num` int(11) default NULL, `node` int(11) default NULL, KEY `e_sequence` (`sequence`) ) TYPE=MyISAM;

5.

attributes: to store values of properties such as place and category that is used for behavior comparison.
CREATE TABLE `attributes` ( `item` int(10) unsigned NOT NULL default '0', `cnt` int(11) default NULL, `code` varchar(20) NOT NULL default '', `attrib` varchar(100) NOT NULL default '', PRIMARY KEY (`item`) ) TYPE=MyISAM;

A95

You might also like