| by kirupa  |  
					23 September 2006
 I started covering 
					the interesting code from this project in the
					previous page. In 
					this page I will explain how the chart data is normalized 
					and plotted! One of my design goals was to make the chart be capable of 
					plotting a wide range of values. Like I mentioned earlier, 
					you are constrained by your chart's height and width, so you 
					will need to ensure that the highest and lowest values of 
					your chart display in a reasonably accurate scale.
 The following is the code that normalizes 
					the chart's height and width: 
						// Taking care of some 
						bookwork (declaring/initializing variables) int
						maxDataPoints
						= 
						points.Length; int
						chartHeight
						= bmp.Height
						- 
						bottomOffset; int
						chartWidth
						= bmp.Width
						- 
						rightOffset;   // Adjustable Values
						double
						adjustedMax
						= 
						maxValue * .10
						+ 
						maxValue; double
						adjustedMin
						= 
						minValue - .50
						* 
						minValue; double
						adjustVerticalRatio
						= (chartHeight-topOffset)
						/ 
						adjustedMax; double
						adjustHorizontalRatio
						= ((chartWidth
						- 
						leftOffset)
						/ (maxDataPoints
						- 1)); One good way of looking at this is via an 
					example. Let's say your maximum data point is 1000, and your 
					chart's height is 100 pixels. That means, for every pixel, 
					you have to cover 10 points of data so that you can display 
					your 1000-value data point. That also means that a value of 500, 
					will be 50 pixels high. Similarly, a data point that is 100, 
					will only be 10 pixels tall.  What you are trying to do is come up with a 
					good ratio between your chart's height and the number of 
					data values each pixel will cover. The ratio is, as shown 
					above, determined only by your maximum data point, and the 
					ratio is what the adjustVerticalRatio variable 
					stores. Likewise for the horizontal case, the 
					adjustHorizontalRatio variable stores the distance each 
					data point must be separated by in order to fill up the 
					horizontal space. Ideally, that would be the chart's width 
					divided by the number of data points. Notice in a lot of the above cases, I take 
					into account any vertical or horizontal offsets that you may 
					have introduced. To plot the lines, you first determine the starting and 
					ending X and Y positions. Because in order to draw any 
					lines, you need a starting point as well as an ending point. 
					In our case, since all the lines are interconnected, your 
					ending point for one line is the starting point for the next 
					line.
 The code for determining the two x and y 
					positions can be found below: 
						int
						xPos =
						Convert.ToInt32(i
						* 
						adjustHorizontalRatio)
						+ 
						leftOffset; int
						xPos2 
						= Convert.ToInt32((i
						+ 1)
						* 
						adjustHorizontalRatio)
						+ 
						leftOffset;   int
						yPos =
						Convert.ToInt32(chartHeight
						- 
						adjustVerticalRatio *
						points[i]);
						int
						yPos2 
						= Convert.ToInt32(chartHeight
						- 
						adjustVerticalRatio *
						points[i
						+ 1]); Some key things to note are how the earlier 
					adjustHorizontalRatio and adjustVerticalRatio values are 
					being used. Notice also that I am converting all of the 
					earlier data into integers, for as you will see in the next 
					line, the x and y positions are specified as a Point object that 
					only accepts integer values: 
						gfx.DrawLine(chartPen,
						new 
						Point(xPos,
						yPos),
						new 
						Point(xPos2,
						yPos2)); You will see 
					the Point class again when I explain how to draw border 
					lines in the next page. Onwards to the 
					next page! |