Sunday, March 27, 2011

In GDI+ how to draw a text vertically.

Two weeks ago , I moved to a new company, and become very busy, to be honest, at Ninemsn, the culture is quite relax, not too much pressure, while in my new company, cause the team is small, I need to do most of the design and development, so quite busy, that's why I didn't get time to update my blog. 

As my first assignment in this company is to develop a chart control, which need to support line chart, pie chart, stack bar chart etc.  At this point , some people might ask , why not just find one from the market?  well, that's a very good question, I ask them as well, but the answer is , their chart requirement is quite unique ,   for example, they need a kind of stack bar chart.  all the others are standard, while the width of the stack bar should represent the production, that means , if a company, their production is high,  the width of the bar should represent it.  to be honest, I can't find a control from the market can meet this requirement without any funky customization.  furthermore, their want the chart can be export to word natively, when I say natively  means, the chart can be edit in word, cause most chart control currently, they can be export to word as an image, that means the chart can't be editable in word.  based on these two reason , we decide to implement one chart control of our own. 

Technically, it is not difficult, but I do came across a few issues, and I resolve that. 
1. In GDI+ how to draw a text vertically. 
In GDI+ , the way to do it is rotate the axis, for example, if you want to rotate it 90 degree, then you can use RotateTransform function. 
Assume, you want to draw a text at point(100,100) vertically,here is how you gona to do that. 
e.Graphics.TranslateTransform(100,100);
e.Graphics.RotateTransform(-90);
e.Graphics.DrawString("Hello", new Font("Arial", 10f, FontStyle.Regular), Brushes.Red, 0, 0);
e.Graphics.ResetTransform();
The reason why I mention this is , most post missed one point, that you need to translate your axis first, before you do the rotate. cause by default, rotate transform is roate the axis base on Point(0,0), if you don't translate your axis to the position where you want to draw your string, then most of the time, you will not be able to find the string you just drew, cause it is out of range. 

2.In my case, the other challenge is how to draw on multiple platform(WPF, GDI+ and Word), I use an interface to abstract the underlying drawing functionality. 


Sunday, March 13, 2011

How to setup Form Authentication Service through WCF

These few days, I am trying to implement something based on my own interest. And I would like to host my business logic on my server. So Obviously WCF is a good choice.  but I was thinking how can I make sure that my service can be only accessed by legitimate users instead of everyone, then I thought of Form Authentication, and it turns out Microsoft already provide a solution for this.

http://msdn.microsoft.com/en-us/library/bb386582.aspx

Given the fact that there are already pretty much articles about this topic on internet, I just want to write what I had been through.

  1. When you invoke the authentication service, if you get an error message say that the service is disabled. Make sure that the following few lines exist in your web.config file, and enabled has been set to true.
  2. <system.web.extensions>
       <scripting>
         <webServices>
           <authenticationService enabled="true"
            requireSSL = "false"/>
         </webServices>
       </scripting>
    </system.web.extensions>

  3. Why IsLoggedIn function always return false, even right after login. 

Check your local config file, to make sure that allowCookies option had been turned on.

    3.  For all the service that protected by form authentication, when you call those services, make sure you had passed in the form cookie. otherwise , you will be kicked out.

Monday, March 7, 2011

An interesting interview question, How to store an grid of which each dimension has more than 1m elements

One of my friend , he went to an interview, during the interview he was asked, if we have a grid , both x and y dimension have 1 million elements,  what kind of data structure you will use? Given the left top position of a view port , we also know the width and height of the view port, how we can quickly figure out those nodes in the viewport?

I was thinking this these few days, assume each node in the grid, we need to persist it's x axis and y axis,
public struct Node
{
     int x;
     int y;
}
each node need at least 8 bytes in memory, put the memory alignment aside , don't worry about it at this moment, for an 1million * 1million grid, if we store all the nodes in memory, how big it will be,
Total =  1million * 1million * 8 /1024/1024/1024 GB
         =  7450.58GB
so, obviously , it is not possible to store the whole grid in memory, we have to break down the grid to small grids.Assume the size of the view port is 1024 * 768, I will say each small grid, the size is 1024 * 768, a view port.

Based on this , we can break down the big grid to a small one, I will call it page grid, but each cell in the grid, pointing to another grid, which is exactly the size of one view port, I call it a page, sorry, I borrow this idea from database .

x:0-1024
y:0-768

x:1024-2048
y:0-768

x:2048-3072
y:0-768

x:3072 - 4096
y:0-768

......

x:0-1024
y:768-1536

x:1024-2048
y:768-1536

x:2048-3072
y:768-1536

x:3072 - 4096
y:768-1536

......

....

....

....

....

......

The width of this new grid is 1million / 1024 = 977
The height of this grid is 1million / 768 = 1303

The data of each cell on above grid will be store on hard disk, based on the left top position of the view port, we can easily identify data in which cell we need to access.  the formula is quite simple
maximum we will need to load in four cells of data.  think about it.

In this way, the is not too big anymore, so we don't need to bother whether to use linked list or binary tree,  or whatever,  for linked list, it is not design for fast search, it is for easy expandable. while binary tree, it good for search, but maintenance cost is very high. obviously we need to balance

while in this case , I will say , use an array or a hash map to persist the page grid, which is easy to search and maintain.