ch17s03.html
51 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>Canvas graphs</title><link rel="stylesheet" type="text/css" href="manual.css"><meta name="generator" content="DocBook XSL Stylesheets V1.76.0"><link rel="home" href="index.html" title="JpGraph Manual"><link rel="up" href="ch17.html" title="Chapter 17. Additional graph types"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">Canvas graphs</th></tr><tr><td width="20%" align="left"> </td><th width="60%" align="center">Chapter 17. Additional graph types</th><td width="20%" align="right"> </td></tr></table><hr></div><div class="sect1" title="Canvas graphs"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="sec.canvas-graph"></a>Canvas graphs</h2></div></div></div>
<p>This is basically a free form blank canvas where any graphics can be drawn. Canvas
graphs area also used as the basic graph for graphic tables as described in <a class="xref" href="ch19.html" title="Chapter 19. Graphical tables">Chapter 19. <i>Graphical tables</i></a></p>
<p>The library provides two module files to aid with this
"j<code class="filename">pgraph_canvas.php</code>" and
"<code class="filename">jpgraph_canvtools.php</code>". The second module is strictly speaking
not necessary but provides a number of utility classes that makes it much easier to work
with canvas.</p>
<p>Canvas graphs is provided as a layer to make is easier to create arbitrary images and
still make use of some of the convenience methods available in the library (like font
and color support). </p>
<p>Canvas graphs makes it easy to use the low level graphic drawing primitives in the
library provided by the two classes </p>
<p>
</p><div class="orderedlist"><ol class="orderedlist" type="1"><li class="listitem">
<p><code class="code">class Image</code></p>
<p>This is the basic low level class that encapsulates the GD library by
providing a complete framework for using graphic primitives with a coherent
API and many convenience methods.</p>
</li><li class="listitem">
<p><code class="code">class RotImage</code></p>
<p>This is a descendant of class Image that in addition to the basic
primitives also provides support for rotation of graphs</p>
</li></ol></div><p>
</p>
<p>It is possible to work at different levels of abstraction when creating a
canvas.</p>
<p>
</p><div class="orderedlist"><ol class="orderedlist" type="1"><li class="listitem">
<p>By only using the basic Image and RotImage classes. This can be considered
one abstraction level above the most basic GD libraries</p>
</li><li class="listitem">
<p>By making use of the functionality provided by <code class="code">class
CanvasGraph</code> and the supporting classes (e.g. <code class="code">class
CanvasScale</code>). By using the canvas scale class it is possible to
defining a coordinate grid on the canvas. These coordinates can then be used
instead of absolute pixels which is necessary to us ethe basic Image and
RotImage classes.</p>
</li></ol></div><p>
</p>
<p>A concrete example of how canvas graphs can be used can be seen in <a class="xref" href="ch08s02.html#fig.listfontsex1" title="Figure 8.1. List of all latin TTF fonts. (listfontsex1.php)">Figure 8.1. List of all latin TTF fonts. <code class="uri"><a class="uri" href="example_src/listfontsex1.html" target="_top">(<code class="filename">listfontsex1.php</code>)</a></code> </a> where all the available fonts have been drawn on a
canvas.</p>
<div class="sect2" title="Creating a simple canvas"><div class="titlepage"><div><div><h3 class="title"><a name="id2578744"></a>Creating a simple canvas</h3></div></div></div>
<p>Creating a canvas gives you the opportunity draw arbitrary shapes on a "white"
piece of paper. Let's first show a simple example were we just draw a text box. </p>
<p>
</p><div class="example"><a name="example.canvasex01"></a><p class="title"><b>Example 17.1. A simple canvas graph to draw a text box (<code class="filename">canvasex01.php</code>) </b></p><div class="example-contents"> <div class="hl-main"><table class="hl-table" width="100%"><tr><td class="hl-gutter" align="right" valign="top"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
</pre></td><td class="hl-main" valign="top"><pre><span class="hl-inlinetags"><?php</span><span class="hl-code"> </span><span class="hl-comment">//</span><span class="hl-comment"> content="text/plain; charset=utf-8"</span><span class="hl-comment"></span><span class="hl-code">
</span><span class="hl-comment">//</span><span class="hl-comment"> </span><span class="hl-inlinedoc">$Id: canvasex01.php,v 1.3 2002/10/23 08:17:23 aditus Exp $</span><span class="hl-comment"></span><span class="hl-code">
</span><span class="hl-reserved">require_once</span><span class="hl-code"> </span><span class="hl-brackets">(</span><span class="hl-quotes">'</span><span class="hl-string">jpgraph/jpgraph.php</span><span class="hl-quotes">'</span><span class="hl-brackets">)</span><span class="hl-code">;
</span><span class="hl-reserved">require_once</span><span class="hl-code"> </span><span class="hl-brackets">(</span><span class="hl-quotes">'</span><span class="hl-string">jpgraph/jpgraph_canvas.php</span><span class="hl-quotes">'</span><span class="hl-brackets">)</span><span class="hl-code">;
</span><span class="hl-comment">//</span><span class="hl-comment"> Setup a basic canvas we can work </span><span class="hl-comment"></span><span class="hl-code">
</span><span class="hl-var">$g</span><span class="hl-code"> = </span><span class="hl-reserved">new</span><span class="hl-code"> </span><span class="hl-identifier">CanvasGraph</span><span class="hl-brackets">(</span><span class="hl-number">400</span><span class="hl-code">,</span><span class="hl-number">300</span><span class="hl-code">,</span><span class="hl-quotes">'</span><span class="hl-string">auto</span><span class="hl-quotes">'</span><span class="hl-brackets">)</span><span class="hl-code">;
</span><span class="hl-var">$g</span><span class="hl-code">-></span><span class="hl-identifier">SetMargin</span><span class="hl-brackets">(</span><span class="hl-number">5</span><span class="hl-code">,</span><span class="hl-number">11</span><span class="hl-code">,</span><span class="hl-number">6</span><span class="hl-code">,</span><span class="hl-number">11</span><span class="hl-brackets">)</span><span class="hl-code">;
</span><span class="hl-var">$g</span><span class="hl-code">-></span><span class="hl-identifier">SetShadow</span><span class="hl-brackets">(</span><span class="hl-brackets">)</span><span class="hl-code">;
</span><span class="hl-var">$g</span><span class="hl-code">-></span><span class="hl-identifier">SetMarginColor</span><span class="hl-brackets">(</span><span class="hl-quotes">"</span><span class="hl-string">teal</span><span class="hl-quotes">"</span><span class="hl-brackets">)</span><span class="hl-code">;
</span><span class="hl-comment">//</span><span class="hl-comment"> We need to stroke the plotarea and margin before we add the</span><span class="hl-comment"></span><span class="hl-code">
</span><span class="hl-comment">//</span><span class="hl-comment"> text since we otherwise would overwrite the text.</span><span class="hl-comment"></span><span class="hl-code">
</span><span class="hl-var">$g</span><span class="hl-code">-></span><span class="hl-identifier">InitFrame</span><span class="hl-brackets">(</span><span class="hl-brackets">)</span><span class="hl-code">;
</span><span class="hl-comment">//</span><span class="hl-comment"> Draw a text box in the middle</span><span class="hl-comment"></span><span class="hl-code">
</span><span class="hl-var">$txt</span><span class="hl-code">=</span><span class="hl-quotes">"</span><span class="hl-string">This</span><span class="hl-special">\n</span><span class="hl-string">is</span><span class="hl-special">\n</span><span class="hl-string">a TEXT!!!</span><span class="hl-quotes">"</span><span class="hl-code">;
</span><span class="hl-var">$t</span><span class="hl-code"> = </span><span class="hl-reserved">new</span><span class="hl-code"> </span><span class="hl-identifier">Text</span><span class="hl-brackets">(</span><span class="hl-var">$txt</span><span class="hl-code">,</span><span class="hl-number">200</span><span class="hl-code">,</span><span class="hl-number">10</span><span class="hl-brackets">)</span><span class="hl-code">;
</span><span class="hl-var">$t</span><span class="hl-code">-></span><span class="hl-identifier">SetFont</span><span class="hl-brackets">(</span><span class="hl-identifier">FF_ARIAL</span><span class="hl-code">,</span><span class="hl-identifier">FS_BOLD</span><span class="hl-code">,</span><span class="hl-number">40</span><span class="hl-brackets">)</span><span class="hl-code">;
</span><span class="hl-comment">//</span><span class="hl-comment"> How should the text box interpret the coordinates?</span><span class="hl-comment"></span><span class="hl-code">
</span><span class="hl-var">$t</span><span class="hl-code">-></span><span class="hl-identifier">Align</span><span class="hl-brackets">(</span><span class="hl-quotes">'</span><span class="hl-string">center</span><span class="hl-quotes">'</span><span class="hl-code">,</span><span class="hl-quotes">'</span><span class="hl-string">top</span><span class="hl-quotes">'</span><span class="hl-brackets">)</span><span class="hl-code">;
</span><span class="hl-comment">//</span><span class="hl-comment"> How should the paragraph be aligned?</span><span class="hl-comment"></span><span class="hl-code">
</span><span class="hl-var">$t</span><span class="hl-code">-></span><span class="hl-identifier">ParagraphAlign</span><span class="hl-brackets">(</span><span class="hl-quotes">'</span><span class="hl-string">center</span><span class="hl-quotes">'</span><span class="hl-brackets">)</span><span class="hl-code">;
</span><span class="hl-comment">//</span><span class="hl-comment"> Add a box around the text, white fill, black border and gray shadow</span><span class="hl-comment"></span><span class="hl-code">
</span><span class="hl-var">$t</span><span class="hl-code">-></span><span class="hl-identifier">SetBox</span><span class="hl-brackets">(</span><span class="hl-quotes">"</span><span class="hl-string">white</span><span class="hl-quotes">"</span><span class="hl-code">,</span><span class="hl-quotes">"</span><span class="hl-string">black</span><span class="hl-quotes">"</span><span class="hl-code">,</span><span class="hl-quotes">"</span><span class="hl-string">gray</span><span class="hl-quotes">"</span><span class="hl-brackets">)</span><span class="hl-code">;
</span><span class="hl-comment">//</span><span class="hl-comment"> Stroke the text</span><span class="hl-comment"></span><span class="hl-code">
</span><span class="hl-var">$t</span><span class="hl-code">-></span><span class="hl-identifier">Stroke</span><span class="hl-brackets">(</span><span class="hl-var">$g</span><span class="hl-code">-></span><span class="hl-identifier">img</span><span class="hl-brackets">)</span><span class="hl-code">;
</span><span class="hl-comment">//</span><span class="hl-comment"> Stroke the graph</span><span class="hl-comment"></span><span class="hl-code">
</span><span class="hl-var">$g</span><span class="hl-code">-></span><span class="hl-identifier">Stroke</span><span class="hl-brackets">(</span><span class="hl-brackets">)</span><span class="hl-code">;
</span><span class="hl-inlinetags">?></span></pre></td></tr></table></div></div></div><p><br class="example-break"> </p><div class="figure"><a name="fig.canvasex01"></a><p class="title"><b>Figure 17.22. A simple canvas graph to draw a text box <code class="uri"><a class="uri" href="example_src/canvasex01.html" target="_top">(<code class="filename">canvasex01.php</code>)</a></code> </b></p><div class="figure-contents"> <span class="inlinemediaobject"><img src="images/canvasex01.png" alt="A simple canvas graph to draw a text box (canvasex01.php)"></span> </div></div><p><br class="figure-break">
</p>
<p>The example in <a class="xref" href="ch17s03.html#fig.canvasex01" title="Figure 17.22. A simple canvas graph to draw a text box (canvasex01.php)">Figure 17.22. A simple canvas graph to draw a text box <code class="uri"><a class="uri" href="example_src/canvasex01.html" target="_top">(<code class="filename">canvasex01.php</code>)</a></code> </a> starts by creating a 400x200
sized image. </p>
<p>The margins are then set to to get a frame around the image. </p>
<p>For canvases the margins has no effect in the way coordinates are entered. Top
left is (0,0) and bottom right (including any potential margin and shadow) is the
maximum. In this case the coordinate range are X:0-399, and Y:0-199</p>
<p>The <code class="code">InitFrame()</code> method is then called which actually strokes the
margin and plotarea to the graph. Since everything is stroked in the order the
commands are given it is necessary to make sure that the graphical objects that
should be on top are stroked last. This is different from the other graph types
since they will hide these details and stroke the details in the graph in the
correct order. </p>
<p>We then create a Text object, setup it's properties, including the absolute screen
position where we want the text, and then stroke it. </p>
<p>The <code class="code">Text::Align()</code> method specifies the anchor point of the text as
explained in <a class="xref" href="ch08.html" title="Chapter 8. Text and font handling">Chapter 8. <i>Text and font handling</i></a></p>
<p>We also specify that the lines within the paragraph should be centered with a call
to <code class="code">Text::ParagraphAlign()</code> Since we also choose to have a box around the
text we have to make use of the method <code class="code">Text::SetBox()</code> which is used to
specify the fill color, the border color and the shadow color (if the shadow color
is set to '', no shadow will be used).</p>
<p>Now we are ready to stroke the text onto the canvas. In order to do so we must
specify the graphical context when stroking the text. The current graphic context is
always available in the "<code class="code">$img</code>" property of the CanvasGraph
class.</p>
<p>This specification of the graphical context is needed to all Stroke method that is
external to the main graph class.</p>
</div>
<div class="sect2" title="Adding lines and rectangles to a canvas"><div class="titlepage"><div><div><h3 class="title"><a name="id2578750"></a>Adding lines and rectangles to a canvas</h3></div></div></div>
<p>A canvas also makes a good background for using standard graphic primitives, for
example circles and lines. The first thing to remember is that this requires working
with absolute screen coordinates and secondly that all drawing primitives are found
in the Image Class accessible as a property of the Graph class. </p>
<p>This means that to draw a line between absolute coordinates (0,0) and (100,100)
the following code must be created</p>
<p>
</p><div class="hl-main"><table class="hl-table" width="100%"><tr><td class="hl-gutter" align="right" valign="top"><pre>1
</pre></td><td class="hl-main" valign="top"><pre><span class="hl-code">$graph->img->Line(0, 0, 100, 100);</span></pre></td></tr></table></div><p>
</p>
<p>The following example shows how to create some basic graphic shapes on a
canvas</p>
<p>
</p><div class="example"><a name="example.canvasex02"></a><p class="title"><b>Example 17.2. Drawing some basic geometric shapes on a canvas (<code class="filename">canvasex02.php</code>) </b></p><div class="example-contents"> <div class="hl-main"><table class="hl-table" width="100%"><tr><td class="hl-gutter" align="right" valign="top"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
</pre></td><td class="hl-main" valign="top"><pre><span class="hl-inlinetags"><?php</span><span class="hl-code"> </span><span class="hl-comment">//</span><span class="hl-comment"> content="text/plain; charset=utf-8"</span><span class="hl-comment"></span><span class="hl-code">
</span><span class="hl-comment">//</span><span class="hl-comment"> </span><span class="hl-inlinedoc">$Id: canvasex02.php,v 1.1 2002/08/27 20:08:57 aditus Exp $</span><span class="hl-comment"></span><span class="hl-code">
</span><span class="hl-reserved">require_once</span><span class="hl-code"> </span><span class="hl-brackets">(</span><span class="hl-quotes">'</span><span class="hl-string">jpgraph/jpgraph.php</span><span class="hl-quotes">'</span><span class="hl-brackets">)</span><span class="hl-code">;
</span><span class="hl-reserved">require_once</span><span class="hl-code"> </span><span class="hl-brackets">(</span><span class="hl-quotes">'</span><span class="hl-string">jpgraph/jpgraph_canvas.php</span><span class="hl-quotes">'</span><span class="hl-brackets">)</span><span class="hl-code">;
</span><span class="hl-comment">//</span><span class="hl-comment"> Setup a basic canvas we can work </span><span class="hl-comment"></span><span class="hl-code">
</span><span class="hl-var">$g</span><span class="hl-code"> = </span><span class="hl-reserved">new</span><span class="hl-code"> </span><span class="hl-identifier">CanvasGraph</span><span class="hl-brackets">(</span><span class="hl-number">400</span><span class="hl-code">,</span><span class="hl-number">200</span><span class="hl-code">,</span><span class="hl-quotes">'</span><span class="hl-string">auto</span><span class="hl-quotes">'</span><span class="hl-brackets">)</span><span class="hl-code">;
</span><span class="hl-var">$g</span><span class="hl-code">-></span><span class="hl-identifier">SetMargin</span><span class="hl-brackets">(</span><span class="hl-number">5</span><span class="hl-code">,</span><span class="hl-number">11</span><span class="hl-code">,</span><span class="hl-number">6</span><span class="hl-code">,</span><span class="hl-number">11</span><span class="hl-brackets">)</span><span class="hl-code">;
</span><span class="hl-var">$g</span><span class="hl-code">-></span><span class="hl-identifier">SetShadow</span><span class="hl-brackets">(</span><span class="hl-brackets">)</span><span class="hl-code">;
</span><span class="hl-var">$g</span><span class="hl-code">-></span><span class="hl-identifier">SetMarginColor</span><span class="hl-brackets">(</span><span class="hl-quotes">"</span><span class="hl-string">teal</span><span class="hl-quotes">"</span><span class="hl-brackets">)</span><span class="hl-code">;
</span><span class="hl-comment">//</span><span class="hl-comment"> We need to stroke the plotarea and margin before we add the</span><span class="hl-comment"></span><span class="hl-code">
</span><span class="hl-comment">//</span><span class="hl-comment"> text since we otherwise would overwrite the text.</span><span class="hl-comment"></span><span class="hl-code">
</span><span class="hl-var">$g</span><span class="hl-code">-></span><span class="hl-identifier">InitFrame</span><span class="hl-brackets">(</span><span class="hl-brackets">)</span><span class="hl-code">;
</span><span class="hl-comment">//</span><span class="hl-comment"> Add a black line</span><span class="hl-comment"></span><span class="hl-code">
</span><span class="hl-var">$g</span><span class="hl-code">-></span><span class="hl-identifier">img</span><span class="hl-code">-></span><span class="hl-identifier">SetColor</span><span class="hl-brackets">(</span><span class="hl-quotes">'</span><span class="hl-string">black</span><span class="hl-quotes">'</span><span class="hl-brackets">)</span><span class="hl-code">;
</span><span class="hl-var">$g</span><span class="hl-code">-></span><span class="hl-identifier">img</span><span class="hl-code">-></span><span class="hl-identifier">Line</span><span class="hl-brackets">(</span><span class="hl-number">0</span><span class="hl-code">,</span><span class="hl-number">0</span><span class="hl-code">,</span><span class="hl-number">100</span><span class="hl-code">,</span><span class="hl-number">100</span><span class="hl-brackets">)</span><span class="hl-code">;
</span><span class="hl-comment">//</span><span class="hl-comment"> .. and a circle (x,y,diameter)</span><span class="hl-comment"></span><span class="hl-code">
</span><span class="hl-var">$g</span><span class="hl-code">-></span><span class="hl-identifier">img</span><span class="hl-code">-></span><span class="hl-identifier">Circle</span><span class="hl-brackets">(</span><span class="hl-number">100</span><span class="hl-code">,</span><span class="hl-number">100</span><span class="hl-code">,</span><span class="hl-number">50</span><span class="hl-brackets">)</span><span class="hl-code">;
</span><span class="hl-comment">//</span><span class="hl-comment"> .. and a filled circle (x,y,diameter)</span><span class="hl-comment"></span><span class="hl-code">
</span><span class="hl-var">$g</span><span class="hl-code">-></span><span class="hl-identifier">img</span><span class="hl-code">-></span><span class="hl-identifier">SetColor</span><span class="hl-brackets">(</span><span class="hl-quotes">'</span><span class="hl-string">red</span><span class="hl-quotes">'</span><span class="hl-brackets">)</span><span class="hl-code">;
</span><span class="hl-var">$g</span><span class="hl-code">-></span><span class="hl-identifier">img</span><span class="hl-code">-></span><span class="hl-identifier">FilledCircle</span><span class="hl-brackets">(</span><span class="hl-number">200</span><span class="hl-code">,</span><span class="hl-number">100</span><span class="hl-code">,</span><span class="hl-number">50</span><span class="hl-brackets">)</span><span class="hl-code">;
</span><span class="hl-comment">//</span><span class="hl-comment"> .. add a rectangle</span><span class="hl-comment"></span><span class="hl-code">
</span><span class="hl-var">$g</span><span class="hl-code">-></span><span class="hl-identifier">img</span><span class="hl-code">-></span><span class="hl-identifier">SetColor</span><span class="hl-brackets">(</span><span class="hl-quotes">'</span><span class="hl-string">green</span><span class="hl-quotes">'</span><span class="hl-brackets">)</span><span class="hl-code">;
</span><span class="hl-var">$g</span><span class="hl-code">-></span><span class="hl-identifier">img</span><span class="hl-code">-></span><span class="hl-identifier">FilledRectangle</span><span class="hl-brackets">(</span><span class="hl-number">10</span><span class="hl-code">,</span><span class="hl-number">10</span><span class="hl-code">,</span><span class="hl-number">50</span><span class="hl-code">,</span><span class="hl-number">50</span><span class="hl-brackets">)</span><span class="hl-code">;
</span><span class="hl-comment">//</span><span class="hl-comment"> .. add a filled rounded rectangle</span><span class="hl-comment"></span><span class="hl-code">
</span><span class="hl-var">$g</span><span class="hl-code">-></span><span class="hl-identifier">img</span><span class="hl-code">-></span><span class="hl-identifier">SetColor</span><span class="hl-brackets">(</span><span class="hl-quotes">'</span><span class="hl-string">green</span><span class="hl-quotes">'</span><span class="hl-brackets">)</span><span class="hl-code">;
</span><span class="hl-var">$g</span><span class="hl-code">-></span><span class="hl-identifier">img</span><span class="hl-code">-></span><span class="hl-identifier">FilledRoundedRectangle</span><span class="hl-brackets">(</span><span class="hl-number">300</span><span class="hl-code">,</span><span class="hl-number">30</span><span class="hl-code">,</span><span class="hl-number">350</span><span class="hl-code">,</span><span class="hl-number">80</span><span class="hl-code">,</span><span class="hl-number">10</span><span class="hl-brackets">)</span><span class="hl-code">;
</span><span class="hl-comment">//</span><span class="hl-comment"> .. with a darker border</span><span class="hl-comment"></span><span class="hl-code">
</span><span class="hl-var">$g</span><span class="hl-code">-></span><span class="hl-identifier">img</span><span class="hl-code">-></span><span class="hl-identifier">SetColor</span><span class="hl-brackets">(</span><span class="hl-quotes">'</span><span class="hl-string">darkgreen</span><span class="hl-quotes">'</span><span class="hl-brackets">)</span><span class="hl-code">;
</span><span class="hl-var">$g</span><span class="hl-code">-></span><span class="hl-identifier">img</span><span class="hl-code">-></span><span class="hl-identifier">RoundedRectangle</span><span class="hl-brackets">(</span><span class="hl-number">300</span><span class="hl-code">,</span><span class="hl-number">30</span><span class="hl-code">,</span><span class="hl-number">350</span><span class="hl-code">,</span><span class="hl-number">80</span><span class="hl-code">,</span><span class="hl-number">10</span><span class="hl-brackets">)</span><span class="hl-code">;
</span><span class="hl-comment">//</span><span class="hl-comment"> Stroke the graph</span><span class="hl-comment"></span><span class="hl-code">
</span><span class="hl-var">$g</span><span class="hl-code">-></span><span class="hl-identifier">Stroke</span><span class="hl-brackets">(</span><span class="hl-brackets">)</span><span class="hl-code">;
</span><span class="hl-inlinetags">?></span></pre></td></tr></table></div></div></div><p><br class="example-break"> </p><div class="figure"><a name="fig.canvasex02"></a><p class="title"><b>Figure 17.23. Drawing some basic geometric shapes on a canvas <code class="uri"><a class="uri" href="example_src/canvasex02.html" target="_top">(<code class="filename">canvasex02.php</code>)</a></code> </b></p><div class="figure-contents"> <span class="inlinemediaobject"><img src="images/canvasex02.png" alt="Drawing some basic geometric shapes on a canvas (canvasex02.php)"></span> </div></div><p><br class="figure-break">
</p>
</div>
<div class="sect2" title="Using a canvas scale together with the shape class"><div class="titlepage"><div><div><h3 class="title"><a name="id2578860"></a>Using a canvas scale together with the shape class</h3></div></div></div>
<p>The previous method using absolute coordinates works. But it gives very little
flexibility in, for example, scaling the image. Working with absolute coordinates is
therefore not very practical and gets tedious for complex figures.</p>
<p>To mitigate these issues the library offers a convenience class, <code class="code">class
CanvasScale</code>, this will allow the creation of a suitable scale that will
make it easier to both create and scale the graph.</p>
<p>In order to use a canvas scale the module
"<code class="filename">jpgraph_canvtools.php</code>" must first be included. In addition
to the canvas scale class this module also provides the companion <code class="code">Shape</code>
class. This companion shape class is used to draw shapes using the specified scale
onto the canvas. </p>
<p>Using the scale is quite simple and requires only two steps</p>
<p>
</p><div class="orderedlist"><ol class="orderedlist" type="1"><li class="listitem">
<p>An instance of the scale class is first created with the CanvasGraph
instance as the first parameter</p>
</li><li class="listitem">
<p>The wanted scale is then specified with the wanted x and y
scales</p>
</li></ol></div><p>
</p>
<p>The following code snippet shows how this is done</p>
<p>
</p><div class="hl-main"><table class="hl-table" width="100%"><tr><td class="hl-gutter" align="right" valign="top"><pre>1
2
3
4
5
6
7
8
9
10
11
</pre></td><td class="hl-main" valign="top"><pre><span class="hl-inlinetags"><?php</span><span class="hl-code">
</span><span class="hl-var">$graph</span><span class="hl-code"> = </span><span class="hl-identifier">CanvasGraph</span><span class="hl-brackets">(</span><span class="hl-number">400</span><span class="hl-code">,</span><span class="hl-number">300</span><span class="hl-brackets">)</span><span class="hl-code">;
</span><span class="hl-comment">//</span><span class="hl-comment"> ... other canvas formatting</span><span class="hl-comment"></span><span class="hl-code">
</span><span class="hl-comment">//</span><span class="hl-comment"> Create a new scale</span><span class="hl-comment"></span><span class="hl-code">
</span><span class="hl-var">$scale</span><span class="hl-code"> = </span><span class="hl-reserved">new</span><span class="hl-code"> </span><span class="hl-identifier">CanvasScale</span><span class="hl-brackets">(</span><span class="hl-code"> </span><span class="hl-var">$graph</span><span class="hl-code"> </span><span class="hl-brackets">)</span><span class="hl-code">;
</span><span class="hl-var">$scale</span><span class="hl-code">-></span><span class="hl-identifier">Set</span><span class="hl-brackets">(</span><span class="hl-var">$xmin</span><span class="hl-code">, </span><span class="hl-var">$xmax</span><span class="hl-code">, </span><span class="hl-var">$ymin</span><span class="hl-code">, </span><span class="hl-var">$ymax</span><span class="hl-brackets">)</span><span class="hl-code">;
</span><span class="hl-comment">//</span><span class="hl-comment"> ...</span><span class="hl-comment"></span><span class="hl-code">
</span><span class="hl-inlinetags">?></span></pre></td></tr></table></div><p>
</p>
<p>The next step needed to be able to create geometric shapes is to create an
instance of class Shape and give the canvas graph and the scale as the two
parameters as the following line shows.</p>
<p>
</p><div class="hl-main"><table class="hl-table" width="100%"><tr><td class="hl-gutter" align="right" valign="top"><pre>1
2
3
</pre></td><td class="hl-main" valign="top"><pre><span class="hl-inlinetags"><?php</span><span class="hl-code">
</span><span class="hl-var">$shape</span><span class="hl-code"> = </span><span class="hl-reserved">new</span><span class="hl-code"> </span><span class="hl-identifier">Shape</span><span class="hl-brackets">(</span><span class="hl-var">$graph</span><span class="hl-code">, </span><span class="hl-var">$scale</span><span class="hl-brackets">)</span><span class="hl-code">;
</span><span class="hl-inlinetags">?></span></pre></td></tr></table></div><p>
</p>
<p>It is now possible to create arbitrary geometric shapes by using the provided
methods in the shape class. The shape class provides the following methods</p>
<p>
</p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem">
<p><code class="code">Shape::SetColor($aColor)</code></p>
</li><li class="listitem">
<p><code class="code">Shape::Line($x1,$y1,$x2,$y2)</code></p>
</li><li class="listitem">
<p><code class="code">Shape::Polygon($p,$aClosed=false)</code></p>
</li><li class="listitem">
<p><code class="code">Shape::FilledPolygon($p)</code></p>
</li><li class="listitem">
<p><code class="code">Shape::Bezier($p,$aSteps=40)</code></p>
</li><li class="listitem">
<p><code class="code">Shape::Rectangle($x1,$y1,$x2,$y2)</code></p>
</li><li class="listitem">
<p><code class="code">Shape::FilledRectangle($x1,$y1,$x2,$y2)</code></p>
</li><li class="listitem">
<p><code class="code">Shape::Circle($x1,$y1,$r)</code></p>
</li><li class="listitem">
<p><code class="code">Shape::FilledCircle($x1,$y1,$r)</code></p>
</li><li class="listitem">
<p><code class="code">Shape::RoundedRectangle($x1,$y1,$x2,$y2,$r=null)</code></p>
</li><li class="listitem">
<p><code class="code">Shape::FilledRoundedRectangle($x1,$y1,$x2,$y2,$r=null)</code></p>
</li><li class="listitem">
<p><code class="code">Shape::ShadowRectangle($x1,$y1,$x2,$y2,$fcolor=false,$shadow_width=null,$shadow_color=array(102,102,102))</code></p>
</li><li class="listitem">
<p><code class="code">Shape::SetTextAlign($halign,$valign="bottom")</code></p>
</li><li class="listitem">
<p><code class="code">Shape::StrokeText($x1,$y1,$txt,$dir=0,$paragraph_align="left")</code></p>
</li><li class="listitem">
<p><code class="code">Shape::
IndentedRectangle($xt,$yt,$w,$h,$iw=0,$ih=0,$aCorner=3,$aFillColor="",$r=4)</code></p>
</li></ul></div><p>
</p>
<p>We can now show a complete example of using the shape class</p>
<p>
</p><div class="example"><a name="example.canvasex03"></a><p class="title"><b>Example 17.3. Creating a canvas graph with a scale and using the shape class (<code class="filename">canvasex03.php</code>) </b></p><div class="example-contents"> <div class="hl-main"><table class="hl-table" width="100%"><tr><td class="hl-gutter" align="right" valign="top"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
</pre></td><td class="hl-main" valign="top"><pre><span class="hl-inlinetags"><?php</span><span class="hl-code"> </span><span class="hl-comment">//</span><span class="hl-comment"> content="text/plain; charset=utf-8"</span><span class="hl-comment"></span><span class="hl-code">
</span><span class="hl-comment">//</span><span class="hl-comment"> </span><span class="hl-inlinedoc">$Id: canvasex03.php,v 1.1 2002/08/27 20:08:57 aditus Exp $</span><span class="hl-comment"></span><span class="hl-code">
</span><span class="hl-reserved">require_once</span><span class="hl-code"> </span><span class="hl-brackets">(</span><span class="hl-quotes">'</span><span class="hl-string">jpgraph/jpgraph.php</span><span class="hl-quotes">'</span><span class="hl-brackets">)</span><span class="hl-code">;
</span><span class="hl-reserved">require_once</span><span class="hl-code"> </span><span class="hl-brackets">(</span><span class="hl-quotes">'</span><span class="hl-string">jpgraph/jpgraph_canvas.php</span><span class="hl-quotes">'</span><span class="hl-brackets">)</span><span class="hl-code">;
</span><span class="hl-reserved">require_once</span><span class="hl-code"> </span><span class="hl-brackets">(</span><span class="hl-quotes">'</span><span class="hl-string">jpgraph/jpgraph_canvtools.php</span><span class="hl-quotes">'</span><span class="hl-brackets">)</span><span class="hl-code">;
</span><span class="hl-comment">//</span><span class="hl-comment"> Define work space</span><span class="hl-comment"></span><span class="hl-code">
</span><span class="hl-var">$xmax</span><span class="hl-code">=</span><span class="hl-number">20</span><span class="hl-code">;
</span><span class="hl-var">$ymax</span><span class="hl-code">=</span><span class="hl-number">20</span><span class="hl-code">;
</span><span class="hl-comment">//</span><span class="hl-comment"> Setup a basic canvas we can work </span><span class="hl-comment"></span><span class="hl-code">
</span><span class="hl-var">$g</span><span class="hl-code"> = </span><span class="hl-reserved">new</span><span class="hl-code"> </span><span class="hl-identifier">CanvasGraph</span><span class="hl-brackets">(</span><span class="hl-number">400</span><span class="hl-code">,</span><span class="hl-number">200</span><span class="hl-code">,</span><span class="hl-quotes">'</span><span class="hl-string">auto</span><span class="hl-quotes">'</span><span class="hl-brackets">)</span><span class="hl-code">;
</span><span class="hl-var">$g</span><span class="hl-code">-></span><span class="hl-identifier">SetMargin</span><span class="hl-brackets">(</span><span class="hl-number">5</span><span class="hl-code">,</span><span class="hl-number">11</span><span class="hl-code">,</span><span class="hl-number">6</span><span class="hl-code">,</span><span class="hl-number">11</span><span class="hl-brackets">)</span><span class="hl-code">;
</span><span class="hl-var">$g</span><span class="hl-code">-></span><span class="hl-identifier">SetShadow</span><span class="hl-brackets">(</span><span class="hl-brackets">)</span><span class="hl-code">;
</span><span class="hl-var">$g</span><span class="hl-code">-></span><span class="hl-identifier">SetMarginColor</span><span class="hl-brackets">(</span><span class="hl-quotes">"</span><span class="hl-string">teal</span><span class="hl-quotes">"</span><span class="hl-brackets">)</span><span class="hl-code">;
</span><span class="hl-comment">//</span><span class="hl-comment"> We need to stroke the plotarea and margin before we add the</span><span class="hl-comment"></span><span class="hl-code">
</span><span class="hl-comment">//</span><span class="hl-comment"> text since we otherwise would overwrite the text.</span><span class="hl-comment"></span><span class="hl-code">
</span><span class="hl-var">$g</span><span class="hl-code">-></span><span class="hl-identifier">InitFrame</span><span class="hl-brackets">(</span><span class="hl-brackets">)</span><span class="hl-code">;
</span><span class="hl-comment">//</span><span class="hl-comment"> Create a new scale</span><span class="hl-comment"></span><span class="hl-code">
</span><span class="hl-var">$scale</span><span class="hl-code"> = </span><span class="hl-reserved">new</span><span class="hl-code"> </span><span class="hl-identifier">CanvasScale</span><span class="hl-brackets">(</span><span class="hl-var">$g</span><span class="hl-brackets">)</span><span class="hl-code">;
</span><span class="hl-var">$scale</span><span class="hl-code">-></span><span class="hl-identifier">Set</span><span class="hl-brackets">(</span><span class="hl-number">0</span><span class="hl-code">,</span><span class="hl-var">$xmax</span><span class="hl-code">,</span><span class="hl-number">0</span><span class="hl-code">,</span><span class="hl-var">$ymax</span><span class="hl-brackets">)</span><span class="hl-code">;
</span><span class="hl-comment">//</span><span class="hl-comment"> The shape class is wrapper around the Imgae class which translates</span><span class="hl-comment"></span><span class="hl-code">
</span><span class="hl-comment">//</span><span class="hl-comment"> the coordinates for us</span><span class="hl-comment"></span><span class="hl-code">
</span><span class="hl-var">$shape</span><span class="hl-code"> = </span><span class="hl-reserved">new</span><span class="hl-code"> </span><span class="hl-identifier">Shape</span><span class="hl-brackets">(</span><span class="hl-var">$g</span><span class="hl-code">,</span><span class="hl-var">$scale</span><span class="hl-brackets">)</span><span class="hl-code">;
</span><span class="hl-var">$shape</span><span class="hl-code">-></span><span class="hl-identifier">SetColor</span><span class="hl-brackets">(</span><span class="hl-quotes">'</span><span class="hl-string">black</span><span class="hl-quotes">'</span><span class="hl-brackets">)</span><span class="hl-code">;
</span><span class="hl-comment">//</span><span class="hl-comment"> Add a black line</span><span class="hl-comment"></span><span class="hl-code">
</span><span class="hl-var">$shape</span><span class="hl-code">-></span><span class="hl-identifier">SetColor</span><span class="hl-brackets">(</span><span class="hl-quotes">'</span><span class="hl-string">black</span><span class="hl-quotes">'</span><span class="hl-brackets">)</span><span class="hl-code">;
</span><span class="hl-var">$shape</span><span class="hl-code">-></span><span class="hl-identifier">Line</span><span class="hl-brackets">(</span><span class="hl-number">0</span><span class="hl-code">,</span><span class="hl-number">0</span><span class="hl-code">,</span><span class="hl-number">20</span><span class="hl-code">,</span><span class="hl-number">20</span><span class="hl-brackets">)</span><span class="hl-code">;
</span><span class="hl-comment">//</span><span class="hl-comment"> .. and a circle (x,y,diameter)</span><span class="hl-comment"></span><span class="hl-code">
</span><span class="hl-var">$shape</span><span class="hl-code">-></span><span class="hl-identifier">Circle</span><span class="hl-brackets">(</span><span class="hl-number">5</span><span class="hl-code">,</span><span class="hl-number">14</span><span class="hl-code">,</span><span class="hl-number">2</span><span class="hl-brackets">)</span><span class="hl-code">;
</span><span class="hl-comment">//</span><span class="hl-comment"> .. and a filled circle (x,y,diameter)</span><span class="hl-comment"></span><span class="hl-code">
</span><span class="hl-var">$shape</span><span class="hl-code">-></span><span class="hl-identifier">SetColor</span><span class="hl-brackets">(</span><span class="hl-quotes">'</span><span class="hl-string">red</span><span class="hl-quotes">'</span><span class="hl-brackets">)</span><span class="hl-code">;
</span><span class="hl-var">$shape</span><span class="hl-code">-></span><span class="hl-identifier">FilledCircle</span><span class="hl-brackets">(</span><span class="hl-number">11</span><span class="hl-code">,</span><span class="hl-number">8</span><span class="hl-code">,</span><span class="hl-number">3</span><span class="hl-brackets">)</span><span class="hl-code">;
</span><span class="hl-comment">//</span><span class="hl-comment"> .. add a rectangle</span><span class="hl-comment"></span><span class="hl-code">
</span><span class="hl-var">$shape</span><span class="hl-code">-></span><span class="hl-identifier">SetColor</span><span class="hl-brackets">(</span><span class="hl-quotes">'</span><span class="hl-string">green</span><span class="hl-quotes">'</span><span class="hl-brackets">)</span><span class="hl-code">;
</span><span class="hl-var">$shape</span><span class="hl-code">-></span><span class="hl-identifier">FilledRectangle</span><span class="hl-brackets">(</span><span class="hl-number">15</span><span class="hl-code">,</span><span class="hl-number">8</span><span class="hl-code">,</span><span class="hl-number">19</span><span class="hl-code">,</span><span class="hl-number">14</span><span class="hl-brackets">)</span><span class="hl-code">;
</span><span class="hl-comment">//</span><span class="hl-comment"> .. add a filled rounded rectangle</span><span class="hl-comment"></span><span class="hl-code">
</span><span class="hl-var">$shape</span><span class="hl-code">-></span><span class="hl-identifier">SetColor</span><span class="hl-brackets">(</span><span class="hl-quotes">'</span><span class="hl-string">green</span><span class="hl-quotes">'</span><span class="hl-brackets">)</span><span class="hl-code">;
</span><span class="hl-var">$shape</span><span class="hl-code">-></span><span class="hl-identifier">FilledRoundedRectangle</span><span class="hl-brackets">(</span><span class="hl-number">2</span><span class="hl-code">,</span><span class="hl-number">3</span><span class="hl-code">,</span><span class="hl-number">8</span><span class="hl-code">,</span><span class="hl-number">6</span><span class="hl-brackets">)</span><span class="hl-code">;
</span><span class="hl-comment">//</span><span class="hl-comment"> .. with a darker border</span><span class="hl-comment"></span><span class="hl-code">
</span><span class="hl-var">$shape</span><span class="hl-code">-></span><span class="hl-identifier">SetColor</span><span class="hl-brackets">(</span><span class="hl-quotes">'</span><span class="hl-string">darkgreen</span><span class="hl-quotes">'</span><span class="hl-brackets">)</span><span class="hl-code">;
</span><span class="hl-var">$shape</span><span class="hl-code">-></span><span class="hl-identifier">RoundedRectangle</span><span class="hl-brackets">(</span><span class="hl-number">2</span><span class="hl-code">,</span><span class="hl-number">3</span><span class="hl-code">,</span><span class="hl-number">8</span><span class="hl-code">,</span><span class="hl-number">6</span><span class="hl-brackets">)</span><span class="hl-code">;
</span><span class="hl-comment">//</span><span class="hl-comment"> Stroke the graph</span><span class="hl-comment"></span><span class="hl-code">
</span><span class="hl-var">$g</span><span class="hl-code">-></span><span class="hl-identifier">Stroke</span><span class="hl-brackets">(</span><span class="hl-brackets">)</span><span class="hl-code">;
</span><span class="hl-inlinetags">?></span></pre></td></tr></table></div></div></div><p><br class="example-break"> </p><div class="figure"><a name="fig.canvasex03"></a><p class="title"><b>Figure 17.24. Creating a canvas graph with a scale and using the shape class <code class="uri"><a class="uri" href="example_src/canvasex03.html" target="_top">(<code class="filename">canvasex03.php</code>)</a></code> </b></p><div class="figure-contents"> <span class="inlinemediaobject"><img src="images/canvasex03.png" alt="Creating a canvas graph with a scale and using the shape class (canvasex03.php)"></span> </div></div><p><br class="figure-break">
</p>
<p>To show the usefulness of using the scale class <a class="xref" href="ch17s03.html#fig.canvasex04" title="Figure 17.25. Changing the image size to create a smaller version of the previous example (canvasex04.php)">Figure 17.25. Changing the image size to create a smaller version of the previous example <code class="uri"><a class="uri" href="example_src/canvasex04.html" target="_top">(<code class="filename">canvasex04.php</code>)</a></code> </a> shows the result after just changing the image size but keeping the code the
same. The relation between the shapes will remain the same but in a smaller format
to fit the new image size.</p>
<p>
</p><div class="figure"><a name="fig.canvasex04"></a><p class="title"><b>Figure 17.25. Changing the image size to create a smaller version of the previous example <code class="uri"><a class="uri" href="example_src/canvasex04.html" target="_top">(<code class="filename">canvasex04.php</code>)</a></code> </b></p><div class="figure-contents"> <span class="inlinemediaobject"><img src="images/canvasex04.png" alt="Changing the image size to create a smaller version of the previous example (canvasex04.php)"></span> </div></div><p><br class="figure-break">
</p>
<p>If we instead wanted to keep the image size but shrink the shapes we could just
make the scale twice as large which would result in <a class="xref" href="ch17s03.html#fig.canvasex05" title="Figure 17.26. Keeping the image size but changing the scale (canvasex05.php)">Figure 17.26. Keeping the image size but changing the scale <code class="uri"><a class="uri" href="example_src/canvasex05.html" target="_top">(<code class="filename">canvasex05.php</code>)</a></code> </a></p>
<p>
</p><div class="figure"><a name="fig.canvasex05"></a><p class="title"><b>Figure 17.26. Keeping the image size but changing the scale <code class="uri"><a class="uri" href="example_src/canvasex05.html" target="_top">(<code class="filename">canvasex05.php</code>)</a></code> </b></p><div class="figure-contents"> <span class="inlinemediaobject"><img src="images/canvasex05.png" alt="Keeping the image size but changing the scale (canvasex05.php)"></span> </div></div><p><br class="figure-break">
</p>
<p>We previously mentioned that the Shape class was a wrapper around the image class
with one exception. The exception is that it contains one additional method which
draws an "indented rectangle". An indented rectangle is a rectangle where one of
it's four corners have been moved into the rectangle <a class="xref" href="ch17s03.html#fig.canvasex06" title="Figure 17.27. Example of using an indented rectangle (canvasex06.php)">Figure 17.27. Example of using an indented rectangle <code class="uri"><a class="uri" href="example_src/canvasex06.html" target="_top">(<code class="filename">canvasex06.php</code>)</a></code> </a> shows an example of using this shape.</p>
<p>
</p><div class="figure"><a name="fig.canvasex06"></a><p class="title"><b>Figure 17.27. Example of using an indented rectangle <code class="uri"><a class="uri" href="example_src/canvasex06.html" target="_top">(<code class="filename">canvasex06.php</code>)</a></code> </b></p><div class="figure-contents"> <span class="inlinemediaobject"><img src="images/canvasex06.png" alt="Example of using an indented rectangle (canvasex06.php)"></span> </div></div><p><br class="figure-break">
</p>
<p>As a final note we mention the utility class <code class="code">class
CanvasRectangleText</code> This can be used to add a text with a rounded
rectangle (possibly filled) onto the canvas. <a class="xref" href="ch08s02.html#fig.listfontsex1" title="Figure 8.1. List of all latin TTF fonts. (listfontsex1.php)">Figure 8.1. List of all latin TTF fonts. <code class="uri"><a class="uri" href="example_src/listfontsex1.html" target="_top">(<code class="filename">listfontsex1.php</code>)</a></code> </a>
where all the available fonts were shown were using this class. </p>
</div>
</div><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"> </td><td width="20%" align="center"><a accesskey="u" href="ch17.html">Up</a></td><td width="40%" align="right"> </td></tr><tr><td width="40%" align="left" valign="top"> </td><td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td><td width="40%" align="right" valign="top"> </td></tr></table></div></body></html>