Thursday, July 25, 2013

Expert System Shell in Agent-Based Modeling: Demo using Zombie Sim game

Have completed my expert system shell in Java and C#, so rewrote this simple Zombie Sim game (which is originally by http://wr3cktangle.wordpress.com/2008/05/29/zombie-sim-open-source/)  using agent-based modeling, in which instead of hand-coded C# rules, expert system is used for the agent (both human and zombie) decision making.


The demo video can be found at:
http://youtu.be/PWcW6ZuLLJE

The expert system shell support major features such as forward, backward chaining, etc. Below is the code snippet for the human agent expert shell code:

RuleInferenceEngine rie = new RuleInferenceEngine();

Rule rule = new Rule("Rule 1");
rule.AddAntecedent(new IsClause("IsTargetVisible", "yes"));
rule.AddAntecedent(new IsClause("IsTargetAvailable", "yes"));
rule.AddAntecedent(new IsClause("IsCourageous", "yes"));
rule.AddAntecedent(new IsClause("IsUnderAttack", "no"));
rule.setConsequent(new IsClause("Action", "PursuitTarget"));
rie.AddRule(rule);

rule = new Rule("Rule 2");
rule.AddAntecedent(new IsClause("IsUnderAttack", "yes"));
rule.AddAntecedent(new IsClause("IsTargetAvailable", "yes"));
rule.setConsequent(new IsClause("Action", "Attack"));
rie.AddRule(rule);

rule = new Rule("Rule 3");
rule.AddAntecedent(new IsClause("IsTargetAvailable", "yes"));
rule.AddAntecedent(new IsClause("IsCourageous", "no"));
rule.AddAntecedent(new IsClause("IsUnderAttack", "no"));
rule.setConsequent(new IsClause("Action", "RunawayFromTarget"));
rie.AddRule(rule);

rule = new Rule("Rule 4");
rule.AddAntecedent(new IsClause("IsTargetAvailable", "no"));
rule.AddAntecedent(new IsClause("IsFighting", "yes"));
rule.setConsequent(new IsClause("IsFighting", "no"));
rie.AddRule(rule);
Below is the partial code the invoke the expert system for decision making in the human agent
mExpertSystem.ClearFacts();

mExpertSystem.AddFact(new IsClause("IsUnderAttack", is_under_attack ? "yes" : "no"));
mExpertSystem.AddFact(new IsClause("IsTargetVisible", mTarget != null && closest < SpotDistance ? "yes" : "no"));
mExpertSystem.AddFact(new IsClause("IsTargetAvailable", mTarget != null ? "yes" : "no"));
mExpertSystem.AddFact(new IsClause("IsCourageous", mWorld.Random.Next(9) + 1 > mCourage ? "yes" : "no"));

List<clause> unproved_conditions = new List<clause>();

Clause conclusion = mExpertSystem.Infer("Action", unproved_conditions);

if (conclusion == null)
{
 System.Console.WriteLine(mExpertSystem.Facts.ToString());
 Console.WriteLine("/////////////////////////////////////");
 return;
}

if (conclusion.getValue() == "Attack")
{
 mFighting = true;
 mMode = MentalState.Aggressive;
 mTarget.IsAttacked((int)Math.Floor(mWorld.Random.NextDouble() * mStrength));
}
Below are some images showing the ZombieSim Game rewritten using Expert System Shell and Agent-Based Modeling:

Association Rule Learning: Job Posting Skill Set Learning and Employment Matching

Just completed an association rule learning application using job posted on websites as the data source, the current application can do the following:

1. Crawl data from job sites such as indeed, jobdb, etc.
2. Help answer: if you know a particular skill, what other skills you should possess to make you more employable in a particular region or country (e.g., Singapore)
3. Help answer: if you what a particular career, what skill sets you should learn or know to make you successful in employment in a particular region or country (e.g. Singapore)
4. Help answer: if you wish to join a particular company in a particular region or country (Singapore in the demo), what skill sets will increase your chance of being hired by that company
5. Help answer: if you has a particular skill, what companies in a particular region or country (e.g. Singapore) you can join
6. Help answer: if you are working in a particular region or country, what skill sets will make you highly employable here.

The demo video can be viewed at the following link:
http://youtu.be/G52pjiefI5c

Below is a some screenshots:
Crawl Job Sites

Job Post
Learned Skill Set Association

Learned Skill Set - Employment Matching

Association Rule Learning Applications



Sentiment Analysis: Singeat.com Comments Sentiment Analysis

Just completed a demo of sentiment analysis machine learning on comments posted on Singeat.com (新加坡美食网), the comments are in chinese, the sentiment analysis is done to be able to output for multiple criteria such as:

Service (good, bad, neutral, etc)
Taste (good, bad, neutral, etc)
Surrounding (good, bad, neutral, etc)
Overral Rating (good, bad, neutral, etc)

The language is auto-detected (therefore not limited to chinese and english), default model is based on Naive Bayes Classifier and Decision Tree, SVM and neural network , transfer learning are under progress.

The demo video can be viewed at:

http://youtu.be/XRANZezqu24

Below are some screenshots:
Crawl Data

View Comments

Sentiment Analysis (Chinese)

Sentiment Analysis (Chinese)

Sentiment Analysis (English)

Sentiment Analysis (Japanese)


Monday, July 22, 2013

Return the filename from the full file path in MFC

Below is the code snippet for a C++ function to return the filename from the full file path in MFC:

#include "StdAfx.h"

CString CAppUtilManager::ExtractName(CString strFullPath) const
{
 int pos=strFullPath.ReverseFind('\\');
 return strFullPath.Right(strFullPath.GetLength()-pos-1);
}

Return the list of files from a directory in MFC

Below is the code snippet that implements a C++ function to return the list of files in a directory in MFC:


#include "StdAfx.h"

void CAppUtilManager::GetFiles(const CString& parent_folder, const CString& filters, CStringArray& files, BOOL bRecursive) const
{
 CFileFind fFind;
 BOOL bWorking=fFind.FindFile(parent_folder+_T("\\")+filters);

 while(bWorking==TRUE)
 {
  bWorking=fFind.FindNextFile();
  if(fFind.IsDots())
  {
   continue;
  }
  if(fFind.IsDirectory())
  {
   if(bRecursive==TRUE)
   {
    GetFiles(fFind.GetFilePath(), filters, files, bRecursive);
   }
  }
  else
  {
   files.Add(fFind.GetFilePath());
  }
 }
 fFind.Close();
}

Return the list of sub folders from a directory in MFC

Below is the code snippet for a C++ function to return a list of sub folders from a directory in MFC:

#include "StdAfx.h"

void CAppUtilManager::GetSubFolders(const CString& parent_folder, CStringArray& sub_folders) const
{
 CFileFind fFind;
 BOOL bWorking=fFind.FindFile(parent_folder+_T("\\*.*"));

 while(bWorking==TRUE)
 {
  bWorking=fFind.FindNextFile();
  if(fFind.IsDots())
  {
   continue;
  }
  if(fFind.IsDirectory())
  {
   sub_folders.Add(fFind.GetFilePath());
  }
 }
 fFind.Close();
}

Open a Folder Browser with Create Button in MFC

Below is the code snippet that implements a C++ function to open a folder browser in MFC with a Create Folder button, and return the path to the selected folder.


#include "StdAfx.h"
#include "shlobj.h"

CString CAppUtilManager::BrowseForDirectory() const
{
 int MAX_PATH=256;
 TCHAR display_name[MAX_PATH];
 TCHAR path[MAX_PATH];
    BROWSEINFO bi = { 0 };
    bi.lpszTitle = _T("Select an existing or created folder");
 bi.pszDisplayName=display_name;
 bi.ulFlags |= BIF_NEWDIALOGSTYLE;
    LPITEMIDLIST pidl = SHBrowseForFolder(&bi);

 CString directory_path(_T(""));

    if(pidl != 0)
    {
        // get the name of the folder and put it in path
        SHGetPathFromIDList (pidl, path);

        //Set the current directory to path
        directory_path=path;

        // free memory used
        IMalloc * imalloc = 0;
        if ( SUCCEEDED( SHGetMalloc ( &imalloc )) )
        {
            imalloc->Free ( pidl );
            imalloc->Release ( );
        }
    }

 return directory_path;
}

Having TinyXML working with MFC

If you are using TinyXml with MFC, remember to add the following line

#include "stdafx.h"

to the top of the the source files tinystr.cpp, tinyxml.cpp, and tinyxmlerror.cpp, tinyxmlparser.cpp to prevent compilation error in MFC project.

Performing Statistical Hypothesis Test in C++ using AlgLilb: Student's t-test and Wilcoxon

Sometimes when comparing the performance of two algorithms such as in control, optimization, machine learning, etc. the comparison is done by running a number of simulations run on a set of benchmark problems for these algorithms, the statistical performance metrics are then derived from these simulation runs to compare their performances. However, it is usually not sufficient to claim one algorithm/method is better simply based on the average values of the performance metrics. In other words, performance comparison should also consider statistical hypothesis tests such as Student's t-test and Wilcoxon. Details of these methods can be found here:

https://en.wikipedia.org/wiki/Student's_t-test
http://en.wikipedia.org/wiki/Wilcoxon_signed-rank_test

This post is about how to do statistical hypothesis test in C++ using alglib

Step 1: Download AlgLib

Download the AlgLib from the following link:

http://www.4shared.com/zip/ZWXFztx-/alglib-250cpp.html

Step 2: Add AlgLib to C++ project

In this case, I am using VS2008 C++ IDE, unzip the downloaded AlgLib to the project solution folder, and add it to the C++ project by the following properties configuration:

1) Properties->Configuration Properties->C++->General->Additional Include Directories->$(ProjectDir)alglib-2.5.0.cpp\out
2) Properties->Configuration Properties->Linker->General->Additional Library Directories->$(ProjectDir)alglib-2.5.0.cpp\out
3) Properties->Configuration Properties->Linker->Input->libalglib.lib

Step 3: Student's t-test in C++
Suppose you implement your code in a source file main.cpp, define the Student's t-test as shown below in

#include "studentttests.h"
//data1: vector containing simulation results of a performance metric (say MetricA) for algorithm 1
//data2: vector containing simulation results of a performance metric (say MetricA) for algorithm 2
//if left-tail is less than the confidence threshold, left-tail rejected, and we have MetricA (algorithm 1) > MetricA (algorithm 2)
//if right-tail is less than the confidence threshold, right-tail rejected, and we have MetricA (algorithm 1) < MetricA (algorithm 2)
void ComputeStudentT(const std::vector<double>& data1, const std::vector<double>& data2, double& bothtails, double& lefttail, double& righttail)
{
 if(data1.empty() || data2.empty())
 {
  return;
 }

 ap::real_1d_array x;
 ap::real_1d_array y;
 
 int n=static_cast<int>(data1.size());
 x.setlength(n);
 for(int i = 0; i != n; i++)
 {
  x(i) = data1[i];
 }

 int m=static_cast<int>(data2.size());
 y.setlength(m);
 for(int i=0; i != m; ++i)
 {
  y(i)=data2[i];
 }

 /*************************************************************************
 Two-sample unpooled test

 This test checks three hypotheses about the mean of the given samples. The
 following tests are performed:
  * two-tailed test (null hypothesis - the means are equal)
  * left-tailed test (null hypothesis - the mean of the first sample  is
    greater than or equal to the mean of the second sample)
  * right-tailed test (null hypothesis - the mean of the first sample is
    less than or equal to the mean of the second sample).

 Test is based on the following assumptions:
  * given samples have normal distributions
  * samples are independent.
 Dispersion equality is not required

 Input parameters:
  X - sample 1. Array whose index goes from 0 to N-1.
  N - size of the sample.
  Y - sample 2. Array whose index goes from 0 to M-1.
  M - size of the sample.

 Output parameters:
  BothTails   -   p-value for two-tailed test.
      If BothTails is less than the given significance level
      the null hypothesis is rejected.
  LeftTail    -   p-value for left-tailed test.
      If LeftTail is less than the given significance level,
      the null hypothesis is rejected.
  RightTail   -   p-value for right-tailed test.
      If RightTail is less than the given significance level
      the null hypothesis is rejected.

   -- ALGLIB --
   Copyright 18.09.2006 by Bochkanov Sergey
 *************************************************************************/
 
 unequalvariancettest(x, n, y, m, bothtails, lefttail, righttail);
}

For ComputeStudentT() method, the parameter data1 is a vector containing simulation results of a performance metric (say MetricA) for algorithm 1, which is obtained from simulation runs on a benchmark problem (suppose there are 30 simulation runs, then data1 is a vector of length 30), while data2 is a vector containing results of MetricA for algorithm 2, which is obtained from simulation runs on the same benchmark problem.

Below shows how one can use the CompareStudentT() in the coding

RunSimulationsToObtainMetricAForAlgorithm1();
RunSimulationsToObtainMetricAForAlgorithm2();

std::vector<double> data1;
LoadMetricAForAlgorithm1IntoVector(data1);

std::vector<double> data2;
LoadmetricAForAlgorithm2IntoVector(data2);

double bothtails=0, lefttail=0, righttail=0;

double p_threshold=0.05; //set p threshold to 0.05 for 95% confidence level

ComputeStudentT(data1, data2, bothtails, lefttail, righttail);

/*
* two-tailed test (null hypothesis - the means are equal)
* left-tailed test (null hypothesis - the mean of the first sample  is
  greater than or equal to the mean of the second sample)
* right-tailed test (null hypothesis - the mean of the first sample is
  less than or equal to the mean of the second sample).
*/
if(bothtails < p_threshold)
{
 //null hypothesis rejected, the mean of data1 is either greater or less than tat of data2
 if(lefttail < p_threshold && righttail > p_threshold)
 {
  std::cout << "The true mean of MetricA(algorithm1) is smaller than tat of MetricA(algorithm2)" << std::endl;
 }
 else if(lefttail > p_threshold && righttail < p_threshold)
 {
  std::cout << "The true mean of MetricA(algorithm1) is greater than tat of MetricA(algorithm2)" << std::endl;
 }
 else
 {
  std::cerr << "error: t stat failed" << std::endl;
  exit(0);
 }
}


Step 4: Wilcoxon test in C++ 

Below shows the Wilcoxon test method in C++, the interface and usage of ComputeWilcoxon() method is same as ComputeStudentT() method

#include "wsr.h"

//if left-tail is less than the confidence threshold, left-tail rejected, and we have data1 > data2
//if right-tail is less than the confidence threshold, right-tail rejected, and we have data2 < data1
void ComputeWilcoxon(const std::vector<double>& data1, const std::vector<double<& data2, double& bothtails, double& lefttail, double& righttail)
{
 if(data1.empty() || data2.empty())
 {
  return;
 }

 ap::real_1d_array x;
 ap::real_1d_array y;
 
 int n=static_cast<int>(data1.size());
 int m=static_cast<int>(data2.size());

 if(n > m)
 {
  n=m;
 }

 x.setlength(n);
 for(int i = 0; i != n; i++)
 {
  x(i) = (data1[i] - data2[i]);
 }

 double assumed_median=0; //the given value

 /*************************************************************************
 Wilcoxon signed-rank test

 This test checks three hypotheses about the median  of  the  given sample.
 The following tests are performed:
  * two-tailed test (null hypothesis - the median is equal to the  given
    value)
  * left-tailed test (null hypothesis - the median is  greater  than  or
    equal to the given value)
  * right-tailed test (null hypothesis  -  the  median  is  less than or
    equal to the given value)

 Requirements:
  * the scale of measurement should be ordinal, interval or  ratio (i.e.
    the test could not be applied to nominal variables).
  * the distribution should be continuous and symmetric relative to  its
    median.
  * number of distinct values in the X array should be greater than 4

 The test is non-parametric and doesn't require distribution X to be normal

 Input parameters:
  X       -   sample. Array whose index goes from 0 to N-1.
  N       -   size of the sample.
  Median  -   assumed median value.

 Output parameters:
  BothTails   -   p-value for two-tailed test.
      If BothTails is less than the given significance level
      the null hypothesis is rejected.
  LeftTail    -   p-value for left-tailed test.
      If LeftTail is less than the given significance level,
      the null hypothesis is rejected.
  RightTail   -   p-value for right-tailed test.
      If RightTail is less than the given significance level
      the null hypothesis is rejected.

 To calculate p-values, special approximation is used. This method lets  us
 calculate p-values with two decimal places in interval [0.0001, 1].

 "Two decimal places" does not sound very impressive, but in  practice  the
 relative error of less than 1% is enough to make a decision.

 There is no approximation outside the [0.0001, 1] interval. Therefore,  if
 the significance level outlies this interval, the test returns 0.0001.

   -- ALGLIB --
   Copyright 08.09.2006 by Bochkanov Sergey
 *************************************************************************/
 wilcoxonsignedranktest(x, n, assumed_median, bothtails, lefttail, righttail);
}


Access SQLite using C++

This is a description of accessing SQLite using C++

Step 1: Download the CppSQLite

For me, I have been using the version which can be downloaded from:

http://www.4shared.com/zip/aNL2EdT_/sqlite.html

Step 2: Build the CppSQLite library

In this example, I am using VS2008 C++ IDE,

1) Extract the downloaded content to the folder sqlite
2) Open sqlite\SQLite_Static_Library\SQLite_Static_Library.sln
3) You may need to change the runtime libraries of the project to match those of the executable that will include the libraries, in order to avoid linker errors.
4) Build the library.

Step 3: Add the CppSQLite to your project

1) copy the sqlite folder to your solution folder
2) Include the library directory in your application (Project->Properties->Configuration Properties->Linker->General->Additional Library Directories->["$(ProjectDir)sqlite\SQLite_Static_Library\release"])
3) Include the static library built in step 2 (Project->Properties->Configuration Properties->Linker->Input->Additional Dependencies->[SQLite_Static_Library.lib])
4) Add the C++ wrapper to your project.  It's in the sqlite root dir:

      CppSQLite3.h
      CppSQLite3.cpp

Step 4: Implement code to access SQLite

The following a simple singleton class written in C++:

#ifndef _H_DB_MANAGER_H
#define _H_DB_MANAGER_H

#include <sstream>
#include <ctime>
#include "CppSQLite3.h"

class DBManager
{
public:
 virtual ~DBManager()
 {
  
 }

private:
 DBManager()
 {
  
 }

 DBManager(const DBManager& rhs) { }
 DBManager& operator= (const DBManager& rhs) { return *this; }

public:
 void record_data(int attr1_value, const std::string& attr2_value, int attr3_value)
 {
  std::ostringstream oss;
  oss << "INSERT INTO demo_table (attr1, attr2, attr3) VALUES (" << attr1_value << ", '" << attr2_value << "', " << attr3_value << ");" ;
  try{
   mDB.execDML(oss.str().c_str());
  }catch(CppSQLite3Exception& e)
  {
   std::cerr << e.errorCode() << ": " << e.errorMessage() << "\n";
  }
 }

public:
 static DBManager* getSingletonPtr()
 {
  static DBManager theInstance;
  return &theInstance;
 }

public:
 void open(const char* dbname)
 {
  try{
   remove(dbname);
   mDB.open(dbname);

   mDB.execDML("CREATE TABLE demo_table (id INTEGER PRIMARY_KEY, attr1 INTEGER, attr2 TEXT, attr3 INTEGER);");
  
  }catch (CppSQLite3Exception& e)
  {
   std::cerr << e.errorCode() << ":" << e.errorMessage() << "\n";
  }
 }
 void close()
 {
  mDB.close();
 }

private:
 CppSQLite3DB mDB;
};
#endif

Below is a simple explanation of the database manager class
  • The open() method recreate the database, and then create a datatable "demo_table" in the database file with three fields: attr1, attr2, attr3, attr1 and attr3 are INTEGER while attr2 is a TEXT. 
  • The record_data() method record a single row into the database "demo_table" 
  • The close() method should be called at the end of database operation to create database connection


To use the singleton class above, it is very easy, below is a simple example:
#include "DBManager.h"
DBManager::getSingletonPtr()->open("demo.db");
DBManager::getSingletonPtr()->record_data(1, "Hello World", 2);
DBManager::getSingletonPtr()->close();

Add Code Syntax Highlighter to your Blogger

Go to the "Template" menu and click "Edit Html" below the current template, add the following lines above the </head>
 
 

In your content, surround the code block by <pre> element, like to one shown below:

<pre class="brush: csharp">private void Download(string url)
{
    WebClient client = new WebClient();
    client.DownloadFileCompleted +=    new AsyncCompletedEventHandler(client_DownloadFileCompleted);
    client.DownloadFileAsync(new Uri(url), @"c:\temp.html");
}

void client_DownloadFileCompleted(object sender, AsyncCompletedEventArgs e)
{
    //do something here
}
</pre>

which will be rendered as:
private void Download(string url)
{
    WebClient client = new WebClient();
    client.DownloadFileCompleted +=    new AsyncCompletedEventHandler(client_DownloadFileCompleted);
    client.DownloadFileAsync(new Uri(url), @"c:\temp.html");
}

void client_DownloadFileCompleted(object sender, AsyncCompletedEventArgs e)
{
    //do something here
}
If your code block contains template such as the one below:

Dictionary<string, string> some_dict=new Dictionary<string, string>();

Change "Dictionary<string, string>" to "Dictionary&lt;string, string&gt;" so that the code syntax highlighter won't display errorly.

One further thing that i found out is that if you are using dynamic view template for your blogger, the code syntax highlighter probably won't work

Sunday, July 21, 2013

Singeat.com Map-based Desktop using Web Crawling Technique

Last friday, I decided to have a relaxed night with my younger brother by going out and rewarding ourselves a good meal. Being lazy and nerdy, my tendency for finding a nice place to eat is usually by searching online. We searched singeat.com (新加坡美食网)for a nice hotpot corner near the place we stay so that we only commute a short distance back and forth (yeah that lazy). singeat.com is nice, offering many comprehensive information, e.g. food category, search area, photos, comments, groupon, order, and other comprehensive information such as surrouding, main cuisines, parking, and so on.

But then when it comes to find a hotpot restaurant near the place we stay, it becomes troublesome. Firstly, the place we stay is far from the city down town, which means not a lot of restaurants around. Secondly, they don't offer a map which one can select the restaurants near a particular location user specifies (e.g. something like gothere.sg and nearby.sg). Thirdly, while navigating page by page certainly generate traffic flows for singeat.com, it makes impatient web users like me even more impatient. Therefore, while enjoying hotpot with my brother on friday night, I decided to do something, maybe save myself the trouble experienced when using singeat.com - by writing an map-based application which shows any type of restaurant with rating from nearby the place i indicated on the map. It took my saturday to come up with a desktop application that does what i want :) The following list down the steps i used to create this app.

Step 1: What I need to decide before creating the application
The first thing i need to decide is what type of application i am to create: since this is for my personal usage, and i want to do it quickly, i decided to write the application in C# Winform. 

The second thing i need is how am i going to obtain data from singeat.com: I am not aware of any web services or rss exposed by singeat.com that will allow me to retrieve most of the information from their website, which means i need to write a web crawler to help me crawl and organize information from their website. 

The third thing i need is to display those information on a map on the desktop which user can interact such as performing search, view rating and photos and so on.

Step 2: Technologies to deploy in my application
As the application development is going to be a RAD (yeah i completed in one day), I need to use tools and libraries that are already out there so as to help me shorten the time of development. The following are the tools that i ultimately used in the application:


  • Html Agility Pack: parsing the html web pages downloaded from singeat for information and photos
  • GMap.Net: display map on winform as well as performing geocoding and reverse geocoding.
  • Custom TabControl: a tab control that makes winform tab looks better (since i uses quite a number of tab controls in this app, i make some extra efforts to make them look nicer)

Step 3: Implement codes to crawl singeat.com
In order to retrieve information from singeat.com, my implementation code first go to their search page and crawl the search fields such as SearchFood, SearchAreas, etc. This is done using Html Agility Pack to parse the hidden input fields and <select> elements on the search page.

Once i obtained the list of search terms, the crawler codes crawl the search page by sending various queries using different combination of search terms (to minimize the traffic, pages are cached locally as well as limiting the total queries and interval for queries). 

Next for each queried search page, my implemented code parse the html link for the individual restaurant page, and the crawler uses these link to visit and download these individual restaurant pages (again, cache is used to prevent traffic)

When each individual restaurant page is downloaded, the parser parses html table and form inputs for further information such as address, restaurant cuisines, rooms, seats, comments, links to photos and so on. The links to photos and comments are then further extracted to download photos if any to the cache. 

Once all the information for a restaurant are obtained, the information is encapsulated into a restaurant object completed with photo locations, comments, original link, restaurant order link and so on.

Step 4: Implement code to display restaurant information on the map
Since the singeat.com restaurant page does not contains information such as (latitude, longitude), reverse geocoding must be performed to obtain the actual geo location, this is done using GMap.Net, which also provides a winform map control for display the restaurants. 

Another important step is to calculate nearby restaurant, this can be done easily using equation that caculates the geo distance between the current location and restaurant location. 

Step 5: Put every thing together
Below shows some screenshots from the application:

Figure 1: Set Search Query using SearchFood and SearchArea

Figure 2: Display restaurants of various types on the map
Figure 3: Display restaurant names
Figure 4: Change to Bing Map from Google Map
Figure 5: Display restaurant details when clicked
Figure 6: Display comments on the restaurant
Figure 7: Display photos related to the restaurant
Figure 8: Display Search by Region and Radius
Figure 9: Refine Search Further using Filter



Below is the short video:

Converting between Country Code and Country Name in C#

I have made a simple class for user to convert between country code and country name in C#, which can be downloaded from:

http://www.4shared.com/file/XyWMBYlV/CountryCodeManager.html

This is a singleton class, to get the country code for a country, e.g. Netherlands, use it like this:

string country_code = CountryCodeManager.Instance.GetCountryCode("Netherlands");

Copy directory in C#

The following method copy a directory and its contents to another location:


private static void DirectoryCopy(string sourceDirName, string destDirName, bool copySubDirs=true)
 {
 DirectoryInfo dir = new DirectoryInfo(sourceDirName);
 DirectoryInfo[] dirs = dir.GetDirectories();

 if (!dir.Exists)
 {
  throw new DirectoryNotFoundException(
   "Source directory does not exist or could not be found: "
   + sourceDirName);
 }

 if (!Directory.Exists(destDirName))
 {
  Directory.CreateDirectory(destDirName);
 }

 FileInfo[] files = dir.GetFiles();
 foreach (FileInfo file in files)
 {
  string temppath = Path.Combine(destDirName, file.Name);
  file.CopyTo(temppath, false);
 }

 if (copySubDirs)
 {
  foreach (DirectoryInfo subdir in dirs)
  {
   string temppath = Path.Combine(destDirName, subdir.Name);
   DirectoryCopy(subdir.FullName, temppath, copySubDirs);
  }
 }
}

Get Path to the current directory of the executing program in C#

In C#, if you already included the System.Windows.Forms namespace, the directory from which your application is run can be obtained by

string current_dir=Application.StartupPath;

On the other hand, if you are writing a library which needs to know the directory form which the calling application is run, or you do not use the System.Windows.Forms namespace than the directory can be obtained by:

using System.IO;
using System.Diagnostics;
using System.Reflection;

string current_dir=null;
try{
   current_dir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().GetModules()[0].FullyQualifiedName);
}
catch (IOException e)
{
 throw new IOException("Can't get app root directory", e);
}

Geocoding and Reverse Geocoding in C#

Step 1: Download and add the GMap.Net to your project

download a copy of GMap.Net library from:

http://greatmaps.codeplex.com/

add a reference to GMap.Net.Core to your project

Step 2: Get address or (lat, lon) from (lat, lon) or address

The following two methods allow you to retrieve address from (lat, lon) or (lat, lon) from a given address. The code also uses simple cache technique to store the retrieved results.

public static string FindAddress(double lat, double lng)
{
 int latE6 = (int)(lat * 1000000);
 int lngE6 = (int)(lng * 1000000);

 string foldername = "location_cache";
 if (!Directory.Exists(foldername))
 {
  Directory.CreateDirectory(foldername);
 }

 string filename = string.Format("{0}\\{1}_{2}.txt", foldername, latE6, lngE6);

 if (File.Exists(filename))
 {
  StreamReader reader = new StreamReader(filename);
  string data=reader.ReadToEnd();
  reader.Close();
  return data;
 }

 string address = "";
 GeoCoderStatusCode status;
 var pos = GMapProviders.GoogleMap.GetPlacemark(new PointLatLng(lat, lng), out status);
 if (status == GeoCoderStatusCode.G_GEO_SUCCESS && pos != null)
 {
  address = pos.Address;
  StreamWriter writer = new StreamWriter(filename);
  writer.WriteLine(address);
  writer.Close();
 }

 return address;
}

public static bool FindLatLngByAddress(string address, out double lat, out double lng)
{
 string address64 = EncodeTo64(address);

 string foldername = "address_cache";
 if (!Directory.Exists(foldername))
 {
  Directory.CreateDirectory(foldername);
 }

 string filename = string.Format("{0}\\{1}.txt", foldername, address64);

 if (File.Exists(filename))
 {
  StreamReader reader = new StreamReader(filename);
  string data = reader.ReadToEnd();
  reader.Close();
  string[] latlng=data.Split(new char[]{','});
  lat = double.Parse(latlng[0].Trim());
  lng = double.Parse(latlng[1].Trim());
  return true;
 }

 lat = 0;
 lng = 0;
 GeoCoderStatusCode status;
 PointLatLng? point=GMapProviders.GoogleMap.GetPoint(address, out status);
 if (status == GeoCoderStatusCode.G_GEO_SUCCESS && point != null)
 {
  lat = point.Value.Lat;
  lng = point.Value.Lng;

  StreamWriter writer = new StreamWriter(filename);
  writer.WriteLine(string.Format("{0},{1}", lat, lng));
  writer.Close();
  return true;
 }
 return false;
}

static public string EncodeTo64(string toEncode)
{
 byte[] toEncodeAsBytes
    = System.Text.ASCIIEncoding.ASCII.GetBytes(toEncode);
 string returnValue
    = System.Convert.ToBase64String(toEncodeAsBytes);
 return returnValue;
}

Calculate distance between two geolocations

The following methods can be used to calculate the actual distance between two geo locations in (lat, lon)

//get distance based on latitude and longitude
public static double GetDistance_m(double lat1, double lon1, double lat2, double lon2)
{
 double theta = lon1 - lon2;

 double dist = Math.Sin(Deg2Rad(lat1)) * Math.Sin(Deg2Rad(lat2)) + Math.Cos(Deg2Rad(lat1)) * Math.Cos(Deg2Rad(lat2)) * Math.Cos(Deg2Rad(theta));
 if (dist > 1)
  dist = 1;
 if (dist < -1)
  dist = -1;
 dist = Math.Acos(dist);
 dist = Rad2Deg(dist);
 dist = dist * 60 * 1.1515;
 dist = dist * 1609.344;
 return (dist);
}

//get distance based on latitude and longitude
public static double GetDistance_km(double lat1, double lon1, double lat2, double lon2)
{
 double theta = lon1 - lon2;

 double dist = Math.Sin(Deg2Rad(lat1)) * Math.Sin(Deg2Rad(lat2)) + Math.Cos(Deg2Rad(lat1)) * Math.Cos(Deg2Rad(lat2)) * Math.Cos(Deg2Rad(theta));
 if (dist > 1)
  dist = 1;
 if (dist < -1)
  dist = -1;
 dist = Math.Acos(dist);
 dist = Rad2Deg(dist);
 dist = dist * 60 * 1.1515;
 dist = dist * 1609.344 / 1000;
 return (dist);
}

 //convert degree to radian
public static double Deg2Rad(double deg)
{
 return (deg * Math.PI / 180.0);
}

//convert radian to degree
public static double Rad2Deg(double rad)
{
 return (rad / Math.PI * 180.0);

}

Parsing Html form input elements in Web Page using C#

Step 1: download and add reference of Html Agility Pack to your project
Download Html Agility Pack from the following link:

http://htmlagilitypack.codeplex.com/

Add a reference of the library to your project

Step 2: download the html web page to parse

Use the following code to download the web page.

private void Download(string url)
{
    WebClient client = new WebClient();

    client.DownloadFileCompleted +=    new AsyncCompletedEventHandler(client_DownloadFileCompleted);

    client.DownloadFileAsync(new Uri(url), @"c:\temp.html");
 }

void client_DownloadFileCompleted(object sender, AsyncCompletedEventArgs e)
{
    //do something here
}

Step 3: Parse the downloaded web page using Html Agility Pack

Use the following code in the client_DownloadFileCompleted() to enumerate all links in the web page.

void client_DownloadFileCompleted(object sender, AsyncCompletedEventArgs e)
{
   String storesadd="";
   string storesname="";
   string bestfood="";
 HtmlNodeCollection form_node_collection=doc.DocumentNode.SelectNodes("//form");
 foreach (HtmlNode form_node in form_node_collection)
 {
  HtmlNodeCollection input_node_collection = form_node.SelectNodes("//input");
  if(input_node_collection != null)
  {
   foreach (HtmlNode input_node in input_node_collection)
   {
    if (input_node.Attributes.Contains("id") && input_node.Attributes.Contains("value"))
    {
     string input_id=input_node.Attributes["id"].Value;
     string input_value = input_node.Attributes["value"].Value;
     if (string.IsNullOrEmpty(input_value))
     {
      continue;
     }
     if (input_id == "storesadd")
     {
      storesadd = input_value;
     }
     else if (input_id == "bestfood")
     {
      bestfood = input_value;
     }
     else if (input_id == "storesname")
     {
      storesname = input_value;
     }
    }

   }
  }
 }
}

Parsing Html select elements in Web Page using C#

Step 1: download and add reference of Html Agility Pack to your project
Download Html Agility Pack from the following link:

http://htmlagilitypack.codeplex.com/

Add a reference of the library to your project

Step 2: download the html web page to parse

Use the following code to download the web page.

private void Download(string url)
{
    WebClient client = new WebClient();

    client.DownloadFileCompleted +=    new AsyncCompletedEventHandler(client_DownloadFileCompleted);

    client.DownloadFileAsync(new Uri(url), @"c:\temp.html");
 }

void client_DownloadFileCompleted(object sender, AsyncCompletedEventArgs e)
{
    //do something here
}
Step 3: Parse the downloaded web page using Html Agility Pack

Use the following code in the client_DownloadFileCompleted() to enumerate all links in the web page.

void client_DownloadFileCompleted(object sender, AsyncCompletedEventArgs e)
{
 Dictionary<string, string> search_foods=new Dictionary<string, string>();
 HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();
 HtmlNode.ElementsFlags.Remove("option");
 doc.Load("c:\\temp.html", Encoding.UTF8);

 HtmlNodeCollection select_node_collection = doc.DocumentNode.SelectNodes("//select[@name='SearchFood']//option");
 if (select_node_collection != null)
 {
  foreach (HtmlNode node in select_node_collection)
  {
   string option_value = node.Attributes["value"].Value;
   string option_text = node.InnerText;
   search_foods[option_text] = option_value;
  }
 }
}

Parsing Html Table in Web Pages using C#

Step 1: download and add reference of Html Agility Pack to your project
Download Html Agility Pack from the following link:

http://htmlagilitypack.codeplex.com/

Add a reference of the library to your project

Step 2: download the html web page to parse

Use the following code to download the web page.



Step 3: Parse the downloaded web page for the html table using Html Agility Pack

private void Download(string url)
{
    WebClient client = new WebClient();

    client.DownloadFileCompleted +=    new AsyncCompletedEventHandler(client_DownloadFileCompleted);

    client.DownloadFileAsync(new Uri(url), @"c:\temp.html");
 }

void client_DownloadFileCompleted(object sender, AsyncCompletedEventArgs e)
{
    //do something here
}
Use the following code in the client_DownloadFileCompleted() to enumerate all links in the web page.

void client_DownloadFileCompleted(object sender, AsyncCompletedEventArgs e)
{
 string address="";
 foreach (HtmlNode table in doc.DocumentNode.SelectNodes("//table"))
 {
  //Console.WriteLine("Found: " + table.Id);
  HtmlNodeCollection hnc=table.SelectNodes("tr");
  if(hnc != null)
  {
   foreach (HtmlNode row in hnc)
   {
    bool address_found=false;
    bool address_stored=true;
    foreach (HtmlNode cell in row.SelectNodes("td"))
    {
     // get address
     if (cell.InnerText.Contains("详细地址") && !cell.InnerText.Contains(""))
     {
      address_found = true;
      address_stored = false;
     }
     else if (address_found && address_stored == false)
     {
      address = cell.InnerText.Trim();
      address_stored = true;
     }
     
    }
   }
  }
 }

 Console.WriteLine("Found Address in Web Page: {0}", address);
}

Parsing Html Links in Web Pages in C#

Step 1: download and add reference of Html Agility Pack to your project
Download Html Agility Pack from the following link:

http://htmlagilitypack.codeplex.com/

Add a reference of the library to your project

Step 2: download the html web page to parse

Use the following code to download the web page.


Step 3: Parse the downloaded web page for <a href="..."></a> link using Html Agility Pack

private void Download(string url)
{
    WebClient client = new WebClient();
    client.DownloadFileCompleted +=    new AsyncCompletedEventHandler(client_DownloadFileCompleted);
    client.DownloadFileAsync(new Uri(url), @"c:\temp.html");
}

void client_DownloadFileCompleted(object sender, AsyncCompletedEventArgs e)
{
    //do something here
}
Use the following code in the client_DownloadFileCompleted() to enumerate all links in the web page.

void client_DownloadFileCompleted(object sender, AsyncCompletedEventArgs e)
{
 HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();
 doc.Load("c:\\temp.html", Encoding.UTF8);

 foreach (HtmlNode link in doc.DocumentNode.SelectNodes("//a/@href"))
 {
  HtmlAttribute att = link.Attributes["href"];
  string url = att.Value;
  Console.WriteLine("Url in temp.html: {0}", url);
 }
}

Thursday, July 18, 2013

ERROR: Unable to update the dependencies of the project.

Today, out of blue, my vs2010 setup project is not working, keep telling me errors like:

ERROR: Unable to update the dependencies of the project. The dependencies for the object ‘assembly_name’ cannot be determined."

I searched online, it is said the error is due to "VS2010 QFE: Setup project compilation fails with command line" and find this hotfix from microsoft to fix the problem:

http://archive.msdn.microsoft.com/KB2286556/Release/ProjectReleases.aspx?ReleaseId=4994

Timely GUI update of progress for background worker process in .NET

Sometime when you are performing a very expensive process using a background working in .NET, for example processing records from the database one by one, you want the GUI to display update on the progress of the progress, typical code will look like to following:

BackgroundWorker worker=new BackgroundWorker();
worker.WorkerReportsProgress=true;

bool is_running=true;

int total_record_count=EmployeeDb.GetDbRecordCount(criteria)
worker.DoWork+=(s1, e1)=>
{
    EmployeeDb.DoAnalysis(criteria, (rec_index)=>
      {
           worker.ReportProgress(rec_index * 100 / total_record_count);
           return is_running;
      });
};
worker.ProgressChanged+=(s1, e1)=>
{
    progressBar1.Value=e1.ProgressPercentage;
};
worker.RunWorkerCompleted+=(s1, e1)=>
{
   MessageBox.Show("Done!");
};

worker.RunWorkerAsync();

The problem with the above method is that we may not know how frequently the worker.ReportProgress() is called, and within what time interval two consecutive worker.ReportProgress() are called. This can be bad for two reason: firstly, if the time interval between two consecutive calls to worker.ReportProgress() is very short, the GUI may not get updated since it a low priority task; secondly, two many calls to worker.ReportProgress() wasting CPU cycles while present no real difference to the user.

My solution at the moment is to timely call worker.ReportProgress() instead, e.g. by every 1 seconds. This is very easily done. the following shows the timely call procedure (the change is in the bold highlight):

BackgroundWorker worker=new BackgroundWorker();
worker.WorkerReportsProgress=true;

bool is_running=true;

DateTime current_time=DateTime.Now;
DateTime report_time=DateTime.Now;
TimeSpan ts;

int total_record_count=EmployeeDb.GetDbRecordCount(criteria)
worker.DoWork+=(s1, e1)=>
{
    EmployeeDb.DoAnalysis(criteria, (rec_index)=>
      {
           current_time=DateTime.Now;
           ts=current_time - report_time;
           if(ts.TotalMilliSeconds > 1000)
           {
                  report_time=current_time;
                  worker.ReportProgress(rec_index * 100 / total_record_count);
           }
           return is_running;
      });
};
worker.ProgressChanged+=(s1, e1)=>
{
    progressBar1.Value=e1.ProgressPercentage;
};
worker.RunWorkerCompleted+=(s1, e1)=>
{
   MessageBox.Show("Done!");
};

worker.RunWorkerAsync();



Wednesday, July 17, 2013

Calculate the margin of errors and required sample size in a Monte Carlo simulation

Suppose you have a monte carlo simulation, in which a sample of size N is used, each event with K different outcomes (which follows certain probability distribution function) and is independent of each other, given the sample size N is known, and the accuracy of the monte carlo simulation can be estimated using the margin of error which is given by:

margin_of_error = z / (2 * Math.Sqrt(N))

where z is the z-score from normal distribution at a certain confidence level. Typical values of z at different confidence level are given below:

z=1.96 at confidence level 95%
z=2.58 at confidence level 99%
z=3.29 at confidence level 99.9%

Suppose the sample size is N=10000, then at 95% confidence, we can say the margin of error of a monte carlo simulation is:

margin_of_error=1.96 / (2 * Math.Sqrt(10000))

The above equation can also be used to calculate the sample size required if a particular accuracy or margin of error is to be achieved for a monte carlo simulation:

N=(z / (2 * margin_of_error))^2

Further details can be found in:

http://ellard.org/dan/www/Courses/sq98_root.pdf

How to Calculate Confidence Levels

How to Calculate Confidence Levels

Hide .NET Winform application in tray when minimized

First drop a NotifyIcon onto the winform and name it "notifyIcon", add a mouse double click event handler for the notifyIcon to the winform as shown below:

private void notifyIcon_MouseDoubleClick(object sender, MouseEventArgs e)
{
 ShowApp();
}

private void ShowApp()
{
 this.WindowState = FormWindowState.Maximized;
 this.ShowInTaskbar = true;
 this.Show();
}
This will ensure that when the notifyIcon in the system tray is clicked, the application will be shown. Next add a resize event handler to the winform as shown below:

private void FrmCrawler_Resize(object sender, EventArgs e)
{
 if (FormWindowState.Minimized == this.WindowState)
 {
  this.ShowInTaskbar = false;
  this.Hide();
 }
}
This is triggered when user click the minimize icon on the winform app, which in turns hide the app.

Tuesday, July 16, 2013

Add auto complete function for a textbox in your winform

auto complete is useful in a winform to, for example, help user to save time for type things such as username, to add auto listing to a textbox in a winform is very easy, below is an example code added to the Load delegate method in a winform:


            List<string> usernames = AccountManager.Instance.Usernames;
            if (usernames.Count > 0)
            {
                var source = new AutoCompleteStringCollection();
                foreach (string username in usernames)
                {
                    source.Add(username);
                }

                txtUsername.AutoCompleteCustomSource = source;
                txtUsername.AutoCompleteMode = AutoCompleteMode.SuggestAppend;
                txtUsername.AutoCompleteSource = AutoCompleteSource.CustomSource;
            }

Some good resources for learning OpenFOAM

Basic Tutorial:

http://web.student.chalmers.se/groups/ofw5/Basic_Training/gettingStarted.pdf
http://web.student.chalmers.se/groups/ofw5/Program.htm

Course Material:
http://www.tfd.chalmers.se/~hani/kurser/OS_CFD_2010/

Material Archive:
http://powerlab.fsb.hr/ped/kturbo/OpenFOAM/docs/

At this point, I cannot find a good book on OpenFOAM, some suggested a good starting point is to learn CFD using book such as "Ferziger, Peric, Computational Methods for Fluid Dynamics, Springer".


Reading Xml in PHP using SimpleXML

suppose you have an xml file "sample.xml" on your server with the following content:

<samples>
<sample index="1" value="0.3" />
<sample index="2" value="0.332" />
<sample index="3" value="0.83" />
<sample index="4" value="0.23" />
</samples>

The following codes will transform the above xml file into a html table using SimpleXML:

<?php
echo "<table>";
$filepath="sample.xml";
$xml=simplexml_load_file($filepath);
foreach($xml->children() as $child)
{
$index=$child->attributes()->index;
        $val=$child->attributes()->value;
        echo "<tr><td>".$index."</td><td>".$val."</td></tr>";
}
echo "</table>";
?>

Getting JqPlot to work inside a JQuery UI Tab

Jqplot is a very simple jquery-based plotting library for displaying simple plotting charts on html page, however, having a jqplot <div> in a jquery ui container such as tab and not having it displayed as default (e.g. having the jqplot as the second tab page instead of the default first tab page), the jqplot <div> will not display any plot. For example the following code will not work for the jqplot:

<html>
<head>
<link rel="stylesheet" type="text/css" href="jquery-ui/themes/base/jquery.ui.all.css">
<link rel="stylesheet" type="text/css" href="jquery-ui/demos.css">
<link rel="stylesheet" type="text/css" href="jqplot/jquery.jqplot.min.css" />
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script type="text/javascript" src="jqplot/jquery.jqplot.min.js"></script>
<script type="text/javascript" src="jqplot/plugins/jqplot.barRenderer.min.js"></script>
<script type="text/javascript" src="jqplot/plugins/jqplot.categoryAxisRenderer.min.js"></script>
<script type="text/javascript" src="jqplot/plugins/jqplot.pieRenderer.min.js"></script>
<script type="text/javascript" src="jqplot/plugins/jqplot.pointLabels.min.js"></script>
<script src="jquery-ui/ui/jquery.ui.core.js"></script>
<script src="jquery-ui/ui/jquery.ui.widget.js"></script>
<script src="jquery-ui/ui/jquery.ui.tabs.js"></script>
<script type="text/javascript">
$(function(){
$( "#tabs" ).tabs();

    var s1 = [1, 2, 3];
    // Can specify a custom tick Array.
    // Ticks should match up one for each y value (category) in the series.
    var ticks = ["Val1", "Val2", "Val3"];
     
    var plot1 = $.jqplot('chart1', [s1], {
        // The "seriesDefaults" option is an options object that will
        // be applied to all series in the chart.
        seriesDefaults:{
            renderer:$.jqplot.BarRenderer,
            rendererOptions: {fillToZero: true}
        },
        // Custom labels for the series are specified with the "label"
        // option on the series option.  Here a series option object
        // is specified for each series.
        series:[
            {label:'Search Query'}
        ],
        // Show the legend and put it outside the grid, but inside the
        // plot container, shrinking the grid to accomodate the legend.
        // A value of "outside" would not shrink the grid and allow
        // the legend to overflow the container.
        legend: {
            show: true,
            placement: 'outsideGrid'
        },
        axes: {
            // Use a category axis on the x axis and use our custom ticks.
            xaxis: {
                renderer: $.jqplot.CategoryAxisRenderer,
                ticks: ticks
            },
            // Pad the y axis just a little so bars can get close to, but
            // not touch, the grid boundaries.  1.2 is the default padding.
            yaxis: {
                pad: 1.05,
                tickOptions: {formatString: '%d'}
            }
        }
    });
var s2 = [["Val1":1], ["Val2":2], ["Val3":3]];
         
    var plot2 = $.jqplot('pie', [s2], {
        grid: {
            drawBorder: false, 
            drawGridlines: false,
            background: '#ffffff',
            shadow:false
        },
        axesDefaults: {
             
        },
        seriesDefaults:{
            renderer:$.jqplot.PieRenderer,
            rendererOptions: {
                showDataLabels: true
            }
        },
        legend: {
            show: true,
            rendererOptions: {
                numberRows: 1
            },
            location: 's'
        }
    }); 
$('#tabs').bind('tabsshow', function(event, ui) {
 if (ui.index === 1 && plot1._drawCount === 0) {
plot1.replot();
 }
 else if (ui.index === 2 && plot2._drawCount === 0) {
plot2.replot();
 }
});

});
</script>
</head>
<body>
<div id="tabs" style="min-height:500px">
<ul>
<li><a href="#tabs-1">Tabular Data</a></li>
<li><a href="#tabs-2">Histogram</a></li>
<li><a href="#tabs-3">Pie Chart</a></li>
</ul>
       <div id="tabs-1">
First Tab Page
</div>
<div id="tabs-2">
<div id="chart1" data-height="480px" data-width="960px" style="margin-top:20px; margin-left:20px;"></div>
</div>
<div id="tabs-3">
<div id="pie" data-height="480px" data-width="960px" style="margin-top:20px; margin-left:20px;"></div>
</div>
</div>
</body>
</html>

The solution is to call the jqplot element's replot() method when a tab page is selected by adding the highlighted section shown below:

<html>
<head>
<link rel="stylesheet" type="text/css" href="jquery-ui/themes/base/jquery.ui.all.css">
<link rel="stylesheet" type="text/css" href="jquery-ui/demos.css">
<link rel="stylesheet" type="text/css" href="jqplot/jquery.jqplot.min.css" />
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script type="text/javascript" src="jqplot/jquery.jqplot.min.js"></script>
<script type="text/javascript" src="jqplot/plugins/jqplot.barRenderer.min.js"></script>
<script type="text/javascript" src="jqplot/plugins/jqplot.categoryAxisRenderer.min.js"></script>
<script type="text/javascript" src="jqplot/plugins/jqplot.pieRenderer.min.js"></script>
<script type="text/javascript" src="jqplot/plugins/jqplot.pointLabels.min.js"></script>
<script src="jquery-ui/ui/jquery.ui.core.js"></script>
<script src="jquery-ui/ui/jquery.ui.widget.js"></script>
<script src="jquery-ui/ui/jquery.ui.tabs.js"></script>
<script type="text/javascript">
$(function(){
$( "#tabs" ).tabs();

    var s1 = [1, 2, 3];
    // Can specify a custom tick Array.
    // Ticks should match up one for each y value (category) in the series.
    var ticks = ["Val1", "Val2", "Val3"];
     
    var plot1 = $.jqplot('chart1', [s1], {
        // The "seriesDefaults" option is an options object that will
        // be applied to all series in the chart.
        seriesDefaults:{
            renderer:$.jqplot.BarRenderer,
            rendererOptions: {fillToZero: true}
        },
        // Custom labels for the series are specified with the "label"
        // option on the series option.  Here a series option object
        // is specified for each series.
        series:[
            {label:'Search Query'}
        ],
        // Show the legend and put it outside the grid, but inside the
        // plot container, shrinking the grid to accomodate the legend.
        // A value of "outside" would not shrink the grid and allow
        // the legend to overflow the container.
        legend: {
            show: true,
            placement: 'outsideGrid'
        },
        axes: {
            // Use a category axis on the x axis and use our custom ticks.
            xaxis: {
                renderer: $.jqplot.CategoryAxisRenderer,
                ticks: ticks
            },
            // Pad the y axis just a little so bars can get close to, but
            // not touch, the grid boundaries.  1.2 is the default padding.
            yaxis: {
                pad: 1.05,
                tickOptions: {formatString: '%d'}
            }
        }
    });
var s2 = [["Val1":1], ["Val2":2], ["Val3":3]];
         
    var plot2 = $.jqplot('pie', [s2], {
        grid: {
            drawBorder: false, 
            drawGridlines: false,
            background: '#ffffff',
            shadow:false
        },
        axesDefaults: {
             
        },
        seriesDefaults:{
            renderer:$.jqplot.PieRenderer,
            rendererOptions: {
                showDataLabels: true
            }
        },
        legend: {
            show: true,
            rendererOptions: {
                numberRows: 1
            },
            location: 's'
        }
    }); 
$('#tabs').bind('tabsshow', function(event, ui) {
  if (ui.index === 1 && plot1._drawCount === 0) {
plot1.replot();
  }
  else if (ui.index === 2 && plot2._drawCount === 0) {
plot2.replot();
  }
});

});
</script>
</head>
<body>
<div id="tabs" style="min-height:500px">
<ul>
<li><a href="#tabs-1">Tabular Data</a></li>
<li><a href="#tabs-2">Histogram</a></li>
<li><a href="#tabs-3">Pie Chart</a></li>
</ul>
       <div id="tabs-1">
First Tab Page
</div>
<div id="tabs-2">
<div id="chart1" data-height="480px" data-width="960px" style="margin-top:20px; margin-left:20px;"></div>
</div>
<div id="tabs-3">
<div id="pie" data-height="480px" data-width="960px" style="margin-top:20px; margin-left:20px;"></div>
</div>
</div>
</body>
</html>