Programming dojox.chart(6) – gfx3d support added

Web September 30th, 2007

Area chart is not as popular as Column though, it is still commonly used in the business world to demonstrate the contribution from different categories, for example:
Area Chart

And further more, I decided to migrate the broken pie3d.js and bar3d.js to dojox.chart.Chart framework. The calcLayout of Column3d is still quite experimental, we may refactor it when theme concept is introduced:
Column3d Chart

The implementation of Pie3d is far less bullet-proof, and the BSP scheduler is quite computation-extensive; but I am impressed by the beauty of lighting effect, the color of Firefox is really gorgeous:
Pie3d Chart

In the next step, we would normalize the calcLayout using theme. Here is the code snapshot.

Programming dojox.chart(5) – Naive scientific plotting

Web September 29th, 2007

Logarithmic axis is quite important for the scientific plotting to demonstrate the exponential growth like infection of virus, possible a good candidate for viral marketing as well. Here is two examples based upon XYLine: XLogYLine with linear X axis and logarithmic Y axis and LogXLogYLine with logarithmic X,Y axes. Grid is added to help readability:
Linear X, Logarithmic Y chart
Logarithmic X, Logarithmic Y chart

Here is code snapshot.

Programming dojox.chart(4) – 2D Charts revised

Web September 26th, 2007

Basic 2D charts include the following types:

  • Column, the traditional chart to show the growth of the profile
  • Bar, the sister of Column
  • Pie, the favorite of marketing salesman
  • XYLine, commonly used in scientific computing

Just as the following screenshots demonstrates:
Column Chart
Bar Chart
Pie Chart
XYLines Chart
There are quite a few variants of the basic graphics:

  • Stacked Column/Bar, either normalized or not
  • logarithmic axes
  • 3D versions of all the above

The dojox.chart.Chart is the work horse behind the scene, there are only couple of functions that need to be overrided to support new chart:

  • constructor, binding the axes
  • getSeriesStyle, generate the styles for series if the user do not specify
  • _render, the ultimate method to visualize the data

You can fetch the code from here, it depends on dojo-0.9; and we are planning to migrate the 3D chart into this framework, you may bypass the bump of the road if you stick to the dojo-svn from the very beginning.

Optimize WordPress in another 4 steps

Web September 21st, 2007

I just moved out from Globat to a new place, Jumpline. It is a good time to clean the house, and throw out all trashes.

Enable WP-Cache + GZIP

Although the official WP-Cache suggests to disable GZIP support, there are some hacks(1, 2) to enable it. That is quite neat.

After this optimization, the total size of front page is 247.6K, 85.1K of that is JavaScript, the built-in prototype.js takes 71.2K. We should take some actions for it.

GZIP the JavaScript and Stylesheet

dailyApps suggests to dynamically gzip the stylesheet and JavaScript to reduce the HTTP download. jotsheet goes even further, a neat method is demonstrated to consolidate all the CSS/JavaScript into one to save the HTTP request.

For normal users, the big bottleneck is the size of prototype.js, and it is most unlikely change unless major version update. So let’s gzip it first and check out the performance boost:
Using Dojo ShrinkSafe, the prototype.js is cut to 49K, not bad.

Thanks to the flexibility of VDS powered by Jumpline, I could easily add mod_deflate to Apache, and enable mod_deflate globally to all CSS and JavaScript. Check out the doc for details.


AddOutputFilterByType DEFLATE text/javascript
AddOutputFilterByType DEFLATE application/x-javascript
AddOutputFilterByType DEFLATE text/css

This helps me to save tens of kilobytes, now the gzipped-shrunk protoype.js is 14.6K only, the overall improvement is gzipped 30.2K versus original 142.0K, that is quite impressive.

Use client-side cache

mod_expires just did the right work, load the module and enable it wherever the content would not change:

ExpiresActive On
ExpiresDefault A2592000

Remove ETag

Use these directive to disable ETag globally in httpd.conf:

Header unset ETag
FileETag None

I get B(87) with cache, A(95) without cache in YSlow performance score. The next step optimization may introduce CDN service, for example, Amazon S3.

Learning Django by Example(5): Time to Attack

Python, Web September 19th, 2007

In the last four section(1, 2, 3, 4) ,we have been familiar with the environment, it is time to do some real work.

I will add more fresh to models.py , linking eBook file and its meta data, thumbnail of the cover, regular size cover etc. Two other models are added for eBook:

class FileType(models.Model):
    type = models.CharField(maxlength=10)

class File(models.Model):
    type = models.ForeignKey(FileType)
    handle = models.FileField(upload_to="files")
    meta = models.ForeignKey(Book)

Book to File is one-to-many as one book may have more than one formats, a PDF version for print, a CHM version for reference.

To server the images of book covers, , we need to setup the MEDIA_ROOT and MEDIA_URL:

MEDIA_ROOT = ‘/home/share/eBooks/’
MEDIA_URL = ‘http://localhost:8000/repo/’

and setup the url mapping as well:

(r’^repo/(?P .*)$’, ‘django.views.static.serve’, {’document_root’: ‘/home/share/eBooks’}),

To save an image file, we can easily call save_FOO_file method, it works with two drawbacks: first, you need to read the image into the memory; second, it is synchronous function call aka it is blocked until the file is fetched, read and written. urlretrive is preferred in this way:

from django.conf import settings
from urllib import urlopen, unquote, urlretrieve
from urlparse import urlparse
from os import path
… …
                thumb = unquote(urlparse(item[‘thumburl’])[2].split(‘/’)[-1])
                # using hard-coded image temporary
                urlretrieve(item[‘thumburl’], path.join(settings.MEDIA_ROOT, ‘images’, thumb))
                book.thumb = path.join(‘images’, thumb);
                book.save()

A further optimization may introduce Twisted or asyncore.

More work needs to be done in the UI side: the Book objects are populated in brief or detail modes. Brief mode just highlight the title, cover, authors and ISBN of the book, commonly used in general listing, search results, my favorite and so on; while detail mode shows more detailed information like editorial review, related book, tags etc. It is worthy extracting the code snippet of brief mode to a template, so we can reuse it later by {% include book_item_brief.html %}. Detail view would fetch the editorial view from Amazon using the same AJAX hack as discussed before.

With stylesheet, it looks much better, Brief view:

Breif view



and Detail view:

Detail view



Check r30.