Some time ago we’ve been working on a project, which required some reports and charts. We used an embedded version of Firefox 3 beta to run a web ajax application on the desktop. They have included some cool new features like native SVG support, which after some initial testing turned out to be working pretty well. Canvas was way more tested at that time, there were tons of demos on the web including some quite complex animations and even minigames. I’ve been wondering for a while which technology to use and chose SVG.
The main reasons for that were two:
1 It’s vector based, which means you don’t have to worry about things like resizing, opacity and gradient calculations – the browser will do all that for you.
2 It uses the DOM – if you need to get the whole thing interactive it should be quite easy to attach events to DOM elements and manipulate their attributes in a very familiar manner (haven’t tried to do that yet)
So we had a pseudo 3D SVG bar chart working well in Firefox 3, which was not even declared stable yet …
When it came to printing it though things got a bit more complex. I wanted to reuse as much of the code as I could. The natural way to do it was to move the whole SVG specific part in a separate renderer class and access different renderers through some graphics abstraction layer interface. The chart wouldn’t know if it renders as SVG or communicates with the XPCOM GDI printing component as long as they maintain the same interface and I could add other graphics implementations at a later time (hopefully without touching the chart code).
The time came when we needed to use the same component in a pure web application. Some browsers wouldn’t support SVG, others (like Opera back then) would support it very badly. Fighting the problem with minimal efforts, I decided to write a serverside renderer and generate images on the server which I could later fetch and display (I’ll post about that soon).
Few days ago around the whole blog mania, a colleague showed me something working with VML in MSIE. It was worth trying to write a VML renderer since it’s supported on MSIE 5 or later and I needed to post something anyway … The end result was not as good as I expected – MSIE seems to render VML way slower than other browsers do SVG, it’s usable though. Had to do some workarounds, but as a whole no major obstacles appeared.
Some of the tricky parts that worth mentioning:
1) When you do a transformation on a shape in SVG it will rotate the gradient or whatever you fill it with also. VML doesn’t do it exactly the same way so I needed to add a parameter for it.
2) While SVG rotation is based at (0, 0) VML rotates the shape around it’s center and some calculations are needed to adjust the coordinates.
I added some VML/SVG browser capabilities detection code, few buttons that change the chart parameters and packed everything together. You can download the whole thing from here or see a demo here.

Some time ago we’ve been working on a project, which required some reports and charts. We used an embedded version of Firefox 3 beta to run a web ajax application on the desktop. They have included some cool new features like native SVG support, which after some initial testing turned out to be working pretty well. Canvas was way more tested at that time, there were tons of demos on the web including some quite complex animations and even minigames. I’ve been wondering for a while which technology to use and chose SVG.

The main reasons for that were two:

1 It’s vector based, which means you don’t have to worry about things like resizing, opacity and gradient calculations – the browser will do all that for you.

2 It uses the DOM – if you need to get the whole thing interactive it should be quite easy to attach events to DOM elements and manipulate their attributes in a very familiar manner (haven’t tried to do that yet)

So we had a pseudo 3D SVG bar chart working well in Firefox 3, which was not even declared stable yet …

When it came to printing it though things got a bit more complex. I wanted to reuse as much of the code as I could. The natural way to do it was to move the whole SVG specific part in a separate renderer class and access different renderers through some graphics abstraction layer interface. The chart wouldn’t know if it renders as SVG or communicates with the XPCOM GDI printing component as long as they maintain the same interface and I could add other graphics implementations at a later time (hopefully without touching the chart code).

The time came when we needed to use the same component in a pure web application. Some browsers wouldn’t support SVG, others (like Opera back then) would support it very badly. Fighting the problem with minimal efforts, I decided to write a serverside renderer and generate images on the server which I could later fetch and display (I’ll post about that soon).

Few days ago around the whole blog mania, a colleague showed me something working with VML in MSIE. It was worth trying to write a VML renderer since it’s supported on MSIE 5 or later and I needed to post something anyway… The end result was not as good as I expected – MSIE seems to render VML way slower than other browsers do SVG, it’s usable though. Had to do some workarounds, but as a whole no major obstacles appeared.

Some of the tricky parts that worth mentioning:

1 When you do a transformation on a shape in SVG it will rotate the gradient or whatever you fill it with also. VML doesn’t do it exactly the same way so I needed to add a parameter for it.

2 While SVG rotation is based at (0, 0) VML rotates the shape around it’s center and some calculations are needed to adjust the coordinates.

I added some VML/SVG browser capabilities detection code, few buttons that change the chart parameters and packed everything together. You can download the whole thing from here.

Some parameter explanations:

graphics=new Cnx.Graphics();
renderer=graphics.createPreferredRendererInstance(document.getElementById("chartDemo"), 600, 400);
if(renderer) {
	renderer.init();
	chart=new Cnx.Chart({
		values: [1, 3, 2, 5.5, 7, 4, 9, 10],									// bar values
		titles: ["entry 1", "entry 2", "entry 3", "entry 4", "entry 5", "entry 6", "entry 7", "entry 8"],	// bar titles
		style: "verticalBars",											// the only type of chart we have so far
		width: 600,
		height: 400,
		spaceTop: 50,												// padding
		spaceLeft: 80,
		spaceRight: 10,
		spaceBottom: 40,
		yCaption: "Rating",											// the caption for the y axis
		xCaption: "Entry",											// the caption for the x axis
		mainCaption: ["Entry ratings main caption", "Entry ratings main caption second line"],			// caption displayed over the chart (can be more than 1 line)
		mainCaptionFont: {fontFamily: "Verdana", fontSize: 20},
		axisVerticalMax: 11,											// max value for the y axis
		axisVerticalMin: 0,											// min value for the y axis
		axisVerticalValuesDisplay: [1, 4, 7, 10],								// control values for the y axis - displays the values next to the axis and a dashed line
		valueFormat: null,											// override display value function
		colors: [												// bar color gradients, if more values than colors round-robin
			{start: "#ff0000", end: "#6f0000", light: "#ffaaaa"},
			{start: "#00ff00", end: "#006f00", light: "#aaffaa"},
			{start: "#0000ff", end: "#00006f", light: "#aaaaff"},
			{start: "#ffff00", end: "#6f6f00", light: "#ffffaa"},
			{start: "#ff00ff", end: "#6f006f", light: "#ffaaff"},
			{start: "#00ffff", end: "#006f6f", light: "#aaffff"},
			{start: "#6f6f6f", end: "#ffffff", light: "#aaaaaa"}
		],
		legendFlag: false,											// display legend?
		legendHeight: 0,
		controlLineFlag: true,											// display control line?
		controlLineValues: [3, 3, 5, 6, 7, 4, 9, 8],
		controlLineColor: "#ffffff",
		controlLineIncludeInLegend: true,
		controlLineLegendTitle: "Control line"
	});
	chart.setRenderer(renderer);
	chart.render();
} else alert("Unsupported browser");

Things to do in future:

1 Make the chart animated and interactive (attach events to the bars).

2 Support other types of charts (piechart).

3 Canvas support would be nice to have, but not really a priority. The chances are good if you have canvas you have SVG also.

Any comments, suggestions and improvements are appreciated.

Credits:

While googling for VML related stuff I came across an interesting project, which aims at the same problems – http://prototype-graphic.xilinus.com/

It’s a framework based on prototype and adresses also cross browser graphics rendering. Doesn’t seem to be very advanced yet, supports canvas, SVG and VML for creating basic shapes. Digging into the source helped me solve some of the VML problems I had.

crescentfresh has a cool answer on how to detect SVG and VML support at http://stackoverflow.com/questions/654112/how-do-you-detect-support-for-vml-or-svg-in-a-browser

Things to do in future:
1) Make the chart animated and interactive (attach events to the bars).
2) Support other types of charts (piechart).
3) Canvas support would be nice to have, but not really a priority. The chances are good if you have canvas you have SVG also.
Any comments, suggestions and improvements are appreciated.
Credits:
While googling for VML related stuff I came across an interesting project, which aims at the same problems – http://prototype-graphic.xilinus.com/
It’s a framework based on prototype and adresses also cross browser graphics rendering. Doesn’t seem to be very advanced yet, supports canvas, SVG and VML for creating basic shapes. Digging into the source helped me solve some of the VML problems I had.
crescentfresh has a cool answer on how to detect SVG and VML support at http://stackoverflow.com/questions/654112/how-do-you-detect-support-for-vml-or-svg-in-a-browser

by ivan